Skip to content

Commit 8ae6507

Browse files
authored
Merge pull request #58871 from artemcm/57-04182022ParseableFixes
[5.7-04182022][Parseable Output] Compute file extensions using full extension strings & emit output in WMO
2 parents 4148ef1 + 1186973 commit 8ae6507

File tree

3 files changed

+117
-47
lines changed

3 files changed

+117
-47
lines changed

lib/FrontendTool/FrontendTool.cpp

Lines changed: 90 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -588,9 +588,32 @@ mapFrontendInvocationToAction(const CompilerInvocation &Invocation) {
588588
// StaticLinkJob, DynamicLinkJob
589589
}
590590

591+
// TODO: Apply elsewhere in the compiler
592+
static swift::file_types::ID computeFileTypeForPath(const StringRef Path) {
593+
if (!llvm::sys::path::has_extension(Path))
594+
return swift::file_types::ID::TY_INVALID;
595+
596+
auto Extension = llvm::sys::path::extension(Path).str();
597+
auto FileType = file_types::lookupTypeForExtension(Extension);
598+
if (FileType == swift::file_types::ID::TY_INVALID) {
599+
auto PathStem = llvm::sys::path::stem(Path);
600+
// If this path has a multiple '.' extension (e.g. .abi.json),
601+
// then iterate over all preceeding possible extension variants.
602+
while (llvm::sys::path::has_extension(PathStem)) {
603+
auto NextExtension = llvm::sys::path::extension(PathStem);
604+
Extension = NextExtension.str() + Extension;
605+
FileType = file_types::lookupTypeForExtension(Extension);
606+
if (FileType != swift::file_types::ID::TY_INVALID)
607+
break;
608+
}
609+
}
610+
611+
return FileType;
612+
}
613+
591614
static DetailedTaskDescription
592615
constructDetailedTaskDescription(const CompilerInvocation &Invocation,
593-
const InputFile &PrimaryInput,
616+
ArrayRef<InputFile> PrimaryInputs,
594617
ArrayRef<const char *> Args) {
595618
// Command line and arguments
596619
std::string Executable = Invocation.getFrontendOptions().MainExecutablePath;
@@ -604,24 +627,25 @@ constructDetailedTaskDescription(const CompilerInvocation &Invocation,
604627
CommandLine += std::string(" ") + A;
605628
}
606629

607-
// Primary Input only
608-
Inputs.push_back(CommandInput(PrimaryInput.getFileName()));
630+
// Primary Inputs
631+
for (const auto &input : PrimaryInputs) {
632+
Inputs.push_back(CommandInput(input.getFileName()));
633+
}
609634

610-
// Output for this Primary
611-
auto OutputFile = PrimaryInput.outputFilename();
612-
Outputs.push_back(OutputPair(file_types::lookupTypeForExtension(
613-
llvm::sys::path::extension(OutputFile)),
614-
OutputFile));
635+
for (const auto &input : PrimaryInputs) {
636+
// Main outputs
637+
auto OutputFile = input.outputFilename();
638+
if (!OutputFile.empty())
639+
Outputs.push_back(OutputPair(computeFileTypeForPath(OutputFile), OutputFile));
615640

616-
// Supplementary outputs
617-
const auto &primarySpecificFiles = PrimaryInput.getPrimarySpecificPaths();
618-
const auto &supplementaryOutputPaths =
619-
primarySpecificFiles.SupplementaryOutputs;
620-
supplementaryOutputPaths.forEachSetOutput([&](const std::string &output) {
621-
Outputs.push_back(OutputPair(
622-
file_types::lookupTypeForExtension(llvm::sys::path::extension(output)),
623-
output));
624-
});
641+
// Supplementary outputs
642+
const auto &primarySpecificFiles = input.getPrimarySpecificPaths();
643+
const auto &supplementaryOutputPaths =
644+
primarySpecificFiles.SupplementaryOutputs;
645+
supplementaryOutputPaths.forEachSetOutput([&](const std::string &output) {
646+
Outputs.push_back(OutputPair(computeFileTypeForPath(output), output));
647+
});
648+
}
625649
return DetailedTaskDescription{Executable, Arguments, CommandLine, Inputs,
626650
Outputs};
627651
}
@@ -2125,15 +2149,26 @@ int swift::performFrontend(ArrayRef<const char *> Args,
21252149
// making sure it cannot collide with a real PID (always positive). Non-batch
21262150
// compilation gets a real OS PID.
21272151
int64_t Pid = IO.hasUniquePrimaryInput() ? OSPid : QUASI_PID_START;
2128-
IO.forEachPrimaryInputWithIndex([&](const InputFile &Input,
2129-
unsigned idx) -> bool {
2130-
emitBeganMessage(
2131-
llvm::errs(),
2132-
mapFrontendInvocationToAction(Invocation),
2133-
constructDetailedTaskDescription(Invocation, Input, Args), Pid - idx,
2134-
ProcInfo);
2135-
return false;
2136-
});
2152+
2153+
if (IO.hasPrimaryInputs()) {
2154+
IO.forEachPrimaryInputWithIndex([&](const InputFile &Input,
2155+
unsigned idx) -> bool {
2156+
ArrayRef<InputFile> Inputs(Input);
2157+
emitBeganMessage(llvm::errs(),
2158+
mapFrontendInvocationToAction(Invocation),
2159+
constructDetailedTaskDescription(Invocation,
2160+
Inputs,
2161+
Args), Pid - idx,
2162+
ProcInfo);
2163+
return false;
2164+
});
2165+
} else {
2166+
// If no primary inputs are present, we are in WMO.
2167+
emitBeganMessage(llvm::errs(),
2168+
mapFrontendInvocationToAction(Invocation),
2169+
constructDetailedTaskDescription(Invocation, IO.getAllInputs(), Args),
2170+
OSPid, ProcInfo);
2171+
}
21372172
}
21382173

