Skip to content

Commit 0bfff6b

Browse files
committed
Add libSwiftScan entry-points to query supported compiler flags and compiler features
For the client library (`libSwiftDriver`), this is critical for multiplexing library instances, and for compatibility with different versions of `libSwiftDrvier`. Resolves rdar://73631930
1 parent b4249c9 commit 0bfff6b

File tree

6 files changed

+110
-4
lines changed

6 files changed

+110
-4
lines changed

include/swift-c/DependencyScan/DependencyScan.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
/// SWIFTSCAN_VERSION_MINOR should increase when there are API additions.
2828
/// SWIFTSCAN_VERSION_MAJOR is intended for "major" source/ABI breaking changes.
2929
#define SWIFTSCAN_VERSION_MAJOR 0
30-
#define SWIFTSCAN_VERSION_MINOR 1
30+
#define SWIFTSCAN_VERSION_MINOR 2
3131

3232
SWIFTSCAN_BEGIN_DECLS
3333

@@ -292,6 +292,13 @@ swiftscan_batch_scan_result_dispose(swiftscan_batch_scan_result_t *result);
292292
SWIFTSCAN_PUBLIC void
293293
swiftscan_scan_invocation_dispose(swiftscan_scan_invocation_t invocation);
294294

295+
//=== Feature-Query Functions -----------------------------------------===//
296+
SWIFTSCAN_PUBLIC swiftscan_string_set_t *
297+
swiftscan_compiler_supported_arguments_query();
298+
299+
SWIFTSCAN_PUBLIC swiftscan_string_set_t *
300+
swiftscan_compiler_supported_features_query();
301+
295302
//=== Scanner Functions ---------------------------------------------------===//
296303

297304
/// Container of the configuration state and shared cache for dependency

tools/libSwiftScan/libSwiftScan.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "swift/DependencyScan/DependencyScanImpl.h"
1919
#include "swift/DependencyScan/DependencyScanningTool.h"
2020
#include "swift/DependencyScan/StringUtils.h"
21+
#include "swift/Option/Options.h"
2122

2223
using namespace swift::dependencies;
2324

@@ -461,3 +462,34 @@ void swiftscan_scan_invocation_dispose(swiftscan_scan_invocation_t invocation) {
461462
swiftscan_string_set_dispose(invocation->argv);
462463
delete invocation;
463464
}
465+
466+
//=== Feature-Query Functions -----------------------------------------===//
467+
static void addFrontendFlagOption(llvm::opt::OptTable &table,
468+
swift::options::ID id,
469+
std::vector<std::string> &frontendOptions) {
470+
if (table.getOption(id).hasFlag(swift::options::FrontendOption)) {
471+
auto name = table.getOptionName(id);
472+
if (strlen(name) > 0) {
473+
frontendOptions.push_back(std::string(name));
474+
}
475+
}
476+
}
477+
478+
// use" swiftscan_string_set_t *create_set(const std::vector<std::string> &strings) {
479+
swiftscan_string_set_t *
480+
swiftscan_compiler_supported_arguments_query() {
481+
std::unique_ptr<llvm::opt::OptTable> table = swift::createSwiftOptTable();
482+
std::vector<std::string> frontendFlags;
483+
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
484+
HELPTEXT, METAVAR, VALUES) \
485+
addFrontendFlagOption(*table, swift::options::OPT_##ID, frontendFlags);
486+
#include "swift/Option/Options.inc"
487+
#undef OPTION
488+
return create_set(frontendFlags);
489+
}
490+
491+
swiftscan_string_set_t *
492+
swiftscan_compiler_supported_features_query() {
493+
// TODO: We are yet to figure out how "Features" will be organized.
494+
return nullptr;
495+
}

tools/libSwiftScan/libSwiftScan.exports

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,5 @@ swiftscan_dependency_graph_dispose
5151
swiftscan_batch_scan_result_dispose
5252
swiftscan_import_set_dispose
5353
swiftscan_scanner_dispose
54+
swiftscan_compiler_supported_arguments_query
55+
swiftscan_compiler_supported_features_query

