Skip to content

Commit

Permalink
[CIR] Add record kind enum in StructType
Browse files Browse the repository at this point in the history
Serves as a way to identify the kind of record type (union, class,
struct, etc.), which is useful for codegen and lowering.

ghstack-source-id: a642fe834f12893d555b527af030d1c2a9c9df46
Pull Request resolved: llvm#227
  • Loading branch information
sitio-couto authored and lanza committed Mar 20, 2024
1 parent ff10005 commit afd820b
Show file tree
Hide file tree
Showing 45 changed files with 463 additions and 385 deletions.
28 changes: 28 additions & 0 deletions clang/include/clang/CIR/Dialect/IR/CIRTypes.td
Original file line number Diff line number Diff line change
Expand Up @@ -110,12 +110,19 @@ def CIR_StructType : CIR_Type<"Struct", "struct",
"mlir::StringAttr":$typeName,
"bool":$body,
"bool":$packed,
"mlir::cir::StructType::RecordKind":$kind,
"std::optional<::mlir::cir::ASTRecordDeclAttr>":$ast
);

let hasCustomAssemblyFormat = 1;

let extraClassDeclaration = [{
enum RecordKind : uint32_t {
Class,
Union,
Struct
};

private:
// All these support lazily computation and storage
// for the struct size and alignment.
Expand All @@ -127,6 +134,27 @@ def CIR_StructType : CIR_Type<"Struct", "struct",
size_t getNumElements() const { return getMembers().size(); }
bool isOpaque() const { return !getBody(); }
bool isPadded(const ::mlir::DataLayout &dataLayout) const;

std::string getPrefixedName() {
const auto name = getTypeName().getValue().str();
switch (getKind()) {
case RecordKind::Class:
return "class." + name;
case RecordKind::Union:
return "union "+ name;
case RecordKind::Struct:
return "struct." + name;
}
}

/// Return whether this is a class declaration.
bool isClass() const { return getKind() == RecordKind::Class; }

/// Return whether this is a union declaration.
bool isUnion() const { return getKind() == RecordKind::Union; }

/// Return whether this is a struct declaration.
bool isStruct() const { return getKind() == RecordKind::Struct; }
}];

