diff --git a/clang/include/clang/Basic/TargetCXXABI.h b/clang/include/clang/Basic/TargetCXXABI.h --- a/clang/include/clang/Basic/TargetCXXABI.h +++ b/clang/include/clang/Basic/TargetCXXABI.h @@ -103,6 +103,12 @@ /// of these details is necessarily final yet. WebAssembly, + /// The Fuchsia ABI is a modified version of the Itanium ABI. + /// + /// The relevant changes from the Itanium ABI are: + /// - constructors and destructors return 'this', as in ARM. + Fuchsia, + /// The Microsoft ABI is the ABI used by Microsoft Visual Studio (and /// compatible compilers). /// @@ -133,6 +139,7 @@ /// Does this ABI generally fall into the Itanium family of ABIs? bool isItaniumFamily() const { switch (getKind()) { + case Fuchsia: case GenericAArch64: case GenericItanium: case GenericARM: @@ -152,6 +159,7 @@ /// Is this ABI an MSVC-compatible ABI? bool isMicrosoft() const { switch (getKind()) { + case Fuchsia: case GenericAArch64: case GenericItanium: case GenericARM: @@ -182,6 +190,7 @@ case WebAssembly: // WebAssembly doesn't require any special alignment for member functions. return false; + case Fuchsia: case GenericARM: case GenericAArch64: case GenericMIPS: @@ -257,6 +266,7 @@ /// done on a generic Itanium platform. bool canKeyFunctionBeInline() const { switch (getKind()) { + case Fuchsia: case GenericARM: case iOS64: case WebAssembly: @@ -309,6 +319,7 @@ // iOS on ARM64 and WebAssembly use the C++11 POD rules. They do not honor // the Itanium exception about classes with over-large bitfields. + case Fuchsia: case iOS64: case WebAssembly: case WatchOS: diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -771,6 +771,7 @@ if (!LangOpts.CPlusPlus) return nullptr; switch (T.getCXXABI().getKind()) { + case TargetCXXABI::Fuchsia: case TargetCXXABI::GenericARM: // Same as Itanium at this level case TargetCXXABI::iOS: case TargetCXXABI::iOS64: @@ -10169,6 +10170,7 @@ if (!T) T = Target; switch (T->getCXXABI().getKind()) { + case TargetCXXABI::Fuchsia: case TargetCXXABI::GenericAArch64: case TargetCXXABI::GenericItanium: case TargetCXXABI::GenericARM: diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h --- a/clang/lib/Basic/Targets/OSTargets.h +++ b/clang/lib/Basic/Targets/OSTargets.h @@ -808,6 +808,7 @@ FuchsiaTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) : OSTargetInfo(Triple, Opts) { this->MCountName = "__mcount"; + this->TheCXXABI.set(TargetCXXABI::Fuchsia); } }; diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -73,6 +73,7 @@ static CGCXXABI *createCXXABI(CodeGenModule &CGM) { switch (CGM.getTarget().getCXXABI().getKind()) { + case TargetCXXABI::Fuchsia: case TargetCXXABI::GenericAArch64: case TargetCXXABI::GenericARM: case TargetCXXABI::iOS: diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -487,6 +487,19 @@ bool shouldRTTIBeUnique() const override { return false; } }; +class FuchsiaCXXABI final : public ItaniumCXXABI { +public: + explicit FuchsiaCXXABI(CodeGen::CodeGenModule &CGM) + : ItaniumCXXABI(CGM) {} + +private: + bool HasThisReturn(GlobalDecl GD) const override { + return isa(GD.getDecl()) || + (isa(GD.getDecl()) && + GD.getDtorType() != Dtor_Deleting); + } +}; + class WebAssemblyCXXABI final : public ItaniumCXXABI { public: explicit WebAssemblyCXXABI(CodeGen::CodeGenModule &CGM) @@ -516,6 +529,9 @@ case TargetCXXABI::iOS64: return new iOS64CXXABI(CGM); + case TargetCXXABI::Fuchsia: + return new FuchsiaCXXABI(CGM); + // Note that AArch64 uses the generic ItaniumCXXABI class since it doesn't // include the other 32-bit ARM oddities: constructor/destructor return values // and array cookies. diff --git a/clang/test/CodeGenCXX/constructor-destructor-return-this.cpp b/clang/test/CodeGenCXX/constructor-destructor-return-this.cpp --- a/clang/test/CodeGenCXX/constructor-destructor-return-this.cpp +++ b/clang/test/CodeGenCXX/constructor-destructor-return-this.cpp @@ -3,6 +3,8 @@ //RUN: %clang_cc1 %s -emit-llvm -o - -triple=thumbv7-apple-ios5.0 -target-abi apcs-gnu | FileCheck --check-prefix=CHECKIOS5 %s //RUN: %clang_cc1 %s -emit-llvm -o - -triple=wasm32-unknown-unknown \ //RUN: | FileCheck --check-prefix=CHECKARM %s +//RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-unknown-fuchsia | FileCheck --check-prefix=CHECKFUCHSIA %s +//RUN: %clang_cc1 %s -emit-llvm -o - -triple=aarch64-unknown-fuchsia | FileCheck --check-prefix=CHECKFUCHSIA %s //RUN: %clang_cc1 %s -emit-llvm -o - -triple=i386-pc-win32 -fno-rtti | FileCheck --check-prefix=CHECKMS %s // FIXME: these tests crash on the bots when run with -triple=x86_64-pc-win32 @@ -45,6 +47,11 @@ // CHECKIOS5-LABEL: define %class.B* @_ZN1BD2Ev(%class.B* %this) // CHECKIOS5-LABEL: define %class.B* @_ZN1BD1Ev(%class.B* %this) +// CHECKFUCHSIA-LABEL: define %class.B* @_ZN1BC2EPi(%class.B* returned %this, i32* %i) +// CHECKFUCHSIA-LABEL: define %class.B* @_ZN1BC1EPi(%class.B* returned %this, i32* %i) +// CHECKFUCHSIA-LABEL: define %class.B* @_ZN1BD2Ev(%class.B* returned %this) +// CHECKFUCHSIA-LABEL: define %class.B* @_ZN1BD1Ev(%class.B* returned %this) + // CHECKMS-LABEL: define dso_local x86_thiscallcc %class.B* @"??0B@@QAE@PAH@Z"(%class.B* returned %this, i32* %i) // CHECKMS-LABEL: define dso_local x86_thiscallcc void @"??1B@@UAE@XZ"(%class.B* %this) @@ -83,6 +90,14 @@ // CHECKIOS5-LABEL: define void @_ZN1CD0Ev(%class.C* %this) // CHECKIOS5-LABEL: define void @_ZThn8_N1CD0Ev(%class.C* %this) +// CHECKFUCHSIA-LABEL: define %class.C* @_ZN1CC2EPiPc(%class.C* returned %this, i32* %i, i8* %c) +// CHECKFUCHSIA-LABEL: define %class.C* @_ZN1CC1EPiPc(%class.C* returned %this, i32* %i, i8* %c) +// CHECKFUCHSIA-LABEL: define %class.C* @_ZN1CD2Ev(%class.C* returned %this) +// CHECKFUCHSIA-LABEL: define %class.C* @_ZN1CD1Ev(%class.C* returned %this) +// CHECKFUCHSIA-LABEL: define %class.C* @_ZThn16_N1CD1Ev(%class.C* %this) +// CHECKFUCHSIA-LABEL: define void @_ZN1CD0Ev(%class.C* %this) +// CHECKFUCHSIA-LABEL: define void @_ZThn16_N1CD0Ev(%class.C* %this) + // CHECKMS-LABEL: define dso_local x86_thiscallcc %class.C* @"??0C@@QAE@PAHPAD@Z"(%class.C* returned %this, i32* %i, i8* %c) // CHECKMS-LABEL: define dso_local x86_thiscallcc void @"??1C@@UAE@XZ"(%class.C* %this) @@ -110,6 +125,11 @@ // CHECKIOS5-LABEL: define %class.D* @_ZN1DD2Ev(%class.D* %this, i8** %vtt) // CHECKIOS5-LABEL: define %class.D* @_ZN1DD1Ev(%class.D* %this) +// CHECKFUCHSIA-LABEL: define %class.D* @_ZN1DC2Ev(%class.D* returned %this, i8** %vtt) +// CHECKFUCHSIA-LABEL: define %class.D* @_ZN1DC1Ev(%class.D* returned %this) +// CHECKFUCHSIA-LABEL: define %class.D* @_ZN1DD2Ev(%class.D* returned %this, i8** %vtt) +// CHECKFUCHSIA-LABEL: define %class.D* @_ZN1DD1Ev(%class.D* returned %this) + // CHECKMS-LABEL: define dso_local x86_thiscallcc %class.D* @"??0D@@QAE@XZ"(%class.D* returned %this, i32 %is_most_derived) // CHECKMS-LABEL: define dso_local x86_thiscallcc void @"??1D@@UAE@XZ"(%class.D* %this) @@ -127,15 +147,15 @@ e2->~E(); } -// CHECKARM-LABEL: define void @_Z15test_destructorv() +// CHECKARM-LABEL,CHECKFUCHSIA-LABEL: define void @_Z15test_destructorv() // Verify that virtual calls to destructors are not marked with a 'returned' // this parameter at the call site... -// CHECKARM: [[VFN:%.*]] = getelementptr inbounds %class.E* (%class.E*)*, %class.E* (%class.E*)** -// CHECKARM: [[THUNK:%.*]] = load %class.E* (%class.E*)*, %class.E* (%class.E*)** [[VFN]] -// CHECKARM: call %class.E* [[THUNK]](%class.E* % +// CHECKARM,CHECKFUCHSIA: [[VFN:%.*]] = getelementptr inbounds %class.E* (%class.E*)*, %class.E* (%class.E*)** +// CHECKARM,CHECKFUCHSIA: [[THUNK:%.*]] = load %class.E* (%class.E*)*, %class.E* (%class.E*)** [[VFN]] +// CHECKARM,CHECKFUCHSIA: call %class.E* [[THUNK]](%class.E* % // ...but static calls create declarations with 'returned' this -// CHECKARM: {{%.*}} = call %class.E* @_ZN1ED1Ev(%class.E* % +// CHECKARM,CHECKFUCHSIA: {{%.*}} = call %class.E* @_ZN1ED1Ev(%class.E* % -// CHECKARM: declare %class.E* @_ZN1ED1Ev(%class.E* returned) +// CHECKARM,CHECKFUCHSIA: declare %class.E* @_ZN1ED1Ev(%class.E* returned)