[clang] [CIR] Upstream support for typedef and type aliases (PR #136335)

via cfe-commits cfe-commits at lists.llvm.org
Fri Apr 18 11:02:22 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Andy Kaylor (andykaylor)

<details>
<summary>Changes</summary>

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.

---
Full diff: https://github.com/llvm/llvm-project/pull/136335.diff


5 Files Affected:

- (modified) clang/lib/CIR/CodeGen/CIRGenDecl.cpp (+8) 
- (modified) clang/lib/CIR/CodeGen/CIRGenModule.cpp (+2) 
- (modified) clang/test/CIR/CodeGen/basic.c (+21) 
- (modified) clang/test/CIR/CodeGen/basic.cpp (+15) 
- (added) clang/test/CIR/CodeGen/typedef.c (+27) 


``````````diff
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 cf687e44044c4..4e1c7803975fd 100644
--- a/clang/test/CIR/CodeGen/basic.c
+++ b/clang/test/CIR/CodeGen/basic.c
@@ -169,3 +169,24 @@ int f6(void) {
 // OGCG-NEXT: entry:
 // OGCG-NEXT:   %[[GV:.*]] = load i32, ptr @gv, align 4
 // OGCG-NEXT:   ret i32 %[[GV]]
+
+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

``````````

</details>


https://github.com/llvm/llvm-project/pull/136335


More information about the cfe-commits mailing list