aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaOverload.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-06-24 16:50:40 +0000
committerDouglas Gregor <dgregor@apple.com>2009-06-24 16:50:40 +0000
commit34d1dc9f0ca8f5b0528a8cd29f1addfe096361b8 (patch)
treed66a64a537b596dbf6aa9313f5690c0b882982c2 /lib/Sema/SemaOverload.cpp
parente6510f1945c80f9d5162f26e3ca4e4686c5ac8b1 (diff)
Implement matching of function templates, so that one can declare overloaded function templates. C++ [temp.over.link] paragraphs 4-8.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74079 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r--lib/Sema/SemaOverload.cpp29
1 files changed, 27 insertions, 2 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 11cd5107fc..6217e6d57a 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -301,6 +301,15 @@ Sema::IsOverload(FunctionDecl *New, Decl* OldD,
// 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 @@ Sema::IsOverload(FunctionDecl *New, Decl* OldD,
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 @@ Sema::IsOverload(FunctionDecl *New, Decl* OldD,
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.
//