Skip to content

Commit 1e01014

Browse files
committed
Added new feature for checking macro and preprocessor conditional consistency.
llvm-svn: 187228
1 parent 318f09f commit 1e01014

File tree

6 files changed

+1236
-13
lines changed

6 files changed

+1236
-13
lines changed

clang-tools-extra/modularize/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ set(LLVM_LINK_COMPONENTS
77

88
add_clang_executable(modularize
99
Modularize.cpp
10+
PreprocessorTracker.cpp
1011
)
1112

1213
target_link_libraries(modularize

clang-tools-extra/modularize/Modularize.cpp

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,12 @@
9090
#include <iterator>
9191
#include <string>
9292
#include <vector>
93+
#include "PreprocessorTracker.h"
9394

9495
using namespace clang::tooling;
9596
using namespace clang;
9697
using namespace llvm;
98+
using namespace Modularize;
9799

98100
// Option to specify a file name for a list of header files to check.
99101
cl::opt<std::string>
@@ -382,8 +384,14 @@ class CollectEntitiesVisitor
382384

383385
class CollectEntitiesConsumer : public ASTConsumer {
384386
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(); }
387395

388396
virtual void HandleTranslationUnit(ASTContext &Ctx) {
389397
SourceManager &SM = Ctx.getSourceManager();
@@ -409,33 +417,41 @@ class CollectEntitiesConsumer : public ASTConsumer {
409417

410418
private:
411419
EntityMap &Entities;
420+
PreprocessorTracker &PPTracker;
412421
Preprocessor &PP;
413422
};
414423

415424
class CollectEntitiesAction : public SyntaxOnlyAction {
416425
public:
417-
CollectEntitiesAction(EntityMap &Entities) : Entities(Entities) {}
426+
CollectEntitiesAction(EntityMap &Entities,
427+
PreprocessorTracker &preprocessorTracker)
428+
: Entities(Entities), PPTracker(preprocessorTracker) {}
418429

419430
protected:
420431
virtual clang::ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
421432
StringRef InFile) {
422-
return new CollectEntitiesConsumer(Entities, CI.getPreprocessor());
433+
return new CollectEntitiesConsumer(Entities, PPTracker,
434+
CI.getPreprocessor(), InFile);
423435
}
424436

425437
private:
426438
EntityMap &Entities;
439+
PreprocessorTracker &PPTracker;
427440
};
428441

429442
class ModularizeFrontendActionFactory : public FrontendActionFactory {
430443
public:
431-
ModularizeFrontendActionFactory(EntityMap &Entities) : Entities(Entities) {}
444+
ModularizeFrontendActionFactory(EntityMap &Entities,
445+
PreprocessorTracker &preprocessorTracker)
446+
: Entities(Entities), PPTracker(preprocessorTracker) {}
432447

433448
virtual CollectEntitiesAction *create() {
434-
return new CollectEntitiesAction(Entities);
449+
return new CollectEntitiesAction(Entities, PPTracker);
435450
}
436451

437452
private:
438453
EntityMap &Entities;
454+
PreprocessorTracker &PPTracker;
439455
};
440456

441457
int main(int argc, const char **argv) {
@@ -464,10 +480,14 @@ int main(int argc, const char **argv) {
464480
Compilations.reset(
465481
new FixedCompilationDatabase(Twine(PathBuf), CC1Arguments));
466482

483+
// Create preprocessor tracker, to watch for macro and conditional problems.
484+
OwningPtr<PreprocessorTracker> PPTracker(PreprocessorTracker::create());
485+
467486
// Parse all of the headers, detecting duplicates.
468487
EntityMap Entities;
469488
ClangTool Tool(*Compilations, Headers);
470-
int HadErrors = Tool.run(new ModularizeFrontendActionFactory(Entities));
489+
int HadErrors =
490+
Tool.run(new ModularizeFrontendActionFactory(Entities, *PPTracker));
471491

472492
// Create a place to save duplicate entity locations, separate bins per kind.
473493
typedef SmallVector<Location, 8> LocationArray;
@@ -515,6 +535,16 @@ int main(int argc, const char **argv) {
515535
}
516536
}
517537

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+
518548
// Complain about any headers that have contents that differ based on how
519549
// they are included.
520550
// FIXME: Could we provide information about which preprocessor conditionals
@@ -530,7 +560,7 @@ int main(int argc, const char **argv) {
530560

531561
HadErrors = 1;
532562
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";
534564
for (unsigned I = 0, N = H->second.size(); I != N; ++I) {
535565
errs() << "note: '" << H->second[I].Name << "' in "
536566
<< H->second[I].Loc.File->getName() << " at "

0 commit comments

Comments
 (0)