Skip to content

Commit 72bde68

Browse files
committed
[sourcekit] Use the driver to parse command line arguments
Stop parsing frontend arguments directly and use the driver instead. The most intersting part of this change is that it forces us to consider whether our compiler invocation will have inputs or not. We have several kinds of requests that need to create a compiler instance, but not parse any inputs (interface-generation, doc-info, and indexing when operating on a module instead of source files). Incidentally, add an error when trying to do doc-info on multiple source files. This was already very broken (assertion failures and bogus source locations), so add an error for it. rdar://problem/17897287
1 parent 368e25e commit 72bde68

File tree

10 files changed

+98
-72
lines changed

10 files changed

+98
-72
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,7 @@
11
// RUN: %sourcekitd-test -req=doc-info %S/Inputs/main.swift > %t.response
22
// RUN: diff -u %s.response %t.response
3+
4+
// RUN: not %sourcekitd-test -req=doc-info %S/Inputs/main.swift -- %S/Inputs/cake.swift 2> %t.error
5+
// RUN: %FileCheck %s -check-prefix=MULTI_FILE < %t.error
6+
7+
// MULTI_FILE: unexpected input in compiler arguments

test/SourceKit/DocumentStructure/structure.swift.placeholders.response

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
key.name: "<#MyCls#>",
1010
key.offset: 0,
1111
key.length: 35,
12-
key.runtime_name: "_TtC4main9<#MyCls#>",
12+
key.runtime_name: "_TtC12placeholders9<#MyCls#>",
1313
key.nameoffset: 6,
1414
key.namelength: 9,
1515
key.bodyoffset: 34,

test/SourceKit/Misc/ignored-flags.swift

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,26 @@ s.
44
// CHECK: littleEndian
55

66
// RUN: %sourcekitd-test -req=complete -pos=2:3 %s -- -j4 %s | %FileCheck %s
7-
// RUN: %sourcekitd-test -req=complete -pos=2:3 %s -- -c %s | %FileCheck %s
7+
// RUN: %sourcekitd-test -req=complete -pos=2:3 %s -- -j 4 %s | %FileCheck %s
88
// RUN: %sourcekitd-test -req=complete -pos=2:3 %s -- -v %s | %FileCheck %s
9+
// RUN: %sourcekitd-test -req=complete -pos=2:3 %s -- -c %s | %FileCheck %s
910
// RUN: %sourcekitd-test -req=complete -pos=2:3 %s -- -embed-bitcode %s | %FileCheck %s
1011
// RUN: %sourcekitd-test -req=complete -pos=2:3 %s -- -enable-bridging-pch %s | %FileCheck %s
1112
// RUN: %sourcekitd-test -req=complete -pos=2:3 %s -- -disable-bridging-pch %s | %FileCheck %s
13+
// RUN: %sourcekitd-test -req=complete -pos=2:3 %s -- -verify-debug-info %s | %FileCheck %s
14+
// RUN: %sourcekitd-test -req=complete -pos=2:3 %s -- -Xlinker blah %s | %FileCheck %s
15+
// RUN: %sourcekitd-test -req=complete -pos=2:3 %s -- -use-ld=blah %s | %FileCheck %s
16+
// RUN: %sourcekitd-test -req=complete -pos=2:3 %s -- -incremental %s | %FileCheck %s
17+
// RUN: %sourcekitd-test -req=complete -pos=2:3 %s -- -driver-time-compilation %s | %FileCheck %s
18+
19+
20+
// Mode flags
21+
// RUN: %empty-directory(%t)
22+
// RUN: %sourcekitd-test -req=complete -pos=2:3 %s -- -emit-object %s -o %t/test.o | %FileCheck %s
23+
// RUN: not find %t/test.o
24+
// RUN: %sourcekitd-test -req=complete -pos=2:3 %s -- -emit-executable %s -o %t/test | %FileCheck %s
25+
// RUN: not find %t/test
26+
// RUN: %sourcekitd-test -req=complete -pos=2:3 %s -- -emit-library -module-name test %s -o %t/test | %FileCheck %s
27+
// RUN: not find %t/test
28+
// RUN: %sourcekitd-test -req=complete -pos=2:3 %s -- -emit-module -module-name test %s -o %t/test.swiftmodule | %FileCheck %s
29+
// RUN: not find %t/test.swiftmodule

tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp

Lines changed: 34 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "SourceKit/Support/Tracing.h"
2222

