reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
//===-- CoverageChecker.h - Module map coverage checker -*- C++ -*-------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===--------------------------------------------------------------------===//
///
/// \file
/// Definitions for CoverageChecker.
///
//===--------------------------------------------------------------------===//

#ifndef COVERAGECHECKER_H
#define COVERAGECHECKER_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 <string>
#include <vector>

namespace Modularize {

/// 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 CoverageChecker {
  // Checker arguments.

  /// The module.modulemap 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.modulemap
  /// file directory on down, leave this empty.)
  std::vector<std::string> IncludePaths;
  /// The remaining arguments, to be passed to the front end.
  llvm::ArrayRef<std::string> CommandLine;
  /// The module map.
  clang::ModuleMap *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<llvm::MallocAllocator> 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<std::string> FileSystemHeaders;
  /// Headers found in file system, but not in module map.
  std::vector<std::string> UnaccountedForHeaders;

public:
  /// Constructor.
  /// You can use the static createCoverageChecker to create an instance
  /// of this object.
  /// \param ModuleMapPath The module.modulemap 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.modulemap
  ///   file directory on down, leave this empty.)
  /// \param CommandLine Compile command line arguments.
  /// \param ModuleMap The module map to check.
  CoverageChecker(llvm::StringRef ModuleMapPath,
    std::vector<std::string> &IncludePaths,
    llvm::ArrayRef<std::string> CommandLine,
    clang::ModuleMap *ModuleMap);

  /// Create instance of CoverageChecker.
  /// \param ModuleMapPath The module.modulemap 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.modulemap
  ///   file directory on down, leave this empty.)
  /// \param CommandLine Compile command line arguments.
  /// \param ModuleMap The module map to check.
  /// \returns Initialized CoverageChecker object.
  static std::unique_ptr<CoverageChecker> createCoverageChecker(
      llvm::StringRef ModuleMapPath, std::vector<std::string> &IncludePaths,
      llvm::ArrayRef<std::string> CommandLine, clang::ModuleMap *ModuleMap);

  /// Do checks.
  /// Starting from the directory of the module.modulemap 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.modulemap 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.

  /// 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 CoverageCheckerCallbacks 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.modulemap 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.modulemap 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();
};

} // end namespace Modularize

#endif // COVERAGECHECKER_H