21
21
#include " rapidjson/reader.h"
22
22
#include " spdlog/fmt/fmt.h"
23
23
24
+ #include " indexer/CommandLineCleaner.h"
24
25
#include " indexer/CompilationDatabase.h"
25
26
#include " indexer/FileSystem.h"
26
27
#include " indexer/LlvmCommandLineParsing.h"
@@ -73,25 +74,30 @@ namespace {
73
74
74
75
using AbsolutePath = scip_clang::AbsolutePath;
75
76
using ToolchainInfo = scip_clang::compdb::ToolchainInfo;
77
+ using CommandLineCleaner = scip_clang::compdb::CommandLineCleaner;
76
78
using CompilerKind = scip_clang::compdb::CompilerKind;
79
+ using CliOptionKind = scip_clang::compdb::CliOptionKind;
77
80
78
81
struct ClangToolchainInfo : public ToolchainInfo {
79
82
std::string resourceDir;
80
83
std::vector<std::string> findResourceDirInvocation;
81
84
std::string compilerDriverPath;
82
85
std::vector<std::string> findDriverInvocation;
86
+ std::unique_ptr<CommandLineCleaner> cleaner;
83
87
84
88
// All strings and vectors above should be non-empty for
85
89
// a valid toolchain.
86
90
87
91
ClangToolchainInfo (std::string resourceDir,
88
92
std::vector<std::string> findResourceDirInvocation,
89
93
std::string compilerDriverPath,
90
- std::vector<std::string> findDriverInvocation)
94
+ std::vector<std::string> findDriverInvocation,
95
+ std::unique_ptr<CommandLineCleaner> cleaner)
91
96
: ToolchainInfo(), resourceDir(resourceDir),
92
97
findResourceDirInvocation (findResourceDirInvocation),
93
98
compilerDriverPath(compilerDriverPath),
94
- findDriverInvocation(findDriverInvocation){};
99
+ findDriverInvocation(findDriverInvocation),
100
+ cleaner(std::move(cleaner)){};
95
101
96
102
virtual CompilerKind kind () const override {
97
103
return CompilerKind::Clang;
@@ -116,6 +122,7 @@ struct ClangToolchainInfo : public ToolchainInfo {
116
122
virtual void
117
123
adjustCommandLine (std::vector<std::string> &commandLine) const override {
118
124
commandLine[0 ] = this ->compilerDriverPath ;
125
+ this ->cleaner ->clean (commandLine);
119
126
commandLine.push_back (" -resource-dir" );
120
127
commandLine.push_back (this ->resourceDir );
121
128
}
@@ -165,18 +172,21 @@ struct ClangToolchainInfo : public ToolchainInfo {
165
172
166
173
return std::make_unique<ClangToolchainInfo>(
167
174
resourceDir, findResourceDirInvocation, compilerDriverPath,
168
- findDriverInvocation);
175
+ findDriverInvocation, CommandLineCleaner::forClangOrGcc () );
169
176
}
170
177
};
171
178
172
179
struct GccToolchainInfo : public ToolchainInfo {
173
180
std::string installDir;
174
181
std::vector<std::string> findInstallDirInvocation;
182
+ std::unique_ptr<CommandLineCleaner> cleaner;
175
183
176
184
GccToolchainInfo (std::string installDir,
177
- std::vector<std::string> findInstallDirInvocation)
185
+ std::vector<std::string> findInstallDirInvocation,
186
+ std::unique_ptr<CommandLineCleaner> cleaner)
178
187
: ToolchainInfo(), installDir(installDir),
179
- findInstallDirInvocation (findInstallDirInvocation) {}
188
+ findInstallDirInvocation (findInstallDirInvocation),
189
+ cleaner(std::move(cleaner)) {}
180
190
181
191
virtual CompilerKind kind () const override {
182
192
return CompilerKind::Gcc;
@@ -194,6 +204,7 @@ struct GccToolchainInfo : public ToolchainInfo {
194
204
195
205
virtual void
196
206
adjustCommandLine (std::vector<std::string> &commandLine) const override {
207
+ this ->cleaner ->clean (commandLine);
197
208
commandLine.push_back (" -resource-dir" );
198
209
commandLine.push_back (this ->installDir );
199
210
// gcc-7 adds headers like limits.h and syslimits.h in include-fixed
@@ -227,21 +238,17 @@ struct GccToolchainInfo : public ToolchainInfo {
227
238
return nullptr ;
228
239
}
229
240
spdlog::debug (" found gcc install directory at {}" , installDir);
230
- return std::make_unique<GccToolchainInfo>(installDir,
231
- findSearchDirsInvocation);
241
+ return std::make_unique<GccToolchainInfo>(
242
+ installDir, findSearchDirsInvocation,
243
+ CommandLineCleaner::forClangOrGcc ());
232
244
}
233
245
};
234
246
235
- enum class NvccOptionType {
236
- NoArgument,
237
- OneArgument,
238
- };
239
-
240
247
// Based on nvcc --help from nvcc version V12.2.140
241
248
// Build cuda_12.2.r12.2/compiler.33191640_0
242
249
243
250
// clang-format off
244
- constexpr const char * skipOptionsNoArgs [] = {
251
+ constexpr const char * nvccSkipOptionsNoArgs [] = {
245
252
" --cuda" , " -cuda" ,
246
253
" --cubin" , " -cubin" ,
247
254
" --fatbin" , " -fatbin" ,
@@ -303,7 +310,7 @@ constexpr const char* skipOptionsNoArgs[] = {
303
310
" --host-relocatable-link" , " -r"
304
311
};
305
312
306
- constexpr const char * skipOptionsWithArgs [] = {
313
+ constexpr const char * nvccSkipOptionsWithArgs [] = {
307
314
" --cudart" , " -cudart" ,
308
315
" --cudadevrt" , " -cudadevrt" ,
309
316
" --libdevice-directory" , " -ldir" ,
@@ -361,18 +368,19 @@ struct NvccToolchainInfo : public ToolchainInfo {
361
368
// / doesn't even construct the appropriate CUDAKernelCallExpr values.
362
369
std::unique_ptr<ClangToolchainInfo> clangInfo;
363
370
364
- absl::flat_hash_map<std::string_view, NvccOptionType> toBeSkipped ;
371
+ CommandLineCleaner cleaner ;
365
372
366
373
NvccToolchainInfo (AbsolutePath cudaDir)
367
374
: ToolchainInfo(), cudaDir(cudaDir), clangInfo(nullptr ) {
368
- for ( auto s : skipOptionsNoArgs) {
369
- this -> toBeSkipped . emplace ( std::string_view (s),
370
- NvccOptionType ::NoArgument);
375
+ CommandLineCleaner::MapType toZap;
376
+ for ( auto s : nvccSkipOptionsNoArgs) {
377
+ toZap. emplace ( std::string_view (s), CliOptionKind ::NoArgument);
371
378
}
372
- for (auto s : skipOptionsWithArgs) {
373
- this ->toBeSkipped .emplace (std::string_view (s),
374
- NvccOptionType::OneArgument);
379
+ for (auto s : nvccSkipOptionsWithArgs) {
380
+ toZap.emplace (std::string_view (s), CliOptionKind::OneArgument);
375
381
}
382
+ this ->cleaner =
383
+ CommandLineCleaner{.toZap = toZap, .noArgumentMatcher = std::nullopt};
376
384
377
385
// TODO: In principle, we could pick up Clang from -ccbin but that
378
386
// requires more plumbing; it would require using the -ccbin arg
@@ -412,72 +420,15 @@ struct NvccToolchainInfo : public ToolchainInfo {
412
420
return true ;
413
421
}
414
422
415
- enum class ArgumentProcessing {
416
- Keep,
417
- DropCurrent,
418
- DropCurrentAndNextIffBothPresent,
419
- };
420
-
421
- ArgumentProcessing handleArgument (const std::string &arg) const {
422
- if (!arg.starts_with (' -' )) {
423
- return ArgumentProcessing::Keep;
424
- }
425
- std::string_view substr = arg;
426
- auto eqIndex = arg.find (' =' );
427
- if (eqIndex != std::string::npos) {
428
- substr = std::string_view (arg.data (), eqIndex);
429
- }
430
- auto it = this ->toBeSkipped .find (substr);
431
- if (it == this ->toBeSkipped .end ()) {
432
- return ArgumentProcessing::Keep;
433
- }
434
- switch (it->second ) {
435
- case NvccOptionType::NoArgument:
436
- return ArgumentProcessing::DropCurrent;
437
- case NvccOptionType::OneArgument:
438
- if (substr.size () == arg.size ()) {
439
- return ArgumentProcessing::DropCurrentAndNextIffBothPresent;
440
- }
441
- return ArgumentProcessing::DropCurrent;
442
- }
443
- ENFORCE (false , " should've exited earlier" );
444
- }
445
-
446
- void removeUnknownArguments (std::vector<std::string> &commandLine) const {
447
- absl::flat_hash_set<size_t > drop{};
448
- for (size_t i = 0 ; i < commandLine.size (); ++i) {
449
- switch (this ->handleArgument (commandLine[i])) {
450
- case ArgumentProcessing::Keep:
451
- continue ;
452
- case ArgumentProcessing::DropCurrent:
453
- drop.insert (i);
454
- continue ;
455
- case ArgumentProcessing::DropCurrentAndNextIffBothPresent:
456
- if (i + 1 < commandLine.size ()) {
457
- drop.insert (i);
458
- drop.insert (i + 1 );
459
- }
460
- }
461
- }
462
- std::vector<std::string> tmp;
463
- tmp.reserve (commandLine.size () - drop.size ());
464
- for (size_t i = 0 ; i < commandLine.size (); ++i) {
465
- if (!drop.contains (i)) {
466
- tmp.push_back (std::move (commandLine[i]));
467
- }
468
- }
469
- std::swap (tmp, commandLine);
470
- }
471
-
472
423
virtual void
473
424
adjustCommandLine (std::vector<std::string> &commandLine) const override {
474
- this ->removeUnknownArguments (commandLine);
475
- commandLine.push_back (
476
- fmt::format (" -isystem{}{}include" , this ->cudaDir .asStringRef (),
477
- std::filesystem::path::preferred_separator));
425
+ this ->cleaner .clean (commandLine);
478
426
if (this ->clangInfo ) {
479
427
this ->clangInfo ->adjustCommandLine (commandLine);
480
428
}
429
+ commandLine.push_back (
430
+ fmt::format (" -isystem{}{}include" , this ->cudaDir .asStringRef (),
431
+ std::filesystem::path::preferred_separator));
481
432
}
482
433
483
434
static std::unique_ptr<NvccToolchainInfo>
0 commit comments