#define KEYWORD(X,Y) TOK(kw_ ## X)
#endif
#ifndef ALIAS
-#define ALIAS(X,Y)
+#define ALIAS(X,Y,Z)
#endif
#ifndef PPKEYWORD
#define PPKEYWORD(X)
// C99 6.4.1: Keywords. These turn into kw_* tokens.
// Flags allowed:
-// NOTC90 - In C90, this token is never available.
-// 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++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.
+// KEYALL - This is a keyword in all variants of C and C++, or it
+// is a keyword in the implementation namespace that should
+// always be treated as a keyword
+// KEYC99 - This is a keyword introduced to C in C99
+// KEYCXX - This is a C++ keyword, or a C++-specific keyword in the
+// implementation namespace
+// KEYCXX0X - This is a C++ keyword introduced to C++ in C++0x
+// KEYGNU - This is a keyword if GNU extensions are enabled
+// KEYMS - This is a keyword if Microsoft extensions are enabled
//
-KEYWORD(auto , 0)
-KEYWORD(break , 0)
-KEYWORD(case , 0)
-KEYWORD(char , 0)
-KEYWORD(const , 0)
-KEYWORD(continue , 0)
-KEYWORD(default , 0)
-KEYWORD(do , 0)
-KEYWORD(double , 0)
-KEYWORD(else , 0)
-KEYWORD(enum , 0)
-KEYWORD(extern , 0)
-KEYWORD(float , 0)
-KEYWORD(for , 0)
-KEYWORD(goto , 0)
-KEYWORD(if , 0)
-KEYWORD(inline , EXTC90) // Ext in C90, ok in C99/C++
-KEYWORD(int , 0)
-KEYWORD(long , 0)
-KEYWORD(register , 0)
-KEYWORD(restrict , NOTC90) // Not in C90
-KEYWORD(return , 0)
-KEYWORD(short , 0)
-KEYWORD(signed , 0)
-KEYWORD(sizeof , 0)
-KEYWORD(static , 0)
-KEYWORD(struct , 0)
-KEYWORD(switch , 0)
-KEYWORD(typedef , 0)
-KEYWORD(union , 0)
-KEYWORD(unsigned , 0)
-KEYWORD(void , 0)
-KEYWORD(volatile , 0)
-KEYWORD(while , 0)
-KEYWORD(_Bool , EXTC90|EXTCPP|EXTCPP0x) // C99 only
-KEYWORD(_Complex , EXTC90|EXTCPP|EXTCPP0x) // C99 only
-KEYWORD(_Imaginary , EXTC90|NOTCPP|NOTCPP0x) // C90 only
-
-// Special tokens to the compiler.
-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.
+KEYWORD(auto , KEYALL)
+KEYWORD(break , KEYALL)
+KEYWORD(case , KEYALL)
+KEYWORD(char , KEYALL)
+KEYWORD(const , KEYALL)
+KEYWORD(continue , KEYALL)
+KEYWORD(default , KEYALL)
+KEYWORD(do , KEYALL)
+KEYWORD(double , KEYALL)
+KEYWORD(else , KEYALL)
+KEYWORD(enum , KEYALL)
+KEYWORD(extern , KEYALL)
+KEYWORD(float , KEYALL)
+KEYWORD(for , KEYALL)
+KEYWORD(goto , KEYALL)
+KEYWORD(if , KEYALL)
+KEYWORD(inline , KEYC99|KEYCXX|KEYGNU)
+KEYWORD(int , KEYALL)
+KEYWORD(long , KEYALL)
+KEYWORD(register , KEYALL)
+KEYWORD(restrict , KEYC99|KEYGNU)
+KEYWORD(return , KEYALL)
+KEYWORD(short , KEYALL)
+KEYWORD(signed , KEYALL)
+KEYWORD(sizeof , KEYALL)
+KEYWORD(static , KEYALL)
+KEYWORD(struct , KEYALL)
+KEYWORD(switch , KEYALL)
+KEYWORD(typedef , KEYALL)
+KEYWORD(union , KEYALL)
+KEYWORD(unsigned , KEYALL)
+KEYWORD(void , KEYALL)
+KEYWORD(volatile , KEYALL)
+KEYWORD(while , KEYALL)
+KEYWORD(_Bool , KEYALL)
+KEYWORD(_Complex , KEYALL)
+KEYWORD(_Imaginary , KEYALL)
+KEYWORD(__func__ , KEYALL)
// C++ 2.11p1: Keywords.
-KEYWORD(asm , EXTC90|EXTC99) // Exts in C90/C99
-KEYWORD(bool , BOOLSUPPORT)
-KEYWORD(catch , NOTC90|NOTC99)
-KEYWORD(class , NOTC90|NOTC99)
-KEYWORD(const_cast , NOTC90|NOTC99)
-KEYWORD(delete , NOTC90|NOTC99)
-KEYWORD(dynamic_cast , NOTC90|NOTC99)
-KEYWORD(explicit , NOTC90|NOTC99)
-KEYWORD(export , NOTC90|NOTC99)
-KEYWORD(false , BOOLSUPPORT)
-KEYWORD(friend , NOTC90|NOTC99)
-KEYWORD(mutable , NOTC90|NOTC99)
-KEYWORD(namespace , NOTC90|NOTC99)
-KEYWORD(new , NOTC90|NOTC99)
-KEYWORD(operator , NOTC90|NOTC99)
-KEYWORD(private , NOTC90|NOTC99)
-KEYWORD(protected , NOTC90|NOTC99)
-KEYWORD(public , NOTC90|NOTC99)
-KEYWORD(reinterpret_cast , NOTC90|NOTC99)
-KEYWORD(static_cast , NOTC90|NOTC99)
-KEYWORD(template , NOTC90|NOTC99)
-KEYWORD(this , NOTC90|NOTC99)
-KEYWORD(throw , NOTC90|NOTC99)
-KEYWORD(true , BOOLSUPPORT)
-KEYWORD(try , NOTC90|NOTC99)
-KEYWORD(typename , NOTC90|NOTC99)
-KEYWORD(typeid , NOTC90|NOTC99)
-KEYWORD(using , NOTC90|NOTC99)
-KEYWORD(virtual , NOTC90|NOTC99)
-KEYWORD(wchar_t , NOTC90|NOTC99)
+KEYWORD(asm , KEYCXX|KEYGNU)
+KEYWORD(bool , KEYCXX)
+KEYWORD(catch , KEYCXX)
+KEYWORD(class , KEYCXX)
+KEYWORD(const_cast , KEYCXX)
+KEYWORD(delete , KEYCXX)
+KEYWORD(dynamic_cast , KEYCXX)
+KEYWORD(explicit , KEYCXX)
+KEYWORD(export , KEYCXX)
+KEYWORD(false , KEYCXX)
+KEYWORD(friend , KEYCXX)
+KEYWORD(mutable , KEYCXX)
+KEYWORD(namespace , KEYCXX)
+KEYWORD(new , KEYCXX)
+KEYWORD(operator , KEYCXX)
+KEYWORD(private , KEYCXX)
+KEYWORD(protected , KEYCXX)
+KEYWORD(public , KEYCXX)
+KEYWORD(reinterpret_cast , KEYCXX)
+KEYWORD(static_cast , KEYCXX)
+KEYWORD(template , KEYCXX)
+KEYWORD(this , KEYCXX)
+KEYWORD(throw , KEYCXX)
+KEYWORD(true , KEYCXX)
+KEYWORD(try , KEYCXX)
+KEYWORD(typename , KEYCXX)
+KEYWORD(typeid , KEYCXX)
+KEYWORD(using , KEYCXX)
+KEYWORD(virtual , KEYCXX)
+KEYWORD(wchar_t , KEYCXX)
// C++ 2.5p2: Alternative Representations.
CXX_KEYWORD_OPERATOR(and , ampamp)
CXX_KEYWORD_OPERATOR(xor_eq , caretequal)
// C++0x keywords
-KEYWORD(alignof , NOTC90|NOTC99|NOTCPP)
-KEYWORD(axiom , NOTC90|NOTC99|NOTCPP)
-KEYWORD(char16_t , NOTC90|NOTC99|NOTCPP)
-KEYWORD(char32_t , NOTC90|NOTC99|NOTCPP)
-KEYWORD(concept , NOTC90|NOTC99|NOTCPP)
-KEYWORD(concept_map , NOTC90|NOTC99|NOTCPP)
-KEYWORD(constexpr , NOTC90|NOTC99|NOTCPP)
-KEYWORD(decltype , NOTC90|NOTC99|NOTCPP)
-KEYWORD(late_check , NOTC90|NOTC99|NOTCPP)
-KEYWORD(nullptr , NOTC90|NOTC99|NOTCPP)
-KEYWORD(requires , NOTC90|NOTC99|NOTCPP)
-KEYWORD(static_assert , NOTC90|NOTC99|NOTCPP)
-KEYWORD(thread_local , NOTC90|NOTC99|NOTCPP)
-
-// GNU Extensions.
-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|EXTCPP0x)
-KEYWORD(__label__ , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
-KEYWORD(__real , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
-KEYWORD(__thread , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
+KEYWORD(alignof , KEYCXX0X)
+KEYWORD(axiom , KEYCXX0X)
+KEYWORD(char16_t , KEYCXX0X)
+KEYWORD(char32_t , KEYCXX0X)
+KEYWORD(concept , KEYCXX0X)
+KEYWORD(concept_map , KEYCXX0X)
+KEYWORD(constexpr , KEYCXX0X)
+KEYWORD(decltype , KEYCXX0X)
+KEYWORD(late_check , KEYCXX0X)
+KEYWORD(nullptr , KEYCXX0X)
+KEYWORD(requires , KEYCXX0X)
+KEYWORD(static_assert , KEYCXX0X)
+KEYWORD(thread_local , KEYCXX0X)
+
+// GNU Extensions (in impl-reserved namespace)
+KEYWORD(_Decimal32 , KEYALL)
+KEYWORD(_Decimal64 , KEYALL)
+KEYWORD(_Decimal128 , KEYALL)
+KEYWORD(__null , KEYCXX)
+KEYWORD(__alignof , KEYALL)
+KEYWORD(__attribute , KEYALL)
+KEYWORD(__builtin_choose_expr , KEYALL)
+KEYWORD(__builtin_offsetof , KEYALL)
+KEYWORD(__builtin_types_compatible_p, KEYALL)
+KEYWORD(__builtin_va_arg , KEYALL)
+KEYWORD(__extension__ , KEYALL)
+KEYWORD(__imag , KEYALL)
+KEYWORD(__label__ , KEYALL)
+KEYWORD(__real , KEYALL)
+KEYWORD(__thread , KEYALL)
+KEYWORD(__FUNCTION__ , KEYALL)
+KEYWORD(__PRETTY_FUNCTION__ , KEYALL)
+
+// GNU Extensions (outside impl-reserved namespace)
+KEYWORD(typeof , KEYGNU)
// GNU and MS Type Traits
-KEYWORD(__has_nothrow_assign , NOTC90|NOTC99)
-KEYWORD(__has_nothrow_copy , NOTC90|NOTC99)
-KEYWORD(__has_nothrow_constructor , NOTC90|NOTC99)
-KEYWORD(__has_trivial_assign , NOTC90|NOTC99)
-KEYWORD(__has_trivial_copy , NOTC90|NOTC99)
-KEYWORD(__has_trivial_constructor , NOTC90|NOTC99)
-KEYWORD(__has_trivial_destructor , NOTC90|NOTC99)
-KEYWORD(__has_virtual_destructor , NOTC90|NOTC99)
-KEYWORD(__is_abstract , NOTC90|NOTC99)
-KEYWORD(__is_base_of , NOTC90|NOTC99)
-KEYWORD(__is_class , NOTC90|NOTC99)
-KEYWORD(__is_empty , NOTC90|NOTC99)
-KEYWORD(__is_enum , NOTC90|NOTC99)
-KEYWORD(__is_pod , NOTC90|NOTC99)
-KEYWORD(__is_polymorphic , NOTC90|NOTC99)
-KEYWORD(__is_union , NOTC90|NOTC99)
+KEYWORD(__has_nothrow_assign , KEYCXX)
+KEYWORD(__has_nothrow_copy , KEYCXX)
+KEYWORD(__has_nothrow_constructor , KEYCXX)
+KEYWORD(__has_trivial_assign , KEYCXX)
+KEYWORD(__has_trivial_copy , KEYCXX)
+KEYWORD(__has_trivial_constructor , KEYCXX)
+KEYWORD(__has_trivial_destructor , KEYCXX)
+KEYWORD(__has_virtual_destructor , KEYCXX)
+KEYWORD(__is_abstract , KEYCXX)
+KEYWORD(__is_base_of , KEYCXX)
+KEYWORD(__is_class , KEYCXX)
+KEYWORD(__is_empty , KEYCXX)
+KEYWORD(__is_enum , KEYCXX)
+KEYWORD(__is_pod , KEYCXX)
+KEYWORD(__is_polymorphic , KEYCXX)
+KEYWORD(__is_union , KEYCXX)
// FIXME: Add MS's traits, too.
// Apple Extension.
-KEYWORD(__private_extern__ , EXTC90|EXTC99|NOTCPP)
+KEYWORD(__private_extern__ , KEYALL)
// Microsoft Extension.
-KEYWORD(__declspec , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
-KEYWORD(__cdecl , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
-KEYWORD(__stdcall , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
-KEYWORD(__fastcall , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
-KEYWORD(__ptr64 , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
-KEYWORD(__w64 , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
-KEYWORD(__forceinline , EXTC90|EXTC99|EXTCPP|EXTCPP0x)
+KEYWORD(__declspec , KEYALL)
+KEYWORD(__cdecl , KEYALL)
+KEYWORD(__stdcall , KEYALL)
+KEYWORD(__fastcall , KEYALL)
+KEYWORD(__ptr64 , KEYALL)
+KEYWORD(__w64 , KEYALL)
+KEYWORD(__forceinline , KEYALL)
// Alternate spelling for various tokens. There are GCC extensions in all
// languages, but should not be disabled in strict conformance mode.
-ALIAS("__attribute__", __attribute)
-ALIAS("__const" , const )
-ALIAS("__const__" , const )
-ALIAS("__alignof__" , __alignof )
-ALIAS("_asm" , asm )
-ALIAS("__asm" , asm )
-ALIAS("__asm__" , asm )
-ALIAS("__complex" , _Complex )
-ALIAS("__complex__" , _Complex )
-ALIAS("__imag__" , __imag )
-ALIAS("__inline" , inline )
-ALIAS("__inline__" , inline )
-ALIAS("__real__" , __real )
-ALIAS("__restrict" , restrict )
-ALIAS("__restrict__" , restrict )
-ALIAS("__signed" , signed )
-ALIAS("__signed__" , signed )
-ALIAS("__typeof" , typeof )
-ALIAS("__typeof__" , typeof )
-ALIAS("__volatile" , volatile )
-ALIAS("__volatile__" , volatile )
+ALIAS("__attribute__", __attribute, KEYALL)
+ALIAS("__const" , const , KEYALL)
+ALIAS("__const__" , const , KEYALL)
+ALIAS("__alignof__" , __alignof , KEYALL)
+ALIAS("_asm" , asm , KEYMS)
+ALIAS("__asm" , asm , KEYALL)
+ALIAS("__asm__" , asm , KEYALL)
+ALIAS("__complex" , _Complex , KEYALL)
+ALIAS("__complex__" , _Complex , KEYALL)
+ALIAS("__imag__" , __imag , KEYALL)
+ALIAS("__inline" , inline , KEYALL)
+ALIAS("__inline__" , inline , KEYALL)
+ALIAS("__real__" , __real , KEYALL)
+ALIAS("__restrict" , restrict , KEYALL)
+ALIAS("__restrict__" , restrict , KEYALL)
+ALIAS("__signed" , signed , KEYALL)
+ALIAS("__signed__" , signed , KEYALL)
+ALIAS("__typeof" , typeof , KEYALL)
+ALIAS("__typeof__" , typeof , KEYALL)
+ALIAS("__volatile" , volatile , KEYALL)
+ALIAS("__volatile__" , volatile , KEYALL)
//===----------------------------------------------------------------------===//
// Language Keyword Implementation
//===----------------------------------------------------------------------===//
+// Constants for TokenKinds.def
+namespace {
+ enum {
+ KEYALL = 1,
+ KEYC99 = 2,
+ KEYCXX = 4,
+ KEYCXX0X = 8,
+ KEYGNU = 16,
+ KEYMS = 32
+ };
+}
+
/// AddKeyword - This method is used to associate a token ID with specific
/// identifiers because they are language keywords. This causes the lexer to
/// automatically map matching identifiers to specialized token codes.
/// 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 CXX0x, int BoolSupport,
+ tok::TokenKind TokenCode, unsigned Flags,
const LangOptions &LangOpts, IdentifierTable &Table) {
- int Flags = 0;
- if (BoolSupport != 0) {
- Flags = LangOpts.CPlusPlus? 0 : LangOpts.Boolean ? BoolSupport : 2;
- } else if (LangOpts.CPlusPlus) {
- Flags = LangOpts.CPlusPlus0x ? CXX0x : CXX;
- } else if (LangOpts.C99) {
- Flags = C99;
- } else {
- Flags = C90;
- }
-
- // Don't add this keyword if disabled in this language or if an extension
- // and extensions are disabled.
- if (Flags + LangOpts.NoExtensions >= 2) return;
-
+ unsigned AddResult = 0;
+ if (Flags & KEYALL) AddResult = 2;
+ else if (LangOpts.CPlusPlus && (Flags & KEYCXX)) AddResult = 2;
+ else if (LangOpts.CPlusPlus0x && (Flags & KEYCXX0X)) AddResult = 2;
+ else if (LangOpts.C99 && (Flags & KEYC99)) AddResult = 2;
+ else if (LangOpts.GNUMode && (Flags & KEYGNU)) AddResult = 1;
+ else if (LangOpts.Microsoft && (Flags & KEYMS)) AddResult = 1;
+
+ // Don't add this keyword if disabled in this language.
+ if (AddResult == 0) return;
+
IdentifierInfo &Info = Table.get(Keyword, Keyword+KWLen);
Info.setTokenID(TokenCode);
- Info.setIsExtensionToken(Flags == 1);
+ Info.setIsExtensionToken(AddResult == 1);
}
-static void AddAlias(const char *Keyword, unsigned KWLen,
- tok::TokenKind AliaseeID,
- const char *AliaseeKeyword, unsigned AliaseeKWLen,
- const LangOptions &LangOpts, IdentifierTable &Table) {
- IdentifierInfo &AliasInfo = Table.get(Keyword, Keyword+KWLen);
- IdentifierInfo &AliaseeInfo = Table.get(AliaseeKeyword,
- AliaseeKeyword+AliaseeKWLen);
- AliasInfo.setTokenID(AliaseeID);
- AliasInfo.setIsExtensionToken(AliaseeInfo.isExtensionToken());
-}
-
/// AddCXXOperatorKeyword - Register a C++ operator keyword alternative
/// representations.
static void AddCXXOperatorKeyword(const char *Keyword, unsigned KWLen,
/// AddKeywords - Add all keywords to the symbol table.
///
void IdentifierTable::AddKeywords(const LangOptions &LangOpts) {
- enum {
- C90Shift = 0,
- EXTC90 = 1 << C90Shift,
- NOTC90 = 2 << C90Shift,
- C99Shift = 2,
- EXTC99 = 1 << C99Shift,
- NOTC99 = 2 << C99Shift,
- CPPShift = 4,
- EXTCPP = 1 << CPPShift,
- NOTCPP = 2 << CPPShift,
- CPP0xShift = 6,
- EXTCPP0x = 1 << CPP0xShift,
- NOTCPP0x = 2 << CPP0xShift,
- BoolShift = 8,
- BOOLSUPPORT = 1 << BoolShift,
- Mask = 3
- };
-
// Add keywords and tokens for the current language.
#define KEYWORD(NAME, FLAGS) \
AddKeyword(#NAME, strlen(#NAME), tok::kw_ ## NAME, \
- ((FLAGS) >> C90Shift) & Mask, \
- ((FLAGS) >> C99Shift) & Mask, \
- ((FLAGS) >> CPPShift) & Mask, \
- ((FLAGS) >> CPP0xShift) & Mask, \
- ((FLAGS) >> BoolShift) & Mask, LangOpts, *this);
-#define ALIAS(NAME, TOK) \
- AddAlias(NAME, strlen(NAME), tok::kw_ ## TOK, #TOK, strlen(#TOK), \
- LangOpts, *this);
+ FLAGS, LangOpts, *this);
+#define ALIAS(NAME, TOK, FLAGS) \
+ AddKeyword(NAME, strlen(NAME), tok::kw_ ## TOK, \
+ FLAGS, LangOpts, *this);
#define CXX_KEYWORD_OPERATOR(NAME, ALIAS) \
if (LangOpts.CXXOperatorNames) \
AddCXXOperatorKeyword(#NAME, strlen(#NAME), tok::ALIAS, *this);