Skip to content

Commit 0172a3e

Browse files
Merge pull request #65403 from adrian-prantl/108323748-5.9
Add support for nested ASTScopes inside of macro expansions.
2 parents 8f3e3d5 + f4f629d commit 0172a3e

File tree

5 files changed

+95
-67
lines changed

5 files changed

+95
-67
lines changed

include/swift/AST/ASTScope.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,7 @@ class ASTSourceFileScope final : public ASTScopeImpl {
413413
NullablePtr<const void> addressForPrinting() const override { return SF; }
414414

415415
ASTContext &getASTContext() const override;
416+
bool ignoreInDebugInfo() const override { return true; }
416417

417418
protected:
418419
ASTScopeImpl *expandSpecifically(ScopeCreator &scopeCreator) override;

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2165,6 +2165,14 @@ void IRGenDebugInfoImpl::setCurrentLoc(IRBuilder &Builder,
21652165
assert(parentScopesAreSane(DS) && "parent scope sanity check failed");
21662166
auto DL = llvm::DILocation::get(IGM.getLLVMContext(), L.line, L.column, Scope,
21672167
InlinedAt);
2168+
#ifndef NDEBUG
2169+
{
2170+
llvm::DILocalScope *Scope = DL->getInlinedAtScope();
2171+
llvm::DISubprogram *SP = Scope->getSubprogram();
2172+
llvm::Function *F = Builder.GetInsertBlock()->getParent();
2173+
assert((!F || SP->describes(F)) && "location points to different function");
2174+
}
2175+
#endif
21682176
Builder.SetCurrentDebugLocation(DL);
21692177
}
21702178

lib/SILGen/SILGenFunction.cpp

Lines changed: 77 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ SILGenFunction::SILGenFunction(SILGenModule &SGM, SILFunction &F,
5757
SourceLoc SLoc = F.getLocation().getSourceLoc();
5858
if (SF && SLoc) {
5959
FnASTScope = ast_scope::ASTScopeImpl::findStartingScopeForLookup(SF, SLoc);
60-
ScopeMap.insert({FnASTScope, F.getDebugScope()});
60+
ScopeMap.insert({{FnASTScope, nullptr}, F.getDebugScope()});
6161
}
6262
}
6363

@@ -215,47 +215,49 @@ const SILDebugScope *SILGenFunction::getOrCreateScope(SourceLoc SLoc) {
215215
if (!astScope->getParent())
216216
return nullptr;
217217

218-
const SILDebugScope *Scope = getOrCreateScope(astScope);
218+
const SILDebugScope *Scope = getOrCreateScope(astScope, F.getDebugScope());
219219
assert(Scope && "failed to construct SILDebugScope from ASTScope");
220220
return Scope;
221221
}
222222

223223
namespace {
224224
struct MacroInfo {
225-
MacroInfo(SourceLoc SLoc) : Loc(SLoc) {}
226-
RegularLocation Loc;
227-
std::string Name;
225+
MacroInfo(SourceLoc SLoc, SourceLoc ExpansionSLoc)
226+
: SLoc(SLoc), ExpansionSLoc(ExpansionSLoc) {}
227+
SourceLoc SLoc;
228+
SourceLoc ExpansionSLoc;
229+
RegularLocation ExpansionLoc = RegularLocation((Decl*)nullptr);
230+
std::string Name = "__unknown_macro__";
228231
bool Freestanding = false;
229232
};
230233
}
231234

235+
/// Return location of the macro expansion and the macro name.
232236
static MacroInfo getMacroInfo(GeneratedSourceInfo &Info) {
233-
SourceLoc MacroSLoc = Info.generatedSourceRange.getStart();
234-
MacroInfo Result(MacroSLoc);
235-
Result.Name = "__unknown_macro__";
237+
MacroInfo Result(Info.generatedSourceRange.getStart(),
238+
Info.originalSourceRange.getStart());
236239
if (!Info.astNode)
237240
return Result;
238-
239241
// Keep this in sync with ASTMangler::appendMacroExpansionContext().
240242
Mangle::ASTMangler mangler;
241243
switch (Info.kind) {
242244
case GeneratedSourceInfo::ExpressionMacroExpansion: {
243245
auto parent = ASTNode::getFromOpaqueValue(Info.astNode);
244246
if (auto expr =
245247
cast_or_null<MacroExpansionExpr>(parent.dyn_cast<Expr *>())) {
246-
Result.Loc = RegularLocation(expr);
248+
Result.ExpansionLoc = RegularLocation(expr);
247249
Result.Name = mangler.mangleMacroExpansion(expr);
248250
} else {
249251
auto decl = cast<MacroExpansionDecl>(parent.get<Decl *>());
250-
Result.Loc = RegularLocation(decl);
252+
Result.ExpansionLoc = RegularLocation(decl);
251253
Result.Name = mangler.mangleMacroExpansion(decl);
252254
}
253255
break;
254256
}
255257
case GeneratedSourceInfo::FreestandingDeclMacroExpansion: {
256258
auto expansion = cast<MacroExpansionDecl>(
257259
ASTNode::getFromOpaqueValue(Info.astNode).get<Decl *>());
258-
Result.Loc = RegularLocation(expansion);
260+
Result.ExpansionLoc = RegularLocation(expansion);
259261
Result.Name = mangler.mangleMacroExpansion(expansion);
260262
Result.Freestanding = true;
261263
break;
@@ -268,7 +270,7 @@ static MacroInfo getMacroInfo(GeneratedSourceInfo &Info) {
268270
auto decl = ASTNode::getFromOpaqueValue(Info.astNode).get<Decl *>();
269271
auto attr = Info.attachedMacroCustomAttr;
270272
if (auto *macroDecl = decl->getResolvedMacro(attr)) {
271-
Result.Loc = RegularLocation(macroDecl);
273+
Result.ExpansionLoc = RegularLocation(macroDecl);
272274
Result.Name = macroDecl->getBaseName().userFacingName();
273275
Result.Freestanding = true;
274276
}
@@ -297,61 +299,67 @@ const SILDebugScope *SILGenFunction::getMacroScope(SourceLoc SLoc) {
297299
if (Macro.Freestanding)
298300
return nullptr;
299301

300-
SourceLoc OrigSLoc = GeneratedSourceInfo->originalSourceRange.getStart();
301-
if (!OrigSLoc)
302-
return nullptr;
303-
302+
const SILDebugScope *TopLevelScope;
304303
auto It = InlinedScopeMap.find(BufferID);
305304
if (It != InlinedScopeMap.end())
306-
return It->second;
305+
TopLevelScope = It->second;
306+
else {
307+
// Recursively create one inlined function + scope per layer of generated
308+
// sources. Chains of Macro expansions are representad as flat
309+
// function-level scopes.
310+
SILGenFunctionBuilder B(SGM);
311+
auto &ASTContext = SGM.M.getASTContext();
312+
auto ExtInfo = SILFunctionType::ExtInfo::getThin();
313+
auto FunctionType = SILFunctionType::get(
314+
nullptr, ExtInfo, SILCoroutineKind::None,
315+
ParameterConvention::Direct_Unowned, /*Params*/ {},
316+
/*yields*/
317+
{},
318+
/*Results*/ {}, None, SubstitutionMap(), SubstitutionMap(), ASTContext);
319+
StringRef MacroName = ASTContext.getIdentifier(Macro.Name).str();
320+
RegularLocation MacroLoc(Macro.SLoc);
321+
// Use the ExpansionLoc as the location so IRGenDebugInfo can extract the
322+
// human-readable macro name from the MacroExpansionDecl.
323+
SILFunction *MacroFn = B.getOrCreateFunction(
324+
Macro.ExpansionLoc, MacroName,
325+
SILLinkage::DefaultForDeclaration, FunctionType, IsNotBare,
326+
IsNotTransparent, IsNotSerialized, IsNotDynamic, IsNotDistributed,
327+
IsNotRuntimeAccessible);
328+
// At the end of the chain ExpansionLoc should be a macro expansion node.
329+
const SILDebugScope *InlinedAt = nullptr;
330+
const SILDebugScope *ExpansionScope = getOrCreateScope(Macro.ExpansionSLoc);
331+
332+
// Inject an extra scope to hold the inlined call site.
333+
if (ExpansionScope)
334+
InlinedAt = new (SGM.M)
335+
SILDebugScope(Macro.ExpansionLoc, nullptr, ExpansionScope,
336+
ExpansionScope->InlinedCallSite);
337+
338+
TopLevelScope =
339+
new (SGM.M) SILDebugScope(MacroLoc, MacroFn, nullptr, InlinedAt);
340+
341+
InlinedScopeMap.insert({BufferID, TopLevelScope});
342+
}
307343

308-
// Recursively create one inlined function + scope per layer of generated
309-
// sources. Chains of Macro expansions are representad as flat function-level
310-
// scopes.
311-
SILGenFunctionBuilder B(SGM);
312-
auto &ASTContext = SGM.M.getASTContext();
313-
auto ExtInfo = SILFunctionType::ExtInfo::getThin();
314-
auto FunctionType = SILFunctionType::get(
315-
nullptr, ExtInfo, SILCoroutineKind::None,
316-
ParameterConvention::Direct_Unowned, /*Params*/ {},
317-
/*yields*/
318-
{},
319-
/*Results*/ {}, None, SubstitutionMap(), SubstitutionMap(), ASTContext);
320-
StringRef MacroName = ASTContext.getIdentifier(Macro.Name).str();
321-
322-
SILFunction *MacroFn = B.getOrCreateFunction(
323-
Macro.Loc, MacroName, SILLinkage::DefaultForDeclaration, FunctionType,
324-
IsNotBare, IsNotTransparent, IsNotSerialized, IsNotDynamic,
325-
IsNotDistributed, IsNotRuntimeAccessible);
326-
// At the end of the chain OrigSLoc should be a macro expansion node.
327-
const SILDebugScope *InlinedAt = nullptr;
328-
const SILDebugScope *OrigScope = getOrCreateScope(OrigSLoc);
329-
RegularLocation OrigLoc(OrigSLoc);
330-
// Inject an extra scope to hold the inlined call site.
331-
if (OrigScope)
332-
InlinedAt = new (SGM.M)
333-
SILDebugScope(Macro.Freestanding ? Macro.Loc : OrigLoc, nullptr,
334-
OrigScope, OrigScope->InlinedCallSite);
335-
336-
const SILDebugScope *Scope =
337-
new (SGM.M) SILDebugScope(Macro.Loc, MacroFn, nullptr, InlinedAt);
338-
339-
InlinedScopeMap.insert({BufferID, Scope});
340-
return Scope;
344+
// Create the scope hierarchy inside the macro expansion.
345+
auto *MacroAstScope =
346+
ast_scope::ASTScopeImpl::findStartingScopeForLookup(SF, Macro.SLoc);
347+
return getOrCreateScope(MacroAstScope, TopLevelScope,
348+
TopLevelScope->InlinedCallSite);
341349
}
342350

343351
const SILDebugScope *
344-
SILGenFunction::getOrCreateScope(const ast_scope::ASTScopeImpl *ASTScope) {
345-
const SILDebugScope *FnScope = F.getDebugScope();
346-
352+
SILGenFunction::getOrCreateScope(const ast_scope::ASTScopeImpl *ASTScope,
353+
const SILDebugScope *FnScope,
354+
const SILDebugScope *InlinedAt) {
347355
if (!ASTScope)
348356
return FnScope;
349357

350358
// Top-level function scope?
351359
if (ASTScope == FnASTScope)
352360
return FnScope;
353361

354-
auto It = ScopeMap.find(ASTScope);
362+
auto It = ScopeMap.find({ASTScope, InlinedAt});
355363
if (It != ScopeMap.end())
356364
return It->second;
357365

@@ -374,20 +382,21 @@ SILGenFunction::getOrCreateScope(const ast_scope::ASTScopeImpl *ASTScope) {
374382
// Since the arguments to Constructor aren't marked as implicit,
375383
// argument b is in the scope of v, but the call to Constructor
376384
// isn't, which correctly triggers the scope hole verifier.
377-
return B.getCurrentDebugScope();
385+
auto *CurScope = B.getCurrentDebugScope();
386+
return CurScope->InlinedCallSite != InlinedAt ? FnScope : CurScope;
378387
}
379388

380389
// Collapse BraceStmtScopes whose parent is a .*BodyScope.
381390
if (auto Parent = ASTScope->getParent().getPtrOrNull())
382391
if (Parent->getSourceRangeOfThisASTNode() ==
383392
ASTScope->getSourceRangeOfThisASTNode())
384-
return getOrCreateScope(Parent);
393+
return getOrCreateScope(Parent, FnScope, InlinedAt);
385394

386395
// The calls to defer closures have cleanup source locations pointing to the
387396
// defer. Reparent them into the current debug scope.
388397
auto *AncestorScope = ASTScope->getParent().getPtrOrNull();
389398
while (AncestorScope && AncestorScope != FnASTScope &&
390-
!ScopeMap.count(AncestorScope)) {
399+
!ScopeMap.count({AncestorScope, InlinedAt})) {
391400
if (auto *FD = dyn_cast_or_null<FuncDecl>(
392401
AncestorScope->getDeclIfAny().getPtrOrNull())) {
393402
if (cast<DeclContext>(FD) != FunctionDC)
@@ -404,10 +413,16 @@ SILGenFunction::getOrCreateScope(const ast_scope::ASTScopeImpl *ASTScope) {
404413
};
405414

406415
const SILDebugScope *Parent =
407-
getOrCreateScope(ASTScope->getParent().getPtrOrNull());
408-
RegularLocation Loc(ASTScope->getSourceRangeOfThisASTNode().Start);
409-
SILScope = new (SGM.M) SILDebugScope(Loc, &F, Parent);
410-
ScopeMap.insert({ASTScope, SILScope});
416+
getOrCreateScope(ASTScope->getParent().getPtrOrNull(), FnScope, InlinedAt);
417+
SourceLoc SLoc = ASTScope->getSourceRangeOfThisASTNode().Start;
418+
RegularLocation Loc(SLoc);
419+
SILScope = new (SGM.M)
420+
SILDebugScope(Loc, FnScope->getParentFunction(), Parent, InlinedAt);
421+
ScopeMap.insert({{ASTScope, InlinedAt}, SILScope});
422+
423+
assert(SILScope->getParentFunction() == &F &&
424+
"inlinedAt points to other function");
425+
411426
return SILScope;
412427
}
413428

lib/SILGen/SILGenFunction.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -367,8 +367,10 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
367367
using ASTScopeTy = ast_scope::ASTScopeImpl;
368368
const ASTScopeTy *FnASTScope = nullptr;
369369
/// Caches one SILDebugScope for each ASTScope.
370-
llvm::SmallDenseMap<const ASTScopeTy *, const SILDebugScope *, 16> ScopeMap;
371-
/// Caches one inline SILDebugScope for each macro BufferID.
370+
llvm::SmallDenseMap<std::pair<const ASTScopeTy *, const SILDebugScope *>,
371+
const SILDebugScope *, 16>
372+
ScopeMap;
373+
/// Caches one toplevel inline SILDebugScope for each macro BufferID.
372374
llvm::SmallDenseMap<unsigned, const SILDebugScope *, 16> InlinedScopeMap;
373375

374376
/// The cleanup depth and BB for when the operand of a
@@ -720,7 +722,9 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
720722
const SILDebugScope *getOrCreateScope(SourceLoc SLoc);
721723
const SILDebugScope *getMacroScope(SourceLoc SLoc);
722724
const SILDebugScope *
723-
getOrCreateScope(const ast_scope::ASTScopeImpl *ASTScope);
725+
getOrCreateScope(const ast_scope::ASTScopeImpl *ASTScope,
726+
const SILDebugScope *FnScope,
727+
const SILDebugScope *InlinedAt = nullptr);
724728

725729
public:
726730
/// Enter the debug scope for \p Loc, creating it if necessary.

test/Macros/macro_expand.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,9 @@ struct Bad {}
9999
func testFileID(a: Int, b: Int) {
100100
// CHECK: MacroUser/macro_expand.swift
101101
print("Result is \(#customFileID)")
102-
// CHECK-SIL: sil_scope [[SRC_SCOPE:[0-9]+]] { loc "{{.*}}macro_expand.swift":[[@LINE-3]]
102+
// CHECK-SIL: sil_scope [[SRC_SCOPE:[0-9]+]] { loc "{{.*}}macro_expand.swift":[[@LINE-3]]:6 parent {{.*}}testFileID
103103
// CHECK-SIL: sil_scope [[EXPANSION_SCOPE:[0-9]+]] { loc "{{.*}}macro_expand.swift":[[@LINE-2]]:22 parent [[SRC_SCOPE]]
104-
// CHECK-SIL: sil_scope [[MACRO_SCOPE:[0-9]+]] { loc "{{.*}}":[[@LINE-3]]:22 parent @$s9MacroUser10testFileID1a1bySi_SitF06customdE0fMf_ {{.*}} inlined_at [[EXPANSION_SCOPE]] }
104+
// CHECK-SIL: sil_scope [[MACRO_SCOPE:[0-9]+]] { loc "@__swiftmacro{{.*}}":1:1 parent @$s9MacroUser10testFileID1a1bySi_SitF06customdE0fMf_ {{.*}} inlined_at [[EXPANSION_SCOPE]] }
105105
// CHECK-SIL: string_literal utf8 "MacroUser/macro_expand.swift", loc "@__swiftmacro_9MacroUser10testFileID1a1bySi_SitF06customdE0fMf_.swift":1:1, scope [[MACRO_SCOPE]]
106106
// CHECK-IR-DAG: !DISubprogram(name: "customFileID", linkageName: "$s9MacroUser10testFileID1a1bySi_SitF06customdE0fMf_"
107107

0 commit comments

Comments
 (0)