Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CIR] Add record kind enum in StructType #227

Merged
merged 4 commits into from
Aug 28, 2023
Merged
Show file tree
Hide file tree
Changes from 2 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
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
33 changes: 27 additions & 6 deletions clang/lib/CIR/CodeGen/CIRGenBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "CIRGenTypeCache.h"
#include "UnimplementedFeatureGuarding.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 +169,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 All @@ -189,7 +190,8 @@ class CIRGenBuilderTy : public mlir::OpBuilder {
}

if (!ty)
ty = getAnonStructTy(members, /*body=*/true, packed);
ty = getAnonStructTy(mlir::cir::StructType::Struct, members,
/*body=*/true, packed);

auto sTy = ty.dyn_cast<mlir::cir::StructType>();
assert(sTy && "expected struct type");
Expand Down Expand Up @@ -379,21 +381,40 @@ class CIRGenBuilderTy : public mlir::OpBuilder {

/// Get a CIR anonymous struct type.
mlir::cir::StructType
getAnonStructTy(llvm::ArrayRef<mlir::Type> members, bool body,
getAnonStructTy(mlir::cir::StructType::RecordKind kind,
llvm::ArrayRef<mlir::Type> members, bool body,
bool packed = false, const clang::RecordDecl *ast = nullptr) {
return getStructTy(members, "", body, packed, ast);
return getStructTy(kind, 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::TTK_Struct:
return mlir::cir::StructType::Struct;
case clang::TTK_Union:
return mlir::cir::StructType::Union;
case clang::TTK_Class:
return mlir::cir::StructType::Class;
case clang::TTK_Interface:
llvm_unreachable("interface records are NYI");
case clang::TTK_Enum:
llvm_unreachable("enum records are NYI");
}
}

/// Get a CIR named struct type.
mlir::cir::StructType getStructTy(llvm::ArrayRef<mlir::Type> members,
mlir::cir::StructType getStructTy(mlir::cir::StructType::RecordKind kind,
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)
astAttr = getAttr<mlir::cir::ASTRecordDeclAttr>(ast);
return mlir::cir::StructType::get(getContext(), members, nameAttr, body,
packed, astAttr);
packed, kind, astAttr);
}

//
Expand Down
5 changes: 2 additions & 3 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 @@ -168,8 +166,9 @@ mlir::Type CIRGenTypes::convertRecordDeclType(const clang::RecordDecl *RD) {

// Handle forward decl / incomplete types.
if (!entry) {
auto recordKind = Builder.getRecordKind(RD->getTagKind());
auto name = getRecordTypeName(RD, "");
sitio-couto marked this conversation as resolved.
Show resolved Hide resolved
entry = Builder.getStructTy({}, name, /*body=*/false,
entry = Builder.getStructTy(recordKind, {}, name, /*body=*/false,
/*packed=*/false, RD);
recordDeclTypes[key] = entry;
}
Expand Down
4 changes: 3 additions & 1 deletion 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 Expand Up @@ -58,7 +59,8 @@ mlir::Type CIRGenVTables::getVTableType(const VTableLayout &layout) {

// FIXME(cir): should VTableLayout be encoded like we do for some
// AST nodes?
return CGM.getBuilder().getAnonStructTy(tys, /*body=*/true);
return CGM.getBuilder().getAnonStructTy(mlir::cir::StructType::Struct, tys,
/*body=*/true);
}

/// At this point in the translation unit, does it appear that can we
Expand Down
7 changes: 5 additions & 2 deletions clang/lib/CIR/CodeGen/CIRRecordLayoutBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,9 @@ CIRGenTypes::computeRecordLayout(const RecordDecl *D,
builder.astRecordLayout.getSize()) {
CIRRecordLowering baseBuilder(*this, D, /*Packed=*/builder.isPacked);
auto baseIdentifier = getRecordTypeName(D, ".base");
*BaseTy = Builder.getStructTy(baseBuilder.fieldTypes, baseIdentifier,
auto recordKind = Builder.getRecordKind(D->getTagKind());
*BaseTy = Builder.getStructTy(recordKind, baseBuilder.fieldTypes,
sitio-couto marked this conversation as resolved.
Show resolved Hide resolved
baseIdentifier,
/*body=*/true, /*packed=*/false, D);
// TODO(cir): add something like addRecordTypeName

Expand All @@ -594,7 +596,8 @@ CIRGenTypes::computeRecordLayout(const RecordDecl *D,
// Fill in the struct *after* computing the base type. Filling in the body
// signifies that the type is no longer opaque and record layout is complete,
// but we may need to recursively layout D while laying D out as a base type.
*Ty = Builder.getStructTy(builder.fieldTypes, getRecordTypeName(D, ""),
*Ty = Builder.getStructTy(Builder.getRecordKind(D->getTagKind()),
builder.fieldTypes, getRecordTypeName(D, ""),
/*body=*/true, /*packed=*/false, D);

auto RL = std::make_unique<CIRGenRecordLayout>(
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 @@ -1811,7 +1811,7 @@ mlir::LLVMTypeConverter prepareTypeConverter(mlir::MLIRContext *ctx) {
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>
Loading