Author: Andy Kaylor
Date: 2025-04-18T12:52:51-07:00
New Revision: daf3c985f75bae2f4f01594be2fbc02f953e7b06

URL: 
https://github.com/llvm/llvm-project/commit/daf3c985f75bae2f4f01594be2fbc02f953e7b06
DIFF: 
https://github.com/llvm/llvm-project/commit/daf3c985f75bae2f4f01594be2fbc02f953e7b06.diff

LOG: [CIR] Upstream support for typedef and type aliases (#136335)

Nothing is actually needed in ClangIR to support typedef and type
aliases, but the Decl kinds need to be explicitly ignored in the
emitDecl handlers to avoid hitting the default NYI errors. This change
does that and adds tests.

Added: 
    clang/test/CIR/CodeGen/typedef.c

Modified: 
    clang/lib/CIR/CodeGen/CIRGenDecl.cpp
    clang/lib/CIR/CodeGen/CIRGenModule.cpp
    clang/test/CIR/CodeGen/basic.c
    clang/test/CIR/CodeGen/basic.cpp

Removed: 
    


################################################################################
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<OpenACCRoutineDecl>(d));
     return;
+  case Decl::Typedef:     // typedef int X;
+  case Decl::TypeAlias: { // using X = int; [C++0x]
+    QualType ty = cast<TypedefNameDecl>(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<OpenACCDeclareDecl>(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<!u64i>, ["__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<!s32i>, 
!cir.ptr<!cir.ptr<!s32i>>
 // CHECK-NEXT:   %[[RET_VAL:.*]] = cir.load %[[RET_ADDR]] : 
!cir.ptr<!cir.ptr<!s32i>>, !cir.ptr<!s32i>
 // CHECK-NEXT:   cir.return %[[RET_VAL]] : !cir.ptr<!s32i>
+
+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<!u64i>, ["__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<struct "Struct" {!s32i}>,
+// CIR-SAME:       !cir.ptr<!cir.record<struct "Struct" {!s32i}>>, ["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


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to