summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-05-28 18:45:08 +0000
committerJohn McCall <rjmccall@apple.com>2010-05-28 18:45:08 +0000
commitc7e04dad588a30c94648b9bd70cdbe25688d7629 (patch)
tree2ec791de0c74d085108bb126f72e4cf06c4dbb74
parent2b7baf0816a40af3fde3a3e174192a549b785a50 (diff)
A more minimal fix for PR6762.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@104991 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/Sema.cpp2
-rw-r--r--lib/Sema/Sema.h4
-rw-r--r--lib/Sema/SemaLookup.cpp103
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp11
4 files changed, 65 insertions, 55 deletions
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 523b196392..9cc5048572 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -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;
diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h
index 24961c7520..0870cf4646 100644
--- a/lib/Sema/Sema.h
+++ b/lib/Sema/Sema.h
@@ -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:
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index 16d7305867..906bce2fe3 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -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;
-
- if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Arg))
- Functions.append(ULE->decls_begin(), ULE->decls_end());
- else
- continue;
+ UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Arg);
+ if (!ULE) 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());
}
}
}
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp
index 2bdf7cb0d7..0c905fbf32 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p2.cpp
@@ -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);
+ }
+}