@@ -179,9 +179,9 @@ class swift::SourceLookupCache {
179179 // / Top-level macros that produce arbitrary names.
180180 SmallVector<MissingDecl *, 4 > TopLevelArbitraryMacros;
181181
182- SmallVector<Decl *, 4 > MayHaveAuxiliaryDecls;
182+ SmallVector<llvm::PointerUnion<Decl *, MacroExpansionExpr *>, 4 >
183+ MayHaveAuxiliaryDecls;
183184 void populateAuxiliaryDeclCache ();
184-
185185 SourceLookupCache (ASTContext &ctx);
186186
187187public:
@@ -238,10 +238,30 @@ SourceLookupCache &SourceFile::getCache() const {
238238 return *Cache;
239239}
240240
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+
241247template <typename Range>
242- void SourceLookupCache::addToUnqualifiedLookupCache (Range decls ,
248+ void SourceLookupCache::addToUnqualifiedLookupCache (Range items ,
243249 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+
245265 if (auto *VD = dyn_cast<ValueDecl>(D)) {
246266 if (onlyOperators ? VD->isOperator () : VD->hasName ()) {
247267 // Cache the value under both its compound name and its full name.
@@ -280,6 +300,10 @@ void SourceLookupCache::addToUnqualifiedLookupCache(Range decls,
280300 else if (auto *MED = dyn_cast<MacroExpansionDecl>(D)) {
281301 if (!onlyOperators)
282302 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+ }
283307 }
284308 }
285309}
@@ -335,75 +359,113 @@ void SourceLookupCache::addToMemberCache(Range decls) {
335359}
336360
337361void 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+
340366 // Gather macro-introduced peer names.
341367 llvm::SmallDenseMap<MacroRef, llvm::SmallVector<DeclName, 2 >>
342368 introducedNames;
343369
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+ }
368382
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+ });
373387
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+ }
377411 }
378412
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+ }
390452
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);
395456
396- // Record this macro where appropriate .
457+ // Note whether this macro produces arbitrary names .
397458 if (introducesArbitraryNames)
398459 TopLevelArbitraryMacros.push_back (MissingDecl::forUnexpandedMacro (med, decl));
399460 }
400461
401462 // Add macro-introduced names to the top-level auxiliary decl cache as
402463 // unexpanded decls represented by a MissingDecl.
464+ auto anchorDecl = decl ? decl : topLevelCodeDecl;
403465 for (auto macroNames : introducedNames) {
404466 auto macroRef = macroNames.getFirst ();
405467 for (auto name : macroNames.getSecond ()) {
406- auto *placeholder = MissingDecl::forUnexpandedMacro (macroRef, decl );
468+ auto *placeholder = MissingDecl::forUnexpandedMacro (macroRef, anchorDecl );
407469 name.addToLookupTable (TopLevelAuxiliaryDecls, placeholder);
408470 }
409471 }
@@ -421,7 +483,7 @@ SourceLookupCache::SourceLookupCache(const SourceFile &SF)
421483{
422484 FrontendStatsTracer tracer (SF.getASTContext ().Stats ,
423485 " source-file-populate-cache" );
424- addToUnqualifiedLookupCache (SF.getTopLevelDecls (), false );
486+ addToUnqualifiedLookupCache (SF.getTopLevelItems (), false );
425487 addToUnqualifiedLookupCache (SF.getHoistedDecls (), false );
426488}
427489
@@ -432,7 +494,7 @@ SourceLookupCache::SourceLookupCache(const ModuleDecl &M)
432494 " module-populate-cache" );
433495 for (const FileUnit *file : M.getFiles ()) {
434496 auto *SF = cast<SourceFile>(file);
435- addToUnqualifiedLookupCache (SF->getTopLevelDecls (), false );
497+ addToUnqualifiedLookupCache (SF->getTopLevelItems (), false );
436498 addToUnqualifiedLookupCache (SF->getHoistedDecls (), false );
437499
438500 if (auto *SFU = file->getSynthesizedFile ()) {
0 commit comments