https://github.com/andykaylor created 
https://github.com/llvm/llvm-project/pull/137253

This adds the handlers for Decl::Namespace and Decl::UsingDirective (which is 
needed for anonymous namespaces).

>From 8e8baed406019bee2b5acd71b0d08b65360ee032 Mon Sep 17 00:00:00 2001
From: Andy Kaylor <akay...@nvidia.com>
Date: Thu, 17 Apr 2025 11:58:03 -0700
Subject: [PATCH] [CIR] Upstream namepsace handling

This adds the handlers for Decl::Namespace and Decl::UsingDirective (which
is needed for anonymous namespaces).
---
 clang/lib/CIR/CodeGen/CIRGenDecl.cpp   |  4 ++
 clang/lib/CIR/CodeGen/CIRGenModule.cpp | 20 ++++++++++
 clang/lib/CIR/CodeGen/CIRGenModule.h   |  3 ++
 clang/test/CIR/CodeGen/namespace.cpp   | 55 ++++++++++++++++++++++++++
 4 files changed, 82 insertions(+)
 create mode 100644 clang/test/CIR/CodeGen/namespace.cpp

diff --git a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp 
b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
index d7cbb4f64b2ea..8026f22b00117 100644
--- a/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenDecl.cpp
@@ -260,7 +260,11 @@ void CIRGenFunction::emitExprAsInit(const Expr *init, 
const ValueDecl *d,
 
 void CIRGenFunction::emitDecl(const Decl &d) {
   switch (d.getKind()) {
+  case Decl::Namespace:
+    llvm_unreachable("Declaration should not be in declstmts!");
+
   case Decl::Record: // struct/union/class X;
+  case Decl::UsingDirective: // using namespace X; [C++]
     assert(!cir::MissingFeatures::generateDebugInfo());
     return;
   case Decl::Var: {
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp 
b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index 0b266df13fd40..0f4193b5756fd 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -621,6 +621,20 @@ CIRGenModule::getCIRLinkageVarDefinition(const VarDecl 
*vd, bool isConstant) {
   return getCIRLinkageForDeclarator(vd, linkage, isConstant);
 }
 
+void CIRGenModule::emitDeclContext(const DeclContext *dc) {
+  for (Decl *decl : dc->decls()) {
+    // Unlike other DeclContexts, the contents of an ObjCImplDecl at TU scope
+    // are themselves considered "top-level", so EmitTopLevelDecl on an
+    // ObjCImplDecl does not recursively visit them. We need to do that in
+    // case they're nested inside another construct (LinkageSpecDecl /
+    // ExportDecl) that does stop them from being considered "top-level".
+    if (auto *oid = dyn_cast<ObjCImplDecl>(decl))
+      errorNYI(oid->getSourceRange(), "emitDeclConext: ObjCImplDecl");
+
+    emitTopLevelDecl(decl);
+  }
+}
+
 // Emit code for a single top level declaration.
 void CIRGenModule::emitTopLevelDecl(Decl *decl) {
 
@@ -654,12 +668,18 @@ void CIRGenModule::emitTopLevelDecl(Decl *decl) {
     emitGlobalOpenACCDecl(cast<OpenACCDeclareDecl>(decl));
     break;
 
+  case Decl::UsingDirective: // using namespace X; [C++]
   case Decl::Typedef:
   case Decl::TypeAlias: // using foo = bar; [C++11]
   case Decl::Record:
   case Decl::CXXRecord:
     assert(!cir::MissingFeatures::generateDebugInfo());
     break;
+
+  // C++ Decls
+  case Decl::Namespace:
+    emitDeclContext(cast<NamespaceDecl>(decl));
+    break;
   }
 }
 
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.h 
b/clang/lib/CIR/CodeGen/CIRGenModule.h
index 1c14959700cf9..ea30903a97167 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.h
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.h
@@ -170,6 +170,9 @@ class CIRGenModule : public CIRGenTypeCache {
 
   void emitGlobalOpenACCDecl(const clang::OpenACCConstructDecl *cd);
 
+  // C++ related functions.
+  void emitDeclContext(const DeclContext *dc);
+
   /// Return the result of value-initializing the given type, i.e. a null
   /// expression of the given type.
   mlir::Value emitNullConstant(QualType t, mlir::Location loc);
diff --git a/clang/test/CIR/CodeGen/namespace.cpp 
b/clang/test/CIR/CodeGen/namespace.cpp
new file mode 100644
index 0000000000000..cfeb17bd19ced
--- /dev/null
+++ b/clang/test/CIR/CodeGen/namespace.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir 
-emit-cir %s -o - 2>&1 | FileCheck %s
+
+// Test anonymous namespace.
+namespace {
+  int g1 = 1;
+
+  // Note: This causes a warning about the function being undefined, but we
+  // currently have a problem with duplicate definitions when we call 
functions.
+  // This should be updated when that problem is fixed.
+  void f1(void);
+}
+
+
+// Test named namespace.
+namespace test {
+  int g2 = 2;
+  void f2(void);
+
+  // Test nested namespace.
+  namespace test2 {
+    int g3 = 3;
+    void f3(void);
+  }
+}
+
+// CHECK-DAG: cir.global internal @_ZN12_GLOBAL__N_12g1E = #cir.int<1> : !s32i
+// CHECK-DAG: cir.global external @_ZN4test2g2E = #cir.int<2> : !s32i
+// CHECK-DAG: cir.global external @_ZN4test5test22g3E = #cir.int<3> : !s32i
+// CHECK-DAG: cir.func @_ZN12_GLOBAL__N_12f1Ev()
+// CHECK-DAG: cir.func @_ZN4test2f2Ev()
+// CHECK-DAG: cir.func @_ZN4test5test22f3Ev()
+
+using namespace test;
+
+// Test global function.
+int f4(void) {
+    f1();
+    f2();
+    test2::f3();
+    return g1 + g2 + test2::g3;
+}
+
+// The namespace gets added during name mangling, so this is wrong but 
expected.
+// CHECK: cir.func @_Z2f4v()
+// CHECK:   cir.call @_ZN12_GLOBAL__N_12f1Ev()
+// CHECK:   cir.call @_ZN4test2f2Ev()
+// CHECK:   cir.call @_ZN4test5test22f3Ev()
+// CHECK:   %[[G1_ADDR:.*]] = cir.get_global @_ZN12_GLOBAL__N_12g1E : 
!cir.ptr<!s32i>
+// CHECK:   %[[G1_VAL:.*]] = cir.load %[[G1_ADDR]] : !cir.ptr<!s32i>, !s32i
+// CHECK:   %[[G2_ADDR:.*]] = cir.get_global @_ZN4test2g2E : !cir.ptr<!s32i>
+// CHECK:   %[[G2_VAL:.*]] = cir.load %[[G2_ADDR]] : !cir.ptr<!s32i>, !s32i
+// CHECK:   %[[SUM:.*]] = cir.binop(add, %[[G1_VAL]], %[[G2_VAL]]) nsw : !s32i
+// CHECK:   %[[G3_ADDR:.*]] = cir.get_global @_ZN4test5test22g3E : 
!cir.ptr<!s32i>
+// CHECK:   %[[G3_VAL:.*]] = cir.load %[[G3_ADDR]] : !cir.ptr<!s32i>, !s32i
+// CHECK:   %[[SUM2:.*]] = cir.binop(add, %[[SUM]], %[[G3_VAL]]) nsw : !s32i

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

Reply via email to