Skip to content

Commit 30737eb

Browse files
[Caching] Support swift style diagnostics for swift caching
Add support for swift style diagnostics for swift caching. This includes pre-populate the GeneratedSourceInfo with macro name so it doesn't need to infer from an ASTNode, which the caching mechanism cannot preserve. Still leave the default diagnostic style to LLVM style because replaying swift style diagnostics is still very slow and including parsing source file using swift-syntax. rdar://128615572
1 parent 8ff3b05 commit 30737eb

File tree

7 files changed

+125
-44
lines changed

7 files changed

+125
-44
lines changed

include/swift/AST/DiagnosticEngine.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1687,10 +1687,6 @@ namespace swift {
16871687
const StringRef Message;
16881688
};
16891689

1690-
/// Retrieve the macro name for a generated source info that represents
1691-
/// a macro expansion.
1692-
DeclName getGeneratedSourceInfoMacroName(const GeneratedSourceInfo &info);
1693-
16941690
} // end namespace swift
16951691

16961692
#endif

include/swift/Basic/SourceManager.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ class GeneratedSourceInfo {
6969
/// The custom attribute for an attached macro.
7070
CustomAttr *attachedMacroCustomAttr = nullptr;
7171

72+
/// MacroDecl name if the generated source is coming from macro expansion,
73+
/// otherwise empty string.
74+
std::string macroName = "";
75+
7276
/// The name of the source file on disk that was created to hold the
7377
/// contents of this file for external clients.
7478
StringRef onDiskBufferCopyFileName = StringRef();

lib/AST/DiagnosticEngine.cpp

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1463,6 +1463,37 @@ DiagnosticEngine::diagnosticInfoForDiagnostic(const Diagnostic &diagnostic) {
14631463
diagnostic.isChildNote());
14641464
}
14651465

