summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/modularize/Modularize.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra/modularize/Modularize.cpp')
-rw-r--r--clang-tools-extra/modularize/Modularize.cpp46
1 files changed, 38 insertions, 8 deletions
diff --git a/clang-tools-extra/modularize/Modularize.cpp b/clang-tools-extra/modularize/Modularize.cpp
index d68e855c70b..45d825d4414 100644
--- a/clang-tools-extra/modularize/Modularize.cpp
+++ b/clang-tools-extra/modularize/Modularize.cpp
@@ -90,10 +90,12 @@
#include <iterator>
#include <string>
#include <vector>
+#include "PreprocessorTracker.h"
using namespace clang::tooling;
using namespace clang;
using namespace llvm;
+using namespace Modularize;
// Option to specify a file name for a list of header files to check.
cl::opt<std::string>
@@ -382,8 +384,14 @@ private:
class CollectEntitiesConsumer : public ASTConsumer {
public:
- CollectEntitiesConsumer(EntityMap &Entities, Preprocessor &PP)
- : Entities(Entities), PP(PP) {}
+ CollectEntitiesConsumer(EntityMap &Entities,
+ PreprocessorTracker &preprocessorTracker,
+ Preprocessor &PP, StringRef InFile)
+ : Entities(Entities), PPTracker(preprocessorTracker), PP(PP) {
+ PPTracker.handlePreprocessorEntry(PP, InFile);
+ }
+
+ ~CollectEntitiesConsumer() { PPTracker.handlePreprocessorExit(); }
virtual void HandleTranslationUnit(ASTContext &Ctx) {
SourceManager &SM = Ctx.getSourceManager();
@@ -409,33 +417,41 @@ public:
private:
EntityMap &Entities;
+ PreprocessorTracker &PPTracker;
Preprocessor &PP;
};
class CollectEntitiesAction : public SyntaxOnlyAction {
public:
- CollectEntitiesAction(EntityMap &Entities) : Entities(Entities) {}
+ CollectEntitiesAction(EntityMap &Entities,
+ PreprocessorTracker &preprocessorTracker)
+ : Entities(Entities), PPTracker(preprocessorTracker) {}
protected:
virtual clang::ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) {
- return new CollectEntitiesConsumer(Entities, CI.getPreprocessor());
+ return new CollectEntitiesConsumer(Entities, PPTracker,
+ CI.getPreprocessor(), InFile);
}
private:
EntityMap &Entities;
+ PreprocessorTracker &PPTracker;
};
class ModularizeFrontendActionFactory : public FrontendActionFactory {
public:
- ModularizeFrontendActionFactory(EntityMap &Entities) : Entities(Entities) {}
+ ModularizeFrontendActionFactory(EntityMap &Entities,
+ PreprocessorTracker &preprocessorTracker)
+ : Entities(Entities), PPTracker(preprocessorTracker) {}
virtual CollectEntitiesAction *create() {
- return new CollectEntitiesAction(Entities);
+ return new CollectEntitiesAction(Entities, PPTracker);
}
private:
EntityMap &Entities;
+ PreprocessorTracker &PPTracker;
};
int main(int argc, const char **argv) {
@@ -464,10 +480,14 @@ int main(int argc, const char **argv) {
Compilations.reset(
new FixedCompilationDatabase(Twine(PathBuf), CC1Arguments));
+ // Create preprocessor tracker, to watch for macro and conditional problems.
+ OwningPtr<PreprocessorTracker> PPTracker(PreprocessorTracker::create());
+
// Parse all of the headers, detecting duplicates.
EntityMap Entities;
ClangTool Tool(*Compilations, Headers);
- int HadErrors = Tool.run(new ModularizeFrontendActionFactory(Entities));
+ int HadErrors =
+ Tool.run(new ModularizeFrontendActionFactory(Entities, *PPTracker));
// Create a place to save duplicate entity locations, separate bins per kind.
typedef SmallVector<Location, 8> LocationArray;
@@ -515,6 +535,16 @@ int main(int argc, const char **argv) {
}
}
+ // Complain about macro instance in header files that differ based on how
+ // they are included.
+ if (PPTracker->reportInconsistentMacros(errs()))
+ HadErrors = 1;
+
+ // Complain about preprocessor conditional directives in header files that
+ // differ based on how they are included.
+ if (PPTracker->reportInconsistentConditionals(errs()))
+ HadErrors = 1;
+
// Complain about any headers that have contents that differ based on how
// they are included.
// FIXME: Could we provide information about which preprocessor conditionals
@@ -530,7 +560,7 @@ int main(int argc, const char **argv) {
HadErrors = 1;
errs() << "error: header '" << H->first->getName()
- << "' has different contents depending on how it was included\n";
+ << "' has different contents depending on how it was included.\n";
for (unsigned I = 0, N = H->second.size(); I != N; ++I) {
errs() << "note: '" << H->second[I].Name << "' in "
<< H->second[I].Loc.File->getName() << " at "
OpenPOWER on IntegriCloud