mirror of
https://github.com/intel/llvm.git
synced 2026-01-20 10:58:11 +08:00
In Microsoft mode, make "Unqualified lookup into dependent bases of class templates" works inside default argument instantiation.
This is a little bit tricky because during default argument instantiation the CurContext points to a CXXMethodDecl but we can't use the keyword this or have an implicit member call generated. This fixes 2 errors when parsing MFC code with clang. llvm-svn: 144881
This commit is contained in:
@@ -1520,10 +1520,17 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
|
||||
// Don't give errors about ambiguities in this lookup.
|
||||
R.suppressDiagnostics();
|
||||
|
||||
// During a default argument instantiation the CurContext points
|
||||
// to a CXXMethodDecl; but we can't apply a this-> fixit inside a
|
||||
// function parameter list, hence add an explicit check.
|
||||
bool isDefaultArgument = !ActiveTemplateInstantiations.empty() &&
|
||||
ActiveTemplateInstantiations.back().Kind ==
|
||||
ActiveTemplateInstantiation::DefaultFunctionArgumentInstantiation;
|
||||
CXXMethodDecl *CurMethod = dyn_cast<CXXMethodDecl>(CurContext);
|
||||
bool isInstance = CurMethod &&
|
||||
CurMethod->isInstance() &&
|
||||
DC == CurMethod->getParent();
|
||||
DC == CurMethod->getParent() && !isDefaultArgument;
|
||||
|
||||
|
||||
// Give a code modification hint to insert 'this->'.
|
||||
// TODO: fixit for inserting 'Base<T>::' in the other cases.
|
||||
@@ -1569,6 +1576,15 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
|
||||
for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I)
|
||||
Diag((*I)->getLocation(), diag::note_dependent_var_use);
|
||||
|
||||
// Return true if we are inside a default argument instantiation
|
||||
// and the found name refers to an instance member function, otherwise
|
||||
// the function calling DiagnoseEmptyLookup will try to create an
|
||||
// implicit member call and this is wrong for default argument.
|
||||
if (isDefaultArgument && ((*R.begin())->isCXXInstanceMember())) {
|
||||
Diag(R.getNameLoc(), diag::err_member_call_without_object);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Tell the callee to try to recover.
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -8712,7 +8712,7 @@ Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE,
|
||||
// to instantiation time to be able to search into type dependent base
|
||||
// classes.
|
||||
if (getLangOptions().MicrosoftMode && CurContext->isDependentContext() &&
|
||||
isa<CXXMethodDecl>(CurContext)) {
|
||||
(isa<CXXMethodDecl>(CurContext) || isa<CXXRecordDecl>(CurContext))) {
|
||||
CallExpr *CE = new (Context) CallExpr(Context, Fn, Args, NumArgs,
|
||||
Context.DependentTy, VK_RValue,
|
||||
RParenLoc);
|
||||
|
||||
@@ -65,9 +65,36 @@ class B : public A<T> {
|
||||
public:
|
||||
static void z2(){
|
||||
static_func(); // expected-warning {{use of identifier 'static_func' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
|
||||
func(); // expected-warning {{use of identifier 'func' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} expected-error {{call to non-static member function without an object argument}}
|
||||
func(); // expected-warning {{use of identifier 'func' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} expected-error {{call to non-static member function without an object argument}}
|
||||
}
|
||||
};
|
||||
template class B<int>; // expected-note {{requested here}}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
namespace lookup_dependent_base_class_default_argument {
|
||||
|
||||
template<class T>
|
||||
class A {
|
||||
public:
|
||||
static int f1(); // expected-note {{must qualify identifier to find this declaration in dependent base class}}
|
||||
int f2(); // expected-note {{must qualify identifier to find this declaration in dependent base class}}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class B : public A<T> {
|
||||
public:
|
||||
void g1(int p = f1());// expected-warning {{use of identifier 'f1' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
|
||||
void g2(int p = f2());// expected-warning {{use of identifier 'f2' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} expected-error {{call to non-static member function without an object argument}}
|
||||
};
|
||||
|
||||
void foo()
|
||||
{
|
||||
B<int> b;
|
||||
b.g1(); // expected-note {{required here}}
|
||||
b.g2(); // expected-note {{required here}}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user