[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
diff --git a/lib/Lex/MacroInfo.cpp b/lib/Lex/MacroInfo.cpp
index 213e711..dc091f6 100644
--- a/lib/Lex/MacroInfo.cpp
+++ b/lib/Lex/MacroInfo.cpp
@@ -108,14 +108,40 @@
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();
}