-
Notifications
You must be signed in to change notification settings - Fork 14.7k
[CIR] Add decl case for template specialization #143029
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This change adds the switch case to allow template specialization to pass through emitTopLevelDecl without issuing an error.
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clangir Author: Andy Kaylor (andykaylor) ChangesThis change adds the switch case to allow template specialization to pass through emitTopLevelDecl without issuing an error. Full diff: https://github.com/llvm/llvm-project/pull/143029.diff 3 Files Affected:
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..f15a1cba55e0e
--- /dev/null
+++ b/clang/test/CIR/CodeGen/template-specialization.cpp
@@ -0,0 +1,88 @@
+// 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 T>
+class X {
+public:
+ int f() { return 0; }
+};
+
+template<> class X<int> {
+public:
+ int f() { return 1; }
+};
+
+// TODO: This will get dropped when we are deferring functions
+// The speecialization is instantiated first
+// CIR: cir.func{{.*}} @_ZN1XIiE1fEv
+// CIR: cir.const #cir.int<1>
+
+// LLVM: define{{.*}} i32 @_ZN1XIiE1fEv
+// LLVM: store i32 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{{.*}} @_Z8test_intv()
+// CIR: cir.call @_ZN1XIiE1fEv
+
+// 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
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2 nits, else lgtm.
}; | ||
|
||
// TODO: This will get dropped when we are deferring functions | ||
// The speecialization is instantiated first |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// The speecialization is instantiated first | |
// The specialization is instantiated first |
int f() { return 0; } | ||
}; | ||
|
||
template<> class X<int> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add another test for a 'partial' specialization. There shouldn't be any additional code (since a ClassTemplatePartialSpecializationDecl
inherits from ClassTemplateSpecializationDecl
, but it should demonstrative.
You can do this by:
template<typename T, typename U>
class Templ {};
template<typename T>
class Templ<T, int>{};
Templ<int, int> t;
This change adds the switch case to allow template specialization to pass through emitTopLevelDecl without issuing an error.
This change adds the switch case to allow template specialization to pass through emitTopLevelDecl without issuing an error.
This change adds the switch case to allow template specialization to pass through emitTopLevelDecl without issuing an error.