diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Lex/PPMacroExpansion.cpp | 18 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 58 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 1 |
3 files changed, 61 insertions, 16 deletions
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index dc3a45652ac..3959671fdaf 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -87,11 +87,13 @@ void Preprocessor::addLoadedMacroInfo(IdentifierInfo *II, MacroInfo *MI, } // Find the end of the definition chain. - MacroInfo *Prev = StoredMI; - MacroInfo *PrevPrev; + MacroInfo *Prev; + MacroInfo *PrevPrev = StoredMI; bool Ambiguous = StoredMI->isAmbiguous(); bool MatchedOther = false; do { + Prev = PrevPrev; + // If the macros are not identical, we have an ambiguity. if (!Prev->isIdenticalTo(*MI, *this)) { if (!Ambiguous) { @@ -125,25 +127,29 @@ void Preprocessor::addLoadedMacroInfo(IdentifierInfo *II, MacroInfo *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); + II->setHasMacroDefinition(MI->isDefined()); 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. + // FIXME: Yes, this is O(N), and making a pile of macros visible or hidden + // would be quadratic, but it's extremely rare. MacroInfo *Prev = StoredMI; while (Prev->getPreviousDefinition() != MI) Prev = Prev->getPreviousDefinition(); Prev->setPreviousDefinition(MI->getPreviousDefinition()); + MI->setPreviousDefinition(0); // Add the macro back to the list. addLoadedMacroInfo(II, MI); + + II->setHasMacroDefinition(StoredMI->isDefined()); + if (II->isFromAST()) + II->setChangedSinceDeserialization(); } /// \brief Undefine a macro for this identifier. diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 8f18eb8465b..d22e85b18fb 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -1364,9 +1364,28 @@ void ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset, MacroUpdatesMap::iterator Update = MacroUpdates.find(GlobalID); if (Update != MacroUpdates.end()) { if (MI->getUndefLoc().isInvalid()) { - MI->setUndefLoc(Update->second.UndefLoc); - if (PPMutationListener *Listener = PP.getPPMutationListener()) - Listener->UndefinedMacro(MI); + for (unsigned I = 0, N = Update->second.size(); I != N; ++I) { + bool Hidden = false; + if (unsigned SubmoduleID = Update->second[I].first) { + if (Module *Owner = getSubmodule(SubmoduleID)) { + if (Owner->NameVisibility == Module::Hidden) { + // Note that this #undef is hidden. + Hidden = true; + + // Record this hiding for later. + HiddenNamesMap[Owner].push_back( + HiddenName(II, MI, Update->second[I].second.UndefLoc)); + } + } + } + + if (!Hidden) { + MI->setUndefLoc(Update->second[I].second.UndefLoc); + if (PPMutationListener *Listener = PP.getPPMutationListener()) + Listener->UndefinedMacro(MI); + break; + } + } } MacroUpdates.erase(Update); } @@ -2517,7 +2536,11 @@ ASTReader::ReadASTBlock(ModuleFile &F) { if (I == N) break; - MacroUpdates[ID].UndefLoc = ReadSourceLocation(F, Record, I); + SourceLocation UndefLoc = ReadSourceLocation(F, Record, I); + SubmoduleID SubmoduleID = getGlobalSubmoduleID(F, Record[I++]);; + MacroUpdate Update; + Update.UndefLoc = UndefLoc; + MacroUpdates[ID].push_back(std::make_pair(SubmoduleID, Update)); } break; } @@ -2619,15 +2642,30 @@ ASTReader::ASTReadResult ASTReader::validateFileEntries(ModuleFile &M) { void ASTReader::makeNamesVisible(const HiddenNames &Names) { for (unsigned I = 0, N = Names.size(); I != N; ++I) { - if (Names[I].isDecl()) { + switch (Names[I].getKind()) { + case HiddenName::Declaration: Names[I].getDecl()->Hidden = false; - continue; + break; + + case HiddenName::MacroVisibility: { + std::pair<IdentifierInfo *, MacroInfo *> Macro = Names[I].getMacro(); + Macro.second->setHidden(!Macro.second->isPublic()); + if (Macro.second->isDefined()) { + PP.makeLoadedMacroInfoVisible(Macro.first, Macro.second); + } + break; } - std::pair<IdentifierInfo *, MacroInfo *> Macro = Names[I].getMacro(); - Macro.second->setHidden(!Macro.second->isPublic()); - if (Macro.second->isDefined()) { - PP.makeLoadedMacroInfoVisible(Macro.first, Macro.second); + case HiddenName::MacroUndef: { + std::pair<IdentifierInfo *, MacroInfo *> Macro = Names[I].getMacro(); + if (Macro.second->isDefined()) { + Macro.second->setUndefLoc(Names[I].getMacroUndefLoc()); + if (PPMutationListener *Listener = PP.getPPMutationListener()) + Listener->UndefinedMacro(Macro.second); + PP.makeLoadedMacroInfoVisible(Macro.first, Macro.second); + } + break; + } } } } diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index 28f78c61810..2fbe4bf6a33 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -3686,6 +3686,7 @@ void ASTWriter::WriteMacroUpdates() { I != E; ++I) { addMacroRef(I->first, Record); AddSourceLocation(I->second.UndefLoc, Record); + Record.push_back(inferSubmoduleIDFromLocation(I->second.UndefLoc)); } Stream.EmitRecord(MACRO_UPDATES, Record); } |