1 //===--- Utils.h - Misc utilities for the front-end -------------*- 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 // This header contains miscellaneous utilities for various front-end actions. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_FRONTEND_UTILS_H 15 #define LLVM_CLANG_FRONTEND_UTILS_H 16 17 #include "clang/Basic/Diagnostic.h" 18 #include "clang/Basic/VirtualFileSystem.h" 19 #include "llvm/ADT/IntrusiveRefCntPtr.h" 20 #include "llvm/ADT/StringRef.h" 21 #include "llvm/ADT/StringSet.h" 22 #include "llvm/Option/OptSpecifier.h" 23 #include <utility> 24 25 namespace llvm { 26 class raw_fd_ostream; 27 class Triple; 28 29 namespace opt { 30 class ArgList; 31 } 32 } 33 34 namespace clang { 35 class ASTConsumer; 36 class ASTReader; 37 class CompilerInstance; 38 class CompilerInvocation; 39 class Decl; 40 class DependencyOutputOptions; 41 class DiagnosticsEngine; 42 class DiagnosticOptions; 43 class ExternalSemaSource; 44 class FileManager; 45 class HeaderSearch; 46 class HeaderSearchOptions; 47 class IdentifierTable; 48 class LangOptions; 49 class PCHContainerReader; 50 class Preprocessor; 51 class PreprocessorOptions; 52 class PreprocessorOutputOptions; 53 class SourceManager; 54 class Stmt; 55 class TargetInfo; 56 class FrontendOptions; 57 58 /// Apply the header search options to get given HeaderSearch object. 59 void ApplyHeaderSearchOptions(HeaderSearch &HS, 60 const HeaderSearchOptions &HSOpts, 61 const LangOptions &Lang, 62 const llvm::Triple &triple); 63 64 /// InitializePreprocessor - Initialize the preprocessor getting it and the 65 /// environment ready to process a single file. 66 void InitializePreprocessor(Preprocessor &PP, const PreprocessorOptions &PPOpts, 67 const PCHContainerReader &PCHContainerRdr, 68 const FrontendOptions &FEOpts); 69 70 /// DoPrintPreprocessedInput - Implement -E mode. 71 void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream* OS, 72 const PreprocessorOutputOptions &Opts); 73 74 /// An interface for collecting the dependencies of a compilation. Users should 75 /// use \c attachToPreprocessor and \c attachToASTReader to get all of the 76 /// dependencies. 77 /// FIXME: Migrate DependencyFileGen and DependencyGraphGen to use this 78 /// interface. 79 class DependencyCollector { 80 public: 81 virtual void attachToPreprocessor(Preprocessor &PP); 82 virtual void attachToASTReader(ASTReader &R); 83 llvm::ArrayRef<std::string> getDependencies() const { return Dependencies; } 84 85 /// Called when a new file is seen. Return true if \p Filename should be added 86 /// to the list of dependencies. 87 /// 88 /// The default implementation ignores <built-in> and system files. 89 virtual bool sawDependency(StringRef Filename, bool FromModule, 90 bool IsSystem, bool IsModuleFile, bool IsMissing); 91 /// Called when the end of the main file is reached. 92 virtual void finishedMainFile() { } 93 /// Return true if system files should be passed to sawDependency(). 94 virtual bool needSystemDependencies() { return false; } 95 virtual ~DependencyCollector(); 96 97 public: // implementation detail 98 /// Add a dependency \p Filename if it has not been seen before and 99 /// sawDependency() returns true. 100 void maybeAddDependency(StringRef Filename, bool FromModule, bool IsSystem, 101 bool IsModuleFile, bool IsMissing); 102 private: 103 llvm::StringSet<> Seen; 104 std::vector<std::string> Dependencies; 105 }; 106 107 /// Builds a depdenency file when attached to a Preprocessor (for includes) and 108 /// ASTReader (for module imports), and writes it out at the end of processing 109 /// a source file. Users should attach to the ast reader whenever a module is 110 /// loaded. 111 class DependencyFileGenerator { 112 void *Impl; // Opaque implementation 113 DependencyFileGenerator(void *Impl); 114 public: 115 static DependencyFileGenerator *CreateAndAttachToPreprocessor( 116 Preprocessor &PP, const DependencyOutputOptions &Opts); 117 void AttachToASTReader(ASTReader &R); 118 }; 119 120 /// Collects the dependencies for imported modules into a directory. Users 121 /// should attach to the AST reader whenever a module is loaded. 122 class ModuleDependencyCollector : public DependencyCollector { 123 std::string DestDir; 124 bool HasErrors = false; 125 llvm::StringSet<> Seen; 126 vfs::YAMLVFSWriter VFSWriter; 127 128 llvm::StringMap<std::string> SymLinkMap; 129 130 bool getRealPath(StringRef SrcPath, SmallVectorImpl<char> &Result); 131 std::error_code copyToRoot(StringRef Src); 132 public: 133 StringRef getDest() { return DestDir; } 134 bool insertSeen(StringRef Filename) { return Seen.insert(Filename).second; } 135 void addFile(StringRef Filename); 136 void addFileMapping(StringRef VPath, StringRef RPath) { 137 VFSWriter.addFileMapping(VPath, RPath); 138 } 139 140 void attachToPreprocessor(Preprocessor &PP) override; 141 void attachToASTReader(ASTReader &R) override; 142 143 void writeFileMap(); 144 bool hasErrors() { return HasErrors; } 145 ModuleDependencyCollector(std::string DestDir) 146 : DestDir(std::move(DestDir)) {} 147 ~ModuleDependencyCollector() { writeFileMap(); } 148 }; 149 150 /// AttachDependencyGraphGen - Create a dependency graph generator, and attach 151 /// it to the given preprocessor. 152 void AttachDependencyGraphGen(Preprocessor &PP, StringRef OutputFile, 153 StringRef SysRoot); 154 155 /// AttachHeaderIncludeGen - Create a header include list generator, and attach 156 /// it to the given preprocessor. 157 /// 158 /// \param DepOpts - Options controlling the output. 159 /// \param ShowAllHeaders - If true, show all header information instead of just 160 /// headers following the predefines buffer. This is useful for making sure 161 /// includes mentioned on the command line are also reported, but differs from 162 /// the default behavior used by -H. 163 /// \param OutputPath - If non-empty, a path to write the header include 164 /// information to, instead of writing to stderr. 165 /// \param ShowDepth - Whether to indent to show the nesting of the includes. 166 /// \param MSStyle - Whether to print in cl.exe /showIncludes style. 167 void AttachHeaderIncludeGen(Preprocessor &PP, 168 const DependencyOutputOptions &DepOpts, 169 bool ShowAllHeaders = false, 170 StringRef OutputPath = "", 171 bool ShowDepth = true, bool MSStyle = false); 172 173 /// Cache tokens for use with PCH. Note that this requires a seekable stream. 174 void CacheTokens(Preprocessor &PP, raw_pwrite_stream *OS); 175 176 /// The ChainedIncludesSource class converts headers to chained PCHs in 177 /// memory, mainly for testing. 178 IntrusiveRefCntPtr<ExternalSemaSource> 179 createChainedIncludesSource(CompilerInstance &CI, 180 IntrusiveRefCntPtr<ExternalSemaSource> &Reader); 181 182 /// createInvocationFromCommandLine - Construct a compiler invocation object for 183 /// a command line argument vector. 184 /// 185 /// \return A CompilerInvocation, or 0 if none was built for the given 186 /// argument vector. 187 CompilerInvocation * 188 createInvocationFromCommandLine(ArrayRef<const char *> Args, 189 IntrusiveRefCntPtr<DiagnosticsEngine> Diags = 190 IntrusiveRefCntPtr<DiagnosticsEngine>()); 191 192 /// Return the value of the last argument as an integer, or a default. If Diags 193 /// is non-null, emits an error if the argument is given, but non-integral. 194 int getLastArgIntValue(const llvm::opt::ArgList &Args, 195 llvm::opt::OptSpecifier Id, int Default, 196 DiagnosticsEngine *Diags = nullptr); 197 198 inline int getLastArgIntValue(const llvm::opt::ArgList &Args, 199 llvm::opt::OptSpecifier Id, int Default, 200 DiagnosticsEngine &Diags) { 201 return getLastArgIntValue(Args, Id, Default, &Diags); 202 } 203 204 uint64_t getLastArgUInt64Value(const llvm::opt::ArgList &Args, 205 llvm::opt::OptSpecifier Id, uint64_t Default, 206 DiagnosticsEngine *Diags = nullptr); 207 208 inline uint64_t getLastArgUInt64Value(const llvm::opt::ArgList &Args, 209 llvm::opt::OptSpecifier Id, 210 uint64_t Default, 211 DiagnosticsEngine &Diags) { 212 return getLastArgUInt64Value(Args, Id, Default, &Diags); 213 } 214 215 // When Clang->getFrontendOpts().DisableFree is set we don't delete some of the 216 // global objects, but we don't want LeakDetectors to complain, so we bury them 217 // in a globally visible array. 218 void BuryPointer(const void *Ptr); 219 template <typename T> void BuryPointer(std::unique_ptr<T> Ptr) { 220 BuryPointer(Ptr.release()); 221 } 222 223 } // end namespace clang 224 225 #endif 226