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
9 changes: 9 additions & 0 deletions clang/include/clang/CIR/Dialect/IR/CIRTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ struct RecordTypeStorage;

bool isValidFundamentalIntWidth(unsigned width);

/// Returns true if the type is a CIR sized type.
///
/// Types are sized if they implement SizedTypeInterface and
/// return true from its method isSized.
///
/// Unsized types are those that do not have a size, such as
/// void, or abstract types.
bool isSized(mlir::Type ty);

} // namespace cir

//===----------------------------------------------------------------------===//
Expand Down
73 changes: 46 additions & 27 deletions clang/include/clang/CIR/Dialect/IR/CIRTypes.td
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ class CIR_Type<string name, string typeMnemonic, list<Trait> traits = [],
// IntType
//===----------------------------------------------------------------------===//

def CIR_IntType : CIR_Type<"Int", "int",
[DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {
def CIR_IntType : CIR_Type<"Int", "int", [
DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
DeclareTypeInterfaceMethods<CIR_SizedTypeInterface>
]> {
let summary = "Integer type with arbitrary precision up to a fixed limit";
let description = [{
CIR type that represents integer types with arbitrary precision, including
Expand Down Expand Up @@ -82,7 +84,8 @@ def CIR_IntType : CIR_Type<"Int", "int",

class CIR_FloatType<string name, string mnemonic> : CIR_Type<name, mnemonic, [
DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
DeclareTypeInterfaceMethods<CIR_FPTypeInterface>
DeclareTypeInterfaceMethods<CIR_FPTypeInterface>,
DeclareTypeInterfaceMethods<CIR_SizedTypeInterface>
]>;

def CIR_Single : CIR_FloatType<"Single", "float"> {
Expand Down Expand Up @@ -165,9 +168,10 @@ def CIR_LongDouble : CIR_FloatType<"LongDouble", "long_double"> {
// ComplexType
//===----------------------------------------------------------------------===//

def CIR_ComplexType : CIR_Type<"Complex", "complex",
[DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {

def CIR_ComplexType : CIR_Type<"Complex", "complex", [
DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
DeclareTypeInterfaceMethods<CIR_SizedTypeInterface>
]> {
let summary = "CIR complex type";
let description = [{
CIR type that represents a C complex number. `cir.complex` models the C type
Expand Down Expand Up @@ -215,12 +219,13 @@ def CIR_ComplexType : CIR_Type<"Complex", "complex",
// PointerType
//===----------------------------------------------------------------------===//

def CIR_PointerType : CIR_Type<"Pointer", "ptr",
[DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {

def CIR_PointerType : CIR_Type<"Pointer", "ptr", [
DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
DeclareTypeInterfaceMethods<CIR_SizedTypeInterface>
]> {
let summary = "CIR pointer type";
let description = [{
The `cir.ptr` type represents C and C++ pointer types and C++ reference
The `!cir.ptr` type represents C and C++ pointer types and C++ reference
types, other than pointers-to-members. The `pointee` type is the type
pointed to.

Expand Down Expand Up @@ -279,26 +284,27 @@ def CIR_PointerType : CIR_Type<"Pointer", "ptr",
// BoolType
//===----------------------------------------------------------------------===//

def CIR_BoolType :
CIR_Type<"Bool", "bool",
[DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {

def CIR_BoolType : CIR_Type<"Bool", "bool", [
DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
DeclareTypeInterfaceMethods<CIR_SizedTypeInterface>
]> {
let summary = "CIR bool type";
let description = [{
`cir.bool` represents C++ bool type.
`!cir.bool` represents C++ bool type.
}];
}

//===----------------------------------------------------------------------===//
// ArrayType
//===----------------------------------------------------------------------===//

def CIR_ArrayType : CIR_Type<"Array", "array",
[DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {

def CIR_ArrayType : CIR_Type<"Array", "array", [
DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
DeclareTypeInterfaceMethods<CIR_SizedTypeInterface, ["isSized"]>,
]> {
let summary = "CIR array type";
let description = [{
`CIR.array` represents C/C++ constant arrays.
`!cir.array` represents C/C++ constant arrays.
}];

let parameters = (ins "mlir::Type":$elementType, "uint64_t":$size);
Expand All @@ -314,15 +320,22 @@ def CIR_ArrayType : CIR_Type<"Array", "array",
let assemblyFormat = [{
`<` $elementType `x` $size `>`
}];

let extraClassDefinition = [{
bool $cppClass::isSized() const {
return ::cir::isSized(getElementType());
}
}];
}

//===----------------------------------------------------------------------===//
// VectorType (fixed size)
//===----------------------------------------------------------------------===//

def CIR_VectorType : CIR_Type<"Vector", "vector",
[DeclareTypeInterfaceMethods<DataLayoutTypeInterface>]> {

def CIR_VectorType : CIR_Type<"Vector", "vector", [
DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
DeclareTypeInterfaceMethods<CIR_SizedTypeInterface, ["isSized"]>,
]> {
let summary = "CIR vector type";
let description = [{
The `!cir.vector` type represents a fixed-size, one-dimensional vector.
Expand Down Expand Up @@ -363,6 +376,12 @@ def CIR_VectorType : CIR_Type<"Vector", "vector",
}]>,
];

let extraClassDefinition = [{
bool $cppClass::isSized() const {
return ::cir::isSized(getElementType());
}
}];

let genVerifyDecl = 1;
}

Expand Down Expand Up @@ -459,11 +478,11 @@ def CIR_VoidType : CIR_Type<"Void", "void"> {
// The base type for all RecordDecls.
//===----------------------------------------------------------------------===//

def CIR_RecordType : CIR_Type<"Record", "record",
[
DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
MutableType,
]> {
def CIR_RecordType : CIR_Type<"Record", "record", [
DeclareTypeInterfaceMethods<DataLayoutTypeInterface>,
DeclareTypeInterfaceMethods<CIR_SizedTypeInterface>,
MutableType,
]> {
let summary = "CIR record type";
let description = [{
Each unique clang::RecordDecl is mapped to a `cir.record` and any object in
Expand Down
25 changes: 25 additions & 0 deletions clang/include/clang/CIR/Interfaces/CIRTypeInterfaces.td
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,29 @@ def CIR_FPTypeInterface : TypeInterface<"FPTypeInterface"> {
];
}

def CIR_SizedTypeInterface : TypeInterface<"SizedTypeInterface"> {
let description = [{
Annotates types that have known size. Types that don't have a size are
abstract types and void.
}];
let cppNamespace = "::cir";
let methods = [
InterfaceMethod<[{
Returns true if this is a sized type. This mirrors sizedness from the
clang AST, where a type is sized if it has a known size.
By default type defining this interface returns true,
but this can be overridden if sizedness depends on properties of the type.
For example, whether a struct is not sized if it is incomplete.
}],
/*retTy=*/"bool",
/*methodName=*/"isSized",
/*args=*/(ins),
/*methodBody=*/"",
/*defaultImplementation=*/[{
return true;
}]
>,
];
}

#endif // CLANG_CIR_INTERFACES_CIRTYPEINTERFACES_TD
12 changes: 0 additions & 12 deletions clang/lib/CIR/CodeGen/CIRGenBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,18 +139,6 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
return getType<cir::RecordType>(nameAttr, kind);
}

bool isSized(mlir::Type ty) {
if (mlir::isa<cir::PointerType, cir::ArrayType, cir::BoolType, cir::IntType,
cir::FPTypeInterface, cir::ComplexType, cir::RecordType>(ty))
return true;

if (const auto vt = mlir::dyn_cast<cir::VectorType>(ty))
return isSized(vt.getElementType());

assert(!cir::MissingFeatures::unsizedTypes());
return false;
}

// Return true if the value is a null constant such as null pointer, (+0.0)
// for floating-point or zero initializer
bool isNullValue(mlir::Attribute attr) const {
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/CIR/CodeGen/CIRGenTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
mlir::Type elemTy = convertTypeForMem(arrTy->getElementType());
// int X[] -> [0 x int], unless the element type is not sized. If it is
// unsized (e.g. an incomplete record) just use [0 x i8].
if (!builder.isSized(elemTy)) {
if (!cir::isSized(elemTy)) {
elemTy = cgm.SInt8Ty;
}

Expand All @@ -438,7 +438,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) {

// TODO(CIR): In LLVM, "lower arrays of undefined struct type to arrays of
// i8 just to have a concrete type"
if (!builder.isSized(elemTy)) {
if (!cir::isSized(elemTy)) {
cgm.errorNYI(SourceLocation(), "arrays of undefined struct type", type);
resultType = cgm.UInt32Ty;
break;
Expand Down
10 changes: 10 additions & 0 deletions clang/lib/CIR/Dialect/IR/CIRTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,16 @@
#include "clang/CIR/MissingFeatures.h"
#include "llvm/ADT/TypeSwitch.h"

//===----------------------------------------------------------------------===//
// CIR Helpers
//===----------------------------------------------------------------------===//
bool cir::isSized(mlir::Type ty) {
if (auto sizedTy = mlir::dyn_cast<cir::SizedTypeInterface>(ty))
return sizedTy.isSized();
assert(!cir::MissingFeatures::unsizedTypes());
return false;
}

//===----------------------------------------------------------------------===//
// CIR Custom Parser/Printer Signatures
//===----------------------------------------------------------------------===//
Expand Down
Loading