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 87e364197ce7e..e3caa7bee4d1c 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -1139,7 +1139,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; @@ -1148,6 +1147,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 +class Templ {}; + +template +class Templ{}; + +Templ t; + +// CIR: !rec_Templ3Cint2C_int3E = !cir.record" padded {!u8i}> +// CIR: cir.global external @t = #cir.zero : !rec_Templ3Cint2C_int3E + +// LLVM: %"class.Templ" = type { i8 } +// LLVM: @t = global %"class.Templ" zeroinitializer + +// OGCG: %class.Templ = type { i8 } +// OGCG: @t = global %class.Templ zeroinitializer + +template +class X { +public: + int f() { return 0; } +}; + +template<> class X { +public: + int f() { return 1; } +}; + +void test_double() { + X 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 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 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