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