diff --git a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp index 3d15a70d1d6ac..d7cbb4f64b2ea 100644 --- a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp @@ -276,6 +276,14 @@ void CIRGenFunction::emitDecl(const Decl &d) { case Decl::OpenACCRoutine: emitOpenACCRoutine(cast(d)); return; + case Decl::Typedef: // typedef int X; + case Decl::TypeAlias: { // using X = int; [C++0x] + QualType ty = cast(d).getUnderlyingType(); + assert(!cir::MissingFeatures::generateDebugInfo()); + if (ty->isVariablyModifiedType()) + cgm.errorNYI(d.getSourceRange(), "emitDecl: variably modified type"); + return; + } default: cgm.errorNYI(d.getSourceRange(), std::string("emitDecl: unhandled decl type: ") + diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index 1b504546162c1..3b13d495be5e3 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -618,6 +618,8 @@ void CIRGenModule::emitTopLevelDecl(Decl *decl) { emitGlobalOpenACCDecl(cast(decl)); break; + case Decl::Typedef: + case Decl::TypeAlias: // using foo = bar; [C++11] case Decl::Record: case Decl::CXXRecord: assert(!cir::MissingFeatures::generateDebugInfo()); diff --git a/clang/test/CIR/CodeGen/basic.c b/clang/test/CIR/CodeGen/basic.c index 8ce8106b0c6cc..1845d3b64bf68 100644 --- a/clang/test/CIR/CodeGen/basic.c +++ b/clang/test/CIR/CodeGen/basic.c @@ -232,3 +232,24 @@ int f8(int *p) { // OGCG: store i32 2, ptr %[[P]], align 4 // OGCG: %[[P2:.*]] = load ptr, ptr %[[P_PTR]], align 8 // OGCG: %[[STAR_P:.*]] = load i32, ptr %[[P2]], align 4 + +typedef unsigned long size_type; +typedef unsigned long _Tp; + +size_type max_size(void) { + return (size_type)~0 / sizeof(_Tp); +} + +// CIR: cir.func @max_size() +// CIR: %0 = cir.alloca !u64i, !cir.ptr, ["__retval"] {alignment = 8 : i64} +// CIR: %1 = cir.const #cir.int<0> : !s32i +// CIR: %2 = cir.unary(not, %1) : !s32i, !s32i +// CIR: %3 = cir.cast(integral, %2 : !s32i), !u64i +// CIR: %4 = cir.const #cir.int<8> : !u64i +// CIR: %5 = cir.binop(div, %3, %4) : !u64i + +// LLVM: define i64 @max_size() +// LLVM: store i64 2305843009213693951, ptr + +// OGCG: define{{.*}} i64 @max_size() +// OGCG: ret i64 2305843009213693951 diff --git a/clang/test/CIR/CodeGen/basic.cpp b/clang/test/CIR/CodeGen/basic.cpp index 9665b29719004..0f8431325a86f 100644 --- a/clang/test/CIR/CodeGen/basic.cpp +++ b/clang/test/CIR/CodeGen/basic.cpp @@ -87,3 +87,18 @@ int *f5() { // CHECK-NEXT: cir.store %[[P]], %[[RET_ADDR]] : !cir.ptr, !cir.ptr> // CHECK-NEXT: %[[RET_VAL:.*]] = cir.load %[[RET_ADDR]] : !cir.ptr>, !cir.ptr // CHECK-NEXT: cir.return %[[RET_VAL]] : !cir.ptr + +using size_type = unsigned long; +using _Tp = unsigned long; + +size_type max_size() { + return size_type(~0) / sizeof(_Tp); +} + +// CHECK: cir.func @max_size() +// CHECK: %0 = cir.alloca !u64i, !cir.ptr, ["__retval"] {alignment = 8 : i64} +// CHECK: %1 = cir.const #cir.int<0> : !s32i +// CHECK: %2 = cir.unary(not, %1) : !s32i, !s32i +// CHECK: %3 = cir.cast(integral, %2 : !s32i), !u64i +// CHECK: %4 = cir.const #cir.int<8> : !u64i +// CHECK: %5 = cir.binop(div, %3, %4) : !u64i diff --git a/clang/test/CIR/CodeGen/typedef.c b/clang/test/CIR/CodeGen/typedef.c new file mode 100644 index 0000000000000..17fce13abf38a --- /dev/null +++ b/clang/test/CIR/CodeGen/typedef.c @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll +// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG + +void local_typedef(void) { + typedef struct {int a;} Struct; + Struct s; +} + +// CIR: cir.func @local_typedef() +// CIR: cir.alloca !cir.record, +// CIR-SAME: !cir.ptr>, ["s"] +// CIR-SAME: {alignment = 4 : i64} +// CIR: cir.return + +// LLVM: %struct.Struct = type { i32 } +// LLVM: define void @local_typedef() +// LLVM: alloca %struct.Struct, i64 1, align 4 +// LLVM: ret void + +// OGCG: %struct.Struct = type { i32 } +// OGCG: define{{.*}} void @local_typedef() +// OGCG: alloca %struct.Struct, align 4 +// OGCG: ret void