llvm::Type *Ty = getTypes().GetFunctionTypeForVTable(GD);
return GetOrCreateLLVMFunction(Name, Ty, GD, /*ForVTable=*/true,
- /*DontDefer*/ true);
+ /*DontDefer=*/true, /*IsThunk=*/true);
}
static void setThunkVisibility(CodeGenModule &CGM, const CXXMethodDecl *MD,
}
}
-void CodeGenModule::SetFunctionAttributes(GlobalDecl GD,
- llvm::Function *F,
- bool IsIncompleteFunction) {
+void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Function *F,
+ bool IsIncompleteFunction,
+ bool IsThunk) {
if (unsigned IID = F->getIntrinsicID()) {
// If this is an intrinsic function, set the function's attributes
// to the intrinsic's attributes.
// Add the Returned attribute for "this", except for iOS 5 and earlier
// where substantial code, including the libstdc++ dylib, was compiled with
// GCC and does not actually return "this".
- if (getCXXABI().HasThisReturn(GD) &&
+ if (!IsThunk && getCXXABI().HasThisReturn(GD) &&
!(getTarget().getTriple().isiOS() &&
getTarget().getTriple().isOSVersionLT(6))) {
assert(!F->arg_empty() &&
CodeGenModule::GetOrCreateLLVMFunction(StringRef MangledName,
llvm::Type *Ty,
GlobalDecl GD, bool ForVTable,
- bool DontDefer,
+ bool DontDefer, bool IsThunk,
llvm::AttributeSet ExtraAttrs) {
const Decl *D = GD.getDecl();
MangledName, &getModule());
assert(F->getName() == MangledName && "name was uniqued!");
if (D)
- SetFunctionAttributes(GD, F, IsIncompleteFunction);
+ SetFunctionAttributes(GD, F, IsIncompleteFunction, IsThunk);
if (ExtraAttrs.hasAttributes(llvm::AttributeSet::FunctionIndex)) {
llvm::AttrBuilder B(ExtraAttrs, llvm::AttributeSet::FunctionIndex);
F->addAttributes(llvm::AttributeSet::FunctionIndex,
llvm::AttributeSet ExtraAttrs) {
llvm::Constant *C =
GetOrCreateLLVMFunction(Name, FTy, GlobalDecl(), /*ForVTable=*/false,
- /*DontDefer=*/false, ExtraAttrs);
+ /*DontDefer=*/false, /*IsThunk=*/false, ExtraAttrs);
if (auto *F = dyn_cast<llvm::Function>(C))
if (F->empty())
F->setCallingConv(getRuntimeCC());
void addReplacement(StringRef Name, llvm::Constant *C);
private:
-
llvm::Constant *
GetOrCreateLLVMFunction(StringRef MangledName, llvm::Type *Ty, GlobalDecl D,
bool ForVTable, bool DontDefer = false,
+ bool IsThunk = false,
llvm::AttributeSet ExtraAttrs = llvm::AttributeSet());
llvm::Constant *GetOrCreateLLVMGlobal(StringRef MangledName,
void setNonAliasAttributes(const Decl *D, llvm::GlobalObject *GO);
/// Set function attributes for a function declaration.
- void SetFunctionAttributes(GlobalDecl GD,
- llvm::Function *F,
- bool IsIncompleteFunction);
+ void SetFunctionAttributes(GlobalDecl GD, llvm::Function *F,
+ bool IsIncompleteFunction, bool IsThunk);
void EmitGlobalDefinition(GlobalDecl D, llvm::GlobalValue *GV = nullptr);
class A {
public:
A();
- ~A();
+ virtual ~A();
private:
int x_;
class B : public A {
public:
B(int *i);
- ~B();
+ virtual ~B();
private:
int *i_;
// CHECKIOS5-LABEL: define %class.B* @_ZN1BD1Ev(%class.B* %this)
// CHECKMS-LABEL: define x86_thiscallcc %class.B* @"\01??0B@@QAE@PAH@Z"(%class.B* returned %this, i32* %i)
-// CHECKMS-LABEL: define x86_thiscallcc void @"\01??1B@@QAE@XZ"(%class.B* %this)
+// CHECKMS-LABEL: define x86_thiscallcc void @"\01??1B@@UAE@XZ"(%class.B* %this)
class C : public A, public B {
public:
// CHECKGEN-LABEL: define void @_ZN1CC1EPiPc(%class.C* %this, i32* %i, i8* %c)
// CHECKGEN-LABEL: define void @_ZN1CD2Ev(%class.C* %this)
// CHECKGEN-LABEL: define void @_ZN1CD1Ev(%class.C* %this)
+// CHECKGEN-LABEL: define void @_ZThn8_N1CD1Ev(%class.C* %this)
// CHECKGEN-LABEL: define void @_ZN1CD0Ev(%class.C* %this)
+// CHECKGEN-LABEL: define void @_ZThn8_N1CD0Ev(%class.C* %this)
// CHECKARM-LABEL: define %class.C* @_ZN1CC2EPiPc(%class.C* returned %this, i32* %i, i8* %c)
// CHECKARM-LABEL: define %class.C* @_ZN1CC1EPiPc(%class.C* returned %this, i32* %i, i8* %c)
// CHECKARM-LABEL: define %class.C* @_ZN1CD2Ev(%class.C* returned %this)
// CHECKARM-LABEL: define %class.C* @_ZN1CD1Ev(%class.C* returned %this)
+// CHECKARM-LABEL: define %class.C* @_ZThn8_N1CD1Ev(%class.C* %this)
// CHECKARM-LABEL: define void @_ZN1CD0Ev(%class.C* %this)
+// CHECKARM-LABEL: define void @_ZThn8_N1CD0Ev(%class.C* %this)
// CHECKIOS5-LABEL: define %class.C* @_ZN1CC2EPiPc(%class.C* %this, i32* %i, i8* %c)
// CHECKIOS5-LABEL: define %class.C* @_ZN1CC1EPiPc(%class.C* %this, i32* %i, i8* %c)
// CHECKIOS5-LABEL: define %class.C* @_ZN1CD2Ev(%class.C* %this)
// CHECKIOS5-LABEL: define %class.C* @_ZN1CD1Ev(%class.C* %this)
+// CHECKIOS5-LABEL: define %class.C* @_ZThn8_N1CD1Ev(%class.C* %this)
// CHECKIOS5-LABEL: define void @_ZN1CD0Ev(%class.C* %this)
+// CHECKIOS5-LABEL: define void @_ZThn8_N1CD0Ev(%class.C* %this)
// CHECKMS-LABEL: define x86_thiscallcc %class.C* @"\01??0C@@QAE@PAHPAD@Z"(%class.C* returned %this, i32* %i, i8* %c)
// CHECKMS-LABEL: define x86_thiscallcc void @"\01??1C@@UAE@XZ"(%class.C* %this)
// CHECKIOS5-LABEL: define %class.D* @_ZN1DD1Ev(%class.D* %this)
// CHECKMS-LABEL: define x86_thiscallcc %class.D* @"\01??0D@@QAE@XZ"(%class.D* returned %this, i32 %is_most_derived)
-// CHECKMS-LABEL: define x86_thiscallcc void @"\01??1D@@QAE@XZ"(%class.D* %this)
+// CHECKMS-LABEL: define x86_thiscallcc void @"\01??1D@@UAE@XZ"(%class.D*)
class E {
public: