From d4b80f1a0e946aa38c5db7d6f8afcdf05ed57116 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 16 Jul 2007 04:18:29 +0000 Subject: [PATCH] Add support for C++'0x keywords, patch by Doug Gregor git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@39897 91177308-0d34-0410-b5e6-96231b3b80d8 --- Driver/clang.cpp | 12 ++++++- Lex/IdentifierTable.cpp | 18 ++++++---- include/clang/Basic/LangOptions.h | 4 ++- include/clang/Basic/TokenKinds.def | 52 +++++++++++++++------------ test/Lexer/cxx0x_keyword.cpp | 2 ++ test/Lexer/cxx0x_keyword_as_cxx98.cpp | 2 ++ 6 files changed, 60 insertions(+), 30 deletions(-) create mode 100644 test/Lexer/cxx0x_keyword.cpp create mode 100644 test/Lexer/cxx0x_keyword_as_cxx98.cpp diff --git a/Driver/clang.cpp b/Driver/clang.cpp index 43eaee68f6..404baadf48 100644 --- a/Driver/clang.cpp +++ b/Driver/clang.cpp @@ -207,7 +207,8 @@ enum LangStds { lang_unspecified, lang_c89, lang_c94, lang_c99, lang_gnu89, lang_gnu99, - lang_cxx98, lang_gnucxx98 + lang_cxx98, lang_gnucxx98, + lang_cxx0x, lang_gnucxx0x }; static llvm::cl::opt @@ -233,6 +234,11 @@ LangStd("std", llvm::cl::desc("Language standard to compile for"), clEnumValN(lang_gnucxx98, "gnu++98", "ISO C++ 1998 with amendments and GNU " "extensions (default for C++)"), + clEnumValN(lang_cxx0x, "c++0x", + "Upcoming ISO C++ 200x with amendments"), + clEnumValN(lang_gnucxx0x, "gnu++0x", + "Upcoming ISO C++ 200x with amendments and GNU " + "extensions (default for C++)"), clEnumValEnd)); static llvm::cl::opt @@ -269,6 +275,10 @@ static void InitializeLanguageStandard(LangOptions &Options) { // Fall through from newer standards to older ones. This isn't really right. // FIXME: Enable specifically the right features based on the language stds. + case lang_gnucxx0x: + case lang_cxx0x: + Options.CPlusPlus0x = 1; + // FALL THROUGH case lang_gnucxx98: case lang_cxx98: Options.CPlusPlus = 1; diff --git a/Lex/IdentifierTable.cpp b/Lex/IdentifierTable.cpp index e671af9839..4c6516df2d 100644 --- a/Lex/IdentifierTable.cpp +++ b/Lex/IdentifierTable.cpp @@ -59,14 +59,16 @@ IdentifierTable::IdentifierTable(const LangOptions &LangOpts) /// identifiers because they are language keywords. This causes the lexer to /// automatically map matching identifiers to specialized token codes. /// -/// The C90/C99/CPP flags are set to 0 if the token should be enabled in the -/// specified langauge, set to 1 if it is an extension in the specified -/// language, and set to 2 if disabled in the specified language. +/// The C90/C99/CPP/CPP0x flags are set to 0 if the token should be +/// enabled in the specified langauge, set to 1 if it is an extension +/// in the specified language, and set to 2 if disabled in the +/// specified language. static void AddKeyword(const char *Keyword, unsigned KWLen, tok::TokenKind TokenCode, - int C90, int C99, int CXX, + int C90, int C99, int CXX, int CXX0x, const LangOptions &LangOpts, IdentifierTable &Table) { - int Flags = LangOpts.CPlusPlus ? CXX : (LangOpts.C99 ? C99 : C90); + int Flags = LangOpts.CPlusPlus ? (LangOpts.CPlusPlus0x? CXX0x : CXX) + : (LangOpts.C99 ? C99 : C90); // Don't add this keyword if disabled in this language or if an extension // and extensions are disabled. @@ -126,6 +128,9 @@ void IdentifierTable::AddKeywords(const LangOptions &LangOpts) { CPPShift = 4, EXTCPP = 1 << CPPShift, NOTCPP = 2 << CPPShift, + CPP0xShift = 6, + EXTCPP0x = 1 << CPP0xShift, + NOTCPP0x = 2 << CPP0xShift, Mask = 3 }; @@ -134,7 +139,8 @@ void IdentifierTable::AddKeywords(const LangOptions &LangOpts) { AddKeyword(#NAME, strlen(#NAME), tok::kw_ ## NAME, \ ((FLAGS) >> C90Shift) & Mask, \ ((FLAGS) >> C99Shift) & Mask, \ - ((FLAGS) >> CPPShift) & Mask, LangOpts, *this); + ((FLAGS) >> CPPShift) & Mask, \ + ((FLAGS) >> CPP0xShift) & Mask, LangOpts, *this); #define ALIAS(NAME, TOK) \ AddAlias(NAME, strlen(NAME), #TOK, strlen(#TOK), LangOpts, *this); #define PPKEYWORD(NAME) \ diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h index 37a5e73614..a2d07f0e44 100644 --- a/include/clang/Basic/LangOptions.h +++ b/include/clang/Basic/LangOptions.h @@ -27,6 +27,7 @@ struct LangOptions { unsigned C99 : 1; // C99 Support unsigned Microsoft : 1; // Microsoft extensions. unsigned CPlusPlus : 1; // C++ Support + unsigned CPlusPlus0x : 1; // C++0x Support unsigned NoExtensions : 1; // All extensions are disabled, strict mode. unsigned CXXOperatorNames : 1; // Treat C++ operator names as keywords. @@ -35,7 +36,8 @@ struct LangOptions { LangOptions() { Trigraphs = BCPLComment = DollarIdents = Digraphs = ObjC1 = ObjC2 = 0; - C99 = Microsoft = CPlusPlus = NoExtensions = CXXOperatorNames = 0; + C99 = Microsoft = CPlusPlus = CPlusPlus0x = NoExtensions = 0; + CXXOperatorNames = 0; } }; diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def index 4fab08dfde..1310a0e01c 100644 --- a/include/clang/Basic/TokenKinds.def +++ b/include/clang/Basic/TokenKinds.def @@ -180,8 +180,11 @@ TOK(at) // @ // EXTC90 - In C90, this token is an extension that is enabled unless strict. // NOTC99 - In C99, this token is never available. // EXTC99 - In C99, this token is an extension that is enabled unless strict. -// NOTCPP - In C++, this token is never available. -// EXTCPP - In C++, this token is an extension that is enabled unless strict. +// NOTCPP - In C++98, this token is never available. +// EXTCPP - In C++98, this token is an extension that is enabled unless strict. +// NOTCPP0x - In C++0x, this token is never available. +// EXTCPP0x - In C++0x, this token is an extension that is enabled unless +// strict. // KEYWORD(auto , 0) KEYWORD(break , 0) @@ -217,14 +220,14 @@ KEYWORD(unsigned , 0) KEYWORD(void , 0) KEYWORD(volatile , 0) KEYWORD(while , 0) -KEYWORD(_Bool , EXTC90|EXTCPP) // C99 only +KEYWORD(_Bool , EXTC90|EXTCPP|EXTCPP0x) // C99 only KEYWORD(_Complex , EXTC90) // C99/C++ -KEYWORD(_Imaginary , EXTC90|NOTCPP) // C90 only +KEYWORD(_Imaginary , EXTC90|NOTCPP|NOTCPP0x) // C90 only // Special tokens to the compiler. -KEYWORD(__func__ , EXTC90|EXTCPP) // Only in C99. -KEYWORD(__FUNCTION__ , EXTC90|EXTC99|EXTCPP) // GCC Extension. -KEYWORD(__PRETTY_FUNCTION__ , EXTC90|EXTC99|EXTCPP) // GCC Extension. +KEYWORD(__func__ , EXTC90|EXTCPP|EXTCPP0x) // Only in C99. +KEYWORD(__FUNCTION__ , EXTC90|EXTC99|EXTCPP|EXTCPP0x) // GCC Extension. +KEYWORD(__PRETTY_FUNCTION__ , EXTC90|EXTC99|EXTCPP|EXTCPP0x) // GCC Extension. // C++ 2.11p1: Keywords. KEYWORD(asm , EXTC90|EXTC99) // Exts in C90/C99 @@ -271,23 +274,28 @@ CXX_KEYWORD_OPERATOR(or_eq , pipeequal) CXX_KEYWORD_OPERATOR(xor , caret) CXX_KEYWORD_OPERATOR(xor_eq , caretequal) +// C++0x keywords +KEYWORD(char16_t , NOTC90|NOTC99|NOTCPP) +KEYWORD(char32_t , NOTC90|NOTC99|NOTCPP) +KEYWORD(static_assert , NOTC90|NOTC99|NOTCPP) + // GNU Extensions. -KEYWORD(_Decimal32 , EXTC90|EXTC99|EXTCPP) -KEYWORD(_Decimal64 , EXTC90|EXTC99|EXTCPP) -KEYWORD(_Decimal128 , EXTC90|EXTC99|EXTCPP) -KEYWORD(typeof , EXTC90|EXTC99|EXTCPP) -KEYWORD(__null , NOTC90|NOTC99|EXTCPP) // C++-only Extensn -KEYWORD(__alignof , EXTC90|EXTC99|EXTCPP) -KEYWORD(__attribute , EXTC90|EXTC99|EXTCPP) -KEYWORD(__builtin_choose_expr , EXTC90|EXTC99|EXTCPP) -KEYWORD(__builtin_offsetof , EXTC90|EXTC99|EXTCPP) -KEYWORD(__builtin_types_compatible_p, EXTC90|EXTC99|EXTCPP) -KEYWORD(__builtin_va_arg , EXTC90|EXTC99|EXTCPP) +KEYWORD(_Decimal32 , EXTC90|EXTC99|EXTCPP|EXTCPP0x) +KEYWORD(_Decimal64 , EXTC90|EXTC99|EXTCPP|EXTCPP0x) +KEYWORD(_Decimal128 , EXTC90|EXTC99|EXTCPP|EXTCPP0x) +KEYWORD(typeof , EXTC90|EXTC99|EXTCPP|EXTCPP0x) +KEYWORD(__null , NOTC90|NOTC99|EXTCPP|EXTCPP0x) // C++-only Extensn +KEYWORD(__alignof , EXTC90|EXTC99|EXTCPP|EXTCPP0x) +KEYWORD(__attribute , EXTC90|EXTC99|EXTCPP|EXTCPP0x) +KEYWORD(__builtin_choose_expr , EXTC90|EXTC99|EXTCPP|EXTCPP0x) +KEYWORD(__builtin_offsetof , EXTC90|EXTC99|EXTCPP|EXTCPP0x) +KEYWORD(__builtin_types_compatible_p, EXTC90|EXTC99|EXTCPP|EXTCPP0x) +KEYWORD(__builtin_va_arg , EXTC90|EXTC99|EXTCPP|EXTCPP0x) KEYWORD(__extension__ , 0) // Not treated as an extension! -KEYWORD(__imag , EXTC90|EXTC99|EXTCPP) -KEYWORD(__label__ , EXTC90|EXTC99|EXTCPP) -KEYWORD(__real , EXTC90|EXTC99|EXTCPP) -KEYWORD(__thread , EXTC90|EXTC99|EXTCPP) +KEYWORD(__imag , EXTC90|EXTC99|EXTCPP|EXTCPP0x) +KEYWORD(__label__ , EXTC90|EXTC99|EXTCPP|EXTCPP0x) +KEYWORD(__real , EXTC90|EXTC99|EXTCPP|EXTCPP0x) +KEYWORD(__thread , EXTC90|EXTC99|EXTCPP|EXTCPP0x) // Alternate spelling for various tokens. There are GCC extensions in all // languages, but should not be disabled in strict conformance mode. diff --git a/test/Lexer/cxx0x_keyword.cpp b/test/Lexer/cxx0x_keyword.cpp new file mode 100644 index 0000000000..f3a8a7add2 --- /dev/null +++ b/test/Lexer/cxx0x_keyword.cpp @@ -0,0 +1,2 @@ +// RUN: clang -parse-ast-check -std=c++0x %s 2>&1 +int static_assert; /* expected-error {{expected identifier or '('}}} */ diff --git a/test/Lexer/cxx0x_keyword_as_cxx98.cpp b/test/Lexer/cxx0x_keyword_as_cxx98.cpp new file mode 100644 index 0000000000..6700dcb182 --- /dev/null +++ b/test/Lexer/cxx0x_keyword_as_cxx98.cpp @@ -0,0 +1,2 @@ +// RUN: clang %s -fsyntax-only +int static_assert; -- 2.40.0