From: Francois Pichet Date: Thu, 17 Nov 2011 03:44:24 +0000 (+0000) Subject: In Microsoft mode, make "Unqualified lookup into dependent bases of class templates... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e6226ae490903717c8c07782f28bc8349543021f;p=clang 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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@144881 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 362aea9a74..ba9dbedd8d 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -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(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::' 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; } diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index adf4dcae1b..24381a30d7 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -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(CurContext)) { + (isa(CurContext) || isa(CurContext))) { CallExpr *CE = new (Context) CallExpr(Context, Fn, Args, NumArgs, Context.DependentTy, VK_RValue, RParenLoc); diff --git a/test/SemaTemplate/ms-lookup-template-base-classes.cpp b/test/SemaTemplate/ms-lookup-template-base-classes.cpp index 149ec4f8e9..cc5edf7997 100644 --- a/test/SemaTemplate/ms-lookup-template-base-classes.cpp +++ b/test/SemaTemplate/ms-lookup-template-base-classes.cpp @@ -65,9 +65,36 @@ class B : public A { 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; // expected-note {{requested here}} } + + + +namespace lookup_dependent_base_class_default_argument { + +template +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 B : public A { +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 b; + b.g1(); // expected-note {{required here}} + b.g2(); // expected-note {{required here}} +} + +} \ No newline at end of file