diff options
Diffstat (limited to 'contrib/llvm/tools/clang/include/clang/Frontend')
31 files changed, 5278 insertions, 0 deletions
diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/ASTConsumers.h b/contrib/llvm/tools/clang/include/clang/Frontend/ASTConsumers.h new file mode 100644 index 0000000..757fcae --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/ASTConsumers.h @@ -0,0 +1,58 @@ +//===--- ASTConsumers.h - ASTConsumer implementations -----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// AST Consumers. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_ASTCONSUMERS_H +#define LLVM_CLANG_FRONTEND_ASTCONSUMERS_H + +#include "clang/Basic/LLVM.h" +#include <memory> + +namespace clang { + +class ASTConsumer; +class CodeGenOptions; +class DiagnosticsEngine; +class FileManager; +class LangOptions; +class Preprocessor; +class TargetOptions; + +// AST pretty-printer: prints out the AST in a format that is close to the +// original C code. The output is intended to be in a format such that +// clang could re-parse the output back into the same AST, but the +// implementation is still incomplete. +std::unique_ptr<ASTConsumer> CreateASTPrinter(raw_ostream *OS, + StringRef FilterString); + +// AST dumper: dumps the raw AST in human-readable form to stderr; this is +// intended for debugging. +std::unique_ptr<ASTConsumer> CreateASTDumper(StringRef FilterString, + bool DumpDecls, + bool DumpLookups); + +// AST Decl node lister: prints qualified names of all filterable AST Decl +// nodes. +std::unique_ptr<ASTConsumer> CreateASTDeclNodeLister(); + +// Graphical AST viewer: for each function definition, creates a graph of +// the AST and displays it with the graph viewer "dotty". Also outputs +// function declarations to stderr. +std::unique_ptr<ASTConsumer> CreateASTViewer(); + +// DeclContext printer: prints out the DeclContext tree in human-readable form +// to stderr; this is intended for debugging. +std::unique_ptr<ASTConsumer> CreateDeclContextPrinter(); + +} // end clang namespace + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/ASTUnit.h b/contrib/llvm/tools/clang/include/clang/Frontend/ASTUnit.h new file mode 100644 index 0000000..fa4bcf2 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/ASTUnit.h @@ -0,0 +1,917 @@ +//===--- ASTUnit.h - ASTUnit utility ----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// ASTUnit utility class. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_ASTUNIT_H +#define LLVM_CLANG_FRONTEND_ASTUNIT_H + +#include "clang-c/Index.h" +#include "clang/AST/ASTContext.h" +#include "clang/Basic/FileManager.h" +#include "clang/Basic/FileSystemOptions.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Basic/TargetOptions.h" +#include "clang/Lex/HeaderSearchOptions.h" +#include "clang/Lex/ModuleLoader.h" +#include "clang/Lex/PreprocessingRecord.h" +#include "clang/Sema/CodeCompleteConsumer.h" +#include "clang/Serialization/ASTBitCodes.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/Support/MD5.h" +#include "llvm/Support/Path.h" +#include <cassert> +#include <map> +#include <memory> +#include <string> +#include <sys/types.h> +#include <utility> +#include <vector> + +namespace llvm { + class MemoryBuffer; +} + +namespace clang { +class Sema; +class ASTContext; +class ASTReader; +class CodeCompleteConsumer; +class CompilerInvocation; +class CompilerInstance; +class Decl; +class DiagnosticsEngine; +class FileEntry; +class FileManager; +class HeaderSearch; +class Preprocessor; +class PCHContainerOperations; +class PCHContainerReader; +class SourceManager; +class TargetInfo; +class ASTFrontendAction; +class ASTDeserializationListener; + +/// \brief Utility class for loading a ASTContext from an AST file. +/// +class ASTUnit : public ModuleLoader { +public: + struct StandaloneFixIt { + std::pair<unsigned, unsigned> RemoveRange; + std::pair<unsigned, unsigned> InsertFromRange; + std::string CodeToInsert; + bool BeforePreviousInsertions; + }; + + struct StandaloneDiagnostic { + unsigned ID; + DiagnosticsEngine::Level Level; + std::string Message; + std::string Filename; + unsigned LocOffset; + std::vector<std::pair<unsigned, unsigned> > Ranges; + std::vector<StandaloneFixIt> FixIts; + }; + +private: + std::shared_ptr<LangOptions> LangOpts; + IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics; + IntrusiveRefCntPtr<FileManager> FileMgr; + IntrusiveRefCntPtr<SourceManager> SourceMgr; + std::unique_ptr<HeaderSearch> HeaderInfo; + IntrusiveRefCntPtr<TargetInfo> Target; + IntrusiveRefCntPtr<Preprocessor> PP; + IntrusiveRefCntPtr<ASTContext> Ctx; + std::shared_ptr<TargetOptions> TargetOpts; + IntrusiveRefCntPtr<HeaderSearchOptions> HSOpts; + IntrusiveRefCntPtr<ASTReader> Reader; + bool HadModuleLoaderFatalFailure; + + struct ASTWriterData; + std::unique_ptr<ASTWriterData> WriterData; + + FileSystemOptions FileSystemOpts; + + /// \brief The AST consumer that received information about the translation + /// unit as it was parsed or loaded. + std::unique_ptr<ASTConsumer> Consumer; + + /// \brief The semantic analysis object used to type-check the translation + /// unit. + std::unique_ptr<Sema> TheSema; + + /// Optional owned invocation, just used to make the invocation used in + /// LoadFromCommandLine available. + IntrusiveRefCntPtr<CompilerInvocation> Invocation; + + // OnlyLocalDecls - when true, walking this AST should only visit declarations + // that come from the AST itself, not from included precompiled headers. + // FIXME: This is temporary; eventually, CIndex will always do this. + bool OnlyLocalDecls; + + /// \brief Whether to capture any diagnostics produced. + bool CaptureDiagnostics; + + /// \brief Track whether the main file was loaded from an AST or not. + bool MainFileIsAST; + + /// \brief What kind of translation unit this AST represents. + TranslationUnitKind TUKind; + + /// \brief Whether we should time each operation. + bool WantTiming; + + /// \brief Whether the ASTUnit should delete the remapped buffers. + bool OwnsRemappedFileBuffers; + + /// Track the top-level decls which appeared in an ASTUnit which was loaded + /// from a source file. + // + // FIXME: This is just an optimization hack to avoid deserializing large parts + // of a PCH file when using the Index library on an ASTUnit loaded from + // source. In the long term we should make the Index library use efficient and + // more scalable search mechanisms. + std::vector<Decl*> TopLevelDecls; + + /// \brief Sorted (by file offset) vector of pairs of file offset/Decl. + typedef SmallVector<std::pair<unsigned, Decl *>, 64> LocDeclsTy; + typedef llvm::DenseMap<FileID, LocDeclsTy *> FileDeclsTy; + + /// \brief Map from FileID to the file-level declarations that it contains. + /// The files and decls are only local (and non-preamble) ones. + FileDeclsTy FileDecls; + + /// The name of the original source file used to generate this ASTUnit. + std::string OriginalSourceFile; + + /// \brief The set of diagnostics produced when creating the preamble. + SmallVector<StandaloneDiagnostic, 4> PreambleDiagnostics; + + /// \brief The set of diagnostics produced when creating this + /// translation unit. + SmallVector<StoredDiagnostic, 4> StoredDiagnostics; + + /// \brief The set of diagnostics produced when failing to parse, e.g. due + /// to failure to load the PCH. + SmallVector<StoredDiagnostic, 4> FailedParseDiagnostics; + + /// \brief The number of stored diagnostics that come from the driver + /// itself. + /// + /// Diagnostics that come from the driver are retained from one parse to + /// the next. + unsigned NumStoredDiagnosticsFromDriver; + + /// \brief Counter that determines when we want to try building a + /// precompiled preamble. + /// + /// If zero, we will never build a precompiled preamble. Otherwise, + /// it's treated as a counter that decrements each time we reparse + /// without the benefit of a precompiled preamble. When it hits 1, + /// we'll attempt to rebuild the precompiled header. This way, if + /// building the precompiled preamble fails, we won't try again for + /// some number of calls. + unsigned PreambleRebuildCounter; + +public: + class PreambleData { + const FileEntry *File; + std::vector<char> Buffer; + mutable unsigned NumLines; + + public: + PreambleData() : File(nullptr), 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 = nullptr; 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; + } + + /// Data used to determine if a file used in the preamble has been changed. + struct PreambleFileHash { + /// All files have size set. + off_t Size; + + /// Modification time is set for files that are on disk. For memory + /// buffers it is zero. + time_t ModTime; + + /// Memory buffers have MD5 instead of modification time. We don't + /// compute MD5 for on-disk files because we hope that modification time is + /// enough to tell if the file was changed. + llvm::MD5::MD5Result MD5; + + static PreambleFileHash createForFile(off_t Size, time_t ModTime); + static PreambleFileHash + createForMemoryBuffer(const llvm::MemoryBuffer *Buffer); + + friend bool operator==(const PreambleFileHash &LHS, + const PreambleFileHash &RHS); + + friend bool operator!=(const PreambleFileHash &LHS, + const PreambleFileHash &RHS) { + return !(LHS == RHS); + } + }; + +private: + /// \brief The contents of the preamble that has been precompiled to + /// \c PreambleFile. + PreambleData Preamble; + + /// \brief Whether the preamble ends at the start of a new line. + /// + /// Used to inform the lexer as to whether it's starting at the beginning of + /// a line after skipping the preamble. + bool PreambleEndsAtStartOfLine; + + /// \brief Keeps track of the files that were used when computing the + /// preamble, with both their buffer size and their modification time. + /// + /// If any of the files have changed from one compile to the next, + /// the preamble must be thrown away. + llvm::StringMap<PreambleFileHash> FilesInPreamble; + + /// \brief When non-NULL, this is the buffer used to store the contents of + /// the main file when it has been padded for use with the precompiled + /// preamble. + std::unique_ptr<llvm::MemoryBuffer> SavedMainFileBuffer; + + /// \brief When non-NULL, this is the buffer used to store the + /// contents of the preamble when it has been padded to build the + /// precompiled preamble. + std::unique_ptr<llvm::MemoryBuffer> PreambleBuffer; + + /// \brief The number of warnings that occurred while parsing the preamble. + /// + /// 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 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 Whether we should be caching code-completion results. + bool ShouldCacheCodeCompletionResults : 1; + + /// \brief Whether to include brief documentation within the set of code + /// completions cached. + bool IncludeBriefCommentsInCodeCompletion : 1; + + /// \brief True if non-system source files should be treated as volatile + /// (likely to change while trying to use them). + bool UserFilesAreVolatile : 1; + + /// \brief The language options used when we load an AST file. + LangOptions ASTFileLangOpts; + + static void ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> Diags, + ASTUnit &AST, bool CaptureDiagnostics); + + void TranslateStoredDiagnostics(FileManager &FileMgr, + SourceManager &SrcMan, + const SmallVectorImpl<StandaloneDiagnostic> &Diags, + SmallVectorImpl<StoredDiagnostic> &Out); + + void clearFileLevelDecls(); + +public: + /// \brief A cached code-completion result, which may be introduced in one of + /// many different contexts. + struct CachedCodeCompletionResult { + /// \brief The code-completion string corresponding to this completion + /// result. + CodeCompletionString *Completion; + + /// \brief A bitmask that indicates which code-completion contexts should + /// contain this completion result. + /// + /// The bits in the bitmask correspond to the values of + /// CodeCompleteContext::Kind. To map from a completion context kind to a + /// bit, shift 1 by that number of bits. Many completions can occur in + /// several different contexts. + uint64_t ShowInContexts; + + /// \brief The priority given to this code-completion result. + unsigned Priority; + + /// \brief The libclang cursor kind corresponding to this code-completion + /// result. + CXCursorKind Kind; + + /// \brief The availability of this code-completion result. + CXAvailabilityKind Availability; + + /// \brief The simplified type class for a non-macro completion result. + SimplifiedTypeClass TypeClass; + + /// \brief The type of a non-macro completion result, stored as a unique + /// integer used by the string map of cached completion types. + /// + /// This value will be zero if the type is not known, or a unique value + /// determined by the formatted type string. Se \c CachedCompletionTypes + /// for more information. + unsigned Type; + }; + + /// \brief Retrieve the mapping from formatted type names to unique type + /// identifiers. + llvm::StringMap<unsigned> &getCachedCompletionTypes() { + return CachedCompletionTypes; + } + + /// \brief Retrieve the allocator used to cache global code completions. + IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> + getCachedCompletionAllocator() { + return CachedCompletionAllocator; + } + + CodeCompletionTUInfo &getCodeCompletionTUInfo() { + if (!CCTUInfo) + CCTUInfo.reset(new CodeCompletionTUInfo( + new GlobalCodeCompletionAllocator)); + return *CCTUInfo; + } + +private: + /// \brief Allocator used to store cached code completions. + IntrusiveRefCntPtr<GlobalCodeCompletionAllocator> + CachedCompletionAllocator; + + std::unique_ptr<CodeCompletionTUInfo> CCTUInfo; + + /// \brief The set of cached code-completion results. + std::vector<CachedCodeCompletionResult> CachedCompletionResults; + + /// \brief A mapping from the formatted type name to a unique number for that + /// type, which is used for type equality comparisons. + llvm::StringMap<unsigned> CachedCompletionTypes; + + /// \brief A string hash of the top-level declaration and macro definition + /// names processed the last time that we reparsed the file. + /// + /// This hash value is used to determine when we need to refresh the + /// global code-completion cache. + unsigned CompletionCacheTopLevelHashValue; + + /// \brief A string hash of the top-level declaration and macro definition + /// names processed the last time that we reparsed the precompiled preamble. + /// + /// This hash value is used to determine when we need to refresh the + /// global code-completion cache after a rebuild of the precompiled preamble. + unsigned PreambleTopLevelHashValue; + + /// \brief The current hash value for the top-level declaration and macro + /// definition names + unsigned CurrentTopLevelHashValue; + + /// \brief Bit used by CIndex to mark when a translation unit may be in an + /// inconsistent state, and is not safe to free. + unsigned UnsafeToFree : 1; + + /// \brief Cache any "global" code-completion results, so that we can avoid + /// recomputing them with each completion. + void CacheCodeCompletionResults(); + + /// \brief Clear out and deallocate + void ClearCachedCompletionResults(); + + ASTUnit(const ASTUnit &) = delete; + void operator=(const ASTUnit &) = delete; + + explicit ASTUnit(bool MainFileIsAST); + + void CleanTemporaryFiles(); + bool Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps, + std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer); + + struct ComputedPreamble { + llvm::MemoryBuffer *Buffer; + std::unique_ptr<llvm::MemoryBuffer> Owner; + unsigned Size; + bool PreambleEndsAtStartOfLine; + ComputedPreamble(llvm::MemoryBuffer *Buffer, + std::unique_ptr<llvm::MemoryBuffer> Owner, unsigned Size, + bool PreambleEndsAtStartOfLine) + : Buffer(Buffer), Owner(std::move(Owner)), Size(Size), + PreambleEndsAtStartOfLine(PreambleEndsAtStartOfLine) {} + ComputedPreamble(ComputedPreamble &&C) + : Buffer(C.Buffer), Owner(std::move(C.Owner)), Size(C.Size), + PreambleEndsAtStartOfLine(C.PreambleEndsAtStartOfLine) {} + }; + ComputedPreamble ComputePreamble(CompilerInvocation &Invocation, + unsigned MaxLines); + + std::unique_ptr<llvm::MemoryBuffer> getMainBufferWithPrecompiledPreamble( + std::shared_ptr<PCHContainerOperations> PCHContainerOps, + const CompilerInvocation &PreambleInvocationIn, bool AllowRebuild = true, + unsigned MaxLines = 0); + void RealizeTopLevelDeclsFromPreamble(); + + /// \brief Transfers ownership of the objects (like SourceManager) from + /// \param CI to this ASTUnit. + void transferASTDataFromCompilerInstance(CompilerInstance &CI); + + /// \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 { + ASTUnit &Self; + + public: + explicit ConcurrencyCheck(ASTUnit &Self) + : Self(Self) + { + Self.ConcurrencyCheckValue.start(); + } + ~ConcurrencyCheck() { + Self.ConcurrencyCheckValue.finish(); + } + }; + friend class ConcurrencyCheck; + + ~ASTUnit() override; + + bool isMainFileAST() const { return MainFileIsAST; } + + bool isUnsafeToFree() const { return UnsafeToFree; } + void setUnsafeToFree(bool Value) { UnsafeToFree = Value; } + + const DiagnosticsEngine &getDiagnostics() const { return *Diagnostics; } + DiagnosticsEngine &getDiagnostics() { return *Diagnostics; } + + const SourceManager &getSourceManager() const { return *SourceMgr; } + SourceManager &getSourceManager() { return *SourceMgr; } + + const Preprocessor &getPreprocessor() const { return *PP; } + Preprocessor &getPreprocessor() { return *PP; } + + const ASTContext &getASTContext() const { return *Ctx; } + ASTContext &getASTContext() { return *Ctx; } + + void setASTContext(ASTContext *ctx) { Ctx = ctx; } + void setPreprocessor(Preprocessor *pp); + + bool hasSema() const { return (bool)TheSema; } + Sema &getSema() const { + assert(TheSema && "ASTUnit does not have a Sema object!"); + return *TheSema; + } + + const LangOptions &getLangOpts() const { + assert(LangOpts && " ASTUnit does not have language options"); + return *LangOpts; + } + + const FileManager &getFileManager() const { return *FileMgr; } + FileManager &getFileManager() { return *FileMgr; } + + const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; } + + StringRef getOriginalSourceFileName() { + return OriginalSourceFile; + } + + ASTMutationListener *getASTMutationListener(); + ASTDeserializationListener *getDeserializationListener(); + + /// \brief Add a temporary file that the ASTUnit depends on. + /// + /// This file will be erased when the ASTUnit is destroyed. + void addTemporaryFile(StringRef TempFile); + + bool getOnlyLocalDecls() const { return OnlyLocalDecls; } + + bool getOwnsRemappedFileBuffers() const { return OwnsRemappedFileBuffers; } + void setOwnsRemappedFileBuffers(bool val) { OwnsRemappedFileBuffers = val; } + + StringRef getMainFileName() const; + + /// \brief If this ASTUnit came from an AST file, returns the filename for it. + StringRef getASTFileName() const; + + typedef std::vector<Decl *>::iterator top_level_iterator; + + top_level_iterator top_level_begin() { + assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!"); + if (!TopLevelDeclsInPreamble.empty()) + RealizeTopLevelDeclsFromPreamble(); + return TopLevelDecls.begin(); + } + + top_level_iterator top_level_end() { + assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!"); + if (!TopLevelDeclsInPreamble.empty()) + RealizeTopLevelDeclsFromPreamble(); + return TopLevelDecls.end(); + } + + std::size_t top_level_size() const { + assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!"); + return TopLevelDeclsInPreamble.size() + TopLevelDecls.size(); + } + + bool top_level_empty() const { + assert(!isMainFileAST() && "Invalid call for AST based ASTUnit!"); + return TopLevelDeclsInPreamble.empty() && TopLevelDecls.empty(); + } + + /// \brief Add a new top-level declaration. + void addTopLevelDecl(Decl *D) { + TopLevelDecls.push_back(D); + } + + /// \brief Add a new local file-level declaration. + void addFileLevelDecl(Decl *D); + + /// \brief Get the decls that are contained in a file in the Offset/Length + /// range. \p Length can be 0 to indicate a point at \p Offset instead of + /// a range. + void findFileRegionDecls(FileID File, unsigned Offset, unsigned Length, + SmallVectorImpl<Decl *> &Decls); + + /// \brief Add a new top-level declaration, identified by its ID in + /// the precompiled preamble. + void addTopLevelDeclFromPreamble(serialization::DeclID D) { + TopLevelDeclsInPreamble.push_back(D); + } + + /// \brief Retrieve a reference to the current top-level name hash value. + /// + /// Note: This is used internally by the top-level tracking action + unsigned &getCurrentTopLevelHashValue() { return CurrentTopLevelHashValue; } + + /// \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 \p Loc is a loaded location from the preamble, returns + /// the corresponding local location of the main file, otherwise it returns + /// \p Loc. + SourceLocation mapLocationFromPreamble(SourceLocation Loc); + + /// \brief If \p 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 \p Loc. + SourceLocation mapLocationToPreamble(SourceLocation Loc); + + bool isInPreambleFileID(SourceLocation Loc); + bool isInMainFileID(SourceLocation Loc); + SourceLocation getStartOfMainFileID(); + SourceLocation getEndOfPreambleFileID(); + + /// \see mapLocationFromPreamble. + SourceRange mapRangeFromPreamble(SourceRange R) { + return SourceRange(mapLocationFromPreamble(R.getBegin()), + mapLocationFromPreamble(R.getEnd())); + } + + /// \see mapLocationToPreamble. + SourceRange mapRangeToPreamble(SourceRange R) { + return SourceRange(mapLocationToPreamble(R.getBegin()), + mapLocationToPreamble(R.getEnd())); + } + + // Retrieve the diagnostics associated with this AST + typedef StoredDiagnostic *stored_diag_iterator; + typedef const StoredDiagnostic *stored_diag_const_iterator; + stored_diag_const_iterator stored_diag_begin() const { + return StoredDiagnostics.begin(); + } + stored_diag_iterator stored_diag_begin() { + return StoredDiagnostics.begin(); + } + stored_diag_const_iterator stored_diag_end() const { + return StoredDiagnostics.end(); + } + stored_diag_iterator stored_diag_end() { + return StoredDiagnostics.end(); + } + unsigned stored_diag_size() const { return StoredDiagnostics.size(); } + + stored_diag_iterator stored_diag_afterDriver_begin() { + if (NumStoredDiagnosticsFromDriver > StoredDiagnostics.size()) + NumStoredDiagnosticsFromDriver = 0; + return StoredDiagnostics.begin() + NumStoredDiagnosticsFromDriver; + } + + typedef std::vector<CachedCodeCompletionResult>::iterator + cached_completion_iterator; + + cached_completion_iterator cached_completion_begin() { + return CachedCompletionResults.begin(); + } + + cached_completion_iterator cached_completion_end() { + return CachedCompletionResults.end(); + } + + unsigned cached_completion_size() const { + return CachedCompletionResults.size(); + } + + /// \brief Returns an iterator range for the local preprocessing entities + /// of the local Preprocessor, if this is a parsed source file, or the loaded + /// preprocessing entities of the primary module if this is an AST file. + llvm::iterator_range<PreprocessingRecord::iterator> + getLocalPreprocessingEntities() const; + + /// \brief Type for a function iterating over a number of declarations. + /// \returns true to continue iteration and false to abort. + typedef bool (*DeclVisitorFn)(void *context, const Decl *D); + + /// \brief Iterate over local declarations (locally parsed if this is a parsed + /// source file or the loaded declarations of the primary module if this is an + /// AST file). + /// \returns true if the iteration was complete or false if it was aborted. + bool visitLocalTopLevelDecls(void *context, DeclVisitorFn Fn); + + /// \brief Get the PCH file if one was included. + const FileEntry *getPCHFile(); + + /// \brief Returns true if the ASTUnit was constructed from a serialized + /// module file. + bool isModuleFile(); + + std::unique_ptr<llvm::MemoryBuffer> + getBufferForFile(StringRef Filename, std::string *ErrorStr = nullptr); + + /// \brief Determine what kind of translation unit this AST represents. + TranslationUnitKind getTranslationUnitKind() const { return TUKind; } + + /// \brief A mapping from a file name to the memory buffer that stores the + /// remapped contents of that file. + typedef std::pair<std::string, llvm::MemoryBuffer *> RemappedFile; + + /// \brief Create a ASTUnit. Gets ownership of the passed CompilerInvocation. + static ASTUnit *create(CompilerInvocation *CI, + IntrusiveRefCntPtr<DiagnosticsEngine> Diags, + bool CaptureDiagnostics, + bool UserFilesAreVolatile); + + /// \brief Create a ASTUnit from an AST file. + /// + /// \param Filename - The AST file to load. + /// + /// \param PCHContainerOps - The PCHContainerOperations to use for loading and + /// creating modules. + /// \param Diags - The diagnostics engine to use for reporting errors; its + /// lifetime is expected to extend past that of the returned ASTUnit. + /// + /// \returns - The initialized ASTUnit or null if the AST failed to load. + static std::unique_ptr<ASTUnit> LoadFromASTFile( + const std::string &Filename, const PCHContainerReader &PCHContainerRdr, + IntrusiveRefCntPtr<DiagnosticsEngine> Diags, + const FileSystemOptions &FileSystemOpts, bool OnlyLocalDecls = false, + ArrayRef<RemappedFile> RemappedFiles = None, + bool CaptureDiagnostics = false, bool AllowPCHWithCompilerErrors = false, + bool UserFilesAreVolatile = false); + +private: + /// \brief Helper function for \c LoadFromCompilerInvocation() and + /// \c LoadFromCommandLine(), which loads an AST from a compiler invocation. + /// + /// \param PrecompilePreamble Whether to precompile the preamble of this + /// translation unit, to improve the performance of reparsing. + /// + /// \returns \c true if a catastrophic failure occurred (which means that the + /// \c ASTUnit itself is invalid), or \c false otherwise. + bool LoadFromCompilerInvocation( + std::shared_ptr<PCHContainerOperations> PCHContainerOps, + bool PrecompilePreamble); + +public: + + /// \brief Create an ASTUnit from a source file, via a CompilerInvocation + /// object, by invoking the optionally provided ASTFrontendAction. + /// + /// \param CI - The compiler invocation to use; it must have exactly one input + /// source file. The ASTUnit takes ownership of the CompilerInvocation object. + /// + /// \param PCHContainerOps - The PCHContainerOperations to use for loading and + /// creating modules. + /// + /// \param Diags - The diagnostics engine to use for reporting errors; its + /// lifetime is expected to extend past that of the returned ASTUnit. + /// + /// \param Action - The ASTFrontendAction to invoke. Its ownership is not + /// transferred. + /// + /// \param Unit - optionally an already created ASTUnit. Its ownership is not + /// transferred. + /// + /// \param Persistent - if true the returned ASTUnit will be complete. + /// false means the caller is only interested in getting info through the + /// provided \see Action. + /// + /// \param ErrAST - If non-null and parsing failed without any AST to return + /// (e.g. because the PCH could not be loaded), this accepts the ASTUnit + /// mainly to allow the caller to see the diagnostics. + /// This will only receive an ASTUnit if a new one was created. If an already + /// created ASTUnit was passed in \p Unit then the caller can check that. + /// + static ASTUnit *LoadFromCompilerInvocationAction( + CompilerInvocation *CI, + std::shared_ptr<PCHContainerOperations> PCHContainerOps, + IntrusiveRefCntPtr<DiagnosticsEngine> Diags, + ASTFrontendAction *Action = nullptr, ASTUnit *Unit = nullptr, + bool Persistent = true, StringRef ResourceFilesPath = StringRef(), + bool OnlyLocalDecls = false, bool CaptureDiagnostics = false, + bool PrecompilePreamble = false, bool CacheCodeCompletionResults = false, + bool IncludeBriefCommentsInCodeCompletion = false, + bool UserFilesAreVolatile = false, + std::unique_ptr<ASTUnit> *ErrAST = nullptr); + + /// LoadFromCompilerInvocation - Create an ASTUnit from a source file, via a + /// CompilerInvocation object. + /// + /// \param CI - The compiler invocation to use; it must have exactly one input + /// source file. The ASTUnit takes ownership of the CompilerInvocation object. + /// + /// \param PCHContainerOps - The PCHContainerOperations to use for loading and + /// creating modules. + /// + /// \param Diags - The diagnostics engine to use for reporting errors; its + /// lifetime is expected to extend past that of the returned ASTUnit. + // + // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we + // shouldn't need to specify them at construction time. + static std::unique_ptr<ASTUnit> LoadFromCompilerInvocation( + CompilerInvocation *CI, + std::shared_ptr<PCHContainerOperations> PCHContainerOps, + IntrusiveRefCntPtr<DiagnosticsEngine> Diags, bool OnlyLocalDecls = false, + bool CaptureDiagnostics = false, bool PrecompilePreamble = false, + TranslationUnitKind TUKind = TU_Complete, + bool CacheCodeCompletionResults = false, + bool IncludeBriefCommentsInCodeCompletion = false, + bool UserFilesAreVolatile = false); + + /// LoadFromCommandLine - Create an ASTUnit from a vector of command line + /// arguments, which must specify exactly one source file. + /// + /// \param ArgBegin - The beginning of the argument vector. + /// + /// \param ArgEnd - The end of the argument vector. + /// + /// \param PCHContainerOps - The PCHContainerOperations to use for loading and + /// creating modules. + /// + /// \param Diags - The diagnostics engine to use for reporting errors; its + /// lifetime is expected to extend past that of the returned ASTUnit. + /// + /// \param ResourceFilesPath - The path to the compiler resource files. + /// + /// \param ErrAST - If non-null and parsing failed without any AST to return + /// (e.g. because the PCH could not be loaded), this accepts the ASTUnit + /// mainly to allow the caller to see the diagnostics. + /// + // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we + // shouldn't need to specify them at construction time. + static ASTUnit *LoadFromCommandLine( + const char **ArgBegin, const char **ArgEnd, + std::shared_ptr<PCHContainerOperations> PCHContainerOps, + IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath, + bool OnlyLocalDecls = false, bool CaptureDiagnostics = false, + ArrayRef<RemappedFile> RemappedFiles = None, + bool RemappedFilesKeepOriginalName = true, + bool PrecompilePreamble = false, TranslationUnitKind TUKind = TU_Complete, + bool CacheCodeCompletionResults = false, + bool IncludeBriefCommentsInCodeCompletion = false, + bool AllowPCHWithCompilerErrors = false, bool SkipFunctionBodies = false, + bool UserFilesAreVolatile = false, bool ForSerialization = false, + std::unique_ptr<ASTUnit> *ErrAST = nullptr); + + /// \brief Reparse the source files using the same command-line options that + /// were originally used to produce this translation unit. + /// + /// \returns True if a failure occurred that causes the ASTUnit not to + /// contain any translation-unit information, false otherwise. + bool Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps, + ArrayRef<RemappedFile> RemappedFiles = None); + + /// \brief Perform code completion at the given file, line, and + /// column within this translation unit. + /// + /// \param File The file in which code completion will occur. + /// + /// \param Line The line at which code completion will occur. + /// + /// \param Column The column at which code completion will occur. + /// + /// \param IncludeMacros Whether to include macros in the code-completion + /// results. + /// + /// \param IncludeCodePatterns Whether to include code patterns (such as a + /// for loop) in the code-completion results. + /// + /// \param IncludeBriefComments Whether to include brief documentation within + /// the set of code completions returned. + /// + /// FIXME: The Diag, LangOpts, SourceMgr, FileMgr, StoredDiagnostics, and + /// OwnedBuffers parameters are all disgusting hacks. They will go away. + void CodeComplete(StringRef File, unsigned Line, unsigned Column, + ArrayRef<RemappedFile> RemappedFiles, bool IncludeMacros, + bool IncludeCodePatterns, bool IncludeBriefComments, + CodeCompleteConsumer &Consumer, + std::shared_ptr<PCHContainerOperations> PCHContainerOps, + DiagnosticsEngine &Diag, LangOptions &LangOpts, + SourceManager &SourceMgr, FileManager &FileMgr, + SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics, + SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers); + + /// \brief Save this translation unit to a file with the given name. + /// + /// \returns true if there was a file error or false if the save was + /// successful. + bool Save(StringRef File); + + /// \brief Serialize this translation unit with the given output stream. + /// + /// \returns True if an error occurred, false otherwise. + bool serialize(raw_ostream &OS); + + ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path, + Module::NameVisibilityKind Visibility, + bool IsInclusionDirective) override { + // ASTUnit doesn't know how to load modules (not that this matters). + return ModuleLoadResult(); + } + + void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility, + SourceLocation ImportLoc) override {} + + GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override + { return nullptr; } + bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override + { return 0; }; +}; + +} // namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/ChainedDiagnosticConsumer.h b/contrib/llvm/tools/clang/include/clang/Frontend/ChainedDiagnosticConsumer.h new file mode 100644 index 0000000..eb33273 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/ChainedDiagnosticConsumer.h @@ -0,0 +1,72 @@ +//===- ChainedDiagnosticConsumer.h - Chain Diagnostic Clients ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_CHAINEDDIAGNOSTICCONSUMER_H +#define LLVM_CLANG_FRONTEND_CHAINEDDIAGNOSTICCONSUMER_H + +#include "clang/Basic/Diagnostic.h" +#include <memory> + +namespace clang { +class LangOptions; + +/// ChainedDiagnosticConsumer - Chain two diagnostic clients so that diagnostics +/// go to the first client and then the second. The first diagnostic client +/// should be the "primary" client, and will be used for computing whether the +/// diagnostics should be included in counts. +class ChainedDiagnosticConsumer : public DiagnosticConsumer { + virtual void anchor(); + std::unique_ptr<DiagnosticConsumer> OwningPrimary; + DiagnosticConsumer *Primary; + std::unique_ptr<DiagnosticConsumer> Secondary; + +public: + ChainedDiagnosticConsumer(std::unique_ptr<DiagnosticConsumer> Primary, + std::unique_ptr<DiagnosticConsumer> Secondary) + : OwningPrimary(std::move(Primary)), Primary(OwningPrimary.get()), + Secondary(std::move(Secondary)) {} + + /// \brief Construct without taking ownership of \c Primary. + ChainedDiagnosticConsumer(DiagnosticConsumer *Primary, + std::unique_ptr<DiagnosticConsumer> Secondary) + : Primary(Primary), Secondary(std::move(Secondary)) {} + + void BeginSourceFile(const LangOptions &LO, + const Preprocessor *PP) override { + Primary->BeginSourceFile(LO, PP); + Secondary->BeginSourceFile(LO, PP); + } + + void EndSourceFile() override { + Secondary->EndSourceFile(); + Primary->EndSourceFile(); + } + + void finish() override { + Secondary->finish(); + Primary->finish(); + } + + bool IncludeInDiagnosticCounts() const override { + return Primary->IncludeInDiagnosticCounts(); + } + + void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, + const Diagnostic &Info) override { + // Default implementation (Warnings/errors count). + DiagnosticConsumer::HandleDiagnostic(DiagLevel, Info); + + Primary->HandleDiagnostic(DiagLevel, Info); + Secondary->HandleDiagnostic(DiagLevel, Info); + } +}; + +} // end namspace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.def b/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.def new file mode 100644 index 0000000..803d023 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.def @@ -0,0 +1,186 @@ +//===--- CodeGenOptions.def - Code generation option database ------ C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the code generation options. Users of this file +// must define the CODEGENOPT macro to make use of this information. +// Optionally, the user may also define ENUM_CODEGENOPT (for options +// that have enumeration type and VALUE_CODEGENOPT is a code +// generation option that describes a value rather than a flag. +// +//===----------------------------------------------------------------------===// +#ifndef CODEGENOPT +# error Define the CODEGENOPT macro to handle language options +#endif + +#ifndef VALUE_CODEGENOPT +# define VALUE_CODEGENOPT(Name, Bits, Default) \ +CODEGENOPT(Name, Bits, Default) +#endif + +#ifndef ENUM_CODEGENOPT +# define ENUM_CODEGENOPT(Name, Type, Bits, Default) \ +CODEGENOPT(Name, Bits, Default) +#endif + +CODEGENOPT(DisableIntegratedAS, 1, 0) ///< -no-integrated-as +CODEGENOPT(CompressDebugSections, 1, 0) ///< -Wa,-compress-debug-sections +CODEGENOPT(Autolink , 1, 1) ///< -fno-autolink +CODEGENOPT(AsmVerbose , 1, 0) ///< -dA, -fverbose-asm. +CODEGENOPT(ObjCAutoRefCountExceptions , 1, 0) ///< Whether ARC should be EH-safe. +CODEGENOPT(CoverageExtraChecksum, 1, 0) ///< Whether we need a second checksum for functions in GCNO files. +CODEGENOPT(CoverageNoFunctionNamesInData, 1, 0) ///< Do not include function names in GCDA files. +CODEGENOPT(CoverageExitBlockBeforeBody, 1, 0) ///< Whether to emit the exit block before the body blocks in GCNO files. +CODEGENOPT(CXAAtExit , 1, 1) ///< Use __cxa_atexit for calling destructors. +CODEGENOPT(CXXCtorDtorAliases, 1, 0) ///< Emit complete ctors/dtors as linker + ///< aliases to base ctors when possible. +CODEGENOPT(DataSections , 1, 0) ///< Set when -fdata-sections is enabled. +CODEGENOPT(UniqueSectionNames, 1, 1) ///< Set for -funique-section-names. +CODEGENOPT(DisableFPElim , 1, 0) ///< Set when -fomit-frame-pointer is enabled. +CODEGENOPT(DisableFree , 1, 0) ///< Don't free memory. +CODEGENOPT(DisableGCov , 1, 0) ///< Don't run the GCov pass, for testing. +CODEGENOPT(DisableLLVMOpts , 1, 0) ///< Don't run any optimizations, for use in + ///< getting .bc files that correspond to the + ///< internal state before optimizations are + ///< done. +CODEGENOPT(DisableRedZone , 1, 0) ///< Set when -mno-red-zone is enabled. +CODEGENOPT(DisableTailCalls , 1, 0) ///< Do not emit tail calls. +CODEGENOPT(EmitDeclMetadata , 1, 0) ///< Emit special metadata indicating what + ///< Decl* various IR entities came from. + ///< Only useful when running CodeGen as a + ///< subroutine. +CODEGENOPT(EmitGcovArcs , 1, 0) ///< Emit coverage data files, aka. GCDA. +CODEGENOPT(EmitGcovNotes , 1, 0) ///< Emit coverage "notes" files, aka GCNO. +CODEGENOPT(EmitOpenCLArgMetadata , 1, 0) ///< Emit OpenCL kernel arg metadata. +/// \brief FP_CONTRACT mode (on/off/fast). +ENUM_CODEGENOPT(FPContractMode, FPContractModeKind, 2, FPC_On) +CODEGENOPT(ForbidGuardVariables , 1, 0) ///< Issue errors if C++ guard variables + ///< are required. +CODEGENOPT(FunctionSections , 1, 0) ///< Set when -ffunction-sections is enabled. +CODEGENOPT(InstrumentFunctions , 1, 0) ///< Set when -finstrument-functions is + ///< enabled. +CODEGENOPT(InstrumentForProfiling , 1, 0) ///< Set when -pg is enabled. +CODEGENOPT(LessPreciseFPMAD , 1, 0) ///< Enable less precise MAD instructions to + ///< be generated. +CODEGENOPT(PrepareForLTO , 1, 0) ///< Set when -flto is enabled on the + ///< compile step. +CODEGENOPT(MergeAllConstants , 1, 1) ///< Merge identical constants. +CODEGENOPT(MergeFunctions , 1, 0) ///< Set when -fmerge-functions is enabled. +CODEGENOPT(MSVolatile , 1, 0) ///< Set when /volatile:ms is enabled. +CODEGENOPT(NoCommon , 1, 0) ///< Set when -fno-common or C++ is enabled. +CODEGENOPT(NoDwarfDirectoryAsm , 1, 0) ///< Set when -fno-dwarf-directory-asm is + ///< enabled. +CODEGENOPT(NoExecStack , 1, 0) ///< Set when -Wa,--noexecstack is enabled. +CODEGENOPT(FatalWarnings , 1, 0) ///< Set when -Wa,--fatal-warnings is + ///< enabled. +CODEGENOPT(EnableSegmentedStacks , 1, 0) ///< Set when -fsplit-stack is enabled. +CODEGENOPT(NoImplicitFloat , 1, 0) ///< Set when -mno-implicit-float is enabled. +CODEGENOPT(NoInfsFPMath , 1, 0) ///< Assume FP arguments, results not +-Inf. +CODEGENOPT(NoSignedZeros , 1, 0) ///< Allow ignoring the signedness of FP zero +CODEGENOPT(ReciprocalMath , 1, 0) ///< Allow FP divisions to be reassociated. +CODEGENOPT(NoInline , 1, 0) ///< Set when -fno-inline is enabled. + ///< Disables use of the inline keyword. +CODEGENOPT(NoNaNsFPMath , 1, 0) ///< Assume FP arguments, results not NaN. +CODEGENOPT(NoZeroInitializedInBSS , 1, 0) ///< -fno-zero-initialized-in-bss. +/// \brief Method of Objective-C dispatch to use. +ENUM_CODEGENOPT(ObjCDispatchMethod, ObjCDispatchMethodKind, 2, Legacy) +CODEGENOPT(OmitLeafFramePointer , 1, 0) ///< Set when -momit-leaf-frame-pointer is + ///< enabled. +VALUE_CODEGENOPT(OptimizationLevel, 2, 0) ///< The -O[0-3] option specified. +VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is specified. + +CODEGENOPT(ProfileInstrGenerate , 1, 0) ///< Instrument code to generate + ///< execution counts to use with PGO. +CODEGENOPT(CoverageMapping , 1, 0) ///< Generate coverage mapping regions to + ///< enable code coverage analysis. +CODEGENOPT(DumpCoverageMapping , 1, 0) ///< Dump the generated coverage mapping + ///< regions. + + /// If -fpcc-struct-return or -freg-struct-return is specified. +ENUM_CODEGENOPT(StructReturnConvention, StructReturnConventionKind, 2, SRCK_Default) + +CODEGENOPT(RelaxAll , 1, 0) ///< Relax all machine code instructions. +CODEGENOPT(RelaxedAliasing , 1, 0) ///< Set when -fno-strict-aliasing is enabled. +CODEGENOPT(StructPathTBAA , 1, 0) ///< Whether or not to use struct-path TBAA. +CODEGENOPT(SaveTempLabels , 1, 0) ///< Save temporary labels. +CODEGENOPT(SanitizeAddressZeroBaseShadow , 1, 0) ///< Map shadow memory at zero + ///< offset in AddressSanitizer. +CODEGENOPT(SanitizeMemoryTrackOrigins, 2, 0) ///< Enable tracking origins in + ///< MemorySanitizer +CODEGENOPT(SanitizeMemoryUseAfterDtor, 1, 0) ///< Enable use-after-delete detection + ///< in MemorySanitizer +CODEGENOPT(SanitizeCoverageType, 2, 0) ///< Type of sanitizer coverage + ///< instrumentation. +CODEGENOPT(SanitizeCoverageIndirectCalls, 1, 0) ///< Enable sanitizer coverage + ///< for indirect calls. +CODEGENOPT(SanitizeCoverageTraceBB, 1, 0) ///< Enable basic block tracing in + ///< in sanitizer coverage. +CODEGENOPT(SanitizeCoverageTraceCmp, 1, 0) ///< Enable cmp instruction tracing + ///< in sanitizer coverage. +CODEGENOPT(SanitizeCoverage8bitCounters, 1, 0) ///< Use 8-bit frequency counters + ///< in sanitizer coverage. +CODEGENOPT(SimplifyLibCalls , 1, 1) ///< Set when -fbuiltin is enabled. +CODEGENOPT(SoftFloat , 1, 0) ///< -soft-float. +CODEGENOPT(StrictEnums , 1, 0) ///< Optimize based on strict enum definition. +CODEGENOPT(TimePasses , 1, 0) ///< Set when -ftime-report is enabled. +CODEGENOPT(UnitAtATime , 1, 1) ///< Unused. For mirroring GCC optimization + ///< selection. +CODEGENOPT(UnrollLoops , 1, 0) ///< Control whether loops are unrolled. +CODEGENOPT(RerollLoops , 1, 0) ///< Control whether loops are rerolled. +CODEGENOPT(UnsafeFPMath , 1, 0) ///< Allow unsafe floating point optzns. +CODEGENOPT(UnwindTables , 1, 0) ///< Emit unwind tables. +CODEGENOPT(VectorizeBB , 1, 0) ///< Run basic block vectorizer. +CODEGENOPT(VectorizeLoop , 1, 0) ///< Run loop vectorizer. +CODEGENOPT(VectorizeSLP , 1, 0) ///< Run SLP vectorizer. + + /// Attempt to use register sized accesses to bit-fields in structures, when + /// possible. +CODEGENOPT(UseRegisterSizedBitfieldAccess , 1, 0) + +CODEGENOPT(VerifyModule , 1, 1) ///< Control whether the module should be run + ///< through the LLVM Verifier. + +CODEGENOPT(StackRealignment , 1, 0) ///< Control whether to permit stack + ///< realignment. +CODEGENOPT(UseInitArray , 1, 0) ///< Control whether to use .init_array or + ///< .ctors. +VALUE_CODEGENOPT(StackAlignment , 32, 0) ///< Overrides default stack + ///< alignment, if not 0. +VALUE_CODEGENOPT(StackProbeSize , 32, 4096) ///< Overrides default stack + ///< probe size, even if 0. +CODEGENOPT(DebugColumnInfo, 1, 0) ///< Whether or not to use column information + ///< in debug info. + +CODEGENOPT(EmitLLVMUseLists, 1, 0) ///< Control whether to serialize use-lists. + +/// The user specified number of registers to be used for integral arguments, +/// or 0 if unspecified. +VALUE_CODEGENOPT(NumRegisterParameters, 32, 0) + +/// The lower bound for a buffer to be considered for stack protection. +VALUE_CODEGENOPT(SSPBufferSize, 32, 0) + +/// The kind of generated debug info. +ENUM_CODEGENOPT(DebugInfo, DebugInfoKind, 3, NoDebugInfo) + +/// Dwarf version. +VALUE_CODEGENOPT(DwarfVersion, 3, 0) + +/// The kind of inlining to perform. +ENUM_CODEGENOPT(Inlining, InliningMethod, 2, NoInlining) + +// Vector functions library to use. +ENUM_CODEGENOPT(VecLib, VectorLibrary, 1, NoLibrary) + +/// The default TLS model to use. +ENUM_CODEGENOPT(DefaultTLSModel, TLSModel, 2, GeneralDynamicTLSModel) + +#undef CODEGENOPT +#undef ENUM_CODEGENOPT +#undef VALUE_CODEGENOPT + diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.h b/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.h new file mode 100644 index 0000000..53246bc --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/CodeGenOptions.h @@ -0,0 +1,217 @@ +//===--- CodeGenOptions.h ---------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the CodeGenOptions interface. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_CODEGENOPTIONS_H +#define LLVM_CLANG_FRONTEND_CODEGENOPTIONS_H + +#include "clang/Basic/Sanitizers.h" +#include "llvm/Support/Regex.h" +#include <memory> +#include <string> +#include <vector> + +namespace clang { + +/// \brief Bitfields of CodeGenOptions, split out from CodeGenOptions to ensure +/// that this large collection of bitfields is a trivial class type. +class CodeGenOptionsBase { +public: +#define CODEGENOPT(Name, Bits, Default) unsigned Name : Bits; +#define ENUM_CODEGENOPT(Name, Type, Bits, Default) +#include "clang/Frontend/CodeGenOptions.def" + +protected: +#define CODEGENOPT(Name, Bits, Default) +#define ENUM_CODEGENOPT(Name, Type, Bits, Default) unsigned Name : Bits; +#include "clang/Frontend/CodeGenOptions.def" +}; + +/// CodeGenOptions - Track various options which control how the code +/// is optimized and passed to the backend. +class CodeGenOptions : public CodeGenOptionsBase { +public: + enum InliningMethod { + NoInlining, // Perform no inlining whatsoever. + NormalInlining, // Use the standard function inlining pass. + OnlyAlwaysInlining // Only run the always inlining pass. + }; + + enum VectorLibrary { + NoLibrary, // Don't use any vector library. + Accelerate // Use the Accelerate framework. + }; + + enum ObjCDispatchMethodKind { + Legacy = 0, + NonLegacy = 1, + Mixed = 2 + }; + + enum DebugInfoKind { + NoDebugInfo, /// Don't generate debug info. + + LocTrackingOnly, /// Emit location information but do not generate + /// debug info in the output. This is useful in + /// cases where the backend wants to track source + /// locations for instructions without actually + /// emitting debug info for them (e.g., when -Rpass + /// is used). + + DebugLineTablesOnly, /// Emit only debug info necessary for generating + /// line number tables (-gline-tables-only). + + LimitedDebugInfo, /// Limit generated debug info to reduce size + /// (-fno-standalone-debug). This emits + /// forward decls for types that could be + /// replaced with forward decls in the source + /// code. For dynamic C++ classes type info + /// is only emitted int the module that + /// contains the classe's vtable. + + FullDebugInfo /// Generate complete debug info. + }; + + enum TLSModel { + GeneralDynamicTLSModel, + LocalDynamicTLSModel, + InitialExecTLSModel, + LocalExecTLSModel + }; + + enum FPContractModeKind { + FPC_Off, // Form fused FP ops only where result will not be affected. + FPC_On, // Form fused FP ops according to FP_CONTRACT rules. + FPC_Fast // Aggressively fuse FP ops (E.g. FMA). + }; + + enum StructReturnConventionKind { + SRCK_Default, // No special option was passed. + SRCK_OnStack, // Small structs on the stack (-fpcc-struct-return). + SRCK_InRegs // Small structs in registers (-freg-struct-return). + }; + + /// The code model to use (-mcmodel). + std::string CodeModel; + + /// The filename with path we use for coverage files. The extension will be + /// replaced. + std::string CoverageFile; + + /// The version string to put into coverage files. + char CoverageVersion[4]; + + /// Enable additional debugging information. + std::string DebugPass; + + /// The string to embed in debug information as the current working directory. + std::string DebugCompilationDir; + + /// The string to embed in the debug information for the compile unit, if + /// non-empty. + std::string DwarfDebugFlags; + + /// The ABI to use for passing floating point arguments. + std::string FloatABI; + + /// The float precision limit to use, if non-empty. + std::string LimitFloatPrecision; + + /// The name of the bitcode file to link before optzns. + std::string LinkBitcodeFile; + + /// The user provided name for the "main file", if non-empty. This is useful + /// in situations where the input file name does not match the original input + /// file, for example with -save-temps. + std::string MainFileName; + + /// The name for the split debug info file that we'll break out. This is used + /// in the backend for setting the name in the skeleton cu. + std::string SplitDwarfFile; + + /// The name of the relocation model to use. + std::string RelocationModel; + + /// The thread model to use + std::string ThreadModel; + + /// If not an empty string, trap intrinsics are lowered to calls to this + /// function instead of to trap instructions. + std::string TrapFuncName; + + /// A list of command-line options to forward to the LLVM backend. + std::vector<std::string> BackendOptions; + + /// A list of dependent libraries. + std::vector<std::string> DependentLibraries; + + /// Name of the profile file to use as output for -fprofile-instr-generate + /// and -fprofile-generate. + std::string InstrProfileOutput; + + /// Name of the profile file to use with -fprofile-sample-use. + std::string SampleProfileFile; + + /// Name of the profile file to use as input for -fprofile-instr-use + std::string InstrProfileInput; + + /// A list of file names passed with -fcuda-include-gpubinary options to + /// forward to CUDA runtime back-end for incorporating them into host-side + /// object file. + std::vector<std::string> CudaGpuBinaryFileNames; + + /// Regular expression to select optimizations for which we should enable + /// optimization remarks. Transformation passes whose name matches this + /// expression (and support this feature), will emit a diagnostic + /// whenever they perform a transformation. This is enabled by the + /// -Rpass=regexp flag. + std::shared_ptr<llvm::Regex> OptimizationRemarkPattern; + + /// Regular expression to select optimizations for which we should enable + /// missed optimization remarks. Transformation passes whose name matches this + /// expression (and support this feature), will emit a diagnostic + /// whenever they tried but failed to perform a transformation. This is + /// enabled by the -Rpass-missed=regexp flag. + std::shared_ptr<llvm::Regex> OptimizationRemarkMissedPattern; + + /// Regular expression to select optimizations for which we should enable + /// optimization analyses. Transformation passes whose name matches this + /// expression (and support this feature), will emit a diagnostic + /// whenever they want to explain why they decided to apply or not apply + /// a given transformation. This is enabled by the -Rpass-analysis=regexp + /// flag. + std::shared_ptr<llvm::Regex> OptimizationRemarkAnalysisPattern; + + /// Set of files definining the rules for the symbol rewriting. + std::vector<std::string> RewriteMapFiles; + + /// Set of sanitizer checks that are non-fatal (i.e. execution should be + /// continued when possible). + SanitizerSet SanitizeRecover; + + /// Set of sanitizer checks that trap rather than diagnose. + SanitizerSet SanitizeTrap; + +public: + // Define accessors/mutators for code generation options of enumeration type. +#define CODEGENOPT(Name, Bits, Default) +#define ENUM_CODEGENOPT(Name, Type, Bits, Default) \ + Type get##Name() const { return static_cast<Type>(Name); } \ + void set##Name(Type Value) { Name = static_cast<unsigned>(Value); } +#include "clang/Frontend/CodeGenOptions.def" + + CodeGenOptions(); +}; + +} // end namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/CommandLineSourceLoc.h b/contrib/llvm/tools/clang/include/clang/Frontend/CommandLineSourceLoc.h new file mode 100644 index 0000000..a78c96d --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/CommandLineSourceLoc.h @@ -0,0 +1,87 @@ + +//===--- CommandLineSourceLoc.h - Parsing for source locations-*- C++ -*---===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Command line parsing for source locations. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_COMMANDLINESOURCELOC_H +#define LLVM_CLANG_FRONTEND_COMMANDLINESOURCELOC_H + +#include "clang/Basic/LLVM.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/raw_ostream.h" + +namespace clang { + +/// \brief A source location that has been parsed on the command line. +struct ParsedSourceLocation { + std::string FileName; + unsigned Line; + unsigned Column; + +public: + /// Construct a parsed source location from a string; the Filename is empty on + /// error. + static ParsedSourceLocation FromString(StringRef Str) { + ParsedSourceLocation PSL; + std::pair<StringRef, StringRef> ColSplit = Str.rsplit(':'); + std::pair<StringRef, StringRef> LineSplit = + ColSplit.first.rsplit(':'); + + // If both tail splits were valid integers, return success. + if (!ColSplit.second.getAsInteger(10, PSL.Column) && + !LineSplit.second.getAsInteger(10, PSL.Line)) { + PSL.FileName = LineSplit.first; + + // On the command-line, stdin may be specified via "-". Inside the + // compiler, stdin is called "<stdin>". + if (PSL.FileName == "-") + PSL.FileName = "<stdin>"; + } + + return PSL; + } +}; + +} + +namespace llvm { + namespace cl { + /// \brief Command-line option parser that parses source locations. + /// + /// Source locations are of the form filename:line:column. + template<> + class parser<clang::ParsedSourceLocation> final + : public basic_parser<clang::ParsedSourceLocation> { + public: + inline bool parse(Option &O, StringRef ArgName, StringRef ArgValue, + clang::ParsedSourceLocation &Val); + }; + + bool + parser<clang::ParsedSourceLocation>:: + parse(Option &O, StringRef ArgName, StringRef ArgValue, + clang::ParsedSourceLocation &Val) { + using namespace clang; + + Val = ParsedSourceLocation::FromString(ArgValue); + if (Val.FileName.empty()) { + errs() << "error: " + << "source location must be of the form filename:line:column\n"; + return true; + } + + return false; + } + } +} + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInstance.h b/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInstance.h new file mode 100644 index 0000000..45e5ed1 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInstance.h @@ -0,0 +1,779 @@ +//===-- CompilerInstance.h - Clang Compiler Instance ------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_ +#define LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_ + +#include "clang/AST/ASTConsumer.h" +#include "clang/Frontend/PCHContainerOperations.h" +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Frontend/CompilerInvocation.h" +#include "clang/Frontend/Utils.h" +#include "clang/Lex/ModuleLoader.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/StringRef.h" +#include <cassert> +#include <list> +#include <memory> +#include <string> +#include <utility> + +namespace llvm { +class raw_fd_ostream; +class Timer; +class TimerGroup; +} + +namespace clang { +class ASTContext; +class ASTConsumer; +class ASTReader; +class CodeCompleteConsumer; +class DiagnosticsEngine; +class DiagnosticConsumer; +class ExternalASTSource; +class FileEntry; +class FileManager; +class FrontendAction; +class Module; +class Preprocessor; +class Sema; +class SourceManager; +class TargetInfo; + +/// CompilerInstance - Helper class for managing a single instance of the Clang +/// compiler. +/// +/// The CompilerInstance serves two purposes: +/// (1) It manages the various objects which are necessary to run the compiler, +/// for example the preprocessor, the target information, and the AST +/// context. +/// (2) It provides utility routines for constructing and manipulating the +/// common Clang objects. +/// +/// The compiler instance generally owns the instance of all the objects that it +/// manages. However, clients can still share objects by manually setting the +/// object and retaking ownership prior to destroying the CompilerInstance. +/// +/// The compiler instance is intended to simplify clients, but not to lock them +/// in to the compiler instance for everything. When possible, utility functions +/// come in two forms; a short form that reuses the CompilerInstance objects, +/// and a long form that takes explicit instances of any required objects. +class CompilerInstance : public ModuleLoader { + /// The options used in this compiler instance. + IntrusiveRefCntPtr<CompilerInvocation> Invocation; + + /// The diagnostics engine instance. + IntrusiveRefCntPtr<DiagnosticsEngine> Diagnostics; + + /// The target being compiled for. + IntrusiveRefCntPtr<TargetInfo> Target; + + /// The virtual file system. + IntrusiveRefCntPtr<vfs::FileSystem> VirtualFileSystem; + + /// The file manager. + IntrusiveRefCntPtr<FileManager> FileMgr; + + /// The source manager. + IntrusiveRefCntPtr<SourceManager> SourceMgr; + + /// The preprocessor. + IntrusiveRefCntPtr<Preprocessor> PP; + + /// The AST context. + IntrusiveRefCntPtr<ASTContext> Context; + + /// The AST consumer. + std::unique_ptr<ASTConsumer> Consumer; + + /// The code completion consumer. + std::unique_ptr<CodeCompleteConsumer> CompletionConsumer; + + /// \brief The semantic analysis object. + std::unique_ptr<Sema> TheSema; + + /// \brief The frontend timer group. + std::unique_ptr<llvm::TimerGroup> FrontendTimerGroup; + + /// \brief The frontend timer. + std::unique_ptr<llvm::Timer> FrontendTimer; + + /// \brief The ASTReader, if one exists. + IntrusiveRefCntPtr<ASTReader> ModuleManager; + + /// \brief The module dependency collector for crashdumps + std::shared_ptr<ModuleDependencyCollector> ModuleDepCollector; + + /// \brief The module provider. + std::shared_ptr<PCHContainerOperations> ThePCHContainerOperations; + + /// \brief The dependency file generator. + std::unique_ptr<DependencyFileGenerator> TheDependencyFileGenerator; + + std::vector<std::shared_ptr<DependencyCollector>> DependencyCollectors; + + /// \brief The set of top-level modules that has already been loaded, + /// along with the module map + llvm::DenseMap<const IdentifierInfo *, Module *> KnownModules; + + /// \brief Module names that have an override for the target file. + llvm::StringMap<std::string> ModuleFileOverrides; + + /// \brief Module files that we've explicitly loaded via \ref loadModuleFile, + /// and their dependencies. + llvm::StringSet<> ExplicitlyLoadedModuleFiles; + + /// \brief The location of the module-import keyword for the last module + /// import. + SourceLocation LastModuleImportLoc; + + /// \brief The result of the last module import. + /// + ModuleLoadResult LastModuleImportResult; + + /// \brief Whether we should (re)build the global module index once we + /// have finished with this translation unit. + bool BuildGlobalModuleIndex; + + /// \brief We have a full global module index, with all modules. + bool HaveFullGlobalModuleIndex; + + /// \brief One or more modules failed to build. + bool ModuleBuildFailed; + + /// \brief Holds information about the output file. + /// + /// If TempFilename is not empty we must rename it to Filename at the end. + /// TempFilename may be empty and Filename non-empty if creating the temporary + /// failed. + struct OutputFile { + std::string Filename; + std::string TempFilename; + std::unique_ptr<raw_ostream> OS; + + OutputFile(std::string filename, std::string tempFilename, + std::unique_ptr<raw_ostream> OS) + : Filename(std::move(filename)), TempFilename(std::move(tempFilename)), + OS(std::move(OS)) {} + OutputFile(OutputFile &&O) + : Filename(std::move(O.Filename)), + TempFilename(std::move(O.TempFilename)), OS(std::move(O.OS)) {} + }; + + /// If the output doesn't support seeking (terminal, pipe). we switch + /// the stream to a buffer_ostream. These are the buffer and the original + /// stream. + std::unique_ptr<llvm::raw_fd_ostream> NonSeekStream; + + /// The list of active output files. + std::list<OutputFile> OutputFiles; + + CompilerInstance(const CompilerInstance &) = delete; + void operator=(const CompilerInstance &) = delete; +public: + explicit CompilerInstance( + std::shared_ptr<PCHContainerOperations> PCHContainerOps = + std::make_shared<PCHContainerOperations>(), + bool BuildingModule = false); + ~CompilerInstance() override; + + /// @name High-Level Operations + /// { + + /// ExecuteAction - Execute the provided action against the compiler's + /// CompilerInvocation object. + /// + /// This function makes the following assumptions: + /// + /// - The invocation options should be initialized. This function does not + /// handle the '-help' or '-version' options, clients should handle those + /// directly. + /// + /// - The diagnostics engine should have already been created by the client. + /// + /// - No other CompilerInstance state should have been initialized (this is + /// an unchecked error). + /// + /// - Clients should have initialized any LLVM target features that may be + /// required. + /// + /// - Clients should eventually call llvm_shutdown() upon the completion of + /// this routine to ensure that any managed objects are properly destroyed. + /// + /// Note that this routine may write output to 'stderr'. + /// + /// \param Act - The action to execute. + /// \return - True on success. + // + // FIXME: This function should take the stream to write any debugging / + // verbose output to as an argument. + // + // FIXME: Eliminate the llvm_shutdown requirement, that should either be part + // of the context or else not CompilerInstance specific. + bool ExecuteAction(FrontendAction &Act); + + /// } + /// @name Compiler Invocation and Options + /// { + + bool hasInvocation() const { return Invocation != nullptr; } + + CompilerInvocation &getInvocation() { + assert(Invocation && "Compiler instance has no invocation!"); + return *Invocation; + } + + /// setInvocation - Replace the current invocation. + void setInvocation(CompilerInvocation *Value); + + /// \brief Indicates whether we should (re)build the global module index. + bool shouldBuildGlobalModuleIndex() const; + + /// \brief Set the flag indicating whether we should (re)build the global + /// module index. + void setBuildGlobalModuleIndex(bool Build) { + BuildGlobalModuleIndex = Build; + } + + /// } + /// @name Forwarding Methods + /// { + + AnalyzerOptionsRef getAnalyzerOpts() { + return Invocation->getAnalyzerOpts(); + } + + CodeGenOptions &getCodeGenOpts() { + return Invocation->getCodeGenOpts(); + } + const CodeGenOptions &getCodeGenOpts() const { + return Invocation->getCodeGenOpts(); + } + + DependencyOutputOptions &getDependencyOutputOpts() { + return Invocation->getDependencyOutputOpts(); + } + const DependencyOutputOptions &getDependencyOutputOpts() const { + return Invocation->getDependencyOutputOpts(); + } + + DiagnosticOptions &getDiagnosticOpts() { + return Invocation->getDiagnosticOpts(); + } + const DiagnosticOptions &getDiagnosticOpts() const { + return Invocation->getDiagnosticOpts(); + } + + FileSystemOptions &getFileSystemOpts() { + return Invocation->getFileSystemOpts(); + } + const FileSystemOptions &getFileSystemOpts() const { + return Invocation->getFileSystemOpts(); + } + + FrontendOptions &getFrontendOpts() { + return Invocation->getFrontendOpts(); + } + const FrontendOptions &getFrontendOpts() const { + return Invocation->getFrontendOpts(); + } + + HeaderSearchOptions &getHeaderSearchOpts() { + return Invocation->getHeaderSearchOpts(); + } + const HeaderSearchOptions &getHeaderSearchOpts() const { + return Invocation->getHeaderSearchOpts(); + } + + LangOptions &getLangOpts() { + return *Invocation->getLangOpts(); + } + const LangOptions &getLangOpts() const { + return *Invocation->getLangOpts(); + } + + PreprocessorOptions &getPreprocessorOpts() { + return Invocation->getPreprocessorOpts(); + } + const PreprocessorOptions &getPreprocessorOpts() const { + return Invocation->getPreprocessorOpts(); + } + + PreprocessorOutputOptions &getPreprocessorOutputOpts() { + return Invocation->getPreprocessorOutputOpts(); + } + const PreprocessorOutputOptions &getPreprocessorOutputOpts() const { + return Invocation->getPreprocessorOutputOpts(); + } + + TargetOptions &getTargetOpts() { + return Invocation->getTargetOpts(); + } + const TargetOptions &getTargetOpts() const { + return Invocation->getTargetOpts(); + } + + /// } + /// @name Diagnostics Engine + /// { + + bool hasDiagnostics() const { return Diagnostics != nullptr; } + + /// Get the current diagnostics engine. + DiagnosticsEngine &getDiagnostics() const { + assert(Diagnostics && "Compiler instance has no diagnostics!"); + return *Diagnostics; + } + + /// setDiagnostics - Replace the current diagnostics engine. + void setDiagnostics(DiagnosticsEngine *Value); + + DiagnosticConsumer &getDiagnosticClient() const { + assert(Diagnostics && Diagnostics->getClient() && + "Compiler instance has no diagnostic client!"); + return *Diagnostics->getClient(); + } + + /// } + /// @name Target Info + /// { + + bool hasTarget() const { return Target != nullptr; } + + TargetInfo &getTarget() const { + assert(Target && "Compiler instance has no target!"); + return *Target; + } + + /// Replace the current diagnostics engine. + void setTarget(TargetInfo *Value); + + /// } + /// @name Virtual File System + /// { + + bool hasVirtualFileSystem() const { return VirtualFileSystem != nullptr; } + + vfs::FileSystem &getVirtualFileSystem() const { + assert(hasVirtualFileSystem() && + "Compiler instance has no virtual file system"); + return *VirtualFileSystem; + } + + /// \brief Replace the current virtual file system. + /// + /// \note Most clients should use setFileManager, which will implicitly reset + /// the virtual file system to the one contained in the file manager. + void setVirtualFileSystem(IntrusiveRefCntPtr<vfs::FileSystem> FS) { + VirtualFileSystem = FS; + } + + /// } + /// @name File Manager + /// { + + bool hasFileManager() const { return FileMgr != nullptr; } + + /// Return the current file manager to the caller. + FileManager &getFileManager() const { + assert(FileMgr && "Compiler instance has no file manager!"); + return *FileMgr; + } + + void resetAndLeakFileManager() { + BuryPointer(FileMgr.get()); + FileMgr.resetWithoutRelease(); + } + + /// \brief Replace the current file manager and virtual file system. + void setFileManager(FileManager *Value); + + /// } + /// @name Source Manager + /// { + + bool hasSourceManager() const { return SourceMgr != nullptr; } + + /// Return the current source manager. + SourceManager &getSourceManager() const { + assert(SourceMgr && "Compiler instance has no source manager!"); + return *SourceMgr; + } + + void resetAndLeakSourceManager() { + BuryPointer(SourceMgr.get()); + SourceMgr.resetWithoutRelease(); + } + + /// setSourceManager - Replace the current source manager. + void setSourceManager(SourceManager *Value); + + /// } + /// @name Preprocessor + /// { + + bool hasPreprocessor() const { return PP != nullptr; } + + /// Return the current preprocessor. + Preprocessor &getPreprocessor() const { + assert(PP && "Compiler instance has no preprocessor!"); + return *PP; + } + + void resetAndLeakPreprocessor() { + BuryPointer(PP.get()); + PP.resetWithoutRelease(); + } + + /// Replace the current preprocessor. + void setPreprocessor(Preprocessor *Value); + + /// } + /// @name ASTContext + /// { + + bool hasASTContext() const { return Context != nullptr; } + + ASTContext &getASTContext() const { + assert(Context && "Compiler instance has no AST context!"); + return *Context; + } + + void resetAndLeakASTContext() { + BuryPointer(Context.get()); + Context.resetWithoutRelease(); + } + + /// setASTContext - Replace the current AST context. + void setASTContext(ASTContext *Value); + + /// \brief Replace the current Sema; the compiler instance takes ownership + /// of S. + void setSema(Sema *S); + + /// } + /// @name ASTConsumer + /// { + + bool hasASTConsumer() const { return (bool)Consumer; } + + ASTConsumer &getASTConsumer() const { + assert(Consumer && "Compiler instance has no AST consumer!"); + return *Consumer; + } + + /// takeASTConsumer - Remove the current AST consumer and give ownership to + /// the caller. + std::unique_ptr<ASTConsumer> takeASTConsumer() { return std::move(Consumer); } + + /// setASTConsumer - Replace the current AST consumer; the compiler instance + /// takes ownership of \p Value. + void setASTConsumer(std::unique_ptr<ASTConsumer> Value); + + /// } + /// @name Semantic analysis + /// { + bool hasSema() const { return (bool)TheSema; } + + Sema &getSema() const { + assert(TheSema && "Compiler instance has no Sema object!"); + return *TheSema; + } + + std::unique_ptr<Sema> takeSema(); + void resetAndLeakSema(); + + /// } + /// @name Module Management + /// { + + IntrusiveRefCntPtr<ASTReader> getModuleManager() const; + void setModuleManager(IntrusiveRefCntPtr<ASTReader> Reader); + + std::shared_ptr<ModuleDependencyCollector> getModuleDepCollector() const; + void setModuleDepCollector( + std::shared_ptr<ModuleDependencyCollector> Collector); + + std::shared_ptr<PCHContainerOperations> getPCHContainerOperations() const { + return ThePCHContainerOperations; + } + + /// Return the appropriate PCHContainerWriter depending on the + /// current CodeGenOptions. + const PCHContainerWriter &getPCHContainerWriter() const { + assert(Invocation && "cannot determine module format without invocation"); + StringRef Format = getHeaderSearchOpts().ModuleFormat; + auto *Writer = ThePCHContainerOperations->getWriterOrNull(Format); + if (!Writer) { + if (Diagnostics) + Diagnostics->Report(diag::err_module_format_unhandled) << Format; + llvm::report_fatal_error("unknown module format"); + } + return *Writer; + } + + /// Return the appropriate PCHContainerReader depending on the + /// current CodeGenOptions. + const PCHContainerReader &getPCHContainerReader() const { + assert(Invocation && "cannot determine module format without invocation"); + StringRef Format = getHeaderSearchOpts().ModuleFormat; + auto *Reader = ThePCHContainerOperations->getReaderOrNull(Format); + if (!Reader) { + if (Diagnostics) + Diagnostics->Report(diag::err_module_format_unhandled) << Format; + llvm::report_fatal_error("unknown module format"); + } + return *Reader; + } + + /// } + /// @name Code Completion + /// { + + bool hasCodeCompletionConsumer() const { return (bool)CompletionConsumer; } + + CodeCompleteConsumer &getCodeCompletionConsumer() const { + assert(CompletionConsumer && + "Compiler instance has no code completion consumer!"); + return *CompletionConsumer; + } + + /// setCodeCompletionConsumer - Replace the current code completion consumer; + /// the compiler instance takes ownership of \p Value. + void setCodeCompletionConsumer(CodeCompleteConsumer *Value); + + /// } + /// @name Frontend timer + /// { + + bool hasFrontendTimer() const { return (bool)FrontendTimer; } + + llvm::Timer &getFrontendTimer() const { + assert(FrontendTimer && "Compiler instance has no frontend timer!"); + return *FrontendTimer; + } + + /// } + /// @name Output Files + /// { + + /// addOutputFile - Add an output file onto the list of tracked output files. + /// + /// \param OutFile - The output file info. + void addOutputFile(OutputFile &&OutFile); + + /// clearOutputFiles - Clear the output file list, destroying the contained + /// output streams. + /// + /// \param EraseFiles - If true, attempt to erase the files from disk. + void clearOutputFiles(bool EraseFiles); + + /// } + /// @name Construction Utility Methods + /// { + + /// Create the diagnostics engine using the invocation's diagnostic options + /// and replace any existing one with it. + /// + /// Note that this routine also replaces the diagnostic client, + /// allocating one if one is not provided. + /// + /// \param Client If non-NULL, a diagnostic client that will be + /// attached to (and, then, owned by) the DiagnosticsEngine inside this AST + /// unit. + /// + /// \param ShouldOwnClient If Client is non-NULL, specifies whether + /// the diagnostic object should take ownership of the client. + void createDiagnostics(DiagnosticConsumer *Client = nullptr, + bool ShouldOwnClient = true); + + /// Create a DiagnosticsEngine object with a the TextDiagnosticPrinter. + /// + /// If no diagnostic client is provided, this creates a + /// DiagnosticConsumer that is owned by the returned diagnostic + /// object, if using directly the caller is responsible for + /// releasing the returned DiagnosticsEngine's client eventually. + /// + /// \param Opts - The diagnostic options; note that the created text + /// diagnostic object contains a reference to these options. + /// + /// \param Client If non-NULL, a diagnostic client that will be + /// attached to (and, then, owned by) the returned DiagnosticsEngine + /// object. + /// + /// \param CodeGenOpts If non-NULL, the code gen options in use, which may be + /// used by some diagnostics printers (for logging purposes only). + /// + /// \return The new object on success, or null on failure. + static IntrusiveRefCntPtr<DiagnosticsEngine> + createDiagnostics(DiagnosticOptions *Opts, + DiagnosticConsumer *Client = nullptr, + bool ShouldOwnClient = true, + const CodeGenOptions *CodeGenOpts = nullptr); + + /// Create the file manager and replace any existing one with it. + void createFileManager(); + + /// Create the source manager and replace any existing one with it. + void createSourceManager(FileManager &FileMgr); + + /// Create the preprocessor, using the invocation, file, and source managers, + /// and replace any existing one with it. + void createPreprocessor(TranslationUnitKind TUKind); + + std::string getSpecificModuleCachePath(); + + /// Create the AST context. + void createASTContext(); + + /// Create an external AST source to read a PCH file and attach it to the AST + /// context. + void createPCHExternalASTSource(StringRef Path, bool DisablePCHValidation, + bool AllowPCHWithCompilerErrors, + void *DeserializationListener, + bool OwnDeserializationListener); + + /// Create an external AST source to read a PCH file. + /// + /// \return - The new object on success, or null on failure. + static IntrusiveRefCntPtr<ASTReader> createPCHExternalASTSource( + StringRef Path, StringRef Sysroot, bool DisablePCHValidation, + bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context, + const PCHContainerReader &PCHContainerRdr, + void *DeserializationListener, bool OwnDeserializationListener, + bool Preamble, bool UseGlobalModuleIndex); + + /// Create a code completion consumer using the invocation; note that this + /// will cause the source manager to truncate the input source file at the + /// completion point. + void createCodeCompletionConsumer(); + + /// Create a code completion consumer to print code completion results, at + /// \p Filename, \p Line, and \p Column, to the given output stream \p OS. + static CodeCompleteConsumer *createCodeCompletionConsumer( + Preprocessor &PP, StringRef Filename, unsigned Line, unsigned Column, + const CodeCompleteOptions &Opts, raw_ostream &OS); + + /// \brief Create the Sema object to be used for parsing. + void createSema(TranslationUnitKind TUKind, + CodeCompleteConsumer *CompletionConsumer); + + /// Create the frontend timer and replace any existing one with it. + void createFrontendTimer(); + + /// Create the default output file (from the invocation's options) and add it + /// to the list of tracked output files. + /// + /// The files created by this function always use temporary files to write to + /// their result (that is, the data is written to a temporary file which will + /// atomically replace the target output on success). + /// + /// \return - Null on error. + raw_pwrite_stream *createDefaultOutputFile(bool Binary = true, + StringRef BaseInput = "", + StringRef Extension = ""); + + /// Create a new output file and add it to the list of tracked output files, + /// optionally deriving the output path name. + /// + /// \return - Null on error. + raw_pwrite_stream *createOutputFile(StringRef OutputPath, bool Binary, + bool RemoveFileOnSignal, + StringRef BaseInput, StringRef Extension, + bool UseTemporary, + bool CreateMissingDirectories = false); + + /// Create a new output file, optionally deriving the output path name. + /// + /// If \p OutputPath is empty, then createOutputFile will derive an output + /// path location as \p BaseInput, with any suffix removed, and \p Extension + /// appended. If \p OutputPath is not stdout and \p UseTemporary + /// is true, createOutputFile will create a new temporary file that must be + /// renamed to \p OutputPath in the end. + /// + /// \param OutputPath - If given, the path to the output file. + /// \param Error [out] - On failure, the error. + /// \param BaseInput - If \p OutputPath is empty, the input path name to use + /// for deriving the output path. + /// \param Extension - The extension to use for derived output names. + /// \param Binary - The mode to open the file in. + /// \param RemoveFileOnSignal - Whether the file should be registered with + /// llvm::sys::RemoveFileOnSignal. Note that this is not safe for + /// multithreaded use, as the underlying signal mechanism is not reentrant + /// \param UseTemporary - Create a new temporary file that must be renamed to + /// OutputPath in the end. + /// \param CreateMissingDirectories - When \p UseTemporary is true, create + /// missing directories in the output path. + /// \param ResultPathName [out] - If given, the result path name will be + /// stored here on success. + /// \param TempPathName [out] - If given, the temporary file path name + /// will be stored here on success. + std::unique_ptr<raw_pwrite_stream> + createOutputFile(StringRef OutputPath, std::error_code &Error, bool Binary, + bool RemoveFileOnSignal, StringRef BaseInput, + StringRef Extension, bool UseTemporary, + bool CreateMissingDirectories, std::string *ResultPathName, + std::string *TempPathName); + + llvm::raw_null_ostream *createNullOutputFile(); + + /// } + /// @name Initialization Utility Methods + /// { + + /// InitializeSourceManager - Initialize the source manager to set InputFile + /// as the main file. + /// + /// \return True on success. + bool InitializeSourceManager(const FrontendInputFile &Input); + + /// InitializeSourceManager - Initialize the source manager to set InputFile + /// as the main file. + /// + /// \return True on success. + static bool InitializeSourceManager(const FrontendInputFile &Input, + DiagnosticsEngine &Diags, + FileManager &FileMgr, + SourceManager &SourceMgr, + const FrontendOptions &Opts); + + /// } + + // Create module manager. + void createModuleManager(); + + bool loadModuleFile(StringRef FileName); + + ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path, + Module::NameVisibilityKind Visibility, + bool IsInclusionDirective) override; + + void makeModuleVisible(Module *Mod, Module::NameVisibilityKind Visibility, + SourceLocation ImportLoc) override; + + bool hadModuleLoaderFatalFailure() const { + return ModuleLoader::HadFatalFailure; + } + + GlobalModuleIndex *loadGlobalModuleIndex(SourceLocation TriggerLoc) override; + + bool lookupMissingImports(StringRef Name, SourceLocation TriggerLoc) override; + + void addDependencyCollector(std::shared_ptr<DependencyCollector> Listener) { + DependencyCollectors.push_back(std::move(Listener)); + } +}; + +} // end namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInvocation.h b/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInvocation.h new file mode 100644 index 0000000..7d12548 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/CompilerInvocation.h @@ -0,0 +1,219 @@ +//===-- CompilerInvocation.h - Compiler Invocation Helper Data --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H_ +#define LLVM_CLANG_FRONTEND_COMPILERINVOCATION_H_ + +#include "clang/Basic/DiagnosticOptions.h" +#include "clang/Basic/FileSystemOptions.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/TargetOptions.h" +#include "clang/Frontend/CodeGenOptions.h" +#include "clang/Frontend/DependencyOutputOptions.h" +#include "clang/Frontend/FrontendOptions.h" +#include "clang/Frontend/LangStandard.h" +#include "clang/Frontend/MigratorOptions.h" +#include "clang/Frontend/PreprocessorOutputOptions.h" +#include "clang/Lex/HeaderSearchOptions.h" +#include "clang/Lex/PreprocessorOptions.h" +#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include <string> +#include <vector> + +namespace llvm { +namespace opt { +class ArgList; +} +} + +namespace clang { +class CompilerInvocation; +class DiagnosticsEngine; + +/// \brief Fill out Opts based on the options given in Args. +/// +/// Args must have been created from the OptTable returned by +/// createCC1OptTable(). +/// +/// When errors are encountered, return false and, if Diags is non-null, +/// report the error(s). +bool ParseDiagnosticArgs(DiagnosticOptions &Opts, llvm::opt::ArgList &Args, + DiagnosticsEngine *Diags = nullptr); + +class CompilerInvocationBase : public RefCountedBase<CompilerInvocation> { + void operator=(const CompilerInvocationBase &) = delete; + +public: + /// Options controlling the language variant. + std::shared_ptr<LangOptions> LangOpts; + + /// Options controlling the target. + std::shared_ptr<TargetOptions> TargetOpts; + + /// Options controlling the diagnostic engine. + IntrusiveRefCntPtr<DiagnosticOptions> DiagnosticOpts; + + /// Options controlling the \#include directive. + IntrusiveRefCntPtr<HeaderSearchOptions> HeaderSearchOpts; + + /// Options controlling the preprocessor (aside from \#include handling). + IntrusiveRefCntPtr<PreprocessorOptions> PreprocessorOpts; + + CompilerInvocationBase(); + ~CompilerInvocationBase(); + + CompilerInvocationBase(const CompilerInvocationBase &X); + + LangOptions *getLangOpts() { return LangOpts.get(); } + const LangOptions *getLangOpts() const { return LangOpts.get(); } + + TargetOptions &getTargetOpts() { return *TargetOpts.get(); } + const TargetOptions &getTargetOpts() const { + return *TargetOpts.get(); + } + + DiagnosticOptions &getDiagnosticOpts() const { return *DiagnosticOpts; } + + HeaderSearchOptions &getHeaderSearchOpts() { return *HeaderSearchOpts; } + const HeaderSearchOptions &getHeaderSearchOpts() const { + return *HeaderSearchOpts; + } + + PreprocessorOptions &getPreprocessorOpts() { return *PreprocessorOpts; } + const PreprocessorOptions &getPreprocessorOpts() const { + return *PreprocessorOpts; + } +}; + +/// \brief Helper class for holding the data necessary to invoke the compiler. +/// +/// This class is designed to represent an abstract "invocation" of the +/// compiler, including data such as the include paths, the code generation +/// options, the warning flags, and so on. +class CompilerInvocation : public CompilerInvocationBase { + /// Options controlling the static analyzer. + AnalyzerOptionsRef AnalyzerOpts; + + MigratorOptions MigratorOpts; + + /// Options controlling IRgen and the backend. + CodeGenOptions CodeGenOpts; + + /// Options controlling dependency output. + DependencyOutputOptions DependencyOutputOpts; + + /// Options controlling file system operations. + FileSystemOptions FileSystemOpts; + + /// Options controlling the frontend itself. + FrontendOptions FrontendOpts; + + /// Options controlling preprocessed output. + PreprocessorOutputOptions PreprocessorOutputOpts; + +public: + CompilerInvocation() : AnalyzerOpts(new AnalyzerOptions()) {} + + /// @name Utility Methods + /// @{ + + /// \brief Create a compiler invocation from a list of input options. + /// \returns true on success. + /// + /// \param [out] Res - The resulting invocation. + /// \param ArgBegin - The first element in the argument vector. + /// \param ArgEnd - The last element in the argument vector. + /// \param Diags - The diagnostic engine to use for errors. + static bool CreateFromArgs(CompilerInvocation &Res, + const char* const *ArgBegin, + const char* const *ArgEnd, + DiagnosticsEngine &Diags); + + /// \brief Get the directory where the compiler headers + /// reside, relative to the compiler binary (found by the passed in + /// arguments). + /// + /// \param Argv0 - The program path (from argv[0]), for finding the builtin + /// compiler path. + /// \param MainAddr - The address of main (or some other function in the main + /// executable), for finding the builtin compiler path. + static std::string GetResourcesPath(const char *Argv0, void *MainAddr); + + /// \brief Set language defaults for the given input language and + /// language standard in the given LangOptions object. + /// + /// \param Opts - The LangOptions object to set up. + /// \param IK - The input language. + /// \param LangStd - The input language standard. + static void setLangDefaults(LangOptions &Opts, InputKind IK, + LangStandard::Kind LangStd = LangStandard::lang_unspecified); + + /// \brief Retrieve a module hash string that is suitable for uniquely + /// identifying the conditions under which the module was built. + std::string getModuleHash() const; + + /// @} + /// @name Option Subgroups + /// @{ + + AnalyzerOptionsRef getAnalyzerOpts() const { + return AnalyzerOpts; + } + + MigratorOptions &getMigratorOpts() { return MigratorOpts; } + const MigratorOptions &getMigratorOpts() const { + return MigratorOpts; + } + + CodeGenOptions &getCodeGenOpts() { return CodeGenOpts; } + const CodeGenOptions &getCodeGenOpts() const { + return CodeGenOpts; + } + + DependencyOutputOptions &getDependencyOutputOpts() { + return DependencyOutputOpts; + } + const DependencyOutputOptions &getDependencyOutputOpts() const { + return DependencyOutputOpts; + } + + FileSystemOptions &getFileSystemOpts() { return FileSystemOpts; } + const FileSystemOptions &getFileSystemOpts() const { + return FileSystemOpts; + } + + FrontendOptions &getFrontendOpts() { return FrontendOpts; } + const FrontendOptions &getFrontendOpts() const { + return FrontendOpts; + } + + PreprocessorOutputOptions &getPreprocessorOutputOpts() { + return PreprocessorOutputOpts; + } + const PreprocessorOutputOptions &getPreprocessorOutputOpts() const { + return PreprocessorOutputOpts; + } + + /// @} +}; + +namespace vfs { + class FileSystem; +} + +IntrusiveRefCntPtr<vfs::FileSystem> +createVFSFromCompilerInvocation(const CompilerInvocation &CI, + DiagnosticsEngine &Diags); + +} // end namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/DependencyOutputOptions.h b/contrib/llvm/tools/clang/include/clang/Frontend/DependencyOutputOptions.h new file mode 100644 index 0000000..2221b54 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/DependencyOutputOptions.h @@ -0,0 +1,70 @@ +//===--- DependencyOutputOptions.h ------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_DEPENDENCYOUTPUTOPTIONS_H +#define LLVM_CLANG_FRONTEND_DEPENDENCYOUTPUTOPTIONS_H + +#include <string> +#include <vector> + +namespace clang { + +/// DependencyOutputFormat - Format for the compiler dependency file. +enum class DependencyOutputFormat { Make, NMake }; + +/// DependencyOutputOptions - Options for controlling the compiler dependency +/// file generation. +class DependencyOutputOptions { +public: + unsigned IncludeSystemHeaders : 1; ///< Include system header dependencies. + unsigned ShowHeaderIncludes : 1; ///< Show header inclusions (-H). + unsigned UsePhonyTargets : 1; ///< Include phony targets for each + /// dependency, which can avoid some 'make' + /// problems. + unsigned AddMissingHeaderDeps : 1; ///< Add missing headers to dependency list + unsigned PrintShowIncludes : 1; ///< Print cl.exe style /showIncludes info. + unsigned IncludeModuleFiles : 1; ///< Include module file dependencies. + + /// The format for the dependency file. + DependencyOutputFormat OutputFormat; + + /// The file to write dependency output to. + std::string OutputFile; + + /// The file to write header include output to. This is orthogonal to + /// ShowHeaderIncludes (-H) and will include headers mentioned in the + /// predefines buffer. If the output file is "-", output will be sent to + /// stderr. + std::string HeaderIncludeOutputFile; + + /// A list of names to use as the targets in the dependency file; this list + /// must contain at least one entry. + std::vector<std::string> Targets; + + /// \brief The file to write GraphViz-formatted header dependencies to. + std::string DOTOutputFile; + + /// \brief The directory to copy module dependencies to when collecting them. + std::string ModuleDependencyOutputDir; + +public: + DependencyOutputOptions() { + IncludeSystemHeaders = 0; + ShowHeaderIncludes = 0; + UsePhonyTargets = 0; + AddMissingHeaderDeps = 0; + PrintShowIncludes = 0; + IncludeModuleFiles = 0; + OutputFormat = DependencyOutputFormat::Make; + } +}; + +} // end namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/DiagnosticRenderer.h b/contrib/llvm/tools/clang/include/clang/Frontend/DiagnosticRenderer.h new file mode 100644 index 0000000..84a0f50 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/DiagnosticRenderer.h @@ -0,0 +1,176 @@ +//===--- DiagnosticRenderer.h - Diagnostic Pretty-Printing ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This is a utility class that provides support for pretty-printing of +// diagnostics. It is used to implement the different code paths which require +// such functionality in a consistent way. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_DIAGNOSTICRENDERER_H +#define LLVM_CLANG_FRONTEND_DIAGNOSTICRENDERER_H + +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/PointerUnion.h" + +namespace clang { + +class DiagnosticOptions; +class LangOptions; +class SourceManager; + +typedef llvm::PointerUnion<const Diagnostic *, + const StoredDiagnostic *> DiagOrStoredDiag; + +/// \brief Class to encapsulate the logic for formatting a diagnostic message. +/// +/// Actual "printing" logic is implemented by subclasses. +/// +/// This class provides an interface for building and emitting +/// diagnostic, including all of the macro backtraces, caret diagnostics, FixIt +/// Hints, and code snippets. In the presence of macros this involves +/// a recursive process, synthesizing notes for each macro expansion. +/// +/// A brief worklist: +/// FIXME: Sink the recursive printing of template instantiations into this +/// class. +class DiagnosticRenderer { +protected: + const LangOptions &LangOpts; + IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts; + + /// \brief The location of the previous diagnostic if known. + /// + /// This will be invalid in cases where there is no (known) previous + /// diagnostic location, or that location itself is invalid or comes from + /// a different source manager than SM. + SourceLocation LastLoc; + + /// \brief The location of the last include whose stack was printed if known. + /// + /// Same restriction as LastLoc essentially, but tracking include stack + /// root locations rather than diagnostic locations. + SourceLocation LastIncludeLoc; + + /// \brief The level of the last diagnostic emitted. + /// + /// The level of the last diagnostic emitted. Used to detect level changes + /// which change the amount of information displayed. + DiagnosticsEngine::Level LastLevel; + + DiagnosticRenderer(const LangOptions &LangOpts, + DiagnosticOptions *DiagOpts); + + virtual ~DiagnosticRenderer(); + + virtual void emitDiagnosticMessage(SourceLocation Loc, PresumedLoc PLoc, + DiagnosticsEngine::Level Level, + StringRef Message, + ArrayRef<CharSourceRange> Ranges, + const SourceManager *SM, + DiagOrStoredDiag Info) = 0; + + virtual void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc, + DiagnosticsEngine::Level Level, + ArrayRef<CharSourceRange> Ranges, + const SourceManager &SM) = 0; + + virtual void emitCodeContext(SourceLocation Loc, + DiagnosticsEngine::Level Level, + SmallVectorImpl<CharSourceRange>& Ranges, + ArrayRef<FixItHint> Hints, + const SourceManager &SM) = 0; + + virtual void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc, + const SourceManager &SM) = 0; + virtual void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc, + StringRef ModuleName, + const SourceManager &SM) = 0; + virtual void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc, + StringRef ModuleName, + const SourceManager &SM) = 0; + + virtual void beginDiagnostic(DiagOrStoredDiag D, + DiagnosticsEngine::Level Level) {} + virtual void endDiagnostic(DiagOrStoredDiag D, + DiagnosticsEngine::Level Level) {} + + +private: + void emitBasicNote(StringRef Message); + void emitIncludeStack(SourceLocation Loc, PresumedLoc PLoc, + DiagnosticsEngine::Level Level, const SourceManager &SM); + void emitIncludeStackRecursively(SourceLocation Loc, const SourceManager &SM); + void emitImportStack(SourceLocation Loc, const SourceManager &SM); + void emitImportStackRecursively(SourceLocation Loc, StringRef ModuleName, + const SourceManager &SM); + void emitModuleBuildStack(const SourceManager &SM); + void emitCaret(SourceLocation Loc, DiagnosticsEngine::Level Level, + ArrayRef<CharSourceRange> Ranges, ArrayRef<FixItHint> Hints, + const SourceManager &SM); + void emitMacroExpansions(SourceLocation Loc, + DiagnosticsEngine::Level Level, + ArrayRef<CharSourceRange> Ranges, + ArrayRef<FixItHint> Hints, + const SourceManager &SM, + unsigned &MacroDepth, + unsigned OnMacroInst = 0); +public: + /// \brief Emit a diagnostic. + /// + /// This is the primary entry point for emitting diagnostic messages. + /// It handles formatting and rendering the message as well as any ancillary + /// information needed based on macros whose expansions impact the + /// diagnostic. + /// + /// \param Loc The location for this caret. + /// \param Level The level of the diagnostic to be emitted. + /// \param Message The diagnostic message to emit. + /// \param Ranges The underlined ranges for this code snippet. + /// \param FixItHints The FixIt hints active for this diagnostic. + /// \param SM The SourceManager; will be null if the diagnostic came from the + /// frontend, thus \p Loc will be invalid. + void emitDiagnostic(SourceLocation Loc, DiagnosticsEngine::Level Level, + StringRef Message, ArrayRef<CharSourceRange> Ranges, + ArrayRef<FixItHint> FixItHints, + const SourceManager *SM, + DiagOrStoredDiag D = (Diagnostic *)nullptr); + + void emitStoredDiagnostic(StoredDiagnostic &Diag); +}; + +/// Subclass of DiagnosticRender that turns all subdiagostics into explicit +/// notes. It is up to subclasses to further define the behavior. +class DiagnosticNoteRenderer : public DiagnosticRenderer { +public: + DiagnosticNoteRenderer(const LangOptions &LangOpts, + DiagnosticOptions *DiagOpts) + : DiagnosticRenderer(LangOpts, DiagOpts) {} + + ~DiagnosticNoteRenderer() override; + + void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc, + const SourceManager &SM) override; + + void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc, + StringRef ModuleName, + const SourceManager &SM) override; + + void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc, + StringRef ModuleName, + const SourceManager &SM) override; + + virtual void emitNote(SourceLocation Loc, StringRef Message, + const SourceManager *SM) = 0; +}; +} // end clang namespace +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendAction.h b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendAction.h new file mode 100644 index 0000000..c407ff8 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendAction.h @@ -0,0 +1,298 @@ +//===-- FrontendAction.h - Generic Frontend Action Interface ----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief Defines the clang::FrontendAction interface and various convenience +/// abstract classes (clang::ASTFrontendAction, clang::PluginASTAction, +/// clang::PreprocessorFrontendAction, and clang::WrapperFrontendAction) +/// derived from it. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_FRONTENDACTION_H +#define LLVM_CLANG_FRONTEND_FRONTENDACTION_H + +#include "clang/AST/ASTConsumer.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Frontend/ASTUnit.h" +#include "clang/Frontend/FrontendOptions.h" +#include "llvm/ADT/StringRef.h" +#include <memory> +#include <string> +#include <vector> + +namespace clang { +class ASTMergeAction; +class CompilerInstance; + +/// Abstract base class for actions which can be performed by the frontend. +class FrontendAction { + FrontendInputFile CurrentInput; + std::unique_ptr<ASTUnit> CurrentASTUnit; + CompilerInstance *Instance; + friend class ASTMergeAction; + friend class WrapperFrontendAction; + +private: + std::unique_ptr<ASTConsumer> CreateWrappedASTConsumer(CompilerInstance &CI, + StringRef InFile); + +protected: + /// @name Implementation Action Interface + /// @{ + + /// \brief Create the AST consumer object for this action, if supported. + /// + /// This routine is called as part of BeginSourceFile(), which will + /// fail if the AST consumer cannot be created. This will not be called if the + /// action has indicated that it only uses the preprocessor. + /// + /// \param CI - The current compiler instance, provided as a convenience, see + /// getCompilerInstance(). + /// + /// \param InFile - The current input file, provided as a convenience, see + /// getCurrentFile(). + /// + /// \return The new AST consumer, or null on failure. + virtual std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) = 0; + + /// \brief Callback before starting processing a single input, giving the + /// opportunity to modify the CompilerInvocation or do some other action + /// before BeginSourceFileAction is called. + /// + /// \return True on success; on failure BeginSourceFileAction(), + /// ExecuteAction() and EndSourceFileAction() will not be called. + virtual bool BeginInvocation(CompilerInstance &CI) { return true; } + + /// \brief Callback at the start of processing a single input. + /// + /// \return True on success; on failure ExecutionAction() and + /// EndSourceFileAction() will not be called. + virtual bool BeginSourceFileAction(CompilerInstance &CI, + StringRef Filename) { + return true; + } + + /// \brief Callback to run the program action, using the initialized + /// compiler instance. + /// + /// This is guaranteed to only be called between BeginSourceFileAction() + /// and EndSourceFileAction(). + virtual void ExecuteAction() = 0; + + /// \brief Callback at the end of processing a single input. + /// + /// This is guaranteed to only be called following a successful call to + /// BeginSourceFileAction (and BeginSourceFile). + virtual void EndSourceFileAction() {} + + /// \brief Callback at the end of processing a single input, to determine + /// if the output files should be erased or not. + /// + /// By default it returns true if a compiler error occurred. + /// This is guaranteed to only be called following a successful call to + /// BeginSourceFileAction (and BeginSourceFile). + virtual bool shouldEraseOutputFiles(); + + /// @} + +public: + FrontendAction(); + virtual ~FrontendAction(); + + /// @name Compiler Instance Access + /// @{ + + CompilerInstance &getCompilerInstance() const { + assert(Instance && "Compiler instance not registered!"); + return *Instance; + } + + void setCompilerInstance(CompilerInstance *Value) { Instance = Value; } + + /// @} + /// @name Current File Information + /// @{ + + bool isCurrentFileAST() const { + assert(!CurrentInput.isEmpty() && "No current file!"); + return (bool)CurrentASTUnit; + } + + const FrontendInputFile &getCurrentInput() const { + return CurrentInput; + } + + const StringRef getCurrentFile() const { + assert(!CurrentInput.isEmpty() && "No current file!"); + return CurrentInput.getFile(); + } + + InputKind getCurrentFileKind() const { + assert(!CurrentInput.isEmpty() && "No current file!"); + return CurrentInput.getKind(); + } + + ASTUnit &getCurrentASTUnit() const { + assert(CurrentASTUnit && "No current AST unit!"); + return *CurrentASTUnit; + } + + std::unique_ptr<ASTUnit> takeCurrentASTUnit() { + return std::move(CurrentASTUnit); + } + + void setCurrentInput(const FrontendInputFile &CurrentInput, + std::unique_ptr<ASTUnit> AST = nullptr); + + /// @} + /// @name Supported Modes + /// @{ + + /// \brief Is this action invoked on a model file? + /// + /// Model files are incomplete translation units that relies on type + /// information from another translation unit. Check ParseModelFileAction for + /// details. + virtual bool isModelParsingAction() const { return false; } + + /// \brief Does this action only use the preprocessor? + /// + /// If so no AST context will be created and this action will be invalid + /// with AST file inputs. + virtual bool usesPreprocessorOnly() const = 0; + + /// \brief For AST-based actions, the kind of translation unit we're handling. + virtual TranslationUnitKind getTranslationUnitKind() { return TU_Complete; } + + /// \brief Does this action support use with PCH? + virtual bool hasPCHSupport() const { return !usesPreprocessorOnly(); } + + /// \brief Does this action support use with AST files? + virtual bool hasASTFileSupport() const { return !usesPreprocessorOnly(); } + + /// \brief Does this action support use with IR files? + virtual bool hasIRSupport() const { return false; } + + /// \brief Does this action support use with code completion? + virtual bool hasCodeCompletionSupport() const { return false; } + + /// @} + /// @name Public Action Interface + /// @{ + + /// \brief Prepare the action for processing the input file \p Input. + /// + /// This is run after the options and frontend have been initialized, + /// but prior to executing any per-file processing. + /// + /// \param CI - The compiler instance this action is being run from. The + /// action may store and use this object up until the matching EndSourceFile + /// action. + /// + /// \param Input - The input filename and kind. Some input kinds are handled + /// specially, for example AST inputs, since the AST file itself contains + /// several objects which would normally be owned by the + /// CompilerInstance. When processing AST input files, these objects should + /// generally not be initialized in the CompilerInstance -- they will + /// automatically be shared with the AST file in between + /// BeginSourceFile() and EndSourceFile(). + /// + /// \return True on success; on failure the compilation of this file should + /// be aborted and neither Execute() nor EndSourceFile() should be called. + bool BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input); + + /// \brief Set the source manager's main input file, and run the action. + bool Execute(); + + /// \brief Perform any per-file post processing, deallocate per-file + /// objects, and run statistics and output file cleanup code. + void EndSourceFile(); + + /// @} +}; + +/// \brief Abstract base class to use for AST consumer-based frontend actions. +class ASTFrontendAction : public FrontendAction { +protected: + /// \brief Implement the ExecuteAction interface by running Sema on + /// the already-initialized AST consumer. + /// + /// This will also take care of instantiating a code completion consumer if + /// the user requested it and the action supports it. + void ExecuteAction() override; + +public: + ASTFrontendAction() {} + bool usesPreprocessorOnly() const override { return false; } +}; + +class PluginASTAction : public ASTFrontendAction { + virtual void anchor(); +public: + std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override = 0; + + /// \brief Parse the given plugin command line arguments. + /// + /// \param CI - The compiler instance, for use in reporting diagnostics. + /// \return True if the parsing succeeded; otherwise the plugin will be + /// destroyed and no action run. The plugin is responsible for using the + /// CompilerInstance's Diagnostic object to report errors. + virtual bool ParseArgs(const CompilerInstance &CI, + const std::vector<std::string> &arg) = 0; +}; + +/// \brief Abstract base class to use for preprocessor-based frontend actions. +class PreprocessorFrontendAction : public FrontendAction { +protected: + /// \brief Provide a default implementation which returns aborts; + /// this method should never be called by FrontendAction clients. + std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override; + +public: + bool usesPreprocessorOnly() const override { return true; } +}; + +/// \brief A frontend action which simply wraps some other runtime-specified +/// frontend action. +/// +/// Deriving from this class allows an action to inject custom logic around +/// some existing action's behavior. It implements every virtual method in +/// the FrontendAction interface by forwarding to the wrapped action. +class WrapperFrontendAction : public FrontendAction { + std::unique_ptr<FrontendAction> WrappedAction; + +protected: + std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override; + bool BeginInvocation(CompilerInstance &CI) override; + bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename) override; + void ExecuteAction() override; + void EndSourceFileAction() override; + +public: + /// Construct a WrapperFrontendAction from an existing action, taking + /// ownership of it. + WrapperFrontendAction(FrontendAction *WrappedAction); + + bool usesPreprocessorOnly() const override; + TranslationUnitKind getTranslationUnitKind() override; + bool hasPCHSupport() const override; + bool hasASTFileSupport() const override; + bool hasIRSupport() const override; + bool hasCodeCompletionSupport() const override; +}; + +} // end namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendActions.h b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendActions.h new file mode 100644 index 0000000..f61775f --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendActions.h @@ -0,0 +1,241 @@ +//===-- FrontendActions.h - Useful Frontend Actions -------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_FRONTENDACTIONS_H +#define LLVM_CLANG_FRONTEND_FRONTENDACTIONS_H + +#include "clang/Frontend/FrontendAction.h" +#include <string> +#include <vector> + +namespace clang { + +class Module; +class FileEntry; + +//===----------------------------------------------------------------------===// +// Custom Consumer Actions +//===----------------------------------------------------------------------===// + +class InitOnlyAction : public FrontendAction { + void ExecuteAction() override; + + std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override; + +public: + // Don't claim to only use the preprocessor, we want to follow the AST path, + // but do nothing. + bool usesPreprocessorOnly() const override { return false; } +}; + +//===----------------------------------------------------------------------===// +// AST Consumer Actions +//===----------------------------------------------------------------------===// + +class ASTPrintAction : public ASTFrontendAction { +protected: + std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override; +}; + +class ASTDumpAction : public ASTFrontendAction { +protected: + std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override; +}; + +class ASTDeclListAction : public ASTFrontendAction { +protected: + std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override; +}; + +class ASTViewAction : public ASTFrontendAction { +protected: + std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override; +}; + +class DeclContextPrintAction : public ASTFrontendAction { +protected: + std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override; +}; + +class GeneratePCHAction : public ASTFrontendAction { +protected: + std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override; + + TranslationUnitKind getTranslationUnitKind() override { + return TU_Prefix; + } + + bool hasASTFileSupport() const override { return false; } + +public: + /// \brief Compute the AST consumer arguments that will be used to + /// create the PCHGenerator instance returned by CreateASTConsumer. + /// + /// \returns true if an error occurred, false otherwise. + static raw_pwrite_stream * + ComputeASTConsumerArguments(CompilerInstance &CI, StringRef InFile, + std::string &Sysroot, std::string &OutputFile); +}; + +class GenerateModuleAction : public ASTFrontendAction { + clang::Module *Module; + const FileEntry *ModuleMapForUniquing; + bool IsSystem; + +protected: + std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override; + + TranslationUnitKind getTranslationUnitKind() override { + return TU_Module; + } + + bool hasASTFileSupport() const override { return false; } + +public: + GenerateModuleAction(const FileEntry *ModuleMap = nullptr, + bool IsSystem = false) + : ASTFrontendAction(), ModuleMapForUniquing(ModuleMap), IsSystem(IsSystem) + { } + + bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename) override; + + /// \brief Compute the AST consumer arguments that will be used to + /// create the PCHGenerator instance returned by CreateASTConsumer. + /// + /// \returns true if an error occurred, false otherwise. + raw_pwrite_stream *ComputeASTConsumerArguments(CompilerInstance &CI, + StringRef InFile, + std::string &Sysroot, + std::string &OutputFile); +}; + +class SyntaxOnlyAction : public ASTFrontendAction { +protected: + std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override; + +public: + bool hasCodeCompletionSupport() const override { return true; } +}; + +/// \brief Dump information about the given module file, to be used for +/// basic debugging and discovery. +class DumpModuleInfoAction : public ASTFrontendAction { +protected: + std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override; + void ExecuteAction() override; + +public: + bool hasPCHSupport() const override { return false; } + bool hasASTFileSupport() const override { return true; } + bool hasIRSupport() const override { return false; } + bool hasCodeCompletionSupport() const override { return false; } +}; + +class VerifyPCHAction : public ASTFrontendAction { +protected: + std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override; + + void ExecuteAction() override; + +public: + bool hasCodeCompletionSupport() const override { return false; } +}; + +/** + * \brief Frontend action adaptor that merges ASTs together. + * + * This action takes an existing AST file and "merges" it into the AST + * context, producing a merged context. This action is an action + * adaptor, which forwards most of its calls to another action that + * will consume the merged context. + */ +class ASTMergeAction : public FrontendAction { + /// \brief The action that the merge action adapts. + FrontendAction *AdaptedAction; + + /// \brief The set of AST files to merge. + std::vector<std::string> ASTFiles; + +protected: + std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override; + + bool BeginSourceFileAction(CompilerInstance &CI, + StringRef Filename) override; + + void ExecuteAction() override; + void EndSourceFileAction() override; + +public: + ASTMergeAction(FrontendAction *AdaptedAction, ArrayRef<std::string> ASTFiles); + ~ASTMergeAction() override; + + bool usesPreprocessorOnly() const override; + TranslationUnitKind getTranslationUnitKind() override; + bool hasPCHSupport() const override; + bool hasASTFileSupport() const override; + bool hasCodeCompletionSupport() const override; +}; + +class PrintPreambleAction : public FrontendAction { +protected: + void ExecuteAction() override; + std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &, + StringRef) override { + return nullptr; + } + + bool usesPreprocessorOnly() const override { return true; } +}; + +//===----------------------------------------------------------------------===// +// Preprocessor Actions +//===----------------------------------------------------------------------===// + +class DumpRawTokensAction : public PreprocessorFrontendAction { +protected: + void ExecuteAction() override; +}; + +class DumpTokensAction : public PreprocessorFrontendAction { +protected: + void ExecuteAction() override; +}; + +class GeneratePTHAction : public PreprocessorFrontendAction { +protected: + void ExecuteAction() override; +}; + +class PreprocessOnlyAction : public PreprocessorFrontendAction { +protected: + void ExecuteAction() override; +}; + +class PrintPreprocessedAction : public PreprocessorFrontendAction { +protected: + void ExecuteAction() override; + + bool hasPCHSupport() const override { return true; } +}; + +} // end namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendDiagnostic.h new file mode 100644 index 0000000..0f37b7e --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendDiagnostic.h @@ -0,0 +1,28 @@ +//===--- DiagnosticFrontend.h - Diagnostics for frontend --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_FRONTENDDIAGNOSTIC_H +#define LLVM_CLANG_FRONTEND_FRONTENDDIAGNOSTIC_H + +#include "clang/Basic/Diagnostic.h" + +namespace clang { + namespace diag { + enum { +#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,\ + SFINAE,NOWERROR,SHOWINSYSHEADER,CATEGORY) ENUM, +#define FRONTENDSTART +#include "clang/Basic/DiagnosticFrontendKinds.inc" +#undef DIAG + NUM_BUILTIN_FRONTEND_DIAGNOSTICS + }; + } // end namespace diag +} // end namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendOptions.h b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendOptions.h new file mode 100644 index 0000000..c3aa226 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendOptions.h @@ -0,0 +1,277 @@ +//===--- FrontendOptions.h --------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_FRONTENDOPTIONS_H +#define LLVM_CLANG_FRONTEND_FRONTENDOPTIONS_H + +#include "clang/Frontend/CommandLineSourceLoc.h" +#include "clang/Sema/CodeCompleteOptions.h" +#include "llvm/ADT/StringRef.h" +#include <string> +#include <vector> + +namespace llvm { +class MemoryBuffer; +} + +namespace clang { + +namespace frontend { + enum ActionKind { + ASTDeclList, ///< Parse ASTs and list Decl nodes. + ASTDump, ///< Parse ASTs and dump them. + ASTPrint, ///< Parse ASTs and print them. + ASTView, ///< Parse ASTs and view them in Graphviz. + DumpRawTokens, ///< Dump out raw tokens. + DumpTokens, ///< Dump out preprocessed tokens. + EmitAssembly, ///< Emit a .s file. + EmitBC, ///< Emit a .bc file. + EmitHTML, ///< Translate input source into HTML. + EmitLLVM, ///< Emit a .ll file. + EmitLLVMOnly, ///< Generate LLVM IR, but do not emit anything. + EmitCodeGenOnly, ///< Generate machine code, but don't emit anything. + EmitObj, ///< Emit a .o file. + FixIt, ///< Parse and apply any fixits to the source. + GenerateModule, ///< Generate pre-compiled module. + GeneratePCH, ///< Generate pre-compiled header. + GeneratePTH, ///< Generate pre-tokenized header. + InitOnly, ///< Only execute frontend initialization. + ModuleFileInfo, ///< Dump information about a module file. + VerifyPCH, ///< Load and verify that a PCH file is usable. + ParseSyntaxOnly, ///< Parse and perform semantic analysis. + PluginAction, ///< Run a plugin action, \see ActionName. + PrintDeclContext, ///< Print DeclContext and their Decls. + PrintPreamble, ///< Print the "preamble" of the input file + PrintPreprocessedInput, ///< -E mode. + RewriteMacros, ///< Expand macros but not \#includes. + RewriteObjC, ///< ObjC->C Rewriter. + RewriteTest, ///< Rewriter playground + RunAnalysis, ///< Run one or more source code analyses. + MigrateSource, ///< Run migrator. + RunPreprocessorOnly ///< Just lex, no output. + }; +} + +enum InputKind { + IK_None, + IK_Asm, + IK_C, + IK_CXX, + IK_ObjC, + IK_ObjCXX, + IK_PreprocessedC, + IK_PreprocessedCXX, + IK_PreprocessedObjC, + IK_PreprocessedObjCXX, + IK_OpenCL, + IK_CUDA, + IK_PreprocessedCuda, + IK_AST, + IK_LLVM_IR +}; + + +/// \brief An input file for the front end. +class FrontendInputFile { + /// \brief The file name, or "-" to read from standard input. + std::string File; + + llvm::MemoryBuffer *Buffer; + + /// \brief The kind of input, e.g., C source, AST file, LLVM IR. + InputKind Kind; + + /// \brief Whether we're dealing with a 'system' input (vs. a 'user' input). + bool IsSystem; + +public: + FrontendInputFile() : Buffer(nullptr), Kind(IK_None) { } + FrontendInputFile(StringRef File, InputKind Kind, bool IsSystem = false) + : File(File.str()), Buffer(nullptr), Kind(Kind), IsSystem(IsSystem) { } + FrontendInputFile(llvm::MemoryBuffer *buffer, InputKind Kind, + bool IsSystem = false) + : Buffer(buffer), Kind(Kind), IsSystem(IsSystem) { } + + InputKind getKind() const { return Kind; } + bool isSystem() const { return IsSystem; } + + bool isEmpty() const { return File.empty() && Buffer == nullptr; } + bool isFile() const { return !isBuffer(); } + bool isBuffer() const { return Buffer != nullptr; } + + StringRef getFile() const { + assert(isFile()); + return File; + } + llvm::MemoryBuffer *getBuffer() const { + assert(isBuffer()); + return Buffer; + } +}; + +/// FrontendOptions - Options for controlling the behavior of the frontend. +class FrontendOptions { +public: + unsigned DisableFree : 1; ///< Disable memory freeing on exit. + unsigned RelocatablePCH : 1; ///< When generating PCH files, + /// instruct the AST writer to create + /// relocatable PCH files. + unsigned ShowHelp : 1; ///< Show the -help text. + unsigned ShowStats : 1; ///< Show frontend performance + /// metrics and statistics. + unsigned ShowTimers : 1; ///< Show timers for individual + /// actions. + unsigned ShowVersion : 1; ///< Show the -version text. + unsigned FixWhatYouCan : 1; ///< Apply fixes even if there are + /// unfixable errors. + unsigned FixOnlyWarnings : 1; ///< Apply fixes only for warnings. + unsigned FixAndRecompile : 1; ///< Apply fixes and recompile. + unsigned FixToTemporaries : 1; ///< Apply fixes to temporary files. + unsigned ARCMTMigrateEmitARCErrors : 1; /// Emit ARC errors even if the + /// migrator can fix them + unsigned SkipFunctionBodies : 1; ///< Skip over function bodies to + /// speed up parsing in cases you do + /// not need them (e.g. with code + /// completion). + unsigned UseGlobalModuleIndex : 1; ///< Whether we can use the + ///< global module index if available. + unsigned GenerateGlobalModuleIndex : 1; ///< Whether we can generate the + ///< global module index if needed. + unsigned ASTDumpDecls : 1; ///< Whether we include declaration + ///< dumps in AST dumps. + unsigned ASTDumpLookups : 1; ///< Whether we include lookup table + ///< dumps in AST dumps. + + CodeCompleteOptions CodeCompleteOpts; + + enum { + ARCMT_None, + ARCMT_Check, + ARCMT_Modify, + ARCMT_Migrate + } ARCMTAction; + + enum { + ObjCMT_None = 0, + /// \brief Enable migration to modern ObjC literals. + ObjCMT_Literals = 0x1, + /// \brief Enable migration to modern ObjC subscripting. + ObjCMT_Subscripting = 0x2, + /// \brief Enable migration to modern ObjC readonly property. + ObjCMT_ReadonlyProperty = 0x4, + /// \brief Enable migration to modern ObjC readwrite property. + ObjCMT_ReadwriteProperty = 0x8, + /// \brief Enable migration to modern ObjC property. + ObjCMT_Property = (ObjCMT_ReadonlyProperty | ObjCMT_ReadwriteProperty), + /// \brief Enable annotation of ObjCMethods of all kinds. + ObjCMT_Annotation = 0x10, + /// \brief Enable migration of ObjC methods to 'instancetype'. + ObjCMT_Instancetype = 0x20, + /// \brief Enable migration to NS_ENUM/NS_OPTIONS macros. + ObjCMT_NsMacros = 0x40, + /// \brief Enable migration to add conforming protocols. + ObjCMT_ProtocolConformance = 0x80, + /// \brief prefer 'atomic' property over 'nonatomic'. + ObjCMT_AtomicProperty = 0x100, + /// \brief annotate property with NS_RETURNS_INNER_POINTER + ObjCMT_ReturnsInnerPointerProperty = 0x200, + /// \brief use NS_NONATOMIC_IOSONLY for property 'atomic' attribute + ObjCMT_NsAtomicIOSOnlyProperty = 0x400, + /// \brief Enable inferring NS_DESIGNATED_INITIALIZER for ObjC methods. + ObjCMT_DesignatedInitializer = 0x800, + /// \brief Enable converting setter/getter expressions to property-dot syntx. + ObjCMT_PropertyDotSyntax = 0x1000, + ObjCMT_MigrateDecls = (ObjCMT_ReadonlyProperty | ObjCMT_ReadwriteProperty | + ObjCMT_Annotation | ObjCMT_Instancetype | + ObjCMT_NsMacros | ObjCMT_ProtocolConformance | + ObjCMT_NsAtomicIOSOnlyProperty | + ObjCMT_DesignatedInitializer), + ObjCMT_MigrateAll = (ObjCMT_Literals | ObjCMT_Subscripting | + ObjCMT_MigrateDecls | ObjCMT_PropertyDotSyntax) + }; + unsigned ObjCMTAction; + std::string ObjCMTWhiteListPath; + + std::string MTMigrateDir; + std::string ARCMTMigrateReportOut; + + /// The input files and their types. + std::vector<FrontendInputFile> Inputs; + + /// The output file, if any. + std::string OutputFile; + + /// If given, the new suffix for fix-it rewritten files. + std::string FixItSuffix; + + /// If given, filter dumped AST Decl nodes by this substring. + std::string ASTDumpFilter; + + /// If given, enable code completion at the provided location. + ParsedSourceLocation CodeCompletionAt; + + /// The frontend action to perform. + frontend::ActionKind ProgramAction; + + /// The name of the action to run when using a plugin action. + std::string ActionName; + + /// Args to pass to the plugin + std::vector<std::string> PluginArgs; + + /// The list of plugin actions to run in addition to the normal action. + std::vector<std::string> AddPluginActions; + + /// Args to pass to the additional plugins + std::vector<std::vector<std::string> > AddPluginArgs; + + /// The list of plugins to load. + std::vector<std::string> Plugins; + + /// \brief The list of module map files to load before processing the input. + std::vector<std::string> ModuleMapFiles; + + /// \brief The list of additional prebuilt module files to load before + /// processing the input. + std::vector<std::string> ModuleFiles; + + /// \brief The list of AST files to merge. + std::vector<std::string> ASTMergeFiles; + + /// \brief A list of arguments to forward to LLVM's option processing; this + /// should only be used for debugging and experimental features. + std::vector<std::string> LLVMArgs; + + /// \brief File name of the file that will provide record layouts + /// (in the format produced by -fdump-record-layouts). + std::string OverrideRecordLayoutsFile; + +public: + FrontendOptions() : + DisableFree(false), RelocatablePCH(false), ShowHelp(false), + ShowStats(false), ShowTimers(false), ShowVersion(false), + FixWhatYouCan(false), FixOnlyWarnings(false), FixAndRecompile(false), + FixToTemporaries(false), ARCMTMigrateEmitARCErrors(false), + SkipFunctionBodies(false), UseGlobalModuleIndex(true), + GenerateGlobalModuleIndex(true), ASTDumpDecls(false), ASTDumpLookups(false), + ARCMTAction(ARCMT_None), ObjCMTAction(ObjCMT_None), + ProgramAction(frontend::ParseSyntaxOnly) + {} + + /// getInputKindForExtension - Return the appropriate input kind for a file + /// extension. For example, "c" would return IK_C. + /// + /// \return The input kind for the extension, or IK_None if the extension is + /// not recognized. + static InputKind getInputKindForExtension(StringRef Extension); +}; + +} // end namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/FrontendPluginRegistry.h b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendPluginRegistry.h new file mode 100644 index 0000000..ecab630 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/FrontendPluginRegistry.h @@ -0,0 +1,26 @@ +//===-- FrontendAction.h - Pluggable Frontend Action Interface --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_FRONTENDPLUGINREGISTRY_H +#define LLVM_CLANG_FRONTEND_FRONTENDPLUGINREGISTRY_H + +#include "clang/Frontend/FrontendAction.h" +#include "llvm/Support/Registry.h" + +// Instantiated in FrontendAction.cpp. +extern template class llvm::Registry<clang::PluginASTAction>; + +namespace clang { + +/// The frontend plugin registry. +typedef llvm::Registry<PluginASTAction> FrontendPluginRegistry; + +} // end namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/LangStandard.h b/contrib/llvm/tools/clang/include/clang/Frontend/LangStandard.h new file mode 100644 index 0000000..8021d08 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/LangStandard.h @@ -0,0 +1,100 @@ +//===--- LangStandard.h -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_LANGSTANDARD_H +#define LLVM_CLANG_FRONTEND_LANGSTANDARD_H + +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/StringRef.h" + +namespace clang { + +namespace frontend { + +enum LangFeatures { + LineComment = (1 << 0), + C89 = (1 << 1), + C99 = (1 << 2), + C11 = (1 << 3), + CPlusPlus = (1 << 4), + CPlusPlus11 = (1 << 5), + CPlusPlus14 = (1 << 6), + CPlusPlus1z = (1 << 7), + Digraphs = (1 << 8), + GNUMode = (1 << 9), + HexFloat = (1 << 10), + ImplicitInt = (1 << 11) +}; + +} + +/// LangStandard - Information about the properties of a particular language +/// standard. +struct LangStandard { + enum Kind { +#define LANGSTANDARD(id, name, desc, features) \ + lang_##id, +#include "clang/Frontend/LangStandards.def" + lang_unspecified + }; + + const char *ShortName; + const char *Description; + unsigned Flags; + +public: + /// getName - Get the name of this standard. + const char *getName() const { return ShortName; } + + /// getDescription - Get the description of this standard. + const char *getDescription() const { return Description; } + + /// Language supports '//' comments. + bool hasLineComments() const { return Flags & frontend::LineComment; } + + /// isC89 - Language is a superset of C89. + bool isC89() const { return Flags & frontend::C89; } + + /// isC99 - Language is a superset of C99. + bool isC99() const { return Flags & frontend::C99; } + + /// isC11 - Language is a superset of C11. + bool isC11() const { return Flags & frontend::C11; } + + /// isCPlusPlus - Language is a C++ variant. + bool isCPlusPlus() const { return Flags & frontend::CPlusPlus; } + + /// isCPlusPlus11 - Language is a C++11 variant (or later). + bool isCPlusPlus11() const { return Flags & frontend::CPlusPlus11; } + + /// isCPlusPlus14 - Language is a C++14 variant (or later). + bool isCPlusPlus14() const { return Flags & frontend::CPlusPlus14; } + + /// isCPlusPlus1z - Language is a C++17 variant (or later). + bool isCPlusPlus1z() const { return Flags & frontend::CPlusPlus1z; } + + /// hasDigraphs - Language supports digraphs. + bool hasDigraphs() const { return Flags & frontend::Digraphs; } + + /// isGNUMode - Language includes GNU extensions. + bool isGNUMode() const { return Flags & frontend::GNUMode; } + + /// hasHexFloats - Language supports hexadecimal float constants. + bool hasHexFloats() const { return Flags & frontend::HexFloat; } + + /// hasImplicitInt - Language allows variables to be typed as int implicitly. + bool hasImplicitInt() const { return Flags & frontend::ImplicitInt; } + + static const LangStandard &getLangStandardForKind(Kind K); + static const LangStandard *getLangStandardForName(StringRef Name); +}; + +} // end namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/LangStandards.def b/contrib/llvm/tools/clang/include/clang/Frontend/LangStandards.def new file mode 100644 index 0000000..cac9c3c --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/LangStandards.def @@ -0,0 +1,153 @@ +//===-- LangStandards.def - Language Standard Data --------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LANGSTANDARD +#error "LANGSTANDARD must be defined before including this file" +#endif + +/// LANGSTANDARD(IDENT, NAME, DESC, FEATURES) +/// +/// \param IDENT - The name of the standard as a C++ identifier. +/// \param NAME - The name of the standard. +/// \param DESC - A short description of the standard. +/// \param FEATURES - The standard features as flags, these are enums from the +/// clang::frontend namespace, which is assumed to be be available. + +// C89-ish modes. +LANGSTANDARD(c89, "c89", + "ISO C 1990", + C89 | ImplicitInt) +LANGSTANDARD(c90, "c90", + "ISO C 1990", + C89 | ImplicitInt) +LANGSTANDARD(iso9899_1990, "iso9899:1990", + "ISO C 1990", + C89 | ImplicitInt) + +LANGSTANDARD(c94, "iso9899:199409", + "ISO C 1990 with amendment 1", + C89 | Digraphs | ImplicitInt) + +LANGSTANDARD(gnu89, "gnu89", + "ISO C 1990 with GNU extensions", + LineComment | C89 | Digraphs | GNUMode | ImplicitInt) +LANGSTANDARD(gnu90, "gnu90", + "ISO C 1990 with GNU extensions", + LineComment | C89 | Digraphs | GNUMode | ImplicitInt) + +// C99-ish modes +LANGSTANDARD(c99, "c99", + "ISO C 1999", + LineComment | C99 | Digraphs | HexFloat) +LANGSTANDARD(c9x, "c9x", + "ISO C 1999", + LineComment | C99 | Digraphs | HexFloat) +LANGSTANDARD(iso9899_1999, + "iso9899:1999", "ISO C 1999", + LineComment | C99 | Digraphs | HexFloat) +LANGSTANDARD(iso9899_199x, + "iso9899:199x", "ISO C 1999", + LineComment | C99 | Digraphs | HexFloat) + +LANGSTANDARD(gnu99, "gnu99", + "ISO C 1999 with GNU extensions", + LineComment | C99 | Digraphs | GNUMode | HexFloat) +LANGSTANDARD(gnu9x, "gnu9x", + "ISO C 1999 with GNU extensions", + LineComment | C99 | Digraphs | GNUMode | HexFloat) + +// C11 modes +LANGSTANDARD(c11, "c11", + "ISO C 2011", + LineComment | C99 | C11 | Digraphs | HexFloat) +LANGSTANDARD(c1x, "c1x", + "ISO C 2011", + LineComment | C99 | C11 | Digraphs | HexFloat) +LANGSTANDARD(iso9899_2011, + "iso9899:2011", "ISO C 2011", + LineComment | C99 | C11 | Digraphs | HexFloat) +LANGSTANDARD(iso9899_201x, + "iso9899:2011", "ISO C 2011", + LineComment | C99 | C11 | Digraphs | HexFloat) + +LANGSTANDARD(gnu11, "gnu11", + "ISO C 2011 with GNU extensions", + LineComment | C99 | C11 | Digraphs | GNUMode | HexFloat) +LANGSTANDARD(gnu1x, "gnu1x", + "ISO C 2011 with GNU extensions", + LineComment | C99 | C11 | Digraphs | GNUMode | HexFloat) + +// C++ modes +LANGSTANDARD(cxx98, "c++98", + "ISO C++ 1998 with amendments", + LineComment | CPlusPlus | Digraphs) +LANGSTANDARD(cxx03, "c++03", + "ISO C++ 1998 with amendments", + LineComment | CPlusPlus | Digraphs) +LANGSTANDARD(gnucxx98, "gnu++98", + "ISO C++ 1998 with amendments and GNU extensions", + LineComment | CPlusPlus | Digraphs | GNUMode) + +LANGSTANDARD(cxx0x, "c++0x", + "ISO C++ 2011 with amendments", + LineComment | CPlusPlus | CPlusPlus11 | Digraphs) +LANGSTANDARD(cxx11, "c++11", + "ISO C++ 2011 with amendments", + LineComment | CPlusPlus | CPlusPlus11 | Digraphs) +LANGSTANDARD(gnucxx0x, "gnu++0x", + "ISO C++ 2011 with amendments and GNU extensions", + LineComment | CPlusPlus | CPlusPlus11 | Digraphs | GNUMode) +LANGSTANDARD(gnucxx11, "gnu++11", + "ISO C++ 2011 with amendments and GNU extensions", + LineComment | CPlusPlus | CPlusPlus11 | Digraphs | GNUMode) + +LANGSTANDARD(cxx1y, "c++1y", + "ISO C++ 2014 with amendments", + LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | Digraphs) +LANGSTANDARD(cxx14, "c++14", + "ISO C++ 2014 with amendments", + LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | Digraphs) +LANGSTANDARD(gnucxx1y, "gnu++1y", + "ISO C++ 2014 with amendments and GNU extensions", + LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | Digraphs | + GNUMode) +LANGSTANDARD(gnucxx14, "gnu++14", + "ISO C++ 2014 with amendments and GNU extensions", + LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | Digraphs | + GNUMode) + +LANGSTANDARD(cxx1z, "c++1z", + "Working draft for ISO C++ 2017", + LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus1z | + Digraphs) +LANGSTANDARD(gnucxx1z, "gnu++1z", + "Working draft for ISO C++ 2017 with GNU extensions", + LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus1z | + Digraphs | GNUMode) + +// OpenCL +LANGSTANDARD(opencl, "cl", + "OpenCL 1.0", + LineComment | C99 | Digraphs | HexFloat) +LANGSTANDARD(opencl11, "CL1.1", + "OpenCL 1.1", + LineComment | C99 | Digraphs | HexFloat) +LANGSTANDARD(opencl12, "CL1.2", + "OpenCL 1.2", + LineComment | C99 | Digraphs | HexFloat) +LANGSTANDARD(opencl20, "CL2.0", + "OpenCL 2.0", + LineComment | C99 | Digraphs | HexFloat) + +// CUDA +LANGSTANDARD(cuda, "cuda", + "NVIDIA CUDA(tm)", + LineComment | CPlusPlus | Digraphs) + +#undef LANGSTANDARD diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/LayoutOverrideSource.h b/contrib/llvm/tools/clang/include/clang/Frontend/LayoutOverrideSource.h new file mode 100644 index 0000000..16d032b --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/LayoutOverrideSource.h @@ -0,0 +1,63 @@ +//===--- LayoutOverrideSource.h --Override Record Layouts -----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_LAYOUTOVERRIDESOURCE_H +#define LLVM_CLANG_FRONTEND_LAYOUTOVERRIDESOURCE_H + +#include "clang/AST/ExternalASTSource.h" +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" + +namespace clang { + /// \brief An external AST source that overrides the layout of + /// a specified set of record types. + /// + /// This class is used only for testing the ability of external AST sources + /// to override the layout of record types. Its input is the output format + /// of the command-line argument -fdump-record-layouts. + class LayoutOverrideSource : public ExternalASTSource { + /// \brief The layout of a given record. + struct Layout { + /// \brief The size of the record. + uint64_t Size; + + /// \brief The alignment of the record. + uint64_t Align; + + /// \brief The offsets of the fields, in source order. + SmallVector<uint64_t, 8> FieldOffsets; + }; + + /// \brief The set of layouts that will be overridden. + llvm::StringMap<Layout> Layouts; + + public: + /// \brief Create a new AST source that overrides the layout of some + /// set of record types. + /// + /// The file is the result of passing -fdump-record-layouts to a file. + explicit LayoutOverrideSource(StringRef Filename); + + /// \brief If this particular record type has an overridden layout, + /// return that layout. + bool + layoutRecordType(const RecordDecl *Record, + uint64_t &Size, uint64_t &Alignment, + llvm::DenseMap<const FieldDecl *, uint64_t> &FieldOffsets, + llvm::DenseMap<const CXXRecordDecl *, CharUnits> &BaseOffsets, + llvm::DenseMap<const CXXRecordDecl *, + CharUnits> &VirtualBaseOffsets) override; + + /// \brief Dump the overridden layouts. + void dump(); + }; +} + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/LogDiagnosticPrinter.h b/contrib/llvm/tools/clang/include/clang/Frontend/LogDiagnosticPrinter.h new file mode 100644 index 0000000..98adf65 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/LogDiagnosticPrinter.h @@ -0,0 +1,85 @@ +//===--- LogDiagnosticPrinter.h - Log Diagnostic Client ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_LOGDIAGNOSTICPRINTER_H +#define LLVM_CLANG_FRONTEND_LOGDIAGNOSTICPRINTER_H + +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" + +namespace clang { +class DiagnosticOptions; +class LangOptions; + +class LogDiagnosticPrinter : public DiagnosticConsumer { + struct DiagEntry { + /// The primary message line of the diagnostic. + std::string Message; + + /// The source file name, if available. + std::string Filename; + + /// The source file line number, if available. + unsigned Line; + + /// The source file column number, if available. + unsigned Column; + + /// The ID of the diagnostic. + unsigned DiagnosticID; + + /// The Option Flag for the diagnostic + std::string WarningOption; + + /// The level of the diagnostic. + DiagnosticsEngine::Level DiagnosticLevel; + }; + + void EmitDiagEntry(llvm::raw_ostream &OS, + const LogDiagnosticPrinter::DiagEntry &DE); + + // Conditional ownership (when StreamOwner is non-null, it's keeping OS + // alive). We might want to replace this with a wrapper for conditional + // ownership eventually - it seems to pop up often enough. + raw_ostream &OS; + std::unique_ptr<raw_ostream> StreamOwner; + const LangOptions *LangOpts; + IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts; + + SourceLocation LastWarningLoc; + FullSourceLoc LastLoc; + + SmallVector<DiagEntry, 8> Entries; + + std::string MainFilename; + std::string DwarfDebugFlags; + +public: + LogDiagnosticPrinter(raw_ostream &OS, DiagnosticOptions *Diags, + std::unique_ptr<raw_ostream> StreamOwner); + + void setDwarfDebugFlags(StringRef Value) { + DwarfDebugFlags = Value; + } + + void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP) override { + LangOpts = &LO; + } + + void EndSourceFile() override; + + void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, + const Diagnostic &Info) override; +}; + +} // end namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/MigratorOptions.h b/contrib/llvm/tools/clang/include/clang/Frontend/MigratorOptions.h new file mode 100644 index 0000000..8eb71b1 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/MigratorOptions.h @@ -0,0 +1,31 @@ +//===--- MigratorOptions.h - MigratorOptions Options ------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This header contains the structures necessary for a front-end to specify +// various migration analysis. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_MIGRATOROPTIONS_H +#define LLVM_CLANG_FRONTEND_MIGRATOROPTIONS_H + +namespace clang { + +class MigratorOptions { +public: + unsigned NoNSAllocReallocError : 1; + unsigned NoFinalizeRemoval : 1; + MigratorOptions() { + NoNSAllocReallocError = 0; + NoFinalizeRemoval = 0; + } +}; + +} +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/MultiplexConsumer.h b/contrib/llvm/tools/clang/include/clang/Frontend/MultiplexConsumer.h new file mode 100644 index 0000000..873af03 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/MultiplexConsumer.h @@ -0,0 +1,69 @@ +//===-- MultiplexConsumer.h - AST Consumer for PCH Generation ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares the MultiplexConsumer class, which can be used to +// multiplex ASTConsumer and SemaConsumer messages to many consumers. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_MULTIPLEXCONSUMER_H +#define LLVM_CLANG_FRONTEND_MULTIPLEXCONSUMER_H + +#include "clang/Basic/LLVM.h" +#include "clang/Sema/SemaConsumer.h" +#include <memory> +#include <vector> + +namespace clang { + +class MultiplexASTMutationListener; +class MultiplexASTDeserializationListener; + +// Has a list of ASTConsumers and calls each of them. Owns its children. +class MultiplexConsumer : public SemaConsumer { +public: + // Takes ownership of the pointers in C. + MultiplexConsumer(std::vector<std::unique_ptr<ASTConsumer>> C); + ~MultiplexConsumer() override; + + // ASTConsumer + void Initialize(ASTContext &Context) override; + void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override; + bool HandleTopLevelDecl(DeclGroupRef D) override; + void HandleInlineMethodDefinition(CXXMethodDecl *D) override; + void HandleInterestingDecl(DeclGroupRef D) override; + void HandleTranslationUnit(ASTContext &Ctx) override; + void HandleTagDeclDefinition(TagDecl *D) override; + void HandleTagDeclRequiredDefinition(const TagDecl *D) override; + void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) override; + void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override; + void HandleImplicitImportDecl(ImportDecl *D) override; + void HandleLinkerOptionPragma(llvm::StringRef Opts) override; + void HandleDetectMismatch(llvm::StringRef Name, + llvm::StringRef Value) override; + void HandleDependentLibrary(llvm::StringRef Lib) override; + void CompleteTentativeDefinition(VarDecl *D) override; + void HandleVTable(CXXRecordDecl *RD) override; + ASTMutationListener *GetASTMutationListener() override; + ASTDeserializationListener *GetASTDeserializationListener() override; + void PrintStats() override; + + // SemaConsumer + void InitializeSema(Sema &S) override; + void ForgetSema() override; + +private: + std::vector<std::unique_ptr<ASTConsumer>> Consumers; // Owns these. + std::unique_ptr<MultiplexASTMutationListener> MutationListener; + std::unique_ptr<MultiplexASTDeserializationListener> DeserializationListener; +}; + +} // end namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/PCHContainerOperations.h b/contrib/llvm/tools/clang/include/clang/Frontend/PCHContainerOperations.h new file mode 100644 index 0000000..868ea68 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/PCHContainerOperations.h @@ -0,0 +1,124 @@ +//===--- Frontend/PCHContainerOperations.h - PCH Containers -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_PCH_CONTAINER_OPERATIONS_H +#define LLVM_CLANG_PCH_CONTAINER_OPERATIONS_H + +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/Support/MemoryBuffer.h" +#include <memory> + +namespace llvm { +class raw_pwrite_stream; +class BitstreamReader; +} + +using llvm::StringRef; + +namespace clang { + +class ASTConsumer; +class CodeGenOptions; +class DiagnosticsEngine; +class HeaderSearchOptions; +class LangOptions; +class PreprocessorOptions; +class TargetOptions; + +struct PCHBuffer { + bool IsComplete; + llvm::SmallVector<char, 0> Data; +}; + +/// This abstract interface provides operations for creating +/// containers for serialized ASTs (precompiled headers and clang +/// modules). +class PCHContainerWriter { +public: + virtual ~PCHContainerWriter() = 0; + virtual StringRef getFormat() const = 0; + + /// Return an ASTConsumer that can be chained with a + /// PCHGenerator that produces a wrapper file format containing a + /// serialized AST bitstream. + virtual std::unique_ptr<ASTConsumer> CreatePCHContainerGenerator( + DiagnosticsEngine &Diags, const HeaderSearchOptions &HSO, + const PreprocessorOptions &PPO, const TargetOptions &TO, + const LangOptions &LO, const std::string &MainFileName, + const std::string &OutputFileName, llvm::raw_pwrite_stream *OS, + std::shared_ptr<PCHBuffer> Buffer) const = 0; +}; + +/// This abstract interface provides operations for unwrapping +/// containers for serialized ASTs (precompiled headers and clang +/// modules). +class PCHContainerReader { +public: + virtual ~PCHContainerReader() = 0; + /// Equivalent to the format passed to -fmodule-format= + virtual StringRef getFormat() const = 0; + + /// Initialize an llvm::BitstreamReader with the serialized AST inside + /// the PCH container Buffer. + virtual void ExtractPCH(llvm::MemoryBufferRef Buffer, + llvm::BitstreamReader &StreamFile) const = 0; +}; + +/// Implements write operations for a raw pass-through PCH container. +class RawPCHContainerWriter : public PCHContainerWriter { + StringRef getFormat() const override { return "raw"; } + + /// Return an ASTConsumer that can be chained with a + /// PCHGenerator that writes the module to a flat file. + std::unique_ptr<ASTConsumer> CreatePCHContainerGenerator( + DiagnosticsEngine &Diags, const HeaderSearchOptions &HSO, + const PreprocessorOptions &PPO, const TargetOptions &TO, + const LangOptions &LO, const std::string &MainFileName, + const std::string &OutputFileName, llvm::raw_pwrite_stream *OS, + std::shared_ptr<PCHBuffer> Buffer) const override; +}; + +/// Implements read operations for a raw pass-through PCH container. +class RawPCHContainerReader : public PCHContainerReader { + StringRef getFormat() const override { return "raw"; } + + /// Initialize an llvm::BitstreamReader with Buffer. + void ExtractPCH(llvm::MemoryBufferRef Buffer, + llvm::BitstreamReader &StreamFile) const override; +}; + +/// A registry of PCHContainerWriter and -Reader objects for different formats. +class PCHContainerOperations { + llvm::StringMap<std::unique_ptr<PCHContainerWriter>> Writers; + llvm::StringMap<std::unique_ptr<PCHContainerReader>> Readers; +public: + /// Automatically registers a RawPCHContainerWriter and + /// RawPCHContainerReader. + PCHContainerOperations(); + void registerWriter(std::unique_ptr<PCHContainerWriter> Writer) { + Writers[Writer->getFormat()] = std::move(Writer); + } + void registerReader(std::unique_ptr<PCHContainerReader> Reader) { + Readers[Reader->getFormat()] = std::move(Reader); + } + const PCHContainerWriter *getWriterOrNull(StringRef Format) { + return Writers[Format].get(); + } + const PCHContainerReader *getReaderOrNull(StringRef Format) { + return Readers[Format].get(); + } + const PCHContainerReader &getRawReader() { + return *getReaderOrNull("raw"); + } +}; + +} + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/PreprocessorOutputOptions.h b/contrib/llvm/tools/clang/include/clang/Frontend/PreprocessorOutputOptions.h new file mode 100644 index 0000000..f86c490 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/PreprocessorOutputOptions.h @@ -0,0 +1,41 @@ +//===--- PreprocessorOutputOptions.h ----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_PREPROCESSOROUTPUTOPTIONS_H +#define LLVM_CLANG_FRONTEND_PREPROCESSOROUTPUTOPTIONS_H + +namespace clang { + +/// PreprocessorOutputOptions - Options for controlling the C preprocessor +/// output (e.g., -E). +class PreprocessorOutputOptions { +public: + unsigned ShowCPP : 1; ///< Print normal preprocessed output. + unsigned ShowComments : 1; ///< Show comments. + unsigned ShowLineMarkers : 1; ///< Show \#line markers. + unsigned UseLineDirectives : 1; ///< Use \#line instead of GCC-style \# N. + unsigned ShowMacroComments : 1; ///< Show comments, even in macros. + unsigned ShowMacros : 1; ///< Print macro definitions. + unsigned RewriteIncludes : 1; ///< Preprocess include directives only. + +public: + PreprocessorOutputOptions() { + ShowCPP = 0; + ShowComments = 0; + ShowLineMarkers = 1; + UseLineDirectives = 0; + ShowMacroComments = 0; + ShowMacros = 0; + RewriteIncludes = 0; + } +}; + +} // end namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/SerializedDiagnosticPrinter.h b/contrib/llvm/tools/clang/include/clang/Frontend/SerializedDiagnosticPrinter.h new file mode 100644 index 0000000..4c57e9d --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/SerializedDiagnosticPrinter.h @@ -0,0 +1,43 @@ +//===--- SerializedDiagnosticPrinter.h - Serializer for diagnostics -------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_SERIALIZEDDIAGNOSTICPRINTER_H +#define LLVM_CLANG_FRONTEND_SERIALIZEDDIAGNOSTICPRINTER_H + +#include "clang/Basic/LLVM.h" +#include "clang/Frontend/SerializedDiagnostics.h" +#include "llvm/Bitcode/BitstreamWriter.h" + +namespace llvm { +class raw_ostream; +} + +namespace clang { +class DiagnosticConsumer; +class DiagnosticsEngine; +class DiagnosticOptions; + +namespace serialized_diags { + +/// \brief Returns a DiagnosticConsumer that serializes diagnostics to +/// a bitcode file. +/// +/// The created DiagnosticConsumer is designed for quick and lightweight +/// transfer of of diagnostics to the enclosing build system (e.g., an IDE). +/// This allows wrapper tools for Clang to get diagnostics from Clang +/// (via libclang) without needing to parse Clang's command line output. +/// +std::unique_ptr<DiagnosticConsumer> create(StringRef OutputFile, + DiagnosticOptions *Diags, + bool MergeChildRecords = false); + +} // end serialized_diags namespace +} // end clang namespace + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/SerializedDiagnosticReader.h b/contrib/llvm/tools/clang/include/clang/Frontend/SerializedDiagnosticReader.h new file mode 100644 index 0000000..92e99d3 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/SerializedDiagnosticReader.h @@ -0,0 +1,131 @@ +//===--- SerializedDiagnosticReader.h - Reads diagnostics -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_SERIALIZED_DIAGNOSTIC_READER_H_ +#define LLVM_CLANG_FRONTEND_SERIALIZED_DIAGNOSTIC_READER_H_ + +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/Bitcode/BitstreamReader.h" +#include "llvm/Support/ErrorOr.h" + +namespace clang { +namespace serialized_diags { + +enum class SDError { + CouldNotLoad = 1, + InvalidSignature, + InvalidDiagnostics, + MalformedTopLevelBlock, + MalformedSubBlock, + MalformedBlockInfoBlock, + MalformedMetadataBlock, + MalformedDiagnosticBlock, + MalformedDiagnosticRecord, + MissingVersion, + VersionMismatch, + UnsupportedConstruct, + /// A generic error for subclass handlers that don't want or need to define + /// their own error_category. + HandlerFailed +}; + +const std::error_category &SDErrorCategory(); + +inline std::error_code make_error_code(SDError E) { + return std::error_code(static_cast<int>(E), SDErrorCategory()); +} + +/// \brief A location that is represented in the serialized diagnostics. +struct Location { + unsigned FileID; + unsigned Line; + unsigned Col; + unsigned Offset; + Location(unsigned FileID, unsigned Line, unsigned Col, unsigned Offset) + : FileID(FileID), Line(Line), Col(Col), Offset(Offset) {} +}; + +/// \brief A base class that handles reading serialized diagnostics from a file. +/// +/// Subclasses should override the visit* methods with their logic for handling +/// the various constructs that are found in serialized diagnostics. +class SerializedDiagnosticReader { +public: + SerializedDiagnosticReader() {} + virtual ~SerializedDiagnosticReader() {} + + /// \brief Read the diagnostics in \c File + std::error_code readDiagnostics(StringRef File); + +private: + enum class Cursor; + + /// \brief Read to the next record or block to process. + llvm::ErrorOr<Cursor> skipUntilRecordOrBlock(llvm::BitstreamCursor &Stream, + unsigned &BlockOrRecordId); + + /// \brief Read a metadata block from \c Stream. + std::error_code readMetaBlock(llvm::BitstreamCursor &Stream); + + /// \brief Read a diagnostic block from \c Stream. + std::error_code readDiagnosticBlock(llvm::BitstreamCursor &Stream); + +protected: + /// \brief Visit the start of a diagnostic block. + virtual std::error_code visitStartOfDiagnostic() { + return std::error_code(); + }; + /// \brief Visit the end of a diagnostic block. + virtual std::error_code visitEndOfDiagnostic() { return std::error_code(); }; + /// \brief Visit a category. This associates the category \c ID to a \c Name. + virtual std::error_code visitCategoryRecord(unsigned ID, StringRef Name) { + return std::error_code(); + }; + /// \brief Visit a flag. This associates the flag's \c ID to a \c Name. + virtual std::error_code visitDiagFlagRecord(unsigned ID, StringRef Name) { + return std::error_code(); + }; + /// \brief Visit a diagnostic. + virtual std::error_code + visitDiagnosticRecord(unsigned Severity, const Location &Location, + unsigned Category, unsigned Flag, StringRef Message) { + return std::error_code(); + }; + /// \brief Visit a filename. This associates the file's \c ID to a \c Name. + virtual std::error_code visitFilenameRecord(unsigned ID, unsigned Size, + unsigned Timestamp, + StringRef Name) { + return std::error_code(); + }; + /// \brief Visit a fixit hint. + virtual std::error_code + visitFixitRecord(const Location &Start, const Location &End, StringRef Text) { + return std::error_code(); + }; + /// \brief Visit a source range. + virtual std::error_code visitSourceRangeRecord(const Location &Start, + const Location &End) { + return std::error_code(); + }; + /// \brief Visit the version of the set of diagnostics. + virtual std::error_code visitVersionRecord(unsigned Version) { + return std::error_code(); + }; +}; + +} // end serialized_diags namespace +} // end clang namespace + +namespace std { +template <> +struct is_error_code_enum<clang::serialized_diags::SDError> : std::true_type {}; +} + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/SerializedDiagnostics.h b/contrib/llvm/tools/clang/include/clang/Frontend/SerializedDiagnostics.h new file mode 100644 index 0000000..2032cd3 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/SerializedDiagnostics.h @@ -0,0 +1,59 @@ +//===--- SerializedDiagnostics.h - Common data for serialized diagnostics -===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_SERIALIZE_DIAGNOSTICS_H_ +#define LLVM_CLANG_FRONTEND_SERIALIZE_DIAGNOSTICS_H_ + +#include "llvm/Bitcode/BitCodes.h" + +namespace clang { +namespace serialized_diags { + +enum BlockIDs { + /// \brief A top-level block which represents any meta data associated + /// with the diagostics, including versioning of the format. + BLOCK_META = llvm::bitc::FIRST_APPLICATION_BLOCKID, + + /// \brief The this block acts as a container for all the information + /// for a specific diagnostic. + BLOCK_DIAG +}; + +enum RecordIDs { + RECORD_VERSION = 1, + RECORD_DIAG, + RECORD_SOURCE_RANGE, + RECORD_DIAG_FLAG, + RECORD_CATEGORY, + RECORD_FILENAME, + RECORD_FIXIT, + RECORD_FIRST = RECORD_VERSION, + RECORD_LAST = RECORD_FIXIT +}; + +/// \brief A stable version of DiagnosticIDs::Level. +/// +/// Do not change the order of values in this enum, and please increment the +/// serialized diagnostics version number when you add to it. +enum Level { + Ignored = 0, + Note, + Warning, + Error, + Fatal, + Remark +}; + +/// \brief The serialized diagnostics version number. +enum { VersionNumber = 2 }; + +} // end serialized_diags namespace +} // end clang namespace + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnostic.h b/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnostic.h new file mode 100644 index 0000000..d41f15a --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnostic.h @@ -0,0 +1,122 @@ +//===--- TextDiagnostic.h - Text Diagnostic Pretty-Printing -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This is a utility class that provides support for textual pretty-printing of +// diagnostics. It is used to implement the different code paths which require +// such functionality in a consistent way. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_TEXTDIAGNOSTIC_H +#define LLVM_CLANG_FRONTEND_TEXTDIAGNOSTIC_H + +#include "clang/Frontend/DiagnosticRenderer.h" + +namespace clang { + +/// \brief Class to encapsulate the logic for formatting and printing a textual +/// diagnostic message. +/// +/// This class provides an interface for building and emitting a textual +/// diagnostic, including all of the macro backtraces, caret diagnostics, FixIt +/// Hints, and code snippets. In the presence of macros this involves +/// a recursive process, synthesizing notes for each macro expansion. +/// +/// The purpose of this class is to isolate the implementation of printing +/// beautiful text diagnostics from any particular interfaces. The Clang +/// DiagnosticClient is implemented through this class as is diagnostic +/// printing coming out of libclang. +class TextDiagnostic : public DiagnosticRenderer { + raw_ostream &OS; + +public: + TextDiagnostic(raw_ostream &OS, + const LangOptions &LangOpts, + DiagnosticOptions *DiagOpts); + + ~TextDiagnostic() override; + + /// \brief Print the diagonstic level to a raw_ostream. + /// + /// This is a static helper that handles colorizing the level and formatting + /// it into an arbitrary output stream. This is used internally by the + /// TextDiagnostic emission code, but it can also be used directly by + /// consumers that don't have a source manager or other state that the full + /// TextDiagnostic logic requires. + static void printDiagnosticLevel(raw_ostream &OS, + DiagnosticsEngine::Level Level, + bool ShowColors, + bool CLFallbackMode = false); + + /// \brief Pretty-print a diagnostic message to a raw_ostream. + /// + /// This is a static helper to handle the line wrapping, colorizing, and + /// rendering of a diagnostic message to a particular ostream. It is + /// publicly visible so that clients which do not have sufficient state to + /// build a complete TextDiagnostic object can still get consistent + /// formatting of their diagnostic messages. + /// + /// \param OS Where the message is printed + /// \param IsSupplemental true if this is a continuation note diagnostic + /// \param Message The text actually printed + /// \param CurrentColumn The starting column of the first line, accounting + /// for any prefix. + /// \param Columns The number of columns to use in line-wrapping, 0 disables + /// all line-wrapping. + /// \param ShowColors Enable colorizing of the message. + static void printDiagnosticMessage(raw_ostream &OS, bool IsSupplemental, + StringRef Message, unsigned CurrentColumn, + unsigned Columns, bool ShowColors); + +protected: + void emitDiagnosticMessage(SourceLocation Loc,PresumedLoc PLoc, + DiagnosticsEngine::Level Level, + StringRef Message, + ArrayRef<CharSourceRange> Ranges, + const SourceManager *SM, + DiagOrStoredDiag D) override; + + void emitDiagnosticLoc(SourceLocation Loc, PresumedLoc PLoc, + DiagnosticsEngine::Level Level, + ArrayRef<CharSourceRange> Ranges, + const SourceManager &SM) override; + + void emitCodeContext(SourceLocation Loc, + DiagnosticsEngine::Level Level, + SmallVectorImpl<CharSourceRange>& Ranges, + ArrayRef<FixItHint> Hints, + const SourceManager &SM) override { + emitSnippetAndCaret(Loc, Level, Ranges, Hints, SM); + } + + void emitIncludeLocation(SourceLocation Loc, PresumedLoc PLoc, + const SourceManager &SM) override; + + void emitImportLocation(SourceLocation Loc, PresumedLoc PLoc, + StringRef ModuleName, + const SourceManager &SM) override; + + void emitBuildingModuleLocation(SourceLocation Loc, PresumedLoc PLoc, + StringRef ModuleName, + const SourceManager &SM) override; + +private: + void emitSnippetAndCaret(SourceLocation Loc, DiagnosticsEngine::Level Level, + SmallVectorImpl<CharSourceRange>& Ranges, + ArrayRef<FixItHint> Hints, + const SourceManager &SM); + + void emitSnippet(StringRef SourceLine); + + void emitParseableFixits(ArrayRef<FixItHint> Hints, const SourceManager &SM); +}; + +} // end namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnosticBuffer.h b/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnosticBuffer.h new file mode 100644 index 0000000..3bcf824 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnosticBuffer.h @@ -0,0 +1,55 @@ +//===--- TextDiagnosticBuffer.h - Buffer Text Diagnostics -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This is a concrete diagnostic client, which buffers the diagnostic messages. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_TEXTDIAGNOSTICBUFFER_H +#define LLVM_CLANG_FRONTEND_TEXTDIAGNOSTICBUFFER_H + +#include "clang/Basic/Diagnostic.h" +#include <vector> + +namespace clang { + +class Preprocessor; +class SourceManager; + +class TextDiagnosticBuffer : public DiagnosticConsumer { +public: + typedef std::vector<std::pair<SourceLocation, std::string> > DiagList; + typedef DiagList::iterator iterator; + typedef DiagList::const_iterator const_iterator; +private: + DiagList Errors, Warnings, Remarks, Notes; +public: + const_iterator err_begin() const { return Errors.begin(); } + const_iterator err_end() const { return Errors.end(); } + + const_iterator warn_begin() const { return Warnings.begin(); } + const_iterator warn_end() const { return Warnings.end(); } + + const_iterator remark_begin() const { return Remarks.begin(); } + const_iterator remark_end() const { return Remarks.end(); } + + const_iterator note_begin() const { return Notes.begin(); } + const_iterator note_end() const { return Notes.end(); } + + void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, + const Diagnostic &Info) override; + + /// FlushDiagnostics - Flush the buffered diagnostics to an given + /// diagnostic engine. + void FlushDiagnostics(DiagnosticsEngine &Diags) const; +}; + +} // end namspace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnosticPrinter.h b/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnosticPrinter.h new file mode 100644 index 0000000..04a5705 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/TextDiagnosticPrinter.h @@ -0,0 +1,58 @@ +//===--- TextDiagnosticPrinter.h - Text Diagnostic Client -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This is a concrete diagnostic client, which prints the diagnostics to +// standard error. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_TEXTDIAGNOSTICPRINTER_H +#define LLVM_CLANG_FRONTEND_TEXTDIAGNOSTICPRINTER_H + +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include <memory> + +namespace clang { +class DiagnosticOptions; +class LangOptions; +class TextDiagnostic; + +class TextDiagnosticPrinter : public DiagnosticConsumer { + raw_ostream &OS; + IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts; + + /// \brief Handle to the currently active text diagnostic emitter. + std::unique_ptr<TextDiagnostic> TextDiag; + + /// A string to prefix to error messages. + std::string Prefix; + + unsigned OwnsOutputStream : 1; + +public: + TextDiagnosticPrinter(raw_ostream &os, DiagnosticOptions *diags, + bool OwnsOutputStream = false); + ~TextDiagnosticPrinter() override; + + /// setPrefix - Set the diagnostic printer prefix string, which will be + /// printed at the start of any diagnostics. If empty, no prefix string is + /// used. + void setPrefix(std::string Value) { Prefix = Value; } + + void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP) override; + void EndSourceFile() override; + void HandleDiagnostic(DiagnosticsEngine::Level Level, + const Diagnostic &Info) override; +}; + +} // end namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/Utils.h b/contrib/llvm/tools/clang/include/clang/Frontend/Utils.h new file mode 100644 index 0000000..aa567b4 --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/Utils.h @@ -0,0 +1,215 @@ +//===--- Utils.h - Misc utilities for the front-end -------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This header contains miscellaneous utilities for various front-end actions. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_UTILS_H +#define LLVM_CLANG_FRONTEND_UTILS_H + +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/VirtualFileSystem.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringSet.h" +#include "llvm/Option/OptSpecifier.h" + +namespace llvm { +class raw_fd_ostream; +class Triple; + +namespace opt { +class ArgList; +} +} + +namespace clang { +class ASTConsumer; +class ASTReader; +class CompilerInstance; +class CompilerInvocation; +class Decl; +class DependencyOutputOptions; +class DiagnosticsEngine; +class DiagnosticOptions; +class ExternalSemaSource; +class FileManager; +class HeaderSearch; +class HeaderSearchOptions; +class IdentifierTable; +class LangOptions; +class PCHContainerReader; +class Preprocessor; +class PreprocessorOptions; +class PreprocessorOutputOptions; +class SourceManager; +class Stmt; +class TargetInfo; +class FrontendOptions; + +/// Apply the header search options to get given HeaderSearch object. +void ApplyHeaderSearchOptions(HeaderSearch &HS, + const HeaderSearchOptions &HSOpts, + const LangOptions &Lang, + const llvm::Triple &triple); + +/// InitializePreprocessor - Initialize the preprocessor getting it and the +/// environment ready to process a single file. +void InitializePreprocessor(Preprocessor &PP, const PreprocessorOptions &PPOpts, + const PCHContainerReader &PCHContainerRdr, + const FrontendOptions &FEOpts); + +/// DoPrintPreprocessedInput - Implement -E mode. +void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream* OS, + const PreprocessorOutputOptions &Opts); + +/// An interface for collecting the dependencies of a compilation. Users should +/// use \c attachToPreprocessor and \c attachToASTReader to get all of the +/// dependencies. +// FIXME: Migrate DependencyFileGen, DependencyGraphGen, ModuleDepCollectory to +// use this interface. +class DependencyCollector { +public: + void attachToPreprocessor(Preprocessor &PP); + void attachToASTReader(ASTReader &R); + llvm::ArrayRef<std::string> getDependencies() const { return Dependencies; } + + /// Called when a new file is seen. Return true if \p Filename should be added + /// to the list of dependencies. + /// + /// The default implementation ignores <built-in> and system files. + virtual bool sawDependency(StringRef Filename, bool FromModule, + bool IsSystem, bool IsModuleFile, bool IsMissing); + /// Called when the end of the main file is reached. + virtual void finishedMainFile() { } + /// Return true if system files should be passed to sawDependency(). + virtual bool needSystemDependencies() { return false; } + virtual ~DependencyCollector(); + +public: // implementation detail + /// Add a dependency \p Filename if it has not been seen before and + /// sawDependency() returns true. + void maybeAddDependency(StringRef Filename, bool FromModule, bool IsSystem, + bool IsModuleFile, bool IsMissing); +private: + llvm::StringSet<> Seen; + std::vector<std::string> Dependencies; +}; + +/// Builds a depdenency file when attached to a Preprocessor (for includes) and +/// ASTReader (for module imports), and writes it out at the end of processing +/// a source file. Users should attach to the ast reader whenever a module is +/// loaded. +class DependencyFileGenerator { + void *Impl; // Opaque implementation + DependencyFileGenerator(void *Impl); +public: + static DependencyFileGenerator *CreateAndAttachToPreprocessor( + Preprocessor &PP, const DependencyOutputOptions &Opts); + void AttachToASTReader(ASTReader &R); +}; + +/// Collects the dependencies for imported modules into a directory. Users +/// should attach to the AST reader whenever a module is loaded. +class ModuleDependencyCollector { + std::string DestDir; + bool HasErrors; + llvm::StringSet<> Seen; + vfs::YAMLVFSWriter VFSWriter; + +public: + StringRef getDest() { return DestDir; } + bool insertSeen(StringRef Filename) { return Seen.insert(Filename).second; } + void setHasErrors() { HasErrors = true; } + void addFileMapping(StringRef VPath, StringRef RPath) { + VFSWriter.addFileMapping(VPath, RPath); + } + + void attachToASTReader(ASTReader &R); + void writeFileMap(); + bool hasErrors() { return HasErrors; } + ModuleDependencyCollector(std::string DestDir) + : DestDir(DestDir), HasErrors(false) {} + ~ModuleDependencyCollector() { writeFileMap(); } +}; + +/// AttachDependencyGraphGen - Create a dependency graph generator, and attach +/// it to the given preprocessor. + void AttachDependencyGraphGen(Preprocessor &PP, StringRef OutputFile, + StringRef SysRoot); + +/// AttachHeaderIncludeGen - Create a header include list generator, and attach +/// it to the given preprocessor. +/// +/// \param ShowAllHeaders - If true, show all header information instead of just +/// headers following the predefines buffer. This is useful for making sure +/// includes mentioned on the command line are also reported, but differs from +/// the default behavior used by -H. +/// \param OutputPath - If non-empty, a path to write the header include +/// information to, instead of writing to stderr. +/// \param ShowDepth - Whether to indent to show the nesting of the includes. +/// \param MSStyle - Whether to print in cl.exe /showIncludes style. +void AttachHeaderIncludeGen(Preprocessor &PP, bool ShowAllHeaders = false, + StringRef OutputPath = "", + bool ShowDepth = true, bool MSStyle = false); + +/// Cache tokens for use with PCH. Note that this requires a seekable stream. +void CacheTokens(Preprocessor &PP, raw_pwrite_stream *OS); + +/// The ChainedIncludesSource class converts headers to chained PCHs in +/// memory, mainly for testing. +IntrusiveRefCntPtr<ExternalSemaSource> +createChainedIncludesSource(CompilerInstance &CI, + IntrusiveRefCntPtr<ExternalSemaSource> &Reader); + +/// createInvocationFromCommandLine - Construct a compiler invocation object for +/// a command line argument vector. +/// +/// \return A CompilerInvocation, or 0 if none was built for the given +/// argument vector. +CompilerInvocation * +createInvocationFromCommandLine(ArrayRef<const char *> Args, + IntrusiveRefCntPtr<DiagnosticsEngine> Diags = + IntrusiveRefCntPtr<DiagnosticsEngine>()); + +/// Return the value of the last argument as an integer, or a default. If Diags +/// is non-null, emits an error if the argument is given, but non-integral. +int getLastArgIntValue(const llvm::opt::ArgList &Args, + llvm::opt::OptSpecifier Id, int Default, + DiagnosticsEngine *Diags = nullptr); + +inline int getLastArgIntValue(const llvm::opt::ArgList &Args, + llvm::opt::OptSpecifier Id, int Default, + DiagnosticsEngine &Diags) { + return getLastArgIntValue(Args, Id, Default, &Diags); +} + +uint64_t getLastArgUInt64Value(const llvm::opt::ArgList &Args, + llvm::opt::OptSpecifier Id, uint64_t Default, + DiagnosticsEngine *Diags = nullptr); + +inline uint64_t getLastArgUInt64Value(const llvm::opt::ArgList &Args, + llvm::opt::OptSpecifier Id, + uint64_t Default, + DiagnosticsEngine &Diags) { + return getLastArgUInt64Value(Args, Id, Default, &Diags); +} + +// When Clang->getFrontendOpts().DisableFree is set we don't delete some of the +// global objects, but we don't want LeakDetectors to complain, so we bury them +// in a globally visible array. +void BuryPointer(const void *Ptr); +template <typename T> void BuryPointer(std::unique_ptr<T> Ptr) { + BuryPointer(Ptr.release()); +} + +} // end namespace clang + +#endif diff --git a/contrib/llvm/tools/clang/include/clang/Frontend/VerifyDiagnosticConsumer.h b/contrib/llvm/tools/clang/include/clang/Frontend/VerifyDiagnosticConsumer.h new file mode 100644 index 0000000..475f07f --- /dev/null +++ b/contrib/llvm/tools/clang/include/clang/Frontend/VerifyDiagnosticConsumer.h @@ -0,0 +1,278 @@ +//===- VerifyDiagnosticConsumer.h - Verifying Diagnostic Client -*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_VERIFYDIAGNOSTICCONSUMER_H +#define LLVM_CLANG_FRONTEND_VERIFYDIAGNOSTICCONSUMER_H + +#include "clang/Basic/Diagnostic.h" +#include "clang/Lex/Preprocessor.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/STLExtras.h" +#include <climits> +#include <memory> + +namespace clang { + +class DiagnosticsEngine; +class TextDiagnosticBuffer; +class FileEntry; + +/// VerifyDiagnosticConsumer - Create a diagnostic client which will use +/// markers in the input source to check that all the emitted diagnostics match +/// those expected. +/// +/// USING THE DIAGNOSTIC CHECKER: +/// +/// Indicating that a line expects an error or a warning is simple. Put a +/// comment on the line that has the diagnostic, use: +/// +/// \code +/// expected-{error,warning,remark,note} +/// \endcode +/// +/// to tag if it's an expected error, remark or warning, and place the expected +/// text between {{ and }} markers. The full text doesn't have to be included, +/// only enough to ensure that the correct diagnostic was emitted. +/// +/// Here's an example: +/// +/// \code +/// int A = B; // expected-error {{use of undeclared identifier 'B'}} +/// \endcode +/// +/// You can place as many diagnostics on one line as you wish. To make the code +/// more readable, you can use slash-newline to separate out the diagnostics. +/// +/// Alternatively, it is possible to specify the line on which the diagnostic +/// should appear by appending "@<line>" to "expected-<type>", for example: +/// +/// \code +/// #warning some text +/// // expected-warning@10 {{some text}} +/// \endcode +/// +/// The line number may be absolute (as above), or relative to the current +/// line by prefixing the number with either '+' or '-'. +/// +/// If the diagnostic is generated in a separate file, for example in a shared +/// header file, it may be beneficial to be able to declare the file in which +/// the diagnostic will appear, rather than placing the expected-* directive in +/// the actual file itself. This can be done using the following syntax: +/// +/// \code +/// // expected-error@path/include.h:15 {{error message}} +/// \endcode +/// +/// The path can be absolute or relative and the same search paths will be used +/// as for #include directives. The line number in an external file may be +/// substituted with '*' meaning that any line number will match (useful where +/// the included file is, for example, a system header where the actual line +/// number may change and is not critical). +/// +/// The simple syntax above allows each specification to match exactly one +/// error. You can use the extended syntax to customize this. The extended +/// syntax is "expected-<type> <n> {{diag text}}", where \<type> is one of +/// "error", "warning" or "note", and \<n> is a positive integer. This allows +/// the diagnostic to appear as many times as specified. Example: +/// +/// \code +/// void f(); // expected-note 2 {{previous declaration is here}} +/// \endcode +/// +/// Where the diagnostic is expected to occur a minimum number of times, this +/// can be specified by appending a '+' to the number. Example: +/// +/// \code +/// void f(); // expected-note 0+ {{previous declaration is here}} +/// void g(); // expected-note 1+ {{previous declaration is here}} +/// \endcode +/// +/// In the first example, the diagnostic becomes optional, i.e. it will be +/// swallowed if it occurs, but will not generate an error if it does not +/// occur. In the second example, the diagnostic must occur at least once. +/// As a short-hand, "one or more" can be specified simply by '+'. Example: +/// +/// \code +/// void g(); // expected-note + {{previous declaration is here}} +/// \endcode +/// +/// A range can also be specified by "<n>-<m>". Example: +/// +/// \code +/// void f(); // expected-note 0-1 {{previous declaration is here}} +/// \endcode +/// +/// In this example, the diagnostic may appear only once, if at all. +/// +/// Regex matching mode may be selected by appending '-re' to type and +/// including regexes wrapped in double curly braces in the directive, such as: +/// +/// \code +/// expected-error-re {{format specifies type 'wchar_t **' (aka '{{.+}}')}} +/// \endcode +/// +/// Examples matching error: "variable has incomplete type 'struct s'" +/// +/// \code +/// // expected-error {{variable has incomplete type 'struct s'}} +/// // expected-error {{variable has incomplete type}} +/// +/// // expected-error-re {{variable has type 'struct {{.}}'}} +/// // expected-error-re {{variable has type 'struct {{.*}}'}} +/// // expected-error-re {{variable has type 'struct {{(.*)}}'}} +/// // expected-error-re {{variable has type 'struct{{[[:space:]](.*)}}'}} +/// \endcode +/// +/// VerifyDiagnosticConsumer expects at least one expected-* directive to +/// be found inside the source code. If no diagnostics are expected the +/// following directive can be used to indicate this: +/// +/// \code +/// // expected-no-diagnostics +/// \endcode +/// +class VerifyDiagnosticConsumer: public DiagnosticConsumer, + public CommentHandler { +public: + /// Directive - Abstract class representing a parsed verify directive. + /// + class Directive { + public: + static std::unique_ptr<Directive> create(bool RegexKind, + SourceLocation DirectiveLoc, + SourceLocation DiagnosticLoc, + bool MatchAnyLine, StringRef Text, + unsigned Min, unsigned Max); + + public: + /// Constant representing n or more matches. + static const unsigned MaxCount = UINT_MAX; + + SourceLocation DirectiveLoc; + SourceLocation DiagnosticLoc; + const std::string Text; + unsigned Min, Max; + bool MatchAnyLine; + + virtual ~Directive() { } + + // Returns true if directive text is valid. + // Otherwise returns false and populates E. + virtual bool isValid(std::string &Error) = 0; + + // Returns true on match. + virtual bool match(StringRef S) = 0; + + protected: + Directive(SourceLocation DirectiveLoc, SourceLocation DiagnosticLoc, + bool MatchAnyLine, StringRef Text, unsigned Min, unsigned Max) + : DirectiveLoc(DirectiveLoc), DiagnosticLoc(DiagnosticLoc), + Text(Text), Min(Min), Max(Max), MatchAnyLine(MatchAnyLine) { + assert(!DirectiveLoc.isInvalid() && "DirectiveLoc is invalid!"); + assert(!DiagnosticLoc.isInvalid() && "DiagnosticLoc is invalid!"); + } + + private: + Directive(const Directive &) = delete; + void operator=(const Directive &) = delete; + }; + + typedef std::vector<std::unique_ptr<Directive>> DirectiveList; + + /// ExpectedData - owns directive objects and deletes on destructor. + /// + struct ExpectedData { + DirectiveList Errors; + DirectiveList Warnings; + DirectiveList Remarks; + DirectiveList Notes; + + void Reset() { + Errors.clear(); + Warnings.clear(); + Remarks.clear(); + Notes.clear(); + } + }; + + enum DirectiveStatus { + HasNoDirectives, + HasNoDirectivesReported, + HasExpectedNoDiagnostics, + HasOtherExpectedDirectives + }; + +private: + DiagnosticsEngine &Diags; + DiagnosticConsumer *PrimaryClient; + std::unique_ptr<DiagnosticConsumer> PrimaryClientOwner; + std::unique_ptr<TextDiagnosticBuffer> Buffer; + const Preprocessor *CurrentPreprocessor; + const LangOptions *LangOpts; + SourceManager *SrcManager; + unsigned ActiveSourceFiles; + DirectiveStatus Status; + ExpectedData ED; + + void CheckDiagnostics(); + void setSourceManager(SourceManager &SM) { + assert((!SrcManager || SrcManager == &SM) && "SourceManager changed!"); + SrcManager = &SM; + } + + // These facilities are used for validation in debug builds. + class UnparsedFileStatus { + llvm::PointerIntPair<const FileEntry *, 1, bool> Data; + public: + UnparsedFileStatus(const FileEntry *File, bool FoundDirectives) + : Data(File, FoundDirectives) {} + const FileEntry *getFile() const { return Data.getPointer(); } + bool foundDirectives() const { return Data.getInt(); } + }; + typedef llvm::DenseMap<FileID, const FileEntry *> ParsedFilesMap; + typedef llvm::DenseMap<FileID, UnparsedFileStatus> UnparsedFilesMap; + ParsedFilesMap ParsedFiles; + UnparsedFilesMap UnparsedFiles; + +public: + /// Create a new verifying diagnostic client, which will issue errors to + /// the currently-attached diagnostic client when a diagnostic does not match + /// what is expected (as indicated in the source file). + VerifyDiagnosticConsumer(DiagnosticsEngine &Diags); + ~VerifyDiagnosticConsumer() override; + + void BeginSourceFile(const LangOptions &LangOpts, + const Preprocessor *PP) override; + + void EndSourceFile() override; + + enum ParsedStatus { + /// File has been processed via HandleComment. + IsParsed, + + /// File has diagnostics and may have directives. + IsUnparsed, + + /// File has diagnostics but guaranteed no directives. + IsUnparsedNoDirectives + }; + + /// \brief Update lists of parsed and unparsed files. + void UpdateParsedFileStatus(SourceManager &SM, FileID FID, ParsedStatus PS); + + bool HandleComment(Preprocessor &PP, SourceRange Comment) override; + + void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, + const Diagnostic &Info) override; +}; + +} // end namspace clang + +#endif |