ASTUnit.h revision abc563f554951259bbe0315055cad92ee14d87e4
1150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan//===--- ASTUnit.h - ASTUnit utility ----------------------------*- C++ -*-===// 2150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan// 3150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan// The LLVM Compiler Infrastructure 4150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan// 5150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan// This file is distributed under the University of Illinois Open Source 6150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan// License. See LICENSE.TXT for details. 7150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan// 8ac774a74e9ac234cb38c90ede73b337a8b1a629dLogan//===----------------------------------------------------------------------===// 9150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan// 10b2dad2eb089019c73935e568087a03be1653d140Logan// ASTUnit utility class. 11b2dad2eb089019c73935e568087a03be1653d140Logan// 12150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan//===----------------------------------------------------------------------===// 13150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan 14150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan#ifndef LLVM_CLANG_FRONTEND_ASTUNIT_H 15150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan#define LLVM_CLANG_FRONTEND_ASTUNIT_H 16150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan 17150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan#include "clang/Lex/PreprocessingRecord.h" 18150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan#include "clang/Basic/SourceManager.h" 19150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan#include "llvm/ADT/IntrusiveRefCntPtr.h" 20150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan#include "llvm/ADT/OwningPtr.h" 21150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan#include "clang/Basic/FileManager.h" 22150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan#include "clang/Index/ASTLocation.h" 23150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan#include "llvm/ADT/SmallVector.h" 24150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan#include "llvm/System/Path.h" 25150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan#include <map> 26150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan#include <string> 27150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan#include <vector> 28150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan#include <cassert> 298f00e2be0e639dcacb2719f34b24d5387fe32f93Shih-wei Liao#include <utility> 30150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan 31150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logannamespace llvm { 32150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan class MemoryBuffer; 33e5cc4c967178669dd19832bc0fb03b293d5d969fStephen Hines} 34e5cc4c967178669dd19832bc0fb03b293d5d969fStephen Hines 35150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logannamespace clang { 36150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Loganclass ASTContext; 37d271e4b0c6c42a0e670226e697963df427e35a56Logan Chienclass CompilerInvocation; 38d271e4b0c6c42a0e670226e697963df427e35a56Logan Chienclass Decl; 39d271e4b0c6c42a0e670226e697963df427e35a56Logan Chienclass Diagnostic; 40150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Loganclass FileEntry; 41560ad31c413724fafd13d6fd723e403f28daa132Shih-wei Liaoclass FileManager; 42150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Loganclass HeaderSearch; 43150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Loganclass Preprocessor; 44150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Loganclass SourceManager; 45150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Loganclass TargetInfo; 46150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan 4779525fbe7b9bdf64a79a8d20cff2147702eae738Stephen Hinesusing namespace idx; 48150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan 490a9399c6726563f480537649e6f28da5186c4b78Nowar Gu/// \brief Utility class for loading a ASTContext from a PCH file. 5050b2af40295eadba516c5e85ec1bb3443d64aae3Logan Chien/// 51cb9b577d473e0af82e3fadf0c7b85cd04b3018a7Logan Chienclass ASTUnit { 5250b2af40295eadba516c5e85ec1bb3443d64aae3Logan Chienpublic: 53cb9b577d473e0af82e3fadf0c7b85cd04b3018a7Logan Chien typedef std::map<FileID, std::vector<PreprocessedEntity *> > 5450b2af40295eadba516c5e85ec1bb3443d64aae3Logan Chien PreprocessedEntitiesByFileMap; 5550b2af40295eadba516c5e85ec1bb3443d64aae3Logan Chienprivate: 5650b2af40295eadba516c5e85ec1bb3443d64aae3Logan Chien llvm::IntrusiveRefCntPtr<Diagnostic> Diagnostics; 57150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan llvm::OwningPtr<FileManager> FileMgr; 58150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan llvm::OwningPtr<SourceManager> SourceMgr; 59150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan llvm::OwningPtr<HeaderSearch> HeaderInfo; 60150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan llvm::OwningPtr<TargetInfo> Target; 610a9399c6726563f480537649e6f28da5186c4b78Nowar Gu llvm::OwningPtr<Preprocessor> PP; 62fe6bd6dc51777802a0118521b9039981a0e6a806Logan Chien llvm::OwningPtr<ASTContext> Ctx; 63d271e4b0c6c42a0e670226e697963df427e35a56Logan Chien 644652e307dc8fc772d0df8c6c434613884fe0feecStephen Hines /// Optional owned invocation, just used to make the invocation used in 654652e307dc8fc772d0df8c6c434613884fe0feecStephen Hines /// LoadFromCommandLine available. 664652e307dc8fc772d0df8c6c434613884fe0feecStephen Hines llvm::OwningPtr<CompilerInvocation> Invocation; 674652e307dc8fc772d0df8c6c434613884fe0feecStephen Hines 684652e307dc8fc772d0df8c6c434613884fe0feecStephen Hines // OnlyLocalDecls - when true, walking this AST should only visit declarations 694652e307dc8fc772d0df8c6c434613884fe0feecStephen Hines // that come from the AST itself, not from included precompiled headers. 704652e307dc8fc772d0df8c6c434613884fe0feecStephen Hines // FIXME: This is temporary; eventually, CIndex will always do this. 71b491e684395ee19123abdd73b75776fea966d8cfStephen Hines bool OnlyLocalDecls; 72150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan 73150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan /// \brief Whether to capture any diagnostics produced. 74150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan bool CaptureDiagnostics; 75150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan 76150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan /// Track whether the main file was loaded from an AST or not. 77fe6bd6dc51777802a0118521b9039981a0e6a806Logan Chien bool MainFileIsAST; 78fe6bd6dc51777802a0118521b9039981a0e6a806Logan Chien 79150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan /// Track the top-level decls which appeared in an ASTUnit which was loaded 800c115a16d479c7cda12c66bceb3782fd45177481Nowar Gu /// from a source file. 81150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan // 823a936caf79bc7448ac5ec60c14faeb87c74e5392Stephen Hines // FIXME: This is just an optimization hack to avoid deserializing large parts 83150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan // of a PCH file when using the Index library on an ASTUnit loaded from 84150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan // source. In the long term we should make the Index library use efficient and 85150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan // more scalable search mechanisms. 86150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan std::vector<Decl*> TopLevelDecls; 87bd3aca04d304b9f31240b94af0aad818f6f932abStephen Hines 88150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan /// The name of the original source file used to generate this ASTUnit. 89361035524dc26094825134f30c07311f38f4f8b1Stephen Hines std::string OriginalSourceFile; 90150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan 91150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan // Critical optimization when using clang_getCursor(). 92a902511dd22624b15cc61e36d167d1cf3549bc74Stephen Hines ASTLocation LastLoc; 93150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan 946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /// \brief The set of diagnostics produced when creating this 956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines /// translation unit. 966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines llvm::SmallVector<StoredDiagnostic, 4> StoredDiagnostics; 97150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan 98177982bea7e4ccffd2577c8f63a5872eebebe54bStephen Hines /// \brief Temporary files that should be removed when the ASTUnit is 99177982bea7e4ccffd2577c8f63a5872eebebe54bStephen Hines /// destroyed. 100177982bea7e4ccffd2577c8f63a5872eebebe54bStephen Hines llvm::SmallVector<llvm::sys::Path, 4> TemporaryFiles; 101177982bea7e4ccffd2577c8f63a5872eebebe54bStephen Hines 102177982bea7e4ccffd2577c8f63a5872eebebe54bStephen Hines /// \brief A mapping from file IDs to the set of preprocessed entities 103177982bea7e4ccffd2577c8f63a5872eebebe54bStephen Hines /// stored in that file. 104150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan /// 105150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan /// FIXME: This is just an optimization hack to avoid searching through 106150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan /// many preprocessed entities during cursor traversal in the CIndex library. 107150e0efec6302fa5a8c3b5c3c4ecf5778d3a29f5Logan /// Ideally, we would just be able to perform a binary search within the 108952626a19a1c58e405be194854566b76a35b6063Andrew Hsieh /// list of preprocessed entities. 109ce5d5dc827d36f09a1df7d1bec48b0bb429d6afaStephen Hines PreprocessedEntitiesByFileMap PreprocessedEntitiesByFile; 110e7ea4e58ac544083d9052b1a7f8aabec750afac3Ying Wang 111e7ea4e58ac544083d9052b1a7f8aabec750afac3Ying Wang /// \brief Simple hack to allow us to assert that ASTUnit is not being 112e7ea4e58ac544083d9052b1a7f8aabec750afac3Ying Wang /// used concurrently, which is not supported. 113e7ea4e58ac544083d9052b1a7f8aabec750afac3Ying Wang /// 114e7ea4e58ac544083d9052b1a7f8aabec750afac3Ying Wang /// Clients should create instances of the ConcurrencyCheck class whenever 11517fe6b86205261afc93f7689a73da21a83e0cc65Tim Murray /// using the ASTUnit in a way that isn't intended to be concurrent, which is 116ef8225444452a1486bd721f3285301fe84643b00Stephen Hines /// just about any usage. 117ef8225444452a1486bd721f3285301fe84643b00Stephen Hines unsigned int ConcurrencyCheckValue; 118e7ea4e58ac544083d9052b1a7f8aabec750afac3Ying Wang static const unsigned int CheckLocked = 28573289; 119952626a19a1c58e405be194854566b76a35b6063Andrew Hsieh static const unsigned int CheckUnlocked = 9803453; 12017fe6b86205261afc93f7689a73da21a83e0cc65Tim Murray 121952626a19a1c58e405be194854566b76a35b6063Andrew Hsieh ASTUnit(const ASTUnit&); // DO NOT IMPLEMENT 122952626a19a1c58e405be194854566b76a35b6063Andrew Hsieh ASTUnit &operator=(const ASTUnit &); // DO NOT IMPLEMENT 123ce5d5dc827d36f09a1df7d1bec48b0bb429d6afaStephen Hines 124 explicit ASTUnit(bool MainFileIsAST); 125 126 void CleanTemporaryFiles(); 127 bool Parse(); 128 129public: 130 class ConcurrencyCheck { 131 volatile ASTUnit &Self; 132 133 public: 134 explicit ConcurrencyCheck(ASTUnit &Self) 135 : Self(Self) 136 { 137 assert(Self.ConcurrencyCheckValue == CheckUnlocked && 138 "Concurrent access to ASTUnit!"); 139 Self.ConcurrencyCheckValue = CheckLocked; 140 } 141 142 ~ConcurrencyCheck() { 143 Self.ConcurrencyCheckValue = CheckUnlocked; 144 } 145 }; 146 friend class ConcurrencyCheck; 147 148 ~ASTUnit(); 149 150 bool isMainFileAST() const { return MainFileIsAST; } 151 152 const Diagnostic &getDiagnostics() const { return *Diagnostics; } 153 Diagnostic &getDiagnostics() { return *Diagnostics; } 154 155 const SourceManager &getSourceManager() const { return *SourceMgr; } 156 SourceManager &getSourceManager() { return *SourceMgr; } 157 158 const Preprocessor &getPreprocessor() const { return *PP.get(); } 159 Preprocessor &getPreprocessor() { return *PP.get(); } 160 161 const ASTContext &getASTContext() const { return *Ctx.get(); } 162 ASTContext &getASTContext() { return *Ctx.get(); } 163 164 const FileManager &getFileManager() const { return *FileMgr; } 165 FileManager &getFileManager() { return *FileMgr; } 166 167 const std::string &getOriginalSourceFileName(); 168 const std::string &getPCHFileName(); 169 170 /// \brief Add a temporary file that the ASTUnit depends on. 171 /// 172 /// This file will be erased when the ASTUnit is destroyed. 173 void addTemporaryFile(const llvm::sys::Path &TempFile) { 174 TemporaryFiles.push_back(TempFile); 175 } 176 177 bool getOnlyLocalDecls() const { return OnlyLocalDecls; } 178 179 void setLastASTLocation(ASTLocation ALoc) { LastLoc = ALoc; } 180 ASTLocation getLastASTLocation() const { return LastLoc; } 181 182 std::vector<Decl*> &getTopLevelDecls() { 183 assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!"); 184 return TopLevelDecls; 185 } 186 const std::vector<Decl*> &getTopLevelDecls() const { 187 assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!"); 188 return TopLevelDecls; 189 } 190 191 /// \brief Retrieve the mapping from File IDs to the preprocessed entities 192 /// within that file. 193 PreprocessedEntitiesByFileMap &getPreprocessedEntitiesByFile() { 194 return PreprocessedEntitiesByFile; 195 } 196 197 // Retrieve the diagnostics associated with this AST 198 typedef const StoredDiagnostic *stored_diag_iterator; 199 stored_diag_iterator stored_diag_begin() const { 200 return StoredDiagnostics.begin(); 201 } 202 stored_diag_iterator stored_diag_end() const { 203 return StoredDiagnostics.end(); 204 } 205 unsigned stored_diag_size() const { return StoredDiagnostics.size(); } 206 207 llvm::SmallVector<StoredDiagnostic, 4> &getStoredDiagnostics() { 208 return StoredDiagnostics; 209 } 210 211 /// \brief A mapping from a file name to the memory buffer that stores the 212 /// remapped contents of that file. 213 typedef std::pair<std::string, const llvm::MemoryBuffer *> RemappedFile; 214 215 /// \brief Create a ASTUnit from a PCH file. 216 /// 217 /// \param Filename - The PCH file to load. 218 /// 219 /// \param Diags - The diagnostics engine to use for reporting errors; its 220 /// lifetime is expected to extend past that of the returned ASTUnit. 221 /// 222 /// \returns - The initialized ASTUnit or null if the PCH failed to load. 223 static ASTUnit *LoadFromPCHFile(const std::string &Filename, 224 llvm::IntrusiveRefCntPtr<Diagnostic> Diags, 225 bool OnlyLocalDecls = false, 226 RemappedFile *RemappedFiles = 0, 227 unsigned NumRemappedFiles = 0, 228 bool CaptureDiagnostics = false); 229 230 /// LoadFromCompilerInvocation - Create an ASTUnit from a source file, via a 231 /// CompilerInvocation object. 232 /// 233 /// \param CI - The compiler invocation to use; it must have exactly one input 234 /// source file. The ASTUnit takes ownership of the CompilerInvocation object. 235 /// 236 /// \param Diags - The diagnostics engine to use for reporting errors; its 237 /// lifetime is expected to extend past that of the returned ASTUnit. 238 // 239 // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we 240 // shouldn't need to specify them at construction time. 241 static ASTUnit *LoadFromCompilerInvocation(CompilerInvocation *CI, 242 llvm::IntrusiveRefCntPtr<Diagnostic> Diags, 243 bool OnlyLocalDecls = false, 244 bool CaptureDiagnostics = false); 245 246 /// LoadFromCommandLine - Create an ASTUnit from a vector of command line 247 /// arguments, which must specify exactly one source file. 248 /// 249 /// \param ArgBegin - The beginning of the argument vector. 250 /// 251 /// \param ArgEnd - The end of the argument vector. 252 /// 253 /// \param Diags - The diagnostics engine to use for reporting errors; its 254 /// lifetime is expected to extend past that of the returned ASTUnit. 255 /// 256 /// \param ResourceFilesPath - The path to the compiler resource files. 257 // 258 // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we 259 // shouldn't need to specify them at construction time. 260 static ASTUnit *LoadFromCommandLine(const char **ArgBegin, 261 const char **ArgEnd, 262 llvm::IntrusiveRefCntPtr<Diagnostic> Diags, 263 llvm::StringRef ResourceFilesPath, 264 bool OnlyLocalDecls = false, 265 RemappedFile *RemappedFiles = 0, 266 unsigned NumRemappedFiles = 0, 267 bool CaptureDiagnostics = false); 268 269 /// \brief Reparse the source files using the same command-line options that 270 /// were originally used to produce this translation unit. 271 /// 272 /// \returns True if a failure occurred that causes the ASTUnit not to 273 /// contain any translation-unit information, false otherwise. 274 bool Reparse(RemappedFile *RemappedFiles = 0, 275 unsigned NumRemappedFiles = 0); 276}; 277 278} // namespace clang 279 280#endif 281