diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGVtable.cpp | 20 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 3 | ||||
-rw-r--r-- | clang/lib/CodeGen/Mangle.cpp | 59 | ||||
-rw-r--r-- | clang/lib/CodeGen/Mangle.h | 9 |
4 files changed, 86 insertions, 5 deletions
diff --git a/clang/lib/CodeGen/CGVtable.cpp b/clang/lib/CodeGen/CGVtable.cpp index 279fcaac7d7..6fee2a566c4 100644 --- a/clang/lib/CodeGen/CGVtable.cpp +++ b/clang/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<CXXMethodDecl>(GD.getDecl()); + + // Compute the mangled name. + llvm::SmallString<256> Name; + if (const CXXDestructorDecl* DD = dyn_cast<CXXDestructorDecl>(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/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 47dd3a842ba..a8170c17db4 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/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/clang/lib/CodeGen/Mangle.cpp b/clang/lib/CodeGen/Mangle.cpp index f2a73f1c2d1..d7ebda5e5f0 100644 --- a/clang/lib/CodeGen/Mangle.cpp +++ b/clang/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) { // <call-offset> ::= h <nv-offset> _ // ::= v <v-offset> _ // <nv-offset> ::= <offset number> # non-virtual base override // <v-offset> ::= <offset number> _ <virtual offset number> // # 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<char> &Res) { + // <special-name> ::= T <call-offset> <base encoding> + // # base is the nominal target function of thunk + // <special-name> ::= Tc <call-offset> <call-offset> <base encoding> + // # base is the nominal target function of thunk + // # first call-offset is 'this' adjustment + // # second call-offset is result adjustment + + assert(!isa<CXXDestructorDecl>(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<char> &Res) { + // <special-name> ::= T <call-offset> <base encoding> + // # 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/clang/lib/CodeGen/Mangle.h b/clang/lib/CodeGen/Mangle.h index 62656b95da1..759cfc3beff 100644 --- a/clang/lib/CodeGen/Mangle.h +++ b/clang/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<char> &); + void mangleThunk(const CXXMethodDecl *MD, + const ThunkInfo &Thunk, + llvm::SmallVectorImpl<char> &); void mangleCXXDtorThunk(const CXXDestructorDecl *D, CXXDtorType Type, const ThunkAdjustment &ThisAdjustment, llvm::SmallVectorImpl<char> &); + void mangleCXXDtorThunk(const CXXDestructorDecl *DD, CXXDtorType Type, + const ThisAdjustment &ThisAdjustment, + llvm::SmallVectorImpl<char> &); void mangleCovariantThunk(const FunctionDecl *FD, const CovariantThunkAdjustment& Adjustment, llvm::SmallVectorImpl<char> &); |