21392174
int ReturnValue = 0;
@@ -2164,23 +2199,41 @@ int swift::performFrontend(ArrayRef<const char *> Args,
21642199
// making sure it cannot collide with a real PID (always positive). Non-batch
21652200
// compilation gets a real OS PID.
21662201
int64_t Pid = IO.hasUniquePrimaryInput() ? OSPid : QUASI_PID_START;
2167-
IO.forEachPrimaryInputWithIndex([&](const InputFile &Input,
2168-
unsigned idx) -> bool {
2169-
assert(FileSpecificDiagnostics.count(Input.getFileName()) != 0 &&
2170-
"Expected diagnostic collection for input.");
21712202

2172-
// Join all diagnostics produced for this file into a single output.
2173-
auto PrimaryDiags = FileSpecificDiagnostics.lookup(Input.getFileName());
2203+
if (IO.hasPrimaryInputs()) {
2204+
IO.forEachPrimaryInputWithIndex([&](const InputFile &Input,
2205+
unsigned idx) -> bool {
2206+
assert(FileSpecificDiagnostics.count(Input.getFileName()) != 0 &&
2207+
"Expected diagnostic collection for input.");
2208+
2209+
// Join all diagnostics produced for this file into a single output.
2210+
auto PrimaryDiags = FileSpecificDiagnostics.lookup(Input.getFileName());
2211+
const char *const Delim = "";
2212+
std::ostringstream JoinedDiags;
2213+
std::copy(PrimaryDiags.begin(), PrimaryDiags.end(),
2214+
std::ostream_iterator<std::string>(JoinedDiags, Delim));
2215+
2216+
emitFinishedMessage(llvm::errs(),
2217+
mapFrontendInvocationToAction(Invocation),
2218+
JoinedDiags.str(), r, Pid - idx, ProcInfo);
2219+
return false;
2220+
});
2221+
} else {
2222+
// If no primary inputs are present, we are in WMO.
2223+
std::vector<std::string> AllDiagnostics;
2224+
for (const auto &FileDiagnostics : FileSpecificDiagnostics) {
2225+
AllDiagnostics.insert(AllDiagnostics.end(),
2226+
FileDiagnostics.getValue().begin(),
2227+
FileDiagnostics.getValue().end());
2228+
}
21742229
const char *const Delim = "";
21752230
std::ostringstream JoinedDiags;
2176-
std::copy(PrimaryDiags.begin(), PrimaryDiags.end(),
2231+
std::copy(AllDiagnostics.begin(), AllDiagnostics.end(),
21772232
std::ostream_iterator<std::string>(JoinedDiags, Delim));
2178-
21792233
emitFinishedMessage(llvm::errs(),
21802234
mapFrontendInvocationToAction(Invocation),
2181-
JoinedDiags.str(), r, Pid - idx, ProcInfo);
2182-
return false;
2183-
});
2235+
JoinedDiags.str(), r, OSPid, ProcInfo);
2236+
}
21842237
}
21852238

