diff options
Diffstat (limited to 'clang-tools-extra/modularize/Modularize.cpp')
-rw-r--r-- | clang-tools-extra/modularize/Modularize.cpp | 46 |
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 " |