r360302 - When typo-correcting a function name, consider correcting to a type name

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Wed May 8 17:57:25 PDT 2019


Author: rsmith
Date: Wed May  8 17:57:24 2019
New Revision: 360302

URL: http://llvm.org/viewvc/llvm-project?rev=360302&view=rev
Log:
When typo-correcting a function name, consider correcting to a type name
for a function-style cast.

Modified:
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaLookup.cpp
    cfe/trunk/test/CXX/class/class.mem/p1.cpp
    cfe/trunk/test/FixIt/fixit-unrecoverable.cpp
    cfe/trunk/test/SemaCXX/typo-correction.cpp

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=360302&r1=360301&r2=360302&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed May  8 17:57:24 2019
@@ -2068,8 +2068,8 @@ bool Sema::DiagnoseEmptyLookup(Scope *S,
       AcceptableWithoutRecovery =
           isa<TypeDecl>(UnderlyingND) || isa<ObjCInterfaceDecl>(UnderlyingND);
     } else {
-      // FIXME: We found a keyword. Suggest it, but don't provide a fix-it
-      // because we aren't able to recover.
+      // FIXME: We found a keyword or a type. Suggest it, but don't provide a
+      // fix-it because we aren't able to recover.
       AcceptableWithoutRecovery = true;
     }
 

Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=360302&r1=360301&r2=360302&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Wed May  8 17:57:24 2019
@@ -4996,7 +4996,9 @@ FunctionCallFilterCCC::FunctionCallFilte
     : NumArgs(NumArgs), HasExplicitTemplateArgs(HasExplicitTemplateArgs),
       CurContext(SemaRef.CurContext), MemberFn(ME) {
   WantTypeSpecifiers = false;
-  WantFunctionLikeCasts = SemaRef.getLangOpts().CPlusPlus && NumArgs == 1;
+  WantFunctionLikeCasts = SemaRef.getLangOpts().CPlusPlus &&
+                          !HasExplicitTemplateArgs && NumArgs == 1;
+  WantCXXNamedCasts = HasExplicitTemplateArgs && NumArgs == 1;
   WantRemainingKeywords = false;
 }
 
@@ -5025,6 +5027,13 @@ bool FunctionCallFilterCCC::ValidateCand
       }
     }
 
+    // A typo for a function-style cast can look like a function call in C++.
+    if ((HasExplicitTemplateArgs ? getAsTypeTemplateDecl(ND) != nullptr
+                                 : isa<TypeDecl>(ND)) &&
+        CurContext->getParentASTContext().getLangOpts().CPlusPlus)
+      // Only a class or class template can take two or more arguments.
+      return NumArgs <= 1 || HasExplicitTemplateArgs || isa<CXXRecordDecl>(ND);
+
     // Skip the current candidate if it is not a FunctionDecl or does not accept
     // the current number of arguments.
     if (!FD || !(FD->getNumParams() >= NumArgs &&

Modified: cfe/trunk/test/CXX/class/class.mem/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class/class.mem/p1.cpp?rev=360302&r1=360301&r2=360302&view=diff
==============================================================================
--- cfe/trunk/test/CXX/class/class.mem/p1.cpp (original)
+++ cfe/trunk/test/CXX/class/class.mem/p1.cpp Wed May  8 17:57:24 2019
@@ -9,14 +9,14 @@ struct S
   static int v; //expected-error{{redefinition of 'v' as different kind of symbol}}
   int v; //expected-error{{duplicate member 'v'}}
   static int v; //expected-error{{redefinition of 'v' as different kind of symbol}}
-  enum EnumT { E = 10 };
+  enum EnumT { E = 10 }; // expected-note {{declared here}}
   friend struct M;
   struct X;  //expected-note{{forward declaration of 'S::X'}}
   friend struct X;
 };
 
 S::EnumT Evar = S::E; // ok
-S::EnumT Evar2 = EnumT(); //expected-error{{use of undeclared identifier 'EnumT'}}
+S::EnumT Evar2 = EnumT(); //expected-error{{use of undeclared identifier 'EnumT'; did you mean 'S::EnumT'?}}
 S::M m; //expected-error{{no type named 'M' in 'S'}}
 S::X x; //expected-error{{variable has incomplete type 'S::X'}}
 

Modified: cfe/trunk/test/FixIt/fixit-unrecoverable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit-unrecoverable.cpp?rev=360302&r1=360301&r2=360302&view=diff
==============================================================================
--- cfe/trunk/test/FixIt/fixit-unrecoverable.cpp (original)
+++ cfe/trunk/test/FixIt/fixit-unrecoverable.cpp Wed May  8 17:57:24 2019
@@ -8,3 +8,10 @@
 float f(int y) {
   return static_cst<float>(y); // expected-error{{use of undeclared identifier 'static_cst'; did you mean 'static_cast'?}}
 }
+
+struct Foobar {}; // expected-note {{here}}
+template<typename T> struct Goobar {}; // expected-note {{here}}
+void use_foobar() {
+  auto x = zoobar(); // expected-error {{did you mean 'Foobar'}}
+  auto y = zoobar<int>(); // expected-error {{did you mean 'Goobar'}}
+}

Modified: cfe/trunk/test/SemaCXX/typo-correction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/typo-correction.cpp?rev=360302&r1=360301&r2=360302&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/typo-correction.cpp (original)
+++ cfe/trunk/test/SemaCXX/typo-correction.cpp Wed May  8 17:57:24 2019
@@ -344,20 +344,20 @@ void zif::nab(int) {
 
 namespace TemplateFunction {
 template <class T>
-void A(T) { }  // expected-note {{'::TemplateFunction::A' declared here}}
+void fnA(T) { }  // expected-note {{'::TemplateFunction::fnA' declared here}}
 
 template <class T>
-void B(T) { }  // expected-note {{'::TemplateFunction::B' declared here}}
+void fnB(T) { }  // expected-note {{'::TemplateFunction::fnB' declared here}}
 
 class Foo {
  public:
-  void A(int, int) {}
-  void B() {}
+  void fnA(int, int) {}
+  void fnB() {}
 };
 
 void test(Foo F, int num) {
-  F.A(num);  // expected-error {{too few arguments to function call, expected 2, have 1; did you mean '::TemplateFunction::A'?}}
-  F.B(num);  // expected-error {{too many arguments to function call, expected 0, have 1; did you mean '::TemplateFunction::B'?}}
+  F.fnA(num);  // expected-error {{too few arguments to function call, expected 2, have 1; did you mean '::TemplateFunction::fnA'?}}
+  F.fnB(num);  // expected-error {{too many arguments to function call, expected 0, have 1; did you mean '::TemplateFunction::fnB'?}}
 }
 }
 namespace using_suggestion_val_dropped_specifier {
@@ -537,9 +537,9 @@ namespace no_correct_template_id_to_non_
 namespace PR18852 {
 void func() {
   struct foo {
-    void bar() {}
+    void barberry() {}
   };
-  bar();  // expected-error-re {{use of undeclared identifier 'bar'{{$}}}}
+  barberry();  // expected-error-re {{use of undeclared identifier 'barberry'{{$}}}}
 }
 
 class Thread {




More information about the cfe-commits mailing list