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 "
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);
// 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\r
+ // create a type dependent CallExpr. The goal is to postpone name lookup\r
+ // to instantiation time to be able to search into type dependent base
+ // classes.\r
+ if (getLangOptions().Microsoft && CurContext->isDependentContext() && \r
+ isa<CXXMethodDecl>(CurContext)) {\r
+ CallExpr *CE = new (Context) CallExpr(Context, Fn, Args, NumArgs,\r
+ Context.DependentTy, VK_RValue,\r
+ RParenLoc);\r
+ CE->setTypeDependent(true);\r
+ return Owned(CE);\r
+ }\r
return BuildRecoveryCallExpr(*this, S, Fn, ULE, LParenLoc, Args, NumArgs,
RParenLoc, /*EmptyLookup=*/true);
+ }
OverloadCandidateSet::iterator Best;
switch (CandidateSet.BestViableFunction(*this, Fn->getLocStart(), Best)) {
--- /dev/null
+// 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);
+}
+
+