mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-27 15:41:46 +00:00
Avoid allocating extra memory to handle the lazy definition data pointer for
CXXRecordDecls when modules is enabled. llvm-svn: 209482
This commit is contained in:
parent
276d7a1434
commit
64c0630585
@ -257,10 +257,31 @@ public:
|
||||
TypeSourceInfo *getTypeSourceInfo() const { return BaseTypeInfo; }
|
||||
};
|
||||
|
||||
/// \brief A lazy pointer to the definition data for a declaration.
|
||||
/// FIXME: This is a little CXXRecordDecl-specific that the moment.
|
||||
template<typename Decl, typename T> class LazyDefinitionDataPtr {
|
||||
llvm::PointerUnion<T *, Decl *> DataOrCanonicalDecl;
|
||||
|
||||
LazyDefinitionDataPtr update() {
|
||||
if (Decl *Canon = DataOrCanonicalDecl.template dyn_cast<Decl*>()) {
|
||||
if (Canon->isCanonicalDecl())
|
||||
Canon->getMostRecentDecl();
|
||||
else
|
||||
// Declaration isn't canonical any more;
|
||||
// update it and perform path compression.
|
||||
*this = Canon->getPreviousDecl()->DefinitionData.update();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
public:
|
||||
LazyDefinitionDataPtr(Decl *Canon) : DataOrCanonicalDecl(Canon) {}
|
||||
LazyDefinitionDataPtr(T *Data) : DataOrCanonicalDecl(Data) {}
|
||||
T *getNotUpdated() { return DataOrCanonicalDecl.template dyn_cast<T*>(); }
|
||||
T *get() { return update().getNotUpdated(); }
|
||||
};
|
||||
|
||||
/// \brief Represents a C++ struct/union/class.
|
||||
///
|
||||
/// FIXME: This class will disappear once we've properly taught RecordDecl
|
||||
/// to deal with C++-specific things.
|
||||
class CXXRecordDecl : public RecordDecl {
|
||||
|
||||
friend void TagDecl::startDefinition();
|
||||
@ -496,9 +517,9 @@ class CXXRecordDecl : public RecordDecl {
|
||||
CXXBaseSpecifier *getVBasesSlowCase() const;
|
||||
};
|
||||
|
||||
typedef LazyGenerationalUpdatePtr<const Decl*, struct DefinitionData*,
|
||||
&ExternalASTSource::CompleteRedeclChain>
|
||||
typedef LazyDefinitionDataPtr<CXXRecordDecl, struct DefinitionData>
|
||||
DefinitionDataPtr;
|
||||
friend class LazyDefinitionDataPtr<CXXRecordDecl, struct DefinitionData>;
|
||||
|
||||
mutable DefinitionDataPtr DefinitionData;
|
||||
|
||||
@ -558,7 +579,7 @@ class CXXRecordDecl : public RecordDecl {
|
||||
};
|
||||
|
||||
struct DefinitionData &data() const {
|
||||
auto *DD = DefinitionData.get(this);
|
||||
auto *DD = DefinitionData.get();
|
||||
assert(DD && "queried property of class with no definition");
|
||||
return *DD;
|
||||
}
|
||||
@ -643,11 +664,11 @@ public:
|
||||
}
|
||||
|
||||
CXXRecordDecl *getDefinition() const {
|
||||
auto *DD = DefinitionData.get(this);
|
||||
auto *DD = DefinitionData.get();
|
||||
return DD ? DD->Definition : nullptr;
|
||||
}
|
||||
|
||||
bool hasDefinition() const { return DefinitionData.get(this); }
|
||||
bool hasDefinition() const { return DefinitionData.get(); }
|
||||
|
||||
static CXXRecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC,
|
||||
SourceLocation StartLoc, SourceLocation IdLoc,
|
||||
|
@ -3240,7 +3240,7 @@ void TagDecl::startDefinition() {
|
||||
struct CXXRecordDecl::DefinitionData *Data =
|
||||
new (getASTContext()) struct CXXRecordDecl::DefinitionData(D);
|
||||
for (auto I : redecls())
|
||||
cast<CXXRecordDecl>(I)->DefinitionData.setNotUpdated(Data);
|
||||
cast<CXXRecordDecl>(I)->DefinitionData = Data;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@ CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, const ASTContext &C,
|
||||
CXXRecordDecl *PrevDecl)
|
||||
: RecordDecl(K, TK, C, DC, StartLoc, IdLoc, Id, PrevDecl),
|
||||
DefinitionData(PrevDecl ? PrevDecl->DefinitionData
|
||||
: DefinitionDataPtr(C)),
|
||||
: DefinitionDataPtr(this)),
|
||||
TemplateOrInstantiation() {}
|
||||
|
||||
CXXRecordDecl *CXXRecordDecl::Create(const ASTContext &C, TagKind TK,
|
||||
@ -115,9 +115,9 @@ CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC,
|
||||
new (C, DC) CXXRecordDecl(CXXRecord, TTK_Class, C, DC, Loc, Loc,
|
||||
nullptr, nullptr);
|
||||
R->IsBeingDefined = true;
|
||||
R->DefinitionData.setNotUpdated(
|
||||
R->DefinitionData =
|
||||
new (C) struct LambdaDefinitionData(R, Info, Dependent, IsGeneric,
|
||||
CaptureDefault));
|
||||
CaptureDefault);
|
||||
R->MayHaveOutOfDateDef = false;
|
||||
R->setImplicit(true);
|
||||
C.getTypeDeclType(R, /*PrevDecl=*/nullptr);
|
||||
|
@ -1405,7 +1405,7 @@ void ASTDeclReader::ReadCXXRecordDefinition(CXXRecordDecl *D) {
|
||||
// that all other deserialized declarations will see it.
|
||||
CXXRecordDecl *Canon = D->getCanonicalDecl();
|
||||
if (Canon == D) {
|
||||
D->DefinitionData.setNotUpdated(DD);
|
||||
D->DefinitionData = DD;
|
||||
D->IsCompleteDefinition = true;
|
||||
} else if (auto *CanonDD = Canon->DefinitionData.getNotUpdated()) {
|
||||
// We have already deserialized a definition of this record. This
|
||||
@ -1417,7 +1417,7 @@ void ASTDeclReader::ReadCXXRecordDefinition(CXXRecordDecl *D) {
|
||||
D->IsCompleteDefinition = false;
|
||||
MergeDefinitionData(D, *DD);
|
||||
} else {
|
||||
Canon->DefinitionData.setNotUpdated(DD);
|
||||
Canon->DefinitionData = DD;
|
||||
D->DefinitionData = Canon->DefinitionData;
|
||||
D->IsCompleteDefinition = true;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user