]>
Commit | Line | Data |
---|---|---|
223e47cc LB |
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/Serialization/ASTBitCodes.h" | |
18 | #include "clang/Sema/Sema.h" | |
19 | #include "clang/Sema/CodeCompleteConsumer.h" | |
20 | #include "clang/Lex/ModuleLoader.h" | |
21 | #include "clang/Lex/PreprocessingRecord.h" | |
22 | #include "clang/AST/ASTContext.h" | |
23 | #include "clang/Basic/LangOptions.h" | |
24 | #include "clang/Basic/SourceManager.h" | |
25 | #include "clang/Basic/FileManager.h" | |
26 | #include "clang/Basic/FileSystemOptions.h" | |
27 | #include "clang-c/Index.h" | |
28 | #include "llvm/ADT/IntrusiveRefCntPtr.h" | |
29 | #include "llvm/ADT/OwningPtr.h" | |
30 | #include "llvm/ADT/SmallVector.h" | |
31 | #include "llvm/ADT/StringMap.h" | |
32 | #include "llvm/Support/Path.h" | |
33 | #include <map> | |
34 | #include <string> | |
35 | #include <vector> | |
36 | #include <cassert> | |
37 | #include <utility> | |
38 | #include <sys/types.h> | |
39 | ||
40 | namespace llvm { | |
41 | class MemoryBuffer; | |
42 | } | |
43 | ||
44 | namespace clang { | |
45 | class ASTContext; | |
46 | class ASTReader; | |
47 | class CodeCompleteConsumer; | |
48 | class CompilerInvocation; | |
49 | class CompilerInstance; | |
50 | class Decl; | |
51 | class DiagnosticsEngine; | |
52 | class FileEntry; | |
53 | class FileManager; | |
54 | class HeaderSearch; | |
55 | class Preprocessor; | |
56 | class SourceManager; | |
57 | class TargetInfo; | |
58 | class ASTFrontendAction; | |
59 | ||
60 | /// \brief Utility class for loading a ASTContext from an AST file. | |
61 | /// | |
62 | class ASTUnit : public ModuleLoader { | |
63 | private: | |
64 | IntrusiveRefCntPtr<LangOptions> LangOpts; | |
65 | IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics; | |
66 | IntrusiveRefCntPtr<FileManager> FileMgr; | |
67 | IntrusiveRefCntPtr<SourceManager> SourceMgr; | |
68 | OwningPtr<HeaderSearch> HeaderInfo; | |
69 | IntrusiveRefCntPtr<TargetInfo> Target; | |
70 | IntrusiveRefCntPtr<Preprocessor> PP; | |
71 | IntrusiveRefCntPtr<ASTContext> Ctx; | |
72 | ASTReader *Reader; | |
73 | ||
74 | FileSystemOptions FileSystemOpts; | |
75 | ||
76 | /// \brief The AST consumer that received information about the translation | |
77 | /// unit as it was parsed or loaded. | |
78 | OwningPtr<ASTConsumer> Consumer; | |
79 | ||
80 | /// \brief The semantic analysis object used to type-check the translation | |
81 | /// unit. | |
82 | OwningPtr<Sema> TheSema; | |
83 | ||
84 | /// Optional owned invocation, just used to make the invocation used in | |
85 | /// LoadFromCommandLine available. | |
86 | IntrusiveRefCntPtr<CompilerInvocation> Invocation; | |
87 | ||
88 | /// \brief The set of target features. | |
89 | /// | |
90 | /// FIXME: each time we reparse, we need to restore the set of target | |
91 | /// features from this vector, because TargetInfo::CreateTargetInfo() | |
92 | /// mangles the target options in place. Yuck! | |
93 | std::vector<std::string> TargetFeatures; | |
94 | ||
95 | // OnlyLocalDecls - when true, walking this AST should only visit declarations | |
96 | // that come from the AST itself, not from included precompiled headers. | |
97 | // FIXME: This is temporary; eventually, CIndex will always do this. | |
98 | bool OnlyLocalDecls; | |
99 | ||
100 | /// \brief Whether to capture any diagnostics produced. | |
101 | bool CaptureDiagnostics; | |
102 | ||
103 | /// \brief Track whether the main file was loaded from an AST or not. | |
104 | bool MainFileIsAST; | |
105 | ||
106 | /// \brief What kind of translation unit this AST represents. | |
107 | TranslationUnitKind TUKind; | |
108 | ||
109 | /// \brief Whether we should time each operation. | |
110 | bool WantTiming; | |
111 | ||
112 | /// \brief Whether the ASTUnit should delete the remapped buffers. | |
113 | bool OwnsRemappedFileBuffers; | |
114 | ||
115 | /// Track the top-level decls which appeared in an ASTUnit which was loaded | |
116 | /// from a source file. | |
117 | // | |
118 | // FIXME: This is just an optimization hack to avoid deserializing large parts | |
119 | // of a PCH file when using the Index library on an ASTUnit loaded from | |
120 | // source. In the long term we should make the Index library use efficient and | |
121 | // more scalable search mechanisms. | |
122 | std::vector<Decl*> TopLevelDecls; | |
123 | ||
124 | /// \brief Sorted (by file offset) vector of pairs of file offset/Decl. | |
125 | typedef SmallVector<std::pair<unsigned, Decl *>, 64> LocDeclsTy; | |
126 | typedef llvm::DenseMap<FileID, LocDeclsTy *> FileDeclsTy; | |
127 | ||
128 | /// \brief Map from FileID to the file-level declarations that it contains. | |
129 | /// The files and decls are only local (and non-preamble) ones. | |
130 | FileDeclsTy FileDecls; | |
131 | ||
132 | /// The name of the original source file used to generate this ASTUnit. | |
133 | std::string OriginalSourceFile; | |
134 | ||
135 | /// \brief The set of diagnostics produced when creating the preamble. | |
136 | SmallVector<StoredDiagnostic, 4> PreambleDiagnostics; | |
137 | ||
138 | /// \brief The set of diagnostics produced when creating this | |
139 | /// translation unit. | |
140 | SmallVector<StoredDiagnostic, 4> StoredDiagnostics; | |
141 | ||
142 | /// \brief The set of diagnostics produced when failing to parse, e.g. due | |
143 | /// to failure to load the PCH. | |
144 | SmallVector<StoredDiagnostic, 4> FailedParseDiagnostics; | |
145 | ||
146 | /// \brief The number of stored diagnostics that come from the driver | |
147 | /// itself. | |
148 | /// | |
149 | /// Diagnostics that come from the driver are retained from one parse to | |
150 | /// the next. | |
151 | unsigned NumStoredDiagnosticsFromDriver; | |
152 | ||
153 | /// \brief Counter that determines when we want to try building a | |
154 | /// precompiled preamble. | |
155 | /// | |
156 | /// If zero, we will never build a precompiled preamble. Otherwise, | |
157 | /// it's treated as a counter that decrements each time we reparse | |
158 | /// without the benefit of a precompiled preamble. When it hits 1, | |
159 | /// we'll attempt to rebuild the precompiled header. This way, if | |
160 | /// building the precompiled preamble fails, we won't try again for | |
161 | /// some number of calls. | |
162 | unsigned PreambleRebuildCounter; | |
163 | ||
164 | public: | |
165 | class PreambleData { | |
166 | const FileEntry *File; | |
167 | std::vector<char> Buffer; | |
168 | mutable unsigned NumLines; | |
169 | ||
170 | public: | |
171 | PreambleData() : File(0), NumLines(0) { } | |
172 | ||
173 | void assign(const FileEntry *F, const char *begin, const char *end) { | |
174 | File = F; | |
175 | Buffer.assign(begin, end); | |
176 | NumLines = 0; | |
177 | } | |
178 | ||
179 | void clear() { Buffer.clear(); File = 0; NumLines = 0; } | |
180 | ||
181 | size_t size() const { return Buffer.size(); } | |
182 | bool empty() const { return Buffer.empty(); } | |
183 | ||
184 | const char *getBufferStart() const { return &Buffer[0]; } | |
185 | ||
186 | unsigned getNumLines() const { | |
187 | if (NumLines) | |
188 | return NumLines; | |
189 | countLines(); | |
190 | return NumLines; | |
191 | } | |
192 | ||
193 | SourceRange getSourceRange(const SourceManager &SM) const { | |
194 | SourceLocation FileLoc = SM.getLocForStartOfFile(SM.getPreambleFileID()); | |
195 | return SourceRange(FileLoc, FileLoc.getLocWithOffset(size()-1)); | |
196 | } | |
197 | ||
198 | private: | |
199 | void countLines() const; | |
200 | }; | |
201 | ||
202 | const PreambleData &getPreambleData() const { | |
203 | return Preamble; | |
204 | } | |
205 | ||
206 | private: | |
207 | ||
208 | /// \brief The contents of the preamble that has been precompiled to | |
209 | /// \c PreambleFile. | |
210 | PreambleData Preamble; | |
211 | ||
212 | /// \brief Whether the preamble ends at the start of a new line. | |
213 | /// | |
214 | /// Used to inform the lexer as to whether it's starting at the beginning of | |
215 | /// a line after skipping the preamble. | |
216 | bool PreambleEndsAtStartOfLine; | |
217 | ||
218 | /// \brief The size of the source buffer that we've reserved for the main | |
219 | /// file within the precompiled preamble. | |
220 | unsigned PreambleReservedSize; | |
221 | ||
222 | /// \brief Keeps track of the files that were used when computing the | |
223 | /// preamble, with both their buffer size and their modification time. | |
224 | /// | |
225 | /// If any of the files have changed from one compile to the next, | |
226 | /// the preamble must be thrown away. | |
227 | llvm::StringMap<std::pair<off_t, time_t> > FilesInPreamble; | |
228 | ||
229 | /// \brief When non-NULL, this is the buffer used to store the contents of | |
230 | /// the main file when it has been padded for use with the precompiled | |
231 | /// preamble. | |
232 | llvm::MemoryBuffer *SavedMainFileBuffer; | |
233 | ||
234 | /// \brief When non-NULL, this is the buffer used to store the | |
235 | /// contents of the preamble when it has been padded to build the | |
236 | /// precompiled preamble. | |
237 | llvm::MemoryBuffer *PreambleBuffer; | |
238 | ||
239 | /// \brief The number of warnings that occurred while parsing the preamble. | |
240 | /// | |
241 | /// This value will be used to restore the state of the \c DiagnosticsEngine | |
242 | /// object when re-using the precompiled preamble. Note that only the | |
243 | /// number of warnings matters, since we will not save the preamble | |
244 | /// when any errors are present. | |
245 | unsigned NumWarningsInPreamble; | |
246 | ||
247 | /// \brief A list of the serialization ID numbers for each of the top-level | |
248 | /// declarations parsed within the precompiled preamble. | |
249 | std::vector<serialization::DeclID> TopLevelDeclsInPreamble; | |
250 | ||
251 | /// \brief Whether we should be caching code-completion results. | |
252 | bool ShouldCacheCodeCompletionResults : 1; | |
253 | ||
254 | /// \brief Whether to include brief documentation within the set of code | |
255 | /// completions cached. | |
256 | bool IncludeBriefCommentsInCodeCompletion : 1; | |
257 | ||
258 | /// \brief True if non-system source files should be treated as volatile | |
259 | /// (likely to change while trying to use them). | |
260 | bool UserFilesAreVolatile : 1; | |
261 | ||
262 | /// \brief The language options used when we load an AST file. | |
263 | LangOptions ASTFileLangOpts; | |
264 | ||
265 | static void ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> &Diags, | |
266 | const char **ArgBegin, const char **ArgEnd, | |
267 | ASTUnit &AST, bool CaptureDiagnostics); | |
268 | ||
269 | void TranslateStoredDiagnostics(ASTReader *MMan, StringRef ModName, | |
270 | SourceManager &SrcMan, | |
271 | const SmallVectorImpl<StoredDiagnostic> &Diags, | |
272 | SmallVectorImpl<StoredDiagnostic> &Out); | |
273 | ||
274 | void clearFileLevelDecls(); | |
275 | ||
276 | public: | |
277 | /// \brief A cached code-completion result, which may be introduced in one of | |
278 | /// many different contexts. | |
279 | struct CachedCodeCompletionResult { | |
280 | /// \brief The code-completion string corresponding to this completion | |
281 | /// result. | |
282 | CodeCompletionString *Completion; | |
283 | ||
284 | /// \brief A bitmask that indicates which code-completion contexts should | |
285 | /// contain this completion result. | |
286 | /// | |
287 | /// The bits in the bitmask correspond to the values of | |
288 | /// CodeCompleteContext::Kind. To map from a completion context kind to a | |
289 | /// bit, shift 1 by that number of bits. Many completions can occur in | |
290 | /// several different contexts. | |
291 | uint64_t ShowInContexts; | |
292 | ||
293 | /// \brief The priority given to this code-completion result. | |
294 | unsigned Priority; | |
295 | ||
296 | /// \brief The libclang cursor kind corresponding to this code-completion | |
297 | /// result. | |
298 | CXCursorKind Kind; | |
299 | ||
300 | /// \brief The availability of this code-completion result. | |
301 | CXAvailabilityKind Availability; | |
302 | ||
303 | /// \brief The simplified type class for a non-macro completion result. | |
304 | SimplifiedTypeClass TypeClass; | |
305 | ||
306 | /// \brief The type of a non-macro completion result, stored as a unique | |
307 | /// integer used by the string map of cached completion types. | |
308 | /// | |
309 | /// This value will be zero if the type is not known, or a unique value | |
310 | /// determined by the formatted type string. Se \c CachedCompletionTypes | |
311 | /// for more information. | |
312 | unsigned Type; | |
313 | }; | |
314 | ||
315 | /// \brief Retrieve the mapping from formatted type names to unique type | |
316 | /// identifiers. | |
317 | llvm::StringMap<unsigned> &getCachedCompletionTypes() { | |
318 | return CachedCompletionTypes; | |
319 | } | |
320 | ||
321 | /// \brief Retrieve the allocator used to cache global code completions. | |
322 | IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> | |
323 | getCachedCompletionAllocator() { | |
324 | return CachedCompletionAllocator; | |
325 | } | |
326 | ||
327 | CodeCompletionTUInfo &getCodeCompletionTUInfo() { | |
328 | if (!CCTUInfo) | |
329 | CCTUInfo.reset(new CodeCompletionTUInfo( | |
330 | new GlobalCodeCompletionAllocator)); | |
331 | return *CCTUInfo; | |
332 | } | |
333 | ||
334 | private: | |
335 | /// \brief Allocator used to store cached code completions. | |
336 | IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> | |
337 | CachedCompletionAllocator; | |
338 | ||
339 | OwningPtr<CodeCompletionTUInfo> CCTUInfo; | |
340 | ||
341 | /// \brief The set of cached code-completion results. | |
342 | std::vector<CachedCodeCompletionResult> CachedCompletionResults; | |
343 | ||
344 | /// \brief A mapping from the formatted type name to a unique number for that | |
345 | /// type, which is used for type equality comparisons. | |
346 | llvm::StringMap<unsigned> CachedCompletionTypes; | |
347 | ||
348 | /// \brief A string hash of the top-level declaration and macro definition | |
349 | /// names processed the last time that we reparsed the file. | |
350 | /// | |
351 | /// This hash value is used to determine when we need to refresh the | |
352 | /// global code-completion cache. | |
353 | unsigned CompletionCacheTopLevelHashValue; | |
354 | ||
355 | /// \brief A string hash of the top-level declaration and macro definition | |
356 | /// names processed the last time that we reparsed the precompiled preamble. | |
357 | /// | |
358 | /// This hash value is used to determine when we need to refresh the | |
359 | /// global code-completion cache after a rebuild of the precompiled preamble. | |
360 | unsigned PreambleTopLevelHashValue; | |
361 | ||
362 | /// \brief The current hash value for the top-level declaration and macro | |
363 | /// definition names | |
364 | unsigned CurrentTopLevelHashValue; | |
365 | ||
366 | /// \brief Bit used by CIndex to mark when a translation unit may be in an | |
367 | /// inconsistent state, and is not safe to free. | |
368 | unsigned UnsafeToFree : 1; | |
369 | ||
370 | /// \brief Cache any "global" code-completion results, so that we can avoid | |
371 | /// recomputing them with each completion. | |
372 | void CacheCodeCompletionResults(); | |
373 | ||
374 | /// \brief Clear out and deallocate | |
375 | void ClearCachedCompletionResults(); | |
376 | ||
377 | ASTUnit(const ASTUnit &) LLVM_DELETED_FUNCTION; | |
378 | void operator=(const ASTUnit &) LLVM_DELETED_FUNCTION; | |
379 | ||
380 | explicit ASTUnit(bool MainFileIsAST); | |
381 | ||
382 | void CleanTemporaryFiles(); | |
383 | bool Parse(llvm::MemoryBuffer *OverrideMainBuffer); | |
384 | ||
385 | std::pair<llvm::MemoryBuffer *, std::pair<unsigned, bool> > | |
386 | ComputePreamble(CompilerInvocation &Invocation, | |
387 | unsigned MaxLines, bool &CreatedBuffer); | |
388 | ||
389 | llvm::MemoryBuffer *getMainBufferWithPrecompiledPreamble( | |
390 | const CompilerInvocation &PreambleInvocationIn, | |
391 | bool AllowRebuild = true, | |
392 | unsigned MaxLines = 0); | |
393 | void RealizeTopLevelDeclsFromPreamble(); | |
394 | ||
395 | /// \brief Transfers ownership of the objects (like SourceManager) from | |
396 | /// \param CI to this ASTUnit. | |
397 | void transferASTDataFromCompilerInstance(CompilerInstance &CI); | |
398 | ||
399 | /// \brief Allows us to assert that ASTUnit is not being used concurrently, | |
400 | /// which is not supported. | |
401 | /// | |
402 | /// Clients should create instances of the ConcurrencyCheck class whenever | |
403 | /// using the ASTUnit in a way that isn't intended to be concurrent, which is | |
404 | /// just about any usage. | |
405 | /// Becomes a noop in release mode; only useful for debug mode checking. | |
406 | class ConcurrencyState { | |
407 | #ifndef NDEBUG | |
408 | void *Mutex; // a llvm::sys::MutexImpl in debug; | |
409 | #endif | |
410 | ||
411 | public: | |
412 | ConcurrencyState(); | |
413 | ~ConcurrencyState(); | |
414 | ||
415 | void start(); | |
416 | void finish(); | |
417 | }; | |
418 | ConcurrencyState ConcurrencyCheckValue; | |
419 | ||
420 | public: | |
421 | class ConcurrencyCheck { | |
422 | ASTUnit &Self; | |
423 | ||
424 | public: | |
425 | explicit ConcurrencyCheck(ASTUnit &Self) | |
426 | : Self(Self) | |
427 | { | |
428 | Self.ConcurrencyCheckValue.start(); | |
429 | } | |
430 | ~ConcurrencyCheck() { | |
431 | Self.ConcurrencyCheckValue.finish(); | |
432 | } | |
433 | }; | |
434 | friend class ConcurrencyCheck; | |
435 | ||
436 | ~ASTUnit(); | |
437 | ||
438 | bool isMainFileAST() const { return MainFileIsAST; } | |
439 | ||
440 | bool isUnsafeToFree() const { return UnsafeToFree; } | |
441 | void setUnsafeToFree(bool Value) { UnsafeToFree = Value; } | |
442 | ||
443 | const DiagnosticsEngine &getDiagnostics() const { return *Diagnostics; } | |
444 | DiagnosticsEngine &getDiagnostics() { return *Diagnostics; } | |
445 | ||
446 | const SourceManager &getSourceManager() const { return *SourceMgr; } | |
447 | SourceManager &getSourceManager() { return *SourceMgr; } | |
448 | ||
449 | const Preprocessor &getPreprocessor() const { return *PP; } | |
450 | Preprocessor &getPreprocessor() { return *PP; } | |
451 | ||
452 | const ASTContext &getASTContext() const { return *Ctx; } | |
453 | ASTContext &getASTContext() { return *Ctx; } | |
454 | ||
455 | void setASTContext(ASTContext *ctx) { Ctx = ctx; } | |
456 | void setPreprocessor(Preprocessor *pp); | |
457 | ||
458 | bool hasSema() const { return TheSema; } | |
459 | Sema &getSema() const { | |
460 | assert(TheSema && "ASTUnit does not have a Sema object!"); | |
461 | return *TheSema; | |
462 | } | |
463 | ||
464 | const FileManager &getFileManager() const { return *FileMgr; } | |
465 | FileManager &getFileManager() { return *FileMgr; } | |
466 | ||
467 | const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; } | |
468 | ||
469 | const std::string &getOriginalSourceFileName(); | |
470 | ||
471 | /// \brief Add a temporary file that the ASTUnit depends on. | |
472 | /// | |
473 | /// This file will be erased when the ASTUnit is destroyed. | |
474 | void addTemporaryFile(const llvm::sys::Path &TempFile); | |
475 | ||
476 | bool getOnlyLocalDecls() const { return OnlyLocalDecls; } | |
477 | ||
478 | bool getOwnsRemappedFileBuffers() const { return OwnsRemappedFileBuffers; } | |
479 | void setOwnsRemappedFileBuffers(bool val) { OwnsRemappedFileBuffers = val; } | |
480 | ||
481 | StringRef getMainFileName() const; | |
482 | ||
483 | typedef std::vector<Decl *>::iterator top_level_iterator; | |
484 | ||
485 | top_level_iterator top_level_begin() { | |
486 | assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!"); | |
487 | if (!TopLevelDeclsInPreamble.empty()) | |
488 | RealizeTopLevelDeclsFromPreamble(); | |
489 | return TopLevelDecls.begin(); | |
490 | } | |
491 | ||
492 | top_level_iterator top_level_end() { | |
493 | assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!"); | |
494 | if (!TopLevelDeclsInPreamble.empty()) | |
495 | RealizeTopLevelDeclsFromPreamble(); | |
496 | return TopLevelDecls.end(); | |
497 | } | |
498 | ||
499 | std::size_t top_level_size() const { | |
500 | assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!"); | |
501 | return TopLevelDeclsInPreamble.size() + TopLevelDecls.size(); | |
502 | } | |
503 | ||
504 | bool top_level_empty() const { | |
505 | assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!"); | |
506 | return TopLevelDeclsInPreamble.empty() && TopLevelDecls.empty(); | |
507 | } | |
508 | ||
509 | /// \brief Add a new top-level declaration. | |
510 | void addTopLevelDecl(Decl *D) { | |
511 | TopLevelDecls.push_back(D); | |
512 | } | |
513 | ||
514 | /// \brief Add a new local file-level declaration. | |
515 | void addFileLevelDecl(Decl *D); | |
516 | ||
517 | /// \brief Get the decls that are contained in a file in the Offset/Length | |
518 | /// range. \p Length can be 0 to indicate a point at \p Offset instead of | |
519 | /// a range. | |
520 | void findFileRegionDecls(FileID File, unsigned Offset, unsigned Length, | |
521 | SmallVectorImpl<Decl *> &Decls); | |
522 | ||
523 | /// \brief Add a new top-level declaration, identified by its ID in | |
524 | /// the precompiled preamble. | |
525 | void addTopLevelDeclFromPreamble(serialization::DeclID D) { | |
526 | TopLevelDeclsInPreamble.push_back(D); | |
527 | } | |
528 | ||
529 | /// \brief Retrieve a reference to the current top-level name hash value. | |
530 | /// | |
531 | /// Note: This is used internally by the top-level tracking action | |
532 | unsigned &getCurrentTopLevelHashValue() { return CurrentTopLevelHashValue; } | |
533 | ||
534 | /// \brief Get the source location for the given file:line:col triplet. | |
535 | /// | |
536 | /// The difference with SourceManager::getLocation is that this method checks | |
537 | /// whether the requested location points inside the precompiled preamble | |
538 | /// in which case the returned source location will be a "loaded" one. | |
539 | SourceLocation getLocation(const FileEntry *File, | |
540 | unsigned Line, unsigned Col) const; | |
541 | ||
542 | /// \brief Get the source location for the given file:offset pair. | |
543 | SourceLocation getLocation(const FileEntry *File, unsigned Offset) const; | |
544 | ||
545 | /// \brief If \p Loc is a loaded location from the preamble, returns | |
546 | /// the corresponding local location of the main file, otherwise it returns | |
547 | /// \p Loc. | |
548 | SourceLocation mapLocationFromPreamble(SourceLocation Loc); | |
549 | ||
550 | /// \brief If \p Loc is a local location of the main file but inside the | |
551 | /// preamble chunk, returns the corresponding loaded location from the | |
552 | /// preamble, otherwise it returns \p Loc. | |
553 | SourceLocation mapLocationToPreamble(SourceLocation Loc); | |
554 | ||
555 | bool isInPreambleFileID(SourceLocation Loc); | |
556 | bool isInMainFileID(SourceLocation Loc); | |
557 | SourceLocation getStartOfMainFileID(); | |
558 | SourceLocation getEndOfPreambleFileID(); | |
559 | ||
560 | /// \see mapLocationFromPreamble. | |
561 | SourceRange mapRangeFromPreamble(SourceRange R) { | |
562 | return SourceRange(mapLocationFromPreamble(R.getBegin()), | |
563 | mapLocationFromPreamble(R.getEnd())); | |
564 | } | |
565 | ||
566 | /// \see mapLocationToPreamble. | |
567 | SourceRange mapRangeToPreamble(SourceRange R) { | |
568 | return SourceRange(mapLocationToPreamble(R.getBegin()), | |
569 | mapLocationToPreamble(R.getEnd())); | |
570 | } | |
571 | ||
572 | // Retrieve the diagnostics associated with this AST | |
573 | typedef StoredDiagnostic *stored_diag_iterator; | |
574 | typedef const StoredDiagnostic *stored_diag_const_iterator; | |
575 | stored_diag_const_iterator stored_diag_begin() const { | |
576 | return StoredDiagnostics.begin(); | |
577 | } | |
578 | stored_diag_iterator stored_diag_begin() { | |
579 | return StoredDiagnostics.begin(); | |
580 | } | |
581 | stored_diag_const_iterator stored_diag_end() const { | |
582 | return StoredDiagnostics.end(); | |
583 | } | |
584 | stored_diag_iterator stored_diag_end() { | |
585 | return StoredDiagnostics.end(); | |
586 | } | |
587 | unsigned stored_diag_size() const { return StoredDiagnostics.size(); } | |
588 | ||
589 | stored_diag_iterator stored_diag_afterDriver_begin() { | |
590 | if (NumStoredDiagnosticsFromDriver > StoredDiagnostics.size()) | |
591 | NumStoredDiagnosticsFromDriver = 0; | |
592 | return StoredDiagnostics.begin() + NumStoredDiagnosticsFromDriver; | |
593 | } | |
594 | ||
595 | typedef std::vector<CachedCodeCompletionResult>::iterator | |
596 | cached_completion_iterator; | |
597 | ||
598 | cached_completion_iterator cached_completion_begin() { | |
599 | return CachedCompletionResults.begin(); | |
600 | } | |
601 | ||
602 | cached_completion_iterator cached_completion_end() { | |
603 | return CachedCompletionResults.end(); | |
604 | } | |
605 | ||
606 | unsigned cached_completion_size() const { | |
607 | return CachedCompletionResults.size(); | |
608 | } | |
609 | ||
610 | llvm::MemoryBuffer *getBufferForFile(StringRef Filename, | |
611 | std::string *ErrorStr = 0); | |
612 | ||
613 | /// \brief Determine what kind of translation unit this AST represents. | |
614 | TranslationUnitKind getTranslationUnitKind() const { return TUKind; } | |
615 | ||
616 | typedef llvm::PointerUnion<const char *, const llvm::MemoryBuffer *> | |
617 | FilenameOrMemBuf; | |
618 | /// \brief A mapping from a file name to the memory buffer that stores the | |
619 | /// remapped contents of that file. | |
620 | typedef std::pair<std::string, FilenameOrMemBuf> RemappedFile; | |
621 | ||
622 | /// \brief Create a ASTUnit. Gets ownership of the passed CompilerInvocation. | |
623 | static ASTUnit *create(CompilerInvocation *CI, | |
624 | IntrusiveRefCntPtr<DiagnosticsEngine> Diags, | |
625 | bool CaptureDiagnostics, | |
626 | bool UserFilesAreVolatile); | |
627 | ||
628 | /// \brief Create a ASTUnit from an AST file. | |
629 | /// | |
630 | /// \param Filename - The AST file to load. | |
631 | /// | |
632 | /// \param Diags - The diagnostics engine to use for reporting errors; its | |
633 | /// lifetime is expected to extend past that of the returned ASTUnit. | |
634 | /// | |
635 | /// \returns - The initialized ASTUnit or null if the AST failed to load. | |
636 | static ASTUnit *LoadFromASTFile(const std::string &Filename, | |
637 | IntrusiveRefCntPtr<DiagnosticsEngine> Diags, | |
638 | const FileSystemOptions &FileSystemOpts, | |
639 | bool OnlyLocalDecls = false, | |
640 | RemappedFile *RemappedFiles = 0, | |
641 | unsigned NumRemappedFiles = 0, | |
642 | bool CaptureDiagnostics = false, | |
643 | bool AllowPCHWithCompilerErrors = false, | |
644 | bool UserFilesAreVolatile = false); | |
645 | ||
646 | private: | |
647 | /// \brief Helper function for \c LoadFromCompilerInvocation() and | |
648 | /// \c LoadFromCommandLine(), which loads an AST from a compiler invocation. | |
649 | /// | |
650 | /// \param PrecompilePreamble Whether to precompile the preamble of this | |
651 | /// translation unit, to improve the performance of reparsing. | |
652 | /// | |
653 | /// \returns \c true if a catastrophic failure occurred (which means that the | |
654 | /// \c ASTUnit itself is invalid), or \c false otherwise. | |
655 | bool LoadFromCompilerInvocation(bool PrecompilePreamble); | |
656 | ||
657 | public: | |
658 | ||
659 | /// \brief Create an ASTUnit from a source file, via a CompilerInvocation | |
660 | /// object, by invoking the optionally provided ASTFrontendAction. | |
661 | /// | |
662 | /// \param CI - The compiler invocation to use; it must have exactly one input | |
663 | /// source file. The ASTUnit takes ownership of the CompilerInvocation object. | |
664 | /// | |
665 | /// \param Diags - The diagnostics engine to use for reporting errors; its | |
666 | /// lifetime is expected to extend past that of the returned ASTUnit. | |
667 | /// | |
668 | /// \param Action - The ASTFrontendAction to invoke. Its ownership is not | |
669 | /// transfered. | |
670 | /// | |
671 | /// \param Unit - optionally an already created ASTUnit. Its ownership is not | |
672 | /// transfered. | |
673 | /// | |
674 | /// \param Persistent - if true the returned ASTUnit will be complete. | |
675 | /// false means the caller is only interested in getting info through the | |
676 | /// provided \see Action. | |
677 | /// | |
678 | /// \param ErrAST - If non-null and parsing failed without any AST to return | |
679 | /// (e.g. because the PCH could not be loaded), this accepts the ASTUnit | |
680 | /// mainly to allow the caller to see the diagnostics. | |
681 | /// This will only receive an ASTUnit if a new one was created. If an already | |
682 | /// created ASTUnit was passed in \p Unit then the caller can check that. | |
683 | /// | |
684 | static ASTUnit *LoadFromCompilerInvocationAction(CompilerInvocation *CI, | |
685 | IntrusiveRefCntPtr<DiagnosticsEngine> Diags, | |
686 | ASTFrontendAction *Action = 0, | |
687 | ASTUnit *Unit = 0, | |
688 | bool Persistent = true, | |
689 | StringRef ResourceFilesPath = StringRef(), | |
690 | bool OnlyLocalDecls = false, | |
691 | bool CaptureDiagnostics = false, | |
692 | bool PrecompilePreamble = false, | |
693 | bool CacheCodeCompletionResults = false, | |
694 | bool IncludeBriefCommentsInCodeCompletion = false, | |
695 | bool UserFilesAreVolatile = false, | |
696 | OwningPtr<ASTUnit> *ErrAST = 0); | |
697 | ||
698 | /// LoadFromCompilerInvocation - Create an ASTUnit from a source file, via a | |
699 | /// CompilerInvocation object. | |
700 | /// | |
701 | /// \param CI - The compiler invocation to use; it must have exactly one input | |
702 | /// source file. The ASTUnit takes ownership of the CompilerInvocation object. | |
703 | /// | |
704 | /// \param Diags - The diagnostics engine to use for reporting errors; its | |
705 | /// lifetime is expected to extend past that of the returned ASTUnit. | |
706 | // | |
707 | // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we | |
708 | // shouldn't need to specify them at construction time. | |
709 | static ASTUnit *LoadFromCompilerInvocation(CompilerInvocation *CI, | |
710 | IntrusiveRefCntPtr<DiagnosticsEngine> Diags, | |
711 | bool OnlyLocalDecls = false, | |
712 | bool CaptureDiagnostics = false, | |
713 | bool PrecompilePreamble = false, | |
714 | TranslationUnitKind TUKind = TU_Complete, | |
715 | bool CacheCodeCompletionResults = false, | |
716 | bool IncludeBriefCommentsInCodeCompletion = false, | |
717 | bool UserFilesAreVolatile = false); | |
718 | ||
719 | /// LoadFromCommandLine - Create an ASTUnit from a vector of command line | |
720 | /// arguments, which must specify exactly one source file. | |
721 | /// | |
722 | /// \param ArgBegin - The beginning of the argument vector. | |
723 | /// | |
724 | /// \param ArgEnd - The end of the argument vector. | |
725 | /// | |
726 | /// \param Diags - The diagnostics engine to use for reporting errors; its | |
727 | /// lifetime is expected to extend past that of the returned ASTUnit. | |
728 | /// | |
729 | /// \param ResourceFilesPath - The path to the compiler resource files. | |
730 | /// | |
731 | /// \param ErrAST - If non-null and parsing failed without any AST to return | |
732 | /// (e.g. because the PCH could not be loaded), this accepts the ASTUnit | |
733 | /// mainly to allow the caller to see the diagnostics. | |
734 | /// | |
735 | // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we | |
736 | // shouldn't need to specify them at construction time. | |
737 | static ASTUnit *LoadFromCommandLine(const char **ArgBegin, | |
738 | const char **ArgEnd, | |
739 | IntrusiveRefCntPtr<DiagnosticsEngine> Diags, | |
740 | StringRef ResourceFilesPath, | |
741 | bool OnlyLocalDecls = false, | |
742 | bool CaptureDiagnostics = false, | |
743 | RemappedFile *RemappedFiles = 0, | |
744 | unsigned NumRemappedFiles = 0, | |
745 | bool RemappedFilesKeepOriginalName = true, | |
746 | bool PrecompilePreamble = false, | |
747 | TranslationUnitKind TUKind = TU_Complete, | |
748 | bool CacheCodeCompletionResults = false, | |
749 | bool IncludeBriefCommentsInCodeCompletion = false, | |
750 | bool AllowPCHWithCompilerErrors = false, | |
751 | bool SkipFunctionBodies = false, | |
752 | bool UserFilesAreVolatile = false, | |
753 | OwningPtr<ASTUnit> *ErrAST = 0); | |
754 | ||
755 | /// \brief Reparse the source files using the same command-line options that | |
756 | /// were originally used to produce this translation unit. | |
757 | /// | |
758 | /// \returns True if a failure occurred that causes the ASTUnit not to | |
759 | /// contain any translation-unit information, false otherwise. | |
760 | bool Reparse(RemappedFile *RemappedFiles = 0, | |
761 | unsigned NumRemappedFiles = 0); | |
762 | ||
763 | /// \brief Perform code completion at the given file, line, and | |
764 | /// column within this translation unit. | |
765 | /// | |
766 | /// \param File The file in which code completion will occur. | |
767 | /// | |
768 | /// \param Line The line at which code completion will occur. | |
769 | /// | |
770 | /// \param Column The column at which code completion will occur. | |
771 | /// | |
772 | /// \param IncludeMacros Whether to include macros in the code-completion | |
773 | /// results. | |
774 | /// | |
775 | /// \param IncludeCodePatterns Whether to include code patterns (such as a | |
776 | /// for loop) in the code-completion results. | |
777 | /// | |
778 | /// \param IncludeBriefComments Whether to include brief documentation within | |
779 | /// the set of code completions returned. | |
780 | /// | |
781 | /// FIXME: The Diag, LangOpts, SourceMgr, FileMgr, StoredDiagnostics, and | |
782 | /// OwnedBuffers parameters are all disgusting hacks. They will go away. | |
783 | void CodeComplete(StringRef File, unsigned Line, unsigned Column, | |
784 | RemappedFile *RemappedFiles, unsigned NumRemappedFiles, | |
785 | bool IncludeMacros, bool IncludeCodePatterns, | |
786 | bool IncludeBriefComments, | |
787 | CodeCompleteConsumer &Consumer, | |
788 | DiagnosticsEngine &Diag, LangOptions &LangOpts, | |
789 | SourceManager &SourceMgr, FileManager &FileMgr, | |
790 | SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics, | |
791 | SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers); | |
792 | ||
793 | /// \brief Save this translation unit to a file with the given name. | |
794 | /// | |
795 | /// \returns true if there was a file error or false if the save was | |
796 | /// successful. | |
797 | bool Save(StringRef File); | |
798 | ||
799 | /// \brief Serialize this translation unit with the given output stream. | |
800 | /// | |
801 | /// \returns True if an error occurred, false otherwise. | |
802 | bool serialize(raw_ostream &OS); | |
803 | ||
804 | virtual Module *loadModule(SourceLocation ImportLoc, ModuleIdPath Path, | |
805 | Module::NameVisibilityKind Visibility, | |
806 | bool IsInclusionDirective) { | |
807 | // ASTUnit doesn't know how to load modules (not that this matters). | |
808 | return 0; | |
809 | } | |
810 | }; | |
811 | ||
812 | } // namespace clang | |
813 | ||
814 | #endif |