diff options
-rw-r--r-- | clang/Lex/IdentifierTable.cpp | 16 | ||||
-rw-r--r-- | clang/Lex/Preprocessor.cpp | 6 | ||||
-rw-r--r-- | clang/include/clang/Basic/TokenKinds.def | 19 | ||||
-rw-r--r-- | clang/include/clang/Lex/IdentifierTable.h | 9 | ||||
-rw-r--r-- | clang/test/Preprocessor/cxx_and.cpp | 17 | ||||
-rw-r--r-- | clang/test/Preprocessor/cxx_bitand.cpp | 16 | ||||
-rw-r--r-- | clang/test/Preprocessor/cxx_bitor.cpp | 18 | ||||
-rw-r--r-- | clang/test/Preprocessor/cxx_compl.cpp | 16 | ||||
-rw-r--r-- | clang/test/Preprocessor/cxx_not.cpp | 15 | ||||
-rw-r--r-- | clang/test/Preprocessor/cxx_not_eq.cpp | 16 | ||||
-rw-r--r-- | clang/test/Preprocessor/cxx_or.cpp | 17 | ||||
-rw-r--r-- | clang/test/Preprocessor/cxx_xor.cpp | 18 |
12 files changed, 179 insertions, 4 deletions
diff --git a/clang/Lex/IdentifierTable.cpp b/clang/Lex/IdentifierTable.cpp index eaa0f1a5bb9..adc1e377222 100644 --- a/clang/Lex/IdentifierTable.cpp +++ b/clang/Lex/IdentifierTable.cpp @@ -31,6 +31,7 @@ IdentifierInfo::IdentifierInfo() { IsExtension = false; IsPoisoned = false; IsOtherTargetMacro = false; + IsCPPOperatorKeyword = false; FETokenInfo = 0; } @@ -85,6 +86,16 @@ static void AddPPKeyword(tok::PPKeywordKind PPID, Table.get(Name, Name+NameLen).setPPKeywordID(PPID); } +/// AddCXXOperatorKeyword - Register a C++ operator keyword alternative +/// representations. +static void AddCXXOperatorKeyword(const char *Keyword, unsigned KWLen, + tok::TokenKind TokenCode, + IdentifierTable &Table) { + IdentifierInfo &Info = Table.get(Keyword, Keyword + KWLen); + Info.setTokenID(TokenCode); + Info.setIsCPlusplusOperatorKeyword(); +} + /// AddObjCKeyword - Register an Objective-C @keyword like "class" "selector" or /// "property". static void AddObjCKeyword(tok::ObjCKeywordKind ObjCID, @@ -119,6 +130,9 @@ void IdentifierTable::AddKeywords(const LangOptions &LangOpts) { AddKeyword(NAME, strlen(NAME), tok::kw_ ## TOK, 0, 0, 0, LangOpts, *this); #define PPKEYWORD(NAME) \ AddPPKeyword(tok::pp_##NAME, #NAME, strlen(#NAME), *this); +#define CXX_KEYWORD_OPERATOR(NAME, ALIAS) \ + if (LangOpts.CPlusPlus) \ + AddCXXOperatorKeyword(#NAME, strlen(#NAME), tok::ALIAS, *this); #define OBJC1_AT_KEYWORD(NAME) \ if (LangOpts.ObjC1) \ AddObjCKeyword(tok::objc_##NAME, #NAME, strlen(#NAME), *this); @@ -173,5 +187,3 @@ void IdentifierTable::PrintStats() const { // Compute statistics about the memory allocated for identifiers. HashTable.getAllocator().PrintStats(); } - - diff --git a/clang/Lex/Preprocessor.cpp b/clang/Lex/Preprocessor.cpp index 4af6d31c186..57cdbe94407 100644 --- a/clang/Lex/Preprocessor.cpp +++ b/clang/Lex/Preprocessor.cpp @@ -967,6 +967,12 @@ void Preprocessor::HandleIdentifier(LexerToken &Identifier) { } + // C++ 2.11p2: If this is an alternative representation of a C++ operator, + // then we act as if it is the actual operator and not the textual + // representation of it. + if (II.isCPlusPlusOperatorKeyword()) + Identifier.setIdentifierInfo(0); + // Change the kind of this identifier to the appropriate token kind, e.g. // turning "for" into a keyword. Identifier.setKind(II.getTokenID()); diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index 6474d6da639..9d37536961a 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -26,6 +26,9 @@ #ifndef PPKEYWORD #define PPKEYWORD(X) #endif +#ifndef CXX_KEYWORD_OPERATOR +#define CXX_KEYWORD_OPERATOR(X,Y) +#endif #ifndef OBJC1_AT_KEYWORD #define OBJC1_AT_KEYWORD(X) #endif @@ -222,7 +225,7 @@ KEYWORD(__func__ , EXTC90|EXTCPP) // Only in C99. KEYWORD(__FUNCTION__ , EXTC90|EXTC99|EXTCPP) // GCC Extension. KEYWORD(__PRETTY_FUNCTION__ , EXTC90|EXTC99|EXTCPP) // GCC Extension. -// C++ +// C++ 2.11p1: Keywords. KEYWORD(asm , EXTC90|EXTC99) // Exts in C90/C99 KEYWORD(catch , NOTC90|NOTC99) KEYWORD(class , NOTC90|NOTC99) @@ -253,6 +256,19 @@ KEYWORD(using , NOTC90|NOTC99) KEYWORD(virtual , NOTC90|NOTC99) KEYWORD(wchar_t , NOTC90|NOTC99) +// C++ 2.5p2: Alternative Representations. +CXX_KEYWORD_OPERATOR(and , ampamp) +CXX_KEYWORD_OPERATOR(and_eq , ampequal) +CXX_KEYWORD_OPERATOR(bitand , amp) +CXX_KEYWORD_OPERATOR(bitor , pipe) +CXX_KEYWORD_OPERATOR(compl , tilde) +CXX_KEYWORD_OPERATOR(not , exclaim) +CXX_KEYWORD_OPERATOR(not_eq , exclaimequal) +CXX_KEYWORD_OPERATOR(or , pipepipe) +CXX_KEYWORD_OPERATOR(or_eq , pipeequal) +CXX_KEYWORD_OPERATOR(xor , caret) +CXX_KEYWORD_OPERATOR(xor_eq , caretequal) + // GNU Extensions. KEYWORD(_Decimal32 , EXTC90|EXTC99|EXTCPP) KEYWORD(_Decimal64 , EXTC90|EXTC99|EXTCPP) @@ -329,6 +345,7 @@ OBJC2_AT_KEYWORD(property) #undef OBJC2_AT_KEYWORD #undef OBJC1_AT_KEYWORD +#undef CXX_KEYWORD_OPERATOR #undef PPKEYWORD #undef ALIAS #undef KEYWORD diff --git a/clang/include/clang/Lex/IdentifierTable.h b/clang/include/clang/Lex/IdentifierTable.h index f3adfc89702..16e2045ae7b 100644 --- a/clang/include/clang/Lex/IdentifierTable.h +++ b/clang/include/clang/Lex/IdentifierTable.h @@ -36,6 +36,7 @@ class IdentifierInfo { bool IsExtension : 1; // True if identifier is a lang extension. bool IsPoisoned : 1; // True if identifier is poisoned. bool IsOtherTargetMacro : 1; // True if ident is macro on another target. + bool IsCPPOperatorKeyword : 1; // True if ident is a C++ operator keyword. void *FETokenInfo; // Managed by the language front-end. IdentifierInfo(const IdentifierInfo&); // NONCOPYABLE. public: @@ -90,7 +91,13 @@ public: /// is seen as being a macro on some other target. void setIsOtherTargetMacro(bool Val = true) { IsOtherTargetMacro = Val; } bool isOtherTargetMacro() const { return IsOtherTargetMacro; } - + + /// isCPlusPlusOperatorKeyword/setIsCPlusPlusOperatorKeyword controls whether + /// this identifier is a C++ alternate representation of an operator. + void setIsCPlusplusOperatorKeyword(bool Val = true) + { IsCPPOperatorKeyword = Val; } + bool isCPlusPlusOperatorKeyword() const { return IsCPPOperatorKeyword; } + /// getFETokenInfo/setFETokenInfo - The language front-end is allowed to /// associate arbitrary metadata with this token. template<typename T> diff --git a/clang/test/Preprocessor/cxx_and.cpp b/clang/test/Preprocessor/cxx_and.cpp new file mode 100644 index 00000000000..b6bd00e5293 --- /dev/null +++ b/clang/test/Preprocessor/cxx_and.cpp @@ -0,0 +1,17 @@ +// RUN: clang -DA -DB -E %s | grep 'int a = 37 == 37' && +// RUN: clang -DA -E %s | grep 'int a = 927 == 927' && +// RUN: clang -DB -E %s | grep 'int a = 927 == 927' && +// RUN: clang -E %s | grep 'int a = 927 == 927' +#if defined(A) and defined(B) +#define X 37 +#else +#define X 927 +#endif + +#if defined(A) && defined(B) +#define Y 37 +#else +#define Y 927 +#endif + +int a = X == Y; diff --git a/clang/test/Preprocessor/cxx_bitand.cpp b/clang/test/Preprocessor/cxx_bitand.cpp new file mode 100644 index 00000000000..ecc52e89ab5 --- /dev/null +++ b/clang/test/Preprocessor/cxx_bitand.cpp @@ -0,0 +1,16 @@ +// RUN: clang -DA=1 -DB=2 -E %s | grep 'int a = 927 == 927' && +// RUN: clang -DA=1 -DB=1 -E %s | grep 'int a = 37 == 37' && +// RUN: clang -E %s | grep 'int a = 927 == 927' +#if A bitand B +#define X 37 +#else +#define X 927 +#endif + +#if A & B +#define Y 37 +#else +#define Y 927 +#endif + +int a = X == Y; diff --git a/clang/test/Preprocessor/cxx_bitor.cpp b/clang/test/Preprocessor/cxx_bitor.cpp new file mode 100644 index 00000000000..36c44523df3 --- /dev/null +++ b/clang/test/Preprocessor/cxx_bitor.cpp @@ -0,0 +1,18 @@ +// RUN: clang -DA=1 -DB=1 -E %s | grep 'int a = 37 == 37' && +// RUN: clang -DA=0 -DB=1 -E %s | grep 'int a = 37 == 37' && +// RUN: clang -DA=1 -DB=0 -E %s | grep 'int a = 37 == 37' && +// RUN: clang -DA=0 -DB=0 -E %s | grep 'int a = 927 == 927' && +// RUN: clang -E %s | grep 'int a = 927 == 927' +#if A bitor B +#define X 37 +#else +#define X 927 +#endif + +#if A | B +#define Y 37 +#else +#define Y 927 +#endif + +int a = X == Y; diff --git a/clang/test/Preprocessor/cxx_compl.cpp b/clang/test/Preprocessor/cxx_compl.cpp new file mode 100644 index 00000000000..12e589ffa1e --- /dev/null +++ b/clang/test/Preprocessor/cxx_compl.cpp @@ -0,0 +1,16 @@ +// RUN: clang -DA=1 -E %s | grep 'int a = 37 == 37' && +// RUN: clang -DA=0 -E %s | grep 'int a = 927 == 927' && +// RUN: clang -E %s | grep 'int a = 927 == 927' +#if compl 0 bitand A +#define X 37 +#else +#define X 927 +#endif + +#if ~0 & A +#define Y 37 +#else +#define Y 927 +#endif + +int a = X == Y; diff --git a/clang/test/Preprocessor/cxx_not.cpp b/clang/test/Preprocessor/cxx_not.cpp new file mode 100644 index 00000000000..2587b0ab994 --- /dev/null +++ b/clang/test/Preprocessor/cxx_not.cpp @@ -0,0 +1,15 @@ +// RUN: clang -DA=1 -E %s | grep 'int a = 927 == 927' && +// RUN: clang -E %s | grep 'int a = 37 == 37' +#if not defined(A) +#define X 37 +#else +#define X 927 +#endif + +#if ! defined(A) +#define Y 37 +#else +#define Y 927 +#endif + +int a = X == Y; diff --git a/clang/test/Preprocessor/cxx_not_eq.cpp b/clang/test/Preprocessor/cxx_not_eq.cpp new file mode 100644 index 00000000000..b0be7b39173 --- /dev/null +++ b/clang/test/Preprocessor/cxx_not_eq.cpp @@ -0,0 +1,16 @@ +// RUN: clang -DA=1 -DB=1 -E %s | grep 'int a = 927 == 927' && +// RUN: clang -E %s | grep 'int a = 927 == 927' && +// RUN: clang -DA=1 -DB=2 -E %s | grep 'int a = 37 == 37' +#if A not_eq B +#define X 37 +#else +#define X 927 +#endif + +#if A != B +#define Y 37 +#else +#define Y 927 +#endif + +int a = X == Y; diff --git a/clang/test/Preprocessor/cxx_or.cpp b/clang/test/Preprocessor/cxx_or.cpp new file mode 100644 index 00000000000..ce3fed1cd48 --- /dev/null +++ b/clang/test/Preprocessor/cxx_or.cpp @@ -0,0 +1,17 @@ +// RUN: clang -DA -DB -E %s | grep 'int a = 37 == 37' && +// RUN: clang -DA -E %s | grep 'int a = 37 == 37' && +// RUN: clang -DB -E %s | grep 'int a = 37 == 37' && +// RUN: clang -E %s | grep 'int a = 927 == 927' +#if defined(A) or defined(B) +#define X 37 +#else +#define X 927 +#endif + +#if defined(A) || defined(B) +#define Y 37 +#else +#define Y 927 +#endif + +int a = X == Y; diff --git a/clang/test/Preprocessor/cxx_xor.cpp b/clang/test/Preprocessor/cxx_xor.cpp new file mode 100644 index 00000000000..7a4c8822cda --- /dev/null +++ b/clang/test/Preprocessor/cxx_xor.cpp @@ -0,0 +1,18 @@ +// RUN: clang -DA=1 -DB=1 -E %s | grep 'int a = 927 == 927' && +// RUN: clang -DA=0 -DB=1 -E %s | grep 'int a = 37 == 37' && +// RUN: clang -DA=1 -DB=0 -E %s | grep 'int a = 37 == 37' && +// RUN: clang -DA=0 -DB=0 -E %s | grep 'int a = 927 == 927' && +// RUN: clang -E %s | grep 'int a = 927 == 927' +#if A xor B +#define X 37 +#else +#define X 927 +#endif + +#if A ^ B +#define Y 37 +#else +#define Y 927 +#endif + +int a = X == Y; |