1 //===- PreprocessorTracker.h - Tracks preprocessor activities -*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===--------------------------------------------------------------------===// 9 /// 10 /// \file 11 /// \brief Macro expansions and preprocessor conditional consistency checker. 12 /// 13 //===--------------------------------------------------------------------===// 14 15 #ifndef MODULARIZE_PREPROCESSOR_TRACKER_H 16 #define MODULARIZE_PREPROCESSOR_TRACKER_H 17 18 #include "clang/Lex/Preprocessor.h" 19 20 namespace Modularize { 21 22 /// \brief Preprocessor tracker for modularize. 23 /// 24 /// The PreprocessorTracker class defines an API for 25 /// checking macro expansions and preprocessor conditional expressions 26 /// in a header file for consistency among one or more compilations of 27 /// the header in a #include scenario. This is for helping a user 28 /// find which macro expansions or conditionals might be problematic with 29 /// respect to using the headers in the modules scenario, because they 30 /// evaluate to different values depending on how or where a header 31 /// is included. 32 /// 33 /// The handlePreprocessorEntry function implementation will register 34 /// a PPCallbacks object in the given Preprocessor object. The calls to 35 /// the callbacks will collect information about the macro expansions 36 /// and preprocessor conditionals encountered, for later analysis and 37 /// reporting of inconsistencies between runs performed by calls to 38 /// the reportInconsistentMacros and reportInconsistentConditionals 39 /// functions respectively. The handlePreprocessorExit informs the 40 /// implementation that a preprocessing session is complete, allowing 41 /// it to do any needed compilation completion activities in the checker. 42 class PreprocessorTracker { 43 public: 44 virtual ~PreprocessorTracker(); 45 46 // Handle entering a preprocessing session. 47 // (Called after a Preprocessor object is created, but before preprocessing.) 48 virtual void handlePreprocessorEntry(clang::Preprocessor &PP, 49 llvm::StringRef RootHeaderFile) = 0; 50 // Handle exiting a preprocessing session. 51 // (Called after preprocessing is complete, but before the Preprocessor 52 // object is destroyed.) 53 virtual void handlePreprocessorExit() = 0; 54 55 // Handle include directive. 56 // This function is called every time an include directive is seen by the 57 // preprocessor, for the purpose of later checking for 'extern "" {}' or 58 // "namespace {}" blocks containing #include directives. 59 virtual void handleIncludeDirective(llvm::StringRef DirectivePath, 60 int DirectiveLine, int DirectiveColumn, 61 llvm::StringRef TargetPath) = 0; 62 63 // Check for include directives within the given source line range. 64 // Report errors if any found. Returns true if no include directives 65 // found in block. 66 virtual bool checkForIncludesInBlock(clang::Preprocessor &PP, 67 clang::SourceRange BlockSourceRange, 68 const char *BlockIdentifierMessage, 69 llvm::raw_ostream &OS) = 0; 70 71 // Report on inconsistent macro instances. 72 // Returns true if any mismatches. 73 virtual bool reportInconsistentMacros(llvm::raw_ostream &OS) = 0; 74 75 // Report on inconsistent conditional directive instances. 76 // Returns true if any mismatches. 77 virtual bool reportInconsistentConditionals(llvm::raw_ostream &OS) = 0; 78 79 // Create instance of PreprocessorTracker. 80 static PreprocessorTracker *create( 81 llvm::SmallVector<std::string, 32> &Headers, 82 bool DoBlockCheckHeaderListOnly); 83 }; 84 85 } // end namespace Modularize 86 87 #endif 88