//===-- ModuleMapChecker.h - Common defs for module-map-checker -*- C++ -*-==// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===--------------------------------------------------------------------===// /// /// \file /// \brief Common definitions for ModuleMapChecker. /// //===--------------------------------------------------------------------===// #ifndef MODULEMAPCHECKER_H #define MODULEMAPCHECKER_H #include "clang/Basic/Diagnostic.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" #include "clang/Frontend/TextDiagnosticPrinter.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/HeaderSearchOptions.h" #include "clang/Lex/ModuleMap.h" #include "clang/Lex/Preprocessor.h" #include "llvm/ADT/StringSet.h" #include "llvm/Support/Host.h" #include #include /// Subclass TargetOptions so we can construct it inline with /// the minimal option, the triple. class ModuleMapTargetOptions : public clang::TargetOptions { public: ModuleMapTargetOptions() { Triple = llvm::sys::getDefaultTargetTriple(); } }; /// Module map checker class. /// This is the heart of the checker. /// The doChecks function does the main work. /// The data members store the options and internally collected data. class ModuleMapChecker { // Checker arguments. /// The module.map file path. Can be relative or absolute. llvm::StringRef ModuleMapPath; /// The include paths to check for files. /// (Note that other directories above these paths are ignored. /// To expect all files to be accounted for from the module.map /// file directory on down, leave this empty.) std::vector IncludePaths; /// Flag to dump the module map information during check. bool DumpModuleMap; /// The remaining arguments, to be passed to the front end. llvm::ArrayRef CommandLine; // Supporting objects. /// Options controlling the language variant. std::shared_ptr LangOpts; /// Diagnostic IDs. const llvm::IntrusiveRefCntPtr DiagIDs; /// Options controlling the diagnostic engine. llvm::IntrusiveRefCntPtr DiagnosticOpts; /// Diagnostic consumer. clang::TextDiagnosticPrinter DC; /// Diagnostic engine. llvm::IntrusiveRefCntPtr Diagnostics; /// Options controlling the target. std::shared_ptr TargetOpts; /// Target information. llvm::IntrusiveRefCntPtr Target; /// Options controlling the file system manager. clang::FileSystemOptions FileSystemOpts; /// File system manager. llvm::IntrusiveRefCntPtr FileMgr; /// Source manager. llvm::IntrusiveRefCntPtr SourceMgr; /// Options controlling the \#include directive. llvm::IntrusiveRefCntPtr HeaderSearchOpts; /// Header search manager. std::unique_ptr HeaderInfo; /// The module map. std::unique_ptr ModMap; // Internal data. /// Directory containing the module map. /// Might be relative to the current directory, or absolute. std::string ModuleMapDirectory; /// Set of all the headers found in the module map. llvm::StringSet ModuleMapHeadersSet; /// All the headers found in the file system starting at the /// module map, or the union of those from the include paths. std::vector FileSystemHeaders; /// Headers found in file system, but not in module map. std::vector UnaccountedForHeaders; public: /// Constructor. /// You can use the static createModuleMapChecker to create an instance /// of this object. /// \param ModuleMapPath The module.map file path. /// Can be relative or absolute. /// \param IncludePaths The include paths to check for files. /// (Note that other directories above these paths are ignored. /// To expect all files to be accounted for from the module.map /// file directory on down, leave this empty.) /// \param DumpModuleMap Flag to dump the module map information /// during check. ModuleMapChecker(llvm::StringRef ModuleMapPath, std::vector &IncludePaths, bool DumpModuleMap, llvm::ArrayRef CommandLine); /// Create instance of ModuleMapChecker. /// \param ModuleMapPath The module.map file path. /// Can be relative or absolute. /// \param IncludePaths The include paths to check for files. /// (Note that other directories above these paths are ignored. /// To expect all files to be accounted for from the module.map /// file directory on down, leave this empty.) /// \param DumpModuleMap Flag to dump the module map information /// during check. /// \returns Initialized ModuleMapChecker object. static ModuleMapChecker *createModuleMapChecker( llvm::StringRef ModuleMapPath, std::vector &IncludePaths, bool DumpModuleMap, llvm::ArrayRef CommandLine); /// Do checks. /// Starting from the directory of the module.map file, /// Find all header files, optionally looking only at files /// covered by the include path options, and compare against /// the headers referenced by the module.map file. /// Display warnings for unaccounted-for header files. /// \returns 0 if there were no errors or warnings, 1 if there /// were warnings, 2 if any other problem, such as a bad /// module map path argument was specified. std::error_code doChecks(); // The following functions are called by doChecks. /// Load module map. /// \returns True if module.map file loaded successfully. bool loadModuleMap(); /// Collect module headers. /// Walks the modules and collects referenced headers into /// ModuleMapHeadersSet. void collectModuleHeaders(); /// Collect referenced headers from one module. /// Collects the headers referenced in the given module into /// ModuleMapHeadersSet. /// \param Mod The module reference. /// \return True if no errors. bool collectModuleHeaders(const clang::Module &Mod); /// Collect headers from an umbrella directory. /// \param UmbrellaDirName The umbrella directory name. /// \return True if no errors. bool collectUmbrellaHeaders(llvm::StringRef UmbrellaDirName); /// Collect headers rferenced from an umbrella file. /// \param UmbrellaHeaderName The umbrella file path. /// \return True if no errors. bool collectUmbrellaHeaderHeaders(llvm::StringRef UmbrellaHeaderName); /// Called from ModuleMapCheckerCallbacks to track a header included /// from an umbrella header. /// \param HeaderName The header file path. void collectUmbrellaHeaderHeader(llvm::StringRef HeaderName); /// Collect file system header files. /// This function scans the file system for header files, /// starting at the directory of the module.map file, /// optionally filtering out all but the files covered by /// the include path options. /// \returns True if no errors. bool collectFileSystemHeaders(); /// Collect file system header files from the given path. /// This function scans the file system for header files, /// starting at the given directory, which is assumed to be /// relative to the directory of the module.map file. /// \returns True if no errors. bool collectFileSystemHeaders(llvm::StringRef IncludePath); /// Find headers unaccounted-for in module map. /// This function compares the list of collected header files /// against those referenced in the module map. Display /// warnings for unaccounted-for header files. /// Save unaccounted-for file list for possible. /// fixing action. void findUnaccountedForHeaders(); // Utility functions. /// Get directory path component from file path. /// \returns the component of the given path, which will be /// relative if the given path is relative, absolute if the /// given path is absolute, or "." if the path has no leading /// path component. std::string getDirectoryFromPath(llvm::StringRef Path); /// Convert header path to canonical form. /// The canonical form is basically just use forward slashes, /// and remove "./". /// \param FilePath The file path. /// \returns The file path in canonical form. std::string getCanonicalPath(llvm::StringRef FilePath); /// Check for header file extension. /// If the file extension is .h, .inc, or missing, it's /// assumed to be a header. /// \param FileName The file name. Must not be a directory. /// \returns true if it has a header extension or no extension. bool isHeader(llvm::StringRef FileName); }; #endif // MODULEMAPCHECKER_H