[cfe-commits] r74079 - in /cfe/trunk: lib/Sema/SemaOverload.cpp lib/Sema/SemaTemplate.cpp test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4-neg.cpp test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4.cpp
Douglas Gregor
dgregor at apple.com
Wed Jun 24 09:50:45 PDT 2009
Author: dgregor
Date: Wed Jun 24 11:50:40 2009
New Revision: 74079
URL: http://llvm.org/viewvc/llvm-project?rev=74079&view=rev
Log:
Implement matching of function templates, so that one can declare overloaded function templates. C++ [temp.over.link] paragraphs 4-8.
Added:
cfe/trunk/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4-neg.cpp
cfe/trunk/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4.cpp
Modified:
cfe/trunk/lib/Sema/SemaOverload.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=74079&r1=74078&r2=74079&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Wed Jun 24 11:50:40 2009
@@ -301,6 +301,15 @@
// This function overloads every function in the overload set.
return true;
} else if (FunctionDecl* Old = dyn_cast<FunctionDecl>(OldD)) {
+ FunctionTemplateDecl *OldTemplate = Old->getDescribedFunctionTemplate();
+ FunctionTemplateDecl *NewTemplate = New->getDescribedFunctionTemplate();
+
+ // C++ [temp.fct]p2:
+ // A function template can be overloaded with other function templates
+ // and with normal (non-template) functions.
+ if ((OldTemplate == 0) != (NewTemplate == 0))
+ return true;
+
// Is the function New an overload of the function Old?
QualType OldQType = Context.getCanonicalType(Old->getType());
QualType NewQType = Context.getCanonicalType(New->getType());
@@ -315,8 +324,8 @@
isa<FunctionNoProtoType>(NewQType.getTypePtr()))
return false;
- FunctionProtoType* OldType = cast<FunctionProtoType>(OldQType.getTypePtr());
- FunctionProtoType* NewType = cast<FunctionProtoType>(NewQType.getTypePtr());
+ FunctionProtoType* OldType = cast<FunctionProtoType>(OldQType);
+ FunctionProtoType* NewType = cast<FunctionProtoType>(NewQType);
// The signature of a function includes the types of its
// parameters (C++ 1.3.10), which includes the presence or absence
@@ -328,6 +337,22 @@
NewType->arg_type_begin())))
return true;
+ // C++ [temp.over.link]p4:
+ // The signature of a function template consists of its function
+ // signature, its return type and its template parameter list. The names
+ // of the template parameters are significant only for establishing the
+ // relationship between the template parameters and the rest of the
+ // signature.
+ //
+ // We check the return type and template parameter lists for function
+ // templates first; the remaining checks follow.
+ if (NewTemplate &&
+ (!TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(),
+ OldTemplate->getTemplateParameters(),
+ false, false, SourceLocation()) ||
+ OldType->getResultType() != NewType->getResultType()))
+ return true;
+
// If the function is a class member, its signature includes the
// cv-qualifiers (if any) on the function itself.
//
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=74079&r1=74078&r2=74079&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Jun 24 11:50:40 2009
@@ -1874,15 +1874,17 @@
OldParmEnd = Old->end(), NewParm = New->begin();
OldParm != OldParmEnd; ++OldParm, ++NewParm) {
if ((*OldParm)->getKind() != (*NewParm)->getKind()) {
- unsigned NextDiag = diag::err_template_param_different_kind;
- if (TemplateArgLoc.isValid()) {
- Diag(TemplateArgLoc, diag::err_template_arg_template_params_mismatch);
- NextDiag = diag::note_template_param_different_kind;
- }
- Diag((*NewParm)->getLocation(), NextDiag)
+ if (Complain) {
+ unsigned NextDiag = diag::err_template_param_different_kind;
+ if (TemplateArgLoc.isValid()) {
+ Diag(TemplateArgLoc, diag::err_template_arg_template_params_mismatch);
+ NextDiag = diag::note_template_param_different_kind;
+ }
+ Diag((*NewParm)->getLocation(), NextDiag)
<< IsTemplateTemplateParm;
- Diag((*OldParm)->getLocation(), diag::note_template_prev_declaration)
+ Diag((*OldParm)->getLocation(), diag::note_template_prev_declaration)
<< IsTemplateTemplateParm;
+ }
return false;
}
Added: cfe/trunk/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4-neg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4-neg.cpp?rev=74079&view=auto
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4-neg.cpp (added)
+++ cfe/trunk/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4-neg.cpp Wed Jun 24 11:50:40 2009
@@ -0,0 +1,27 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+template<typename T> void f0(T) { } // expected-note{{previous}}
+template<class U> void f0(U) { } // expected-error{{redefinition}}
+
+template<int I> void f0() { } // expected-note{{previous}}
+template<int> void f0() { } // expected-error{{redefinition}}
+
+typedef int INT;
+
+template<template<class T, T Value1, INT> class X>
+ void f0() { } // expected-note{{previous}}
+template<template<typename T, T Value1, int> class>
+ void f0() { } // expected-error{{redefinition}}
+
+template<typename T>
+struct MetaFun;
+
+template<typename T>
+ typename MetaFun<T*>::type f0(const T&) { } // expected-note{{previous}}
+template<class U>
+ typename MetaFun<U*>::type f0(const U&) { } // expected-error{{redefinition}}
+
+// FIXME: We need canonicalization of expressions for this to work
+// template<int> struct A { };
+// template<int I> void f0(A<I>) { } // Xpected-note{{previous}}
+// template<int J> void f0(A<J>) { } // Xpected-error{{redefinition}}
\ No newline at end of file
Added: cfe/trunk/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4.cpp?rev=74079&view=auto
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4.cpp (added)
+++ cfe/trunk/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4.cpp Wed Jun 24 11:50:40 2009
@@ -0,0 +1,13 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+// All of these function templates are distinct.
+template<typename T> void f0(T) { }
+template<typename T, typename U> void f0(T) { }
+template<typename T, typename U> void f0(U) { }
+void f0();
+template<typename T> void f0(T*);
+void f0(int);
+template<int I> void f0();
+template<typename T> void f0();
+
+
More information about the cfe-commits
mailing list