21862239
return r;

test/Frontend/parseable_output.swift

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,48 @@
1-
// RUN: %target-swift-frontend -primary-file %s -o %t.out -emit-module -emit-module-path %t.swiftmodule -frontend-parseable-output 2>&1 | %FileCheck %s
1+
// RUN: %target-swift-frontend -primary-file %s %S/Inputs/filelist-other.swift -o %t.out -module-name parseable_output -empty-abi-descriptor -emit-abi-descriptor-path %t.abi.json -emit-module -emit-module-path %t.swiftmodule -serialize-diagnostics -serialize-diagnostics-path %t.dia -frontend-parseable-output 2>&1 | %FileCheck %s
2+
// Check without primary files (WMO):
3+
// RUN: %target-swift-frontend %s %S/Inputs/filelist-other.swift -o %t.out -module-name parseable_output -empty-abi-descriptor -emit-abi-descriptor-path %t.abi.json -emit-module -emit-module-path %t.swiftmodule -serialize-diagnostics -serialize-diagnostics-path %t.dia -frontend-parseable-output 2>&1 | %FileCheck %s
24

35
// CHECK: {{[1-9][0-9]*}}
46
// CHECK-NEXT: {
57
// CHECK-NEXT: "kind": "began",
68
// CHECK-NEXT: "name": "compile",
7-
// CHECK-NEXT: "command": "{{.*[\\/]}}swift-frontend{{(\.exe)?}}{{.*}}-primary-file {{.*[\\/]}}parseable_output.swift -o {{.*[\\/]}}parseable_output.swift.tmp.out -emit-module -emit-module-path {{.*[\\/]}}parseable_output.swift.tmp.swiftmodule -frontend-parseable-output",
9+
// CHECK-NEXT: "command": "{{.*[\\/]}}swift-frontend{{(\.exe)?}}{{.*}} {{.*[\\/]}}parseable_output.swift {{.*[\\/]}}filelist-other.swift -o {{.*[\\/]}}parseable_output.swift.tmp.out -module-name parseable_output -empty-abi-descriptor -emit-abi-descriptor-path {{.*[\\/]}}parseable_output.swift.tmp.abi.json -emit-module -emit-module-path {{.*[\\/]}}parseable_output.swift.tmp.swiftmodule -serialize-diagnostics -serialize-diagnostics-path {{.*[\\/]}}parseable_output.swift.tmp.dia -frontend-parseable-output",
810
// CHECK-NEXT: "command_executable": "{{.*[\\/]}}swift{{(-frontend|c)?(\.exe)?}}",
911
// CHECK-NEXT: "command_arguments": [
10-
// CHECK: "-primary-file",
11-
// CHECK-NEXT: "{{.*[\\/]}}parseable_output.swift",
12+
// CHECK: "{{.*[\\/]}}parseable_output.swift",
1213
// CHECK: "-o",
1314
// CHECK-NEXT: "{{.*[\\/]}}parseable_output.swift.tmp.out",
15+
// CHECK-NEXT: "-module-name",
16+
// CHECK-NEXT: "parseable_output",
17+
// CHECK-NEXT: "-empty-abi-descriptor",
18+
// CHECK-NEXT: "-emit-abi-descriptor-path",
19+
// CHECK-NEXT: "{{.*[\\/]}}parseable_output.swift.tmp.abi.json",
1420
// CHECK-NEXT: "-emit-module",
1521
// CHECK-NEXT: "-emit-module-path",
1622
// CHECK-NEXT: "{{.*[\\/]}}parseable_output.swift.tmp.swiftmodule",
23+
// CHECK-NEXT: "-serialize-diagnostics",
24+
// CHECK-NEXT: "-serialize-diagnostics-path"
25+
// CHECK-NEXT: "{{.*[\\/]}}parseable_output.swift.tmp.dia",
1726
// CHECK-NEXT: "-frontend-parseable-output"
1827
// CHECK-NEXT: ],
1928
// CHECK-NEXT: "inputs": [
2029
// CHECK-NEXT: "{{.*[\\/]}}parseable_output.swift"
21-
// CHECK-NEXT: ],
22-
// CHECK-NEXT: "outputs": [
30+
// CHECK: "outputs": [
2331
// CHECK-NEXT: {
2432
// CHECK-NEXT: "type": "image",
2533
// CHECK-NEXT: "path": "{{.*[\\/]}}parseable_output.swift.tmp.out"
2634
// CHECK-NEXT: },
2735
// CHECK-NEXT: {
2836
// CHECK-NEXT: "type": "swiftmodule",
2937
// CHECK-NEXT: "path": "{{.*[\\/]}}parseable_output.swift.tmp.swiftmodule"
38+
// CHECK-NEXT: },
39+
// CHECK-NEXT: {
40+
// CHECK-NEXT: "type": "diagnostics",
41+
// CHECK-NEXT: "path": "{{.*[\\/]}}parseable_output.swift.tmp.dia"
42+
// CHECK-NEXT: },
43+
// CHECK-NEXT: {
44+
// CHECK-NEXT: "type": "abi-baseline-json",
45+
// CHECK-NEXT: "path": "{{.*[\\/]}}parseable_output.swift.tmp.abi.json"
3046
// CHECK-NEXT: }
3147
// CHECK-NEXT: ],
3248
// CHECK-NEXT: "pid": [[PID:[0-9]*]]

