Skip to content

Commit bedfee0

Browse files
authored
[CIR] Upstream TypeInfo attribute (llvm#159426)
This change adds support for TypeInfoAttr which is needed later for RTTI in exceptions Issue llvm#154992
1 parent 21f5f32 commit bedfee0

File tree

5 files changed

+117
-4
lines changed

5 files changed

+117
-4
lines changed

clang/include/clang/CIR/Dialect/IR/CIRAttrConstraints.td

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,27 @@ def CIR_AnyIntOrFloatAttr : AnyAttrOf<[CIR_AnyIntAttr, CIR_AnyFPAttr],
3838
string cppType = "::mlir::TypedAttr";
3939
}
4040

41+
//===----------------------------------------------------------------------===//
42+
// GlobalViewAttr constraints
43+
//===----------------------------------------------------------------------===//
44+
45+
def CIR_AnyGlobalViewAttr : CIR_AttrConstraint<"::cir::GlobalViewAttr", "GlobalView attribute">;
46+
47+
def CIR_AnyIntOrGlobalViewAttr : AnyAttrOf<[CIR_AnyIntAttr, CIR_AnyGlobalViewAttr],
48+
"integer or global view attribute"> {
49+
string cppType = "::mlir::TypedAttr";
50+
}
51+
4152
//===----------------------------------------------------------------------===//
4253
// ArrayAttr constraints
4354
//===----------------------------------------------------------------------===//
4455

4556
def CIR_IntArrayAttr : TypedArrayAttrBase<CIR_AnyIntAttr,
4657
"integer array attribute">;
4758

59+
def CIR_IntOrGlobalViewArrayAttr : TypedArrayAttrBase<CIR_AnyIntOrGlobalViewAttr,
60+
"integer or global view array attribute">{
61+
string cppType = "::mlir::ArrayAttr";
62+
}
63+
4864
#endif // CLANG_CIR_DIALECT_IR_CIRATTRCONSTRAINTS_TD

clang/include/clang/CIR/Dialect/IR/CIRAttrs.td

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -779,4 +779,56 @@ def CIR_AddressPointAttr : CIR_Attr<"AddressPoint", "address_point"> {
779779
}];
780780
}
781781

782+
//===----------------------------------------------------------------------===//
783+
// TypeInfoAttr
784+
//===----------------------------------------------------------------------===//
785+
786+
def CIR_TypeInfoAttr : CIR_Attr<"TypeInfo", "typeinfo", [TypedAttrInterface]> {
787+
let summary = "Represents a typeinfo used for RTTI";
788+
let description = [{
789+
The typeinfo data for a given class is stored into an ArrayAttr. The
790+
layout is determined by the C++ ABI used (clang only implements
791+
itanium on CIRGen).
792+
793+
The verifier enforces that the output type is always a `!cir.record`,
794+
and that the ArrayAttr element types match the equivalent member type
795+
for the resulting record, i.e, a GlobalViewAttr for symbol reference or
796+
an IntAttr for flags.
797+
798+
Example:
799+
800+
```
801+
cir.global "private" external @_ZTVN10__cxxabiv120__si_class_type_infoE
802+
: !cir.ptr<i32>
803+
804+
!rec_anon_struct = !cir.record<struct {!cir.ptr<!u8i>, !cir.ptr<!u8i>,
805+
!cir.ptr<!u8i>}>
806+
807+
cir.global constant external @type_info = #cir.typeinfo<{
808+
#cir.global_view<@_ZTVN10__cxxabiv120__si_class_type_infoE, [2 : i32]>
809+
: !cir.ptr<!u8i>, #cir.global_view<@_ZTS1B> : !cir.ptr<!u8i>,
810+
#cir.global_view<@_ZTI1A> : !cir.ptr<!u8i>}> : !rec_anon_struct
811+
```
812+
}];
813+
814+
let parameters = (ins
815+
AttributeSelfTypeParameter<"">:$type,
816+
CIR_IntOrGlobalViewArrayAttr:$data
817+
);
818+
819+
let builders = [
820+
AttrBuilderWithInferredContext<(ins "mlir::Type":$type,
821+
"mlir::ArrayAttr":$data), [{
822+
return $_get(type.getContext(), type, data);
823+
}]>
824+
];
825+
826+
// Checks record element types should match the array for every equivalent
827+
// element type.
828+
let genVerifyDecl = 1;
829+
let assemblyFormat = [{
830+
`<` custom<RecordMembers>($data) `>`
831+
}];
832+
}
833+
782834
#endif // CLANG_CIR_DIALECT_IR_CIRATTRS_TD

clang/lib/CIR/Dialect/IR/CIRDialect.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@
2626
#include "llvm/ADT/SmallSet.h"
2727
#include "llvm/Support/LogicalResult.h"
2828

