Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions clang/include/clang/CIR/Dialect/IR/CIRAttrConstraints.td
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,27 @@ def CIR_AnyIntOrFloatAttr : AnyAttrOf<[CIR_AnyIntAttr, CIR_AnyFPAttr],
string cppType = "::mlir::TypedAttr";
}

//===----------------------------------------------------------------------===//
// GlobalViewAttr constraints
//===----------------------------------------------------------------------===//

def CIR_AnyGlobalViewAttr : CIR_AttrConstraint<"::cir::GlobalViewAttr", "GlobalView attribute">;

def CIR_AnyIntOrGlobalViewAttr : AnyAttrOf<[CIR_AnyIntAttr, CIR_AnyGlobalViewAttr],
"integer or global view attribute"> {
string cppType = "::mlir::TypedAttr";
}

//===----------------------------------------------------------------------===//
// ArrayAttr constraints
//===----------------------------------------------------------------------===//

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

def CIR_IntOrGlobalViewArrayAttr : TypedArrayAttrBase<CIR_AnyIntOrGlobalViewAttr,
"integer or global view array attribute">{
string cppType = "::mlir::ArrayAttr";
}

#endif // CLANG_CIR_DIALECT_IR_CIRATTRCONSTRAINTS_TD
52 changes: 52 additions & 0 deletions clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
Original file line number Diff line number Diff line change
Expand Up @@ -779,4 +779,56 @@ def CIR_AddressPointAttr : CIR_Attr<"AddressPoint", "address_point"> {
}];
}

//===----------------------------------------------------------------------===//
// TypeInfoAttr
//===----------------------------------------------------------------------===//

def CIR_TypeInfoAttr : CIR_Attr<"TypeInfo", "typeinfo", [TypedAttrInterface]> {
let summary = "Represents a typeinfo used for RTTI";
let description = [{
The typeinfo data for a given class is stored into an ArrayAttr. The
layout is determined by the C++ ABI used (clang only implements
itanium on CIRGen).

The verifier enforces that the output type is always a `!cir.record`,
and that the ArrayAttr element types match the equivalent member type
for the resulting record, i.e, a GlobalViewAttr for symbol reference or
an IntAttr for flags.

Example:

```
cir.global "private" external @_ZTVN10__cxxabiv120__si_class_type_infoE
: !cir.ptr<i32>

!rec_anon_struct = !cir.record<struct {!cir.ptr<!u8i>, !cir.ptr<!u8i>,
!cir.ptr<!u8i>}>

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>}> : !rec_anon_struct
```
}];

let parameters = (ins
AttributeSelfTypeParameter<"">:$type,
CIR_IntOrGlobalViewArrayAttr:$data
);

let builders = [
AttrBuilderWithInferredContext<(ins "mlir::Type":$type,
"mlir::ArrayAttr":$data), [{
return $_get(type.getContext(), type, data);
}]>
];

// Checks record element types should match the array for every equivalent
// element type.
let genVerifyDecl = 1;
let assemblyFormat = [{
`<` custom<RecordMembers>($data) `>`
}];
}

#endif // CLANG_CIR_DIALECT_IR_CIRATTRS_TD
20 changes: 16 additions & 4 deletions clang/lib/CIR/Dialect/IR/CIRDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@
#include "llvm/ADT/SmallSet.h"
#include "llvm/Support/LogicalResult.h"

#include <numeric>

using namespace mlir;
using namespace cir;

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

if (mlir::isa<cir::ConstArrayAttr, cir::ConstVectorAttr,
cir::ConstComplexAttr, cir::ConstRecordAttr,
cir::GlobalViewAttr, cir::PoisonAttr, cir::VTableAttr>(
attrType))
cir::GlobalViewAttr, cir::PoisonAttr, cir::TypeInfoAttr,
cir::VTableAttr>(attrType))
return success();

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

//===----------------------------------------------------------------------===//
// TypeInfoAttr
//===----------------------------------------------------------------------===//

LogicalResult cir::TypeInfoAttr::verify(
::llvm::function_ref<::mlir::InFlightDiagnostic()> emitError,
::mlir::Type type, ::mlir::ArrayAttr typeInfoData) {

if (cir::ConstRecordAttr::verify(emitError, type, typeInfoData).failed())
return failure();

return success();
}

//===----------------------------------------------------------------------===//
// TableGen'd op method definitions
//===----------------------------------------------------------------------===//
Expand Down
16 changes: 16 additions & 0 deletions clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ class CIRAttrToValue {
mlir::Value visitCirAttr(cir::ConstRecordAttr attr);
mlir::Value visitCirAttr(cir::ConstVectorAttr attr);
mlir::Value visitCirAttr(cir::GlobalViewAttr attr);
mlir::Value visitCirAttr(cir::TypeInfoAttr attr);
mlir::Value visitCirAttr(cir::VTableAttr attr);
mlir::Value visitCirAttr(cir::ZeroAttr attr);

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

// TypeInfoAttr visitor.
mlir::Value CIRAttrToValue::visitCirAttr(cir::TypeInfoAttr typeInfoAttr) {
mlir::Type llvmTy = converter->convertType(typeInfoAttr.getType());
mlir::Location loc = parentOp->getLoc();
mlir::Value result = mlir::LLVM::UndefOp::create(rewriter, loc, llvmTy);

for (auto [idx, elt] : llvm::enumerate(typeInfoAttr.getData())) {
mlir::Value init = visit(elt);
result =
mlir::LLVM::InsertValueOp::create(rewriter, loc, result, init, idx);
}

return result;
}

// VTableAttr visitor.
mlir::Value CIRAttrToValue::visitCirAttr(cir::VTableAttr vtableArr) {
mlir::Type llvmTy = converter->convertType(vtableArr.getType());
Expand Down
17 changes: 17 additions & 0 deletions clang/test/CIR/IR/invalid-type-info.cir
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// RUN: cir-opt %s -verify-diagnostics -split-input-file

!u8i = !cir.int<u, 8>

!rec_anon_struct = !cir.record<struct {!cir.ptr<!u8i>, !cir.ptr<!u8i>, !cir.ptr<!u8i>}>

// expected-error @below {{expected !cir.record type}}
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

// -----

!u8i = !cir.int<u, 8>

!rec_anon_struct = !cir.record<struct {!u8i, !u8i, !u8i}>

// expected-error @below {{integer or global view array attribute}}
cir.global constant external @type_info = #cir.typeinfo<{ #cir.undef : !u8i, #cir.int<1> : !u8i, #cir.int<1> : !u8i}> : !rec_anon_struct