test/Frontend/parseable_output_error.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
// RUN: not %target-swift-frontend -primary-file %s -o %t.out -emit-module -emit-module-path %t.swiftmodule -frontend-parseable-output 2>&1 | %FileCheck %s
2+
// Check without primary files (WMO):
3+
// RUN: not %target-swift-frontend %s -o %t.out -emit-module -emit-module-path %t.swiftmodule -frontend-parseable-output 2>&1 | %FileCheck %s
24

35
func foo() {
46
return 11;
@@ -7,11 +9,10 @@ func foo() {
79
// CHECK-NEXT: {
810
// CHECK-NEXT: "kind": "began",
911
// CHECK-NEXT: "name": "compile",
10-
// CHECK-NEXT: "command": "{{.*[\\/]}}swift-frontend{{(\.exe)?}}{{.*}}-primary-file {{.*[\\/]}}parseable_output_error.swift -o {{.*[\\/]}}parseable_output_error.swift.tmp.out -emit-module -emit-module-path {{.*[\\/]}}parseable_output_error.swift.tmp.swiftmodule -frontend-parseable-output",
12+
// CHECK-NEXT: "command": "{{.*[\\/]}}swift-frontend{{(\.exe)?}}{{.*}} {{.*[\\/]}}parseable_output_error.swift -o {{.*[\\/]}}parseable_output_error.swift.tmp.out -emit-module -emit-module-path {{.*[\\/]}}parseable_output_error.swift.tmp.swiftmodule -frontend-parseable-output",
1113
// CHECK-NEXT: "command_executable": "{{.*[\\/]}}swift{{(-frontend|c)?(\.exe)?}}",
1214
// CHECK-NEXT: "command_arguments": [
13-
// CHECK: "-primary-file",
14-
// CHECK-NEXT: "{{.*[\\/]}}parseable_output_error.swift",
15+
// CHECK: "{{.*[\\/]}}parseable_output_error.swift",
1516
// CHECK-NEXT: "-o",
1617
// CHECK-NEXT: "{{.*[\\/]}}parseable_output_error.swift.tmp.out",
1718
// CHECK-NEXT: "-emit-module",
@@ -43,7 +44,7 @@ func foo() {
4344
// CHECK-NEXT: "kind": "finished",
4445
// CHECK-NEXT: "name": "compile",
4546
// CHECK-NEXT: "pid": [[PID]],
46-
// CHECK-NEXT: "output": "{{.*[\\/]}}parseable_output_error.swift:4:12: error: unexpected non-void return value in void function{{.*}}return 11;{{.*[\\/]}}parseable_output_error.swift:4:12: note: did you mean to add a return type?{{.*}}return 11;
47+
// CHECK-NEXT: "output": "{{.*[\\/]}}parseable_output_error.swift:6:12: error: unexpected non-void return value in void function{{.*}}return 11;{{.*[\\/]}}parseable_output_error.swift:6:12: note: did you mean to add a return type?{{.*}}return 11;
4748
// CHECK-NEXT: "process": {
4849
// CHECK-NEXT: "real_pid": [[PID]]
4950
// CHECK-NEXT: },

0 commit comments

Comments
 (0)