Author: Andy Kaylor Date: 2025-06-05T16:50:36-07:00 New Revision: 6c1ca07586196c5a693f720d35a9a4be6e76d7d2
URL: https://github.com/llvm/llvm-project/commit/6c1ca07586196c5a693f720d35a9a4be6e76d7d2 DIFF: https://github.com/llvm/llvm-project/commit/6c1ca07586196c5a693f720d35a9a4be6e76d7d2.diff LOG: [CIR] Add decl case for template specialization (#143029) This change adds the switch case to allow template specialization to pass through emitTopLevelDecl without issuing an error. Added: clang/test/CIR/CodeGen/template-specialization.cpp Modified: clang/include/clang/CIR/MissingFeatures.h clang/lib/CIR/CodeGen/CIRGenModule.cpp Removed: ################################################################################ diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h index 7f20424e9b675..f1e0c15d41f64 100644 --- a/clang/include/clang/CIR/MissingFeatures.h +++ b/clang/include/clang/CIR/MissingFeatures.h @@ -217,6 +217,7 @@ struct MissingFeatures { static bool peepholeProtection() { return false; } static bool instrumentation() { return false; } static bool cleanupAfterErrorDiags() { return false; } + static bool cxxRecordStaticMembers() { return false; } // Missing types static bool dataMemberType() { return false; } diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index 1c8945206d448..ce3c57e5f20a8 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -1140,7 +1140,6 @@ void CIRGenModule::emitTopLevelDecl(Decl *decl) { case Decl::Typedef: case Decl::TypeAlias: // using foo = bar; [C++11] case Decl::Record: - case Decl::CXXRecord: assert(!cir::MissingFeatures::generateDebugInfo()); break; @@ -1153,6 +1152,12 @@ void CIRGenModule::emitTopLevelDecl(Decl *decl) { case Decl::Namespace: emitDeclContext(Decl::castToDeclContext(decl)); break; + + case Decl::ClassTemplateSpecialization: + case Decl::CXXRecord: + assert(!cir::MissingFeatures::generateDebugInfo()); + assert(!cir::MissingFeatures::cxxRecordStaticMembers()); + break; } } diff --git a/clang/test/CIR/CodeGen/template-specialization.cpp b/clang/test/CIR/CodeGen/template-specialization.cpp new file mode 100644 index 0000000000000..5151f8ce15424 --- /dev/null +++ b/clang/test/CIR/CodeGen/template-specialization.cpp @@ -0,0 +1,103 @@ +// 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 + +template<typename T, typename U> +class Templ {}; + +template<typename T> +class Templ<T, int>{}; + +Templ<int, int> t; + +// CIR: !rec_Templ3Cint2C_int3E = !cir.record<class "Templ<int, int>" padded {!u8i}> +// CIR: cir.global external @t = #cir.zero : !rec_Templ3Cint2C_int3E + +// LLVM: %"class.Templ<int, int>" = type { i8 } +// LLVM: @t = global %"class.Templ<int, int>" zeroinitializer + +// OGCG: %class.Templ = type { i8 } +// OGCG: @t = global %class.Templ zeroinitializer + +template<class T> +class X { +public: + int f() { return 0; } +}; + +template<> class X<int> { +public: + int f() { return 1; } +}; + +void test_double() { + X<double> d; + d.f(); +} + +// CIR: cir.func{{.*}} @_ZN1XIdE1fEv +// CIR: cir.const #cir.int<0> +// +// CIR: cir.func{{.*}} @_Z11test_doublev() +// CIR: cir.call @_ZN1XIdE1fEv + +// LLVM: define{{.*}} i32 @_ZN1XIdE1fEv +// LLVM: store i32 0 +// +// LLVM: define{{.*}} void @_Z11test_doublev() +// LLVM: call i32 @_ZN1XIdE1fEv + +// OGCG: define{{.*}} void @_Z11test_doublev() +// OGCG: call{{.*}} i32 @_ZN1XIdE1fEv +// +// OGCG: define{{.*}} i32 @_ZN1XIdE1fEv +// OGCG: ret i32 0 + +void test_int() { + X<int> n; + n.f(); +} + +// CIR: cir.func{{.*}} @_ZN1XIiE1fEv +// CIR: cir.const #cir.int<1> +// +// CIR: cir.func{{.*}} @_Z8test_intv() +// CIR: cir.call @_ZN1XIiE1fEv + +// LLVM: define{{.*}} i32 @_ZN1XIiE1fEv +// LLVM: store i32 1 +// +// LLVM: define{{.*}} void @_Z8test_intv() +// LLVM: call i32 @_ZN1XIiE1fEv + +// OGCG: define{{.*}} void @_Z8test_intv() +// OGCG: call{{.*}} i32 @_ZN1XIiE1fEv +// +// OGCG: define{{.*}} i32 @_ZN1XIiE1fEv +// OGCG: ret i32 1 + +void test_short() { + X<short> s; + s.f(); +} + +// CIR: cir.func{{.*}} @_ZN1XIsE1fEv +// CIR: cir.const #cir.int<0> +// +// CIR: cir.func{{.*}} @_Z10test_shortv() +// CIR: cir.call @_ZN1XIsE1fEv + +// LLVM: define{{.*}} i32 @_ZN1XIsE1fEv +// LLVM: store i32 0 +// +// LLVM: define{{.*}} void @_Z10test_shortv() +// LLVM: call i32 @_ZN1XIsE1fEv + +// OGCG: define{{.*}} void @_Z10test_shortv() +// OGCG: call{{.*}} i32 @_ZN1XIsE1fEv +// +// OGCG: define{{.*}} i32 @_ZN1XIsE1fEv +// OGCG: ret i32 0 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits