diff options
-rw-r--r-- | clang/Lex/Preprocessor.cpp | 21 | ||||
-rw-r--r-- | clang/include/clang/Lex/LexerToken.h | 7 |
2 files changed, 24 insertions, 4 deletions
diff --git a/clang/Lex/Preprocessor.cpp b/clang/Lex/Preprocessor.cpp index 1a95b887f39..b614785dd83 100644 --- a/clang/Lex/Preprocessor.cpp +++ b/clang/Lex/Preprocessor.cpp @@ -147,6 +147,8 @@ void Preprocessor::DumpToken(const LexerToken &Tok, bool DumpFlags) const { std::cerr << " [StartOfLine]"; if (Tok.hasLeadingSpace()) std::cerr << " [LeadingSpace]"; + if (Tok.isExpandDisabled()) + std::cerr << " [ExpandDisabled]"; if (Tok.needsCleaning()) { const char *Start = SourceMgr.getCharacterData(Tok.getLocation()); std::cerr << " [UnClean='" << std::string(Start, Start+Tok.getLength()) @@ -675,6 +677,11 @@ bool Preprocessor::HandleMacroExpandedIdentifier(LexerToken &Identifier, SourceMgr.getInstantiationLoc(Identifier.getLocation(), InstantiateLoc); Identifier.SetLocation(Loc); + // If this is #define X X, we must mark the result as unexpandible. + if (IdentifierInfo *NewII = Identifier.getIdentifierInfo()) + if (NewII->getMacroInfo() == MI) + Identifier.SetFlag(LexerToken::DisableExpand); + // Since this is not an identifier token, it can't be macro expanded, so // we're done. ++NumFastMacroExpanded; @@ -998,9 +1005,17 @@ void Preprocessor::HandleIdentifier(LexerToken &Identifier) { // If this is a macro to be expanded, do it. if (MacroInfo *MI = II.getMacroInfo()) - if (MI->isEnabled() && !DisableMacroExpansion) - if (!HandleMacroExpandedIdentifier(Identifier, MI)) - return; + if (!DisableMacroExpansion && !Identifier.isExpandDisabled()) { + if (MI->isEnabled()) { + if (!HandleMacroExpandedIdentifier(Identifier, MI)) + return; + } else { + // C99 6.10.3.4p2 says that a disabled macro may never again be + // expanded, even if it's in a context where it could be expanded in the + // future. + Identifier.SetFlag(LexerToken::DisableExpand); + } + } // Change the kind of this identifier to the appropriate token kind, e.g. // turning "for" into a keyword. diff --git a/clang/include/clang/Lex/LexerToken.h b/clang/include/clang/Lex/LexerToken.h index 94793706a0c..1816b9d18a4 100644 --- a/clang/include/clang/Lex/LexerToken.h +++ b/clang/include/clang/Lex/LexerToken.h @@ -47,7 +47,8 @@ public: enum TokenFlags { StartOfLine = 0x01, // At start of line or only after whitespace. LeadingSpace = 0x02, // Whitespace exists before this token. - NeedsCleaning = 0x04 // Contained an escaped newline or trigraph. + DisableExpand = 0x04, // This identifier may never be macro expanded. + NeedsCleaning = 0x08 // Contained an escaped newline or trigraph. }; tok::TokenKind getKind() const { return Kind; } @@ -100,6 +101,10 @@ public: /// bool hasLeadingSpace() const { return Flags & LeadingSpace; } + /// isExpandDisabled - Return true if this identifier token should never + /// be expanded in the future, due to C99 6.10.3.4p2. + bool isExpandDisabled() const { return Flags & DisableExpand; } + /// needsCleaning - Return true if this token has trigraphs or escaped /// newlines in it. /// |