aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Sema/SemaExpr.cpp15
-rw-r--r--lib/Sema/SemaOverload.cpp2
-rw-r--r--test/SemaTemplate/ms-lookup-template-base-classes.cpp27
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}}
+}
+
+}