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 | |
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')
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 135 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 21 |
2 files changed, 80 insertions, 76 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 diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 76eb1a1a8a..98e841cb2b 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -1744,6 +1744,7 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) { AddIdentifierRef(Name, Record); addMacroRef(MI, Record); + Record.push_back(inferSubmoduleIDFromLocation(MI->getDefinitionLoc())); AddSourceLocation(MI->getDefinitionLoc(), Record); AddSourceLocation(MI->getUndefLoc(), Record); Record.push_back(MI->isUsed()); @@ -2587,8 +2588,14 @@ public: if (isInterestingIdentifier(II, Macro)) { DataLen += 2; // 2 bytes for builtin ID DataLen += 2; // 2 bytes for flags - if (hadMacroDefinition(II, Macro)) - DataLen += 8; + if (hadMacroDefinition(II, Macro)) { + for (MacroInfo *M = Macro; M; M = M->getPreviousDefinition()) { + if (Writer.getMacroRef(M) != 0) + DataLen += 4; + } + + DataLen += 4; + } for (IdentifierResolver::iterator D = IdResolver.begin(II), DEnd = IdResolver.end(); @@ -2635,9 +2642,13 @@ public: clang::io::Emit16(Out, Bits); if (HadMacroDefinition) { - clang::io::Emit32(Out, Writer.getMacroRef(Macro)); - clang::io::Emit32(Out, - Writer.inferSubmoduleIDFromLocation(Macro->getDefinitionLoc())); + // Write all of the macro IDs associated with this identifier. + for (MacroInfo *M = Macro; M; M = M->getPreviousDefinition()) { + if (MacroID ID = Writer.getMacroRef(M)) + clang::io::Emit32(Out, ID); + } + + clang::io::Emit32(Out, 0); } // Emit the declaration IDs in reverse order, because the |