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;
}
: 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;
}
}
}
+ // 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 &&
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'}}
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'}}
+}
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 {
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 {