diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-10-11 00:46:49 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-10-11 00:46:49 +0000 |
commit | 6c6c54a59a6e7dbe63ff6a9bbab76f6e0c7c8462 (patch) | |
tree | cea015c280d1666e0a42bdb2f208d8829a5f4cc9 /lib/Serialization/ASTReader.cpp | |
parent | 8b03277b0bc18ab73be11b6067474d515fdad271 (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/Serialization/ASTReader.cpp')
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 135 |
1 files changed, 64 insertions, 71 deletions
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 4e6673bedd..6e3eee9533 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -573,31 +573,13 @@ IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k, // If this identifier is a macro, deserialize the macro // definition. if (hadMacroDefinition) { - // FIXME: Check for conflicts? - uint32_t LocalID = ReadUnalignedLE32(d); - unsigned LocalSubmoduleID = ReadUnalignedLE32(d); - - // Determine whether this macro definition should be visible now, or - // whether it is in a hidden submodule. - bool Visible = true; - if (SubmoduleID GlobalSubmoduleID - = Reader.getGlobalSubmoduleID(F, LocalSubmoduleID)) { - if (Module *Owner = Reader.getSubmodule(GlobalSubmoduleID)) { - if (Owner->NameVisibility == Module::Hidden) { - // The owning module is not visible, and this macro definition should - // not be, either. - Visible = false; - - // Note that this macro definition was hidden because its owning - // module is not yet visible. - Reader.HiddenNamesMap[Owner].push_back(II); - } - } + SmallVector<MacroID, 4> MacroIDs; + while (uint32_t LocalID = ReadUnalignedLE32(d)) { + MacroIDs.push_back(Reader.getGlobalMacroID(F, LocalID)); + DataLen -= 4; } - - Reader.setIdentifierIsMacro(II, Reader.getGlobalMacroID(F, LocalID), - Visible && hasMacroDefinition); - DataLen -= 8; + DataLen -= 4; + Reader.setIdentifierIsMacro(II, MacroIDs); } Reader.SetIdentifierInfo(ID, II); @@ -1322,7 +1304,8 @@ void ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset) { if (MacrosLoaded[GlobalID - NUM_PREDEF_MACRO_IDS]) return; - unsigned NextIndex = 2; + SubmoduleID GlobalSubmoduleID = getGlobalSubmoduleID(F, Record[2]); + unsigned NextIndex = 3; SourceLocation Loc = ReadSourceLocation(F, Record, NextIndex); MacroInfo *MI = PP.AllocateMacroInfo(Loc); @@ -1360,6 +1343,7 @@ void ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset) { DeserializationListener->MacroRead(GlobalID, MI); // If an update record marked this as undefined, do so now. + // FIXME: Only if the submodule this update came from is visible? MacroUpdatesMap::iterator Update = MacroUpdates.find(GlobalID); if (Update != MacroUpdates.end()) { if (MI->getUndefLoc().isInvalid()) { @@ -1370,8 +1354,25 @@ void ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset) { MacroUpdates.erase(Update); } + // Determine whether this macro definition is visible. + bool Hidden = !MI->isPublic(); + if (!Hidden && GlobalSubmoduleID) { + if (Module *Owner = getSubmodule(GlobalSubmoduleID)) { + if (Owner->NameVisibility == Module::Hidden) { + // The owning module is not visible, and this macro definition + // should not be, either. + Hidden = true; + + // Note that this macro definition was hidden because its owning + // module is not yet visible. + HiddenNamesMap[Owner].push_back(HiddenName(II, MI)); + } + } + } + MI->setHidden(Hidden); + // Finally, install the macro. - PP.setMacroInfo(II, MI, /*LoadedFromAST=*/true); + PP.addLoadedMacroInfo(II, MI); // Remember that we saw this macro last so that we add the tokens that // form its body to it. @@ -1480,21 +1481,16 @@ HeaderFileInfoTrait::ReadData(const internal_key_type, const unsigned char *d, return HFI; } -void ASTReader::setIdentifierIsMacro(IdentifierInfo *II, MacroID ID, - bool Visible) { - if (Visible) { - // Note that this identifier has a macro definition. - II->setHasMacroDefinition(true); - } else { - II->setHadMacroDefinition(true); - } - - // FIXME: This could end up overwriting a previously recording macro - // definition here, which is not cool at all. - UnreadMacroIDs[II] = ID; +void ASTReader::setIdentifierIsMacro(IdentifierInfo *II, ArrayRef<MacroID> IDs){ + II->setHadMacroDefinition(true); + assert(NumCurrentElementsDeserializing > 0 &&"Missing deserialization guard"); + PendingMacroIDs[II].append(IDs.begin(), IDs.end()); } void ASTReader::ReadDefinedMacros() { + // Note that we are loading defined macros. + Deserializing Macros(this); + for (ModuleReverseIterator I = ModuleMgr.rbegin(), E = ModuleMgr.rend(); I != E; ++I) { llvm::BitstreamCursor &MacroCursor = (*I)->MacroCursor; @@ -1546,24 +1542,14 @@ void ASTReader::ReadDefinedMacros() { } } } - - // Drain the unread macro-record offsets map. - while (!UnreadMacroIDs.empty()) - LoadMacroDefinition(UnreadMacroIDs.begin()); } -void ASTReader::LoadMacroDefinition( - llvm::DenseMap<IdentifierInfo *, MacroID>::iterator Pos) { - assert(Pos != UnreadMacroIDs.end() && "Unknown macro definition"); - uint64_t GlobalID = Pos->second; - UnreadMacroIDs.erase(Pos); - getMacro(GlobalID); -} - -void ASTReader::LoadMacroDefinition(IdentifierInfo *II) { - llvm::DenseMap<IdentifierInfo *, MacroID>::iterator Pos - = UnreadMacroIDs.find(II); - LoadMacroDefinition(Pos); +void ASTReader::LoadMacroDefinition(PendingMacroIDsMap::iterator Pos) { + assert(Pos != PendingMacroIDs.end() && "Unknown macro definition"); + SmallVector<MacroID, 2> GlobalIDs = Pos->second; + PendingMacroIDs.erase(Pos); + for (unsigned I = 0, N = GlobalIDs.size(); I != N; ++I) + getMacro(GlobalIDs[I]); } namespace { @@ -1612,6 +1598,9 @@ namespace { } void ASTReader::updateOutOfDateIdentifier(IdentifierInfo &II) { + // Note that we are loading an identifier. + Deserializing AnIdentifier(this); + unsigned PriorGeneration = 0; if (getContext().getLangOpts().Modules) PriorGeneration = IdentifierGeneration[&II]; @@ -2620,22 +2609,17 @@ ASTReader::ASTReadResult ASTReader::validateFileEntries(ModuleFile &M) { void ASTReader::makeNamesVisible(const HiddenNames &Names) { for (unsigned I = 0, N = Names.size(); I != N; ++I) { - if (Decl *D = Names[I].dyn_cast<Decl *>()) - D->Hidden = false; - else { - IdentifierInfo *II = Names[I].get<IdentifierInfo *>(); - // FIXME: Check if this works correctly with macro history. - if (!II->hasMacroDefinition()) { - // Make sure that this macro hasn't been #undef'd in the mean-time. - llvm::DenseMap<IdentifierInfo*, MacroInfo*>::iterator Known - = PP.Macros.find(II); - if (Known == PP.Macros.end() || - Known->second->getUndefLoc().isInvalid()) { - II->setHasMacroDefinition(true); - if (DeserializationListener) - DeserializationListener->MacroVisible(II); - } - } + if (Names[I].isDecl()) { + Names[I].getDecl()->Hidden = false; + continue; + } + + std::pair<IdentifierInfo *, MacroInfo *> Macro = Names[I].getMacro(); + Macro.second->setHidden(!Macro.second->isPublic()); + if (Macro.second->isDefined()) { + PP.makeLoadedMacroInfoVisible(Macro.first, Macro.second); + if (DeserializationListener) + DeserializationListener->MacroVisible(Macro.first); } } } @@ -5418,6 +5402,9 @@ void ASTReader::InitializeSema(Sema &S) { } IdentifierInfo* ASTReader::get(const char *NameStart, const char *NameEnd) { + // Note that we are loading an identifier. + Deserializing AnIdentifier(this); + IdentifierLookupVisitor Visitor(StringRef(NameStart, NameEnd - NameStart), /*PriorGeneration=*/0); ModuleMgr.visit(IdentifierLookupVisitor::visit, &Visitor); @@ -6516,7 +6503,8 @@ void ASTReader::ReadComments() { } void ASTReader::finishPendingActions() { - while (!PendingIdentifierInfos.empty() || !PendingDeclChains.empty()) { + while (!PendingIdentifierInfos.empty() || !PendingDeclChains.empty() || + !PendingMacroIDs.empty()) { // If any identifiers with corresponding top-level declarations have // been loaded, load those declarations now. while (!PendingIdentifierInfos.empty()) { @@ -6531,6 +6519,11 @@ void ASTReader::finishPendingActions() { PendingDeclChainsKnown.erase(PendingDeclChains[I]); } PendingDeclChains.clear(); + + // Load any pending macro definitions. + // FIXME: Non-determinism here. + while (!PendingMacroIDs.empty()) + LoadMacroDefinition(PendingMacroIDs.begin()); } // If we deserialized any C++ or Objective-C class definitions, any |