summaryrefslogtreecommitdiffstats
path: root/clang/lib/Lex/PPMacroExpansion.cpp
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
commit5a4649b034dd247a8e47792e4026036576ab7863 (patch)
tree8ab1c702997a85a6d960254300e625fb53d8bfbd /clang/lib/Lex/PPMacroExpansion.cpp
parent45df60c1f3289dd3061f613644815f745b76cce6 (diff)
downloadbcm5719-llvm-5a4649b034dd247a8e47792e4026036576ab7863.tar.gz
bcm5719-llvm-5a4649b034dd247a8e47792e4026036576ab7863.zip
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. llvm-svn: 165682
Diffstat (limited to 'clang/lib/Lex/PPMacroExpansion.cpp')
-rw-r--r--clang/lib/Lex/PPMacroExpansion.cpp101
1 files changed, 89 insertions, 12 deletions
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index 1ef534daa76..013178c5550 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/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!");
OpenPOWER on IntegriCloud