2323
#include "swift/Basic/Cache.h"
24+
#include "swift/Driver/FrontendUtil.h"
2425
#include "swift/Frontend/Frontend.h"
2526
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
2627
#include "swift/Strings.h"
@@ -370,49 +371,6 @@ SwiftASTManager::getMemoryBuffer(StringRef Filename, std::string &Error) {
370371
return Impl.getMemoryBuffer(Filename, Error);
371372
}
372373

373-
static void setModuleName(CompilerInvocation &Invocation) {
374-
if (!Invocation.getModuleName().empty())
375-
return;
376-
377-
StringRef Filename = Invocation.getOutputFilename();
378-
if (Filename.empty()) {
379-
if (!Invocation.getFrontendOptions().InputsAndOutputs.hasInputs()) {
380-
Invocation.setModuleName("main");
381-
return;
382-
}
383-
Filename = Invocation.getFrontendOptions()
384-
.InputsAndOutputs.getFilenameOfFirstInput();
385-
}
386-
Filename = llvm::sys::path::filename(Filename);
387-
StringRef ModuleName = llvm::sys::path::stem(Filename);
388-
if (ModuleName.empty() || !Lexer::isIdentifier(ModuleName)) {
389-
Invocation.setModuleName("main");
390-
return;
391-
}
392-
Invocation.setModuleName(ModuleName);
393-
}
394-
395-
static void sanitizeCompilerArgs(ArrayRef<const char *> Args,
396-
SmallVectorImpl<const char *> &NewArgs) {
397-
for (const char *CArg : Args) {
398-
StringRef Arg = CArg;
399-
if (Arg.startswith("-j"))
400-
continue;
401-
if (Arg == "-c")
402-
continue;
403-
if (Arg == "-v")
404-
continue;
405-
if (Arg == "-Xfrontend")
406-
continue;
407-
if (Arg == "-embed-bitcode")
408-
continue;
409-
if (Arg == "-enable-bridging-pch" ||
410-
Arg == "-disable-bridging-pch")
411-
continue;
412-
NewArgs.push_back(CArg);
413-
}
414-
}
415-
416374
static FrontendInputsAndOutputs
417375
convertFileContentsToInputs(const SmallVectorImpl<FileContent> &contents) {
418376
FrontendInputsAndOutputs inputsAndOutputs;
@@ -456,19 +414,20 @@ resolveSymbolicLinksInInputs(FrontendInputsAndOutputs &inputsAndOutputs,
456414
}
457415

458416
bool SwiftASTManager::initCompilerInvocation(CompilerInvocation &Invocation,
459-
ArrayRef<const char *> OrigArgs,
417+
ArrayRef<const char *> Args,
460418
DiagnosticEngine &Diags,
461419
StringRef UnresolvedPrimaryFile,
462420
std::string &Error) {
463-
SmallVector<const char *, 16> Args;
464-
sanitizeCompilerArgs(OrigArgs, Args);
465-
466-
Invocation.setRuntimeResourcePath(Impl.RuntimeResourcePath);
467-
if (Invocation.parseArgs(Args, Diags)) {
421+
if (auto driverInvocation = driver::createCompilerInvocation(Args, Diags)) {
422+
Invocation = *driverInvocation;
423+
} else {
468424
// FIXME: Get the actual diagnostic.
469425
Error = "error when parsing the compiler arguments";
470426
return true;
471427
}
428+
429+
Invocation.setRuntimeResourcePath(Impl.RuntimeResourcePath);
430+
472431
Invocation.getFrontendOptions().InputsAndOutputs =
473432
resolveSymbolicLinksInInputs(
474433
Invocation.getFrontendOptions().InputsAndOutputs,
@@ -479,7 +438,7 @@ bool SwiftASTManager::initCompilerInvocation(CompilerInvocation &Invocation,
479438
ClangImporterOptions &ImporterOpts = Invocation.getClangImporterOptions();
480439
ImporterOpts.DetailedPreprocessingRecord = true;
481440

482-
setModuleName(Invocation);
441+
assert(!Invocation.getModuleName().empty());
483442
Invocation.setSerializedDiagnosticsPath(StringRef());
484443
Invocation.getLangOptions().AttachCommentsToDecls = true;
485444
Invocation.getLangOptions().DiagnosticsEditorMode = true;
@@ -497,6 +456,10 @@ bool SwiftASTManager::initCompilerInvocation(CompilerInvocation &Invocation,
497456
FrontendOpts.IndexStorePath.clear();
498457
ImporterOpts.IndexStorePath.clear();
499458

459+
// Force the action type to be -typecheck. This affects importing the
460+
// SwiftONoneSupport module.
461+
FrontendOpts.RequestedAction = FrontendOptions::ActionType::Typecheck;
462+
500463
return false;
501464
}
502465

@@ -520,6 +483,27 @@ bool SwiftASTManager::initCompilerInvocation(CompilerInvocation &CompInvok,
520483
return false;
521484
}
522485

486+
bool SwiftASTManager::initCompilerInvocationNoInputs(
487+
swift::CompilerInvocation &Invocation, ArrayRef<const char *> OrigArgs,
488+
swift::DiagnosticEngine &Diags, std::string &Error, bool AllowInputs) {
489+
490+
SmallVector<const char *, 16> Args(OrigArgs.begin(), OrigArgs.end());
491+
// Use stdin as a .swift input to satisfy the driver.
492+
Args.push_back("-");
493+
if (initCompilerInvocation(Invocation, Args, Diags, "", Error))
494+
return true;
495+
496+
if (!AllowInputs &&
497+
Invocation.getFrontendOptions().InputsAndOutputs.inputCount() > 1) {
498+
Error = "unexpected input in compiler arguments";
499+
return true;
500+
}
501+
502+
// Clear the inputs.
503+
Invocation.getFrontendOptions().InputsAndOutputs.clearInputs();
504+
return false;
505+
}
506+
523507
SwiftInvocationRef
524508
SwiftASTManager::getInvocation(ArrayRef<const char *> OrigArgs,
525509
StringRef PrimaryFile,

tools/SourceKit/lib/SwiftLang/SwiftASTManager.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,16 @@ class SwiftASTManager {
118118
StringRef PrimaryFile,
119119
std::string &Error);
120120

121+
/// Initializes \p Invocation as if for typechecking, but with no inputs.
122+
///
123+
/// If \p AllowInputs is false, it is an error for \p OrigArgs to contain any
124+
/// input files.
125+
bool initCompilerInvocationNoInputs(swift::CompilerInvocation &Invocation,
126+
ArrayRef<const char *> OrigArgs,
127+
swift::DiagnosticEngine &Diags,
128+
std::string &Error,
129+
bool AllowInputs = true);
130+
121131
void removeCachedAST(SwiftInvocationRef Invok);
122132

123133
struct Implementation;

tools/SourceKit/lib/SwiftLang/SwiftCompletion.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,10 +1194,14 @@ void SwiftLangSupport::codeCompleteOpen(
11941194

11951195
// Add any codecomplete.open specific flags.
11961196
std::vector<const char *> extendedArgs(args.begin(), args.end());
1197-
if (CCOpts.addInitsToTopLevel)
1197+
if (CCOpts.addInitsToTopLevel) {
1198+
extendedArgs.push_back("-Xfrontend");
11981199
extendedArgs.push_back("-code-complete-inits-in-postfix-expr");
1199-
if (CCOpts.callPatternHeuristics)
1200+
}
1201+
if (CCOpts.callPatternHeuristics) {
1202+
extendedArgs.push_back("-Xfrontend");
12001203
extendedArgs.push_back("-code-complete-call-pattern-heuristics");
1204+
}
12011205

12021206
// Invoke completion.
12031207
std::string error;

tools/SourceKit/lib/SwiftLang/SwiftDocSupport.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1359,9 +1359,8 @@ SourceFile *SwiftLangSupport::getSyntacticSourceFile(
13591359
CompilerInstance &ParseCI, std::string &Error) {
13601360
CompilerInvocation Invocation;
13611361

1362-
bool Failed = getASTManager().initCompilerInvocation(Invocation, Args,
1363-
ParseCI.getDiags(),
1364-
StringRef(), Error);
1362+
bool Failed = getASTManager().initCompilerInvocationNoInputs(
1363+
Invocation, Args, ParseCI.getDiags(), Error);
13651364
if (Failed) {
13661365
Error = "Compiler invocation init failed";
13671366
return nullptr;
@@ -1415,14 +1414,14 @@ void SwiftLangSupport::getDocInfo(llvm::MemoryBuffer *InputBuf,
14151414

14161415
CompilerInvocation Invocation;
14171416
std::string Error;
1418-
bool Failed = getASTManager().initCompilerInvocation(Invocation, Args,
1419-
CI.getDiags(),
1420-
StringRef(),
1421-
Error);
1417+
bool Failed = getASTManager().initCompilerInvocationNoInputs(
1418+
Invocation, Args, CI.getDiags(), Error, /*AllowInputs=*/false);
1419+
14221420
if (Failed) {
14231421
Consumer.failed(Error);
14241422
return;
14251423
}
1424+
14261425
Invocation.getClangImporterOptions().ImportForwardDeclarations = true;
14271426

14281427
if (!ModuleName.empty()) {
@@ -1451,8 +1450,8 @@ findModuleGroups(StringRef ModuleName, ArrayRef<const char *> Args,
14511450
CI.addDiagnosticConsumer(&PrintDiags);
14521451
std::vector<StringRef> Groups;
14531452
std::string Error;
1454-
if (getASTManager().initCompilerInvocation(Invocation, Args, CI.getDiags(),
1455-
StringRef(), Error)) {
1453+
if (getASTManager().initCompilerInvocationNoInputs(Invocation, Args,
1454+
CI.getDiags(), Error)) {
14561455
Receiver(Groups, Error);
14571456
return;
14581457
}

tools/SourceKit/lib/SwiftLang/SwiftEditor.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1766,7 +1766,8 @@ void SwiftEditorDocument::parse(ImmutableTextSnapshotRef Snapshot,
17661766
Impl.SemanticInfo->getInvocation()->applyTo(CompInv);
17671767
Impl.SemanticInfo->getInvocation()->raw(Args, PrimaryFile);
17681768
} else {
1769-
ArrayRef<const char *> Args;
1769+
SmallVector<const char *, 1> Args;
1770+
Args.push_back(Impl.FilePath.c_str()); // Input
17701771
std::string Error;
17711772
// Ignore possible error(s)
17721773
Lang.getASTManager().

tools/SourceKit/lib/SwiftLang/SwiftEditorInterfaceGen.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -700,8 +700,8 @@ void SwiftLangSupport::editorOpenInterface(EditorConsumer &Consumer,
700700

701701
CompilerInvocation Invocation;
702702
std::string Error;
703-
if (getASTManager().initCompilerInvocation(Invocation, Args, CI.getDiags(),
704-
StringRef(), Error)) {
703+
if (getASTManager().initCompilerInvocationNoInputs(Invocation, Args,
704+
CI.getDiags(), Error)) {
705705
Consumer.handleRequestError(Error.c_str());
706706
return;
707707
}
@@ -814,8 +814,8 @@ void SwiftLangSupport::editorOpenHeaderInterface(EditorConsumer &Consumer,
814814
std::string Error;
815815

816816
ArrayRef<const char *> SwiftArgs = UsingSwiftArgs ? Args : llvm::None;
817-
if (getASTManager().initCompilerInvocation(Invocation, SwiftArgs, CI.getDiags(),
818-
StringRef(), Error)) {
817+
if (getASTManager().initCompilerInvocationNoInputs(Invocation, SwiftArgs,
818+
CI.getDiags(), Error)) {
819819
Consumer.handleRequestError(Error.c_str());
820820
return;
821821
}

tools/SourceKit/lib/SwiftLang/SwiftIndexing.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -253,13 +253,18 @@ void SwiftLangSupport::indexSource(StringRef InputFile,
253253
// response, and it can be expensive to do typo-correction when there are many
254254
// errors, which is common in indexing.
255255
SmallVector<const char *, 16> Args(OrigArgs.begin(), OrigArgs.end());
256+
Args.push_back("-Xfrontend");
256257
Args.push_back("-disable-typo-correction");
257258

258259
CompilerInvocation Invocation;
259-
bool Failed = getASTManager().initCompilerInvocation(Invocation, Args,
260-
CI.getDiags(),
261-
/*PrimaryFile=*/IsModuleIndexing ? StringRef() : InputFile,
262-
Error);
260+
bool Failed = true;
261+
if (IsModuleIndexing) {
262+
Failed = getASTManager().initCompilerInvocationNoInputs(
263+
Invocation, Args, CI.getDiags(), Error);
264+
} else {
265+
Failed = getASTManager().initCompilerInvocation(
266+
Invocation, Args, CI.getDiags(), InputFile, Error);
267+
}
263268
if (Failed) {
264269
IdxConsumer.failed(Error);
265270
return;

0 commit comments

Comments
 (0)