summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td3
-rw-r--r--clang/lib/Sema/SemaExpr.cpp2
-rw-r--r--clang/lib/Sema/SemaOverload.cpp15
-rw-r--r--clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp31
4 files changed, 50 insertions, 1 deletions
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 4143fef781d..e39a2c72f38 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2392,6 +2392,9 @@ def err_unexpected_typedef : Error<
def err_unexpected_namespace : Error<
"unexpected namespace name %0: expected expression">;
def err_undeclared_var_use : Error<"use of undeclared identifier %0">;
+def warn_found_via_dependent_bases_lookup : ExtWarn<"use of identifier %0 "
+ "found via unqualified lookup into dependent bases of class templates is a "
+ "Microsoft extension">, InGroup<Microsoft>;
def note_dependent_var_use : Note<"must qualify identifier to find this "
"declaration in dependent base class">;
def err_not_found_by_two_phase_lookup : Error<"call to function %0 that is neither "
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 076602fa7b5..cbcbef91f72 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -1456,6 +1456,8 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
CXXMethodDecl *DepMethod = cast_or_null<CXXMethodDecl>(
CurMethod->getInstantiatedFromMemberFunction());
if (DepMethod) {
+ if (getLangOptions().Microsoft)
+ diagnostic = diag::warn_found_via_dependent_bases_lookup;
Diag(R.getNameLoc(), diagnostic) << Name
<< FixItHint::CreateInsertion(R.getNameLoc(), "this->");
QualType DepThisType = DepMethod->getThisType(Context);
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 6f3b1aa7bf5..4f36189ce56 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -8289,9 +8289,22 @@ Sema::BuildOverloadedCallExpr(Scope *S, Expr *Fn, UnresolvedLookupExpr *ULE,
// If we found nothing, try to recover.
// BuildRecoveryCallExpr diagnoses the error itself, so we just bail
// out if it fails.
- if (CandidateSet.empty())
+ if (CandidateSet.empty()) {
+ // In Microsoft mode, if we are inside a template class member function then
+ // create a type dependent CallExpr. The goal is to postpone name lookup
+ // to instantiation time to be able to search into type dependent base
+ // classes.
+ if (getLangOptions().Microsoft && CurContext->isDependentContext() &&
+ isa<CXXMethodDecl>(CurContext)) {
+ CallExpr *CE = new (Context) CallExpr(Context, Fn, Args, NumArgs,
+ Context.DependentTy, VK_RValue,
+ RParenLoc);
+ CE->setTypeDependent(true);
+ return Owned(CE);
+ }
return BuildRecoveryCallExpr(*this, S, Fn, ULE, LParenLoc, Args, NumArgs,
RParenLoc, /*EmptyLookup=*/true);
+ }
OverloadCandidateSet::iterator Best;
switch (CandidateSet.BestViableFunction(*this, Fn->getLocStart(), Best)) {
diff --git a/clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp b/clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp
new file mode 100644
index 00000000000..910fa37e80d
--- /dev/null
+++ b/clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify %s
+
+
+template <class T>
+class A {
+public:
+ void f(T a) { }// expected-note {{must qualify identifier to find this declaration in dependent base class}}
+ void g();// expected-note {{must qualify identifier to find this declaration in dependent base class}}
+};
+
+
+template <class T>
+class B : public A<T> {
+public:
+ void z(T a)
+ {
+ f(a); // expected-warning {{use of identifier 'f' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
+ g(); // expected-warning {{use of identifier 'g' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
+ }
+};
+
+template class B<int>; // expected-note {{requested here}}
+template class B<char>;
+
+void test()
+{
+ B<int> b;
+ b.z(3);
+}
+
+
OpenPOWER on IntegriCloud