зеркало из https://github.com/microsoft/clang.git
In Microsoft mode, if we are inside a template class member function and we can't resolve a function call then create a type-dependent CallExpr even if the function has no type dependent arguments. The goal is to postpone name lookup to instantiation time to be able to search into type dependent base classes.
With this patch in, clang will generate only 37 errors (down from 212) when parsing a typical MFC source file. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139210 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
46e3908af1
Коммит
0f74d1e441
|
@ -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 "
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
Загрузка…
Ссылка в новой задаче