A more minimal fix for PR6762.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@104991 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
John McCall 2010-05-28 18:45:08 +00:00
Родитель 2b7baf0816
Коммит c7e04dad58
4 изменённых файлов: 65 добавлений и 55 удалений

Просмотреть файл

@ -43,6 +43,8 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) {
TUScope = S;
PushDeclContext(S, Context.getTranslationUnitDecl());
VAListTagName = PP.getIdentifierInfo("__va_list_tag");
if (PP.getTargetInfo().getPointerWidth(0) >= 64) {
TypeSourceInfo *TInfo;

Просмотреть файл

@ -239,6 +239,10 @@ public:
/// CurContext - This is the current declaration context of parsing.
DeclContext *CurContext;
/// VAListTagName - The declaration name corresponding to __va_list_tag.
/// This is used as part of a hack to omit that class from ADL results.
DeclarationName VAListTagName;
/// A RAII object to temporarily push a declaration context.
class ContextRAII {
private:

Просмотреть файл

@ -1416,11 +1416,22 @@ bool Sema::DiagnoseAmbiguousLookup(LookupResult &Result) {
return true;
}
namespace {
struct AssociatedLookup {
AssociatedLookup(Sema &S,
Sema::AssociatedNamespaceSet &Namespaces,
Sema::AssociatedClassSet &Classes)
: S(S), Namespaces(Namespaces), Classes(Classes) {
}
Sema &S;
Sema::AssociatedNamespaceSet &Namespaces;
Sema::AssociatedClassSet &Classes;
};
}
static void
addAssociatedClassesAndNamespaces(QualType T,
ASTContext &Context,
Sema::AssociatedNamespaceSet &AssociatedNamespaces,
Sema::AssociatedClassSet &AssociatedClasses);
addAssociatedClassesAndNamespaces(AssociatedLookup &Result, QualType T);
static void CollectEnclosingNamespace(Sema::AssociatedNamespaceSet &Namespaces,
DeclContext *Ctx) {
@ -1439,10 +1450,8 @@ static void CollectEnclosingNamespace(Sema::AssociatedNamespaceSet &Namespaces,
// \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) {
addAssociatedClassesAndNamespaces(AssociatedLookup &Result,
const TemplateArgument &Arg) {
// C++ [basic.lookup.koenig]p2, last bullet:
// -- [...] ;
switch (Arg.getKind()) {
@ -1453,9 +1462,7 @@ addAssociatedClassesAndNamespaces(const TemplateArgument &Arg,
// [...] 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);
addAssociatedClassesAndNamespaces(Result, Arg.getAsType());
break;
case TemplateArgument::Template: {
@ -1467,9 +1474,9 @@ addAssociatedClassesAndNamespaces(const TemplateArgument &Arg,
= dyn_cast<ClassTemplateDecl>(Template.getAsTemplateDecl())) {
DeclContext *Ctx = ClassTemplate->getDeclContext();
if (CXXRecordDecl *EnclosingClass = dyn_cast<CXXRecordDecl>(Ctx))
AssociatedClasses.insert(EnclosingClass);
Result.Classes.insert(EnclosingClass);
// Add the associated namespace for this class.
CollectEnclosingNamespace(AssociatedNamespaces, Ctx);
CollectEnclosingNamespace(Result.Namespaces, Ctx);
}
break;
}
@ -1485,9 +1492,7 @@ addAssociatedClassesAndNamespaces(const TemplateArgument &Arg,
for (TemplateArgument::pack_iterator P = Arg.pack_begin(),
PEnd = Arg.pack_end();
P != PEnd; ++P)
addAssociatedClassesAndNamespaces(*P, Context,
AssociatedNamespaces,
AssociatedClasses);
addAssociatedClassesAndNamespaces(Result, *P);
break;
}
}
@ -1496,10 +1501,13 @@ addAssociatedClassesAndNamespaces(const TemplateArgument &Arg,
// argument-dependent lookup with an argument of class type
// (C++ [basic.lookup.koenig]p2).
static void
addAssociatedClassesAndNamespaces(CXXRecordDecl *Class,
ASTContext &Context,
Sema::AssociatedNamespaceSet &AssociatedNamespaces,
Sema::AssociatedClassSet &AssociatedClasses) {
addAssociatedClassesAndNamespaces(AssociatedLookup &Result,
CXXRecordDecl *Class) {
// Just silently ignore anything whose name is __va_list_tag.
if (Class->getDeclName() == Result.S.VAListTagName)
return;
// C++ [basic.lookup.koenig]p2:
// [...]
// -- If T is a class type (including unions), its associated
@ -1511,13 +1519,13 @@ addAssociatedClassesAndNamespaces(CXXRecordDecl *Class,
// Add the class of which it is a member, if any.
DeclContext *Ctx = Class->getDeclContext();
if (CXXRecordDecl *EnclosingClass = dyn_cast<CXXRecordDecl>(Ctx))
AssociatedClasses.insert(EnclosingClass);
Result.Classes.insert(EnclosingClass);
// Add the associated namespace for this class.
CollectEnclosingNamespace(AssociatedNamespaces, Ctx);
CollectEnclosingNamespace(Result.Namespaces, Ctx);
// Add the class itself. If we've already seen this class, we don't
// need to visit base classes.
if (!AssociatedClasses.insert(Class))
if (!Result.Classes.insert(Class))
return;
// -- If T is a template-id, its associated namespaces and classes are
@ -1533,15 +1541,13 @@ addAssociatedClassesAndNamespaces(CXXRecordDecl *Class,
= dyn_cast<ClassTemplateSpecializationDecl>(Class)) {
DeclContext *Ctx = Spec->getSpecializedTemplate()->getDeclContext();
if (CXXRecordDecl *EnclosingClass = dyn_cast<CXXRecordDecl>(Ctx))
AssociatedClasses.insert(EnclosingClass);
Result.Classes.insert(EnclosingClass);
// Add the associated namespace for this class.
CollectEnclosingNamespace(AssociatedNamespaces, Ctx);
CollectEnclosingNamespace(Result.Namespaces, Ctx);
const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
addAssociatedClassesAndNamespaces(TemplateArgs[I], Context,
AssociatedNamespaces,
AssociatedClasses);
addAssociatedClassesAndNamespaces(Result, TemplateArgs[I]);
}
// Only recurse into base classes for complete types.
@ -1573,10 +1579,10 @@ addAssociatedClassesAndNamespaces(CXXRecordDecl *Class,
if (!BaseType)
continue;
CXXRecordDecl *BaseDecl = cast<CXXRecordDecl>(BaseType->getDecl());
if (AssociatedClasses.insert(BaseDecl)) {
if (Result.Classes.insert(BaseDecl)) {
// Find the associated namespace for this base class.
DeclContext *BaseCtx = BaseDecl->getDeclContext();
CollectEnclosingNamespace(AssociatedNamespaces, BaseCtx);
CollectEnclosingNamespace(Result.Namespaces, BaseCtx);
// Make sure we visit the bases of this base class.
if (BaseDecl->bases_begin() != BaseDecl->bases_end())
@ -1590,10 +1596,7 @@ addAssociatedClassesAndNamespaces(CXXRecordDecl *Class,
// argument-dependent lookup with an argument of type T
// (C++ [basic.lookup.koenig]p2).
static void
addAssociatedClassesAndNamespaces(QualType Ty,
ASTContext &Context,
Sema::AssociatedNamespaceSet &AssociatedNamespaces,
Sema::AssociatedClassSet &AssociatedClasses) {
addAssociatedClassesAndNamespaces(AssociatedLookup &Result, QualType Ty) {
// C++ [basic.lookup.koenig]p2:
//
// For each argument type T in the function call, there is a set
@ -1648,9 +1651,7 @@ addAssociatedClassesAndNamespaces(QualType Ty,
case Type::Record: {
CXXRecordDecl *Class
= cast<CXXRecordDecl>(cast<RecordType>(T)->getDecl());
addAssociatedClassesAndNamespaces(Class, Context,
AssociatedNamespaces,
AssociatedClasses);
addAssociatedClassesAndNamespaces(Result, Class);
break;
}
@ -1663,10 +1664,10 @@ addAssociatedClassesAndNamespaces(QualType Ty,
DeclContext *Ctx = Enum->getDeclContext();
if (CXXRecordDecl *EnclosingClass = dyn_cast<CXXRecordDecl>(Ctx))
AssociatedClasses.insert(EnclosingClass);
Result.Classes.insert(EnclosingClass);
// Add the associated namespace for this class.
CollectEnclosingNamespace(AssociatedNamespaces, Ctx);
CollectEnclosingNamespace(Result.Namespaces, Ctx);
break;
}
@ -1753,6 +1754,8 @@ Sema::FindAssociatedClassesAndNamespaces(Expr **Args, unsigned NumArgs,
AssociatedNamespaces.clear();
AssociatedClasses.clear();
AssociatedLookup Result(*this, AssociatedNamespaces, AssociatedClasses);
// C++ [basic.lookup.koenig]p2:
// For each argument type T in the function call, there is a set
// of zero or more associated namespaces and a set of zero or more
@ -1764,9 +1767,7 @@ Sema::FindAssociatedClassesAndNamespaces(Expr **Args, unsigned NumArgs,
Expr *Arg = Args[ArgIdx];
if (Arg->getType() != Context.OverloadTy) {
addAssociatedClassesAndNamespaces(Arg->getType(), Context,
AssociatedNamespaces,
AssociatedClasses);
addAssociatedClassesAndNamespaces(Result, Arg->getType());
continue;
}
@ -1782,17 +1783,11 @@ Sema::FindAssociatedClassesAndNamespaces(Expr **Args, unsigned NumArgs,
if (unaryOp->getOpcode() == UnaryOperator::AddrOf)
Arg = unaryOp->getSubExpr();
// TODO: avoid the copies. This should be easy when the cases
// share a storage implementation.
llvm::SmallVector<NamedDecl*, 8> Functions;
UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Arg);
if (!ULE) continue;
if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Arg))
Functions.append(ULE->decls_begin(), ULE->decls_end());
else
continue;
for (llvm::SmallVectorImpl<NamedDecl*>::iterator I = Functions.begin(),
E = Functions.end(); I != E; ++I) {
for (UnresolvedSetIterator I = ULE->decls_begin(), E = ULE->decls_end();
I != E; ++I) {
// Look through any using declarations to find the underlying function.
NamedDecl *Fn = (*I)->getUnderlyingDecl();
@ -1802,9 +1797,7 @@ Sema::FindAssociatedClassesAndNamespaces(Expr **Args, unsigned NumArgs,
// Add the classes and namespaces associated with the parameter
// types and return type of this function.
addAssociatedClassesAndNamespaces(FDecl->getType(), Context,
AssociatedNamespaces,
AssociatedClasses);
addAssociatedClassesAndNamespaces(Result, FDecl->getType());
}
}
}

Просмотреть файл

@ -97,3 +97,14 @@ namespace test5 {
foo(&bar);
}
}
// PR6762: __builtin_va_list should be invisible to ADL on all platforms.
void test6_function(__builtin_va_list &argv);
namespace test6 {
void test6_function(__builtin_va_list &argv);
void test() {
__builtin_va_list args;
test6_function(args);
}
}