let extraClassDefinition = [{
Expand Down
28 changes: 25 additions & 3 deletions clang/lib/CIR/CodeGen/CIRGenBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
#include "CIRGenTypeCache.h"
#include "UnimplementedFeatureGuarding.h"

#include "clang/AST/Decl.h"
#include "clang/AST/Type.h"
#include "clang/CIR/Dialect/IR/CIRAttrs.h"
#include "clang/CIR/Dialect/IR/CIRDialect.h"
#include "clang/CIR/Dialect/IR/CIROpsEnums.h"
Expand Down Expand Up @@ -168,7 +170,7 @@ class CIRGenBuilderTy : public mlir::OpBuilder {
if (!structTy)
structTy = getType<mlir::cir::StructType>(
members, mlir::StringAttr::get(getContext()),
/*body=*/true, packed,
/*body=*/true, packed, mlir::cir::StructType::Struct,
/*ast=*/std::nullopt);

// Return zero or anonymous constant struct.
Expand Down Expand Up @@ -384,16 +386,36 @@ class CIRGenBuilderTy : public mlir::OpBuilder {
return getStructTy(members, "", body, packed, ast);
}

/// Get a CIR record kind from a AST declaration tag.
mlir::cir::StructType::RecordKind
getRecordKind(const clang::TagTypeKind kind) {
switch (kind) {
case clang::TagTypeKind::Struct:
return mlir::cir::StructType::Struct;
case clang::TagTypeKind::Union:
return mlir::cir::StructType::Union;
case clang::TagTypeKind::Class:
return mlir::cir::StructType::Class;
case clang::TagTypeKind::Interface:
llvm_unreachable("interface records are NYI");
case clang::TagTypeKind::Enum:
llvm_unreachable("enum records are NYI");
}
}

/// Get a CIR named struct type.
mlir::cir::StructType getStructTy(llvm::ArrayRef<mlir::Type> members,
llvm::StringRef name, bool body,
bool packed, const clang::RecordDecl *ast) {
const auto nameAttr = getStringAttr(name);
std::optional<mlir::cir::ASTRecordDeclAttr> astAttr = std::nullopt;
if (ast)
auto kind = mlir::cir::StructType::RecordKind::Struct;
if (ast) {
astAttr = getAttr<mlir::cir::ASTRecordDeclAttr>(ast);
kind = getRecordKind(ast->getTagKind());
}
return mlir::cir::StructType::get(getContext(), members, nameAttr, body,
packed, astAttr);
packed, kind, astAttr);
}

//
Expand Down
5 changes: 1 addition & 4 deletions clang/lib/CIR/CodeGen/CIRGenTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,6 @@ std::string CIRGenTypes::getRecordTypeName(const clang::RecordDecl *recordDecl,
llvm::SmallString<256> typeName;
llvm::raw_svector_ostream outStream(typeName);

outStream << recordDecl->getKindName() << '.';

PrintingPolicy policy = recordDecl->getASTContext().getPrintingPolicy();
policy.SuppressInlineNamespace = false;

Expand Down Expand Up @@ -169,8 +167,7 @@ mlir::Type CIRGenTypes::convertRecordDeclType(const clang::RecordDecl *RD) {
// Handle forward decl / incomplete types.
if (!entry) {
auto name = getRecordTypeName(RD, "");
entry = Builder.getStructTy({}, name, /*body=*/false,
/*packed=*/false, RD);
entry = Builder.getStructTy({}, name, /*body=*/false, /*packed=*/false, RD);
recordDeclTypes[key] = entry;
}

Expand Down
1 change: 1 addition & 0 deletions clang/lib/CIR/CodeGen/CIRGenVTables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/RecordLayout.h"
#include "clang/Basic/CodeGenOptions.h"
#include "clang/CIR/Dialect/IR/CIRTypes.h"
#include "clang/CodeGen/CGFunctionInfo.h"
#include "clang/CodeGen/ConstantInitBuilder.h"
#include "llvm/Support/Format.h"
Expand Down
33 changes: 31 additions & 2 deletions clang/lib/CIR/Dialect/IR/CIRTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,15 +95,30 @@ void BoolType::print(mlir::AsmPrinter &printer) const {}
//===----------------------------------------------------------------------===//

Type StructType::parse(mlir::AsmParser &parser) {
const auto loc = parser.getCurrentLocation();
llvm::SmallVector<mlir::Type> members;
mlir::StringAttr id;
bool body = false;
bool packed = false;
mlir::cir::ASTRecordDeclAttr ast = nullptr;
RecordKind kind;

if (parser.parseLess())
return {};

// TODO(cir): in the future we should probably separate types for different
// source language declarations such as cir.class, cir.union, and cir.struct
if (parser.parseOptionalKeyword("struct").succeeded())
kind = RecordKind::Struct;
else if (parser.parseOptionalKeyword("union").succeeded())
kind = RecordKind::Union;
else if (parser.parseOptionalKeyword("class").succeeded())
kind = RecordKind::Class;
else {
parser.emitError(loc, "unknown struct type");
return {};
}

if (parser.parseAttribute(id))
return {};

Expand All @@ -130,12 +145,26 @@ Type StructType::parse(mlir::AsmParser &parser) {
if (parser.parseGreater())
return {};

return StructType::get(parser.getContext(), members, id, body, packed,
return StructType::get(parser.getContext(), members, id, body, packed, kind,
std::nullopt);
}

void StructType::print(mlir::AsmPrinter &printer) const {
printer << '<' << getTypeName() << " ";
printer << '<';

switch (getKind()) {
case RecordKind::Struct:
printer << "struct ";
break;
case RecordKind::Union:
printer << "union ";
break;
case RecordKind::Class:
printer << "class ";
break;
}

printer << getTypeName() << " ";

if (getPacked())
printer << "packed ";
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1823,7 +1823,7 @@ void prepareTypeConverter(mlir::LLVMTypeConverter &converter) {
mlir::LLVM::LLVMStructType llvmStruct;
if (type.getTypeName().size() != 0) {
llvmStruct = mlir::LLVM::LLVMStructType::getIdentified(
type.getContext(), type.getTypeName());
type.getContext(), type.getPrefixedName());
if (llvmStruct.setBody(llvmMembers, /*isPacked=*/type.getPacked())
.failed())
llvm_unreachable("Failed to set body of struct");
Expand Down
30 changes: 15 additions & 15 deletions clang/test/CIR/CodeGen/String.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,56 +18,56 @@ void test() {
}

// CHECK: cir.func linkonce_odr @_ZN6StringC2Ev
// CHECK-NEXT: %0 = cir.alloca !cir.ptr<!ty_22class2EString22>
// CHECK-NEXT: %0 = cir.alloca !cir.ptr<!ty_22String22>
// CHECK-NEXT: cir.store %arg0, %0
// CHECK-NEXT: %1 = cir.load %0
// CHECK-NEXT: %2 = "cir.struct_element_addr"(%1) <{member_index = 0 : index, member_name = "storage"}>
// CHECK-NEXT: %3 = cir.const(#cir.null : !cir.ptr<!s8i>) : !cir.ptr<!s8i>
// CHECK-NEXT: cir.store %3, %2 : !cir.ptr<!s8i>, cir.ptr <!cir.ptr<!s8i>>
// CHECK-NEXT: %4 = "cir.struct_element_addr"(%1) <{member_index = 1 : index, member_name = "size"}> : (!cir.ptr<!ty_22class2EString22>) -> !cir.ptr<!s64i>
// CHECK-NEXT: %4 = "cir.struct_element_addr"(%1) <{member_index = 1 : index, member_name = "size"}> : (!cir.ptr<!ty_22String22>) -> !cir.ptr<!s64i>
// CHECK-NEXT: %5 = cir.const(#cir.int<0> : !s32i) : !s32i
// CHECK-NEXT: %6 = cir.cast(integral, %5 : !s32i), !s64i
// CHECK-NEXT: cir.store %6, %4 : !s64i, cir.ptr <!s64i>
// CHECK-NEXT: cir.return
// CHECK-NEXT: }
// CHECK: cir.func linkonce_odr @_ZN6StringC2Ei
// CHECK-NEXT: %0 = cir.alloca !cir.ptr<!ty_22class2EString22>
// CHECK-NEXT: %0 = cir.alloca !cir.ptr<!ty_22String22>
// CHECK-NEXT: %1 = cir.alloca !s32i, cir.ptr <!s32i>, ["size", init]
// CHECK-NEXT: cir.store %arg0, %0
// CHECK-NEXT: cir.store %arg1, %1
// CHECK-NEXT: %2 = cir.load %0
// CHECK-NEXT: %3 = "cir.struct_element_addr"(%2) <{member_index = 0 : index, member_name = "storage"}>
// CHECK-NEXT: %4 = cir.const(#cir.null : !cir.ptr<!s8i>)
// CHECK-NEXT: cir.store %4, %3
// CHECK-NEXT: %5 = "cir.struct_element_addr"(%2) <{member_index = 1 : index, member_name = "size"}> : (!cir.ptr<!ty_22class2EString22>) -> !cir.ptr<!s64i>
// CHECK-NEXT: %5 = "cir.struct_element_addr"(%2) <{member_index = 1 : index, member_name = "size"}> : (!cir.ptr<!ty_22String22>) -> !cir.ptr<!s64i>
// CHECK-NEXT: %6 = cir.load %1 : cir.ptr <!s32i>, !s32i
// CHECK-NEXT: %7 = cir.cast(integral, %6 : !s32i), !s64i
// CHECK-NEXT: cir.store %7, %5 : !s64i, cir.ptr <!s64i>
// CHECK-NEXT: cir.return
// CHECK-NEXT: }

// CHECK: cir.func linkonce_odr @_ZN6StringC2EPKc
// CHECK-NEXT: %0 = cir.alloca !cir.ptr<!ty_22class2EString22>, cir.ptr <!cir.ptr<!ty_22class2EString22>>, ["this", init] {alignment = 8 : i64}
// CHECK-NEXT: %0 = cir.alloca !cir.ptr<!ty_22String22>, cir.ptr <!cir.ptr<!ty_22String22>>, ["this", init] {alignment = 8 : i64}
// CHECK-NEXT: %1 = cir.alloca !cir.ptr<!s8i>, cir.ptr <!cir.ptr<!s8i>>, ["s", init] {alignment = 8 : i64}
// CHECK-NEXT: cir.store %arg0, %0 : !cir.ptr<!ty_22class2EString22>, cir.ptr <!cir.ptr<!ty_22class2EString22>>
// CHECK-NEXT: cir.store %arg0, %0 : !cir.ptr<!ty_22String22>, cir.ptr <!cir.ptr<!ty_22String22>>
// CHECK-NEXT: cir.store %arg1, %1 : !cir.ptr<!s8i>, cir.ptr <!cir.ptr<!s8i>>
// CHECK-NEXT: %2 = cir.load %0 : cir.ptr <!cir.ptr<!ty_22class2EString22>>, !cir.ptr<!ty_22class2EString22>
// CHECK-NEXT: %3 = "cir.struct_element_addr"(%2) <{member_index = 0 : index, member_name = "storage"}> : (!cir.ptr<!ty_22class2EString22>) -> !cir.ptr<!cir.ptr<!s8i>>
// CHECK-NEXT: %2 = cir.load %0 : cir.ptr <!cir.ptr<!ty_22String22>>, !cir.ptr<!ty_22String22>
// CHECK-NEXT: %3 = "cir.struct_element_addr"(%2) <{member_index = 0 : index, member_name = "storage"}> : (!cir.ptr<!ty_22String22>) -> !cir.ptr<!cir.ptr<!s8i>>
// CHECK-NEXT: %4 = cir.const(#cir.null : !cir.ptr<!s8i>) : !cir.ptr<!s8i>
// CHECK-NEXT: cir.store %4, %3 : !cir.ptr<!s8i>, cir.ptr <!cir.ptr<!s8i>>
// CHECK-NEXT: cir.return

// CHECK: cir.func linkonce_odr @_ZN6StringC1EPKc
// CHECK-NEXT: %0 = cir.alloca !cir.ptr<!ty_22class2EString22>, cir.ptr <!cir.ptr<!ty_22class2EString22>>, ["this", init] {alignment = 8 : i64}
// CHECK-NEXT: %0 = cir.alloca !cir.ptr<!ty_22String22>, cir.ptr <!cir.ptr<!ty_22String22>>, ["this", init] {alignment = 8 : i64}
// CHECK-NEXT: %1 = cir.alloca !cir.ptr<!s8i>, cir.ptr <!cir.ptr<!s8i>>, ["s", init] {alignment = 8 : i64}
// CHECK-NEXT: cir.store %arg0, %0 : !cir.ptr<!ty_22class2EString22>, cir.ptr <!cir.ptr<!ty_22class2EString22>>
// CHECK-NEXT: cir.store %arg0, %0 : !cir.ptr<!ty_22String22>, cir.ptr <!cir.ptr<!ty_22String22>>
// CHECK-NEXT: cir.store %arg1, %1 : !cir.ptr<!s8i>, cir.ptr <!cir.ptr<!s8i>>
// CHECK-NEXT: %2 = cir.load %0 : cir.ptr <!cir.ptr<!ty_22class2EString22>>, !cir.ptr<!ty_22class2EString22>
// CHECK-NEXT: %2 = cir.load %0 : cir.ptr <!cir.ptr<!ty_22String22>>, !cir.ptr<!ty_22String22>
// CHECK-NEXT: %3 = cir.load %1 : cir.ptr <!cir.ptr<!s8i>>, !cir.ptr<!s8i>
// CHECK-NEXT: cir.call @_ZN6StringC2EPKc(%2, %3) : (!cir.ptr<!ty_22class2EString22>, !cir.ptr<!s8i>) -> ()
// CHECK-NEXT: cir.call @_ZN6StringC2EPKc(%2, %3) : (!cir.ptr<!ty_22String22>, !cir.ptr<!s8i>) -> ()
// CHECK-NEXT: cir.return

// CHECK: cir.func @_Z4testv()
// CHECK: cir.call @_ZN6StringC1Ev(%0) : (!cir.ptr<!ty_22class2EString22>) -> ()
// CHECK: cir.call @_ZN6StringC1Ei(%1, %3) : (!cir.ptr<!ty_22class2EString22>, !s32i) -> ()
// CHECK: cir.call @_ZN6StringC1EPKc(%2, %5) : (!cir.ptr<!ty_22class2EString22>, !cir.ptr<!s8i>) -> ()
// CHECK: cir.call @_ZN6StringC1Ev(%0) : (!cir.ptr<!ty_22String22>) -> ()
// CHECK: cir.call @_ZN6StringC1Ei(%1, %3) : (!cir.ptr<!ty_22String22>, !s32i) -> ()
// CHECK: cir.call @_ZN6StringC1EPKc(%2, %5) : (!cir.ptr<!ty_22String22>, !cir.ptr<!s8i>) -> ()
32 changes: 16 additions & 16 deletions clang/test/CIR/CodeGen/agg-init.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++17 -fclangir-enable -Wno-unused-value -emit-cir %s -o %t.cir
// RUN: FileCheck --input-file=%t.cir %s

// CHECK: !ty_22struct2EZero22 = !cir.struct<"struct.Zero" {!u8i}>
// CHECK: !ty_22struct2Eyep_22 = !cir.struct<"struct.yep_" {!u32i, !u32i}>
// CHECK: !ty_22Zero22 = !cir.struct<struct "Zero" {!u8i}>
// CHECK: !ty_22yep_22 = !cir.struct<struct "yep_" {!u32i, !u32i}>

struct Zero {
void yolo();
Expand All @@ -15,9 +15,9 @@ void f() {
}

// CHECK: cir.func @_Z1fv()
// CHECK: %0 = cir.alloca !ty_22struct2EZero22, cir.ptr <!ty_22struct2EZero22>, ["z0", init]
// CHECK: %1 = cir.alloca !ty_22struct2EZero22, cir.ptr <!ty_22struct2EZero22>, ["z1"]
// CHECK: cir.call @_ZN4ZeroC1Ev(%0) : (!cir.ptr<!ty_22struct2EZero22>) -> ()
// CHECK: %0 = cir.alloca !ty_22Zero22, cir.ptr <!ty_22Zero22>, ["z0", init]
// CHECK: %1 = cir.alloca !ty_22Zero22, cir.ptr <!ty_22Zero22>, ["z1"]
// CHECK: cir.call @_ZN4ZeroC1Ev(%0) : (!cir.ptr<!ty_22Zero22>) -> ()
// CHECK: cir.return

typedef enum xxy_ {
Expand All @@ -34,11 +34,11 @@ typedef struct yep_ {
void use() { yop{}; }

// CHECK: cir.func @_Z3usev()
// CHECK: %0 = cir.alloca !ty_22struct2Eyep_22, cir.ptr <!ty_22struct2Eyep_22>, ["agg.tmp0"] {alignment = 4 : i64}
// CHECK: %1 = "cir.struct_element_addr"(%0) <{member_index = 0 : index, member_name = "Status"}> : (!cir.ptr<!ty_22struct2Eyep_22>) -> !cir.ptr<!u32i>
// CHECK: %0 = cir.alloca !ty_22yep_22, cir.ptr <!ty_22yep_22>, ["agg.tmp0"] {alignment = 4 : i64}
// CHECK: %1 = "cir.struct_element_addr"(%0) <{member_index = 0 : index, member_name = "Status"}> : (!cir.ptr<!ty_22yep_22>) -> !cir.ptr<!u32i>
// CHECK: %2 = cir.const(#cir.int<0> : !u32i) : !u32i
// CHECK: cir.store %2, %1 : !u32i, cir.ptr <!u32i>
// CHECK: %3 = "cir.struct_element_addr"(%0) <{member_index = 1 : index, member_name = "HC"}> : (!cir.ptr<!ty_22struct2Eyep_22>) -> !cir.ptr<!u32i>
// CHECK: %3 = "cir.struct_element_addr"(%0) <{member_index = 1 : index, member_name = "HC"}> : (!cir.ptr<!ty_22yep_22>) -> !cir.ptr<!u32i>
// CHECK: %4 = cir.const(#cir.int<0> : !u32i) : !u32i
// CHECK: cir.store %4, %3 : !u32i, cir.ptr <!u32i>
// CHECK: cir.return
Expand All @@ -64,16 +64,16 @@ void yo() {
}

// CHECK: cir.func @_Z2yov()
// CHECK: %0 = cir.alloca !ty_22struct2EYo22, cir.ptr <!ty_22struct2EYo22>, ["ext"] {alignment = 8 : i64}
// CHECK: %1 = cir.alloca !ty_22struct2EYo22, cir.ptr <!ty_22struct2EYo22>, ["ext2", init] {alignment = 8 : i64}
// CHECK: %2 = cir.const(#cir.const_struct<{#cir.int<1000070000> : !u32i, #cir.null : !cir.ptr<!void>, #cir.int<0> : !u64i}> : !ty_22struct2EYo22) : !ty_22struct2EYo22
// CHECK: cir.store %2, %0 : !ty_22struct2EYo22, cir.ptr <!ty_22struct2EYo22>
// CHECK: %3 = "cir.struct_element_addr"(%1) <{member_index = 0 : index, member_name = "type"}> : (!cir.ptr<!ty_22struct2EYo22>) -> !cir.ptr<!u32i>
// CHECK: %0 = cir.alloca !ty_22Yo22, cir.ptr <!ty_22Yo22>, ["ext"] {alignment = 8 : i64}
// CHECK: %1 = cir.alloca !ty_22Yo22, cir.ptr <!ty_22Yo22>, ["ext2", init] {alignment = 8 : i64}
// CHECK: %2 = cir.const(#cir.const_struct<{#cir.int<1000070000> : !u32i, #cir.null : !cir.ptr<!void>, #cir.int<0> : !u64i}> : !ty_22Yo22) : !ty_22Yo22
// CHECK: cir.store %2, %0 : !ty_22Yo22, cir.ptr <!ty_22Yo22>
// CHECK: %3 = "cir.struct_element_addr"(%1) <{member_index = 0 : index, member_name = "type"}> : (!cir.ptr<!ty_22Yo22>) -> !cir.ptr<!u32i>
// CHECK: %4 = cir.const(#cir.int<1000066001> : !u32i) : !u32i
// CHECK: cir.store %4, %3 : !u32i, cir.ptr <!u32i>
// CHECK: %5 = "cir.struct_element_addr"(%1) <{member_index = 1 : index, member_name = "next"}> : (!cir.ptr<!ty_22struct2EYo22>) -> !cir.ptr<!cir.ptr<!void>>
// CHECK: %6 = cir.cast(bitcast, %0 : !cir.ptr<!ty_22struct2EYo22>), !cir.ptr<!void>
// CHECK: %5 = "cir.struct_element_addr"(%1) <{member_index = 1 : index, member_name = "next"}> : (!cir.ptr<!ty_22Yo22>) -> !cir.ptr<!cir.ptr<!void>>
// CHECK: %6 = cir.cast(bitcast, %0 : !cir.ptr<!ty_22Yo22>), !cir.ptr<!void>
// CHECK: cir.store %6, %5 : !cir.ptr<!void>, cir.ptr <!cir.ptr<!void>>
// CHECK: %7 = "cir.struct_element_addr"(%1) <{member_index = 2 : index, member_name = "createFlags"}> : (!cir.ptr<!ty_22struct2EYo22>) -> !cir.ptr<!u64i>
// CHECK: %7 = "cir.struct_element_addr"(%1) <{member_index = 2 : index, member_name = "createFlags"}> : (!cir.ptr<!ty_22Yo22>) -> !cir.ptr<!u64i>
// CHECK: %8 = cir.const(#cir.int<0> : !u64i) : !u64i
// CHECK: cir.store %8, %7 : !u64i, cir.ptr <!u64i>
2 changes: 1 addition & 1 deletion clang/test/CIR/CodeGen/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
struct S {
int i;
} arr[3] = {{1}};
// CHECK: cir.global external @arr = #cir.const_array<[#cir.const_struct<{#cir.int<1> : !s32i}> : !ty_22struct2ES22, #cir.zero : !ty_22struct2ES22, #cir.zero : !ty_22struct2ES22]> : !cir.array<!ty_22struct2ES22 x 3>
// CHECK: cir.global external @arr = #cir.const_array<[#cir.const_struct<{#cir.int<1> : !s32i}> : !ty_22S22, #cir.zero : !ty_22S22, #cir.zero : !ty_22S22]> : !cir.array<!ty_22S22 x 3>
2 changes: 1 addition & 1 deletion clang/test/CIR/CodeGen/array.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ int globalNullArr[] = {0, 0};
struct S {
int i;
} arr[3] = {{1}};
// CHECK: cir.global external @arr = #cir.const_array<[#cir.const_struct<{#cir.int<1> : !s32i}> : !ty_22struct2ES22, #cir.zero : !ty_22struct2ES22, #cir.zero : !ty_22struct2ES22]> : !cir.array<!ty_22struct2ES22 x 3>
// CHECK: cir.global external @arr = #cir.const_array<[#cir.const_struct<{#cir.int<1> : !s32i}> : !ty_22S22, #cir.zero : !ty_22S22, #cir.zero : !ty_22S22]> : !cir.array<!ty_22S22 x 3>

void testPointerDecaySubscriptAccess(int arr[]) {
// CHECK: cir.func @{{.+}}testPointerDecaySubscriptAccess
Expand Down
Loading

0 comments on commit afd820b

Please sign in to comment.