diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Lex/MacroInfo.cpp | 6 | ||||
-rw-r--r-- | lib/Lex/PPMacroExpansion.cpp | 101 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 135 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 21 |
4 files changed, 173 insertions, 90 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!"); 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 |