@@ -1241,6 +1241,74 @@ bool Sema::DiagnoseAmbiguousLookup(LookupResult &Result, DeclarationName Name,
1241
1241
return true ;
1242
1242
}
1243
1243
1244
+ static void
1245
+ addAssociatedClassesAndNamespaces (QualType T,
1246
+ ASTContext &Context,
1247
+ Sema::AssociatedNamespaceSet &AssociatedNamespaces,
1248
+ Sema::AssociatedClassSet &AssociatedClasses,
1249
+ bool &GlobalScope);
1250
+
1251
+ // \brief Add the associated classes and namespaces for argument-dependent
1252
+ // lookup that involves a template argument (C++ [basic.lookup.koenig]p2).
1253
+ static void
1254
+ addAssociatedClassesAndNamespaces (const TemplateArgument &Arg,
1255
+ ASTContext &Context,
1256
+ Sema::AssociatedNamespaceSet &AssociatedNamespaces,
1257
+ Sema::AssociatedClassSet &AssociatedClasses,
1258
+ bool &GlobalScope) {
1259
+ // C++ [basic.lookup.koenig]p2, last bullet:
1260
+ // -- [...] ;
1261
+ switch (Arg.getKind ()) {
1262
+ case TemplateArgument::Null:
1263
+ break ;
1264
+
1265
+ case TemplateArgument::Type:
1266
+ // [...] the namespaces and classes associated with the types of the
1267
+ // template arguments provided for template type parameters (excluding
1268
+ // template template parameters)
1269
+ addAssociatedClassesAndNamespaces (Arg.getAsType (), Context,
1270
+ AssociatedNamespaces,
1271
+ AssociatedClasses,
1272
+ GlobalScope);
1273
+ break ;
1274
+
1275
+ case TemplateArgument::Declaration:
1276
+ // [...] the namespaces in which any template template arguments are
1277
+ // defined; and the classes in which any member templates used as
1278
+ // template template arguments are defined.
1279
+ if (ClassTemplateDecl *ClassTemplate
1280
+ = dyn_cast<ClassTemplateDecl>(Arg.getAsDecl ())) {
1281
+ DeclContext *Ctx = ClassTemplate->getDeclContext ();
1282
+ if (CXXRecordDecl *EnclosingClass = dyn_cast<CXXRecordDecl>(Ctx))
1283
+ AssociatedClasses.insert (EnclosingClass);
1284
+ // Add the associated namespace for this class.
1285
+ while (Ctx->isRecord ())
1286
+ Ctx = Ctx->getParent ();
1287
+ if (NamespaceDecl *EnclosingNamespace = dyn_cast<NamespaceDecl>(Ctx))
1288
+ AssociatedNamespaces.insert (EnclosingNamespace);
1289
+ else if (Ctx->isTranslationUnit ())
1290
+ GlobalScope = true ;
1291
+ }
1292
+ break ;
1293
+
1294
+ case TemplateArgument::Integral:
1295
+ case TemplateArgument::Expression:
1296
+ // [Note: non-type template arguments do not contribute to the set of
1297
+ // associated namespaces. ]
1298
+ break ;
1299
+
1300
+ case TemplateArgument::Pack:
1301
+ for (TemplateArgument::pack_iterator P = Arg.pack_begin (),
1302
+ PEnd = Arg.pack_end ();
1303
+ P != PEnd; ++P)
1304
+ addAssociatedClassesAndNamespaces (*P, Context,
1305
+ AssociatedNamespaces,
1306
+ AssociatedClasses,
1307
+ GlobalScope);
1308
+ break ;
1309
+ }
1310
+ }
1311
+
1244
1312
// \brief Add the associated classes and namespaces for
1245
1313
// argument-dependent lookup with an argument of class type
1246
1314
// (C++ [basic.lookup.koenig]p2).
@@ -1275,8 +1343,36 @@ addAssociatedClassesAndNamespaces(CXXRecordDecl *Class,
1275
1343
if (!AssociatedClasses.insert (Class))
1276
1344
return ;
1277
1345
1278
- // FIXME: Handle class template specializations
1279
-
1346
+ // -- If T is a template-id, its associated namespaces and classes are
1347
+ // the namespace in which the template is defined; for member
1348
+ // templates, the member template’s class; the namespaces and classes
1349
+ // associated with the types of the template arguments provided for
1350
+ // template type parameters (excluding template template parameters); the
1351
+ // namespaces in which any template template arguments are defined; and
1352
+ // the classes in which any member templates used as template template
1353
+ // arguments are defined. [Note: non-type template arguments do not
1354
+ // contribute to the set of associated namespaces. ]
1355
+ if (ClassTemplateSpecializationDecl *Spec
1356
+ = dyn_cast<ClassTemplateSpecializationDecl>(Class)) {
1357
+ DeclContext *Ctx = Spec->getSpecializedTemplate ()->getDeclContext ();
1358
+ if (CXXRecordDecl *EnclosingClass = dyn_cast<CXXRecordDecl>(Ctx))
1359
+ AssociatedClasses.insert (EnclosingClass);
1360
+ // Add the associated namespace for this class.
1361
+ while (Ctx->isRecord ())
1362
+ Ctx = Ctx->getParent ();
1363
+ if (NamespaceDecl *EnclosingNamespace = dyn_cast<NamespaceDecl>(Ctx))
1364
+ AssociatedNamespaces.insert (EnclosingNamespace);
1365
+ else if (Ctx->isTranslationUnit ())
1366
+ GlobalScope = true ;
1367
+
1368
+ const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs ();
1369
+ for (unsigned I = 0 , N = TemplateArgs.size (); I != N; ++I)
1370
+ addAssociatedClassesAndNamespaces (TemplateArgs[I], Context,
1371
+ AssociatedNamespaces,
1372
+ AssociatedClasses,
1373
+ GlobalScope);
1374
+ }
1375
+
1280
1376
// Add direct and indirect base classes along with their associated
1281
1377
// namespaces.
1282
1378
llvm::SmallVector<CXXRecordDecl *, 32 > Bases;
@@ -1297,7 +1393,8 @@ addAssociatedClassesAndNamespaces(CXXRecordDecl *Class,
1297
1393
DeclContext *BaseCtx = BaseDecl->getDeclContext ();
1298
1394
while (BaseCtx->isRecord ())
1299
1395
BaseCtx = BaseCtx->getParent ();
1300
- if (NamespaceDecl *EnclosingNamespace = dyn_cast<NamespaceDecl>(BaseCtx))
1396
+ if (NamespaceDecl *EnclosingNamespace
1397
+ = dyn_cast<NamespaceDecl>(BaseCtx))
1301
1398
AssociatedNamespaces.insert (EnclosingNamespace);
1302
1399
else if (BaseCtx->isTranslationUnit ())
1303
1400
GlobalScope = true ;
@@ -1490,6 +1587,8 @@ Sema::FindAssociatedClassesAndNamespaces(Expr **Args, unsigned NumArgs,
1490
1587
if (!DRE)
1491
1588
continue ;
1492
1589
1590
+ // FIXME: The declaration might be a FunctionTemplateDecl (by itself)
1591
+ // or might be buried in a TemplateIdRefExpr.
1493
1592
OverloadedFunctionDecl *Ovl
1494
1593
= dyn_cast<OverloadedFunctionDecl>(DRE->getDecl ());
1495
1594
if (!Ovl)
0 commit comments