diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-08-03 21:49:18 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-08-03 21:49:18 +0000 |
commit | 6ec60e00eeaaed78d98c85ce962d6f328094ca14 (patch) | |
tree | 8c6aa21eb1c36977660825320495a5f039de62fc | |
parent | f0c1d8f804e7854bedf3f241409185951ee67866 (diff) |
Introduce a local-to-global remapping for identifiers in the AST
reader, and fix up the one (!) place where we were improperly mapping
a local ID to a global ID. Tested via the usual "gaps" trick.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@136817 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Serialization/ASTBitCodes.h | 3 | ||||
-rw-r--r-- | include/clang/Serialization/ASTReader.h | 3 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 59 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 5 |
4 files changed, 52 insertions, 18 deletions
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index 51146f0c99..27dda4fe2a 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -119,6 +119,9 @@ namespace clang { /// \brief An ID number that refers to an identifier in an AST file. typedef uint32_t IdentID; + /// \brief The number of predefined identifier IDs. + const unsigned int NUM_PREDEF_IDENT_IDS = 1; + /// \brief An ID number that refers to a macro in an AST file. typedef uint32_t MacroID; diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index 42843e1ac3..2d1e857f59 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -255,6 +255,9 @@ public: /// \brief Base identifier ID for identifiers local to this module. serialization::IdentID BaseIdentifierID; + /// \brief Remapping table for declaration IDs in this module. + ContinuousRangeMap<uint32_t, int, 2> IdentifierRemap; + /// \brief Actual data for the on-disk hash table of identifiers. /// /// This pointer points into a memory buffer, where the on-disk hash diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 291044f08d..5a564be28a 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -649,19 +649,19 @@ public: const unsigned char* d, unsigned DataLen) { using namespace clang::io; - IdentID ID = Reader.getGlobalSelectorID(F, ReadUnalignedLE32(d)); - bool IsInteresting = ID & 0x01; + unsigned RawID = ReadUnalignedLE32(d); + bool IsInteresting = RawID & 0x01; // Wipe out the "is interesting" bit. - ID = ID >> 1; + RawID = RawID >> 1; + IdentID ID = Reader.getGlobalIdentifierID(F, RawID); if (!IsInteresting) { // For uninteresting identifiers, just build the IdentifierInfo // and associate it with the persistent ID. IdentifierInfo *II = KnownII; if (!II) - II = &Reader.getIdentifierTable().getOwn(StringRef(k.first, - k.second)); + II = &Reader.getIdentifierTable().getOwn(StringRef(k.first, k.second)); Reader.SetIdentifierInfo(ID, II); II->setIsFromAST(); return II; @@ -688,8 +688,7 @@ public: // the new IdentifierInfo. IdentifierInfo *II = KnownII; if (!II) - II = &Reader.getIdentifierTable().getOwn(StringRef(k.first, - k.second)); + II = &Reader.getIdentifierTable().getOwn(StringRef(k.first, k.second)); Reader.SetIdentifierInfo(ID, II); // Set or check the various bits in the IdentifierInfo structure. @@ -2153,22 +2152,34 @@ ASTReader::ReadASTBlock(Module &F) { } break; - case IDENTIFIER_OFFSET: + case IDENTIFIER_OFFSET: { if (F.LocalNumIdentifiers != 0) { Error("duplicate IDENTIFIER_OFFSET record in AST file"); return Failure; } F.IdentifierOffsets = (const uint32_t *)BlobStart; F.LocalNumIdentifiers = Record[0]; + unsigned LocalBaseIdentifierID = Record[1]; F.BaseIdentifierID = getTotalNumIdentifiers(); - // Introduce the global -> local mapping for identifiers within this AST - // file - GlobalIdentifierMap.insert(std::make_pair(getTotalNumIdentifiers() + 1, - &F)); - IdentifiersLoaded.resize(IdentifiersLoaded.size() +F.LocalNumIdentifiers); + if (F.LocalNumIdentifiers > 0) { + // Introduce the global -> local mapping for identifiers within this + // module. + GlobalIdentifierMap.insert(std::make_pair(getTotalNumIdentifiers() + 1, + &F)); + + // Introduce the local -> global mapping for identifiers within this + // module. + F.IdentifierRemap.insert( + std::make_pair(LocalBaseIdentifierID, + F.BaseIdentifierID - LocalBaseIdentifierID)); + + IdentifiersLoaded.resize(IdentifiersLoaded.size() + + F.LocalNumIdentifiers); + } break; - + } + case EXTERNAL_DEFINITIONS: for (unsigned I = 0, N = Record.size(); I != N; ++I) ExternalDefinitions.push_back(getGlobalDeclID(F, Record[I])); @@ -2292,6 +2303,8 @@ ASTReader::ReadASTBlock(Module &F) { // Continuous range maps we may be updating in our module. ContinuousRangeMap<uint32_t, int, 2>::Builder SLocRemap(F.SLocRemap); + ContinuousRangeMap<uint32_t, int, 2>::Builder + IdentifierRemap(F.IdentifierRemap); ContinuousRangeMap<uint32_t, int, 2>::Builder DeclRemap(F.DeclRemap); ContinuousRangeMap<uint32_t, int, 2>::Builder TypeRemap(F.TypeRemap); @@ -2319,7 +2332,9 @@ ASTReader::ReadASTBlock(Module &F) { static_cast<int>(OM->SLocEntryBaseOffset - SLocOffset))); // FIXME: Map other locations - (void)IdentifierIDOffset; + IdentifierRemap.insert( + std::make_pair(IdentifierIDOffset, + OM->BaseIdentifierID - IdentifierIDOffset)); (void)PreprocessedEntityIDOffset; (void)MacroDefinitionIDOffset; (void)SelectorIDOffset; @@ -4824,8 +4839,15 @@ IdentifierInfo *ASTReader::getLocalIdentifier(Module &M, unsigned LocalID) { } IdentifierID ASTReader::getGlobalIdentifierID(Module &M, unsigned LocalID) { - // FIXME: Perform local-to-global remapping - return LocalID; + if (LocalID < NUM_PREDEF_IDENT_IDS) + return LocalID; + + ContinuousRangeMap<uint32_t, int, 2>::iterator I + = M.IdentifierRemap.find(LocalID - NUM_PREDEF_IDENT_IDS); + assert(I != M.IdentifierRemap.end() + && "Invalid index into identifier index remap"); + + return LocalID + I->second; } bool ASTReader::ReadSLocEntry(int ID) { @@ -5556,6 +5578,9 @@ void Module::dump() { llvm::errs() << " Base source location offset: " << SLocEntryBaseOffset << '\n'; dumpLocalRemap("Source location offset map", SLocRemap); + llvm::errs() << " Base identifier ID: " << BaseIdentifierID << '\n' + << "Number of identifiers: " << LocalNumIdentifiers << '\n'; + dumpLocalRemap("Identifier ID map", IdentifierRemap); llvm::errs() << " Base type index: " << BaseTypeIndex << '\n' << " Number of types: " << LocalNumTypes << '\n'; dumpLocalRemap("Type index map", TypeRemap); diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index fe152b1194..ee72f63c16 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -2422,12 +2422,14 @@ void ASTWriter::WriteIdentifierTable(Preprocessor &PP) { BitCodeAbbrev *Abbrev = new BitCodeAbbrev(); Abbrev->Add(BitCodeAbbrevOp(IDENTIFIER_OFFSET)); Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // # of identifiers + Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 32)); // first ID Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); unsigned IdentifierOffsetAbbrev = Stream.EmitAbbrev(Abbrev); RecordData Record; Record.push_back(IDENTIFIER_OFFSET); Record.push_back(IdentifierOffsets.size()); + Record.push_back(FirstIdentID - NUM_PREDEF_IDENT_IDS); Stream.EmitRecordWithBlob(IdentifierOffsetAbbrev, Record, data(IdentifierOffsets)); } @@ -2742,7 +2744,8 @@ ASTWriter::ASTWriter(llvm::BitstreamWriter &Stream) : Stream(Stream), Chain(0), SerializationListener(0), FirstDeclID(NUM_PREDEF_DECL_IDS), NextDeclID(FirstDeclID), FirstTypeID(NUM_PREDEF_TYPE_IDS), NextTypeID(FirstTypeID), - FirstIdentID(1), NextIdentID(FirstIdentID), FirstSelectorID(1), + FirstIdentID(NUM_PREDEF_IDENT_IDS), NextIdentID(FirstIdentID), + FirstSelectorID(1), NextSelectorID(FirstSelectorID), FirstMacroID(1), NextMacroID(FirstMacroID), CollectedStmts(&StmtsToEmit), NumStatements(0), NumMacros(0), NumLexicalDeclContexts(0), |