Add a ThunkAdjustment struct which holds a non-virtual and a virtual adjustment offset. Start using it. General cleanup in Mangle.cpp.
llvm-svn: 89925
This commit is contained in:
parent
0f5e6f8805
commit
c778540f9a
|
@ -819,11 +819,13 @@ const char *CodeGenModule::getMangledCXXDtorName(const CXXDestructorDecl *D,
|
|||
return UniqueMangledName(Name.begin(), Name.end());
|
||||
}
|
||||
|
||||
llvm::Constant *CodeGenFunction::GenerateThunk(llvm::Function *Fn,
|
||||
const CXXMethodDecl *MD,
|
||||
bool Extern, int64_t nv,
|
||||
int64_t v) {
|
||||
return GenerateCovariantThunk(Fn, MD, Extern, nv, v, 0, 0);
|
||||
llvm::Constant *
|
||||
CodeGenFunction::GenerateThunk(llvm::Function *Fn, const CXXMethodDecl *MD,
|
||||
bool Extern,
|
||||
const ThunkAdjustment &ThisAdjustment) {
|
||||
return GenerateCovariantThunk(Fn, MD, Extern,
|
||||
ThisAdjustment.NonVirtual,
|
||||
ThisAdjustment.Virtual, 0, 0);
|
||||
}
|
||||
|
||||
llvm::Value *CodeGenFunction::DynamicTypeAdjust(llvm::Value *V, int64_t nv,
|
||||
|
@ -961,10 +963,14 @@ llvm::Constant *CodeGenFunction::GenerateCovariantThunk(llvm::Function *Fn,
|
|||
return Fn;
|
||||
}
|
||||
|
||||
llvm::Constant *CodeGenModule::BuildThunk(const CXXMethodDecl *MD, bool Extern,
|
||||
int64_t nv, int64_t v) {
|
||||
llvm::Constant *
|
||||
CodeGenModule::BuildThunk(const CXXMethodDecl *MD, bool Extern,
|
||||
const ThunkAdjustment &ThisAdjustment) {
|
||||
|
||||
llvm::SmallString<256> OutName;
|
||||
getMangleContext().mangleThunk(MD, nv, v, OutName);
|
||||
getMangleContext().mangleThunk(MD, ThisAdjustment.NonVirtual,
|
||||
ThisAdjustment.Virtual, OutName);
|
||||
|
||||
llvm::GlobalVariable::LinkageTypes linktype;
|
||||
linktype = llvm::GlobalValue::WeakAnyLinkage;
|
||||
if (!Extern)
|
||||
|
@ -977,7 +983,7 @@ llvm::Constant *CodeGenModule::BuildThunk(const CXXMethodDecl *MD, bool Extern,
|
|||
|
||||
llvm::Function *Fn = llvm::Function::Create(FTy, linktype, OutName.str(),
|
||||
&getModule());
|
||||
CodeGenFunction(*this).GenerateThunk(Fn, MD, Extern, nv, v);
|
||||
CodeGenFunction(*this).GenerateThunk(Fn, MD, Extern, ThisAdjustment);
|
||||
llvm::Constant *m = llvm::ConstantExpr::getBitCast(Fn, Ptr8Ty);
|
||||
return m;
|
||||
}
|
||||
|
|
|
@ -333,7 +333,8 @@ public:
|
|||
Index_t idx = Index[GD];
|
||||
Index_t nv_O = i->second.first;
|
||||
Index_t v_O = i->second.second;
|
||||
submethods[idx] = CGM.BuildThunk(MD, Extern, nv_O, v_O);
|
||||
submethods[idx] = CGM.BuildThunk(MD, Extern,
|
||||
ThunkAdjustment(nv_O, v_O));
|
||||
}
|
||||
Thunks.clear();
|
||||
for (CovariantThunks_t::iterator i = CovariantThunks.begin(),
|
||||
|
|
|
@ -23,7 +23,28 @@ namespace clang {
|
|||
|
||||
namespace CodeGen {
|
||||
class CodeGenModule;
|
||||
|
||||
/// ThunkAdjustment - Virtual and non-virtual adjustment for thunks.
|
||||
struct ThunkAdjustment {
|
||||
ThunkAdjustment(int64_t NonVirtual, int64_t Virtual)
|
||||
: NonVirtual(NonVirtual),
|
||||
Virtual(Virtual) { }
|
||||
|
||||
ThunkAdjustment()
|
||||
: NonVirtual(0), Virtual(0) { }
|
||||
|
||||
// isEmpty - Return whether this thunk adjustment is empty.
|
||||
bool isEmpty() const {
|
||||
return NonVirtual == 0 && Virtual == 0;
|
||||
}
|
||||
|
||||
/// NonVirtual - The non-virtual adjustment.
|
||||
int64_t NonVirtual;
|
||||
|
||||
/// Virtual - The virtual adjustment.
|
||||
int64_t Virtual;
|
||||
};
|
||||
|
||||
class CGVtableInfo {
|
||||
CodeGenModule &CGM;
|
||||
|
||||
|
|
|
@ -441,7 +441,8 @@ public:
|
|||
|
||||
/// GenerateThunk - Generate a thunk for the given method
|
||||
llvm::Constant *GenerateThunk(llvm::Function *Fn, const CXXMethodDecl *MD,
|
||||
bool Extern, int64_t nv, int64_t v);
|
||||
bool Extern,
|
||||
const ThunkAdjustment &ThisAdjustment);
|
||||
llvm::Constant *GenerateCovariantThunk(llvm::Function *Fn,
|
||||
const CXXMethodDecl *MD, bool Extern,
|
||||
int64_t nv_t, int64_t v_t,
|
||||
|
|
|
@ -233,9 +233,10 @@ public:
|
|||
/// non-class type.
|
||||
llvm::Constant *GenerateRtti(QualType Ty);
|
||||
|
||||
/// BuildThunk - Build a thunk for the given method
|
||||
llvm::Constant *BuildThunk(const CXXMethodDecl *MD, bool Extern, int64_t nv,
|
||||
int64_t v);
|
||||
/// BuildThunk - Build a thunk for the given method.
|
||||
llvm::Constant *BuildThunk(const CXXMethodDecl *MD, bool Extern,
|
||||
const ThunkAdjustment &ThisAdjustment);
|
||||
|
||||
/// BuildCoVariantThunk - Build a thunk for the given method
|
||||
llvm::Constant *BuildCovariantThunk(const CXXMethodDecl *MD, bool Extern,
|
||||
int64_t nv_t, int64_t v_t,
|
||||
|
|
|
@ -67,7 +67,9 @@ public:
|
|||
llvm::raw_svector_ostream &getStream() { return Out; }
|
||||
|
||||
void mangle(const NamedDecl *D, llvm::StringRef Prefix = "_Z");
|
||||
void mangleCalloffset(int64_t nv, int64_t v);
|
||||
void mangleCallOffset(int64_t NonVirtualOffset,
|
||||
int64_t VirtualOffset);
|
||||
void mangleNumber(int64_t Number);
|
||||
void mangleFunctionEncoding(const FunctionDecl *FD);
|
||||
void mangleName(const NamedDecl *ND);
|
||||
void mangleType(QualType T);
|
||||
|
@ -336,34 +338,35 @@ void CXXNameMangler::mangleUnscopedTemplateName(const TemplateDecl *ND) {
|
|||
addSubstitution(ND);
|
||||
}
|
||||
|
||||
void CXXNameMangler::mangleCalloffset(int64_t nv, int64_t v) {
|
||||
void CXXNameMangler::mangleNumber(int64_t Number) {
|
||||
// <number> ::= [n] <non-negative decimal integer>
|
||||
if (Number < 0) {
|
||||
Out << 'n';
|
||||
Number = -Number;
|
||||
}
|
||||
|
||||
Out << Number;
|
||||
}
|
||||
|
||||
void CXXNameMangler::mangleCallOffset(int64_t NonVirtualOffset,
|
||||
int64_t VirtualOffset) {
|
||||
// <call-offset> ::= h <nv-offset> _
|
||||
// ::= v <v-offset> _
|
||||
// <nv-offset> ::= <offset number> # non-virtual base override
|
||||
// <v-offset> ::= <offset nubmer> _ <virtual offset number>
|
||||
// <v-offset> ::= <offset number> _ <virtual offset number>
|
||||
// # virtual base override, with vcall offset
|
||||
if (v == 0) {
|
||||
Out << "h";
|
||||
if (nv < 0) {
|
||||
Out << "n";
|
||||
nv = -nv;
|
||||
}
|
||||
Out << nv;
|
||||
} else {
|
||||
Out << "v";
|
||||
if (nv < 0) {
|
||||
Out << "n";
|
||||
nv = -nv;
|
||||
}
|
||||
Out << nv;
|
||||
Out << "_";
|
||||
if (v < 0) {
|
||||
Out << "n";
|
||||
v = -v;
|
||||
}
|
||||
Out << v;
|
||||
if (!VirtualOffset) {
|
||||
Out << 'h';
|
||||
mangleNumber(NonVirtualOffset);
|
||||
Out << '_';
|
||||
return;
|
||||
}
|
||||
Out << "_";
|
||||
|
||||
Out << 'v';
|
||||
mangleNumber(NonVirtualOffset);
|
||||
Out << '_';
|
||||
mangleNumber(VirtualOffset);
|
||||
Out << '_';
|
||||
}
|
||||
|
||||
void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND) {
|
||||
|
@ -1351,7 +1354,9 @@ void MangleContext::mangleCXXDtor(const CXXDestructorDecl *D, CXXDtorType Type,
|
|||
|
||||
/// \brief Mangles the a thunk with the offset n for the declaration D and
|
||||
/// emits that name to the given output stream.
|
||||
void MangleContext::mangleThunk(const FunctionDecl *FD, int64_t nv, int64_t v,
|
||||
void MangleContext::mangleThunk(const FunctionDecl *FD,
|
||||
int64_t NonVirtualOffset,
|
||||
int64_t VirtualOffset,
|
||||
llvm::SmallVectorImpl<char> &Res) {
|
||||
// FIXME: Hum, we might have to thunk these, fix.
|
||||
assert(!isa<CXXDestructorDecl>(FD) &&
|
||||
|
@ -1361,7 +1366,7 @@ void MangleContext::mangleThunk(const FunctionDecl *FD, int64_t nv, int64_t v,
|
|||
// # base is the nominal target function of thunk
|
||||
CXXNameMangler Mangler(*this, Res);
|
||||
Mangler.getStream() << "_ZT";
|
||||
Mangler.mangleCalloffset(nv, v);
|
||||
Mangler.mangleCallOffset(NonVirtualOffset, VirtualOffset);
|
||||
Mangler.mangleFunctionEncoding(FD);
|
||||
}
|
||||
|
||||
|
@ -1380,8 +1385,8 @@ void MangleContext::mangleCovariantThunk(const FunctionDecl *FD, int64_t nv_t,
|
|||
// # second call-offset is result adjustment
|
||||
CXXNameMangler Mangler(*this, Res);
|
||||
Mangler.getStream() << "_ZTc";
|
||||
Mangler.mangleCalloffset(nv_t, v_t);
|
||||
Mangler.mangleCalloffset(nv_r, v_r);
|
||||
Mangler.mangleCallOffset(nv_t, v_t);
|
||||
Mangler.mangleCallOffset(nv_r, v_r);
|
||||
Mangler.mangleFunctionEncoding(FD);
|
||||
}
|
||||
|
||||
|
|
|
@ -61,7 +61,8 @@ public:
|
|||
bool shouldMangleDeclName(const NamedDecl *D);
|
||||
|
||||
void mangleName(const NamedDecl *D, llvm::SmallVectorImpl<char> &);
|
||||
void mangleThunk(const FunctionDecl *FD, int64_t n, int64_t vn,
|
||||
void mangleThunk(const FunctionDecl *FD,
|
||||
int64_t NonVirtualOffset, int64_t VirtualOffset,
|
||||
llvm::SmallVectorImpl<char> &);
|
||||
void mangleCovariantThunk(const FunctionDecl *FD, int64_t nv_t, int64_t v_t,
|
||||
int64_t nv_r, int64_t v_r,
|
||||
|
|
Loading…
Reference in New Issue