diff options
| -rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 19 | ||||
| -rw-r--r-- | clang/test/Modules/Inputs/cxx-templates-a.h | 6 | ||||
| -rw-r--r-- | clang/test/Modules/Inputs/cxx-templates-b.h | 6 | ||||
| -rw-r--r-- | clang/test/Modules/Inputs/module.map | 8 | ||||
| -rw-r--r-- | clang/test/Modules/cxx-templates.cpp | 41 |
5 files changed, 73 insertions, 7 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index ffbff3882b2..3d64fa51d9e 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -1815,10 +1815,10 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { (TagY->getTagKind() == TTK_Struct || TagY->getTagKind() == TTK_Class || TagY->getTagKind() == TTK_Interface)); } - + // Functions with the same type and linkage match. - // FIXME: This needs to cope with function templates, merging of - //prototyped/non-prototyped functions, etc. + // FIXME: This needs to cope with function template specializations, + // merging of prototyped/non-prototyped functions, etc. if (FunctionDecl *FuncX = dyn_cast<FunctionDecl>(X)) { FunctionDecl *FuncY = cast<FunctionDecl>(Y); return (FuncX->getLinkageInternal() == FuncY->getLinkageInternal()) && @@ -1831,16 +1831,21 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) { return (VarX->getLinkageInternal() == VarY->getLinkageInternal()) && VarX->getASTContext().hasSameType(VarX->getType(), VarY->getType()); } - + // Namespaces with the same name and inlinedness match. if (NamespaceDecl *NamespaceX = dyn_cast<NamespaceDecl>(X)) { NamespaceDecl *NamespaceY = cast<NamespaceDecl>(Y); return NamespaceX->isInline() == NamespaceY->isInline(); } - // Identical template names and kinds match. - if (isa<TemplateDecl>(X)) - return true; + // Identical template names and kinds match if their template parameter lists + // and patterns match. + if (TemplateDecl *TemplateX = dyn_cast<TemplateDecl>(X)) { + TemplateDecl *TemplateY = dyn_cast<TemplateDecl>(Y); + // FIXME: Check template parameter lists. + return isSameEntity(TemplateX->getTemplatedDecl(), + TemplateY->getTemplatedDecl()); + } // FIXME: Many other cases to implement. return false; diff --git a/clang/test/Modules/Inputs/cxx-templates-a.h b/clang/test/Modules/Inputs/cxx-templates-a.h new file mode 100644 index 00000000000..52bc3a2e3ad --- /dev/null +++ b/clang/test/Modules/Inputs/cxx-templates-a.h @@ -0,0 +1,6 @@ +template<typename T> T f() { return T(); } +template<typename T> T f(T); +namespace N { + template<typename T> T f() { return T(); } + template<typename T> T f(T); +} diff --git a/clang/test/Modules/Inputs/cxx-templates-b.h b/clang/test/Modules/Inputs/cxx-templates-b.h new file mode 100644 index 00000000000..3cc940c2c40 --- /dev/null +++ b/clang/test/Modules/Inputs/cxx-templates-b.h @@ -0,0 +1,6 @@ +template<typename T> T f(); +template<typename T> T f(T t) { return t; } +namespace N { + template<typename T> T f(); + template<typename T> T f(T t) { return t; } +} diff --git a/clang/test/Modules/Inputs/module.map b/clang/test/Modules/Inputs/module.map index 65c75fdc1c6..d2ed75830b8 100644 --- a/clang/test/Modules/Inputs/module.map +++ b/clang/test/Modules/Inputs/module.map @@ -188,6 +188,14 @@ module cxx_linkage_cache { header "cxx-linkage-cache.h" } +module cxx_templates_a { + header "cxx-templates-a.h" +} + +module cxx_templates_b { + header "cxx-templates-b.h" +} + module config { header "config.h" config_macros [exhaustive] WANT_FOO, WANT_BAR diff --git a/clang/test/Modules/cxx-templates.cpp b/clang/test/Modules/cxx-templates.cpp new file mode 100644 index 00000000000..bc96772083a --- /dev/null +++ b/clang/test/Modules/cxx-templates.cpp @@ -0,0 +1,41 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -std=c++11 -ast-dump -ast-dump-lookups | FileCheck %s --check-prefix=CHECK-GLOBAL +// RUN: %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -std=c++11 -ast-dump -ast-dump-lookups -ast-dump-filter N | FileCheck %s --check-prefix=CHECK-NAMESPACE-N +// RUN: %clang_cc1 -x objective-c++ -fmodules -fmodules-cache-path=%t -I %S/Inputs %s -verify -std=c++11 + +@import cxx_templates_a; +@import cxx_templates_b; + +void g() { + f(0); + f<double>(1.0); + f<int>(); + f(); // expected-error {{no matching function}} + // expected-note@Inputs/cxx-templates-b.h:1 {{couldn't infer template argument}} + // expected-note@Inputs/cxx-templates-b.h:2 {{requires single argument}} + + N::f(0); + N::f<double>(1.0); + N::f<int>(); + N::f(); // expected-error {{no matching function}} + // expected-note@Inputs/cxx-templates-a.h:4 {{couldn't infer template argument}} + // expected-note@Inputs/cxx-templates-a.h:5 {{requires 1 argument, but 0 were provided}} +} + +// FIXME: There should only be two 'f's here. +// CHECK-GLOBAL: DeclarationName 'f' +// CHECK-GLOBAL-NEXT: |-FunctionTemplate {{.*}} 'f' +// CHECK-GLOBAL-NEXT: |-FunctionTemplate {{.*}} 'f' +// CHECK-GLOBAL-NEXT: |-FunctionTemplate {{.*}} 'f' +// CHECK-GLOBAL-NEXT: |-FunctionTemplate {{.*}} 'f' +// CHECK-GLOBAL-NEXT: |-FunctionTemplate {{.*}} 'f' +// CHECK-GLOBAL-NEXT: |-FunctionTemplate {{.*}} 'f' +// CHECK-GLOBAL-NEXT: |-FunctionTemplate {{.*}} 'f' +// CHECK-GLOBAL-NEXT: `-FunctionTemplate {{.*}} 'f' + +// FIXME: There should only be two 'f's here. +// CHECK-NAMESPACE-N: DeclarationName 'f' +// CHECK-NAMESPACE-N-NEXT: |-FunctionTemplate {{.*}} 'f' +// CHECK-NAMESPACE-N-NEXT: |-FunctionTemplate {{.*}} 'f' +// CHECK-NAMESPACE-N-NEXT: |-FunctionTemplate {{.*}} 'f' +// CHECK-NAMESPACE-N-NEXT: `-FunctionTemplate {{.*}} 'f' |

