diff options
-rw-r--r-- | clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 15 | ||||
-rw-r--r-- | clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp | 31 |
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); +} + + |