mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[macros] add -Rmacro-expansions
This adds the -Rmacro-expansions flag. It provides similar functionality to -dump-macro-expansions, but instead of dumping the macro expansion to stderr, it emits it line by line as remarks. This is useful for testing with -verify, where both macro expansion content and warnings need to be tested at the same time.
This commit is contained in:
@@ -9012,5 +9012,7 @@ GROUPED_WARNING(perf_hint_typealias_uses_existential,ExistentialType,none,
|
||||
ERROR(unsafe_self_dependent_result_attr_on_invalid_decl,none,
|
||||
"invalid use of @_unsafeSelfDependentResult", ())
|
||||
|
||||
REMARK(macro_expansion_line, none, "macro content: |%0|", (StringRef))
|
||||
|
||||
#define UNDEFINE_DIAGNOSTIC_MACROS
|
||||
#include "DefineDiagnosticMacros.h"
|
||||
|
||||
@@ -651,6 +651,9 @@ namespace swift {
|
||||
/// Enables dumping macro expansions.
|
||||
bool DumpMacroExpansions = false;
|
||||
|
||||
/// Emits a remark with the content of each macro expansion line, for matching with -verify
|
||||
bool RemarkMacroExpansions = false;
|
||||
|
||||
/// Enables dumping imports for each SourceFile.
|
||||
bool DumpSourceFileImports = false;
|
||||
|
||||
|
||||
@@ -185,6 +185,9 @@ def verify_generic_signatures : Separate<["-"], "verify-generic-signatures">,
|
||||
MetaVarName<"<module-name>">,
|
||||
HelpText<"Verify the generic signatures in the given module">;
|
||||
|
||||
def expansion_remarks: Flag<["-"], "Rmacro-expansions">,
|
||||
HelpText<"Show remarks for each line in macro expansions">;
|
||||
|
||||
def show_diagnostics_after_fatal : Flag<["-"], "show-diagnostics-after-fatal">,
|
||||
HelpText<"Keep emitting subsequent diagnostics after a fatal error">;
|
||||
|
||||
|
||||
@@ -1774,6 +1774,9 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
|
||||
Opts.DumpMacroExpansions = Args.hasArg(
|
||||
OPT_dump_macro_expansions);
|
||||
|
||||
Opts.RemarkMacroExpansions = Args.hasArg(
|
||||
OPT_expansion_remarks);
|
||||
|
||||
Opts.DumpSourceFileImports = Args.hasArg(
|
||||
OPT_dump_source_file_imports);
|
||||
|
||||
|
||||
@@ -1006,6 +1006,21 @@ static CharSourceRange getExpansionInsertionRange(MacroRole role,
|
||||
llvm_unreachable("unhandled MacroRole");
|
||||
}
|
||||
|
||||
static void remarkMacroExpansionsEmitDiags(ASTContext &ctx, unsigned macroBufferID) {
|
||||
SourceManager &sourceMgr = ctx.SourceMgr;
|
||||
CharSourceRange range = sourceMgr.getRangeForBuffer(macroBufferID);
|
||||
SourceLoc start = range.getStart();
|
||||
StringRef content(start.getPointer(), range.getByteLength());
|
||||
size_t newline;
|
||||
do {
|
||||
newline = content.find('\n');
|
||||
StringRef line = content.take_front(newline);
|
||||
content = content.drop_front(newline + 1);
|
||||
|
||||
ctx.Diags.diagnose(SourceLoc::getFromPointer(line.begin()), diag::macro_expansion_line, line);
|
||||
} while (newline != StringRef::npos);
|
||||
}
|
||||
|
||||
static SourceFile *
|
||||
createMacroSourceFile(std::unique_ptr<llvm::MemoryBuffer> buffer,
|
||||
MacroRole role, ASTNode target, DeclContext *dc,
|
||||
@@ -1069,6 +1084,10 @@ createMacroSourceFile(std::unique_ptr<llvm::MemoryBuffer> buffer,
|
||||
originModule = cast<Decl *>(target)->getModuleContextForNameLookup();
|
||||
performImportResolutionForClangMacroBuffer(*macroSourceFile, originModule);
|
||||
}
|
||||
|
||||
if (ctx.LangOpts.RemarkMacroExpansions)
|
||||
remarkMacroExpansionsEmitDiags(ctx, macroBufferID);
|
||||
|
||||
return macroSourceFile;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import SwiftSyntax
|
||||
import SwiftSyntaxBuilder
|
||||
import SwiftSyntaxMacros
|
||||
|
||||
public struct UnstringifyPeerMacro: PeerMacro {
|
||||
public static func expansion(
|
||||
of node: AttributeSyntax,
|
||||
providingPeersOf declaration: some DeclSyntaxProtocol,
|
||||
in context: some MacroExpansionContext
|
||||
) throws -> [DeclSyntax] {
|
||||
do {
|
||||
let argumentList = node.arguments!.as(LabeledExprListSyntax.self)!
|
||||
let arguments = [LabeledExprSyntax](argumentList)
|
||||
let arg = arguments.first!.expression.as(StringLiteralExprSyntax.self)!
|
||||
let content = arg.representedLiteralValue!
|
||||
return [DeclSyntax("\(raw: content)")]
|
||||
}
|
||||
}
|
||||
}
|
||||
36
test/Frontend/DiagnosticVerifier/expansion-remarks.swift
Normal file
36
test/Frontend/DiagnosticVerifier/expansion-remarks.swift
Normal file
@@ -0,0 +1,36 @@
|
||||
// REQUIRES: swift_swift_parser, executable_test
|
||||
|
||||
// RUN: %empty-directory(%t)
|
||||
// RUN: %host-build-swift -swift-version 5 -emit-library -o %t/%target-library-name(UnstringifyMacroDefinition) -module-name=UnstringifyMacroDefinition %S/Inputs/macro/unstringify-macro.swift -g -no-toolchain-stdlib-rpath
|
||||
|
||||
// RUN: %target-typecheck-verify-swift -swift-version 5 -load-plugin-library %t/%target-library-name(UnstringifyMacroDefinition) -Rmacro-expansions
|
||||
|
||||
@attached(peer, names: overloaded)
|
||||
macro unstringifyPeer(_ s: String) =
|
||||
#externalMacro(module: "UnstringifyMacroDefinition", type: "UnstringifyPeerMacro")
|
||||
|
||||
// expected-note@+1 *{{in expansion of macro 'unstringifyPeer' on global function 'foo()' here}}
|
||||
@unstringifyPeer("func foo(_ x: Int) {\nlet a = 2\nlet b = x\n}")
|
||||
func foo() {}
|
||||
/*
|
||||
expected-expansion@-2:14{{
|
||||
expected-remark@1{{macro content: |func foo(_ x: Int) {|}}
|
||||
expected-remark@2{{macro content: | let a = 2|}}
|
||||
expected-warning@2{{initialization of immutable value 'a' was never used; consider replacing with assignment to '_' or removing it}}
|
||||
expected-remark@3{{macro content: | let b = x|}}
|
||||
expected-warning@3{{initialization of immutable value 'b' was never used; consider replacing with assignment to '_' or removing it}}
|
||||
expected-remark@4{{macro content: |}|}}
|
||||
}}
|
||||
*/
|
||||
|
||||
@freestanding(expression) public macro ExprMacro() -> String = #file
|
||||
|
||||
func bar() {
|
||||
// expected-note@+1{{in expansion of macro 'ExprMacro' here}}
|
||||
let _ = #ExprMacro()
|
||||
/*
|
||||
expected-expansion@-2:13{{
|
||||
expected-remark@1{{macro content: |#file|}}
|
||||
}}
|
||||
*/
|
||||
}
|
||||
Reference in New Issue
Block a user