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