aboutsummaryrefslogtreecommitdiff
path: root/lib/Lex
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-03-26 17:17:01 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-03-26 17:17:01 +0000
commitc56fff7fd231aebf4b152f60f8f11ef91835c48a (patch)
tree22119f54c12ae692e50e7ed4930160f950e37f2f /lib/Lex
parent1232e279b4a0d98885b9672d3bb5905488360e49 (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.cpp40
-rw-r--r--lib/Lex/PPDirectives.cpp70
-rw-r--r--lib/Lex/PPExpressions.cpp2
-rw-r--r--lib/Lex/PPMacroExpansion.cpp120
-rw-r--r--lib/Lex/Pragma.cpp13
-rw-r--r--lib/Lex/PreprocessingRecord.cpp15
-rw-r--r--lib/Lex/Preprocessor.cpp14
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))