Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clang/include/clang/CIR/MissingFeatures.h
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down
7 changes: 6 additions & 1 deletion clang/lib/CIR/CodeGen/CIRGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
}
}

Expand Down
88 changes: 88 additions & 0 deletions clang/test/CIR/CodeGen/template-specialization.cpp
Original file line number Diff line number Diff line change
@@ -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> {
Copy link
Collaborator

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;

public:
int f() { return 1; }
};

// TODO: This will get dropped when we are deferring functions
// The speecialization is instantiated first
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// The speecialization is instantiated first
// The specialization 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
Loading