addAssociatedClassesAndNamespaces(CXXRecordDecl *Class,
ASTContext &Context,
Sema::AssociatedNamespaceSet &AssociatedNamespaces,
- Sema::AssociatedClassSet &AssociatedClasses) {
+ Sema::AssociatedClassSet &AssociatedClasses,
+ bool &GlobalScope) {
// C++ [basic.lookup.koenig]p2:
// [...]
// -- If T is a class type (including unions), its associated
DeclContext *Ctx = Class->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;
+
// Add the class itself. If we've already seen this class, we don't
// need to visit base classes.
if (!AssociatedClasses.insert(Class))
BaseCtx = BaseCtx->getParent();
if (NamespaceDecl *EnclosingNamespace = dyn_cast<NamespaceDecl>(BaseCtx))
AssociatedNamespaces.insert(EnclosingNamespace);
+ else if (BaseCtx->isTranslationUnit())
+ GlobalScope = true;
// Make sure we visit the bases of this base class.
if (BaseDecl->bases_begin() != BaseDecl->bases_end())
addAssociatedClassesAndNamespaces(QualType T,
ASTContext &Context,
Sema::AssociatedNamespaceSet &AssociatedNamespaces,
- Sema::AssociatedClassSet &AssociatedClasses) {
+ Sema::AssociatedClassSet &AssociatedClasses,
+ bool &GlobalScope) {
// C++ [basic.lookup.koenig]p2:
//
// For each argument type T in the function call, there is a set
= dyn_cast<CXXRecordDecl>(ClassType->getDecl())) {
addAssociatedClassesAndNamespaces(ClassDecl, Context,
AssociatedNamespaces,
- AssociatedClasses);
+ AssociatedClasses,
+ GlobalScope);
return;
}
Ctx = Ctx->getParent();
if (NamespaceDecl *EnclosingNamespace = dyn_cast<NamespaceDecl>(Ctx))
AssociatedNamespaces.insert(EnclosingNamespace);
+ else if (Ctx->isTranslationUnit())
+ GlobalScope = true;
return;
}
// Return type
addAssociatedClassesAndNamespaces(FunctionType->getResultType(),
Context,
- AssociatedNamespaces, AssociatedClasses);
+ AssociatedNamespaces, AssociatedClasses,
+ GlobalScope);
const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FunctionType);
if (!Proto)
ArgEnd = Proto->arg_type_end();
Arg != ArgEnd; ++Arg)
addAssociatedClassesAndNamespaces(*Arg, Context,
- AssociatedNamespaces, AssociatedClasses);
+ AssociatedNamespaces, AssociatedClasses,
+ GlobalScope);
return;
}
// Handle the type that the pointer to member points to.
addAssociatedClassesAndNamespaces(MemberPtr->getPointeeType(),
Context,
- AssociatedNamespaces, AssociatedClasses);
+ AssociatedNamespaces, AssociatedClasses,
+ GlobalScope);
// Handle the class type into which this points.
if (const RecordType *Class = MemberPtr->getClass()->getAsRecordType())
addAssociatedClassesAndNamespaces(cast<CXXRecordDecl>(Class->getDecl()),
Context,
- AssociatedNamespaces, AssociatedClasses);
+ AssociatedNamespaces, AssociatedClasses,
+ GlobalScope);
return;
}
void
Sema::FindAssociatedClassesAndNamespaces(Expr **Args, unsigned NumArgs,
AssociatedNamespaceSet &AssociatedNamespaces,
- AssociatedClassSet &AssociatedClasses) {
+ AssociatedClassSet &AssociatedClasses,
+ bool &GlobalScope) {
AssociatedNamespaces.clear();
AssociatedClasses.clear();
if (Arg->getType() != Context.OverloadTy) {
addAssociatedClassesAndNamespaces(Arg->getType(), Context,
- AssociatedNamespaces, AssociatedClasses);
+ AssociatedNamespaces, AssociatedClasses,
+ GlobalScope);
continue;
}
DeclContext *Ctx = FDecl->getDeclContext();
if (NamespaceDecl *EnclosingNamespace = dyn_cast<NamespaceDecl>(Ctx))
AssociatedNamespaces.insert(EnclosingNamespace);
+ else if (Ctx->isTranslationUnit())
+ GlobalScope = true;
// Add the classes and namespaces associated with the parameter
// types and return type of this function.
addAssociatedClassesAndNamespaces(FDecl->getType(), Context,
- AssociatedNamespaces, AssociatedClasses);
+ AssociatedNamespaces, AssociatedClasses,
+ GlobalScope);
}
}
}
// arguments we have.
AssociatedNamespaceSet AssociatedNamespaces;
AssociatedClassSet AssociatedClasses;
+ bool GlobalScope = false;
FindAssociatedClassesAndNamespaces(Args, NumArgs,
- AssociatedNamespaces, AssociatedClasses);
+ AssociatedNamespaces, AssociatedClasses,
+ GlobalScope);
// C++ [basic.lookup.argdep]p3:
// Let X be the lookup set produced by unqualified lookup (3.4.1)
Functions.insert(Func);
}
}
+
+ if (GlobalScope) {
+ DeclContext::lookup_iterator I, E;
+ for (llvm::tie(I, E)
+ = Context.getTranslationUnitDecl()->lookup(Context, Name);
+ I != E; ++I) {
+ FunctionDecl *Func = dyn_cast<FunctionDecl>(*I);
+ if (!Func)
+ break;
+
+ Functions.insert(Func);
+ }
+ }
}