1466+
static DeclName
1467+
getGeneratedSourceInfoMacroName(const GeneratedSourceInfo &info) {
1468+
ASTNode expansionNode = ASTNode::getFromOpaqueValue(info.astNode);
1469+
switch (info.kind) {
1470+
#define MACRO_ROLE(Name, Description) \
1471+
case GeneratedSourceInfo::Name##MacroExpansion:
1472+
#include "swift/Basic/MacroRoles.def"
1473+
{
1474+
if (auto customAttr = info.attachedMacroCustomAttr) {
1475+
// FIXME: How will we handle deserialized custom attributes like this?
1476+
auto declRefType = cast<DeclRefTypeRepr>(customAttr->getTypeRepr());
1477+
return declRefType->getNameRef().getFullName();
1478+
}
1479+
1480+
if (auto expansionExpr = dyn_cast_or_null<MacroExpansionExpr>(
1481+
expansionNode.dyn_cast<Expr *>())) {
1482+
return expansionExpr->getMacroName().getFullName();
1483+
}
1484+
1485+
auto expansionDecl =
1486+
cast<MacroExpansionDecl>(expansionNode.get<Decl *>());
1487+
return expansionDecl->getMacroName().getFullName();
1488+
}
1489+
1490+
case GeneratedSourceInfo::PrettyPrinted:
1491+
case GeneratedSourceInfo::ReplacedFunctionBody:
1492+
case GeneratedSourceInfo::DefaultArgument:
1493+
return DeclName();
1494+
}
1495+
}
1496+
14661497
std::vector<Diagnostic>
14671498
DiagnosticEngine::getGeneratedSourceBufferNotes(SourceLoc loc) {
14681499
// The set of child notes we're building up.
@@ -1674,35 +1705,3 @@ EncodedDiagnosticMessage::EncodedDiagnosticMessage(StringRef S)
16741705
: Message(Lexer::getEncodedStringSegment(S, Buf, /*IsFirstSegment=*/true,
16751706
/*IsLastSegment=*/true,
16761707
/*IndentToStrip=*/~0U)) {}
1677-
1678-
DeclName
1679-
swift::getGeneratedSourceInfoMacroName(const GeneratedSourceInfo &info) {
1680-
ASTNode expansionNode = ASTNode::getFromOpaqueValue(info.astNode);
1681-
switch (info.kind) {
1682-
#define MACRO_ROLE(Name, Description) \
1683-
case GeneratedSourceInfo::Name##MacroExpansion:
1684-
#include "swift/Basic/MacroRoles.def"
1685-
{
1686-
DeclName macroName;
1687-
if (auto customAttr = info.attachedMacroCustomAttr) {
1688-
// FIXME: How will we handle deserialized custom attributes like this?
1689-
auto declRefType = cast<DeclRefTypeRepr>(customAttr->getTypeRepr());
1690-
return declRefType->getNameRef().getFullName();
1691-
}
1692-
1693-
if (auto expansionExpr = dyn_cast_or_null<MacroExpansionExpr>(
1694-
expansionNode.dyn_cast<Expr *>())) {
1695-
return expansionExpr->getMacroName().getFullName();
1696-
}
1697-
1698-
auto expansionDecl =
1699-
cast<MacroExpansionDecl>(expansionNode.get<Decl *>());
1700-
return expansionDecl->getMacroName().getFullName();
1701-
}
1702-
1703-
case GeneratedSourceInfo::PrettyPrinted:
1704-
case GeneratedSourceInfo::ReplacedFunctionBody:
1705-
case GeneratedSourceInfo::DefaultArgument:
1706-
return DeclName();
1707-
}
1708-
}

lib/Frontend/CachedDiagnostics.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@
1616

1717
#include "swift/Frontend/CachedDiagnostics.h"
1818

19+
#include "swift/AST/DiagnosticBridge.h"
1920
#include "swift/AST/DiagnosticConsumer.h"
2021
#include "swift/AST/DiagnosticsFrontend.h"
2122
#include "swift/Basic/Assertions.h"
2223
#include "swift/Basic/SourceManager.h"
23-
#include "swift/Frontend/CachingUtils.h"
2424
#include "swift/Frontend/Frontend.h"
2525
#include "swift/Frontend/FrontendInputsAndOutputs.h"
2626
#include "llvm/ADT/IntrusiveRefCntPtr.h"
@@ -101,6 +101,7 @@ struct SerializedGeneratedFileInfo {
101101
unsigned FileID;
102102
SerializedCharSourceRange OriginalRange;
103103
SerializedCharSourceRange GeneratedRange;
104+
std::string MacroName;
104105
};
105106

106107
struct DiagnosticSerializer {
@@ -285,6 +286,7 @@ struct MappingTraits<SerializedGeneratedFileInfo> {
285286
io.mapRequired("FileID", Info.FileID);
286287
io.mapRequired("OriginalRange", Info.OriginalRange);
287288
io.mapRequired("GeneratedRange", Info.GeneratedRange);
289+
io.mapOptional("MacroName", Info.MacroName, "");
288290
}
289291
};
290292

@@ -353,7 +355,7 @@ unsigned DiagnosticSerializer::getFileIDFromBufferID(SourceManager &SM,
353355
[&](const GeneratedSourceInfo &Info) -> SerializedGeneratedFileInfo {
354356
return {(uint8_t)Info.kind, CurrentFileID,
355357
convertSourceRange(SM, Info.originalSourceRange),
356-
convertSourceRange(SM, Info.generatedSourceRange)};
358+
convertSourceRange(SM, Info.generatedSourceRange), Info.macroName};
357359
};
358360
if (Info) {
359361
auto GI = convertGeneratedFileInfo(*Info);
@@ -567,6 +569,7 @@ llvm::Error DiagnosticSerializer::deserializeGeneratedFileInfo(
567569
if (!GeneratedRange)
568570
return GeneratedRange.takeError();
569571
Info.generatedSourceRange = *GeneratedRange;
572+
Info.macroName = GI.MacroName;
570573
SrcMgr.setGeneratedSourceInfo(ID->second, Info);
571574
return llvm::Error::success();
572575
}

lib/Frontend/CompilerInvocation.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
//===----------------------------------------------------------------------===//
1212

1313
#include "swift/AST/SILOptions.h"
14+
#include "swift/Basic/DiagnosticOptions.h"
1415
#include "swift/Frontend/Frontend.h"
1516

1617
#include "ArgsToFrontendOptionsConverter.h"
@@ -2228,8 +2229,12 @@ static bool ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
22282229
Args.hasFlag(OPT_color_diagnostics,
22292230
OPT_no_color_diagnostics,
22302231
/*Default=*/llvm::sys::Process::StandardErrHasColors());
2231-
// If no style options are specified, default to Swift style.
2232-
Opts.PrintedFormattingStyle = DiagnosticOptions::FormattingStyle::Swift;
2232+
// If no style options are specified, default to Swift style, unless it is
2233+
// under swift caching, which llvm style is preferred because LLVM style
2234+
// replays a lot faster.
2235+
Opts.PrintedFormattingStyle = Args.hasArg(OPT_cache_compile_job)
2236+
? DiagnosticOptions::FormattingStyle::LLVM
2237+
: DiagnosticOptions::FormattingStyle::Swift;
22332238
if (const Arg *arg = Args.getLastArg(OPT_diagnostic_style)) {
22342239
StringRef contents = arg->getValue();
22352240
if (contents == "llvm") {
@@ -2242,9 +2247,6 @@ static bool ParseDiagnosticArgs(DiagnosticOptions &Opts, ArgList &Args,
22422247
return true;
22432248
}
22442249
}
2245-
// Swift style is not fully supported in cached mode yet.
2246-
if (Args.hasArg(OPT_cache_compile_job))
2247-
Opts.PrintedFormattingStyle = DiagnosticOptions::FormattingStyle::LLVM;
22482250

22492251
for (const Arg *arg: Args.filtered(OPT_emit_macro_expansion_files)) {
22502252
StringRef contents = arg->getValue();

lib/Sema/TypeCheckMacros.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -985,6 +985,21 @@ createMacroSourceFile(std::unique_ptr<llvm::MemoryBuffer> buffer,
985985
GeneratedSourceInfo::Kind generatedSourceKind =
986986
getGeneratedSourceInfoKind(role);
987987

988+
/// Retrieve the macro name for a generated source info that represents
989+
/// a macro expansion.
990+
llvm::SmallString<64> macroName;
991+
if (attr)
992+
cast<DeclRefTypeRepr>(attr->getTypeRepr())
993+
->getNameRef()
994+
.getFullName()
995+
.getString(macroName);
996+
else if (auto expansionExpr =
997+
dyn_cast_or_null<MacroExpansionExpr>(target.dyn_cast<Expr *>()))
998+
expansionExpr->getMacroName().getFullName().getString(macroName);
999+
else if (auto expansionDecl =
1000+
dyn_cast_or_null<MacroExpansionDecl>(target.get<Decl *>()))
1001+
expansionDecl->getMacroName().getFullName().getString(macroName);
1002+
9881003
// Create a new source buffer with the contents of the expanded macro.
9891004
unsigned macroBufferID = sourceMgr.addNewSourceBuffer(std::move(buffer));
9901005
auto macroBufferRange = sourceMgr.getRangeForBuffer(macroBufferID);
@@ -993,7 +1008,9 @@ createMacroSourceFile(std::unique_ptr<llvm::MemoryBuffer> buffer,
9931008
macroBufferRange,
9941009
target.getOpaqueValue(),
9951010
dc,
996-
attr};
1011+
attr,
1012+
macroName.c_str()
1013+
};
9971014
sourceMgr.setGeneratedSourceInfo(macroBufferID, sourceInfo);
9981015

9991016
// Create a source file to hold the macro buffer. This is automatically
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// REQUIRES: swift_swift_parser
2+
3+
// RUN: %empty-directory(%t)
4+
// RUN: split-file %s %t
5+
// RUN: %host-build-swift -swift-version 5 -emit-library -o %t/%target-library-name(MacroDefinition) -module-name=MacroDefinition %t/macro.swift
6+
7+
// RUN: %target-swift-frontend -typecheck -module-load-mode prefer-serialized -module-name MyApp -module-cache-path %t/clang-module-cache -O \
8+
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import \
9+
// RUN: %t/main.swift -swift-version 5 -external-plugin-path %t#%swift-plugin-server 2> %t/diag1.txt
10+
11+
// RUN: %target-swift-frontend -scan-dependencies -module-load-mode prefer-serialized -module-name MyApp -module-cache-path %t/clang-module-cache -O \
12+
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import \
13+
// RUN: %t/main.swift -o %t/deps.json -swift-version 5 -cache-compile-job -cas-path %t/cas -external-plugin-path %t#%swift-plugin-server
14+
15+
// RUN: %S/Inputs/SwiftDepsExtractor.py %t/deps.json MyApp casFSRootID > %t/fs.casid
16+
// RUN: llvm-cas -cas %t/cas -ls-tree-recursive @%t/fs.casid | %FileCheck %s --check-prefix=FS
17+
18+
// FS: MacroDefinition
19+
// RUN: %S/Inputs/BuildCommandExtractor.py %t/deps.json clang:SwiftShims > %t/SwiftShims.cmd
20+
// RUN: %swift_frontend_plain @%t/SwiftShims.cmd
21+
22+
// RUN: %S/Inputs/BuildCommandExtractor.py %t/deps.json MyApp > %t/MyApp.cmd
23+
// RUN: %{python} %S/Inputs/GenerateExplicitModuleMap.py %t/deps.json > %t/map.json
24+
// RUN: llvm-cas --cas %t/cas --make-blob --data %t/map.json > %t/map.casid
25+
26+
// RUN: %target-swift-frontend -diagnostic-style=swift \
27+
// RUN: -emit-module -o %t/Test.swiftmodule -cache-compile-job -cas-path %t/cas \
28+
// RUN: -swift-version 5 -disable-implicit-swift-modules \
29+
// RUN: -external-plugin-path %t#%swift-plugin-server \
30+
// RUN: -disable-implicit-string-processing-module-import -disable-implicit-concurrency-module-import \
31+
// RUN: -module-name MyApp -explicit-swift-module-map-file @%t/map.casid -O \
32+
// RUN: %t/main.swift @%t/MyApp.cmd -serialize-diagnostics-path %t/Test.diag 2> %t/diag2.txt
33+
34+
// RUN: diff %t/diag1.txt %t/diag2.txt
35+
36+
//--- macro.swift
37+
import SwiftDiagnostics
38+
import SwiftOperators
39+
import SwiftSyntax
40+
import SwiftSyntaxBuilder
41+
@_spi(ExperimentalLanguageFeature) import SwiftSyntaxMacros
42+
43+
public struct CallDeprecatedMacro: ExpressionMacro {
44+
public static func expansion(
45+
of macro: some FreestandingMacroExpansionSyntax,
46+
in context: some MacroExpansionContext
47+
) throws -> ExprSyntax {
48+
return "testDeprecated()"
49+
}
50+
}
51+
52+
//--- main.swift
53+
@freestanding(expression) macro myWarning(_ message: String) = #externalMacro(module: "MacroDefinition", type: "CallDeprecatedMacro")
54+
55+
@available(*, deprecated)
56+
func testDeprecated() {}
57+
58+
func testDiscardableStringify(x: Int) {
59+
#myWarning("this is a warning")
60+
}

0 commit comments

Comments
 (0)