https://github.com/erichkeane created 
https://github.com/llvm/llvm-project/pull/182608

These are fairly simple, particularly if they don't need special cleanups 
(which is left unimplemented), but this provides init for a global reference 
variable.

>From d461fc0f99daaf8d94f6fd48c405f7e1270ce596 Mon Sep 17 00:00:00 2001
From: erichkeane <[email protected]>
Date: Fri, 20 Feb 2026 08:32:50 -0800
Subject: [PATCH] [CIR] Add support for globals reference variables

These are fairly simple, particularly if they don't need special
cleanups (which is left unimplemented), but this provides init for a
global reference variable.
---
 clang/include/clang/CIR/MissingFeatures.h     |   1 +
 clang/lib/CIR/CodeGen/CIRGenCXX.cpp           |  31 ++++-
 clang/lib/CIR/CodeGen/CIRGenConstantEmitter.h |   2 +
 clang/lib/CIR/CodeGen/CIRGenExpr.cpp          |  11 +-
 clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp  |  16 ++-
 clang/lib/CIR/CodeGen/CIRGenModule.cpp        | 108 +++++++++++++++
 clang/lib/CIR/CodeGen/CIRGenModule.h          |   5 +
 clang/test/CIR/CodeGenCXX/global-refs.cpp     | 130 ++++++++++++++++++
 8 files changed, 296 insertions(+), 8 deletions(-)
 create mode 100644 clang/test/CIR/CodeGenCXX/global-refs.cpp

diff --git a/clang/include/clang/CIR/MissingFeatures.h 
b/clang/include/clang/CIR/MissingFeatures.h
index 97c76df0bb0b9..4b26dd96fc3ee 100644
--- a/clang/include/clang/CIR/MissingFeatures.h
+++ b/clang/include/clang/CIR/MissingFeatures.h
@@ -279,6 +279,7 @@ struct MissingFeatures {
   static bool emitNullabilityCheck() { return false; }
   static bool emitTypeCheck() { return false; }
   static bool emitTypeMetadataCodeForVCall() { return false; }
+  static bool materializedGlobalTempCache() { return false; }
 
   // Fast math.
   static bool fastMathGuard() { return false; }
diff --git a/clang/lib/CIR/CodeGen/CIRGenCXX.cpp 
b/clang/lib/CIR/CodeGen/CIRGenCXX.cpp
index c3457e40a9110..3033f1c810845 100644
--- a/clang/lib/CIR/CodeGen/CIRGenCXX.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenCXX.cpp
@@ -294,5 +294,34 @@ void CIRGenModule::emitCXXGlobalVarDeclInit(const VarDecl 
*varDecl,
     return;
   }
 
-  errorNYI(varDecl->getSourceRange(), "global with reference type");
+  mlir::OpBuilder::InsertionGuard guard(builder);
+  auto *block = builder.createBlock(&addr.getCtorRegion());
+  CIRGenFunction::LexicalScope scope{*curCGF, addr.getLoc(),
+                                     builder.getInsertionBlock()};
+  scope.setAsGlobalInit();
+  builder.setInsertionPointToStart(block);
+  mlir::Value getGlobal = builder.createGetGlobal(addr);
+
+  Address declAddr(getGlobal, getASTContext().getDeclAlign(varDecl));
+  assert(performInit && "cannot have a constant initializer which needs "
+                        "destruction for reference");
+  RValue rv = cgf.emitReferenceBindingToExpr(varDecl->getInit());
+  {
+    mlir::OpBuilder::InsertionGuard guard(builder);
+    mlir::Operation *rvalDefOp = rv.getValue().getDefiningOp();
+    if (rvalDefOp && rvalDefOp->getBlock()) {
+      mlir::Block *rvalSrcBlock = rvalDefOp->getBlock();
+
+      if (!rvalSrcBlock->empty() && isa<cir::YieldOp>(rvalSrcBlock->back())) {
+        mlir::Operation &front = rvalSrcBlock->front();
+        getGlobal.getDefiningOp()->moveBefore(&front);
+        builder.setInsertionPoint(cast<cir::YieldOp>(rvalSrcBlock->back()));
+      }
+    }
+    cgf.emitStoreOfScalar(rv.getValue(), declAddr, /*isVolatile=*/false,
+                          ty, LValueBaseInfo{});
+  }
+
+  builder.setInsertionPointToEnd(block);
+  cir::YieldOp::create(builder, addr->getLoc());
 }
