diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2013-03-26 17:17:01 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2013-03-26 17:17:01 +0000 |
commit | c56fff7fd231aebf4b152f60f8f11ef91835c48a (patch) | |
tree | 22119f54c12ae692e50e7ed4930160f950e37f2f /lib/Lex | |
parent | 1232e279b4a0d98885b9672d3bb5905488360e49 (diff) |
[Preprocessor/Modules] Separate the macro directives kinds into their own MacroDirective's subclasses.
For each macro directive (define, undefine, visibility) have a separate object that gets chained
to the macro directive history. This has several benefits:
-No need to mutate a MacroDirective when there is a undefine/visibility directive. Stuff like
PPMutationListener become unnecessary.
-No need to keep extra source locations for the undef/visibility locations for the define directive object
(which is the majority of the directives)
-Much easier to hide/unhide a section in the macro directive history.
-Easier to track the effects of the directives across different submodules.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178037 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Lex')
-rw-r--r-- | lib/Lex/MacroInfo.cpp | 40 | ||||
-rw-r--r-- | lib/Lex/PPDirectives.cpp | 70 | ||||
-rw-r--r-- | lib/Lex/PPExpressions.cpp | 2 | ||||
-rw-r--r-- | lib/Lex/PPMacroExpansion.cpp | 120 | ||||
-rw-r--r-- | lib/Lex/Pragma.cpp | 13 | ||||
-rw-r--r-- | lib/Lex/PreprocessingRecord.cpp | 15 | ||||
-rw-r--r-- | lib/Lex/Preprocessor.cpp | 14 |
7 files changed, 94 insertions, 180 deletions
diff --git a/lib/Lex/MacroInfo.cpp b/lib/Lex/MacroInfo.cpp index 213e71132b..dc091f625b 100644 --- a/lib/Lex/MacroInfo.cpp +++ b/lib/Lex/MacroInfo.cpp @@ -108,14 +108,40 @@ bool MacroInfo::isIdenticalTo(const MacroInfo &Other, Preprocessor &PP) const { return true; } -const MacroDirective * +MacroDirective::DefInfo MacroDirective::getDefinition(bool AllowHidden) { + MacroDirective *MD = this; + SourceLocation UndefLoc; + Optional<bool> isPublic; + for (; MD; MD = MD->getPrevious()) { + if (!AllowHidden && MD->isHidden()) + continue; + + if (DefMacroDirective *DefMD = dyn_cast<DefMacroDirective>(MD)) + return DefInfo(DefMD, UndefLoc, + !isPublic.hasValue() || isPublic.getValue()); + + if (UndefMacroDirective *UndefMD = dyn_cast<UndefMacroDirective>(MD)) { + UndefLoc = UndefMD->getLocation(); + continue; + } + + VisibilityMacroDirective *VisMD = cast<VisibilityMacroDirective>(MD); + if (!isPublic.hasValue()) + isPublic = VisMD->isPublic(); + } + + return DefInfo(); +} + +const MacroDirective::DefInfo MacroDirective::findDirectiveAtLoc(SourceLocation L, SourceManager &SM) const { assert(L.isValid() && "SourceLocation is invalid."); - for (const MacroDirective *MD = this; MD; MD = MD->Previous) { - if (MD->getLocation().isInvalid() || // For macros defined on the command line. - SM.isBeforeInTranslationUnit(MD->getLocation(), L)) - return (MD->UndefLocation.isInvalid() || - SM.isBeforeInTranslationUnit(L, MD->UndefLocation)) ? MD : NULL; + for (DefInfo Def = getDefinition(); Def; Def = Def.getPreviousDefinition()) { + if (Def.getLocation().isInvalid() || // For macros defined on the command line. + SM.isBeforeInTranslationUnit(Def.getLocation(), L)) + return (!Def.isUndefined() || + SM.isBeforeInTranslationUnit(L, Def.getUndefLocation())) + ? Def : DefInfo(); } - return NULL; + return DefInfo(); } diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp index 7020da3940..3fc19e41f8 100644 --- a/lib/Lex/PPDirectives.cpp +++ b/lib/Lex/PPDirectives.cpp @@ -70,11 +70,26 @@ MacroInfo *Preprocessor::AllocateDeserializedMacroInfo(SourceLocation L, return MI; } -MacroDirective *Preprocessor::AllocateMacroDirective(MacroInfo *MI, - SourceLocation Loc, - bool isImported) { - MacroDirective *MD = BP.Allocate<MacroDirective>(); - new (MD) MacroDirective(MI, Loc, isImported); +DefMacroDirective * +Preprocessor::AllocateDefMacroDirective(MacroInfo *MI, SourceLocation Loc, + bool isImported) { + DefMacroDirective *MD = BP.Allocate<DefMacroDirective>(); + new (MD) DefMacroDirective(MI, Loc, isImported); + return MD; +} + +UndefMacroDirective * +Preprocessor::AllocateUndefMacroDirective(SourceLocation UndefLoc) { + UndefMacroDirective *MD = BP.Allocate<UndefMacroDirective>(); + new (MD) UndefMacroDirective(UndefLoc); + return MD; +} + +VisibilityMacroDirective * +Preprocessor::AllocateVisibilityMacroDirective(SourceLocation Loc, + bool isPublic) { + VisibilityMacroDirective *MD = BP.Allocate<VisibilityMacroDirective>(); + new (MD) VisibilityMacroDirective(Loc, isPublic); return MD; } @@ -1130,15 +1145,8 @@ void Preprocessor::HandleMacroPublicDirective(Token &Tok) { } // Note that this macro has now been exported. - MD->setVisibility(/*IsPublic=*/true, MacroNameTok.getLocation()); - - // If this macro directive came from a PCH file, mark it as having changed - // since serialization. - if (MD->isFromPCH()) { - MD->setChangedAfterLoad(); - assert(II->isFromAST()); - II->setChangedSinceDeserialization(); - } + appendMacroDirective(II, AllocateVisibilityMacroDirective( + MacroNameTok.getLocation(), /*IsPublic=*/true)); } /// \brief Handle a #private directive. @@ -1164,15 +1172,8 @@ void Preprocessor::HandleMacroPrivateDirective(Token &Tok) { } // Note that this macro has now been marked private. - MD->setVisibility(/*IsPublic=*/false, MacroNameTok.getLocation()); - - // If this macro directive came from a PCH file, mark it as having changed - // since serialization. - if (MD->isFromPCH()) { - MD->setChangedAfterLoad(); - assert(II->isFromAST()); - II->setChangedSinceDeserialization(); - } + appendMacroDirective(II, AllocateVisibilityMacroDirective( + MacroNameTok.getLocation(), /*IsPublic=*/false)); } //===----------------------------------------------------------------------===// @@ -1960,7 +1961,8 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok) { WarnUnusedMacroLocs.erase(OtherMI->getDefinitionLoc()); } - MacroDirective *MD = setMacroDirective(MacroNameTok.getIdentifierInfo(), MI); + DefMacroDirective *MD = + appendDefMacroDirective(MacroNameTok.getIdentifierInfo(), MI); assert(!MI->isUsed()); // If we need warning for not using the macro, add its location in the @@ -1994,7 +1996,7 @@ void Preprocessor::HandleUndefDirective(Token &UndefTok) { // Okay, we finally have a valid identifier to undef. MacroDirective *MD = getMacroDirective(MacroNameTok.getIdentifierInfo()); - const MacroInfo *MI = MD ? MD->getInfo() : 0; + const MacroInfo *MI = MD ? MD->getMacroInfo() : 0; // If the callbacks want to know, tell them about the macro #undef. // Note: no matter if the macro was defined or not. @@ -2010,20 +2012,8 @@ void Preprocessor::HandleUndefDirective(Token &UndefTok) { if (MI->isWarnIfUnused()) WarnUnusedMacroLocs.erase(MI->getDefinitionLoc()); - UndefineMacro(MacroNameTok.getIdentifierInfo(), MD, - MacroNameTok.getLocation()); -} - -void Preprocessor::UndefineMacro(IdentifierInfo *II, MacroDirective *MD, - SourceLocation UndefLoc) { - MD->setUndefLoc(UndefLoc); - if (MD->isFromPCH()) { - MD->setChangedAfterLoad(); - if (Listener) - Listener->UndefinedMacro(MD); - } - - clearMacroInfo(II); + appendMacroDirective(MacroNameTok.getIdentifierInfo(), + AllocateUndefMacroDirective(MacroNameTok.getLocation())); } @@ -2058,7 +2048,7 @@ void Preprocessor::HandleIfdefDirective(Token &Result, bool isIfndef, IdentifierInfo *MII = MacroNameTok.getIdentifierInfo(); MacroDirective *MD = getMacroDirective(MII); - MacroInfo *MI = MD ? MD->getInfo() : 0; + MacroInfo *MI = MD ? MD->getMacroInfo() : 0; if (CurPPLexer->getConditionalStackDepth() == 0) { // If the start of a top-level #ifdef and if the macro is not defined, diff --git a/lib/Lex/PPExpressions.cpp b/lib/Lex/PPExpressions.cpp index 27ad7b4a1b..d9ce8bff23 100644 --- a/lib/Lex/PPExpressions.cpp +++ b/lib/Lex/PPExpressions.cpp @@ -116,7 +116,7 @@ static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT, // If there is a macro, mark it used. if (Result.Val != 0 && ValueLive) { Macro = PP.getMacroDirective(II); - PP.markMacroAsUsed(Macro->getInfo()); + PP.markMacroAsUsed(Macro->getMacroInfo()); } // Invoke the 'defined' callback. diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp index 868820b400..bb2634ffb6 100644 --- a/lib/Lex/PPMacroExpansion.cpp +++ b/lib/Lex/PPMacroExpansion.cpp @@ -41,15 +41,17 @@ Preprocessor::getMacroDirectiveHistory(const IdentifierInfo *II) const { return Pos->second; } -/// \brief Specify a macro for this identifier. -void Preprocessor::setMacroDirective(IdentifierInfo *II, MacroDirective *MD) { +void Preprocessor::appendMacroDirective(IdentifierInfo *II, MacroDirective *MD){ assert(MD && "MacroDirective should be non-zero!"); + assert(!MD->getPrevious() && "Already attached to a MacroDirective history."); MacroDirective *&StoredMD = Macros[II]; MD->setPrevious(StoredMD); StoredMD = MD; - II->setHasMacroDefinition(true); - if (II->isFromAST()) + II->setHasMacroDefinition(MD->isDefined()); + bool isImportedMacro = isa<DefMacroDirective>(MD) && + cast<DefMacroDirective>(MD)->isImported(); + if (II->isFromAST() && !isImportedMacro) II->setChangedSinceDeserialization(); } @@ -66,112 +68,6 @@ void Preprocessor::setLoadedMacroDirective(IdentifierInfo *II, II->setHasMacroDefinition(false); } -void Preprocessor::addLoadedMacroInfo(IdentifierInfo *II, MacroDirective *MD, - MacroDirective *Hint) { - assert(MD && "Missing macro?"); - assert(MD->isImported() && "Macro is not from an AST?"); - assert(!MD->getPrevious() && "Macro already in chain?"); - - MacroDirective *&StoredMD = Macros[II]; - - // Easy case: this is the first macro definition for this macro. - if (!StoredMD) { - StoredMD = MD; - - if (MD->isDefined()) - II->setHasMacroDefinition(true); - return; - } - - // If this macro is a definition and this identifier has been neither - // defined nor undef'd in the current translation unit, add this macro - // to the end of the chain of definitions. - if (MD->isDefined() && StoredMD->isImported()) { - // Simple case: if this is the first actual definition, just put it at - // th beginning. - if (!StoredMD->isDefined()) { - MD->setPrevious(StoredMD); - StoredMD = MD; - - II->setHasMacroDefinition(true); - return; - } - - // Find the end of the definition chain. - MacroDirective *Prev; - MacroDirective *PrevPrev = StoredMD; - bool Ambiguous = StoredMD->isAmbiguous(); - bool MatchedOther = false; - do { - Prev = PrevPrev; - - // If the macros are not identical, we have an ambiguity. - if (!Prev->getInfo()->isIdenticalTo(*MD->getInfo(), *this)) { - if (!Ambiguous) { - Ambiguous = true; - StoredMD->setAmbiguous(true); - } - } else { - MatchedOther = true; - } - } while ((PrevPrev = Prev->getPrevious()) && - PrevPrev->isDefined()); - - // If there are ambiguous definitions, and we didn't match any other - // definition, then mark us as ambiguous. - if (Ambiguous && !MatchedOther) - MD->setAmbiguous(true); - - // Wire this macro information into the chain. - MD->setPrevious(Prev->getPrevious()); - Prev->setPrevious(MD); - return; - } - - // The macro is not a definition; put it at the end of the list. - MacroDirective *Prev = Hint? Hint : StoredMD; - while (Prev->getPrevious()) - Prev = Prev->getPrevious(); - Prev->setPrevious(MD); -} - -void Preprocessor::makeLoadedMacroInfoVisible(IdentifierInfo *II, - MacroDirective *MD) { - assert(MD->isImported() && "Macro must be from the AST"); - - MacroDirective *&StoredMD = Macros[II]; - if (StoredMD == MD) { - // Easy case: this is the first macro anyway. - II->setHasMacroDefinition(MD->isDefined()); - return; - } - - // Go find the macro and pull it out of the list. - // FIXME: Yes, this is O(N), and making a pile of macros visible or hidden - // would be quadratic, but it's extremely rare. - MacroDirective *Prev = StoredMD; - while (Prev->getPrevious() != MD) - Prev = Prev->getPrevious(); - Prev->setPrevious(MD->getPrevious()); - MD->setPrevious(0); - - // Add the macro back to the list. - addLoadedMacroInfo(II, MD); - - II->setHasMacroDefinition(StoredMD->isDefined()); - if (II->isFromAST()) - II->setChangedSinceDeserialization(); -} - -/// \brief Undefine a macro for this identifier. -void Preprocessor::clearMacroInfo(IdentifierInfo *II) { - assert(II->hasMacroDefinition() && "Macro is not defined!"); - assert(Macros[II]->getUndefLoc().isValid() && "Macro is still defined!"); - II->setHasMacroDefinition(false); - if (II->isFromAST()) - II->setChangedSinceDeserialization(); -} - /// RegisterBuiltinMacro - Register the specified identifier in the identifier /// table and mark it as a builtin macro to be expanded. static IdentifierInfo *RegisterBuiltinMacro(Preprocessor &PP, const char *Name){ @@ -181,7 +77,7 @@ static IdentifierInfo *RegisterBuiltinMacro(Preprocessor &PP, const char *Name){ // Mark it as being a macro that is builtin. MacroInfo *MI = PP.AllocateMacroInfo(SourceLocation()); MI->setIsBuiltinMacro(); - PP.setMacroDirective(Id, MI); + PP.appendDefMacroDirective(Id, MI); return Id; } @@ -315,7 +211,7 @@ bool Preprocessor::isNextPPTokenLParen() { /// expanded as a macro, handle it and return the next token as 'Identifier'. bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier, MacroDirective *MD) { - MacroInfo *MI = MD->getInfo(); + MacroInfo *MI = MD->getMacroInfo(); // If this is a macro expansion in the "#if !defined(x)" line for the file, // then the macro could expand to different things in other contexts, we need diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp index 2094dd1e1c..95e8a8ca8f 100644 --- a/lib/Lex/Pragma.cpp +++ b/lib/Lex/Pragma.cpp @@ -703,9 +703,10 @@ void Preprocessor::HandlePragmaPopMacro(Token &PopMacroTok) { if (iter != PragmaPushMacroInfo.end()) { // Forget the MacroInfo currently associated with IdentInfo. if (MacroDirective *CurrentMD = getMacroDirective(IdentInfo)) { - if (CurrentMD->getInfo()->isWarnIfUnused()) - WarnUnusedMacroLocs.erase(CurrentMD->getInfo()->getDefinitionLoc()); - UndefineMacro(IdentInfo, CurrentMD, MessageLoc); + MacroInfo *MI = CurrentMD->getMacroInfo(); + if (MI->isWarnIfUnused()) + WarnUnusedMacroLocs.erase(MI->getDefinitionLoc()); + appendMacroDirective(IdentInfo, AllocateUndefMacroDirective(MessageLoc)); } // Get the MacroInfo we want to reinstall. @@ -713,10 +714,8 @@ void Preprocessor::HandlePragmaPopMacro(Token &PopMacroTok) { if (MacroToReInstall) { // Reinstall the previously pushed macro. - setMacroDirective(IdentInfo, MacroToReInstall, MessageLoc, - /*isImported=*/false); - } else if (IdentInfo->hasMacroDefinition()) { - clearMacroInfo(IdentInfo); + appendDefMacroDirective(IdentInfo, MacroToReInstall, MessageLoc, + /*isImported=*/false); } // Pop PragmaPushMacroInfo stack. diff --git a/lib/Lex/PreprocessingRecord.cpp b/lib/Lex/PreprocessingRecord.cpp index b834d6cfb8..b10e7f7bee 100644 --- a/lib/Lex/PreprocessingRecord.cpp +++ b/lib/Lex/PreprocessingRecord.cpp @@ -385,31 +385,34 @@ void PreprocessingRecord::Ifdef(SourceLocation Loc, const Token &MacroNameTok, const MacroDirective *MD) { // This is not actually a macro expansion but record it as a macro reference. if (MD) - addMacroExpansion(MacroNameTok, MD->getInfo(), MacroNameTok.getLocation()); + addMacroExpansion(MacroNameTok, MD->getMacroInfo(), + MacroNameTok.getLocation()); } void PreprocessingRecord::Ifndef(SourceLocation Loc, const Token &MacroNameTok, const MacroDirective *MD) { // This is not actually a macro expansion but record it as a macro reference. if (MD) - addMacroExpansion(MacroNameTok, MD->getInfo(), MacroNameTok.getLocation()); + addMacroExpansion(MacroNameTok, MD->getMacroInfo(), + MacroNameTok.getLocation()); } void PreprocessingRecord::Defined(const Token &MacroNameTok, const MacroDirective *MD) { // This is not actually a macro expansion but record it as a macro reference. if (MD) - addMacroExpansion(MacroNameTok, MD->getInfo(), MacroNameTok.getLocation()); + addMacroExpansion(MacroNameTok, MD->getMacroInfo(), + MacroNameTok.getLocation()); } void PreprocessingRecord::MacroExpands(const Token &Id,const MacroDirective *MD, SourceRange Range) { - addMacroExpansion(Id, MD->getInfo(), Range); + addMacroExpansion(Id, MD->getMacroInfo(), Range); } void PreprocessingRecord::MacroDefined(const Token &Id, const MacroDirective *MD) { - const MacroInfo *MI = MD->getInfo(); + const MacroInfo *MI = MD->getMacroInfo(); SourceRange R(MI->getDefinitionLoc(), MI->getDefinitionEndLoc()); MacroDefinition *Def = new (*this) MacroDefinition(Id.getIdentifierInfo(), R); @@ -421,7 +424,7 @@ void PreprocessingRecord::MacroUndefined(const Token &Id, const MacroDirective *MD) { // Note: MI may be null (when #undef'ining an undefined macro). if (MD) - MacroDefinitions.erase(MD->getInfo()); + MacroDefinitions.erase(MD->getMacroInfo()); } void PreprocessingRecord::InclusionDirective( diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp index af000ec1d1..bda72be555 100644 --- a/lib/Lex/Preprocessor.cpp +++ b/lib/Lex/Preprocessor.cpp @@ -306,15 +306,15 @@ StringRef Preprocessor::getLastMacroWithSpelling( StringRef BestSpelling; for (Preprocessor::macro_iterator I = macro_begin(), E = macro_end(); I != E; ++I) { - if (!I->second->getInfo()->isObjectLike()) + if (!I->second->getMacroInfo()->isObjectLike()) continue; - const MacroDirective * - MD = I->second->findDirectiveAtLoc(Loc, SourceMgr); - if (!MD) + const MacroDirective::DefInfo + Def = I->second->findDirectiveAtLoc(Loc, SourceMgr); + if (!Def) continue; - if (!MacroDefinitionEquals(MD->getInfo(), Tokens)) + if (!MacroDefinitionEquals(Def.getMacroInfo(), Tokens)) continue; - SourceLocation Location = I->second->getInfo()->getDefinitionLoc(); + SourceLocation Location = Def.getLocation(); // Choose the macro defined latest. if (BestLocation.isInvalid() || (Location.isValid() && @@ -643,7 +643,7 @@ void Preprocessor::HandleIdentifier(Token &Identifier) { // If this is a macro to be expanded, do it. if (MacroDirective *MD = getMacroDirective(&II)) { - MacroInfo *MI = MD->getInfo(); + MacroInfo *MI = MD->getMacroInfo(); if (!DisableMacroExpansion) { if (!Identifier.isExpandDisabled() && MI->isEnabled()) { if (!HandleMacroExpandedIdentifier(Identifier, MD)) |