diff options
author | Anders Carlsson <andersca@mac.com> | 2009-04-17 01:58:57 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-04-17 01:58:57 +0000 |
commit | 27ae53665f8b00fe4ba21da0fa79a4ce6e0b6cd5 (patch) | |
tree | 10a22e278b8d77f35f630084165189eeadc0fbca | |
parent | ec9587d5bed6149f6df8b57192bb787c62aedb1b (diff) |
Add support for generating (very basic) C++ destructors. These aren't called by anything yet.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69343 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CGCXX.cpp | 91 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 3 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.h | 16 | ||||
-rw-r--r-- | lib/CodeGen/Mangle.cpp | 70 | ||||
-rw-r--r-- | lib/CodeGen/Mangle.h | 3 |
5 files changed, 143 insertions, 40 deletions
diff --git a/lib/CodeGen/CGCXX.cpp b/lib/CodeGen/CGCXX.cpp index e61cef3498..cfb93b90d7 100644 --- a/lib/CodeGen/CGCXX.cpp +++ b/lib/CodeGen/CGCXX.cpp @@ -124,27 +124,6 @@ llvm::Value *CodeGenFunction::LoadCXXThis() { return Builder.CreateLoad(LocalDeclMap[CXXThisDecl], "this"); } -const char *CodeGenModule::getMangledCXXCtorName(const CXXConstructorDecl *D, - CXXCtorType Type) { - llvm::SmallString<256> Name; - llvm::raw_svector_ostream Out(Name); - mangleCXXCtor(D, Type, Context, Out); - - Name += '\0'; - return UniqueMangledName(Name.begin(), Name.end()); -} - -void CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *D, - CXXCtorType Type) { - - llvm::Function *Fn = GetAddrOfCXXConstructor(D, Type); - - CodeGenFunction(*this).GenerateCode(D, Fn); - - SetFunctionDefinitionAttributes(D, Fn); - SetLLVMFunctionAttributesForDefinition(D, Fn); -} - void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type, @@ -190,10 +169,8 @@ CodeGenFunction::EmitCXXTemporaryObjectExpr(llvm::Value *Dest, E->arg_begin(), E->arg_end()); } -static bool canGenerateCXXConstructor(const CXXConstructorDecl *D, - ASTContext &Context) { - const CXXRecordDecl *RD = D->getParent(); - +static bool canGenerateCXXstructor(const CXXRecordDecl *RD, + ASTContext &Context) { // The class has base classes - we don't support that right now. if (RD->getNumBases() > 0) return false; @@ -209,7 +186,7 @@ static bool canGenerateCXXConstructor(const CXXConstructorDecl *D, } void CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) { - if (!canGenerateCXXConstructor(D, getContext())) { + if (!canGenerateCXXstructor(D->getParent(), getContext())) { ErrorUnsupported(D, "C++ constructor", true); return; } @@ -218,6 +195,17 @@ void CodeGenModule::EmitCXXConstructors(const CXXConstructorDecl *D) { EmitCXXConstructor(D, Ctor_Base); } +void CodeGenModule::EmitCXXConstructor(const CXXConstructorDecl *D, + CXXCtorType Type) { + + llvm::Function *Fn = GetAddrOfCXXConstructor(D, Type); + + CodeGenFunction(*this).GenerateCode(D, Fn); + + SetFunctionDefinitionAttributes(D, Fn); + SetLLVMFunctionAttributesForDefinition(D, Fn); +} + llvm::Function * CodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D, CXXCtorType Type) { @@ -227,3 +215,54 @@ CodeGenModule::GetAddrOfCXXConstructor(const CXXConstructorDecl *D, const char *Name = getMangledCXXCtorName(D, Type); return cast<llvm::Function>(GetOrCreateLLVMFunction(Name, FTy, D)); } + +const char *CodeGenModule::getMangledCXXCtorName(const CXXConstructorDecl *D, + CXXCtorType Type) { + llvm::SmallString<256> Name; + llvm::raw_svector_ostream Out(Name); + mangleCXXCtor(D, Type, Context, Out); + + Name += '\0'; + return UniqueMangledName(Name.begin(), Name.end()); +} + +void CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) { + if (!canGenerateCXXstructor(D->getParent(), getContext())) { + ErrorUnsupported(D, "C++ destructor", true); + return; + } + + EmitCXXDestructor(D, Dtor_Complete); + EmitCXXDestructor(D, Dtor_Base); +} + +void CodeGenModule::EmitCXXDestructor(const CXXDestructorDecl *D, + CXXDtorType Type) { + llvm::Function *Fn = GetAddrOfCXXDestructor(D, Type); + + CodeGenFunction(*this).GenerateCode(D, Fn); + + SetFunctionDefinitionAttributes(D, Fn); + SetLLVMFunctionAttributesForDefinition(D, Fn); +} + +llvm::Function * +CodeGenModule::GetAddrOfCXXDestructor(const CXXDestructorDecl *D, + CXXDtorType Type) { + const llvm::FunctionType *FTy = + getTypes().GetFunctionType(getTypes().getFunctionInfo(D), false); + + const char *Name = getMangledCXXDtorName(D, Type); + return cast<llvm::Function>(GetOrCreateLLVMFunction(Name, FTy, D)); +} + +const char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D, + CXXDtorType Type) { + llvm::SmallString<256> Name; + llvm::raw_svector_ostream Out(Name); + mangleCXXDtor(D, Type, Context, Out); + + Name += '\0'; + return UniqueMangledName(Name.begin(), Name.end()); +} + diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 7cb5e43cb5..4cb1b43ba5 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -1367,6 +1367,9 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { case Decl::CXXConstructor: EmitCXXConstructors(cast<CXXConstructorDecl>(D)); break; + case Decl::CXXDestructor: + EmitCXXDestructors(cast<CXXDestructorDecl>(D)); + break; // Objective-C Decls diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 469c637e2d..e7924fade5 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -56,6 +56,7 @@ namespace clang { class CompileOptions; class Diagnostic; class AnnotateAttr; + class CXXDestructorDecl; namespace CodeGen { @@ -240,6 +241,11 @@ public: /// given type. llvm::Function *GetAddrOfCXXConstructor(const CXXConstructorDecl *D, CXXCtorType Type); + + /// GetAddrOfCXXDestructor - Return the address of the constructor of the + /// given type. + llvm::Function *GetAddrOfCXXDestructor(const CXXDestructorDecl *D, + CXXDtorType Type); /// getBuiltinLibFunction - Given a builtin id for a function like /// "__builtin_fabsf", return a Function* for "fabsf". @@ -331,6 +337,8 @@ public: const char *getMangledName(const NamedDecl *ND); const char *getMangledCXXCtorName(const CXXConstructorDecl *D, CXXCtorType Type); + const char *getMangledCXXDtorName(const CXXDestructorDecl *D, + CXXDtorType Type); enum GVALinkage { GVA_Internal, @@ -392,6 +400,14 @@ private: /// a C++ constructor Decl. void EmitCXXConstructor(const CXXConstructorDecl *D, CXXCtorType Type); + /// EmitCXXDestructors - Emit destructors (base, complete) from a + /// C++ destructor Decl. + void EmitCXXDestructors(const CXXDestructorDecl *D); + + /// EmitCXXDestructor - Emit a single destructor with the given type from + /// a C++ destructor Decl. + void EmitCXXDestructor(const CXXDestructorDecl *D, CXXDtorType Type); + // FIXME: Hardcoding priority here is gross. void AddGlobalCtor(llvm::Function * Ctor, int Priority=65535); void AddGlobalDtor(llvm::Function * Dtor, int Priority=65535); diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp index e42b6fdb79..3a7fe9c1f7 100644 --- a/lib/CodeGen/Mangle.cpp +++ b/lib/CodeGen/Mangle.cpp @@ -29,16 +29,19 @@ namespace { ASTContext &Context; llvm::raw_ostream &Out; - const CXXConstructorDecl *Ctor; + const CXXMethodDecl *Structor; + unsigned StructorType; CXXCtorType CtorType; public: CXXNameMangler(ASTContext &C, llvm::raw_ostream &os) - : Context(C), Out(os), Ctor(0), CtorType(Ctor_Complete) { } + : Context(C), Out(os), Structor(0), StructorType(0) { } bool mangle(const NamedDecl *D); void mangleGuardVariable(const VarDecl *D); + void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type); + void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type); private: bool mangleFunctionDecl(const FunctionDecl *FD); @@ -63,6 +66,7 @@ namespace { void mangleType(const ObjCInterfaceType *T); void mangleExpression(Expr *E); void mangleCXXCtorType(CXXCtorType T); + void mangleCXXDtorType(CXXDtorType T); }; } @@ -132,9 +136,18 @@ bool CXXNameMangler::mangle(const NamedDecl *D) { void CXXNameMangler::mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type) { - assert(!Ctor && "Ctor already set!"); - Ctor = D; - CtorType = Type; + assert(!Structor && "Structor already set!"); + Structor = D; + StructorType = Type; + + mangle(D); +} + +void CXXNameMangler::mangleCXXDtor(const CXXDestructorDecl *D, + CXXDtorType Type) { + assert(!Structor && "Structor already set!"); + Structor = D; + StructorType = Type; mangle(D); } @@ -198,10 +211,10 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND) { break; case DeclarationName::CXXConstructorName: - if (ND == Ctor) + if (ND == Structor) // If the named decl is the C++ constructor we're mangling, use the // type we were given. - mangleCXXCtorType(CtorType); + mangleCXXCtorType(static_cast<CXXCtorType>(StructorType)); else // Otherwise, use the complete constructor name. This is relevant if a // class with a constructor is declared within a constructor. @@ -209,13 +222,14 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND) { break; case DeclarationName::CXXDestructorName: - // <ctor-dtor-name> ::= D0 # deleting destructor - // ::= D1 # complete object destructor - // ::= D2 # base object destructor - // - // FIXME: We don't even have all of these destructors in the AST - // yet. - Out << "D0"; + if (ND == Structor) + // If the named decl is the C++ destructor we're mangling, use the + // type we were given. + mangleCXXDtorType(static_cast<CXXDtorType>(StructorType)); + else + // Otherwise, use the complete destructor name. This is relevant if a + // class with a destructor is declared within a destructor. + mangleCXXDtorType(Dtor_Complete); break; case DeclarationName::CXXConversionFunctionName: @@ -612,6 +626,24 @@ void CXXNameMangler::mangleCXXCtorType(CXXCtorType T) { } } +void CXXNameMangler::mangleCXXDtorType(CXXDtorType T) { + // <ctor-dtor-name> ::= D0 # deleting destructor + // ::= D1 # complete object destructor + // ::= D2 # base object destructor + // + switch (T) { + case Dtor_Deleting: + Out << "D0"; + break; + case Dtor_Complete: + Out << "D1"; + break; + case Dtor_Base: + Out << "D2"; + break; + } +} + namespace clang { /// \brief Mangles the name of the declaration D and emits that name /// to the given output stream. @@ -648,5 +680,15 @@ namespace clang { os.flush(); } + + void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type, + ASTContext &Context, llvm::raw_ostream &os) { + CXXNameMangler Mangler(Context, os); + Mangler.mangleCXXDtor(D, Type); + + os.flush(); + } + + } diff --git a/lib/CodeGen/Mangle.h b/lib/CodeGen/Mangle.h index a8ca09d1cf..77cbd97751 100644 --- a/lib/CodeGen/Mangle.h +++ b/lib/CodeGen/Mangle.h @@ -27,6 +27,7 @@ namespace llvm { namespace clang { class ASTContext; class CXXConstructorDecl; + class CXXDestructorDecl; class NamedDecl; class VarDecl; @@ -36,6 +37,8 @@ namespace clang { llvm::raw_ostream &os); void mangleCXXCtor(const CXXConstructorDecl *D, CXXCtorType Type, ASTContext &Context, llvm::raw_ostream &os); + void mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type, + ASTContext &Context, llvm::raw_ostream &os); } #endif |