From 1e9d3b74fae3e52b385582f1de05e2cf0cf2ffa3 Mon Sep 17 00:00:00 2001 From: Brent Royal-Gordon Date: Thu, 20 Jun 2019 17:43:55 -0700 Subject: [PATCH 1/6] Make #file only include the filename This change may have significant code size benefits. --- lib/SILGen/SILGenApply.cpp | 4 +++- test/PlaygroundTransform/implicit_return_never.swift | 2 +- test/PlaygroundTransform/placeholder.swift | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp index ac8ba2912ecfa..d935543d10903 100644 --- a/lib/SILGen/SILGenApply.cpp +++ b/lib/SILGen/SILGenApply.cpp @@ -5134,7 +5134,9 @@ RValue SILGenFunction::emitLiteral(LiteralExpr *literal, SGFContext C) { std::string value; if (loc.isValid()) value = ctx.SourceMgr.getDisplayNameForLoc(loc); - builtinLiteralArgs = emitStringLiteral(*this, literal, value, C, + builtinLiteralArgs = emitStringLiteral(*this, literal, + llvm::sys::path::filename(value), + C, magicLiteral->getStringEncoding()); builtinInit = magicLiteral->getBuiltinInitializer(); init = magicLiteral->getInitializer(); diff --git a/test/PlaygroundTransform/implicit_return_never.swift b/test/PlaygroundTransform/implicit_return_never.swift index dca3f752bd9ee..bbb8f41429bd9 100644 --- a/test/PlaygroundTransform/implicit_return_never.swift +++ b/test/PlaygroundTransform/implicit_return_never.swift @@ -13,7 +13,7 @@ func f() -> Int { fatalError() -// CRASH-CHECK: {{[fF]}}atal error: file {{.*}}/main.swift, line [[@LINE-1]] +// CRASH-CHECK: {{[fF]}}atal error: file main.swift, line [[@LINE-1]] } f() diff --git a/test/PlaygroundTransform/placeholder.swift b/test/PlaygroundTransform/placeholder.swift index 734237ad1ef02..213ce95a88d93 100644 --- a/test/PlaygroundTransform/placeholder.swift +++ b/test/PlaygroundTransform/placeholder.swift @@ -15,7 +15,7 @@ func f(crash crash: Bool) -> Int { if crash { return <#T#> - // CRASH-CHECK: {{[fF]}}atal error: attempt to evaluate editor placeholder: file {{.*}}/main.swift, line [[@LINE-1]] + // CRASH-CHECK: {{[fF]}}atal error: attempt to evaluate editor placeholder: file main.swift, line [[@LINE-1]] } else { return 42 } From e5b582f1744e28d97a8ca8968571ba52d21567e6 Mon Sep 17 00:00:00 2001 From: Brent Royal-Gordon Date: Fri, 15 Nov 2019 19:34:47 -0800 Subject: [PATCH 2/6] Include module name in string Along with a not-yet-usable way to get back to the old behavior. --- lib/SILGen/SILGenApply.cpp | 23 ++++++++++++++----- .../implicit_return_never.swift | 2 +- test/PlaygroundTransform/placeholder.swift | 2 +- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp index d935543d10903..3d812d4e59a16 100644 --- a/lib/SILGen/SILGenApply.cpp +++ b/lib/SILGen/SILGenApply.cpp @@ -4876,6 +4876,21 @@ getMagicFunctionString(SILGenFunction &SGF) { return SGF.MagicFunctionString; } +static std::string getMagicFileString(SILGenFunction &SGF, SourceLoc loc) { + if (!loc.isValid()) + return ""; + + auto path = SGF.getASTContext().SourceMgr.getDisplayNameForLoc(loc); + if (false /* FIXME: Add a command line flag for this */) + return path; + + auto value = llvm::sys::path::filename(path).str(); + value += " ("; + value += SGF.getModule().getSwiftModule()->getNameStr(); + value += ")"; + return value; +} + /// Emit an application of the given allocating initializer. RValue SILGenFunction::emitApplyAllocatingInitializer(SILLocation loc, ConcreteDeclRef init, @@ -5131,12 +5146,8 @@ RValue SILGenFunction::emitLiteral(LiteralExpr *literal, SGFContext C) { auto magicLiteral = cast(literal); switch (magicLiteral->getKind()) { case MagicIdentifierLiteralExpr::File: { - std::string value; - if (loc.isValid()) - value = ctx.SourceMgr.getDisplayNameForLoc(loc); - builtinLiteralArgs = emitStringLiteral(*this, literal, - llvm::sys::path::filename(value), - C, + std::string value = getMagicFileString(*this, loc); + builtinLiteralArgs = emitStringLiteral(*this, literal, value, C, magicLiteral->getStringEncoding()); builtinInit = magicLiteral->getBuiltinInitializer(); init = magicLiteral->getInitializer(); diff --git a/test/PlaygroundTransform/implicit_return_never.swift b/test/PlaygroundTransform/implicit_return_never.swift index bbb8f41429bd9..d641b2ce87fef 100644 --- a/test/PlaygroundTransform/implicit_return_never.swift +++ b/test/PlaygroundTransform/implicit_return_never.swift @@ -13,7 +13,7 @@ func f() -> Int { fatalError() -// CRASH-CHECK: {{[fF]}}atal error: file main.swift, line [[@LINE-1]] +// CRASH-CHECK: {{[fF]}}atal error: file main.swift (main), line [[@LINE-1]] } f() diff --git a/test/PlaygroundTransform/placeholder.swift b/test/PlaygroundTransform/placeholder.swift index 213ce95a88d93..4a4c6219f0275 100644 --- a/test/PlaygroundTransform/placeholder.swift +++ b/test/PlaygroundTransform/placeholder.swift @@ -15,7 +15,7 @@ func f(crash crash: Bool) -> Int { if crash { return <#T#> - // CRASH-CHECK: {{[fF]}}atal error: attempt to evaluate editor placeholder: file main.swift, line [[@LINE-1]] + // CRASH-CHECK: {{[fF]}}atal error: attempt to evaluate editor placeholder: file main.swift (main), line [[@LINE-1]] } else { return 42 } From 789d38eb04c437d9c16f916c2b49c42d0f78ef52 Mon Sep 17 00:00:00 2001 From: Brent Royal-Gordon Date: Fri, 15 Nov 2019 20:23:35 -0800 Subject: [PATCH 3/6] Control #file behavior with a command line option --- include/swift/Basic/LangOptions.h | 4 ++++ include/swift/Option/Options.td | 8 ++++++++ lib/Driver/ToolChains.cpp | 1 + lib/Frontend/CompilerInvocation.cpp | 11 +++++++++++ lib/SILGen/SILGenApply.cpp | 2 +- 5 files changed, 25 insertions(+), 1 deletion(-) diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h index 934da2d6e4945..f768546813258 100644 --- a/include/swift/Basic/LangOptions.h +++ b/include/swift/Basic/LangOptions.h @@ -94,6 +94,10 @@ namespace swift { /// when using RequireExplicitAvailability. std::string RequireExplicitAvailabilityTarget; + /// If true, '#file' evaluates to the full path rather than a + /// human-readable string. + bool MagicFileIdentifierEvaluatesToPath = false; + /// /// Support for alternate usage modes /// diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td index e9799c7130123..eb1fbd8bb333e 100644 --- a/include/swift/Option/Options.td +++ b/include/swift/Option/Options.td @@ -267,6 +267,14 @@ def output_file_map_EQ : Joined<["-"], "output-file-map=">, Flags<[NoInteractiveOption, ArgumentIsPath]>, Alias; +def pound_file : Separate<["-"], "pound-file">, + Flags<[FrontendOption]>, + HelpText<"Specifies whether '#file' evaluates to a full path or a compact human-readable string">, + MetaVarName<"compact|path">; +def pound_file_EQ : Joined<["-"], "pound-file=">, + Flags<[FrontendOption]>, + Alias; + def save_temps : Flag<["-"], "save-temps">, Flags<[NoInteractiveOption,DoesNotAffectIncrementalBuild]>, HelpText<"Save intermediate compilation results">; diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index a07d30dc7cebb..3e52f31ac6f9d 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -238,6 +238,7 @@ static void addCommonFrontendArgs(const ToolChain &TC, const OutputInfo &OI, inputArgs.AddLastArg(arguments, options::OPT_enable_astscope_lookup); inputArgs.AddLastArg(arguments, options::OPT_disable_astscope_lookup); inputArgs.AddLastArg(arguments, options::OPT_disable_parser_lookup); + inputArgs.AddLastArg(arguments, options::OPT_pound_file); // Pass on any build config options inputArgs.AddAllArgs(arguments, options::OPT_D); diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 879f670e1fe50..dad833fabe440 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -453,6 +453,17 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args, Opts.OptimizationRemarkMissedPattern = generateOptimizationRemarkRegex(Diags, Args, A); + if (Arg *A = Args.getLastArg(OPT_pound_file)) { + StringRef value = A->getValue(); + if (value == "path") + Opts.MagicFileIdentifierEvaluatesToPath = true; + else if (value == "compact") + Opts.MagicFileIdentifierEvaluatesToPath = false; + else + Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value, + A->getSpelling(), value); + } + llvm::Triple Target = Opts.Target; StringRef TargetArg; if (const Arg *A = Args.getLastArg(OPT_target)) { diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp index 3d812d4e59a16..3de13a0315daa 100644 --- a/lib/SILGen/SILGenApply.cpp +++ b/lib/SILGen/SILGenApply.cpp @@ -4881,7 +4881,7 @@ static std::string getMagicFileString(SILGenFunction &SGF, SourceLoc loc) { return ""; auto path = SGF.getASTContext().SourceMgr.getDisplayNameForLoc(loc); - if (false /* FIXME: Add a command line flag for this */) + if (SGF.getASTContext().LangOpts.MagicFileIdentifierEvaluatesToPath) return path; auto value = llvm::sys::path::filename(path).str(); From 44a2f67f4b832cbd614d4bb59d53085bd8b2eae0 Mon Sep 17 00:00:00 2001 From: Brent Royal-Gordon Date: Mon, 18 Nov 2019 19:01:37 -0800 Subject: [PATCH 4/6] Turn new #file behavior off by default --- include/swift/Basic/LangOptions.h | 2 +- .../implicit_return_never.swift | 2 +- test/PlaygroundTransform/placeholder.swift | 2 +- test/SILGen/magic_identifier_file.swift | 25 +++++++++++++++++++ 4 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 test/SILGen/magic_identifier_file.swift diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h index f768546813258..eb5eade35bb3a 100644 --- a/include/swift/Basic/LangOptions.h +++ b/include/swift/Basic/LangOptions.h @@ -96,7 +96,7 @@ namespace swift { /// If true, '#file' evaluates to the full path rather than a /// human-readable string. - bool MagicFileIdentifierEvaluatesToPath = false; + bool MagicFileIdentifierEvaluatesToPath = true; /// /// Support for alternate usage modes diff --git a/test/PlaygroundTransform/implicit_return_never.swift b/test/PlaygroundTransform/implicit_return_never.swift index d641b2ce87fef..dca3f752bd9ee 100644 --- a/test/PlaygroundTransform/implicit_return_never.swift +++ b/test/PlaygroundTransform/implicit_return_never.swift @@ -13,7 +13,7 @@ func f() -> Int { fatalError() -// CRASH-CHECK: {{[fF]}}atal error: file main.swift (main), line [[@LINE-1]] +// CRASH-CHECK: {{[fF]}}atal error: file {{.*}}/main.swift, line [[@LINE-1]] } f() diff --git a/test/PlaygroundTransform/placeholder.swift b/test/PlaygroundTransform/placeholder.swift index 4a4c6219f0275..734237ad1ef02 100644 --- a/test/PlaygroundTransform/placeholder.swift +++ b/test/PlaygroundTransform/placeholder.swift @@ -15,7 +15,7 @@ func f(crash crash: Bool) -> Int { if crash { return <#T#> - // CRASH-CHECK: {{[fF]}}atal error: attempt to evaluate editor placeholder: file main.swift (main), line [[@LINE-1]] + // CRASH-CHECK: {{[fF]}}atal error: attempt to evaluate editor placeholder: file {{.*}}/main.swift, line [[@LINE-1]] } else { return 42 } diff --git a/test/SILGen/magic_identifier_file.swift b/test/SILGen/magic_identifier_file.swift new file mode 100644 index 0000000000000..c1277f6e50009 --- /dev/null +++ b/test/SILGen/magic_identifier_file.swift @@ -0,0 +1,25 @@ +// RUN: %target-swift-emit-silgen -pound-file=path -module-name Foo %s | %FileCheck --check-prefixes=BOTH,PATH %s +// RUN: %target-swift-emit-silgen -pound-file=compact -module-name Foo %s | %FileCheck --check-prefixes=BOTH,COMPACT %s +// RUN: not %target-swift-emit-silgen -pound-file=zyzyx -module-name Foo %s 2>&1 | %FileCheck --check-prefix=ZYZYX %s + +// RUN: %target-swift-emit-silgen -pound-file path -module-name Foo %s | %FileCheck --check-prefixes=BOTH,PATH %s +// RUN: %target-swift-emit-silgen -pound-file compact -module-name Foo %s | %FileCheck --check-prefixes=BOTH,COMPACT %s +// RUN: not %target-swift-emit-silgen -pound-file zyzyx -module-name Foo %s 2>&1 | %FileCheck --check-prefix=ZYZYX %s + +// RUN: %target-swift-emit-silgen %s -module-name Foo | %FileCheck --check-prefixes=BOTH,COMPACT %s + +// ZYZYX: error: invalid value 'zyzyx' in '-pound-file' + +func directUse() { +// BOTH-LABEL: sil {{.*}} @$s3Foo9directUseyyF + print(#file) +// PATH: string_literal utf8 "SOURCE_DIR/test/SILGen/magic_identifier_file.swift" +// COMPACT: string_literal utf8 "magic_identifier_file.swift (Foo)" +} + +func indirectUse() { +// BOTH-LABEL: sil {{.*}} @$s3Foo11indirectUseyyF + fatalError() +// PATH: string_literal utf8 "SOURCE_DIR/test/SILGen/magic_identifier_file.swift" +// COMPACT: string_literal utf8 "magic_identifier_file.swift (Foo)" +} From 2acaf387c198955d8226e0ad6edcf2922df04a2a Mon Sep 17 00:00:00 2001 From: Brent Royal-Gordon Date: Tue, 19 Nov 2019 13:41:58 -0800 Subject: [PATCH 5/6] Flip default in test --- test/SILGen/magic_identifier_file.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/SILGen/magic_identifier_file.swift b/test/SILGen/magic_identifier_file.swift index c1277f6e50009..cb89bd876bacf 100644 --- a/test/SILGen/magic_identifier_file.swift +++ b/test/SILGen/magic_identifier_file.swift @@ -6,7 +6,7 @@ // RUN: %target-swift-emit-silgen -pound-file compact -module-name Foo %s | %FileCheck --check-prefixes=BOTH,COMPACT %s // RUN: not %target-swift-emit-silgen -pound-file zyzyx -module-name Foo %s 2>&1 | %FileCheck --check-prefix=ZYZYX %s -// RUN: %target-swift-emit-silgen %s -module-name Foo | %FileCheck --check-prefixes=BOTH,COMPACT %s +// RUN: %target-swift-emit-silgen %s -module-name Foo | %FileCheck --check-prefixes=BOTH,PATH %s // ZYZYX: error: invalid value 'zyzyx' in '-pound-file' From 63ec1cf5af226540e4856e15be376b8bd9c6f526 Mon Sep 17 00:00:00 2001 From: Brent Royal-Gordon Date: Thu, 21 Nov 2019 15:06:23 -0800 Subject: [PATCH 6/6] Introduce a separate #filePath, remove -pound-file This makes the path behavior more first-class. The feature is now hidden behind an experimental flag, -enable-experimental-concise-pound-file. --- include/swift/AST/DefaultArgumentKind.h | 2 ++ include/swift/AST/Expr.h | 3 ++- include/swift/Basic/LangOptions.h | 4 +-- include/swift/Option/Options.td | 13 ++++----- lib/AST/ASTDumper.cpp | 2 ++ lib/AST/Decl.cpp | 3 +++ lib/Driver/ToolChains.cpp | 3 ++- lib/Frontend/CompilerInvocation.cpp | 12 ++------- lib/IDE/CodeCompletion.cpp | 5 ++++ lib/Parse/ParseExpr.cpp | 12 +++++++++ lib/Parse/ParsePattern.cpp | 2 ++ lib/SILGen/SILGen.cpp | 1 + lib/SILGen/SILGenApply.cpp | 27 +++++++++++++++---- lib/SILGen/SILGenExpr.cpp | 1 + lib/Sema/CSApply.cpp | 1 + lib/Sema/CSGen.cpp | 1 + lib/Sema/TypeCheckExpr.cpp | 5 ++++ lib/Sema/TypeCheckStmt.cpp | 1 + lib/Sema/TypeChecker.cpp | 1 + lib/Serialization/Deserialization.cpp | 2 ++ lib/Serialization/ModuleFormat.h | 3 ++- lib/Serialization/Serialization.cpp | 1 + test/SILGen/magic_identifier_file.swift | 22 ++++++--------- test/SILGen/magic_identifier_filepath.swift | 26 ++++++++++++++++++ utils/gyb_syntax_support/ExprNodes.py | 6 +++++ .../NodeSerializationCodes.py | 1 + utils/gyb_syntax_support/Token.py | 2 ++ 27 files changed, 120 insertions(+), 42 deletions(-) create mode 100644 test/SILGen/magic_identifier_filepath.swift diff --git a/include/swift/AST/DefaultArgumentKind.h b/include/swift/AST/DefaultArgumentKind.h index a60b9101e931a..f687bb4426eac 100644 --- a/include/swift/AST/DefaultArgumentKind.h +++ b/include/swift/AST/DefaultArgumentKind.h @@ -38,6 +38,8 @@ enum class DefaultArgumentKind : uint8_t { Inherited, /// The #file default argument, which is expanded at the call site. File, + /// The #filePath default argument, which is expanded at the call site. + FilePath, /// The #line default argument, which is expanded at the call site. Line, /// The #column default argument, which is expanded at the call site. diff --git a/include/swift/AST/Expr.h b/include/swift/AST/Expr.h index 78cbaddb9c771..9fcddb0c066a8 100644 --- a/include/swift/AST/Expr.h +++ b/include/swift/AST/Expr.h @@ -1040,7 +1040,7 @@ class InterpolatedStringLiteralExpr : public LiteralExpr { class MagicIdentifierLiteralExpr : public LiteralExpr { public: enum Kind : unsigned { - File, Line, Column, Function, DSOHandle + File, FilePath, Line, Column, Function, DSOHandle }; private: SourceLoc Loc; @@ -1067,6 +1067,7 @@ class MagicIdentifierLiteralExpr : public LiteralExpr { bool isString() const { switch (getKind()) { case File: + case FilePath: case Function: return true; case Line: diff --git a/include/swift/Basic/LangOptions.h b/include/swift/Basic/LangOptions.h index eb5eade35bb3a..8d24bd41d831b 100644 --- a/include/swift/Basic/LangOptions.h +++ b/include/swift/Basic/LangOptions.h @@ -94,9 +94,9 @@ namespace swift { /// when using RequireExplicitAvailability. std::string RequireExplicitAvailabilityTarget; - /// If true, '#file' evaluates to the full path rather than a + /// If false, '#file' evaluates to the full path rather than a /// human-readable string. - bool MagicFileIdentifierEvaluatesToPath = true; + bool EnableConcisePoundFile = false; /// /// Support for alternate usage modes diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td index eb1fbd8bb333e..c6d9718a52f39 100644 --- a/include/swift/Option/Options.td +++ b/include/swift/Option/Options.td @@ -267,14 +267,6 @@ def output_file_map_EQ : Joined<["-"], "output-file-map=">, Flags<[NoInteractiveOption, ArgumentIsPath]>, Alias; -def pound_file : Separate<["-"], "pound-file">, - Flags<[FrontendOption]>, - HelpText<"Specifies whether '#file' evaluates to a full path or a compact human-readable string">, - MetaVarName<"compact|path">; -def pound_file_EQ : Joined<["-"], "pound-file=">, - Flags<[FrontendOption]>, - Alias; - def save_temps : Flag<["-"], "save-temps">, Flags<[NoInteractiveOption,DoesNotAffectIncrementalBuild]>, HelpText<"Save intermediate compilation results">; @@ -462,6 +454,11 @@ def enable_experimental_differentiable_programming : Flag<["-"], "enable-experim Flags<[FrontendOption]>, HelpText<"Enable experimental differentiable programming features">; +def enable_experimental_concise_pound_file : Flag<["-"], + "enable-experimental-concise-pound-file">, + Flags<[FrontendOption]>, + HelpText<"Enable experimental concise '#file' identifier and '#filePath' alternative">; + // Diagnostic control options def suppress_warnings : Flag<["-"], "suppress-warnings">, Flags<[FrontendOption]>, diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index d918e3406fe6d..bec37a1a045e4 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -300,6 +300,7 @@ static StringRef getDefaultArgumentKindString(DefaultArgumentKind value) { case DefaultArgumentKind::Column: return "#column"; case DefaultArgumentKind::DSOHandle: return "#dsohandle"; case DefaultArgumentKind::File: return "#file"; + case DefaultArgumentKind::FilePath: return "#filePath"; case DefaultArgumentKind::Function: return "#function"; case DefaultArgumentKind::Inherited: return "inherited"; case DefaultArgumentKind::Line: return "#line"; @@ -316,6 +317,7 @@ static StringRef getMagicIdentifierLiteralExprKindString(MagicIdentifierLiteralExpr::Kind value) { switch (value) { case MagicIdentifierLiteralExpr::File: return "#file"; + case MagicIdentifierLiteralExpr::FilePath: return "#filePath"; case MagicIdentifierLiteralExpr::Function: return "#function"; case MagicIdentifierLiteralExpr::Line: return "#line"; case MagicIdentifierLiteralExpr::Column: return "#column"; diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index c6e634f724552..95c8bc0942d90 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -6083,6 +6083,7 @@ bool ParamDecl::hasDefaultExpr() const { return false; case DefaultArgumentKind::Normal: case DefaultArgumentKind::File: + case DefaultArgumentKind::FilePath: case DefaultArgumentKind::Line: case DefaultArgumentKind::Column: case DefaultArgumentKind::Function: @@ -6105,6 +6106,7 @@ bool ParamDecl::hasCallerSideDefaultExpr() const { case DefaultArgumentKind::Normal: return false; case DefaultArgumentKind::File: + case DefaultArgumentKind::FilePath: case DefaultArgumentKind::Line: case DefaultArgumentKind::Column: case DefaultArgumentKind::Function: @@ -6414,6 +6416,7 @@ ParamDecl::getDefaultValueStringRepresentation( } case DefaultArgumentKind::Inherited: return "super"; case DefaultArgumentKind::File: return "#file"; + case DefaultArgumentKind::FilePath: return "#filePath"; case DefaultArgumentKind::Line: return "#line"; case DefaultArgumentKind::Column: return "#column"; case DefaultArgumentKind::Function: return "#function"; diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 3e52f31ac6f9d..945ae5e4586d2 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -238,7 +238,8 @@ static void addCommonFrontendArgs(const ToolChain &TC, const OutputInfo &OI, inputArgs.AddLastArg(arguments, options::OPT_enable_astscope_lookup); inputArgs.AddLastArg(arguments, options::OPT_disable_astscope_lookup); inputArgs.AddLastArg(arguments, options::OPT_disable_parser_lookup); - inputArgs.AddLastArg(arguments, options::OPT_pound_file); + inputArgs.AddLastArg(arguments, + options::OPT_enable_experimental_concise_pound_file); // Pass on any build config options inputArgs.AddAllArgs(arguments, options::OPT_D); diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index dad833fabe440..7c3188f0dc168 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -453,16 +453,8 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args, Opts.OptimizationRemarkMissedPattern = generateOptimizationRemarkRegex(Diags, Args, A); - if (Arg *A = Args.getLastArg(OPT_pound_file)) { - StringRef value = A->getValue(); - if (value == "path") - Opts.MagicFileIdentifierEvaluatesToPath = true; - else if (value == "compact") - Opts.MagicFileIdentifierEvaluatesToPath = false; - else - Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value, - A->getSpelling(), value); - } + Opts.EnableConcisePoundFile = + Args.hasArg(OPT_enable_experimental_concise_pound_file); llvm::Triple Target = Opts.Target; StringRef TargetArg; diff --git a/lib/IDE/CodeCompletion.cpp b/lib/IDE/CodeCompletion.cpp index 28dfe3598b4a3..355326f5b8a1c 100644 --- a/lib/IDE/CodeCompletion.cpp +++ b/lib/IDE/CodeCompletion.cpp @@ -2244,6 +2244,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer { return !includeDefaultArgs; case DefaultArgumentKind::File: + case DefaultArgumentKind::FilePath: case DefaultArgumentKind::Line: case DefaultArgumentKind::Column: case DefaultArgumentKind::Function: @@ -3653,6 +3654,10 @@ class CompletionLookup final : public swift::VisibleDeclConsumer { CodeCompletionLiteralKind::StringLiteral, "String"); addFromProto("#file", CodeCompletionKeywordKind::pound_file, CodeCompletionLiteralKind::StringLiteral, "String"); + if (Ctx.LangOpts.EnableConcisePoundFile) { + addFromProto("#filePath", CodeCompletionKeywordKind::pound_file, + CodeCompletionLiteralKind::StringLiteral, "String"); + } addFromProto("#line", CodeCompletionKeywordKind::pound_line, CodeCompletionLiteralKind::IntegerLiteral, "Int"); addFromProto("#column", CodeCompletionKeywordKind::pound_column, diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index d8ce5c140fc64..58592287d021b 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -1014,6 +1014,8 @@ getMagicIdentifierLiteralKind(tok Kind) { case tok::kw___FILE__: case tok::pound_file: return MagicIdentifierLiteralExpr::Kind::File; + case tok::pound_filePath: + return MagicIdentifierLiteralExpr::Kind::FilePath; case tok::kw___FUNCTION__: case tok::pound_function: return MagicIdentifierLiteralExpr::Kind::Function; @@ -1446,6 +1448,15 @@ ParserResult Parser::parseExprPrimary(Diag<> ID, bool isExprBasic) { .fixItReplace(Tok.getLoc(), replacement); LLVM_FALLTHROUGH; } + + case tok::pound_filePath: + // Check twice because of fallthrough--this is ugly but temporary. + if (Tok.is(tok::pound_filePath) && !Context.LangOpts.EnableConcisePoundFile) + diagnose(Tok.getLoc(), diag::unknown_pound_expr, "filePath"); + // Continue since we actually do know how to handle it. This avoids extra + // diagnostics. + LLVM_FALLTHROUGH; + case tok::pound_column: case tok::pound_file: case tok::pound_function: @@ -1455,6 +1466,7 @@ ParserResult Parser::parseExprPrimary(Diag<> ID, bool isExprBasic) { switch (Tok.getKind()) { case tok::pound_column: SKind = SyntaxKind::PoundColumnExpr; break; case tok::pound_file: SKind = SyntaxKind::PoundFileExpr; break; + case tok::pound_filePath: SKind = SyntaxKind::PoundFilePathExpr; break; case tok::pound_function: SKind = SyntaxKind::PoundFunctionExpr; break; // FIXME: #line was renamed to #sourceLocation case tok::pound_line: SKind = SyntaxKind::PoundLineExpr; break; diff --git a/lib/Parse/ParsePattern.cpp b/lib/Parse/ParsePattern.cpp index d0cd5536ee1ce..89a70cf3d5082 100644 --- a/lib/Parse/ParsePattern.cpp +++ b/lib/Parse/ParsePattern.cpp @@ -48,6 +48,8 @@ static DefaultArgumentKind getDefaultArgKind(Expr *init) { return DefaultArgumentKind::Column; case MagicIdentifierLiteralExpr::File: return DefaultArgumentKind::File; + case MagicIdentifierLiteralExpr::FilePath: + return DefaultArgumentKind::FilePath; case MagicIdentifierLiteralExpr::Line: return DefaultArgumentKind::Line; case MagicIdentifierLiteralExpr::Function: diff --git a/lib/SILGen/SILGen.cpp b/lib/SILGen/SILGen.cpp index c61711255a40c..64a337a26d021 100644 --- a/lib/SILGen/SILGen.cpp +++ b/lib/SILGen/SILGen.cpp @@ -1090,6 +1090,7 @@ void SILGenModule::emitDefaultArgGenerator(SILDeclRef constant, case DefaultArgumentKind::Inherited: case DefaultArgumentKind::Column: case DefaultArgumentKind::File: + case DefaultArgumentKind::FilePath: case DefaultArgumentKind::Line: case DefaultArgumentKind::Function: case DefaultArgumentKind::DSOHandle: diff --git a/lib/SILGen/SILGenApply.cpp b/lib/SILGen/SILGenApply.cpp index 3de13a0315daa..44d001c10f1bf 100644 --- a/lib/SILGen/SILGenApply.cpp +++ b/lib/SILGen/SILGenApply.cpp @@ -4876,14 +4876,20 @@ getMagicFunctionString(SILGenFunction &SGF) { return SGF.MagicFunctionString; } -static std::string getMagicFileString(SILGenFunction &SGF, SourceLoc loc) { +static StringRef +getMagicFilePathString(SILGenFunction &SGF, SourceLoc loc) { if (!loc.isValid()) return ""; - auto path = SGF.getASTContext().SourceMgr.getDisplayNameForLoc(loc); - if (SGF.getASTContext().LangOpts.MagicFileIdentifierEvaluatesToPath) - return path; + return SGF.getASTContext().SourceMgr.getDisplayNameForLoc(loc); +} + +static std::string +getConciseMagicFileString(SILGenFunction &SGF, SourceLoc loc) { + if (!loc.isValid()) + return ""; + auto path = getMagicFilePathString(SGF, loc); auto value = llvm::sys::path::filename(path).str(); value += " ("; value += SGF.getModule().getSwiftModule()->getNameStr(); @@ -5146,7 +5152,18 @@ RValue SILGenFunction::emitLiteral(LiteralExpr *literal, SGFContext C) { auto magicLiteral = cast(literal); switch (magicLiteral->getKind()) { case MagicIdentifierLiteralExpr::File: { - std::string value = getMagicFileString(*this, loc); + std::string value = getASTContext().LangOpts.EnableConcisePoundFile + ? getConciseMagicFileString(*this, loc) + : getMagicFilePathString(*this, loc).str(); + builtinLiteralArgs = emitStringLiteral(*this, literal, value, C, + magicLiteral->getStringEncoding()); + builtinInit = magicLiteral->getBuiltinInitializer(); + init = magicLiteral->getInitializer(); + break; + } + + case MagicIdentifierLiteralExpr::FilePath: { + StringRef value = getMagicFilePathString(*this, loc); builtinLiteralArgs = emitStringLiteral(*this, literal, value, C, magicLiteral->getStringEncoding()); builtinInit = magicLiteral->getBuiltinInitializer(); diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp index 99cde2d3e0e6a..83711be6d8ae9 100644 --- a/lib/SILGen/SILGenExpr.cpp +++ b/lib/SILGen/SILGenExpr.cpp @@ -3681,6 +3681,7 @@ RValue RValueEmitter:: visitMagicIdentifierLiteralExpr(MagicIdentifierLiteralExpr *E, SGFContext C) { switch (E->getKind()) { case MagicIdentifierLiteralExpr::File: + case MagicIdentifierLiteralExpr::FilePath: case MagicIdentifierLiteralExpr::Function: case MagicIdentifierLiteralExpr::Line: case MagicIdentifierLiteralExpr::Column: diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp index f411bc6105fe2..2efc2f5d60dc0 100644 --- a/lib/Sema/CSApply.cpp +++ b/lib/Sema/CSApply.cpp @@ -2157,6 +2157,7 @@ namespace { Expr *visitMagicIdentifierLiteralExpr(MagicIdentifierLiteralExpr *expr) { switch (expr->getKind()) { case MagicIdentifierLiteralExpr::File: + case MagicIdentifierLiteralExpr::FilePath: case MagicIdentifierLiteralExpr::Function: return handleStringLiteralExpr(expr); diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp index 2ff2bee03e517..c7d45a660a49d 100644 --- a/lib/Sema/CSGen.cpp +++ b/lib/Sema/CSGen.cpp @@ -1243,6 +1243,7 @@ namespace { switch (expr->getKind()) { case MagicIdentifierLiteralExpr::Column: case MagicIdentifierLiteralExpr::File: + case MagicIdentifierLiteralExpr::FilePath: case MagicIdentifierLiteralExpr::Function: case MagicIdentifierLiteralExpr::Line: return visitLiteralExpr(expr); diff --git a/lib/Sema/TypeCheckExpr.cpp b/lib/Sema/TypeCheckExpr.cpp index 363734188e12f..699f31c96e278 100644 --- a/lib/Sema/TypeCheckExpr.cpp +++ b/lib/Sema/TypeCheckExpr.cpp @@ -730,6 +730,11 @@ static Expr *synthesizeCallerSideDefault(const ParamDecl *param, MagicIdentifierLiteralExpr(MagicIdentifierLiteralExpr::File, loc, /*implicit=*/true); + case DefaultArgumentKind::FilePath: + return new (ctx) + MagicIdentifierLiteralExpr(MagicIdentifierLiteralExpr::FilePath, loc, + /*implicit=*/true); + case DefaultArgumentKind::Line: return new (ctx) MagicIdentifierLiteralExpr(MagicIdentifierLiteralExpr::Line, loc, diff --git a/lib/Sema/TypeCheckStmt.cpp b/lib/Sema/TypeCheckStmt.cpp index 61d70b4f17e2a..7695a180a8378 100644 --- a/lib/Sema/TypeCheckStmt.cpp +++ b/lib/Sema/TypeCheckStmt.cpp @@ -1531,6 +1531,7 @@ static void diagnoseIgnoredLiteral(ASTContext &Ctx, LiteralExpr *LE) { case ExprKind::MagicIdentifierLiteral: switch (cast(LE)->getKind()) { case MagicIdentifierLiteralExpr::Kind::File: return "#file"; + case MagicIdentifierLiteralExpr::Kind::FilePath: return "#filePath"; case MagicIdentifierLiteralExpr::Kind::Line: return "#line"; case MagicIdentifierLiteralExpr::Kind::Column: return "#column"; case MagicIdentifierLiteralExpr::Kind::Function: return "#function"; diff --git a/lib/Sema/TypeChecker.cpp b/lib/Sema/TypeChecker.cpp index 46fe5d847ef81..21ee5fca83e43 100644 --- a/lib/Sema/TypeChecker.cpp +++ b/lib/Sema/TypeChecker.cpp @@ -131,6 +131,7 @@ ProtocolDecl *TypeChecker::getLiteralProtocol(ASTContext &Context, Expr *expr) { if (auto E = dyn_cast(expr)) { switch (E->getKind()) { case MagicIdentifierLiteralExpr::File: + case MagicIdentifierLiteralExpr::FilePath: case MagicIdentifierLiteralExpr::Function: return TypeChecker::getProtocol( Context, expr->getLoc(), diff --git a/lib/Serialization/Deserialization.cpp b/lib/Serialization/Deserialization.cpp index e9272b23dc0eb..e6f211a22a2c7 100644 --- a/lib/Serialization/Deserialization.cpp +++ b/lib/Serialization/Deserialization.cpp @@ -207,6 +207,8 @@ getActualDefaultArgKind(uint8_t raw) { return swift::DefaultArgumentKind::Column; case serialization::DefaultArgumentKind::File: return swift::DefaultArgumentKind::File; + case serialization::DefaultArgumentKind::FilePath: + return swift::DefaultArgumentKind::FilePath; case serialization::DefaultArgumentKind::Line: return swift::DefaultArgumentKind::Line; case serialization::DefaultArgumentKind::Function: diff --git a/lib/Serialization/ModuleFormat.h b/lib/Serialization/ModuleFormat.h index 9176636a29cc6..27636695f690c 100644 --- a/lib/Serialization/ModuleFormat.h +++ b/lib/Serialization/ModuleFormat.h @@ -52,7 +52,7 @@ const uint16_t SWIFTMODULE_VERSION_MAJOR = 0; /// describe what change you made. The content of this comment isn't important; /// it just ensures a conflict if two people change the module format. /// Don't worry about adhering to the 80-column limit for this line. -const uint16_t SWIFTMODULE_VERSION_MINOR = 526; // @_dynamicReplacement adjustments +const uint16_t SWIFTMODULE_VERSION_MINOR = 527; // #filePath /// A standard hash seed used for all string hashes in a serialized module. /// @@ -437,6 +437,7 @@ enum class DefaultArgumentKind : uint8_t { None = 0, Normal, File, + FilePath, Line, Column, Function, diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index c2d07ba6d5c08..837fbabc0d0ed 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -1065,6 +1065,7 @@ static uint8_t getRawStableDefaultArgumentKind(swift::DefaultArgumentKind kind) CASE(Inherited) CASE(Column) CASE(File) + CASE(FilePath) CASE(Line) CASE(Function) CASE(DSOHandle) diff --git a/test/SILGen/magic_identifier_file.swift b/test/SILGen/magic_identifier_file.swift index cb89bd876bacf..f2cfeecfc73d4 100644 --- a/test/SILGen/magic_identifier_file.swift +++ b/test/SILGen/magic_identifier_file.swift @@ -1,25 +1,19 @@ -// RUN: %target-swift-emit-silgen -pound-file=path -module-name Foo %s | %FileCheck --check-prefixes=BOTH,PATH %s -// RUN: %target-swift-emit-silgen -pound-file=compact -module-name Foo %s | %FileCheck --check-prefixes=BOTH,COMPACT %s -// RUN: not %target-swift-emit-silgen -pound-file=zyzyx -module-name Foo %s 2>&1 | %FileCheck --check-prefix=ZYZYX %s +// RUN: %target-swift-emit-silgen -module-name Foo %s | %FileCheck --check-prefixes=BOTH,ABSOLUTE %s +// RUN: %target-swift-emit-silgen -enable-experimental-concise-pound-file -DNEEDS_CONCISE -module-name Foo %s | %FileCheck --check-prefixes=BOTH,CONCISE %s -// RUN: %target-swift-emit-silgen -pound-file path -module-name Foo %s | %FileCheck --check-prefixes=BOTH,PATH %s -// RUN: %target-swift-emit-silgen -pound-file compact -module-name Foo %s | %FileCheck --check-prefixes=BOTH,COMPACT %s -// RUN: not %target-swift-emit-silgen -pound-file zyzyx -module-name Foo %s 2>&1 | %FileCheck --check-prefix=ZYZYX %s - -// RUN: %target-swift-emit-silgen %s -module-name Foo | %FileCheck --check-prefixes=BOTH,PATH %s - -// ZYZYX: error: invalid value 'zyzyx' in '-pound-file' +// FIXME: Once this feature becomes non-experimental, we should update existing +// tests and delete this file. func directUse() { // BOTH-LABEL: sil {{.*}} @$s3Foo9directUseyyF print(#file) -// PATH: string_literal utf8 "SOURCE_DIR/test/SILGen/magic_identifier_file.swift" -// COMPACT: string_literal utf8 "magic_identifier_file.swift (Foo)" +// ABSOLUTE: string_literal utf8 "SOURCE_DIR/test/SILGen/magic_identifier_file.swift" +// CONCISE: string_literal utf8 "magic_identifier_file.swift (Foo)" } func indirectUse() { // BOTH-LABEL: sil {{.*}} @$s3Foo11indirectUseyyF fatalError() -// PATH: string_literal utf8 "SOURCE_DIR/test/SILGen/magic_identifier_file.swift" -// COMPACT: string_literal utf8 "magic_identifier_file.swift (Foo)" +// ABSOLUTE: string_literal utf8 "SOURCE_DIR/test/SILGen/magic_identifier_file.swift" +// CONCISE: string_literal utf8 "magic_identifier_file.swift (Foo)" } diff --git a/test/SILGen/magic_identifier_filepath.swift b/test/SILGen/magic_identifier_filepath.swift new file mode 100644 index 0000000000000..3a407b0da9f0a --- /dev/null +++ b/test/SILGen/magic_identifier_filepath.swift @@ -0,0 +1,26 @@ +// Check that we generate the right code with the flag. +// RUN: %target-swift-emit-silgen -enable-experimental-concise-pound-file -module-name Foo %s | %FileCheck %s + +// Check that we give errors for use of #filePath if concise #file isn't enabled. +// FIXME: Drop if we stop rejecting this. +// RUN: %target-typecheck-verify-swift -module-name Foo %s + +// FIXME: Once this feature becomes non-experimental, we should duplicate +// existing #file tests and delete this file. + +func directUse() { + print(#filePath) // expected-error {{use of unknown directive '#filePath'}} + +// CHECK-LABEL: sil {{.*}} @$s3Foo9directUseyyF +// CHECK: string_literal utf8 "SOURCE_DIR/test/SILGen/magic_identifier_filepath.swift" +} + +func indirectUse() { + functionWithFilePathDefaultArgument() + +// CHECK-LABEL: sil {{.*}} @$s3Foo11indirectUseyyF +// CHECK: string_literal utf8 "SOURCE_DIR/test/SILGen/magic_identifier_filepath.swift" +} + +func functionWithFilePathDefaultArgument(file: String = #filePath) {} +// expected-error@-1 {{use of unknown directive '#filePath'}} diff --git a/utils/gyb_syntax_support/ExprNodes.py b/utils/gyb_syntax_support/ExprNodes.py index 208194499cbe8..8f9835970008f 100644 --- a/utils/gyb_syntax_support/ExprNodes.py +++ b/utils/gyb_syntax_support/ExprNodes.py @@ -130,6 +130,12 @@ Child('PoundFile', kind='PoundFileToken'), ]), + # A #filePath expression. + Node('PoundFilePathExpr', kind='Expr', + children=[ + Child('PoundFilePath', kind='PoundFilePathToken'), + ]), + # A #function expression. Node('PoundFunctionExpr', kind='Expr', children=[ diff --git a/utils/gyb_syntax_support/NodeSerializationCodes.py b/utils/gyb_syntax_support/NodeSerializationCodes.py index 748f089bd1d36..04df2153cd083 100644 --- a/utils/gyb_syntax_support/NodeSerializationCodes.py +++ b/utils/gyb_syntax_support/NodeSerializationCodes.py @@ -241,6 +241,7 @@ 'DifferentiationParam': 237, 'DifferentiableAttributeFuncSpecifier': 238, 'FunctionDeclName': 239, + 'PoundFilePathExpr': 240, } diff --git a/utils/gyb_syntax_support/Token.py b/utils/gyb_syntax_support/Token.py index 3e116471bcaa4..aaacc4fcfeb33 100644 --- a/utils/gyb_syntax_support/Token.py +++ b/utils/gyb_syntax_support/Token.py @@ -265,6 +265,8 @@ def macro_name(self): serialization_code=73), PoundKeyword('PoundFile', 'file', text='#file', serialization_code=68), + PoundKeyword('PoundFilePath', 'filePath', text='#filePath', + serialization_code=121), PoundKeyword('PoundColumn', 'column', text='#column', serialization_code=70), PoundKeyword('PoundFunction', 'function', text='#function',