diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-05-20 04:49:55 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-05-20 04:49:55 +0000 |
commit | 78aa98f7b80647a196a18691ca18d36072fd827e (patch) | |
tree | 3d9f51a7eb14160189327f0127f939ccbdb07b4c /clang | |
parent | 40e489dfd8220d4f0b3ac1182d84350c00250920 (diff) | |
download | bcm5719-llvm-78aa98f7b80647a196a18691ca18d36072fd827e.tar.gz bcm5719-llvm-78aa98f7b80647a196a18691ca18d36072fd827e.zip |
Reclaim memory from chains of ScopedDecls, and reclaim memory for the initializers of EnumConstantDecls.
llvm-svn: 51299
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/AST/Decl.h | 8 | ||||
-rw-r--r-- | clang/lib/AST/Decl.cpp | 37 |
2 files changed, 45 insertions, 0 deletions
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 0714b120ad7..6b3eccf30c9 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -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. diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index c75fb8b674d..02d86a32fcc 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -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); } |