diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 12f37e53e9..09e1fdcd63 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -532,6 +532,14 @@ public: /// a precompiled header or module) rather than having been parsed. bool isFromASTFile() const { return FromASTFile; } + /// \brief Retrieve the global declaration ID associated with this + /// declaration, which specifies where in the + unsigned getGlobalID() const { + if (isFromASTFile()) + return *((const unsigned*)this - 1); + return 0; + } + unsigned getIdentifierNamespace() const { return IdentifierNamespace; } diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index f808b962e1..4a704d0c35 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -675,13 +675,6 @@ private: /// \brief Keeps track of the elements added to PendingDeclChains. llvm::SmallSet PendingDeclChainsKnown; - /// \brief Reverse mapping from declarations to their global declaration IDs. - /// - /// FIXME: This data structure is currently only used for ObjCInterfaceDecls - /// and ObjCProtocolDecls to support declaration merging. If we must have - /// this for other declarations, allocate it along with the Decl itself. - llvm::DenseMap DeclToID; - typedef llvm::DenseMap > MergedDeclsMap; diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index 55484188c8..f4e5d43ee6 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -44,7 +44,20 @@ static bool StatSwitch = false; void *Decl::AllocateDeserializedDecl(const ASTContext &Context, unsigned ID, unsigned Size) { - return Context.Allocate(Size); + // Allocate an extra pointer's worth of storage, which ensures that + // (1) We have enough storage to stash the global declaration ID, and + // (2) We maintain pointer alignment. + // + // Note that this wastes 4 bytes on x86-64, which we'll undoubtedly end up + // finding a use for later. + void *Start = Context.Allocate(Size + sizeof(void*)); + void *Result = (char*)Start + sizeof(void*); + + // Store the global declaration ID + unsigned *IDPtr = (unsigned*)Result - 1; + *IDPtr = ID; + + return Result; } const char *Decl::getDeclKindName() const { diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index cff8667f4b..0672129f1e 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -402,9 +402,6 @@ void ASTDeclReader::VisitTypeDecl(TypeDecl *TD) { } void ASTDeclReader::VisitTypedefNameDecl(TypedefNameDecl *TD) { - // Record the declaration -> global ID mapping. - Reader.DeclToID[TD] = ThisDeclID; - RedeclarableResult Redecl = VisitRedeclarable(TD); VisitTypeDecl(TD); @@ -421,9 +418,6 @@ void ASTDeclReader::VisitTypeAliasDecl(TypeAliasDecl *TD) { } void ASTDeclReader::VisitTagDecl(TagDecl *TD) { - // Record the declaration -> global ID mapping. - Reader.DeclToID[TD] = ThisDeclID; - RedeclarableResult Redecl = VisitRedeclarable(TD); VisitTypeDecl(TD); @@ -490,9 +484,6 @@ void ASTDeclReader::VisitDeclaratorDecl(DeclaratorDecl *DD) { } void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) { - // Record the declaration -> global ID mapping. - Reader.DeclToID[FD] = ThisDeclID; - RedeclarableResult Redecl = VisitRedeclarable(FD); VisitDeclaratorDecl(FD); @@ -673,9 +664,6 @@ void ASTDeclReader::VisitObjCContainerDecl(ObjCContainerDecl *CD) { } void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) { - // Record the declaration -> global ID mapping. - Reader.DeclToID[ID] = ThisDeclID; - RedeclarableResult Redecl = VisitRedeclarable(ID); VisitObjCContainerDecl(ID); TypeIDForTypeDecl = Reader.getGlobalTypeID(F, Record[Idx++]); @@ -746,9 +734,6 @@ void ASTDeclReader::VisitObjCIvarDecl(ObjCIvarDecl *IVD) { } void ASTDeclReader::VisitObjCProtocolDecl(ObjCProtocolDecl *PD) { - // Record the declaration -> global ID mapping. - Reader.DeclToID[PD] = ThisDeclID; - RedeclarableResult Redecl = VisitRedeclarable(PD); VisitObjCContainerDecl(PD); mergeRedeclarable(PD, Redecl); @@ -880,9 +865,6 @@ void ASTDeclReader::VisitIndirectFieldDecl(IndirectFieldDecl *FD) { } void ASTDeclReader::VisitVarDecl(VarDecl *VD) { - // Record the declaration -> global ID mapping. - Reader.DeclToID[VD] = ThisDeclID; - RedeclarableResult Redecl = VisitRedeclarable(VD); VisitDeclaratorDecl(VD); @@ -1561,7 +1543,7 @@ void ASTDeclReader::mergeRedeclarable(Redeclarable *D, // Introduce ExistingCanon into the set of pending declaration chains, // if in fact it came from a module file. if (ExistingCanon->isFromASTFile()) { - GlobalDeclID ExistingCanonID = Reader.DeclToID[ExistingCanon]; + GlobalDeclID ExistingCanonID = ExistingCanon->getGlobalID(); assert(ExistingCanonID && "Unrecorded canonical declaration ID?"); if (Reader.PendingDeclChainsKnown.insert(ExistingCanonID)) Reader.PendingDeclChains.push_back(ExistingCanonID); diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 1317525c27..52578599ea 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -2914,7 +2914,7 @@ void ASTWriter::WriteMergedDecls() { for (ASTReader::MergedDeclsMap::iterator I = Chain->MergedDecls.begin(), IEnd = Chain->MergedDecls.end(); I != IEnd; ++I) { - DeclID CanonID = I->first->isFromASTFile()? Chain->DeclToID[I->first] + DeclID CanonID = I->first->isFromASTFile()? I->first->getGlobalID() : getDeclID(I->first); assert(CanonID && "Merged declaration not known?");