From: Richard Smith Date: Thu, 1 Dec 2016 03:04:07 +0000 (+0000) Subject: Revert r285664, cxx-abi-dev chose to go in a different direction for the ABI here. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f865452420264672cffaf8d88f2b8a21776ff418;p=clang Revert r285664, cxx-abi-dev chose to go in a different direction for the ABI here. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@288304 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index 68593e9227..5f4512d4c2 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -251,8 +251,6 @@ def munwind_tables : Flag<["-"], "munwind-tables">, HelpText<"Generate unwinding tables for all functions">; def mconstructor_aliases : Flag<["-"], "mconstructor-aliases">, HelpText<"Emit complete constructors and destructors as aliases when possible">; -def mqualified_function_type_info : Flag<["-"], "mqualified-function-type-info">, - HelpText<"Emit __qualified_function_type_info for qualified function types">; def mlink_bitcode_file : Separate<["-"], "mlink-bitcode-file">, HelpText<"Link the given bitcode file before performing optimizations.">; def mlink_cuda_bitcode : Separate<["-"], "mlink-cuda-bitcode">, diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def index 05b0a33326..e33ec9e32c 100644 --- a/include/clang/Frontend/CodeGenOptions.def +++ b/include/clang/Frontend/CodeGenOptions.def @@ -133,7 +133,6 @@ CODEGENOPT(DumpCoverageMapping , 1, 0) ///< Dump the generated coverage mapping /// If -fpcc-struct-return or -freg-struct-return is specified. ENUM_CODEGENOPT(StructReturnConvention, StructReturnConventionKind, 2, SRCK_Default) -CODEGENOPT(QualifiedFunctionTypeInfo, 1, 0) ///< Use __qualified_function_type_info. CODEGENOPT(RelaxAll , 1, 0) ///< Relax all machine code instructions. CODEGENOPT(RelaxedAliasing , 1, 0) ///< Set when -fno-strict-aliasing is enabled. CODEGENOPT(StructPathTBAA , 1, 0) ///< Whether or not to use struct-path TBAA. diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp index 1fb7a36e21..1e506d4655 100644 --- a/lib/CodeGen/ItaniumCXXABI.cpp +++ b/lib/CodeGen/ItaniumCXXABI.cpp @@ -47,7 +47,6 @@ protected: bool UseARMMethodPtrABI; bool UseARMGuardVarABI; bool Use32BitVTableOffsetABI; - bool UseQualifiedFunctionTypeInfoABI; ItaniumMangleContext &getMangleContext() { return cast(CodeGen::CGCXXABI::getMangleContext()); @@ -59,8 +58,7 @@ public: bool UseARMGuardVarABI = false) : CGCXXABI(CGM), UseARMMethodPtrABI(UseARMMethodPtrABI), UseARMGuardVarABI(UseARMGuardVarABI), - Use32BitVTableOffsetABI(false), - UseQualifiedFunctionTypeInfoABI(CGM.getCodeGenOpts().QualifiedFunctionTypeInfo) { } + Use32BitVTableOffsetABI(false) { } bool classifyReturnType(CGFunctionInfo &FI) const override; @@ -2432,9 +2430,6 @@ class ItaniumRTTIBuilder { /// descriptor of the given type. llvm::Constant *GetAddrOfExternalRTTIDescriptor(QualType Ty); - /// Determine whether FnTy should be emitted as a qualified function type. - bool EmitAsQualifiedFunctionType(const FunctionType *FnTy); - /// BuildVTablePointer - Build the vtable pointer for the given type. void BuildVTablePointer(const Type *Ty); @@ -2447,10 +2442,6 @@ class ItaniumRTTIBuilder { /// constraints, according ti the Itanium C++ ABI, 2.9.5p5c. void BuildVMIClassTypeInfo(const CXXRecordDecl *RD); - /// Build an abi::__qualified_function_type_info struct, used for function - /// types with various kinds of qualifiers. - void BuildQualifiedFunctionTypeInfo(const FunctionType *FnTy); - /// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct, used /// for pointer types. void BuildPointerTypeInfo(QualType PointeeTy); @@ -2467,27 +2458,6 @@ public: ItaniumRTTIBuilder(const ItaniumCXXABI &ABI) : CGM(ABI.CGM), VMContext(CGM.getModule().getContext()), CXXABI(ABI) {} - // Function type info flags. - enum { - /// Qualifiers for 'this' pointer of member function type. - //@{ - QFTI_Const = 0x1, - QFTI_Volatile = 0x2, - QFTI_Restrict = 0x4, - QFTI_LValRef = 0x8, - QFTI_RValRef = 0x10, - //@} - - /// Noexcept function qualifier (C++17 onwards). - QFTI_Noexcept = 0x20, - - // Transaction-safe function qualifier (Transactional Memory TS). - //QFTI_TxSafe = 0x40, - - /// Noreturn function type qualifier (GNU/Clang extension). - QFTI_Noreturn = 0x80 - }; - // Pointer type info flags. enum { /// PTI_Const - Type has const qualifier. @@ -2839,12 +2809,8 @@ void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty) { case Type::FunctionNoProto: case Type::FunctionProto: - if (EmitAsQualifiedFunctionType(cast(Ty))) - // abi::__qualified_function_type_info. - VTableName = "_ZTVN10__cxxabiv130__qualified_function_type_infoE"; - else - // abi::__function_type_info. - VTableName = "_ZTVN10__cxxabiv120__function_type_infoE"; + // abi::__function_type_info. + VTableName = "_ZTVN10__cxxabiv120__function_type_infoE"; break; case Type::Enum: @@ -3058,15 +3024,10 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty, bool Force, break; case Type::FunctionNoProto: - case Type::FunctionProto: { - auto *FnTy = cast(Ty); + case Type::FunctionProto: // Itanium C++ ABI 2.9.5p5: // abi::__function_type_info adds no data members to std::type_info. - if (EmitAsQualifiedFunctionType(FnTy)) - // abi::__qualified_type_info adds a base function type and qualifiers. - BuildQualifiedFunctionTypeInfo(FnTy); break; - } case Type::Enum: // Itanium C++ ABI 2.9.5p5: @@ -3361,72 +3322,6 @@ void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) { } } -bool ItaniumRTTIBuilder::EmitAsQualifiedFunctionType(const FunctionType *FnTy) { - if (!CXXABI.UseQualifiedFunctionTypeInfoABI) - return false; - - auto *FPT = dyn_cast(FnTy); - if (!FPT) - return false; - return FPT->getTypeQuals() || FPT->getRefQualifier() != RQ_None || - FPT->isNothrow(CXXABI.getContext()) || FPT->getNoReturnAttr(); -} - -void ItaniumRTTIBuilder::BuildQualifiedFunctionTypeInfo( - const FunctionType *FnTy) { - unsigned int Qualifiers = 0; - - auto ExtInfo = FnTy->getExtInfo(); - if (ExtInfo.getNoReturn()) { - Qualifiers |= QFTI_Noreturn; - ExtInfo = ExtInfo.withNoReturn(false); - } - - QualType BaseType; - if (auto *FPT = dyn_cast(FnTy)) { - auto EPI = FPT->getExtProtoInfo(); - EPI.ExtInfo = ExtInfo; - - if (EPI.TypeQuals & Qualifiers::Const) - Qualifiers |= QFTI_Const; - if (EPI.TypeQuals & Qualifiers::Volatile) - Qualifiers |= QFTI_Volatile; - if (EPI.TypeQuals & Qualifiers::Restrict) - Qualifiers |= QFTI_Restrict; - EPI.TypeQuals = 0; - - if (EPI.RefQualifier == RQ_LValue) - Qualifiers |= QFTI_LValRef; - else if (EPI.RefQualifier == RQ_RValue) - Qualifiers |= QFTI_RValRef; - EPI.RefQualifier = RQ_None; - - if (EPI.ExceptionSpec.Type == EST_BasicNoexcept) - Qualifiers |= QFTI_Noexcept; - else - assert(EPI.ExceptionSpec.Type == EST_None && - "unexpected canonical non-dependent exception spec"); - EPI.ExceptionSpec.Type = EST_None; - - BaseType = CXXABI.getContext().getFunctionType(FPT->getReturnType(), - FPT->getParamTypes(), EPI); - } else { - BaseType = - QualType(CXXABI.getContext().adjustFunctionType(FnTy, ExtInfo), 0); - } - - assert(Qualifiers && "should not have created qualified type info"); - - // __base_type is a pointer to the std::type_info derivation for the - // unqualified version of the function type. - Fields.push_back(ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(BaseType)); - - // __qualifiers is a flag word describing the qualifiers of the function type. - llvm::Type *UnsignedIntLTy = - CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy); - Fields.push_back(llvm::ConstantInt::get(UnsignedIntLTy, Qualifiers)); -} - /// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct, /// used for pointer types. void ItaniumRTTIBuilder::BuildPointerTypeInfo(QualType PointeeTy) { diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 874827b7e5..af1ab07151 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -556,7 +556,6 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.ObjCAutoRefCountExceptions = Args.hasArg(OPT_fobjc_arc_exceptions); Opts.CXAAtExit = !Args.hasArg(OPT_fno_use_cxa_atexit); Opts.CXXCtorDtorAliases = Args.hasArg(OPT_mconstructor_aliases); - Opts.QualifiedFunctionTypeInfo = Args.hasArg(OPT_mqualified_function_type_info); Opts.CodeModel = getCodeModel(Args, Diags); Opts.DebugPass = Args.getLastArgValue(OPT_mdebug_pass); Opts.DisableFPElim = diff --git a/test/CodeGenCXX/rtti-qualfn.cpp b/test/CodeGenCXX/rtti-qualfn.cpp deleted file mode 100644 index 879c21b21a..0000000000 --- a/test/CodeGenCXX/rtti-qualfn.cpp +++ /dev/null @@ -1,51 +0,0 @@ -// RUN: %clang_cc1 -std=c++1z -mqualified-function-type-info -I%S %s -triple x86_64-linux-gnu -emit-llvm -o - -fcxx-exceptions | FileCheck %s - -#include "typeinfo" - -struct A {}; - -// CHECK-DAG: @_ZTIKFvvE = [[QFTI:linkonce_odr constant { i8\*, i8\*, i8\*, i32 } { i8\* bitcast \(i8\*\* getelementptr inbounds \(i8\*, i8\*\* @_ZTVN10__cxxabiv130__qualified_function_type_infoE, i64 2\) to i8\*\),]] i8* getelementptr inbounds ([6 x i8], [6 x i8]* @_ZTSKFvvE, i32 0, i32 0), i8* bitcast ({ i8*, i8* }* @_ZTIFvvE to i8*), i32 1 }, comdat -// CHECK-DAG: @_ZTIM1AKFvvE = [[PMFTI:linkonce_odr constant { i8\*, i8\*, i32, i8\*, i8\* } { i8\* bitcast \(i8\*\* getelementptr inbounds \(i8\*, i8\*\* @_ZTVN10__cxxabiv129__pointer_to_member_type_infoE, i64 2\) to i8\*\),]] i8* getelementptr inbounds ([9 x i8], [9 x i8]* @_ZTSM1AKFvvE, i32 0, i32 0), i32 0, i8* bitcast ({ i8*, i8*, i8*, i32 }* @_ZTIKFvvE to i8*), i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*) }, comdat -auto &ti_const = typeid(void (A::*)() const); - -// CHECK-DAG: @_ZTIVFvvE = [[QFTI]] {{.*}} @_ZTIFvvE {{.*}}, i32 2 }, comdat -// CHECK-DAG: @_ZTIM1AVFvvE = [[PMFTI]] {{.*}}), i32 0, {{.*}} @_ZTIVFvvE -auto &ti_volatile = typeid(void (A::*)() volatile); - -// CHECK-DAG: @_ZTIrFvvE = [[QFTI]] {{.*}} @_ZTIFvvE {{.*}}, i32 4 }, comdat -// CHECK-DAG: @_ZTIM1ArFvvE = [[PMFTI]] {{.*}}), i32 0, {{.*}} @_ZTIrFvvE -auto &ti_restrict = typeid(void (A::*)() __restrict); - -// CHECK-DAG: @_ZTIFvvRE = [[QFTI]] {{.*}} @_ZTIFvvE {{.*}}, i32 8 }, comdat -// CHECK-DAG: @_ZTIM1AFvvRE = [[PMFTI]] {{.*}}), i32 0, {{.*}} @_ZTIFvvRE -auto &ti_lref = typeid(void (A::*)() &); - -// CHECK-DAG: @_ZTIFvvOE = [[QFTI]] {{.*}} @_ZTIFvvE {{.*}}, i32 16 }, comdat -// CHECK-DAG: @_ZTIM1AFvvOE = [[PMFTI]] {{.*}}), i32 0, {{.*}} @_ZTIFvvOE -auto &ti_rref = typeid(void (A::*)() &&); - -// CHECK-DAG: @_ZTIDoFvvE = [[QFTI]] {{.*}} @_ZTIFvvE {{.*}}, i32 32 }, comdat -// CHECK-DAG: @_ZTIM1ADoFvvE = [[PMFTI]] {{.*}}), i32 0, {{.*}} @_ZTIDoFvvE -auto &ti_noexcept = typeid(void (A::*)() noexcept); - -//auto &ti_txsafe = typeid(void (A::*)() transaction_safe); - -// FIXME: Produce the typeinfo for a noreturn function type here? -// CHECK-DAG: @_ZTIM1AFvvE = [[PMFTI]] {{.*}}), i32 0, {{.*}} @_ZTIFvvE -auto &ti_noreturn = typeid(void __attribute__((noreturn)) (A::*)()); - -// CHECK-DAG: @_ZTIrVKDoFvvRE = [[QFTI]] {{.*}} @_ZTIFvvE {{.*}}, i32 47 }, comdat -// CHECK-DAG: @_ZTIM1ArVKDoFvvRE = [[PMFTI]] {{.*}}), i32 0, {{.*}} @_ZTIrVKDoFvvRE -auto &ti_rainbow = typeid(void (A::*)() const volatile __restrict & noexcept); - -// CHECK-LABEL: define void @_Z1fv( -__attribute__((noreturn)) void f() noexcept { - // CHECK: call void @__cxa_throw({{.*}}@_ZTIPDoFvvE - throw f; -} - -// CHECK-LABEL: define void @_Z1gM1ADoFvvE( -void g(__attribute__((noreturn)) void (A::*p)() noexcept) { - // CHECK: call void @__cxa_throw({{.*}}@_ZTIM1ADoFvvE - throw p; -} diff --git a/www/cxx_status.html b/www/cxx_status.html index bdaaf174fc..86d65d18de 100644 --- a/www/cxx_status.html +++ b/www/cxx_status.html @@ -612,7 +612,9 @@ as the draft C++1z standard evolves. Make exception specifications part of the type system P0012R1 - SVN (9) + Partial + __has_include in preprocessor conditionals @@ -622,7 +624,7 @@ as the draft C++1z standard evolves. New specification for inheriting constructors (DR1941 et al) P0136R1 - Clang 3.9 (10) + Clang 3.9 (9) @@ -699,7 +701,7 @@ as the draft C++1z standard evolves. Stricter expression evaluation order P0145R3 - SVN (11) + SVN (10) P0400R0 @@ -755,18 +757,10 @@ all language versions that allow type deduction from auto (per the request of the C++ committee). In Clang 3.7, a warning is emitted for all cases that would change meaning.
-(9): Support for throwing a noexcept function pointer and -catching it as a non-noexcept function pointer requires an ABI library with -C++17 support. Currently, only libc++abi 4.0 provides this support, so this -portion of the feature is disabled by default. If you are using a sufficiently -recent ABI library, you can enable support for this feature with the --Xclang -mqualified-function-type-info flag. This flag is likely -to be removed or replaced in future Clang releases. -
-(10): This is the resolution to a Defect Report, so is applied +(9): This is the resolution to a Defect Report, so is applied to all language versions supporting inheriting constructors.
-(11): Under the MS ABI, function parameters are destroyed from +(10): Under the MS ABI, function parameters are destroyed from left to right in the callee. As a result, function parameters in calls to operator<<, operator>>, operator->*, operator&&, operator||, and operator,