diff options
author | dim <dim@FreeBSD.org> | 2011-10-20 21:14:49 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-10-20 21:14:49 +0000 |
commit | 3963a48221351c61c17fb3f382341ab04809a3d3 (patch) | |
tree | ee2483e98b09cac943dc93a6969d83ca737ff139 /include/clang/Frontend/ASTUnit.h | |
parent | 611ba3ea3300b71eb95dc4e45f20eee5dddd32e1 (diff) | |
download | FreeBSD-src-3963a48221351c61c17fb3f382341ab04809a3d3.zip FreeBSD-src-3963a48221351c61c17fb3f382341ab04809a3d3.tar.gz |
Vendor import of clang release_30 branch r142614:
http://llvm.org/svn/llvm-project/cfe/branches/release_30@142614
Diffstat (limited to 'include/clang/Frontend/ASTUnit.h')
-rw-r--r-- | include/clang/Frontend/ASTUnit.h | 292 |
1 files changed, 177 insertions, 115 deletions
diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h index 58a60a1..471476a 100644 --- a/include/clang/Frontend/ASTUnit.h +++ b/include/clang/Frontend/ASTUnit.h @@ -18,6 +18,7 @@ #include "clang/Serialization/ASTBitCodes.h" #include "clang/Sema/Sema.h" #include "clang/Sema/CodeCompleteConsumer.h" +#include "clang/Lex/ModuleLoader.h" #include "clang/Lex/PreprocessingRecord.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/FileManager.h" @@ -41,10 +42,11 @@ namespace llvm { namespace clang { class ASTContext; +class ASTReader; class CodeCompleteConsumer; class CompilerInvocation; class Decl; -class Diagnostic; +class DiagnosticsEngine; class FileEntry; class FileManager; class HeaderSearch; @@ -65,19 +67,15 @@ class GlobalCodeCompletionAllocator /// \brief Utility class for loading a ASTContext from an AST file. /// -class ASTUnit { -public: - typedef std::map<FileID, std::vector<PreprocessedEntity *> > - PreprocessedEntitiesByFileMap; - +class ASTUnit : public ModuleLoader { private: - llvm::IntrusiveRefCntPtr<Diagnostic> Diagnostics; - llvm::IntrusiveRefCntPtr<FileManager> FileMgr; - llvm::IntrusiveRefCntPtr<SourceManager> SourceMgr; - llvm::OwningPtr<HeaderSearch> HeaderInfo; - llvm::IntrusiveRefCntPtr<TargetInfo> Target; - llvm::IntrusiveRefCntPtr<Preprocessor> PP; - llvm::IntrusiveRefCntPtr<ASTContext> Ctx; + llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics; + llvm::IntrusiveRefCntPtr<FileManager> FileMgr; + llvm::IntrusiveRefCntPtr<SourceManager> SourceMgr; + llvm::OwningPtr<HeaderSearch> HeaderInfo; + llvm::IntrusiveRefCntPtr<TargetInfo> Target; + llvm::IntrusiveRefCntPtr<Preprocessor> PP; + llvm::IntrusiveRefCntPtr<ASTContext> Ctx; FileSystemOptions FileSystemOpts; @@ -111,8 +109,8 @@ private: /// \brief Track whether the main file was loaded from an AST or not. bool MainFileIsAST; - /// \brief Whether this AST represents a complete translation unit. - bool CompleteTranslationUnit; + /// \brief What kind of translation unit this AST represents. + TranslationUnitKind TUKind; /// \brief Whether we should time each operation. bool WantTiming; @@ -128,14 +126,6 @@ private: // source. In the long term we should make the Index library use efficient and // more scalable search mechanisms. std::vector<Decl*> TopLevelDecls; - - /// \brief The list of preprocessed entities which appeared when the ASTUnit - /// was loaded. - /// - /// FIXME: This is just an optimization hack to avoid deserializing large - /// parts of a PCH file while performing a walk or search. In the long term, - /// we should provide more scalable search mechanisms. - std::vector<PreprocessedEntity *> PreprocessedEntities; /// The name of the original source file used to generate this ASTUnit. std::string OriginalSourceFile; @@ -143,9 +133,12 @@ private: // Critical optimization when using clang_getCursor(). ASTLocation LastLoc; + /// \brief The set of diagnostics produced when creating the preamble. + SmallVector<StoredDiagnostic, 4> PreambleDiagnostics; + /// \brief The set of diagnostics produced when creating this /// translation unit. - llvm::SmallVector<StoredDiagnostic, 4> StoredDiagnostics; + SmallVector<StoredDiagnostic, 4> StoredDiagnostics; /// \brief The number of stored diagnostics that come from the driver /// itself. @@ -156,27 +149,8 @@ private: /// \brief Temporary files that should be removed when the ASTUnit is /// destroyed. - llvm::SmallVector<llvm::sys::Path, 4> TemporaryFiles; - - /// \brief A mapping from file IDs to the set of preprocessed entities - /// stored in that file. - /// - /// FIXME: This is just an optimization hack to avoid searching through - /// many preprocessed entities during cursor traversal in the CIndex library. - /// Ideally, we would just be able to perform a binary search within the - /// list of preprocessed entities. - PreprocessedEntitiesByFileMap PreprocessedEntitiesByFile; + SmallVector<llvm::sys::Path, 4> TemporaryFiles; - /// \brief Simple hack to allow us to assert that ASTUnit is not being - /// used concurrently, which is not supported. - /// - /// Clients should create instances of the ConcurrencyCheck class whenever - /// using the ASTUnit in a way that isn't intended to be concurrent, which is - /// just about any usage. - unsigned int ConcurrencyCheckValue; - static const unsigned int CheckLocked = 28573289; - static const unsigned int CheckUnlocked = 9803453; - /// \brief Counter that determines when we want to try building a /// precompiled preamble. /// @@ -191,9 +165,53 @@ private: /// \brief The file in which the precompiled preamble is stored. std::string PreambleFile; +public: + class PreambleData { + const FileEntry *File; + std::vector<char> Buffer; + mutable unsigned NumLines; + + public: + PreambleData() : File(0), NumLines(0) { } + + void assign(const FileEntry *F, const char *begin, const char *end) { + File = F; + Buffer.assign(begin, end); + NumLines = 0; + } + + void clear() { Buffer.clear(); File = 0; NumLines = 0; } + + size_t size() const { return Buffer.size(); } + bool empty() const { return Buffer.empty(); } + + const char *getBufferStart() const { return &Buffer[0]; } + + unsigned getNumLines() const { + if (NumLines) + return NumLines; + countLines(); + return NumLines; + } + + SourceRange getSourceRange(const SourceManager &SM) const { + SourceLocation FileLoc = SM.getLocForStartOfFile(SM.getPreambleFileID()); + return SourceRange(FileLoc, FileLoc.getLocWithOffset(size()-1)); + } + + private: + void countLines() const; + }; + + const PreambleData &getPreambleData() const { + return Preamble; + } + +private: + /// \brief The contents of the preamble that has been precompiled to /// \c PreambleFile. - std::vector<char> Preamble; + PreambleData Preamble; /// \brief Whether the preamble ends at the start of a new line. /// @@ -224,27 +242,15 @@ private: /// \brief The number of warnings that occurred while parsing the preamble. /// - /// This value will be used to restore the state of the \c Diagnostic object - /// when re-using the precompiled preamble. Note that only the + /// This value will be used to restore the state of the \c DiagnosticsEngine + /// object when re-using the precompiled preamble. Note that only the /// number of warnings matters, since we will not save the preamble /// when any errors are present. unsigned NumWarningsInPreamble; - /// \brief The number of diagnostics that were stored when parsing - /// the precompiled preamble. - /// - /// This value is used to determine how many of the stored - /// diagnostics should be retained when reparsing in the presence of - /// a precompiled preamble. - unsigned NumStoredDiagnosticsInPreamble; - /// \brief A list of the serialization ID numbers for each of the top-level /// declarations parsed within the precompiled preamble. std::vector<serialization::DeclID> TopLevelDeclsInPreamble; - - /// \brief A list of the offsets into the precompiled preamble which - /// correspond to preprocessed entities. - std::vector<uint64_t> PreprocessedEntitiesInPreamble; /// \brief Whether we should be caching code-completion results. bool ShouldCacheCodeCompletionResults; @@ -252,11 +258,19 @@ private: /// \brief Whether we want to include nested macro expansions in the /// detailed preprocessing record. bool NestedMacroExpansions; - - static void ConfigureDiags(llvm::IntrusiveRefCntPtr<Diagnostic> &Diags, + + /// \brief The language options used when we load an AST file. + LangOptions ASTFileLangOpts; + + static void ConfigureDiags(llvm::IntrusiveRefCntPtr<DiagnosticsEngine> &Diags, const char **ArgBegin, const char **ArgEnd, ASTUnit &AST, bool CaptureDiagnostics); + void TranslateStoredDiagnostics(ASTReader *MMan, StringRef ModName, + SourceManager &SrcMan, + const SmallVectorImpl<StoredDiagnostic> &Diags, + SmallVectorImpl<StoredDiagnostic> &Out); + public: /// \brief A cached code-completion result, which may be introduced in one of /// many different contexts. @@ -309,10 +323,24 @@ public: return CachedCompletionAllocator; } + /// \brief Retrieve the allocator used to cache global code completions. + /// Creates the allocator if it doesn't already exist. + llvm::IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> + getCursorCompletionAllocator() { + if (!CursorCompletionAllocator.getPtr()) { + CursorCompletionAllocator = new GlobalCodeCompletionAllocator; + } + return CursorCompletionAllocator; + } + private: /// \brief Allocator used to store cached code completions. llvm::IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> CachedCompletionAllocator; + + /// \brief Allocator used to store code completions for arbitrary cursors. + llvm::IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> + CursorCompletionAllocator; /// \brief The set of cached code-completion results. std::vector<CachedCodeCompletionResult> CachedCompletionResults; @@ -367,23 +395,38 @@ private: bool AllowRebuild = true, unsigned MaxLines = 0); void RealizeTopLevelDeclsFromPreamble(); - void RealizePreprocessedEntitiesFromPreamble(); + /// \brief Allows us to assert that ASTUnit is not being used concurrently, + /// which is not supported. + /// + /// Clients should create instances of the ConcurrencyCheck class whenever + /// using the ASTUnit in a way that isn't intended to be concurrent, which is + /// just about any usage. + /// Becomes a noop in release mode; only useful for debug mode checking. + class ConcurrencyState { + void *Mutex; // a llvm::sys::MutexImpl in debug; + + public: + ConcurrencyState(); + ~ConcurrencyState(); + + void start(); + void finish(); + }; + ConcurrencyState ConcurrencyCheckValue; + public: class ConcurrencyCheck { - volatile ASTUnit &Self; + ASTUnit &Self; public: explicit ConcurrencyCheck(ASTUnit &Self) : Self(Self) { - assert(Self.ConcurrencyCheckValue == CheckUnlocked && - "Concurrent access to ASTUnit!"); - Self.ConcurrencyCheckValue = CheckLocked; + Self.ConcurrencyCheckValue.start(); } - ~ConcurrencyCheck() { - Self.ConcurrencyCheckValue = CheckUnlocked; + Self.ConcurrencyCheckValue.finish(); } }; friend class ConcurrencyCheck; @@ -395,8 +438,8 @@ public: bool isUnsafeToFree() const { return UnsafeToFree; } void setUnsafeToFree(bool Value) { UnsafeToFree = Value; } - const Diagnostic &getDiagnostics() const { return *Diagnostics; } - Diagnostic &getDiagnostics() { return *Diagnostics; } + const DiagnosticsEngine &getDiagnostics() const { return *Diagnostics; } + DiagnosticsEngine &getDiagnostics() { return *Diagnostics; } const SourceManager &getSourceManager() const { return *SourceMgr; } SourceManager &getSourceManager() { return *SourceMgr; } @@ -407,6 +450,8 @@ public: const ASTContext &getASTContext() const { return *Ctx; } ASTContext &getASTContext() { return *Ctx; } + void setASTContext(ASTContext *ctx) { Ctx = ctx; } + bool hasSema() const { return TheSema; } Sema &getSema() const { assert(TheSema && "ASTUnit does not have a Sema object!"); @@ -419,7 +464,6 @@ public: const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; } const std::string &getOriginalSourceFileName(); - const std::string &getASTFileName(); /// \brief Add a temporary file that the ASTUnit depends on. /// @@ -433,15 +477,11 @@ public: bool getOwnsRemappedFileBuffers() const { return OwnsRemappedFileBuffers; } void setOwnsRemappedFileBuffers(bool val) { OwnsRemappedFileBuffers = val; } - /// \brief Retrieve the maximum PCH level of declarations that a - /// traversal of the translation unit should consider. - unsigned getMaxPCHLevel() const; - void setLastASTLocation(ASTLocation ALoc) { LastLoc = ALoc; } ASTLocation getLastASTLocation() const { return LastLoc; } - llvm::StringRef getMainFileName() const; + StringRef getMainFileName() const; typedef std::vector<Decl *>::iterator top_level_iterator; @@ -484,22 +524,38 @@ public: /// /// Note: This is used internally by the top-level tracking action unsigned &getCurrentTopLevelHashValue() { return CurrentTopLevelHashValue; } - - typedef std::vector<PreprocessedEntity *>::iterator pp_entity_iterator; - - pp_entity_iterator pp_entity_begin(); - pp_entity_iterator pp_entity_end(); - - /// \brief Add a new preprocessed entity that's stored at the given offset - /// in the precompiled preamble. - void addPreprocessedEntityFromPreamble(uint64_t Offset) { - PreprocessedEntitiesInPreamble.push_back(Offset); + + /// \brief Get the source location for the given file:line:col triplet. + /// + /// The difference with SourceManager::getLocation is that this method checks + /// whether the requested location points inside the precompiled preamble + /// in which case the returned source location will be a "loaded" one. + SourceLocation getLocation(const FileEntry *File, + unsigned Line, unsigned Col) const; + + /// \brief Get the source location for the given file:offset pair. + SourceLocation getLocation(const FileEntry *File, unsigned Offset) const; + + /// \brief If \arg Loc is a loaded location from the preamble, returns + /// the corresponding local location of the main file, otherwise it returns + /// \arg Loc. + SourceLocation mapLocationFromPreamble(SourceLocation Loc); + + /// \brief If \arg Loc is a local location of the main file but inside the + /// preamble chunk, returns the corresponding loaded location from the + /// preamble, otherwise it returns \arg Loc. + SourceLocation mapLocationToPreamble(SourceLocation Loc); + + /// \brief \see mapLocationFromPreamble. + SourceRange mapRangeFromPreamble(SourceRange R) { + return SourceRange(mapLocationFromPreamble(R.getBegin()), + mapLocationFromPreamble(R.getEnd())); } - - /// \brief Retrieve the mapping from File IDs to the preprocessed entities - /// within that file. - PreprocessedEntitiesByFileMap &getPreprocessedEntitiesByFile() { - return PreprocessedEntitiesByFile; + + /// \brief \see mapLocationToPreamble. + SourceRange mapRangeToPreamble(SourceRange R) { + return SourceRange(mapLocationToPreamble(R.getBegin()), + mapLocationToPreamble(R.getEnd())); } // Retrieve the diagnostics associated with this AST @@ -512,7 +568,7 @@ public: } unsigned stored_diag_size() const { return StoredDiagnostics.size(); } - llvm::SmallVector<StoredDiagnostic, 4> &getStoredDiagnostics() { + SmallVector<StoredDiagnostic, 4> &getStoredDiagnostics() { return StoredDiagnostics; } @@ -531,14 +587,11 @@ public: return CachedCompletionResults.size(); } - llvm::MemoryBuffer *getBufferForFile(llvm::StringRef Filename, + llvm::MemoryBuffer *getBufferForFile(StringRef Filename, std::string *ErrorStr = 0); - /// \brief Whether this AST represents a complete translation unit. - /// - /// If false, this AST is only a partial translation unit, e.g., one - /// that might still be used as a precompiled header or preamble. - bool isCompleteTranslationUnit() const { return CompleteTranslationUnit; } + /// \brief Determine what kind of translation unit this AST represents. + TranslationUnitKind getTranslationUnitKind() const { return TUKind; } typedef llvm::PointerUnion<const char *, const llvm::MemoryBuffer *> FilenameOrMemBuf; @@ -548,7 +601,7 @@ public: /// \brief Create a ASTUnit. Gets ownership of the passed CompilerInvocation. static ASTUnit *create(CompilerInvocation *CI, - llvm::IntrusiveRefCntPtr<Diagnostic> Diags); + llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags); /// \brief Create a ASTUnit from an AST file. /// @@ -559,7 +612,7 @@ public: /// /// \returns - The initialized ASTUnit or null if the AST failed to load. static ASTUnit *LoadFromASTFile(const std::string &Filename, - llvm::IntrusiveRefCntPtr<Diagnostic> Diags, + llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags, const FileSystemOptions &FileSystemOpts, bool OnlyLocalDecls = false, RemappedFile *RemappedFiles = 0, @@ -590,9 +643,13 @@ public: /// /// \param Action - The ASTFrontendAction to invoke. Its ownership is not /// transfered. + /// + /// \param Unit - optionally an already created ASTUnit. Its ownership is not + /// transfered. static ASTUnit *LoadFromCompilerInvocationAction(CompilerInvocation *CI, - llvm::IntrusiveRefCntPtr<Diagnostic> Diags, - ASTFrontendAction *Action = 0); + llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags, + ASTFrontendAction *Action = 0, + ASTUnit *Unit = 0); /// LoadFromCompilerInvocation - Create an ASTUnit from a source file, via a /// CompilerInvocation object. @@ -606,11 +663,11 @@ public: // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we // shouldn't need to specify them at construction time. static ASTUnit *LoadFromCompilerInvocation(CompilerInvocation *CI, - llvm::IntrusiveRefCntPtr<Diagnostic> Diags, + llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags, bool OnlyLocalDecls = false, bool CaptureDiagnostics = false, bool PrecompilePreamble = false, - bool CompleteTranslationUnit = true, + TranslationUnitKind TUKind = TU_Complete, bool CacheCodeCompletionResults = false, bool NestedMacroExpansions = true); @@ -630,18 +687,16 @@ public: // shouldn't need to specify them at construction time. static ASTUnit *LoadFromCommandLine(const char **ArgBegin, const char **ArgEnd, - llvm::IntrusiveRefCntPtr<Diagnostic> Diags, - llvm::StringRef ResourceFilesPath, + llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags, + StringRef ResourceFilesPath, bool OnlyLocalDecls = false, bool CaptureDiagnostics = false, RemappedFile *RemappedFiles = 0, unsigned NumRemappedFiles = 0, bool RemappedFilesKeepOriginalName = true, bool PrecompilePreamble = false, - bool CompleteTranslationUnit = true, + TranslationUnitKind TUKind = TU_Complete, bool CacheCodeCompletionResults = false, - bool CXXPrecompilePreamble = false, - bool CXXChainedPCH = false, bool NestedMacroExpansions = true); /// \brief Reparse the source files using the same command-line options that @@ -669,24 +724,31 @@ public: /// /// FIXME: The Diag, LangOpts, SourceMgr, FileMgr, StoredDiagnostics, and /// OwnedBuffers parameters are all disgusting hacks. They will go away. - void CodeComplete(llvm::StringRef File, unsigned Line, unsigned Column, + void CodeComplete(StringRef File, unsigned Line, unsigned Column, RemappedFile *RemappedFiles, unsigned NumRemappedFiles, bool IncludeMacros, bool IncludeCodePatterns, CodeCompleteConsumer &Consumer, - Diagnostic &Diag, LangOptions &LangOpts, + DiagnosticsEngine &Diag, LangOptions &LangOpts, SourceManager &SourceMgr, FileManager &FileMgr, - llvm::SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics, - llvm::SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers); + SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics, + SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers); /// \brief Save this translation unit to a file with the given name. /// /// \returns An indication of whether the save was successful or not. - CXSaveError Save(llvm::StringRef File); + CXSaveError Save(StringRef File); /// \brief Serialize this translation unit with the given output stream. /// /// \returns True if an error occurred, false otherwise. - bool serialize(llvm::raw_ostream &OS); + bool serialize(raw_ostream &OS); + + virtual ModuleKey loadModule(SourceLocation ImportLoc, + IdentifierInfo &ModuleName, + SourceLocation ModuleNameLoc) { + // ASTUnit doesn't know how to load modules (not that this matters). + return 0; + } }; } // namespace clang |