/// 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;
}
/// \brief Keeps track of the elements added to PendingDeclChains.
llvm::SmallSet<serialization::DeclID, 16> 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<Decl *, serialization::GlobalDeclID> DeclToID;
-
typedef llvm::DenseMap<Decl *, llvm::SmallVector<serialization::DeclID, 2> >
MergedDeclsMap;
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 {
}
void ASTDeclReader::VisitTypedefNameDecl(TypedefNameDecl *TD) {
- // Record the declaration -> global ID mapping.
- Reader.DeclToID[TD] = ThisDeclID;
-
RedeclarableResult Redecl = VisitRedeclarable(TD);
VisitTypeDecl(TD);
}
void ASTDeclReader::VisitTagDecl(TagDecl *TD) {
- // Record the declaration -> global ID mapping.
- Reader.DeclToID[TD] = ThisDeclID;
-
RedeclarableResult Redecl = VisitRedeclarable(TD);
VisitTypeDecl(TD);
}
void ASTDeclReader::VisitFunctionDecl(FunctionDecl *FD) {
- // Record the declaration -> global ID mapping.
- Reader.DeclToID[FD] = ThisDeclID;
-
RedeclarableResult Redecl = VisitRedeclarable(FD);
VisitDeclaratorDecl(FD);
}
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++]);
}
void ASTDeclReader::VisitObjCProtocolDecl(ObjCProtocolDecl *PD) {
- // Record the declaration -> global ID mapping.
- Reader.DeclToID[PD] = ThisDeclID;
-
RedeclarableResult Redecl = VisitRedeclarable(PD);
VisitObjCContainerDecl(PD);
mergeRedeclarable(PD, Redecl);
}
void ASTDeclReader::VisitVarDecl(VarDecl *VD) {
- // Record the declaration -> global ID mapping.
- Reader.DeclToID[VD] = ThisDeclID;
-
RedeclarableResult Redecl = VisitRedeclarable(VD);
VisitDeclaratorDecl(VD);
// 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);