Utils.h 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- Utils.h - Misc utilities for the front-end ---------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This header contains miscellaneous utilities for various front-end actions.
  15. //
  16. //===----------------------------------------------------------------------===//
  17. #ifndef LLVM_CLANG_FRONTEND_UTILS_H
  18. #define LLVM_CLANG_FRONTEND_UTILS_H
  19. #include "clang/Basic/Diagnostic.h"
  20. #include "clang/Basic/LLVM.h"
  21. #include "clang/Driver/OptionUtils.h"
  22. #include "clang/Frontend/DependencyOutputOptions.h"
  23. #include "llvm/ADT/ArrayRef.h"
  24. #include "llvm/ADT/IntrusiveRefCntPtr.h"
  25. #include "llvm/ADT/StringMap.h"
  26. #include "llvm/ADT/StringRef.h"
  27. #include "llvm/ADT/StringSet.h"
  28. #include "llvm/Option/OptSpecifier.h"
  29. #include "llvm/Support/FileCollector.h"
  30. #include "llvm/Support/VirtualFileSystem.h"
  31. #include <cstdint>
  32. #include <memory>
  33. #include <string>
  34. #include <system_error>
  35. #include <utility>
  36. #include <vector>
  37. namespace clang {
  38. class ASTReader;
  39. class CompilerInstance;
  40. class CompilerInvocation;
  41. class DiagnosticsEngine;
  42. class ExternalSemaSource;
  43. class FrontendOptions;
  44. class PCHContainerReader;
  45. class Preprocessor;
  46. class PreprocessorOptions;
  47. class PreprocessorOutputOptions;
  48. /// InitializePreprocessor - Initialize the preprocessor getting it and the
  49. /// environment ready to process a single file.
  50. void InitializePreprocessor(Preprocessor &PP, const PreprocessorOptions &PPOpts,
  51. const PCHContainerReader &PCHContainerRdr,
  52. const FrontendOptions &FEOpts);
  53. /// DoPrintPreprocessedInput - Implement -E mode.
  54. void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream *OS,
  55. const PreprocessorOutputOptions &Opts);
  56. /// An interface for collecting the dependencies of a compilation. Users should
  57. /// use \c attachToPreprocessor and \c attachToASTReader to get all of the
  58. /// dependencies.
  59. /// FIXME: Migrate DependencyGraphGen to use this interface.
  60. class DependencyCollector {
  61. public:
  62. virtual ~DependencyCollector();
  63. virtual void attachToPreprocessor(Preprocessor &PP);
  64. virtual void attachToASTReader(ASTReader &R);
  65. ArrayRef<std::string> getDependencies() const { return Dependencies; }
  66. /// Called when a new file is seen. Return true if \p Filename should be added
  67. /// to the list of dependencies.
  68. ///
  69. /// The default implementation ignores <built-in> and system files.
  70. virtual bool sawDependency(StringRef Filename, bool FromModule,
  71. bool IsSystem, bool IsModuleFile, bool IsMissing);
  72. /// Called when the end of the main file is reached.
  73. virtual void finishedMainFile(DiagnosticsEngine &Diags) {}
  74. /// Return true if system files should be passed to sawDependency().
  75. virtual bool needSystemDependencies() { return false; }
  76. /// Add a dependency \p Filename if it has not been seen before and
  77. /// sawDependency() returns true.
  78. virtual void maybeAddDependency(StringRef Filename, bool FromModule,
  79. bool IsSystem, bool IsModuleFile,
  80. bool IsMissing);
  81. protected:
  82. /// Return true if the filename was added to the list of dependencies, false
  83. /// otherwise.
  84. bool addDependency(StringRef Filename);
  85. private:
  86. llvm::StringSet<> Seen;
  87. std::vector<std::string> Dependencies;
  88. };
  89. /// Builds a dependency file when attached to a Preprocessor (for includes) and
  90. /// ASTReader (for module imports), and writes it out at the end of processing
  91. /// a source file. Users should attach to the ast reader whenever a module is
  92. /// loaded.
  93. class DependencyFileGenerator : public DependencyCollector {
  94. public:
  95. DependencyFileGenerator(const DependencyOutputOptions &Opts);
  96. void attachToPreprocessor(Preprocessor &PP) override;
  97. void finishedMainFile(DiagnosticsEngine &Diags) override;
  98. bool needSystemDependencies() final override { return IncludeSystemHeaders; }
  99. bool sawDependency(StringRef Filename, bool FromModule, bool IsSystem,
  100. bool IsModuleFile, bool IsMissing) final override;
  101. protected:
  102. void outputDependencyFile(llvm::raw_ostream &OS);
  103. private:
  104. void outputDependencyFile(DiagnosticsEngine &Diags);
  105. std::string OutputFile;
  106. std::vector<std::string> Targets;
  107. bool IncludeSystemHeaders;
  108. bool PhonyTarget;
  109. bool AddMissingHeaderDeps;
  110. bool SeenMissingHeader;
  111. bool IncludeModuleFiles;
  112. DependencyOutputFormat OutputFormat;
  113. unsigned InputFileIndex;
  114. };
  115. /// Collects the dependencies for imported modules into a directory. Users
  116. /// should attach to the AST reader whenever a module is loaded.
  117. class ModuleDependencyCollector : public DependencyCollector {
  118. std::string DestDir;
  119. bool HasErrors = false;
  120. llvm::StringSet<> Seen;
  121. llvm::vfs::YAMLVFSWriter VFSWriter;
  122. llvm::FileCollector::PathCanonicalizer Canonicalizer;
  123. std::error_code copyToRoot(StringRef Src, StringRef Dst = {});
  124. public:
  125. ModuleDependencyCollector(std::string DestDir)
  126. : DestDir(std::move(DestDir)) {}
  127. ~ModuleDependencyCollector() override { writeFileMap(); }
  128. StringRef getDest() { return DestDir; }
  129. virtual bool insertSeen(StringRef Filename) { return Seen.insert(Filename).second; }
  130. virtual void addFile(StringRef Filename, StringRef FileDst = {});
  131. virtual void addFileMapping(StringRef VPath, StringRef RPath) {
  132. VFSWriter.addFileMapping(VPath, RPath);
  133. }
  134. void attachToPreprocessor(Preprocessor &PP) override;
  135. void attachToASTReader(ASTReader &R) override;
  136. virtual void writeFileMap();
  137. virtual bool hasErrors() { return HasErrors; }
  138. };
  139. /// AttachDependencyGraphGen - Create a dependency graph generator, and attach
  140. /// it to the given preprocessor.
  141. void AttachDependencyGraphGen(Preprocessor &PP, StringRef OutputFile,
  142. StringRef SysRoot);
  143. /// AttachHeaderIncludeGen - Create a header include list generator, and attach
  144. /// it to the given preprocessor.
  145. ///
  146. /// \param DepOpts - Options controlling the output.
  147. /// \param ShowAllHeaders - If true, show all header information instead of just
  148. /// headers following the predefines buffer. This is useful for making sure
  149. /// includes mentioned on the command line are also reported, but differs from
  150. /// the default behavior used by -H.
  151. /// \param OutputPath - If non-empty, a path to write the header include
  152. /// information to, instead of writing to stderr.
  153. /// \param ShowDepth - Whether to indent to show the nesting of the includes.
  154. /// \param MSStyle - Whether to print in cl.exe /showIncludes style.
  155. void AttachHeaderIncludeGen(Preprocessor &PP,
  156. const DependencyOutputOptions &DepOpts,
  157. bool ShowAllHeaders = false,
  158. StringRef OutputPath = {},
  159. bool ShowDepth = true, bool MSStyle = false);
  160. /// The ChainedIncludesSource class converts headers to chained PCHs in
  161. /// memory, mainly for testing.
  162. IntrusiveRefCntPtr<ExternalSemaSource>
  163. createChainedIncludesSource(CompilerInstance &CI,
  164. IntrusiveRefCntPtr<ExternalSemaSource> &Reader);
  165. /// createInvocationFromCommandLine - Construct a compiler invocation object for
  166. /// a command line argument vector.
  167. ///
  168. /// \param ShouldRecoverOnErrors - whether we should attempt to return a
  169. /// non-null (and possibly incorrect) CompilerInvocation if any errors were
  170. /// encountered. When this flag is false, always return null on errors.
  171. ///
  172. /// \param CC1Args - if non-null, will be populated with the args to cc1
  173. /// expanded from \p Args. May be set even if nullptr is returned.
  174. ///
  175. /// \return A CompilerInvocation, or nullptr if none was built for the given
  176. /// argument vector.
  177. std::unique_ptr<CompilerInvocation> createInvocationFromCommandLine(
  178. ArrayRef<const char *> Args,
  179. IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
  180. IntrusiveRefCntPtr<DiagnosticsEngine>(),
  181. IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS = nullptr,
  182. bool ShouldRecoverOnErrors = false,
  183. std::vector<std::string> *CC1Args = nullptr);
  184. // Frontend timing utils
  185. } // namespace clang
  186. #endif // LLVM_CLANG_FRONTEND_UTILS_H
  187. #ifdef __GNUC__
  188. #pragma GCC diagnostic pop
  189. #endif