90
90
#include < iterator>
91
91
#include < string>
92
92
#include < vector>
93
+ #include " PreprocessorTracker.h"
93
94
94
95
using namespace clang ::tooling;
95
96
using namespace clang ;
96
97
using namespace llvm ;
98
+ using namespace Modularize ;
97
99
98
100
// Option to specify a file name for a list of header files to check.
99
101
cl::opt<std::string>
@@ -382,8 +384,14 @@ class CollectEntitiesVisitor
382
384
383
385
class CollectEntitiesConsumer : public ASTConsumer {
384
386
public:
385
- CollectEntitiesConsumer (EntityMap &Entities, Preprocessor &PP)
386
- : Entities(Entities), PP(PP) {}
387
+ CollectEntitiesConsumer (EntityMap &Entities,
388
+ PreprocessorTracker &preprocessorTracker,
389
+ Preprocessor &PP, StringRef InFile)
390
+ : Entities(Entities), PPTracker(preprocessorTracker), PP(PP) {
391
+ PPTracker.handlePreprocessorEntry (PP, InFile);
392
+ }
393
+
394
+ ~CollectEntitiesConsumer () { PPTracker.handlePreprocessorExit (); }
387
395
388
396
virtual void HandleTranslationUnit (ASTContext &Ctx) {
389
397
SourceManager &SM = Ctx.getSourceManager ();
@@ -409,33 +417,41 @@ class CollectEntitiesConsumer : public ASTConsumer {
409
417
410
418
private:
411
419
EntityMap &Entities;
420
+ PreprocessorTracker &PPTracker;
412
421
Preprocessor &PP;
413
422
};
414
423
415
424
class CollectEntitiesAction : public SyntaxOnlyAction {
416
425
public:
417
- CollectEntitiesAction (EntityMap &Entities) : Entities(Entities) {}
426
+ CollectEntitiesAction (EntityMap &Entities,
427
+ PreprocessorTracker &preprocessorTracker)
428
+ : Entities(Entities), PPTracker(preprocessorTracker) {}
418
429
419
430
protected:
420
431
virtual clang::ASTConsumer *CreateASTConsumer (CompilerInstance &CI,
421
432
StringRef InFile) {
422
- return new CollectEntitiesConsumer (Entities, CI.getPreprocessor ());
433
+ return new CollectEntitiesConsumer (Entities, PPTracker,
434
+ CI.getPreprocessor (), InFile);
423
435
}
424
436
425
437
private:
426
438
EntityMap &Entities;
439
+ PreprocessorTracker &PPTracker;
427
440
};
428
441
429
442
class ModularizeFrontendActionFactory : public FrontendActionFactory {
430
443
public:
431
- ModularizeFrontendActionFactory (EntityMap &Entities) : Entities(Entities) {}
444
+ ModularizeFrontendActionFactory (EntityMap &Entities,
445
+ PreprocessorTracker &preprocessorTracker)
446
+ : Entities(Entities), PPTracker(preprocessorTracker) {}
432
447
433
448
virtual CollectEntitiesAction *create () {
434
- return new CollectEntitiesAction (Entities);
449
+ return new CollectEntitiesAction (Entities, PPTracker );
435
450
}
436
451
437
452
private:
438
453
EntityMap &Entities;
454
+ PreprocessorTracker &PPTracker;
439
455
};
440
456
441
457
int main (int argc, const char **argv) {
@@ -464,10 +480,14 @@ int main(int argc, const char **argv) {
464
480
Compilations.reset (
465
481
new FixedCompilationDatabase (Twine (PathBuf), CC1Arguments));
466
482
483
+ // Create preprocessor tracker, to watch for macro and conditional problems.
484
+ OwningPtr<PreprocessorTracker> PPTracker (PreprocessorTracker::create ());
485
+
467
486
// Parse all of the headers, detecting duplicates.
468
487
EntityMap Entities;
469
488
ClangTool Tool (*Compilations, Headers);
470
- int HadErrors = Tool.run (new ModularizeFrontendActionFactory (Entities));
489
+ int HadErrors =
490
+ Tool.run (new ModularizeFrontendActionFactory (Entities, *PPTracker));
471
491
472
492
// Create a place to save duplicate entity locations, separate bins per kind.
473
493
typedef SmallVector<Location, 8 > LocationArray;
@@ -515,6 +535,16 @@ int main(int argc, const char **argv) {
515
535
}
516
536
}
517
537
538
+ // Complain about macro instance in header files that differ based on how
539
+ // they are included.
540
+ if (PPTracker->reportInconsistentMacros (errs ()))
541
+ HadErrors = 1 ;
542
+
543
+ // Complain about preprocessor conditional directives in header files that
544
+ // differ based on how they are included.
545
+ if (PPTracker->reportInconsistentConditionals (errs ()))
546
+ HadErrors = 1 ;
547
+
518
548
// Complain about any headers that have contents that differ based on how
519
549
// they are included.
520
550
// FIXME: Could we provide information about which preprocessor conditionals
@@ -530,7 +560,7 @@ int main(int argc, const char **argv) {
530
560
531
561
HadErrors = 1 ;
532
562
errs () << " error: header '" << H->first ->getName ()
533
- << " ' has different contents depending on how it was included\n " ;
563
+ << " ' has different contents depending on how it was included. \n " ;
534
564
for (unsigned I = 0 , N = H->second .size (); I != N; ++I) {
535
565
errs () << " note: '" << H->second [I].Name << " ' in "
536
566
<< H->second [I].Loc .File ->getName () << " at "
0 commit comments