зеркало из https://github.com/microsoft/clang-1.git
Extend ObjCInterfaceDecl::DefinitionData to contain a pointer to the
definition, and implement ObjCInterfaceDecl::getDefinition() efficiently based on that. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146669 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
36370f58d8
Коммит
26fec63b14
|
@ -548,6 +548,10 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
|
||||||
friend class ASTContext;
|
friend class ASTContext;
|
||||||
|
|
||||||
struct DefinitionData {
|
struct DefinitionData {
|
||||||
|
/// \brief The definition of this class, for quick access from any
|
||||||
|
/// declaration.
|
||||||
|
ObjCInterfaceDecl *Definition;
|
||||||
|
|
||||||
/// Class's super class.
|
/// Class's super class.
|
||||||
ObjCInterfaceDecl *SuperClass;
|
ObjCInterfaceDecl *SuperClass;
|
||||||
|
|
||||||
|
@ -574,7 +578,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
|
||||||
|
|
||||||
SourceLocation SuperClassLoc; // location of the super class identifier.
|
SourceLocation SuperClassLoc; // location of the super class identifier.
|
||||||
|
|
||||||
DefinitionData() : SuperClass(), CategoryList(), IvarList(),
|
DefinitionData() : Definition(), SuperClass(), CategoryList(), IvarList(),
|
||||||
ExternallyCompleted() { }
|
ExternallyCompleted() { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -585,10 +589,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
|
||||||
|
|
||||||
/// \brief Contains a pointer to the data associated with this class,
|
/// \brief Contains a pointer to the data associated with this class,
|
||||||
/// which will be NULL if this class has not yet been defined.
|
/// which will be NULL if this class has not yet been defined.
|
||||||
///
|
DefinitionData *Data;
|
||||||
/// The boolean value indicates whether this particular declaration is
|
|
||||||
/// also the definition.
|
|
||||||
llvm::PointerIntPair<DefinitionData *, 1, bool> Definition;
|
|
||||||
|
|
||||||
/// \brief The location of the last location in this declaration, e.g.,
|
/// \brief The location of the last location in this declaration, e.g.,
|
||||||
/// the '>', '}', or identifier.
|
/// the '>', '}', or identifier.
|
||||||
|
@ -602,8 +603,8 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
|
||||||
bool InitiallyForwardDecl : 1;
|
bool InitiallyForwardDecl : 1;
|
||||||
|
|
||||||
DefinitionData &data() const {
|
DefinitionData &data() const {
|
||||||
assert(Definition.getPointer() != 0 && "Declaration is not a definition!");
|
assert(Data != 0 && "Declaration has no definition!");
|
||||||
return *Definition.getPointer();
|
return *Data;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Allocate the definition data for this class.
|
/// \brief Allocate the definition data for this class.
|
||||||
|
@ -778,29 +779,30 @@ public:
|
||||||
return InitiallyForwardDecl;
|
return InitiallyForwardDecl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Determine whether this declaration is a forward declaration of
|
/// \brief Determine whether this class has only ever been forward-declared.
|
||||||
/// the class.
|
bool isForwardDecl() const { return Data == 0; }
|
||||||
bool isForwardDecl() const { return !Definition.getInt(); }
|
|
||||||
|
|
||||||
/// \brief Determine whether this particular declaration of this class is
|
/// \brief Determine whether this particular declaration of this class is
|
||||||
/// actually also a definition.
|
/// actually also a definition.
|
||||||
bool isThisDeclarationADefinition() const { return Definition.getInt(); }
|
bool isThisDeclarationADefinition() const {
|
||||||
|
return Data == 0 || Data->Definition != this;
|
||||||
|
}
|
||||||
|
|
||||||
/// \brief Determine whether this class has been defined.
|
/// \brief Determine whether this class has been defined.
|
||||||
bool hasDefinition() const { return Definition.getPointer() != 0; }
|
bool hasDefinition() const { return Data; }
|
||||||
|
|
||||||
/// \brief Retrieve the definition of this class, or NULL if this class
|
/// \brief Retrieve the definition of this class, or NULL if this class
|
||||||
/// has been forward-declared (with @class) but not yet defined (with
|
/// has been forward-declared (with @class) but not yet defined (with
|
||||||
/// @interface).
|
/// @interface).
|
||||||
ObjCInterfaceDecl *getDefinition() {
|
ObjCInterfaceDecl *getDefinition() {
|
||||||
return hasDefinition()? this : 0;
|
return hasDefinition()? Data->Definition : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Retrieve the definition of this class, or NULL if this class
|
/// \brief Retrieve the definition of this class, or NULL if this class
|
||||||
/// has been forward-declared (with @class) but not yet defined (with
|
/// has been forward-declared (with @class) but not yet defined (with
|
||||||
/// @interface).
|
/// @interface).
|
||||||
const ObjCInterfaceDecl *getDefinition() const {
|
const ObjCInterfaceDecl *getDefinition() const {
|
||||||
return hasDefinition()? this : 0;
|
return hasDefinition()? Data->Definition : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Starts the definition of this Objective-C class, taking it from
|
/// \brief Starts the definition of this Objective-C class, taking it from
|
||||||
|
|
|
@ -224,14 +224,14 @@ void ObjCInterfaceDecl::mergeClassExtensionProtocolList(
|
||||||
|
|
||||||
void ObjCInterfaceDecl::allocateDefinitionData() {
|
void ObjCInterfaceDecl::allocateDefinitionData() {
|
||||||
assert(!hasDefinition() && "ObjC class already has a definition");
|
assert(!hasDefinition() && "ObjC class already has a definition");
|
||||||
Definition.setPointer(new (getASTContext()) DefinitionData());
|
Data = new (getASTContext()) DefinitionData();
|
||||||
Definition.setInt(true);
|
Data->Definition = this;
|
||||||
|
|
||||||
// Update all of the declarations with a pointer to the definition.
|
// Update all of the declarations with a pointer to the definition.
|
||||||
for (redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
|
for (redecl_iterator RD = redecls_begin(), RDEnd = redecls_end();
|
||||||
RD != RDEnd; ++RD) {
|
RD != RDEnd; ++RD) {
|
||||||
if (*RD != this)
|
if (*RD != this)
|
||||||
RD->Definition.setPointer(Definition.getPointer());
|
RD->Data = Data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -684,7 +684,7 @@ ObjCInterfaceDecl::
|
||||||
ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
|
ObjCInterfaceDecl(DeclContext *DC, SourceLocation atLoc, IdentifierInfo *Id,
|
||||||
SourceLocation CLoc, bool FD, bool isInternal)
|
SourceLocation CLoc, bool FD, bool isInternal)
|
||||||
: ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, atLoc),
|
: ObjCContainerDecl(ObjCInterface, DC, Id, CLoc, atLoc),
|
||||||
TypeForDecl(0), Definition(), InitiallyForwardDecl(FD)
|
TypeForDecl(0), Data(), InitiallyForwardDecl(FD)
|
||||||
{
|
{
|
||||||
setImplicit(isInternal);
|
setImplicit(isInternal);
|
||||||
}
|
}
|
||||||
|
|
|
@ -613,15 +613,15 @@ void ASTDeclReader::VisitObjCInterfaceDecl(ObjCInterfaceDecl *ID) {
|
||||||
for (ASTReader::ForwardRefs::iterator I = Refs.begin(),
|
for (ASTReader::ForwardRefs::iterator I = Refs.begin(),
|
||||||
E = Refs.end();
|
E = Refs.end();
|
||||||
I != E; ++I)
|
I != E; ++I)
|
||||||
cast<ObjCInterfaceDecl>(*I)->Definition = ID->Definition;
|
cast<ObjCInterfaceDecl>(*I)->Data = ID->Data;
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
// We later check whether PendingForwardRefs is empty to make sure all
|
// We later check whether PendingForwardRefs is empty to make sure all
|
||||||
// pending references were linked.
|
// pending references were linked.
|
||||||
Reader.PendingForwardRefs.erase(ID);
|
Reader.PendingForwardRefs.erase(ID);
|
||||||
#endif
|
#endif
|
||||||
} else if (Def) {
|
} else if (Def) {
|
||||||
if (Def->Definition.getPointer()) {
|
if (Def->Data) {
|
||||||
ID->Definition.setPointer(Def->Definition.getPointer());
|
ID->Data = Def->Data;
|
||||||
} else {
|
} else {
|
||||||
// The definition is still initializing.
|
// The definition is still initializing.
|
||||||
Reader.PendingForwardRefs[Def].push_back(ID);
|
Reader.PendingForwardRefs[Def].push_back(ID);
|
||||||
|
@ -2072,8 +2072,8 @@ void ASTDeclReader::UpdateDecl(Decl *D, ModuleFile &ModuleFile,
|
||||||
ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
|
ObjCInterfaceDecl *ID = cast<ObjCInterfaceDecl>(D);
|
||||||
ObjCInterfaceDecl *Def
|
ObjCInterfaceDecl *Def
|
||||||
= Reader.ReadDeclAs<ObjCInterfaceDecl>(ModuleFile, Record, Idx);
|
= Reader.ReadDeclAs<ObjCInterfaceDecl>(ModuleFile, Record, Idx);
|
||||||
if (Def->Definition.getPointer()) {
|
if (Def->Data) {
|
||||||
ID->Definition.setPointer(Def->Definition.getPointer());
|
ID->Data = Def->Data;
|
||||||
} else {
|
} else {
|
||||||
// The definition is still initializing.
|
// The definition is still initializing.
|
||||||
Reader.PendingForwardRefs[Def].push_back(ID);
|
Reader.PendingForwardRefs[Def].push_back(ID);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче