Skip to content

Commit 7ea0e3f

Browse files
committed
Switch GeneratedSourceInfo ranges over to CharSourceRange.
Macro expansion buffers, along with other generated source buffers, need more precise "original source ranges" that can be had with the token-based `SourceRange`. Switch over to `CharSourceRange` and provide more thoughtfully-determined original source ranges.
1 parent 7ebc86e commit 7ea0e3f

File tree

11 files changed

+117
-40
lines changed

11 files changed

+117
-40
lines changed

include/swift/AST/ASTWalker.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class ArgumentList;
2424
class Decl;
2525
class Expr;
2626
class ClosureExpr;
27+
class CustomAttr;
2728
class ModuleDecl;
2829
class Stmt;
2930
class Pattern;

include/swift/Basic/SourceManager.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,12 @@ class GeneratedSourceInfo {
6363
/// which source code was generated. Conceptually, one can think of the
6464
/// buffer described by a \c GeneratedSource instance as replacing the
6565
/// code in the \c originalSourceRange.
66-
SourceRange originalSourceRange;
66+
CharSourceRange originalSourceRange;
6767

6868
/// The source range in the generated-source buffer where the generated
6969
/// code exists. This might be a subrange of the buffer containing the
7070
/// generated source, but it will never be from a different buffer.
71-
SourceRange generatedSourceRange;
71+
CharSourceRange generatedSourceRange;
7272

7373
/// The opaque pointer for an ASTNode for which this buffer was generated.
7474
void *astNode;

lib/AST/ASTScopeLookup.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -127,13 +127,16 @@ ASTScopeImpl::findChildContaining(SourceLoc loc,
127127
// A map from enclosing source files to original source ranges of the macro
128128
// expansions within that file, recording the chain of macro expansions for
129129
// the given scope.
130-
llvm::SmallDenseMap<const SourceFile *, SourceRange> scopeExpansions;
130+
llvm::SmallDenseMap<const SourceFile *, CharSourceRange>
131+
scopeExpansions;
131132

132133
// Walk up the chain of macro expansion buffers for the scope, recording the
133134
// original source range of the macro expansion along the way using generated
134135
// source info.
135136
auto *scopeExpansion = scopeSourceFile;
136-
scopeExpansions[scopeExpansion] = scope->getSourceRangeOfThisASTNode();
137+
scopeExpansions[scopeExpansion] =
138+
Lexer::getCharSourceRangeFromSourceRange(
139+
sourceMgr, scope->getSourceRangeOfThisASTNode());
137140
while (auto *ancestor = scopeExpansion->getEnclosingSourceFile()) {
138141
auto generatedInfo =
139142
sourceMgr.getGeneratedSourceInfo(*scopeExpansion->getBufferID());
@@ -150,15 +153,14 @@ ASTScopeImpl::findChildContaining(SourceLoc loc,
150153
if (scopeExpansion != scopeExpansions.end()) {
151154
// Take the original expansion range within the LCA of the loc and
152155
// the scope to compare.
153-
rangeOfScope =
154-
Lexer::getCharSourceRangeFromSourceRange(sourceMgr, scopeExpansion->second);
156+
rangeOfScope = scopeExpansion->second;
155157
loc = expansionLoc;
156158
break;
157159
}
158160

159161
auto generatedInfo =
160162
sourceMgr.getGeneratedSourceInfo(*potentialLCA->getBufferID());
161-
expansionLoc = generatedInfo->originalSourceRange.Start;
163+
expansionLoc = generatedInfo->originalSourceRange.getStart();
162164
potentialLCA = potentialLCA->getEnclosingSourceFile();
163165
}
164166
}

lib/AST/ASTScopeSourceRange.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,11 @@ void ASTScopeImpl::checkSourceRangeBeforeAddingChild(ASTScopeImpl *child,
7575
if (!generatedInfo)
7676
return false;
7777

78-
SourceRange expansionRange = generatedInfo->originalSourceRange;
78+
CharSourceRange expansionRange = generatedInfo->originalSourceRange;
7979
if (expansionRange.isInvalid())
8080
return false;
8181

82-
return containedInParent(
83-
Lexer::getCharSourceRangeFromSourceRange(sourceMgr, expansionRange));
82+
return containedInParent(expansionRange);
8483
};
8584

8685
auto childCharRange = child->getCharSourceRangeOfScope(sourceMgr);

lib/AST/DiagnosticEngine.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,11 +1241,8 @@ DiagnosticEngine::diagnosticInfoForDiagnostic(const Diagnostic &diagnostic) {
12411241
bufferID,
12421242
GeneratedSourceInfo{
12431243
GeneratedSourceInfo::PrettyPrinted,
1244-
SourceRange(),
1245-
SourceRange(
1246-
memBufferStartLoc,
1247-
memBufferStartLoc.getAdvancedLoc(buffer.size())
1248-
),
1244+
CharSourceRange(),
1245+
CharSourceRange(memBufferStartLoc, buffer.size()),
12491246
ASTNode(const_cast<Decl *>(ppDecl)).getOpaqueValue(),
12501247
nullptr
12511248
}

lib/Basic/SourceLoc.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ SourceManager::~SourceManager() {
223223
static Optional<std::string>
224224
dumpBufferToFile(const llvm::MemoryBuffer *buffer,
225225
const SourceManager &sourceMgr,
226-
SourceRange originalSourceRange) {
226+
CharSourceRange originalSourceRange) {
227227
// Create file in the system temporary directory.
228228
SmallString<128> outputFileName;
229229
llvm::sys::path::system_temp_directory(true, outputFileName);
@@ -250,14 +250,15 @@ dumpBufferToFile(const llvm::MemoryBuffer *buffer,
250250
out << "\n";
251251

252252
auto originalFilename =
253-
sourceMgr.getDisplayNameForLoc(originalSourceRange.Start, true);
253+
sourceMgr.getDisplayNameForLoc(originalSourceRange.getStart(),
254+
true);
254255
unsigned startLine, startColumn, endLine, endColumn;
255256
std::tie(startLine, startColumn) =
256257
sourceMgr.getPresumedLineAndColumnForLoc(
257-
originalSourceRange.Start);
258+
originalSourceRange.getStart());
258259
std::tie(endLine, endColumn) =
259260
sourceMgr.getPresumedLineAndColumnForLoc(
260-
originalSourceRange.End);
261+
originalSourceRange.getEnd());
261262
out << "// original-source-range: "
262263
<< originalFilename
263264
<< ":" << startLine << ":" << startColumn
@@ -383,7 +384,11 @@ void SourceManager::setGeneratedSourceInfo(
383384

384385
case GeneratedSourceInfo::ReplacedFunctionBody:
385386
// Keep track of the replaced range.
386-
ReplacedRanges[info.originalSourceRange] = info.generatedSourceRange;
387+
SourceRange orig(info.originalSourceRange.getStart(),
388+
info.originalSourceRange.getEnd());
389+
ReplacedRanges[orig] =
390+
SourceRange(info.generatedSourceRange.getStart(),
391+
info.generatedSourceRange.getEnd());
387392
break;
388393
}
389394
}

lib/Frontend/SerializedDiagnosticConsumer.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -262,11 +262,10 @@ unsigned SerializedDiagnosticConsumer::getEmitFile(
262262
// The source range that this buffer was generated from, expressed as
263263
// offsets into the original buffer.
264264
if (generatedInfo->originalSourceRange.isValid()) {
265-
auto originalFilename = SM.getDisplayNameForLoc(generatedInfo->originalSourceRange.Start,
265+
auto originalFilename = SM.getDisplayNameForLoc(generatedInfo->originalSourceRange.getStart(),
266266
EmitMacroExpansionFiles);
267267
addRangeToRecord(
268-
Lexer::getCharSourceRangeFromSourceRange(
269-
SM, generatedInfo->originalSourceRange),
268+
generatedInfo->originalSourceRange,
270269
SM, originalFilename, Record
271270
);
272271
} else {

lib/IDETool/CompileInstance.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,9 @@ void retypeCheckFunctionBody(AbstractFunctionDecl *func,
193193
sliceBufferID,
194194
GeneratedSourceInfo{
195195
GeneratedSourceInfo::ReplacedFunctionBody,
196-
func->getOriginalBodySourceRange(),
197-
newRange,
196+
Lexer::getCharSourceRangeFromSourceRange(
197+
origSM, func->getOriginalBodySourceRange()),
198+
Lexer::getCharSourceRangeFromSourceRange(newSM, newRange),
198199
func,
199200
nullptr
200201
}

lib/IDETool/IDEInspectionInstance.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -346,8 +346,9 @@ bool IDEInspectionInstance::performCachedOperationIfPossible(
346346
newBufferID,
347347
GeneratedSourceInfo{
348348
GeneratedSourceInfo::ReplacedFunctionBody,
349-
AFD->getOriginalBodySourceRange(),
350-
newBodyRange,
349+
Lexer::getCharSourceRangeFromSourceRange(
350+
SM, AFD->getOriginalBodySourceRange()),
351+
Lexer::getCharSourceRangeFromSourceRange(SM, newBodyRange),
351352
AFD,
352353
nullptr
353354
}

lib/Sema/TypeCheckMacros.cpp

Lines changed: 82 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -593,8 +593,9 @@ Expr *swift::expandMacroExpr(
593593
auto macroBufferRange = sourceMgr.getRangeForBuffer(macroBufferID);
594594
GeneratedSourceInfo sourceInfo{
595595
GeneratedSourceInfo::ExpressionMacroExpansion,
596-
expr->getSourceRange(),
597-
SourceRange(macroBufferRange.getStart(), macroBufferRange.getEnd()),
596+
Lexer::getCharSourceRangeFromSourceRange(
597+
sourceMgr, expr->getSourceRange()),
598+
macroBufferRange,
598599
ASTNode(expr).getOpaqueValue(),
599600
dc
600601
};
@@ -761,8 +762,9 @@ bool swift::expandFreestandingDeclarationMacro(
761762
auto macroBufferRange = sourceMgr.getRangeForBuffer(macroBufferID);
762763
GeneratedSourceInfo sourceInfo{
763764
GeneratedSourceInfo::FreestandingDeclMacroExpansion,
764-
med->getSourceRange(),
765-
SourceRange(macroBufferRange.getStart(), macroBufferRange.getEnd()),
765+
Lexer::getCharSourceRangeFromSourceRange(
766+
sourceMgr, med->getSourceRange()),
767+
macroBufferRange,
766768
ASTNode(med).getOpaqueValue(),
767769
dc
768770
};
@@ -794,6 +796,27 @@ bool swift::expandFreestandingDeclarationMacro(
794796
return true;
795797
}
796798

799+
// If this storage declaration is a variable with an explicit initializer,
800+
// return the range from the `=` to the end of the explicit initializer.
801+
static Optional<SourceRange> getExplicitInitializerRange(
802+
AbstractStorageDecl *storage) {
803+
auto var = dyn_cast<VarDecl>(storage);
804+
if (!var)
805+
return None;
806+
807+
auto pattern = var->getParentPatternBinding();
808+
if (!pattern)
809+
return None;
810+
811+
unsigned index = pattern->getPatternEntryIndexForVarDecl(var);
812+
SourceLoc equalLoc = pattern->getEqualLoc(index);
813+
SourceRange initRange = pattern->getOriginalInitRange(index);
814+
if (equalLoc.isInvalid() || initRange.End.isInvalid())
815+
return None;
816+
817+
return SourceRange(equalLoc, initRange.End);
818+
}
819+
797820
static SourceFile *
798821
evaluateAttachedMacro(MacroDecl *macro, Decl *attachedTo, CustomAttr *attr,
799822
bool passParentContext, MacroRole role) {
@@ -947,20 +970,69 @@ evaluateAttachedMacro(MacroDecl *macro, Decl *attachedTo, CustomAttr *attr,
947970
<< "\n------------------------------\n";
948971
}
949972

973+
CharSourceRange generatedOriginalSourceRange;
950974
GeneratedSourceInfo::Kind generatedSourceKind;
951975
switch (role) {
952-
case MacroRole::Accessor:
976+
case MacroRole::Accessor: {
953977
generatedSourceKind = GeneratedSourceInfo::AccessorMacroExpansion;
978+
979+
// Compute the location where the accessors will be added.
980+
auto storage = cast<AbstractStorageDecl>(attachedTo);
981+
auto bracesRange = storage->getBracesRange();
982+
if (bracesRange.Start.isValid()) {
983+
// We have braces already, so insert them inside the leading '{'.
984+
generatedOriginalSourceRange = CharSourceRange(
985+
Lexer::getLocForEndOfToken(sourceMgr, bracesRange.Start), 0);
986+
} else if (auto initRange = getExplicitInitializerRange(storage)) {
987+
// The accessor had an initializer, so the initializer (including
988+
// the `=`) is replaced by the accessors.
989+
generatedOriginalSourceRange =
990+
Lexer::getCharSourceRangeFromSourceRange(sourceMgr, *initRange);
991+
} else {
992+
// The accessors go at the end.
993+
generatedOriginalSourceRange = CharSourceRange(
994+
Lexer::getLocForEndOfToken(sourceMgr, storage->getEndLoc()), 0);
995+
}
996+
954997
break;
955-
case MacroRole::MemberAttribute:
998+
}
999+
1000+
case MacroRole::MemberAttribute: {
9561001
generatedSourceKind = GeneratedSourceInfo::MemberAttributeMacroExpansion;
1002+
SourceLoc startLoc;
1003+
if (auto valueDecl = dyn_cast<ValueDecl>(attachedTo))
1004+
startLoc = valueDecl->getAttributeInsertionLoc(/*forModifier=*/false);
1005+
else
1006+
startLoc = attachedTo->getStartLoc();
1007+
1008+
generatedOriginalSourceRange = CharSourceRange(startLoc, 0);
9571009
break;
958-
case MacroRole::Member:
1010+
}
1011+
1012+
case MacroRole::Member: {
9591013
generatedSourceKind = GeneratedSourceInfo::MemberMacroExpansion;
1014+
1015+
// Semantically, we insert members right before the closing brace.
1016+
SourceLoc rightBraceLoc;
1017+
if (auto nominal = dyn_cast<NominalTypeDecl>(attachedTo)) {
1018+
rightBraceLoc = nominal->getBraces().End;
1019+
} else {
1020+
auto ext = cast<ExtensionDecl>(parentDecl);
1021+
rightBraceLoc = ext->getBraces().End;
1022+
}
1023+
1024+
generatedOriginalSourceRange = CharSourceRange(rightBraceLoc, 0);
9601025
break;
961-
case MacroRole::Peer:
1026+
}
1027+
1028+
case MacroRole::Peer: {
9621029
generatedSourceKind = GeneratedSourceInfo::PeerMacroExpansion;
1030+
SourceLoc afterDeclLoc =
1031+
Lexer::getLocForEndOfToken(sourceMgr, decl->getEndLoc());
1032+
generatedOriginalSourceRange = CharSourceRange(afterDeclLoc, 0);
9631033
break;
1034+
}
1035+
9641036
case MacroRole::Expression:
9651037
case MacroRole::Declaration:
9661038
llvm_unreachable("freestanding macro in attached macro evaluation");
@@ -973,8 +1045,8 @@ evaluateAttachedMacro(MacroDecl *macro, Decl *attachedTo, CustomAttr *attr,
9731045
auto macroBufferRange = sourceMgr.getRangeForBuffer(macroBufferID);
9741046
GeneratedSourceInfo sourceInfo{
9751047
generatedSourceKind,
976-
attachedTo->getEndLoc(),
977-
SourceRange(macroBufferRange.getStart(), macroBufferRange.getEnd()),
1048+
generatedOriginalSourceRange,
1049+
macroBufferRange,
9781050
ASTNode(attachedTo).getOpaqueValue(),
9791051
dc,
9801052
attr

0 commit comments

Comments
 (0)