diff --git a/clang/lib/CIR/CodeGen/CIRGenConstantEmitter.h 
b/clang/lib/CIR/CodeGen/CIRGenConstantEmitter.h
index 1cd7b5bffb1dc..5280198524773 100644
--- a/clang/lib/CIR/CodeGen/CIRGenConstantEmitter.h
+++ b/clang/lib/CIR/CodeGen/CIRGenConstantEmitter.h
@@ -65,6 +65,8 @@ class ConstantEmitter {
   /// constant.  If this succeeds, the emission must be finalized.
   mlir::Attribute tryEmitForInitializer(const VarDecl &d);
 
+  mlir::Attribute emitForInitializer(const APValue &value, QualType destType);
+
   void finalize(cir::GlobalOp gv);
 
   // All of the "abstract" emission methods below permit the emission to
diff --git a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
index 83d51bac01d1e..69d98c34c249c 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExpr.cpp
@@ -1657,10 +1657,13 @@ static Address createReferenceTemporary(CIRGenFunction 
&cgf,
   }
   case SD_Thread:
   case SD_Static: {
-    cgf.cgm.errorNYI(
-        m->getSourceRange(),
-        "createReferenceTemporary: static/thread storage duration");
-    return Address::invalid();
+    auto addr =
+        mlir::cast<cir::GlobalOp>(cgf.cgm.getAddrOfGlobalTemporary(m, inner));
+    auto getGlobal = cgf.cgm.getBuilder().createGetGlobal(addr);
+    assert(addr.getAlignment().has_value() &&
+           "This should always have an alignment");
+    return Address(getGlobal,
+                   
clang::CharUnits::fromQuantity(addr.getAlignment().value()));
   }
 
   case SD_Dynamic:
diff --git a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp 
b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
index 462e73b3acc8d..e3dca9bc0f3c7 100644
--- a/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenExprConstant.cpp
@@ -1485,9 +1485,11 @@ ConstantLValueEmitter::VisitCXXTypeidExpr(const 
CXXTypeidExpr *e) {
 
 ConstantLValue ConstantLValueEmitter::VisitMaterializeTemporaryExpr(
     const MaterializeTemporaryExpr *e) {
-  cgm.errorNYI(e->getSourceRange(),
-               "ConstantLValueEmitter: materialize temporary expr");
-  return {};
+  assert(e->getStorageDuration() == SD_Static);
+  const Expr *inner = e->getSubExpr()->skipRValueSubobjectAdjustments();
+  mlir::Operation *global = cgm.getAddrOfGlobalTemporary(e, inner);
+  return ConstantLValue(
+      cgm.getBuilder().getGlobalViewAttr(mlir::cast<cir::GlobalOp>(global)));
 }
 
 
//===----------------------------------------------------------------------===//
@@ -1499,6 +1501,14 @@ mlir::Attribute 
ConstantEmitter::tryEmitForInitializer(const VarDecl &d) {
   return markIfFailed(tryEmitPrivateForVarInit(d));
 }
 
+mlir::Attribute ConstantEmitter::emitForInitializer(const APValue &value,
+                                                    QualType destType) {
+  initializeNonAbstract();
+  auto c = tryEmitPrivateForMemory(value, destType);
+  assert(c && "couldn't emit constant value non-abstractly?");
+  return c;
+}
+
 void ConstantEmitter::finalize(cir::GlobalOp gv) {
   assert(initializedNonAbstract &&
          "finalizing emitter that was used for abstract emission?");
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp 
b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
index dbd3c92797f23..8c8483bae94d9 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp
@@ -2884,3 +2884,111 @@ cir::LabelOp
 CIRGenModule::lookupBlockAddressInfo(cir::BlockAddrInfoAttr blockInfo) {
   return blockAddressInfoToLabel.lookup(blockInfo);
 }
+
+mlir::Operation *
+CIRGenModule::getAddrOfGlobalTemporary(const MaterializeTemporaryExpr *mte,
+                                       const Expr *init) {
+  assert((mte->getStorageDuration() == SD_Static ||
+          mte->getStorageDuration() == SD_Thread) &&
+         "not a global temporary");
+  const auto *varDecl = cast<VarDecl>(mte->getExtendingDecl());
+
+  // If we're not materializing a subobject of the temporary, keep the
+  // cv-qualifiers from the type of the MaterializeTemporaryExpr.
+  QualType materializedType = init->getType();
+  if (init == mte->getSubExpr())
+    materializedType = mte->getType();
+
+  CharUnits align = getASTContext().getTypeAlignInChars(materializedType);
+
+  assert(!cir::MissingFeatures::materializedGlobalTempCache());
+
+  // FIXME: If an externally-visible declaration extends multiple temporaries,
+  // we need to give each temporary the same name in every translation unit 
(and
+  // we also need to make the temporaries externally-visible).
+  llvm::SmallString<256> name;
+  llvm::raw_svector_ostream out(name);
+  getCXXABI().getMangleContext().mangleReferenceTemporary(
+      varDecl, mte->getManglingNumber(), out);
+
+  APValue *value = nullptr;
+  if (mte->getStorageDuration() == SD_Static && varDecl->evaluateValue()) {
+    // If the initializer of the extending declaration is a constant
+    // initializer, we should have a cached constant initializer for this
+    // temporay. Note taht this m ight have a different value from the value
+    // computed by evaluating the initializer if the surrounding constant
+    // expression modifies the temporary.
+    value = mte->getOrCreateValue(/*MayCreate=*/false);
+  }
+
+  // Try evaluating it now, it might have a constant initializer
+  Expr::EvalResult evalResult;
+  if (!value && init->EvaluateAsRValue(evalResult, getASTContext()) &&
+      !evalResult.hasSideEffects())
+    value = &evalResult.Val;
+
+  assert(!cir::MissingFeatures::addressSpace());
+
+  std::optional<ConstantEmitter> emitter;
+  mlir::Attribute initialValue = nullptr;
+  bool isConstant = false;
+  mlir::Type type;
+
+  if (value) {
+    emitter.emplace(*this);
+    initialValue =
+        emitter->emitForInitializer(*value, materializedType);
+
+    isConstant = materializedType.isConstantStorage(
+        getASTContext(), /*ExcludeCtor=*/value, /*ExcludeDtor=*/false);
+
+    type = mlir::cast<mlir::TypedAttr>(initialValue).getType();
+  } else {
+    // No initializer, the initialization will be provided when we initialize
+    // the declaration which performed lifetime extension.
+    type = getTypes().convertTypeForMem(materializedType);
+  }
+
+  // Create a global variable for this lifetime-extended temporary.
+  cir::GlobalLinkageKind linkage =
+      getCIRLinkageVarDefinition(varDecl, /*isConstant=*/false);
+  if (linkage == cir::GlobalLinkageKind::ExternalLinkage) {
+    const VarDecl *initVD;
+    if (varDecl->isStaticDataMember() && varDecl->getAnyInitializer(initVD) &&
+        isa<CXXRecordDecl>(initVD->getLexicalDeclContext())) {
+      // Temporaries defined inside a class get linkonce_odr linkage because 
the
+      // calss can be defined in multiple translation units.
+      errorNYI(mte->getSourceRange(), "static data member initialization");
+    } else {
+      // There is no need for this temporary to have external linkage if the
+      // VarDecl has external linkage.
+      linkage = cir::GlobalLinkageKind::InternalLinkage;
+    }
+  }
+  auto loc = getLoc(mte->getSourceRange());
+  auto gv = createGlobalOp(*this, loc, name, type, isConstant);
+  gv.setInitialValueAttr(initialValue);
+
+  if (emitter)
+    emitter->finalize(gv);
+  // Don't assign dllimport or dllexport to local linkage globals
+  if (!gv.hasLocalLinkage()) {
+    setGVProperties(gv, varDecl);
+    assert(!cir::MissingFeatures::setDLLStorageClass());
+  }
+
+  gv.setAlignment(align.getAsAlign().value());
+  if (supportsCOMDAT() && gv.isWeakForLinker())
+    errorNYI(mte->getSourceRange(),
+             "Global temporary with comdat/weak linkage");
+  if (varDecl->getTLSKind())
+    errorNYI(mte->getSourceRange(),
+             "Global temporary with thread local storage");
+  mlir::Operation *cv = gv;
+
+  assert(!cir::MissingFeatures::addressSpace());
+
+  assert(!cir::MissingFeatures::materializedGlobalTempCache());
+
+  return cv;
+}
diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.h 
b/clang/lib/CIR/CodeGen/CIRGenModule.h
index 5b8a105e4912f..3f5a8490864b3 100644
--- a/clang/lib/CIR/CodeGen/CIRGenModule.h
+++ b/clang/lib/CIR/CodeGen/CIRGenModule.h
@@ -655,6 +655,11 @@ class CIRGenModule : public CIRGenTypeCache {
   // Finalize CIR code generation.
   void release();
 
+  /// Returns a pointer to a global variable representing a temporary with
+  /// static or thread storage duration.
+  mlir::Operation *getAddrOfGlobalTemporary(const MaterializeTemporaryExpr 
*mte,
+                                            const Expr *init);
+
   /// -------
   /// Visibility and Linkage
   /// -------
diff --git a/clang/test/CIR/CodeGenCXX/global-refs.cpp 
b/clang/test/CIR/CodeGenCXX/global-refs.cpp
new file mode 100644
index 0000000000000..4271b7ecf3e6b
--- /dev/null
+++ b/clang/test/CIR/CodeGenCXX/global-refs.cpp
@@ -0,0 +1,130 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o 
- | FileCheck %s --check-prefixes=CIR
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o 
- | FileCheck %s --check-prefixes=LLVM
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o - | 
FileCheck %s --check-prefixes=LLVM
+
+struct DefCtor{};
+struct WithCtor{
+  WithCtor();
+  WithCtor(int);
+};
+
+struct WithCtorDtor{
+  WithCtorDtor();
+  WithCtorDtor(int);
+  ~WithCtorDtor();
+};
+
+int globalInt;
+// CIR: cir.global external @globalInt = #cir.int<0> : !s32i {alignment = 4 : 
i64}
+// LLVM: @globalInt = global i32 0, align 4
+
+int &globalIntRef = globalInt;
+// CIR: cir.global constant external @globalIntRef = 
#cir.global_view<@globalInt> : !cir.ptr<!s32i> {alignment = 8 : i64}
+// LLVM: @globalIntRef = constant ptr @globalInt, align 8
+
+const int &constGlobalIntRef = 5;
+// CIR: cir.global "private" external @_ZGR17constGlobalIntRef_ = #cir.int<5> 
: !s32i {alignment = 4 : i64}
+// CIR: cir.global constant external @constGlobalIntRef = 
#cir.global_view<@_ZGR17constGlobalIntRef_> : !cir.ptr<!s32i> {alignment = 8 : 
i64}
+// LLVM: @_ZGR17constGlobalIntRef_ = {{.*}}global i32 5, align 4
+// LLVM: @constGlobalIntRef = constant ptr @_ZGR17constGlobalIntRef_, align 8
+
+DefCtor defCtor{};
+// CIR: cir.global external @defCtor = #cir.undef : !rec_DefCtor {alignment = 
1 : i64}
+// LLVM: @defCtor = global %struct.DefCtor undef, align 1
+// OGCG: FAIL
+
+DefCtor &defCtorRef = defCtor;
+// CIR: cir.global constant external @defCtorRef = #cir.global_view<@defCtor> 
: !cir.ptr<!rec_DefCtor> {alignment = 8 : i64}
+// LLVM: @defCtorRef = constant ptr @defCtor, align 8
+// OGCG: FAIL
+
+const DefCtor &constDefCtorRef{};
+// CIR: cir.global "private" constant external @_ZGR15constDefCtorRef_ = 
#cir.undef : !rec_DefCtor {alignment = 1 : i64}
+// CIR: cir.global constant external @constDefCtorRef = 
#cir.global_view<@_ZGR15constDefCtorRef_> : !cir.ptr<!rec_DefCtor> {alignment = 
8 : i64}
+// LLVM: @_ZGR15constDefCtorRef_ = {{.*}}constant %struct.DefCtor undef, align 
1
+// LLVM: @constDefCtorRef = constant ptr @_ZGR15constDefCtorRef_, align 8
+// OGCG: FAIL
+
+WithCtor withCtor{};
+// CIR: cir.global external @withCtor = #cir.zero : !rec_WithCtor {alignment = 
1 : i64, ast = #cir.var.decl.ast}
+// CIR-NEXT: cir.func internal private @__cxx_global_var_init{{.*}}() {
+// CIR-NEXT:   %[[GET_GLOB:.*]] = cir.get_global @withCtor : 
!cir.ptr<!rec_WithCtor>
+// CIR-NEXT:   cir.call @_ZN8WithCtorC1Ev(%[[GET_GLOB]]) : 
(!cir.ptr<!rec_WithCtor>{{.*}}) -> ()
+// CIR-NEXT:   cir.return
+// CIR-NEXT: }
+// LLVM: @withCtor = global %struct.WithCtor zeroinitializer, align 1
+// OGCG: FAIL
+
+WithCtor &withCtorRef = withCtor;
+// CIR: cir.global constant external @withCtorRef = 
#cir.global_view<@withCtor> : !cir.ptr<!rec_WithCtor> {alignment = 8 : i64}
+// LLVM: @withCtorRef = constant ptr @withCtor, align 8
+// OGCG: FAIL
+
+const WithCtor &constWithCtorRef{};
+// CIR: cir.global external @constWithCtorRef = #cir.ptr<null> : 
!cir.ptr<!rec_WithCtor> {alignment = 8 : i64, ast = #cir.var.decl.ast}
+// CIR-NEXT: cir.func internal private @__cxx_global_var_init{{.*}}() {
+// CIR-NEXT:   %[[GET_GLOB:.*]] = cir.get_global @constWithCtorRef : 
!cir.ptr<!cir.ptr<!rec_WithCtor>>
+// CIR-NEXT:   %[[GET_GLOB_OBJ:.*]] = cir.get_global @_ZGR16constWithCtorRef_ 
: !cir.ptr<!rec_WithCtor>
+// CIR-NEXT:   cir.call @_ZN8WithCtorC1Ev(%[[GET_GLOB_OBJ]]) : 
(!cir.ptr<!rec_WithCtor>{{.*}}) -> ()
+// CIR-NEXT:   cir.store align(8) %[[GET_GLOB_OBJ]], %[[GET_GLOB]] : 
!cir.ptr<!rec_WithCtor>, !cir.ptr<!cir.ptr<!rec_WithCtor>>
+// CIR-NEXT:   cir.return
+// CIR-NEXT: }
+// LLVM: @constWithCtorRef = global ptr null, align 8
+// OGCG: FAIL
+
+const WithCtor &constWithCtorRef2{5};
+// CIR: cir.global external @constWithCtorRef2 = #cir.ptr<null> : 
!cir.ptr<!rec_WithCtor> {alignment = 8 : i64, ast = #cir.var.decl.ast}
+// CIR-NEXT: cir.func internal private @__cxx_global_var_init{{.*}}() {
+// CIR-NEXT:   %[[GET_GLOB:.*]] = cir.get_global @constWithCtorRef2 : 
!cir.ptr<!cir.ptr<!rec_WithCtor>>
+// CIR-NEXT:   %[[GET_GLOB_OBJ:.*]] = cir.get_global @_ZGR17constWithCtorRef2_ 
: !cir.ptr<!rec_WithCtor>
+// CIR-NEXT:   %[[FIVE:.*]] = cir.const #cir.int<5> : !s32i
+// CIR-NEXT:   cir.call @_ZN8WithCtorC1Ei(%[[GET_GLOB_OBJ]], %[[FIVE]]) : 
(!cir.ptr<!rec_WithCtor>{{.*}}, !s32i{{.*}}) -> ()
+// CIR-NEXT:   cir.store align(8) %[[GET_GLOB_OBJ]], %[[GET_GLOB]] : 
!cir.ptr<!rec_WithCtor>, !cir.ptr<!cir.ptr<!rec_WithCtor>>
+// CIR-NEXT:   cir.return
+// CIR-NEXT: }
+// LLVM: @constWithCtorRef2 = global ptr null, align 8
+// OGCG: FAIL
+
+WithCtorDtor withCtorDtor{};
+// CIR: cir.global external @withCtorDtor = #cir.zero : !rec_WithCtorDtor 
{alignment = 1 : i64, ast = #cir.var.decl.ast}
+// CIR: cir.func internal private @__cxx_global_var_init{{.*}}() {
+// CIR-NEXT:   %[[GET_GLOB:.*]] = cir.get_global @withCtorDtor : 
!cir.ptr<!rec_WithCtorDtor>
+// CIR-NEXT:   cir.call @_ZN12WithCtorDtorC1Ev(%[[GET_GLOB]]) : 
(!cir.ptr<!rec_WithCtorDtor>{{.*}}) -> ()
+// CIR-NEXT:   %[[GET_GLOB:.*]] = cir.get_global @withCtorDtor : 
!cir.ptr<!rec_WithCtorDtor> 
+// CIR-NEXT:   %[[GET_DTOR:.*]] = cir.get_global @_ZN12WithCtorDtorD1Ev : 
!cir.ptr<!cir.func<(!cir.ptr<!rec_WithCtorDtor>)>>
+// CIR-NEXT:   %[[VOID_FN_PTR:.*]] = cir.cast bitcast %[[GET_DTOR]] : 
!cir.ptr<!cir.func<(!cir.ptr<!rec_WithCtorDtor>)>> -> 
!cir.ptr<!cir.func<(!cir.ptr<!void>)>>
+// CIR-NEXT:   %[[GLOB_TO_VOID:.*]] = cir.cast bitcast %[[GET_GLOB]] : 
!cir.ptr<!rec_WithCtorDtor> -> !cir.ptr<!void>
+// CIR-NEXT:   %[[DSO_HANDLE:.*]] = cir.get_global @__dso_handle : !cir.ptr<i8>
+// CIR-NEXT:   cir.call @__cxa_atexit(%[[VOID_FN_PTR]], %[[GLOB_TO_VOID]], 
%[[DSO_HANDLE]]) : (!cir.ptr<!cir.func<(!cir.ptr<!void>)>>, !cir.ptr<!void>, 
!cir.ptr<i8>{{.*}}) -> ()
+// CIR-NEXT:   cir.return
+// CIR-NEXT: }
+// LLVM: @withCtorDtor = global %struct.WithCtorDtor zeroinitializer, align 1
+// OGCG: FAIL
+
+WithCtorDtor &withCtorDtorRef = withCtorDtor;
+// CIR: cir.global constant external @withCtorDtorRef = 
#cir.global_view<@withCtorDtor> : !cir.ptr<!rec_WithCtorDtor> {alignment = 8 : 
i64}
+// LLVM: @withCtorDtorRef = constant ptr @withCtorDtor, align 8
+// OGCG: FAIL
+
+// LLVM: define internal void @__cxx_global_var_init{{.*}}()
+// LLVM:   call void @_ZN8WithCtorC1Ev(ptr {{.*}}@withCtor)
+// LLVM-NEXT:   ret void
+
+// LLVM: define internal void @__cxx_global_var_init{{.*}}()
+// LLVM:   call void @_ZN8WithCtorC1Ev(ptr {{.*}}@_ZGR16constWithCtorRef_)
+// LLVM-NEXT:   store ptr @_ZGR16constWithCtorRef_, ptr @constWithCtorRef, 
align 8
+// LLVM-NEXT:   ret void
+
+// LLVM: define internal void @__cxx_global_var_init{{.*}}()
+// LLVM:   call void @_ZN8WithCtorC1Ei(ptr {{.*}}@_ZGR17constWithCtorRef2_, 
i32 {{.*}}5)
+// LLVM-NEXT:   store ptr @_ZGR17constWithCtorRef2_, ptr @constWithCtorRef2, 
align 8
+// LLVM-NEXT:   ret void
+
+// LLVM: define internal void @__cxx_global_var_init{{.*}}()
+// LLVM:   call void @_ZN12WithCtorDtorC1Ev(ptr {{.*}}@withCtorDtor)
+// LLVM-NEXT:   call {{.*}}@__cxa_atexit(ptr {{.*}}@_ZN12WithCtorDtorD1Ev, ptr 
{{.*}}@withCtorDtor, ptr {{.*}}@__dso_handle)
+// LLVM-NEXT:   ret void
+
+// TODO(cir): Once we get destructors for temporaries done, we should test them
+// here, same as the 'const-WithCtor' examples, except with the 'withCtorDtor'
+// versions.

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to