29-
#include <numeric>
30-
3129
using namespace mlir;
3230
using namespace cir;
3331

@@ -342,8 +340,8 @@ static LogicalResult checkConstantTypes(mlir::Operation *op, mlir::Type opType,
342340

343341
if (mlir::isa<cir::ConstArrayAttr, cir::ConstVectorAttr,
344342
cir::ConstComplexAttr, cir::ConstRecordAttr,
345-
cir::GlobalViewAttr, cir::PoisonAttr, cir::VTableAttr>(
346-
attrType))
343+
cir::GlobalViewAttr, cir::PoisonAttr, cir::TypeInfoAttr,
344+
cir::VTableAttr>(attrType))
347345
return success();
348346

349347
assert(isa<TypedAttr>(attrType) && "What else could we be looking at here?");
@@ -2741,6 +2739,20 @@ LogicalResult cir::AtomicCmpXchg::verify() {
27412739
return success();
27422740
}
27432741

2742+
//===----------------------------------------------------------------------===//
2743+
// TypeInfoAttr
2744+
//===----------------------------------------------------------------------===//
2745+
2746+
LogicalResult cir::TypeInfoAttr::verify(
2747+
::llvm::function_ref<::mlir::InFlightDiagnostic()> emitError,
2748+
::mlir::Type type, ::mlir::ArrayAttr typeInfoData) {
2749+
2750+
if (cir::ConstRecordAttr::verify(emitError, type, typeInfoData).failed())
2751+
return failure();
2752+
2753+
return success();
2754+
}
2755+
27442756
//===----------------------------------------------------------------------===//
27452757
// TableGen'd op method definitions
27462758
//===----------------------------------------------------------------------===//

clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ class CIRAttrToValue {
235235
mlir::Value visitCirAttr(cir::ConstRecordAttr attr);
236236
mlir::Value visitCirAttr(cir::ConstVectorAttr attr);
237237
mlir::Value visitCirAttr(cir::GlobalViewAttr attr);
238+
mlir::Value visitCirAttr(cir::TypeInfoAttr attr);
238239
mlir::Value visitCirAttr(cir::VTableAttr attr);
239240
mlir::Value visitCirAttr(cir::ZeroAttr attr);
240241

@@ -521,6 +522,21 @@ mlir::Value CIRAttrToValue::visitCirAttr(cir::GlobalViewAttr globalAttr) {
521522
llvm_unreachable("Expecting pointer or integer type for GlobalViewAttr");
522523
}
523524

525+
// TypeInfoAttr visitor.
526+
mlir::Value CIRAttrToValue::visitCirAttr(cir::TypeInfoAttr typeInfoAttr) {
527+
mlir::Type llvmTy = converter->convertType(typeInfoAttr.getType());
528+
mlir::Location loc = parentOp->getLoc();
529+
mlir::Value result = mlir::LLVM::UndefOp::create(rewriter, loc, llvmTy);
530+
531+
for (auto [idx, elt] : llvm::enumerate(typeInfoAttr.getData())) {
532+
mlir::Value init = visit(elt);
533+
result =
534+
mlir::LLVM::InsertValueOp::create(rewriter, loc, result, init, idx);
535+
}
536+
537+
return result;
538+
}
539+
524540
// VTableAttr visitor.
525541
mlir::Value CIRAttrToValue::visitCirAttr(cir::VTableAttr vtableArr) {
526542
mlir::Type llvmTy = converter->convertType(vtableArr.getType());
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: cir-opt %s -verify-diagnostics -split-input-file
2+
3+
!u8i = !cir.int<u, 8>
4+
5+
!rec_anon_struct = !cir.record<struct {!cir.ptr<!u8i>, !cir.ptr<!u8i>, !cir.ptr<!u8i>}>
6+
7+
// expected-error @below {{expected !cir.record type}}
8+
cir.global constant external @type_info = #cir.typeinfo<{#cir.global_view<@_ZTVN10__cxxabiv120__si_class_type_infoE, [2 : i32]> : !cir.ptr<!u8i>, #cir.global_view<@_ZTS1B> : !cir.ptr<!u8i>, #cir.global_view<@_ZTI1A> : !cir.ptr<!u8i>}> : !u8i
9+
10+
// -----
11+
12+
!u8i = !cir.int<u, 8>
13+
14+
!rec_anon_struct = !cir.record<struct {!u8i, !u8i, !u8i}>
15+
16+
// expected-error @below {{integer or global view array attribute}}
17+
cir.global constant external @type_info = #cir.typeinfo<{ #cir.undef : !u8i, #cir.int<1> : !u8i, #cir.int<1> : !u8i}> : !rec_anon_struct

0 commit comments

Comments
 (0)