diff options
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 15 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 2 | ||||
-rw-r--r-- | test/SemaTemplate/ms-lookup-template-base-classes.cpp | 27 |
3 files changed, 40 insertions, 4 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index ef9d787fe4..e6e6e5f5e1 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -1511,8 +1511,8 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, // unqualified lookup. This is useful when (for example) the // original lookup would not have found something because it was a // dependent name. - for (DeclContext *DC = SS.isEmpty() ? CurContext : 0; - DC; DC = DC->getParent()) { + DeclContext *DC = SS.isEmpty() ? CurContext : 0; + while (DC) { if (isa<CXXRecordDecl>(DC)) { LookupQualifiedName(R, DC); @@ -1591,6 +1591,17 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, R.clear(); } + + // In Microsoft mode, if we are performing lookup from within a friend + // function definition declared at class scope then we must set + // DC to the lexical parent to be able to search into the parent + // class. + if (getLangOptions().MicrosoftMode && DC->isFunctionOrMethod() && + cast<FunctionDecl>(DC)->getFriendObjectKind() && + DC->getLexicalParent()->isRecord()) + DC = DC->getLexicalParent(); + else + DC = DC->getParent(); } // We didn't find anything, so try to correct for a typo. diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 9b605c9319..b54f1a30ab 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -8825,7 +8825,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<CXXRecordDecl>(CurContext))) { + (isa<FunctionDecl>(CurContext) || isa<CXXRecordDecl>(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 cc5edf7997..901f104ec3 100644 --- a/test/SemaTemplate/ms-lookup-template-base-classes.cpp +++ b/test/SemaTemplate/ms-lookup-template-base-classes.cpp @@ -97,4 +97,29 @@ void foo() b.g2(); // expected-note {{required here}} } -}
\ No newline at end of file +} + + +namespace lookup_dependent_base_class_friend { + +template <class T> +class B { +public: + static void g(); // expected-note {{must qualify identifier to find this declaration in dependent base class}} +}; + +template <class T> +class A : public B<T> { +public: + friend void foo(A<T> p){ + g(); // expected-warning {{use of identifier 'g' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} + } +}; + +int main2() +{ + A<int> a; + foo(a); // expected-note {{requested here}} +} + +} |