aboutsummaryrefslogtreecommitdiff
path: root/lib/Lex
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2012-10-11 00:46:49 +0000
committerDouglas Gregor <dgregor@apple.com>2012-10-11 00:46:49 +0000
commit6c6c54a59a6e7dbe63ff6a9bbab76f6e0c7c8462 (patch)
treecea015c280d1666e0a42bdb2f208d8829a5f4cc9 /lib/Lex
parent8b03277b0bc18ab73be11b6067474d515fdad271 (diff)
Deserialize macro history when we deserialize an identifier that has
macro history. When deserializing macro history, we arrange history such that the macros that have definitions (that haven't been #undef'd) and are visible come at the beginning of the list, which is what the preprocessor and other clients of Preprocessor::getMacroInfo() expect. If additional macro definitions become visible later, they'll be moved toward the front of the list. Note that it's possible to have ambiguities, but we don't diagnose them yet. There is a partially-implemented design decision here that, if a particular identifier has been defined or #undef'd within the translation unit, that definition (or #undef) hides any macro definitions that come from imported modules. There's still a little work to do to ensure that the right #undef'ing happens. Additionally, we'll need to scope the update records for #undefs, so they only kick in when the submodule containing that update record becomes visible. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@165682 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Lex')
-rw-r--r--lib/Lex/MacroInfo.cpp6
-rw-r--r--lib/Lex/PPMacroExpansion.cpp101
2 files changed, 93 insertions, 14 deletions
diff --git a/lib/Lex/MacroInfo.cpp b/lib/Lex/MacroInfo.cpp
index ffe31f24d3..7e538fabf4 100644
--- a/lib/Lex/MacroInfo.cpp
+++ b/lib/Lex/MacroInfo.cpp
@@ -31,7 +31,8 @@ MacroInfo::MacroInfo(SourceLocation DefLoc)
IsUsed(false),
IsAllowRedefinitionsWithoutWarning(false),
IsWarnIfUnused(false),
- IsPublic(true) {
+ IsPublic(true),
+ IsHidden(false) {
}
MacroInfo::MacroInfo(const MacroInfo &MI, llvm::BumpPtrAllocator &PPAllocator)
@@ -54,7 +55,8 @@ MacroInfo::MacroInfo(const MacroInfo &MI, llvm::BumpPtrAllocator &PPAllocator)
IsUsed(MI.IsUsed),
IsAllowRedefinitionsWithoutWarning(MI.IsAllowRedefinitionsWithoutWarning),
IsWarnIfUnused(MI.IsWarnIfUnused),
- IsPublic(MI.IsPublic) {
+ IsPublic(MI.IsPublic),
+ IsHidden(MI.IsHidden) {
setArgumentList(MI.ArgumentList, MI.NumArguments, PPAllocator);
}
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index 1ef534daa7..013178c555 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -36,29 +36,106 @@ MacroInfo *Preprocessor::getMacroInfoHistory(IdentifierInfo *II) const {
assert(II->hadMacroDefinition() && "Identifier has not been not a macro!");
macro_iterator Pos = Macros.find(II);
- if (Pos == Macros.end()) {
- // Load this macro from the external source.
- getExternalSource()->LoadMacroDefinition(II);
- Pos = Macros.find(II);
- }
assert(Pos != Macros.end() && "Identifier macro info is missing!");
return Pos->second;
}
/// setMacroInfo - Specify a macro for this identifier.
///
-void Preprocessor::setMacroInfo(IdentifierInfo *II, MacroInfo *MI,
- bool LoadedFromAST) {
+void Preprocessor::setMacroInfo(IdentifierInfo *II, MacroInfo *MI) {
assert(MI && "MacroInfo should be non-zero!");
- assert((LoadedFromAST || MI->getUndefLoc().isInvalid()) &&
- "Undefined macros can only be registered when just LoadedFromAST");
- MI->setPreviousDefinition(Macros[II]);
- Macros[II] = MI;
+ assert(MI->getUndefLoc().isInvalid() &&
+ "Undefined macros cannot be registered");
+
+ MacroInfo *&StoredMI = Macros[II];
+ MI->setPreviousDefinition(StoredMI);
+ StoredMI = MI;
II->setHasMacroDefinition(MI->getUndefLoc().isInvalid());
- if (II->isFromAST() && !LoadedFromAST)
+ if (II->isFromAST())
II->setChangedSinceDeserialization();
}
+void Preprocessor::addLoadedMacroInfo(IdentifierInfo *II, MacroInfo *MI) {
+ assert(MI && "Missing macro?");
+ assert(MI->isFromAST() && "Macro is not from an AST?");
+ assert(!MI->getPreviousDefinition() && "Macro already in chain?");
+
+ MacroInfo *&StoredMI = Macros[II];
+
+ // Easy case: this is the first macro definition for this macro.
+ if (!StoredMI) {
+ StoredMI = MI;
+
+ if (MI->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 (MI->isDefined() && StoredMI->isFromAST()) {
+ // Simple case: if this is the first actual definition, just put it at
+ // th beginning.
+ if (!StoredMI->isDefined()) {
+ MI->setPreviousDefinition(StoredMI);
+ StoredMI = MI;
+
+ II->setHasMacroDefinition(true);
+ return;
+ }
+
+ // Find the end of the definition chain.
+ MacroInfo *Prev = StoredMI;
+ MacroInfo *PrevPrev;
+ bool Ambiguous = false;
+ do {
+ // If the macros are not identical, we have an ambiguity.
+ if (!Prev->isIdenticalTo(*MI, *this))
+ Ambiguous = true;
+ } while ((PrevPrev = Prev->getPreviousDefinition()) &&
+ PrevPrev->isDefined());
+
+ // FIXME: Actually use the ambiguity information for something.
+
+ // Wire this macro information into the chain.
+ MI->setPreviousDefinition(Prev->getPreviousDefinition());
+ Prev->setPreviousDefinition(MI);
+ return;
+ }
+
+ // The macro is not a definition; put it at the end of the list.
+ // FIXME: Adding macro history is quadratic, but a hint could fix this.
+ MacroInfo *Prev = StoredMI;
+ while (Prev->getPreviousDefinition())
+ Prev = Prev->getPreviousDefinition();
+ Prev->setPreviousDefinition(MI);
+}
+
+void Preprocessor::makeLoadedMacroInfoVisible(IdentifierInfo *II,
+ MacroInfo *MI) {
+ assert(MI->isFromAST() && "Macro must be from the AST");
+ assert(MI->isDefined() && "Macro is not visible");
+
+ MacroInfo *&StoredMI = Macros[II];
+ if (StoredMI == MI) {
+ // Easy case: this is the first macro anyway.
+ II->setHasMacroDefinition(true);
+ 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 would be
+ // quadratic.
+ MacroInfo *Prev = StoredMI;
+ while (Prev->getPreviousDefinition() != MI)
+ Prev = Prev->getPreviousDefinition();
+ Prev->setPreviousDefinition(MI->getPreviousDefinition());
+
+ // Add the macro back to the list.
+ addLoadedMacroInfo(II, MI);
+}
+
/// \brief Undefine a macro for this identifier.
void Preprocessor::clearMacroInfo(IdentifierInfo *II) {
assert(II->hasMacroDefinition() && "Macro is not defined!");