aboutsummaryrefslogtreecommitdiff
path: root/lib/Lex/MacroInfo.cpp
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/MacroInfo.cpp
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/MacroInfo.cpp')
-rw-r--r--lib/Lex/MacroInfo.cpp40
1 files changed, 33 insertions, 7 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();
}