ASTUnit.h revision 667514d92afd1485765cb4e2bbe452883adc989b
1//===--- ASTUnit.h - ASTUnit utility ----------------------------*- 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// ASTUnit utility class. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_CLANG_FRONTEND_ASTUNIT_H 15#define LLVM_CLANG_FRONTEND_ASTUNIT_H 16 17#include "clang/Basic/SourceManager.h" 18#include "llvm/ADT/OwningPtr.h" 19#include "clang/Basic/FileManager.h" 20#include "clang/Index/ASTLocation.h" 21#include "llvm/ADT/SmallVector.h" 22#include "llvm/System/Path.h" 23#include <string> 24#include <vector> 25#include <cassert> 26#include <utility> 27 28namespace llvm { 29 class MemoryBuffer; 30} 31 32namespace clang { 33class ASTContext; 34class CompilerInvocation; 35class Decl; 36class Diagnostic; 37class FileEntry; 38class FileManager; 39class HeaderSearch; 40class Preprocessor; 41class SourceManager; 42class TargetInfo; 43 44using namespace idx; 45 46/// \brief Utility class for loading a ASTContext from a PCH file. 47/// 48class ASTUnit { 49 FileManager FileMgr; 50 51 SourceManager SourceMgr; 52 llvm::OwningPtr<HeaderSearch> HeaderInfo; 53 llvm::OwningPtr<TargetInfo> Target; 54 llvm::OwningPtr<Preprocessor> PP; 55 llvm::OwningPtr<ASTContext> Ctx; 56 57 /// Optional owned invocation, just used to make the invocation used in 58 /// LoadFromCommandLine available. 59 llvm::OwningPtr<CompilerInvocation> Invocation; 60 61 // OnlyLocalDecls - when true, walking this AST should only visit declarations 62 // that come from the AST itself, not from included precompiled headers. 63 // FIXME: This is temporary; eventually, CIndex will always do this. 64 bool OnlyLocalDecls; 65 66 /// Track whether the main file was loaded from an AST or not. 67 bool MainFileIsAST; 68 69 /// Track the top-level decls which appeared in an ASTUnit which was loaded 70 /// from a source file. 71 // 72 // FIXME: This is just an optimization hack to avoid deserializing large parts 73 // of a PCH file when using the Index library on an ASTUnit loaded from 74 // source. In the long term we should make the Index library use efficient and 75 // more scalable search mechanisms. 76 std::vector<Decl*> TopLevelDecls; 77 78 /// The name of the original source file used to generate this ASTUnit. 79 std::string OriginalSourceFile; 80 81 // Critical optimization when using clang_getCursor(). 82 ASTLocation LastLoc; 83 84 /// \brief The set of diagnostics produced when creating this 85 /// translation unit. 86 llvm::SmallVector<StoredDiagnostic, 4> Diagnostics; 87 88 /// \brief Temporary files that should be removed when the ASTUnit is 89 /// destroyed. 90 llvm::SmallVector<llvm::sys::Path, 4> TemporaryFiles; 91 92 /// \brief Simple hack to allow us to assert that ASTUnit is not being 93 /// used concurrently, which is not supported. 94 /// 95 /// Clients should create instances of the ConcurrencyCheck class whenever 96 /// using the ASTUnit in a way that isn't intended to be concurrent, which is 97 /// just about any usage. 98 unsigned int ConcurrencyCheckValue; 99 static const unsigned int CheckLocked = 28573289; 100 static const unsigned int CheckUnlocked = 9803453; 101 102 ASTUnit(const ASTUnit&); // DO NOT IMPLEMENT 103 ASTUnit &operator=(const ASTUnit &); // DO NOT IMPLEMENT 104 105public: 106 class ConcurrencyCheck { 107 volatile ASTUnit &Self; 108 109 public: 110 explicit ConcurrencyCheck(ASTUnit &Self) 111 : Self(Self) 112 { 113 assert(Self.ConcurrencyCheckValue == CheckUnlocked && 114 "Concurrent access to ASTUnit!"); 115 Self.ConcurrencyCheckValue = CheckLocked; 116 } 117 118 ~ConcurrencyCheck() { 119 Self.ConcurrencyCheckValue = CheckUnlocked; 120 } 121 }; 122 friend class ConcurrencyCheck; 123 124 ASTUnit(bool MainFileIsAST); 125 ~ASTUnit(); 126 127 bool isMainFileAST() const { return MainFileIsAST; } 128 129 const SourceManager &getSourceManager() const { return SourceMgr; } 130 SourceManager &getSourceManager() { return SourceMgr; } 131 132 const Preprocessor &getPreprocessor() const { return *PP.get(); } 133 Preprocessor &getPreprocessor() { return *PP.get(); } 134 135 const ASTContext &getASTContext() const { return *Ctx.get(); } 136 ASTContext &getASTContext() { return *Ctx.get(); } 137 138 const FileManager &getFileManager() const { return FileMgr; } 139 FileManager &getFileManager() { return FileMgr; } 140 141 const std::string &getOriginalSourceFileName(); 142 const std::string &getPCHFileName(); 143 144 /// \brief Add a temporary file that the ASTUnit depends on. 145 /// 146 /// This file will be erased when the ASTUnit is destroyed. 147 void addTemporaryFile(const llvm::sys::Path &TempFile) { 148 TemporaryFiles.push_back(TempFile); 149 } 150 151 bool getOnlyLocalDecls() const { return OnlyLocalDecls; } 152 153 void setLastASTLocation(ASTLocation ALoc) { LastLoc = ALoc; } 154 ASTLocation getLastASTLocation() const { return LastLoc; } 155 156 std::vector<Decl*> &getTopLevelDecls() { 157 assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!"); 158 return TopLevelDecls; 159 } 160 const std::vector<Decl*> &getTopLevelDecls() const { 161 assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!"); 162 return TopLevelDecls; 163 } 164 165 // Retrieve the diagnostics associated with this AST 166 typedef const StoredDiagnostic * diag_iterator; 167 diag_iterator diag_begin() const { return Diagnostics.begin(); } 168 diag_iterator diag_end() const { return Diagnostics.end(); } 169 unsigned diag_size() const { return Diagnostics.size(); } 170 llvm::SmallVector<StoredDiagnostic, 4> &getDiagnostics() { 171 return Diagnostics; 172 } 173 174 /// \brief A mapping from a file name to the memory buffer that stores the 175 /// remapped contents of that file. 176 typedef std::pair<std::string, const llvm::MemoryBuffer *> RemappedFile; 177 178 /// \brief Create a ASTUnit from a PCH file. 179 /// 180 /// \param Filename - The PCH file to load. 181 /// 182 /// \param Diags - The diagnostics engine to use for reporting errors; its 183 /// lifetime is expected to extend past that of the returned ASTUnit. 184 /// 185 /// \returns - The initialized ASTUnit or null if the PCH failed to load. 186 static ASTUnit *LoadFromPCHFile(const std::string &Filename, 187 Diagnostic &Diags, 188 bool OnlyLocalDecls = false, 189 RemappedFile *RemappedFiles = 0, 190 unsigned NumRemappedFiles = 0, 191 bool CaptureDiagnostics = false); 192 193 /// LoadFromCompilerInvocation - Create an ASTUnit from a source file, via a 194 /// CompilerInvocation object. 195 /// 196 /// \param CI - The compiler invocation to use; it must have exactly one input 197 /// source file. The ASTUnit takes ownership of the CompilerInvocation object. 198 /// 199 /// \param Diags - The diagnostics engine to use for reporting errors; its 200 /// lifetime is expected to extend past that of the returned ASTUnit. 201 // 202 // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we 203 // shouldn't need to specify them at construction time. 204 static ASTUnit *LoadFromCompilerInvocation(CompilerInvocation *CI, 205 Diagnostic &Diags, 206 bool OnlyLocalDecls = false, 207 bool CaptureDiagnostics = false); 208 209 /// LoadFromCommandLine - Create an ASTUnit from a vector of command line 210 /// arguments, which must specify exactly one source file. 211 /// 212 /// \param ArgBegin - The beginning of the argument vector. 213 /// 214 /// \param ArgEnd - The end of the argument vector. 215 /// 216 /// \param Diags - The diagnostics engine to use for reporting errors; its 217 /// lifetime is expected to extend past that of the returned ASTUnit. 218 /// 219 /// \param ResourceFilesPath - The path to the compiler resource files. 220 // 221 // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we 222 // shouldn't need to specify them at construction time. 223 static ASTUnit *LoadFromCommandLine(const char **ArgBegin, 224 const char **ArgEnd, 225 Diagnostic &Diags, 226 llvm::StringRef ResourceFilesPath, 227 bool OnlyLocalDecls = false, 228 RemappedFile *RemappedFiles = 0, 229 unsigned NumRemappedFiles = 0, 230 bool CaptureDiagnostics = false); 231}; 232 233} // namespace clang 234 235#endif 236