r184689 - Slightly improve cross-module merging for function templates.

Richard Smith richard-llvm at metafoo.co.uk
Sun Jun 23 21:45:28 PDT 2013


Author: rsmith
Date: Sun Jun 23 23:45:28 2013
New Revision: 184689

URL: http://llvm.org/viewvc/llvm-project?rev=184689&view=rev
Log:
Slightly improve cross-module merging for function templates.

Added:
    cfe/trunk/test/Modules/Inputs/cxx-templates-a.h
    cfe/trunk/test/Modules/Inputs/cxx-templates-b.h
    cfe/trunk/test/Modules/cxx-templates.cpp
Modified:
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/test/Modules/Inputs/module.map

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=184689&r1=184688&r2=184689&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Sun Jun 23 23:45:28 2013
@@ -1815,10 +1815,10 @@ static bool isSameEntity(NamedDecl *X, N
        (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, N
     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;

Added: cfe/trunk/test/Modules/Inputs/cxx-templates-a.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/cxx-templates-a.h?rev=184689&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/cxx-templates-a.h (added)
+++ cfe/trunk/test/Modules/Inputs/cxx-templates-a.h Sun Jun 23 23:45:28 2013
@@ -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);
+}

Added: cfe/trunk/test/Modules/Inputs/cxx-templates-b.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/cxx-templates-b.h?rev=184689&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/cxx-templates-b.h (added)
+++ cfe/trunk/test/Modules/Inputs/cxx-templates-b.h Sun Jun 23 23:45:28 2013
@@ -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; }
+}

Modified: cfe/trunk/test/Modules/Inputs/module.map
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/module.map?rev=184689&r1=184688&r2=184689&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/module.map (original)
+++ cfe/trunk/test/Modules/Inputs/module.map Sun Jun 23 23:45:28 2013
@@ -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

Added: cfe/trunk/test/Modules/cxx-templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/cxx-templates.cpp?rev=184689&view=auto
==============================================================================
--- cfe/trunk/test/Modules/cxx-templates.cpp (added)
+++ cfe/trunk/test/Modules/cxx-templates.cpp Sun Jun 23 23:45:28 2013
@@ -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
+
+ at import cxx_templates_a;
+ at import cxx_templates_b;
+
+void g() {
+  f(0);
+  f<double>(1.0);
+  f<int>();
+  f(); // expected-error {{no matching function}}
+  // expected-note at Inputs/cxx-templates-b.h:1 {{couldn't infer template argument}}
+  // expected-note at 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 at Inputs/cxx-templates-a.h:4 {{couldn't infer template argument}}
+  // expected-note at 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'





More information about the cfe-commits mailing list