67
67
#include " clang/Driver/Tool.h"
68
68
#include " clang/Driver/ToolChain.h"
69
69
#include " clang/Driver/Types.h"
70
+ #include " clang/Lex/DependencyDirectivesScanner.h"
70
71
#include " llvm/ADT/ArrayRef.h"
71
72
#include " llvm/ADT/STLExtras.h"
72
73
#include " llvm/ADT/StringExtras.h"
@@ -4423,145 +4424,6 @@ void Driver::handleArguments(Compilation &C, DerivedArgList &Args,
4423
4424
}
4424
4425
}
4425
4426
4426
- static void skipWhitespace (const char *&Ptr) {
4427
- while (isWhitespace (*Ptr))
4428
- ++Ptr;
4429
- }
4430
-
4431
- // Returns the length of EOL, either 0 (no end-of-line), 1 (\n) or 2 (\r\n).
4432
- static unsigned isEOL (const char *Ptr) {
4433
- if (*Ptr == ' \0 ' )
4434
- return 0 ;
4435
- if (*(Ptr + 1 ) != ' \0 ' && isVerticalWhitespace (Ptr[0 ]) &&
4436
- isVerticalWhitespace (Ptr[1 ]) && Ptr[0 ] != Ptr[1 ])
4437
- return 2 ;
4438
- return !!isVerticalWhitespace (Ptr[0 ]);
4439
- }
4440
-
4441
- static void skipLine (const char *&Ptr) {
4442
- for (;;) {
4443
- char LastNonWhitespace = ' ' ;
4444
- while (!isVerticalWhitespace (*Ptr) && *Ptr != ' \0 ' ) {
4445
- if (!isHorizontalWhitespace (*Ptr))
4446
- LastNonWhitespace = *Ptr;
4447
- ++Ptr;
4448
- }
4449
-
4450
- const unsigned Len = isEOL (Ptr);
4451
- if (!Len)
4452
- return ;
4453
-
4454
- Ptr += Len;
4455
- if (LastNonWhitespace != ' \\ ' )
4456
- break ;
4457
- }
4458
- }
4459
-
4460
- // Returns the length of a line splice sequence (including trailing whitespace),
4461
- // or 0 if no line splice is found.
4462
- static unsigned isLineSplice (const char *Start) {
4463
- if (*Start != ' \\ ' )
4464
- return 0 ;
4465
-
4466
- const char *Ptr = Start + 1 ;
4467
- while (isHorizontalWhitespace (*Ptr))
4468
- ++Ptr;
4469
-
4470
- if (unsigned Len = isEOL (Ptr))
4471
- return Ptr - Start + Len;
4472
- return 0 ;
4473
- }
4474
-
4475
- static bool trySkipLineSplice (const char *&Ptr) {
4476
- if (unsigned Len = isLineSplice (Ptr); Len) {
4477
- Ptr += Len;
4478
- return true ;
4479
- }
4480
- return false ;
4481
- }
4482
-
4483
- static bool trySkipDirective (const char *&Ptr) {
4484
- if (*Ptr != ' #' )
4485
- return false ;
4486
-
4487
- ++Ptr;
4488
- skipLine (Ptr);
4489
- return true ;
4490
- }
4491
-
4492
- static bool trySkipLineComment (const char *&Ptr) {
4493
- if (Ptr[0 ] != ' /' || Ptr[1 ] != ' /' )
4494
- return false ;
4495
-
4496
- Ptr += 2 ;
4497
- skipLine (Ptr);
4498
- return true ;
4499
- }
4500
-
4501
- static bool trySkipBlockComment (const char *&Ptr) {
4502
- if (Ptr[0 ] != ' /' || Ptr[1 ] != ' *' )
4503
- return false ;
4504
-
4505
- Ptr += 2 ;
4506
- while (*Ptr != ' \0 ' ) {
4507
- if (Ptr[0 ] == ' *' && Ptr[1 ] == ' /' ) {
4508
- Ptr += 2 ; // '*/'
4509
- return true ;
4510
- }
4511
- ++Ptr;
4512
- }
4513
- return true ;
4514
- }
4515
-
4516
- static bool trySkipComment (const char *&Ptr) {
4517
- return trySkipLineComment (Ptr) || trySkipBlockComment (Ptr);
4518
- }
4519
-
4520
- // Skipps over comments and (non-module) directives
4521
- static void skipToRelevantCXXModuleText (const char *&Ptr) {
4522
- while (*Ptr != ' \0 ' ) {
4523
- skipWhitespace (Ptr);
4524
- if (trySkipComment (Ptr) || trySkipDirective (Ptr) || trySkipLineSplice (Ptr))
4525
- continue ;
4526
- break ; // Found relevant text!
4527
- }
4528
- }
4529
-
4530
- static bool scanBufferForCXXModuleUsage (const llvm::MemoryBuffer &Buffer) {
4531
- const char *Ptr = Buffer.getBufferStart ();
4532
- skipToRelevantCXXModuleText (Ptr);
4533
-
4534
- // Check if the buffer has enough remaining bytes left for any of the
4535
- // module-related declaration fragments we are checking for, without making
4536
- // the potentially memory-mapped buffer load unnecessary pages.
4537
- constexpr int MinKeywordLength = 6 ;
4538
- const char *Begin = Ptr;
4539
- for (int i = 0 ; i < MinKeywordLength; ++i) {
4540
- if (*Ptr == ' \0 ' )
4541
- return false ;
4542
- ++Ptr;
4543
- }
4544
- StringRef Text (Begin, MinKeywordLength);
4545
-
4546
- const bool IsGlobalModule = Text.starts_with (" module" );
4547
- if (!IsGlobalModule && !Text.starts_with (" import" ) &&
4548
- !Text.starts_with (" export" ))
4549
- return false ;
4550
-
4551
- // Ensure the keyword has a proper ending and isn't part of a identifier
4552
- // or namespace. For this we might have to skip comments and line
4553
- // continuations.
4554
- while (*Ptr != ' \0 ' ) {
4555
- if (isWhitespace (*Ptr) || (IsGlobalModule && *Ptr == ' ;' ))
4556
- return true ;
4557
- if (trySkipBlockComment (Ptr) || trySkipLineSplice (Ptr))
4558
- continue ;
4559
- return false ;
4560
- }
4561
-
4562
- return false ;
4563
- }
4564
-
4565
4427
static bool hasCXXModuleInputType (const Driver::InputList &Inputs) {
4566
4428
const auto IsTypeCXXModule = [](const auto &Input) -> bool {
4567
4429
const auto TypeID = Input.first ;
@@ -4571,7 +4433,7 @@ static bool hasCXXModuleInputType(const Driver::InputList &Inputs) {
4571
4433
}
4572
4434
4573
4435
llvm::ErrorOr<bool >
4574
- Driver::ScanInputsForCXXModuleUsage (const InputList &Inputs) const {
4436
+ Driver::ScanInputsForCXX20ModulesUsage (const InputList &Inputs) const {
4575
4437
const auto CXXInputs = llvm::make_filter_range (
4576
4438
Inputs, [](const auto &Input) { return types::isCXX (Input.first ); });
4577
4439
@@ -4582,7 +4444,7 @@ Driver::ScanInputsForCXXModuleUsage(const InputList &Inputs) const {
4582
4444
return ErrOrBuffer.getError ();
4583
4445
const auto Buffer = std::move (*ErrOrBuffer);
4584
4446
4585
- if (scanBufferForCXXModuleUsage (* Buffer)) {
4447
+ if (scanInputForCXX20ModulesUsage ( Buffer-> getBuffer () )) {
4586
4448
Diags.Report (diag::remark_found_cxx20_module_usage) << Filename;
4587
4449
return true ;
4588
4450
}
@@ -4609,7 +4471,7 @@ void Driver::BuildActions(Compilation &C, DerivedArgList &Args,
4609
4471
// Currently, this serves diagnostic purposes only.
4610
4472
bool UsesCXXModules = hasCXXModuleInputType (Inputs);
4611
4473
if (!UsesCXXModules) {
4612
- const auto ErrOrScanResult = ScanInputsForCXXModuleUsage (Inputs);
4474
+ const auto ErrOrScanResult = ScanInputsForCXX20ModulesUsage (Inputs);
4613
4475
if (!ErrOrScanResult) {
4614
4476
Diags.Report (diag::err_cannot_open_file)
4615
4477
<< ErrOrScanResult.getError ().message ();
0 commit comments