From 19879c98d964bc67442618510af04e3457219780 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Tue, 23 Mar 2010 17:17:29 +0000 Subject: [PATCH] More thunks scaffolding. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99294 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGVtable.cpp | 20 ++++++++++++- lib/CodeGen/CodeGenModule.h | 3 ++ lib/CodeGen/Mangle.cpp | 59 ++++++++++++++++++++++++++++++++++--- lib/CodeGen/Mangle.h | 9 ++++++ 4 files changed, 86 insertions(+), 5 deletions(-) diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index 279fcaac7d..6fee2a566c 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -3650,9 +3650,27 @@ CodeGenVTables::GenerateVtable(llvm::GlobalVariable::LinkageTypes Linkage, return GV; } +llvm::Constant *CodeGenModule::GetAddrOfThunk(GlobalDecl GD, + const ThunkInfo &Thunk) { + const CXXMethodDecl *MD = cast(GD.getDecl()); + + // Compute the mangled name. + llvm::SmallString<256> Name; + if (const CXXDestructorDecl* DD = dyn_cast(MD)) + getMangleContext().mangleCXXDtorThunk(DD, GD.getDtorType(), Thunk.This, + Name); + else + getMangleContext().mangleThunk(MD, Thunk, Name); + + const llvm::Type *Ty = getTypes().GetFunctionTypeForVtable(MD); + return GetOrCreateLLVMFunction(Name, Ty, GlobalDecl()); +} + void CodeGenVTables::EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk) { - // FIXME: Implement this! + llvm::Constant *ThunkFn = CGM.GetAddrOfThunk(GD, Thunk); + + (void)ThunkFn; } void CodeGenVTables::EmitThunks(GlobalDecl GD) diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 47dd3a842b..a8170c17db 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -225,6 +225,9 @@ public: /// for the given type. llvm::Constant *GetAddrOfRTTIDescriptor(QualType Ty); + /// GetAddrOfThunk - Get the address of the thunk for the given global decl. + llvm::Constant *GetAddrOfThunk(GlobalDecl GD, const ThunkInfo &Thunk); + llvm::Constant *GetAddrOfThunk(GlobalDecl GD, const ThunkAdjustment &ThisAdjustment); llvm::Constant *GetAddrOfCovariantThunk(GlobalDecl GD, diff --git a/lib/CodeGen/Mangle.cpp b/lib/CodeGen/Mangle.cpp index f2a73f1c2d..d7ebda5e5f 100644 --- a/lib/CodeGen/Mangle.cpp +++ b/lib/CodeGen/Mangle.cpp @@ -103,6 +103,7 @@ public: void mangle(const NamedDecl *D, llvm::StringRef Prefix = "_Z"); void mangleCallOffset(const ThunkAdjustment &Adjustment); + void mangleCallOffset(int64_t NonVirtual, int64_t Virtual); void mangleNumber(int64_t Number); void mangleFunctionEncoding(const FunctionDecl *FD); void mangleName(const NamedDecl *ND); @@ -440,22 +441,26 @@ void CXXNameMangler::mangleNumber(int64_t Number) { } void CXXNameMangler::mangleCallOffset(const ThunkAdjustment &Adjustment) { + mangleCallOffset(Adjustment.NonVirtual, Adjustment.Virtual); +} + +void CXXNameMangler::mangleCallOffset(int64_t NonVirtual, int64_t Virtual) { // ::= h _ // ::= v _ // ::= # non-virtual base override // ::= _ // # virtual base override, with vcall offset - if (!Adjustment.Virtual) { + if (!Virtual) { Out << 'h'; - mangleNumber(Adjustment.NonVirtual); + mangleNumber(NonVirtual); Out << '_'; return; } Out << 'v'; - mangleNumber(Adjustment.NonVirtual); + mangleNumber(NonVirtual); Out << '_'; - mangleNumber(Adjustment.Virtual); + mangleNumber(Virtual); Out << '_'; } @@ -1878,6 +1883,52 @@ void MangleContext::mangleThunk(const FunctionDecl *FD, Mangler.mangleFunctionEncoding(FD); } +void MangleContext::mangleThunk(const CXXMethodDecl *MD, + const ThunkInfo &Thunk, + llvm::SmallVectorImpl &Res) { + // ::= T + // # base is the nominal target function of thunk + // ::= Tc + // # base is the nominal target function of thunk + // # first call-offset is 'this' adjustment + // # second call-offset is result adjustment + + assert(!isa(MD) && + "Use mangleCXXDtor for destructor decls!"); + + CXXNameMangler Mangler(*this, Res); + Mangler.getStream() << "_ZT"; + if (!Thunk.Return.isEmpty()) + Mangler.getStream() << 'c'; + + // Mangle the 'this' pointer adjustment. + Mangler.mangleCallOffset(Thunk.This.NonVirtual, Thunk.This.VCallOffsetOffset); + + // Mangle the return pointer adjustment if there is one. + if (!Thunk.Return.isEmpty()) + Mangler.mangleCallOffset(Thunk.Return.NonVirtual, + Thunk.Return.VBaseOffsetOffset); + + Mangler.mangleFunctionEncoding(MD); +} + +void +MangleContext::mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, + const ThisAdjustment &ThisAdjustment, + llvm::SmallVectorImpl &Res) { + // ::= T + // # base is the nominal target function of thunk + + CXXNameMangler Mangler(*this, Res, DD, Type); + Mangler.getStream() << "_ZT"; + + // Mangle the 'this' pointer adjustment. + Mangler.mangleCallOffset(ThisAdjustment.NonVirtual, + ThisAdjustment.VCallOffsetOffset); + + Mangler.mangleFunctionEncoding(DD); +} + void MangleContext::mangleCXXDtorThunk(const CXXDestructorDecl *D, CXXDtorType Type, const ThunkAdjustment &ThisAdjustment, diff --git a/lib/CodeGen/Mangle.h b/lib/CodeGen/Mangle.h index 62656b95da..759cfc3bef 100644 --- a/lib/CodeGen/Mangle.h +++ b/lib/CodeGen/Mangle.h @@ -28,11 +28,14 @@ namespace clang { class ASTContext; class CXXConstructorDecl; class CXXDestructorDecl; + class CXXMethodDecl; class FunctionDecl; class NamedDecl; class VarDecl; namespace CodeGen { + class ThisAdjustment; + class ThunkInfo; class CovariantThunkAdjustment; class ThunkAdjustment; @@ -94,9 +97,15 @@ public: void mangleThunk(const FunctionDecl *FD, const ThunkAdjustment &ThisAdjustment, llvm::SmallVectorImpl &); + void mangleThunk(const CXXMethodDecl *MD, + const ThunkInfo &Thunk, + llvm::SmallVectorImpl &); void mangleCXXDtorThunk(const CXXDestructorDecl *D, CXXDtorType Type, const ThunkAdjustment &ThisAdjustment, llvm::SmallVectorImpl &); + void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, + const ThisAdjustment &ThisAdjustment, + llvm::SmallVectorImpl &); void mangleCovariantThunk(const FunctionDecl *FD, const CovariantThunkAdjustment& Adjustment, llvm::SmallVectorImpl &); -- 2.40.0