unittests/DependencyScan/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
add_swift_unittest(swiftScanTests
22
ScanFixture.cpp
3+
Features.cpp
34
ModuleDeps.cpp)
45

56
target_link_libraries(swiftScanTests

unittests/DependencyScan/Features.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "ScanFixture.h"
14+
#include "swift-c/DependencyScan/DependencyScan.h"
15+
#include "swift/Basic/LLVM.h"
16+
#include "swift/Option/Options.h"
17+
#include "llvm/ADT/StringRef.h"
18+
#include <vector>
19+
#include <unordered_set>
20+
#include "gtest/gtest.h"
21+
22+
using namespace swift;
23+
using namespace swift::unittest;
24+
25+
static void
26+
testHasOption(llvm::opt::OptTable &table, options::ID id,
27+
const std::unordered_set<std::string> &optionSet) {
28+
if (table.getOption(id).hasFlag(swift::options::FrontendOption)) {
29+
auto name = table.getOptionName(id);
30+
if (strlen(name) > 0) {
31+
auto nameStr = std::string(name);
32+
bool setContainsOption = optionSet.find(nameStr) != optionSet.end();
33+
EXPECT_EQ(setContainsOption, true);
34+
}
35+
}
36+
}
37+
38+
TEST_F(ScanTest, TestHasArgumentQuery) {
39+
std::unique_ptr<llvm::opt::OptTable> table = swift::createSwiftOptTable();
40+
auto supported_args_set = swiftscan_compiler_supported_arguments_query();
41+
std::unordered_set<std::string> optionSet;
42+
for (size_t i = 0; i < supported_args_set->count; ++i) {
43+
swiftscan_string_ref_t option = supported_args_set->strings[i];
44+
const char* data = static_cast<const char*>(option.data);
45+
optionSet.insert(std::string(data, option.length));
46+
}
47+
#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
48+
HELPTEXT, METAVAR, VALUES) \
49+
testHasOption(*table, swift::options::OPT_##ID, optionSet);
50+
#include "swift/Option/Options.inc"
51+
#undef OPTION
52+
}
53+
54+
TEST_F(ScanTest, TestDoesNotHaveArgumentQuery) {
55+
auto supported_args_set = swiftscan_compiler_supported_arguments_query();
56+
std::unordered_set<std::string> optionSet;
57+
for (size_t i = 0; i < supported_args_set->count; ++i) {
58+
swiftscan_string_ref_t option = supported_args_set->strings[i];
59+
const char* data = static_cast<const char*>(option.data);
60+
optionSet.insert(std::string(data, option.length));
61+
}
62+
bool hasOption;
63+
hasOption = optionSet.find("-clearly-not-a-compiler-flag") != optionSet.end();
64+
EXPECT_EQ(hasOption, false);
65+
hasOption = optionSet.find("-emit-modul") != optionSet.end();
66+
EXPECT_EQ(hasOption, false);
67+
}

unittests/DependencyScan/ModuleDeps.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ TEST_F(ScanTest, TestModuleDeps) {
5656
// Create test input file
5757
std::string TestPathStr = createFilename(tempDir, "foo.swift");
5858
ASSERT_FALSE(emitFileWithContents(tempDir, "foo.swift", "import A\n"));
59-
llvm::dbgs() << "Input File: " << TestPathStr << "\n";
6059

6160
// Create includes
6261
std::string IncludeDirPath = createFilename(tempDir, "include");
@@ -172,10 +171,8 @@ export *\n\
172171
}
173172

174173
std::vector<const char*> Command;
175-
llvm::dbgs() << "Compiler Command: \n";
176174
for (auto &command : CommandStrArr) {
177175
Command.push_back(command.c_str());
178-
llvm::dbgs() << command.c_str() << "\n";
179176
}
180177
auto DependenciesOrErr = ScannerTool.getDependencies(Command, {});
181178
ASSERT_FALSE(DependenciesOrErr.getError());

0 commit comments

Comments
 (0)