]> granicus.if.org Git - clang/commitdiff
Have the typo correction in DiagnoseEmptyLookup properly handle template
authorKaelyn Uhrain <rikka@google.com>
Fri, 5 Aug 2011 00:09:52 +0000 (00:09 +0000)
committerKaelyn Uhrain <rikka@google.com>
Fri, 5 Aug 2011 00:09:52 +0000 (00:09 +0000)
functions when performing function overload resolution.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@136948 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/Sema.h
lib/Sema/SemaExpr.cpp
lib/Sema/SemaOverload.cpp
test/SemaCXX/function-overload-typo-crash.cpp

index cccff294e5415f7f5d4b7cb6acd5e6fb8bdea6e4..c08df35dbb7f59d5def10bab01c798cbefcbfd7d 100644 (file)
@@ -2265,6 +2265,7 @@ public:
 
   bool DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
                            CorrectTypoContext CTC = CTC_Unknown,
+                           TemplateArgumentListInfo *ExplicitTemplateArgs = 0,
                            Expr **Args = 0, unsigned NumArgs = 0);
 
   ExprResult LookupInObjCMethod(LookupResult &R, Scope *S, IdentifierInfo *II,
index ffa092aad1eadc8b111af31d31d8139942a5fb5e..bc7d0bdfe50bf457de89222fdfdd16fea4fc4365 100644 (file)
@@ -1364,8 +1364,9 @@ Sema::DecomposeUnqualifiedId(const UnqualifiedId &Id,
 ///
 /// \return false if new lookup candidates were found
 bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
-                               CorrectTypoContext CTC, Expr **Args,
-                               unsigned NumArgs) {
+                               CorrectTypoContext CTC,
+                               TemplateArgumentListInfo *ExplicitTemplateArgs,
+                               Expr **Args, unsigned NumArgs) {
   DeclarationName Name = R.getLookupName();
 
   unsigned diagnostic = diag::err_undeclared_var_use;
@@ -1458,10 +1459,13 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
                                         CDEnd = Corrected.end();
              CD != CDEnd; ++CD) {
           if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*CD))
-            AddOverloadCandidate(FD, DeclAccessPair::make(*CD, AS_none),
+            AddOverloadCandidate(FD, DeclAccessPair::make(FD, AS_none),
                                  Args, NumArgs, OCS);
-          // TODO: Handle FunctionTemplateDecl and other Decl types that
-          // support overloading and could be corrected by CorrectTypo.
+          else if (FunctionTemplateDecl *FTD =
+                   dyn_cast<FunctionTemplateDecl>(*CD))
+            AddTemplateOverloadCandidate(
+                FTD, DeclAccessPair::make(FTD, AS_none), ExplicitTemplateArgs,
+                Args, NumArgs, OCS);
         }
         switch (OCS.BestViableFunction(*this, R.getNameLoc(), Best)) {
           case OR_Success:
index 712720bf9e85c7b99bcbe567be6f68de3e8eb24a..72a43d89e8ce5ba703cede48587d6dd0b2af0b14 100644 (file)
@@ -8221,7 +8221,7 @@ BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn,
                               ExplicitTemplateArgs, Args, NumArgs) &&
       (!EmptyLookup ||
        SemaRef.DiagnoseEmptyLookup(S, SS, R, Sema::CTC_Expression,
-                                   Args, NumArgs)))
+                                   ExplicitTemplateArgs, Args, NumArgs)))
     return ExprError();
 
   assert(!R.empty() && "lookup results empty despite recovery");
index a0f70dfbdb9c10a04d543e83acbdde8a0ca604c1..8c5cec8af3a967673f649774e7bd0073e618b466 100644 (file)
@@ -11,20 +11,17 @@ void f() {
   fax(0); //expected-error {{use of undeclared identifier 'fax'; did you mean 'max'}}
 }
 
-// TODO: Add proper function overloading resolution for template functions
-template <typename T> void somefunc(T*, T*);
-template <typename T> void somefunc(const T[]);
-template <typename T1, typename T2> void somefunc(T1*, T2*);
-template <typename T1, typename T2> void somefunc(T1*, const T2[]); //expected-note 5 {{'somefunc' declared here}} \
-                                                                    //expected-note {{candidate function template not viable: requires 2 arguments, but 1 was provided}} TODO this shouldn't happen
+template <typename T> void somefunc(T*, T*); //expected-note {{'somefunc' declared here}}
+template <typename T> void somefunc(const T[]); //expected-note {{'somefunc' declared here}}
+template <typename T1, typename T2> void somefunc(T1*, T2*); //expected-note {{'somefunc' declared here}}
+template <typename T1, typename T2> void somefunc(T1*, const T2[]); //expected-note 2 {{'somefunc' declared here}}
 
 void c() {
   int *i = 0, *j = 0;
   const int x[] = {1, 2, 3};
   long *l = 0;
   somefun(i, j); //expected-error {{use of undeclared identifier 'somefun'; did you mean 'somefunc'?}}
-  somefun(x); //expected-error {{use of undeclared identifier 'somefun'; did you mean 'somefunc'?}} \
-              //expected-error {{no matching function for call to 'somefunc'}} TODO this shouldn't happen
+  somefun(x); //expected-error {{use of undeclared identifier 'somefun'; did you mean 'somefunc'?}}
   somefun(i, l); //expected-error {{use of undeclared identifier 'somefun'; did you mean 'somefunc'?}}
   somefun(l, x); //expected-error {{use of undeclared identifier 'somefun'; did you mean 'somefunc'?}}
   somefun(i, x); //expected-error {{use of undeclared identifier 'somefun'; did you mean 'somefunc'?}}