@@ -179,9 +179,9 @@ class swift::SourceLookupCache {
179
179
// / Top-level macros that produce arbitrary names.
180
180
SmallVector<MissingDecl *, 4 > TopLevelArbitraryMacros;
181
181
182
- SmallVector<Decl *, 4 > MayHaveAuxiliaryDecls;
182
+ SmallVector<llvm::PointerUnion<Decl *, MacroExpansionExpr *>, 4 >
183
+ MayHaveAuxiliaryDecls;
183
184
void populateAuxiliaryDeclCache ();
184
-
185
185
SourceLookupCache (ASTContext &ctx);
186
186
187
187
public:
@@ -238,10 +238,30 @@ SourceLookupCache &SourceFile::getCache() const {
238
238
return *Cache;
239
239
}
240
240
241
+ static Expr *getAsExpr (Decl *decl) { return nullptr ; }
242
+ static Decl *getAsDecl (Decl *decl) { return decl; }
243
+
244
+ static Expr *getAsExpr (ASTNode node) { return node.dyn_cast <Expr *>(); }
245
+ static Decl *getAsDecl (ASTNode node) { return node.dyn_cast <Decl *>(); }
246
+
241
247
template <typename Range>
242
- void SourceLookupCache::addToUnqualifiedLookupCache (Range decls ,
248
+ void SourceLookupCache::addToUnqualifiedLookupCache (Range items ,
243
249
bool onlyOperators) {
244
- for (Decl *D : decls) {
250
+ for (auto item : items) {
251
+ // In script mode, we'll see macro expansion expressions for freestanding
252
+ // macros.
253
+ if (Expr *E = getAsExpr (item)) {
254
+ if (auto MEE = dyn_cast<MacroExpansionExpr>(E)) {
255
+ if (!onlyOperators)
256
+ MayHaveAuxiliaryDecls.push_back (MEE);
257
+ }
258
+ continue ;
259
+ }
260
+
261
+ Decl *D = getAsDecl (item);
262
+ if (!D)
263
+ continue ;
264
+
245
265
if (auto *VD = dyn_cast<ValueDecl>(D)) {
246
266
if (onlyOperators ? VD->isOperator () : VD->hasName ()) {
247
267
// Cache the value under both its compound name and its full name.
@@ -280,6 +300,10 @@ void SourceLookupCache::addToUnqualifiedLookupCache(Range decls,
280
300
else if (auto *MED = dyn_cast<MacroExpansionDecl>(D)) {
281
301
if (!onlyOperators)
282
302
MayHaveAuxiliaryDecls.push_back (MED);
303
+ } else if (auto TLCD = dyn_cast<TopLevelCodeDecl>(D)) {
304
+ if (auto body = TLCD->getBody ()){
305
+ addToUnqualifiedLookupCache (body->getElements (), onlyOperators);
306
+ }
283
307
}
284
308
}
285
309
}
@@ -335,75 +359,113 @@ void SourceLookupCache::addToMemberCache(Range decls) {
335
359
}
336
360
337
361
void SourceLookupCache::populateAuxiliaryDeclCache () {
338
- using MacroRef = llvm::PointerUnion<MacroExpansionDecl *, CustomAttr *>;
339
- for (auto *decl : MayHaveAuxiliaryDecls) {
362
+ using MacroRef = llvm::PointerUnion<FreestandingMacroExpansion *, CustomAttr *>;
363
+ for (auto item : MayHaveAuxiliaryDecls) {
364
+ TopLevelCodeDecl *topLevelCodeDecl = nullptr ;
365
+
340
366
// Gather macro-introduced peer names.
341
367
llvm::SmallDenseMap<MacroRef, llvm::SmallVector<DeclName, 2 >>
342
368
introducedNames;
343
369
344
- // This code deliberately avoids `forEachAttachedMacro`, because it
345
- // will perform overload resolution and possibly invoke unqualified
346
- // lookup for macro arguments, which will recursively populate the
347
- // auxiliary decl cache and cause request cycles.
348
- //
349
- // We do not need a fully resolved macro until expansion. Instead, we
350
- // conservatively consider peer names for all macro declarations with a
351
- // custom attribute name. Unqualified lookup for that name will later
352
- // invoke expansion of the macro, and will yield no results if the resolved
353
- // macro does not produce the requested name, so the only impact is possibly
354
- // expanding earlier than needed / unnecessarily looking in the top-level
355
- // auxiliary decl cache.
356
- for (auto attrConst : decl->getAttrs ().getAttributes <CustomAttr>()) {
357
- auto *attr = const_cast <CustomAttr *>(attrConst);
358
- UnresolvedMacroReference macroRef (attr);
359
- bool introducesArbitraryNames = false ;
360
- namelookup::forEachPotentialResolvedMacro (
361
- decl->getDeclContext ()->getModuleScopeContext (),
362
- macroRef.getMacroName (), MacroRole::Peer,
363
- [&](MacroDecl *macro, const MacroRoleAttr *roleAttr) {
364
- // First check for arbitrary names.
365
- if (roleAttr->hasNameKind (MacroIntroducedDeclNameKind::Arbitrary)) {
366
- introducesArbitraryNames = true ;
367
- }
370
+ // / Introduce names for a freestanding macro.
371
+ auto introduceNamesForFreestandingMacro =
372
+ [&](FreestandingMacroExpansion *macroRef, Decl *decl, MacroRole role) {
373
+ bool introducesArbitraryNames = false ;
374
+ namelookup::forEachPotentialResolvedMacro (
375
+ decl->getDeclContext ()->getModuleScopeContext (),
376
+ macroRef->getMacroName (), role,
377
+ [&](MacroDecl *macro, const MacroRoleAttr *roleAttr) {
378
+ // First check for arbitrary names.
379
+ if (roleAttr->hasNameKind (MacroIntroducedDeclNameKind::Arbitrary)) {
380
+ introducesArbitraryNames = true ;
381
+ }
368
382
369
- macro->getIntroducedNames (MacroRole::Peer ,
370
- dyn_cast<ValueDecl>(decl) ,
371
- introducedNames[attr ]);
372
- });
383
+ macro->getIntroducedNames (role ,
384
+ /* attachedTo */ nullptr ,
385
+ introducedNames[macroRef ]);
386
+ });
373
387
374
- // Record this macro where appropriate.
375
- if (introducesArbitraryNames)
376
- TopLevelArbitraryMacros.push_back (MissingDecl::forUnexpandedMacro (attr, decl));
388
+ return introducesArbitraryNames;
389
+ };
390
+
391
+ // Handle macro expansion expressions, which show up in when we have
392
+ // freestanding macros in "script" mode.
393
+ if (auto expr = item.dyn_cast <MacroExpansionExpr *>()) {
394
+ topLevelCodeDecl = dyn_cast<TopLevelCodeDecl>(expr->getDeclContext ());
395
+ if (topLevelCodeDecl) {
396
+ bool introducesArbitraryNames = false ;
397
+ if (introduceNamesForFreestandingMacro (
398
+ expr, topLevelCodeDecl, MacroRole::Declaration))
399
+ introducesArbitraryNames = true ;
400
+
401
+ if (introduceNamesForFreestandingMacro (
402
+ expr, topLevelCodeDecl, MacroRole::CodeItem))
403
+ introducesArbitraryNames = true ;
404
+
405
+ // Record this macro if it introduces arbitrary names.
406
+ if (introducesArbitraryNames) {
407
+ TopLevelArbitraryMacros.push_back (
408
+ MissingDecl::forUnexpandedMacro (expr, topLevelCodeDecl));
409
+ }
410
+ }
377
411
}
378
412
379
- if (auto *med = dyn_cast<MacroExpansionDecl>(decl)) {
380
- UnresolvedMacroReference macroRef (med);
381
- bool introducesArbitraryNames = false ;
382
- namelookup::forEachPotentialResolvedMacro (
383
- decl->getDeclContext ()->getModuleScopeContext (),
384
- macroRef.getMacroName (), MacroRole::Declaration,
385
- [&](MacroDecl *macro, const MacroRoleAttr *roleAttr) {
386
- // First check for arbitrary names.
387
- if (roleAttr->hasNameKind (MacroIntroducedDeclNameKind::Arbitrary)) {
388
- introducesArbitraryNames = true ;
389
- }
413
+ auto *decl = item.dyn_cast <Decl *>();
414
+ if (decl) {
415
+ // This code deliberately avoids `forEachAttachedMacro`, because it
416
+ // will perform overload resolution and possibly invoke unqualified
417
+ // lookup for macro arguments, which will recursively populate the
418
+ // auxiliary decl cache and cause request cycles.
419
+ //
420
+ // We do not need a fully resolved macro until expansion. Instead, we
421
+ // conservatively consider peer names for all macro declarations with a
422
+ // custom attribute name. Unqualified lookup for that name will later
423
+ // invoke expansion of the macro, and will yield no results if the resolved
424
+ // macro does not produce the requested name, so the only impact is possibly
425
+ // expanding earlier than needed / unnecessarily looking in the top-level
426
+ // auxiliary decl cache.
427
+ for (auto attrConst : decl->getAttrs ().getAttributes <CustomAttr>()) {
428
+ auto *attr = const_cast <CustomAttr *>(attrConst);
429
+ UnresolvedMacroReference macroRef (attr);
430
+ bool introducesArbitraryNames = false ;
431
+ namelookup::forEachPotentialResolvedMacro (
432
+ decl->getDeclContext ()->getModuleScopeContext (),
433
+ macroRef.getMacroName (), MacroRole::Peer,
434
+ [&](MacroDecl *macro, const MacroRoleAttr *roleAttr) {
435
+ // First check for arbitrary names.
436
+ if (roleAttr->hasNameKind (
437
+ MacroIntroducedDeclNameKind::Arbitrary)) {
438
+ introducesArbitraryNames = true ;
439
+ }
440
+
441
+ macro->getIntroducedNames (MacroRole::Peer,
442
+ dyn_cast<ValueDecl>(decl),
443
+ introducedNames[attr]);
444
+ });
445
+
446
+ // Record this macro where appropriate.
447
+ if (introducesArbitraryNames)
448
+ TopLevelArbitraryMacros.push_back (
449
+ MissingDecl::forUnexpandedMacro (attr, decl));
450
+ }
451
+ }
390
452
391
- macro->getIntroducedNames (MacroRole::Declaration,
392
- /* attachedTo*/ nullptr ,
393
- introducedNames[med]);
394
- });
453
+ if (auto *med = dyn_cast_or_null<MacroExpansionDecl>(decl)) {
454
+ bool introducesArbitraryNames =
455
+ introduceNamesForFreestandingMacro (med, decl, MacroRole::Declaration);
395
456
396
- // Record this macro where appropriate .
457
+ // Note whether this macro produces arbitrary names .
397
458
if (introducesArbitraryNames)
398
459
TopLevelArbitraryMacros.push_back (MissingDecl::forUnexpandedMacro (med, decl));
399
460
}
400
461
401
462
// Add macro-introduced names to the top-level auxiliary decl cache as
402
463
// unexpanded decls represented by a MissingDecl.
464
+ auto anchorDecl = decl ? decl : topLevelCodeDecl;
403
465
for (auto macroNames : introducedNames) {
404
466
auto macroRef = macroNames.getFirst ();
405
467
for (auto name : macroNames.getSecond ()) {
406
- auto *placeholder = MissingDecl::forUnexpandedMacro (macroRef, decl );
468
+ auto *placeholder = MissingDecl::forUnexpandedMacro (macroRef, anchorDecl );
407
469
name.addToLookupTable (TopLevelAuxiliaryDecls, placeholder);
408
470
}
409
471
}
@@ -421,7 +483,7 @@ SourceLookupCache::SourceLookupCache(const SourceFile &SF)
421
483
{
422
484
FrontendStatsTracer tracer (SF.getASTContext ().Stats ,
423
485
" source-file-populate-cache" );
424
- addToUnqualifiedLookupCache (SF.getTopLevelDecls (), false );
486
+ addToUnqualifiedLookupCache (SF.getTopLevelItems (), false );
425
487
addToUnqualifiedLookupCache (SF.getHoistedDecls (), false );
426
488
}
427
489
@@ -432,7 +494,7 @@ SourceLookupCache::SourceLookupCache(const ModuleDecl &M)
432
494
" module-populate-cache" );
433
495
for (const FileUnit *file : M.getFiles ()) {
434
496
auto *SF = cast<SourceFile>(file);
435
- addToUnqualifiedLookupCache (SF->getTopLevelDecls (), false );
497
+ addToUnqualifiedLookupCache (SF->getTopLevelItems (), false );
436
498
addToUnqualifiedLookupCache (SF->getHoistedDecls (), false );
437
499
438
500
if (auto *SFU = file->getSynthesizedFile ()) {
0 commit comments