mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-09 01:29:52 +00:00
Revert r285664, cxx-abi-dev chose to go in a different direction for the ABI here.
llvm-svn: 288304
This commit is contained in:
parent
3dade419bf
commit
b17d6fa5b3
@ -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">,
|
||||
|
@ -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.
|
||||
|
@ -47,7 +47,6 @@ protected:
|
||||
bool UseARMMethodPtrABI;
|
||||
bool UseARMGuardVarABI;
|
||||
bool Use32BitVTableOffsetABI;
|
||||
bool UseQualifiedFunctionTypeInfoABI;
|
||||
|
||||
ItaniumMangleContext &getMangleContext() {
|
||||
return cast<ItaniumMangleContext>(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<FunctionType>(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<FunctionType>(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<FunctionProtoType>(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<FunctionProtoType>(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) {
|
||||
|
@ -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 =
|
||||
|
@ -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;
|
||||
}
|
@ -612,7 +612,9 @@ as the draft C++1z standard evolves.
|
||||
<tr>
|
||||
<td>Make exception specifications part of the type system</td>
|
||||
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0012r1.html">P0012R1</a></td>
|
||||
<td class="svn" align="center">SVN <a href="#p0012">(9)</a></td>
|
||||
<td class="partial" align="center">Partial</td>
|
||||
<!-- We don't correctly support throwing noexcept function types and
|
||||
catching as non-noexcept yet. -->
|
||||
</tr>
|
||||
<tr>
|
||||
<td><tt>__has_include</tt> in preprocessor conditionals</td>
|
||||
@ -622,7 +624,7 @@ as the draft C++1z standard evolves.
|
||||
<tr>
|
||||
<td>New specification for inheriting constructors (<a href="cxx_dr_status.html#1941">DR1941</a> et al)</td>
|
||||
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/p0136r1.html">P0136R1</a></td>
|
||||
<td class="full" align="center">Clang 3.9 <a href="#p0136">(10)</a></td>
|
||||
<td class="full" align="center">Clang 3.9 <a href="#p0136">(9)</a></td>
|
||||
</tr>
|
||||
<!-- Jacksonville papers -->
|
||||
<tr>
|
||||
@ -699,7 +701,7 @@ as the draft C++1z standard evolves.
|
||||
<tr>
|
||||
<td rowspan=2>Stricter expression evaluation order</td>
|
||||
<td><a href="http://wg21.link/p0145r3">P0145R3</a></td>
|
||||
<td class="svn" align="center" rowspan=2>SVN <a href="#p0145">(11)</a></td>
|
||||
<td class="svn" align="center" rowspan=2>SVN <a href="#p0145">(10)</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="http://wg21.link/p0400r0">P0400R0</a></td>
|
||||
@ -755,18 +757,10 @@ all language versions that allow type deduction from <tt>auto</tt>
|
||||
(per the request of the C++ committee).
|
||||
In Clang 3.7, a warning is emitted for all cases that would change meaning.
|
||||
</span><br>
|
||||
<span id="p0012">(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
|
||||
<code>-Xclang -mqualified-function-type-info</code> flag. This flag is likely
|
||||
to be removed or replaced in future Clang releases.
|
||||
</span><br>
|
||||
<span id="p0136">(10): This is the resolution to a Defect Report, so is applied
|
||||
<span id="p0136">(9): This is the resolution to a Defect Report, so is applied
|
||||
to all language versions supporting inheriting constructors.
|
||||
</span><br>
|
||||
<span id="p0145">(11): Under the MS ABI, function parameters are destroyed from
|
||||
<span id="p0145">(10): Under the MS ABI, function parameters are destroyed from
|
||||
left to right in the callee. As a result, function parameters in calls to
|
||||
<tt>operator<<</tt>, <tt>operator>></tt>, <tt>operator->*</tt>,
|
||||
<tt>operator&&</tt>, <tt>operator||</tt>, and <tt>operator,</tt>
|
||||
|
Loading…
Reference in New Issue
Block a user