mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-09 01:29:52 +00:00
P0012R1: add Itanium ABI support for throwing non-noexcept function pointers and catching as noexcept.
llvm-svn: 288305
This commit is contained in:
parent
b17d6fa5b3
commit
a7d9378761
@ -2474,7 +2474,13 @@ public:
|
||||
|
||||
/// PTI_ContainingClassIncomplete - Containing class is incomplete.
|
||||
/// (in pointer to member).
|
||||
PTI_ContainingClassIncomplete = 0x10
|
||||
PTI_ContainingClassIncomplete = 0x10,
|
||||
|
||||
/// PTI_TransactionSafe - Pointee is transaction_safe function (C++ TM TS).
|
||||
//PTI_TransactionSafe = 0x20,
|
||||
|
||||
/// PTI_Noexcept - Pointee is noexcept function (C++1z).
|
||||
PTI_Noexcept = 0x40,
|
||||
};
|
||||
|
||||
// VMI type info flags.
|
||||
@ -3124,21 +3130,6 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(QualType Ty, bool Force,
|
||||
return llvm::ConstantExpr::getBitCast(GV, CGM.Int8PtrTy);
|
||||
}
|
||||
|
||||
/// ComputeQualifierFlags - Compute the pointer type info flags from the
|
||||
/// given qualifier.
|
||||
static unsigned ComputeQualifierFlags(Qualifiers Quals) {
|
||||
unsigned Flags = 0;
|
||||
|
||||
if (Quals.hasConst())
|
||||
Flags |= ItaniumRTTIBuilder::PTI_Const;
|
||||
if (Quals.hasVolatile())
|
||||
Flags |= ItaniumRTTIBuilder::PTI_Volatile;
|
||||
if (Quals.hasRestrict())
|
||||
Flags |= ItaniumRTTIBuilder::PTI_Restrict;
|
||||
|
||||
return Flags;
|
||||
}
|
||||
|
||||
/// BuildObjCObjectTypeInfo - Build the appropriate kind of type_info
|
||||
/// for the given Objective-C object type.
|
||||
void ItaniumRTTIBuilder::BuildObjCObjectTypeInfo(const ObjCObjectType *OT) {
|
||||
@ -3322,23 +3313,44 @@ void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) {
|
||||
}
|
||||
}
|
||||
|
||||
/// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct,
|
||||
/// used for pointer types.
|
||||
void ItaniumRTTIBuilder::BuildPointerTypeInfo(QualType PointeeTy) {
|
||||
Qualifiers Quals;
|
||||
QualType UnqualifiedPointeeTy =
|
||||
CGM.getContext().getUnqualifiedArrayType(PointeeTy, Quals);
|
||||
/// Compute the flags for a __pbase_type_info, and remove the corresponding
|
||||
/// pieces from \p Type.
|
||||
static unsigned extractPBaseFlags(ASTContext &Ctx, QualType &Type) {
|
||||
unsigned Flags = 0;
|
||||
|
||||
// Itanium C++ ABI 2.9.5p7:
|
||||
// __flags is a flag word describing the cv-qualification and other
|
||||
// attributes of the type pointed to
|
||||
unsigned Flags = ComputeQualifierFlags(Quals);
|
||||
if (Type.isConstQualified())
|
||||
Flags |= ItaniumRTTIBuilder::PTI_Const;
|
||||
if (Type.isVolatileQualified())
|
||||
Flags |= ItaniumRTTIBuilder::PTI_Volatile;
|
||||
if (Type.isRestrictQualified())
|
||||
Flags |= ItaniumRTTIBuilder::PTI_Restrict;
|
||||
Type = Type.getUnqualifiedType();
|
||||
|
||||
// Itanium C++ ABI 2.9.5p7:
|
||||
// When the abi::__pbase_type_info is for a direct or indirect pointer to an
|
||||
// incomplete class type, the incomplete target type flag is set.
|
||||
if (ContainsIncompleteClassType(UnqualifiedPointeeTy))
|
||||
Flags |= PTI_Incomplete;
|
||||
if (ContainsIncompleteClassType(Type))
|
||||
Flags |= ItaniumRTTIBuilder::PTI_Incomplete;
|
||||
|
||||
if (auto *Proto = Type->getAs<FunctionProtoType>()) {
|
||||
if (Proto->isNothrow(Ctx)) {
|
||||
Flags |= ItaniumRTTIBuilder::PTI_Noexcept;
|
||||
Type = Ctx.getFunctionType(
|
||||
Proto->getReturnType(), Proto->getParamTypes(),
|
||||
Proto->getExtProtoInfo().withExceptionSpec(EST_None));
|
||||
}
|
||||
}
|
||||
|
||||
return Flags;
|
||||
}
|
||||
|
||||
/// BuildPointerTypeInfo - Build an abi::__pointer_type_info struct,
|
||||
/// used for pointer types.
|
||||
void ItaniumRTTIBuilder::BuildPointerTypeInfo(QualType PointeeTy) {
|
||||
// Itanium C++ ABI 2.9.5p7:
|
||||
// __flags is a flag word describing the cv-qualification and other
|
||||
// attributes of the type pointed to
|
||||
unsigned Flags = extractPBaseFlags(CGM.getContext(), PointeeTy);
|
||||
|
||||
llvm::Type *UnsignedIntLTy =
|
||||
CGM.getTypes().ConvertType(CGM.getContext().UnsignedIntTy);
|
||||
@ -3348,7 +3360,7 @@ void ItaniumRTTIBuilder::BuildPointerTypeInfo(QualType PointeeTy) {
|
||||
// __pointee is a pointer to the std::type_info derivation for the
|
||||
// unqualified type being pointed to.
|
||||
llvm::Constant *PointeeTypeInfo =
|
||||
ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(UnqualifiedPointeeTy);
|
||||
ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(PointeeTy);
|
||||
Fields.push_back(PointeeTypeInfo);
|
||||
}
|
||||
|
||||
@ -3358,23 +3370,12 @@ void
|
||||
ItaniumRTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) {
|
||||
QualType PointeeTy = Ty->getPointeeType();
|
||||
|
||||
Qualifiers Quals;
|
||||
QualType UnqualifiedPointeeTy =
|
||||
CGM.getContext().getUnqualifiedArrayType(PointeeTy, Quals);
|
||||
|
||||
// Itanium C++ ABI 2.9.5p7:
|
||||
// __flags is a flag word describing the cv-qualification and other
|
||||
// attributes of the type pointed to.
|
||||
unsigned Flags = ComputeQualifierFlags(Quals);
|
||||
unsigned Flags = extractPBaseFlags(CGM.getContext(), PointeeTy);
|
||||
|
||||
const RecordType *ClassType = cast<RecordType>(Ty->getClass());
|
||||
|
||||
// Itanium C++ ABI 2.9.5p7:
|
||||
// When the abi::__pbase_type_info is for a direct or indirect pointer to an
|
||||
// incomplete class type, the incomplete target type flag is set.
|
||||
if (ContainsIncompleteClassType(UnqualifiedPointeeTy))
|
||||
Flags |= PTI_Incomplete;
|
||||
|
||||
if (IsIncompleteClassType(ClassType))
|
||||
Flags |= PTI_ContainingClassIncomplete;
|
||||
|
||||
@ -3386,7 +3387,7 @@ ItaniumRTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) {
|
||||
// __pointee is a pointer to the std::type_info derivation for the
|
||||
// unqualified type being pointed to.
|
||||
llvm::Constant *PointeeTypeInfo =
|
||||
ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(UnqualifiedPointeeTy);
|
||||
ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(PointeeTy);
|
||||
Fields.push_back(PointeeTypeInfo);
|
||||
|
||||
// Itanium C++ ABI 2.9.5p9:
|
||||
|
23
clang/test/CodeGenCXX/rtti-qualfn.cpp
Normal file
23
clang/test/CodeGenCXX/rtti-qualfn.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
// RUN: %clang_cc1 -std=c++1z -I%S %s -triple x86_64-linux-gnu -emit-llvm -o - -fcxx-exceptions | FileCheck %s
|
||||
|
||||
#include "typeinfo"
|
||||
|
||||
struct A {};
|
||||
|
||||
// CHECK-DAG: @_ZTIFvvE = linkonce_odr constant { i8*, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv120__function_type_infoE, i64 2) to i8*), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @_ZTSFvvE, i32 0, i32 0) }, comdat
|
||||
// CHECK-DAG: @_ZTIPDoFvvE = linkonce_odr constant { i8*, i8*, i32, i8* } { i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv119__pointer_type_infoE, i64 2) to i8*), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @_ZTSPDoFvvE, i32 0, i32 0), i32 64, i8* bitcast ({ i8*, i8* }* @_ZTIFvvE to i8*) }, comdat
|
||||
auto &ti_noexcept_ptr = typeid(void (A::*)() noexcept);
|
||||
// CHECK-DAG: @_ZTIM1ADoFvvE = 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 ([10 x i8], [10 x i8]* @_ZTSM1ADoFvvE, i32 0, i32 0), i32 64, i8* bitcast ({ i8*, i8* }* @_ZTIFvvE to i8*), i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*) }, comdat
|
||||
auto &ti_noexcept_memptr = typeid(void (A::*)() 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,9 +612,7 @@ 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="partial" align="center">Partial</td>
|
||||
<!-- We don't correctly support throwing noexcept function types and
|
||||
catching as non-noexcept yet. -->
|
||||
<td class="svn" align="center">SVN</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><tt>__has_include</tt> in preprocessor conditionals</td>
|
||||
|
Loading…
Reference in New Issue
Block a user