зеркало из https://github.com/microsoft/clang.git
Improve argument-dependent lookup to find associated classes and
namespaces based on the template arguments of a class template specialization type. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74993 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
bbb3128b44
Коммит
69be8d60de
|
@ -1241,6 +1241,74 @@ bool Sema::DiagnoseAmbiguousLookup(LookupResult &Result, DeclarationName Name,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
addAssociatedClassesAndNamespaces(QualType T,
|
||||||
|
ASTContext &Context,
|
||||||
|
Sema::AssociatedNamespaceSet &AssociatedNamespaces,
|
||||||
|
Sema::AssociatedClassSet &AssociatedClasses,
|
||||||
|
bool &GlobalScope);
|
||||||
|
|
||||||
|
// \brief Add the associated classes and namespaces for argument-dependent
|
||||||
|
// lookup that involves a template argument (C++ [basic.lookup.koenig]p2).
|
||||||
|
static void
|
||||||
|
addAssociatedClassesAndNamespaces(const TemplateArgument &Arg,
|
||||||
|
ASTContext &Context,
|
||||||
|
Sema::AssociatedNamespaceSet &AssociatedNamespaces,
|
||||||
|
Sema::AssociatedClassSet &AssociatedClasses,
|
||||||
|
bool &GlobalScope) {
|
||||||
|
// C++ [basic.lookup.koenig]p2, last bullet:
|
||||||
|
// -- [...] ;
|
||||||
|
switch (Arg.getKind()) {
|
||||||
|
case TemplateArgument::Null:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TemplateArgument::Type:
|
||||||
|
// [...] the namespaces and classes associated with the types of the
|
||||||
|
// template arguments provided for template type parameters (excluding
|
||||||
|
// template template parameters)
|
||||||
|
addAssociatedClassesAndNamespaces(Arg.getAsType(), Context,
|
||||||
|
AssociatedNamespaces,
|
||||||
|
AssociatedClasses,
|
||||||
|
GlobalScope);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TemplateArgument::Declaration:
|
||||||
|
// [...] the namespaces in which any template template arguments are
|
||||||
|
// defined; and the classes in which any member templates used as
|
||||||
|
// template template arguments are defined.
|
||||||
|
if (ClassTemplateDecl *ClassTemplate
|
||||||
|
= dyn_cast<ClassTemplateDecl>(Arg.getAsDecl())) {
|
||||||
|
DeclContext *Ctx = ClassTemplate->getDeclContext();
|
||||||
|
if (CXXRecordDecl *EnclosingClass = dyn_cast<CXXRecordDecl>(Ctx))
|
||||||
|
AssociatedClasses.insert(EnclosingClass);
|
||||||
|
// Add the associated namespace for this class.
|
||||||
|
while (Ctx->isRecord())
|
||||||
|
Ctx = Ctx->getParent();
|
||||||
|
if (NamespaceDecl *EnclosingNamespace = dyn_cast<NamespaceDecl>(Ctx))
|
||||||
|
AssociatedNamespaces.insert(EnclosingNamespace);
|
||||||
|
else if (Ctx->isTranslationUnit())
|
||||||
|
GlobalScope = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TemplateArgument::Integral:
|
||||||
|
case TemplateArgument::Expression:
|
||||||
|
// [Note: non-type template arguments do not contribute to the set of
|
||||||
|
// associated namespaces. ]
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TemplateArgument::Pack:
|
||||||
|
for (TemplateArgument::pack_iterator P = Arg.pack_begin(),
|
||||||
|
PEnd = Arg.pack_end();
|
||||||
|
P != PEnd; ++P)
|
||||||
|
addAssociatedClassesAndNamespaces(*P, Context,
|
||||||
|
AssociatedNamespaces,
|
||||||
|
AssociatedClasses,
|
||||||
|
GlobalScope);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// \brief Add the associated classes and namespaces for
|
// \brief Add the associated classes and namespaces for
|
||||||
// argument-dependent lookup with an argument of class type
|
// argument-dependent lookup with an argument of class type
|
||||||
// (C++ [basic.lookup.koenig]p2).
|
// (C++ [basic.lookup.koenig]p2).
|
||||||
|
@ -1275,8 +1343,36 @@ addAssociatedClassesAndNamespaces(CXXRecordDecl *Class,
|
||||||
if (!AssociatedClasses.insert(Class))
|
if (!AssociatedClasses.insert(Class))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// FIXME: Handle class template specializations
|
// -- If T is a template-id, its associated namespaces and classes are
|
||||||
|
// the namespace in which the template is defined; for member
|
||||||
|
// templates, the member template’s class; the namespaces and classes
|
||||||
|
// associated with the types of the template arguments provided for
|
||||||
|
// template type parameters (excluding template template parameters); the
|
||||||
|
// namespaces in which any template template arguments are defined; and
|
||||||
|
// the classes in which any member templates used as template template
|
||||||
|
// arguments are defined. [Note: non-type template arguments do not
|
||||||
|
// contribute to the set of associated namespaces. ]
|
||||||
|
if (ClassTemplateSpecializationDecl *Spec
|
||||||
|
= dyn_cast<ClassTemplateSpecializationDecl>(Class)) {
|
||||||
|
DeclContext *Ctx = Spec->getSpecializedTemplate()->getDeclContext();
|
||||||
|
if (CXXRecordDecl *EnclosingClass = dyn_cast<CXXRecordDecl>(Ctx))
|
||||||
|
AssociatedClasses.insert(EnclosingClass);
|
||||||
|
// Add the associated namespace for this class.
|
||||||
|
while (Ctx->isRecord())
|
||||||
|
Ctx = Ctx->getParent();
|
||||||
|
if (NamespaceDecl *EnclosingNamespace = dyn_cast<NamespaceDecl>(Ctx))
|
||||||
|
AssociatedNamespaces.insert(EnclosingNamespace);
|
||||||
|
else if (Ctx->isTranslationUnit())
|
||||||
|
GlobalScope = true;
|
||||||
|
|
||||||
|
const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
|
||||||
|
for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
|
||||||
|
addAssociatedClassesAndNamespaces(TemplateArgs[I], Context,
|
||||||
|
AssociatedNamespaces,
|
||||||
|
AssociatedClasses,
|
||||||
|
GlobalScope);
|
||||||
|
}
|
||||||
|
|
||||||
// Add direct and indirect base classes along with their associated
|
// Add direct and indirect base classes along with their associated
|
||||||
// namespaces.
|
// namespaces.
|
||||||
llvm::SmallVector<CXXRecordDecl *, 32> Bases;
|
llvm::SmallVector<CXXRecordDecl *, 32> Bases;
|
||||||
|
@ -1297,7 +1393,8 @@ addAssociatedClassesAndNamespaces(CXXRecordDecl *Class,
|
||||||
DeclContext *BaseCtx = BaseDecl->getDeclContext();
|
DeclContext *BaseCtx = BaseDecl->getDeclContext();
|
||||||
while (BaseCtx->isRecord())
|
while (BaseCtx->isRecord())
|
||||||
BaseCtx = BaseCtx->getParent();
|
BaseCtx = BaseCtx->getParent();
|
||||||
if (NamespaceDecl *EnclosingNamespace = dyn_cast<NamespaceDecl>(BaseCtx))
|
if (NamespaceDecl *EnclosingNamespace
|
||||||
|
= dyn_cast<NamespaceDecl>(BaseCtx))
|
||||||
AssociatedNamespaces.insert(EnclosingNamespace);
|
AssociatedNamespaces.insert(EnclosingNamespace);
|
||||||
else if (BaseCtx->isTranslationUnit())
|
else if (BaseCtx->isTranslationUnit())
|
||||||
GlobalScope = true;
|
GlobalScope = true;
|
||||||
|
@ -1490,6 +1587,8 @@ Sema::FindAssociatedClassesAndNamespaces(Expr **Args, unsigned NumArgs,
|
||||||
if (!DRE)
|
if (!DRE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// FIXME: The declaration might be a FunctionTemplateDecl (by itself)
|
||||||
|
// or might be buried in a TemplateIdRefExpr.
|
||||||
OverloadedFunctionDecl *Ovl
|
OverloadedFunctionDecl *Ovl
|
||||||
= dyn_cast<OverloadedFunctionDecl>(DRE->getDecl());
|
= dyn_cast<OverloadedFunctionDecl>(DRE->getDecl());
|
||||||
if (!Ovl)
|
if (!Ovl)
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
// RUN: clang-cc -fsyntax-only -verify %s
|
||||||
|
|
||||||
|
namespace N1 {
|
||||||
|
struct X { };
|
||||||
|
int& f(void*);
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace N2 {
|
||||||
|
template<typename T> struct Y { };
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace N3 {
|
||||||
|
void test() {
|
||||||
|
int &ir = f((N2::Y<N1::X>*)0);
|
||||||
|
}
|
||||||
|
}
|
|
@ -353,7 +353,7 @@ welcome!</p>
|
||||||
<td class="advanced" align="center"></td>
|
<td class="advanced" align="center"></td>
|
||||||
<td class="advanced" align="center"></td>
|
<td class="advanced" align="center"></td>
|
||||||
<td class="na">N/A</td>
|
<td class="na">N/A</td>
|
||||||
<td>Missing support for templates, friend functions.</td>
|
<td>Missing support for friend functions.</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td> 3.4.3 [basic.lookup.qual]</td>
|
<td> 3.4.3 [basic.lookup.qual]</td>
|
||||||
|
|
Загрузка…
Ссылка в новой задаче