зеркало из https://github.com/microsoft/clang-1.git
Reclaim memory from chains of ScopedDecls, and reclaim memory for the initializers of EnumConstantDecls.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@51299 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
f809e3bd0c
Коммит
d1ac17ae7d
|
@ -125,6 +125,8 @@ protected:
|
|||
|
||||
void EmitOutRec(llvm::Serializer& S) const;
|
||||
void ReadOutRec(llvm::Deserializer& D, ASTContext& C);
|
||||
|
||||
friend void Decl::Destroy(ASTContext& C);
|
||||
};
|
||||
|
||||
/// NamespaceDecl - Represent a C++ namespace.
|
||||
|
@ -150,6 +152,8 @@ class NamespaceDecl : public ScopedDecl, public DeclContext {
|
|||
public:
|
||||
static NamespaceDecl *Create(ASTContext &C, DeclContext *DC,
|
||||
SourceLocation L, IdentifierInfo *Id);
|
||||
|
||||
virtual void Destroy(ASTContext& C);
|
||||
|
||||
NamespaceDecl *getNextNamespace() {
|
||||
return cast_or_null<NamespaceDecl>(getNextDeclarator());
|
||||
|
@ -565,6 +569,8 @@ public:
|
|||
QualType T, Expr *E,
|
||||
const llvm::APSInt &V, ScopedDecl *PrevDecl);
|
||||
|
||||
virtual void Destroy(ASTContext& C);
|
||||
|
||||
const Expr *getInitExpr() const { return Init; }
|
||||
Expr *getInitExpr() { return Init; }
|
||||
const llvm::APSInt &getInitVal() const { return Val; }
|
||||
|
@ -703,6 +709,8 @@ public:
|
|||
SourceLocation L, IdentifierInfo *Id,
|
||||
ScopedDecl *PrevDecl);
|
||||
|
||||
virtual void Destroy(ASTContext& C);
|
||||
|
||||
/// defineElements - When created, EnumDecl correspond to a forward declared
|
||||
/// enum. This method is used to mark the decl as being defined, with the
|
||||
/// specified list of enums.
|
||||
|
|
|
@ -226,6 +226,15 @@ NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC,
|
|||
return new (Mem) NamespaceDecl(DC, L, Id);
|
||||
}
|
||||
|
||||
void NamespaceDecl::Destroy(ASTContext& C) {
|
||||
// NamespaceDecl uses "NextDeclarator" to chain namespace declarations
|
||||
// together. They are all top-level Decls.
|
||||
|
||||
this->~Decl();
|
||||
C.getAllocator().Deallocate((void *)this);
|
||||
}
|
||||
|
||||
|
||||
VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC,
|
||||
SourceLocation L,
|
||||
IdentifierInfo *Id, QualType T,
|
||||
|
@ -267,6 +276,11 @@ EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD,
|
|||
return new (Mem) EnumConstantDecl(CD, L, Id, T, E, V, PrevDecl);
|
||||
}
|
||||
|
||||
void EnumConstantDecl::Destroy(ASTContext& C) {
|
||||
if (Init) Init->Destroy(C);
|
||||
Decl::Destroy(C);
|
||||
}
|
||||
|
||||
TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC,
|
||||
SourceLocation L,
|
||||
IdentifierInfo *Id, QualType T,
|
||||
|
@ -289,6 +303,12 @@ RecordDecl *RecordDecl::Create(ASTContext &C, Kind DK, DeclContext *DC,
|
|||
return new (Mem) RecordDecl(DK, DC, L, Id, PrevDecl);
|
||||
}
|
||||
|
||||
void EnumDecl::Destroy(ASTContext& C) {
|
||||
if (ElementList) ElementList->Destroy(C);
|
||||
Decl::Destroy(C);
|
||||
}
|
||||
|
||||
|
||||
FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C,
|
||||
SourceLocation L,
|
||||
StringLiteral *Str) {
|
||||
|
@ -370,6 +390,23 @@ void Decl::swapAttrs(Decl *RHS) {
|
|||
|
||||
|
||||
void Decl::Destroy(ASTContext& C) {
|
||||
|
||||
if (ScopedDecl* SD = dyn_cast<ScopedDecl>(this)) {
|
||||
|
||||
// Observe the unrolled recursion. By setting N->NextDeclarator = 0x0
|
||||
// within the loop, only the Destroy method for the first ScopedDecl
|
||||
// will deallocate all of the ScopedDecls in a chain.
|
||||
|
||||
ScopedDecl* N = SD->getNextDeclarator();
|
||||
|
||||
while (N) {
|
||||
ScopedDecl* Tmp = N->getNextDeclarator();
|
||||
N->NextDeclarator = 0x0;
|
||||
N->Destroy(C);
|
||||
N = Tmp;
|
||||
}
|
||||
}
|
||||
|
||||
this->~Decl();
|
||||
C.getAllocator().Deallocate((void *)this);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче