Author: Morris Hafner Date: 2025-08-13T18:03:05+02:00 New Revision: 0045bfca9c51e3b61b1e1772adf3a2c391a039c2
URL: https://github.com/llvm/llvm-project/commit/0045bfca9c51e3b61b1e1772adf3a2c391a039c2 DIFF: https://github.com/llvm/llvm-project/commit/0045bfca9c51e3b61b1e1772adf3a2c391a039c2.diff LOG: [CIR} Add support for static member variable instantiation (#153200) This patch handles both implicit and explicit template instantiations of template class static member variables. Added: Modified: clang/lib/CIR/CodeGen/CIRGenModule.cpp clang/lib/CIR/CodeGen/CIRGenModule.h clang/lib/CIR/CodeGen/CIRGenerator.cpp clang/test/CIR/CodeGen/static-vars.cpp Removed: ################################################################################ diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index 45dfcf57b1884..d5296881540aa 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -438,6 +438,20 @@ void CIRGenModule::emitGlobalFunctionDefinition(clang::GlobalDecl gd, errorNYI(funcDecl->getSourceRange(), "deferredAnnotations"); } +void CIRGenModule::handleCXXStaticMemberVarInstantiation(VarDecl *vd) { + VarDecl::DefinitionKind dk = vd->isThisDeclarationADefinition(); + if (dk == VarDecl::Definition && vd->hasAttr<DLLImportAttr>()) + return; + + TemplateSpecializationKind tsk = vd->getTemplateSpecializationKind(); + // If we have a definition, this might be a deferred decl. If the + // instantiation is explicit, make sure we emit it at the end. + if (vd->getDefinition() && tsk == TSK_ExplicitInstantiationDefinition) + getAddrOfGlobalVar(vd); + + emitTopLevelDecl(vd); +} + mlir::Operation *CIRGenModule::getGlobalValue(StringRef name) { return mlir::SymbolTable::lookupSymbolIn(theModule, name); } diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.h b/clang/lib/CIR/CodeGen/CIRGenModule.h index 5538aba57014c..283b76a0dd16e 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.h +++ b/clang/lib/CIR/CodeGen/CIRGenModule.h @@ -120,6 +120,9 @@ class CIRGenModule : public CIRGenTypeCache { mlir::Operation *lastGlobalOp = nullptr; + /// Tell the consumer that this variable has been instantiated. + void handleCXXStaticMemberVarInstantiation(VarDecl *vd); + llvm::DenseMap<const Decl *, cir::GlobalOp> staticLocalDeclMap; mlir::Operation *getGlobalValue(llvm::StringRef ref); diff --git a/clang/lib/CIR/CodeGen/CIRGenerator.cpp b/clang/lib/CIR/CodeGen/CIRGenerator.cpp index b0357d9d3b7fa..fb013d1532689 100644 --- a/clang/lib/CIR/CodeGen/CIRGenerator.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenerator.cpp @@ -163,7 +163,7 @@ void CIRGenerator::HandleCXXStaticMemberVarInstantiation(VarDecl *D) { if (diags.hasErrorOccurred()) return; - cgm->errorNYI(D->getSourceRange(), "HandleCXXStaticMemberVarInstantiation"); + cgm->handleCXXStaticMemberVarInstantiation(D); } void CIRGenerator::CompleteTentativeDefinition(VarDecl *d) { diff --git a/clang/test/CIR/CodeGen/static-vars.cpp b/clang/test/CIR/CodeGen/static-vars.cpp index d949936f6bff9..4f22fc7abc541 100644 --- a/clang/test/CIR/CodeGen/static-vars.cpp +++ b/clang/test/CIR/CodeGen/static-vars.cpp @@ -2,6 +2,37 @@ // RUN: FileCheck --input-file=%t.cir %s // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t1.ll // RUN: FileCheck --check-prefix=LLVM --input-file=%t1.ll %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t1.ll +// RUN: FileCheck --check-prefix=OGCG --input-file=%t1.ll %s + +template<typename T> +struct implicitly_instantiated { + static T member; +}; + +template<typename T> +T implicitly_instantiated<T>::member = 12345; + +int use_implicitly_instantiated() { + return implicitly_instantiated<int>::member; +} + +// CHECK-DAG: cir.global linkonce_odr comdat @_ZN23implicitly_instantiatedIiE6memberE = #cir.int<12345> : !s32i +// LLVM-DAG: @_ZN23implicitly_instantiatedIiE6memberE = linkonce_odr global i32 12345, comdat +// OGCG-DAG: @_ZN23implicitly_instantiatedIiE6memberE = linkonce_odr global i32 12345, comdat + +template<typename T> +struct explicitly_instantiated { + static T member; +}; + +template<typename T> +T explicitly_instantiated<T>::member = 54321; + +template int explicitly_instantiated<int>::member; +// CHECK-DAG: cir.global weak_odr comdat @_ZN23explicitly_instantiatedIiE6memberE = #cir.int<54321> : !s32i +// LLVM-DAG: @_ZN23explicitly_instantiatedIiE6memberE = weak_odr global i32 54321, comdat +// OGCG-DAG: @_ZN23explicitly_instantiatedIiE6memberE = weak_odr global i32 54321, comdat void func1(void) { // Should lower default-initialized static vars. @@ -42,6 +73,8 @@ void func2(void) { // LLVM-DAG: $_ZZ4testvE1c = comdat any // LLVM-DAG: @_ZZ4testvE1c = linkonce_odr global i32 0, comdat, align 4 +// OGCG-DAG: $_ZZ4testvE1c = comdat any +// OGCG-DAG: @_ZZ4testvE1c = linkonce_odr global i32 0, comdat, align 4 inline void test() { static int c; } // CHECK-LABEL: @_Z4testv _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits