diff options
Diffstat (limited to 'lib/Lex')
-rw-r--r-- | lib/Lex/MacroInfo.cpp | 6 | ||||
-rw-r--r-- | lib/Lex/PPMacroExpansion.cpp | 101 |
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!"); |