diff options
Diffstat (limited to 'include/clang/Frontend')
22 files changed, 1761 insertions, 68 deletions
diff --git a/include/clang/Frontend/ASTConsumers.h b/include/clang/Frontend/ASTConsumers.h index 742813c..0e7d55e 100644 --- a/include/clang/Frontend/ASTConsumers.h +++ b/include/clang/Frontend/ASTConsumers.h @@ -25,11 +25,12 @@ namespace llvm { namespace clang { class ASTConsumer; +class CodeGenOptions; class Diagnostic; class FileManager; -class Preprocessor; -class CompileOptions; 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 @@ -69,7 +70,7 @@ ASTConsumer *CreateObjCRewriter(const std::string &InFile, bool SilenceRewriteMacroWarning); // LLVM code generator: uses the code generation backend to generate LLVM -// assembly. This runs optimizations depending on the CompileOptions +// assembly. This runs optimizations depending on the CodeGenOptions // parameter. The output depends on the Action parameter. enum BackendAction { Backend_EmitAssembly, // Emit native assembly @@ -80,7 +81,8 @@ enum BackendAction { ASTConsumer *CreateBackendConsumer(BackendAction Action, Diagnostic &Diags, const LangOptions &Features, - const CompileOptions &CompileOpts, + const CodeGenOptions &CodeGenOpts, + const TargetOptions &TargetOpts, const std::string &ModuleID, llvm::raw_ostream *OS, llvm::LLVMContext& C); diff --git a/include/clang/Frontend/Analyses.def b/include/clang/Frontend/Analyses.def index d5e4080..7d55673 100644 --- a/include/clang/Frontend/Analyses.def +++ b/include/clang/Frontend/Analyses.def @@ -48,6 +48,9 @@ ANALYSIS(WarnObjCUnusedIvars, "warn-objc-unused-ivars", ANALYSIS(CheckerCFRef, "checker-cfref", "Run the [Core] Foundation reference count checker", Code) +ANALYSIS(WarnSizeofPointer, "warn-sizeof-pointer", + "Warn about unintended use of sizeof() on pointer expressions", Code) + ANALYSIS(InlineCall, "inline-call", "Experimental transfer function inling callees when its definition" " is available.", TranslationUnit) diff --git a/include/clang/Frontend/AnalysisConsumer.h b/include/clang/Frontend/AnalysisConsumer.h index 34054a7..7a32433 100644 --- a/include/clang/Frontend/AnalysisConsumer.h +++ b/include/clang/Frontend/AnalysisConsumer.h @@ -1,4 +1,4 @@ -//===--- AnalysisConsumer.h - Front-end hooks for the analysis engine------===// +//===--- AnalysisConsumer.h - Front-end Analysis Engine Hooks ---*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -12,6 +12,9 @@ // //===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_FRONTEND_ANALYSISCONSUMER_H +#define LLVM_CLANG_FRONTEND_ANALYSISCONSUMER_H + #include <string> #include <vector> @@ -50,19 +53,37 @@ enum AnalysisDiagClients { NUM_ANALYSIS_DIAG_CLIENTS }; -struct AnalyzerOptions { +class AnalyzerOptions { +public: std::vector<Analyses> AnalysisList; AnalysisStores AnalysisStoreOpt; AnalysisConstraints AnalysisConstraintsOpt; AnalysisDiagClients AnalysisDiagOpt; - bool VisualizeEGDot; - bool VisualizeEGUbi; - bool AnalyzeAll; - bool AnalyzerDisplayProgress; - bool PurgeDead; - bool EagerlyAssume; std::string AnalyzeSpecificFunction; - bool TrimGraph; + unsigned AnalyzeAll : 1; + unsigned AnalyzerDisplayProgress : 1; + unsigned EagerlyAssume : 1; + unsigned PurgeDead : 1; + unsigned TrimGraph : 1; + unsigned VisualizeEGDot : 1; + unsigned VisualizeEGUbi : 1; + unsigned EnableExperimentalChecks : 1; + unsigned EnableExperimentalInternalChecks : 1; +public: + AnalyzerOptions() { + AnalysisStoreOpt = BasicStoreModel; + AnalysisConstraintsOpt = RangeConstraintsModel; + AnalysisDiagOpt = PD_HTML; + AnalyzeAll = 0; + AnalyzerDisplayProgress = 0; + EagerlyAssume = 0; + PurgeDead = 0; + TrimGraph = 0; + VisualizeEGDot = 0; + VisualizeEGUbi = 0; + EnableExperimentalChecks = 0; + EnableExperimentalInternalChecks = 0; + } }; /// CreateAnalysisConsumer - Creates an ASTConsumer to run various code @@ -73,3 +94,5 @@ ASTConsumer* CreateAnalysisConsumer(const Preprocessor &pp, const AnalyzerOptions& Opts); } + +#endif diff --git a/include/clang/Frontend/ChainedDiagnosticClient.h b/include/clang/Frontend/ChainedDiagnosticClient.h new file mode 100644 index 0000000..2d5e128 --- /dev/null +++ b/include/clang/Frontend/ChainedDiagnosticClient.h @@ -0,0 +1,58 @@ +//===--- ChainedDiagnosticClient.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_CHAINEDDIAGNOSTICCLIENT_H +#define LLVM_CLANG_FRONTEND_CHAINEDDIAGNOSTICCLIENT_H + +#include "clang/Basic/Diagnostic.h" +#include "llvm/ADT/OwningPtr.h" + +namespace clang { +class LangOptions; + +/// ChainedDiagnosticClient - 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 ChainedDiagnosticClient : public DiagnosticClient { + llvm::OwningPtr<DiagnosticClient> Primary; + llvm::OwningPtr<DiagnosticClient> Secondary; + +public: + ChainedDiagnosticClient(DiagnosticClient *_Primary, + DiagnosticClient *_Secondary) { + Primary.reset(_Primary); + Secondary.reset(_Secondary); + } + + virtual void BeginSourceFile(const LangOptions &LO, + const Preprocessor *PP) { + Primary->BeginSourceFile(LO, PP); + Secondary->BeginSourceFile(LO, PP); + } + + virtual void EndSourceFile() { + Secondary->EndSourceFile(); + Primary->EndSourceFile(); + } + + virtual bool IncludeInDiagnosticCounts() const { + return Primary->IncludeInDiagnosticCounts(); + } + + virtual void HandleDiagnostic(Diagnostic::Level DiagLevel, + const DiagnosticInfo &Info) { + Primary->HandleDiagnostic(DiagLevel, Info); + Secondary->HandleDiagnostic(DiagLevel, Info); + } +}; + +} // end namspace clang + +#endif diff --git a/include/clang/Frontend/CommandLineSourceLoc.h b/include/clang/Frontend/CommandLineSourceLoc.h index 59f70ed..d5a0598 100644 --- a/include/clang/Frontend/CommandLineSourceLoc.h +++ b/include/clang/Frontend/CommandLineSourceLoc.h @@ -1,3 +1,4 @@ + //===--- CommandLineSourceLoc.h - Parsing for source locations-*- C++ -*---===// // // The LLVM Compiler Infrastructure @@ -37,7 +38,7 @@ namespace llvm { class parser<clang::ParsedSourceLocation> : public basic_parser<clang::ParsedSourceLocation> { public: - bool parse(Option &O, StringRef ArgName, StringRef ArgValue, + inline bool parse(Option &O, StringRef ArgName, StringRef ArgValue, clang::ParsedSourceLocation &Val); }; diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h new file mode 100644 index 0000000..ed28050 --- /dev/null +++ b/include/clang/Frontend/CompilerInstance.h @@ -0,0 +1,523 @@ +//===-- 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/Frontend/CompilerInvocation.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/OwningPtr.h" +#include <cassert> +#include <list> +#include <string> + +namespace llvm { +class LLVMContext; +class raw_ostream; +class raw_fd_ostream; +} + +namespace clang { +class ASTContext; +class ASTConsumer; +class CodeCompleteConsumer; +class Diagnostic; +class DiagnosticClient; +class ExternalASTSource; +class FileManager; +class Preprocessor; +class Source; +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 { + /// The LLVM context used for this instance. + llvm::LLVMContext *LLVMContext; + bool OwnsLLVMContext; + + /// The options used in this compiler instance. + CompilerInvocation Invocation; + + /// The diagnostics engine instance. + llvm::OwningPtr<Diagnostic> Diagnostics; + + /// The diagnostics client instance. + llvm::OwningPtr<DiagnosticClient> DiagClient; + + /// The target being compiled for. + llvm::OwningPtr<TargetInfo> Target; + + /// The file manager. + llvm::OwningPtr<FileManager> FileMgr; + + /// The source manager. + llvm::OwningPtr<SourceManager> SourceMgr; + + /// The preprocessor. + llvm::OwningPtr<Preprocessor> PP; + + /// The AST context. + llvm::OwningPtr<ASTContext> Context; + + /// The AST consumer. + llvm::OwningPtr<ASTConsumer> Consumer; + + /// The code completion consumer. + llvm::OwningPtr<CodeCompleteConsumer> CompletionConsumer; + + /// The list of active output files. + std::list< std::pair<std::string, llvm::raw_ostream*> > OutputFiles; + +public: + /// Create a new compiler instance with the given LLVM context, optionally + /// taking ownership of it. + CompilerInstance(llvm::LLVMContext *_LLVMContext = 0, + bool _OwnsLLVMContext = true); + ~CompilerInstance(); + + /// @name LLVM Context + /// { + + bool hasLLVMContext() const { return LLVMContext != 0; } + + llvm::LLVMContext &getLLVMContext() const { + assert(LLVMContext && "Compiler instance has no LLVM context!"); + return *LLVMContext; + } + + /// setLLVMContext - Replace the current LLVM context and take ownership of + /// \arg Value. + void setLLVMContext(llvm::LLVMContext *Value, bool TakeOwnership = true) { + LLVMContext = Value; + OwnsLLVMContext = TakeOwnership; + } + + /// } + /// @name Compiler Invocation and Options + /// { + + CompilerInvocation &getInvocation() { return Invocation; } + const CompilerInvocation &getInvocation() const { return Invocation; } + void setInvocation(const CompilerInvocation &Value) { Invocation = Value; } + + /// } + /// @name Forwarding Methods + /// { + + AnalyzerOptions &getAnalyzerOpts() { + return Invocation.getAnalyzerOpts(); + } + const AnalyzerOptions &getAnalyzerOpts() const { + 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(); + } + + 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 != 0; } + + Diagnostic &getDiagnostics() const { + assert(Diagnostics && "Compiler instance has no diagnostics!"); + return *Diagnostics; + } + + /// takeDiagnostics - Remove the current diagnostics engine and give ownership + /// to the caller. + Diagnostic *takeDiagnostics() { return Diagnostics.take(); } + + /// setDiagnostics - Replace the current diagnostics engine; the compiler + /// instance takes ownership of \arg Value. + void setDiagnostics(Diagnostic *Value); + + DiagnosticClient &getDiagnosticClient() const { + assert(Target && "Compiler instance has no diagnostic client!"); + return *DiagClient; + } + + /// takeDiagnosticClient - Remove the current diagnostics client and give + /// ownership to the caller. + DiagnosticClient *takeDiagnosticClient() { return DiagClient.take(); } + + /// setDiagnosticClient - Replace the current diagnostics client; the compiler + /// instance takes ownership of \arg Value. + void setDiagnosticClient(DiagnosticClient *Value); + + /// } + /// @name Target Info + /// { + + bool hasTarget() const { return Target != 0; } + + TargetInfo &getTarget() const { + assert(Target && "Compiler instance has no target!"); + return *Target; + } + + /// takeTarget - Remove the current diagnostics engine and give ownership + /// to the caller. + TargetInfo *takeTarget() { return Target.take(); } + + /// setTarget - Replace the current diagnostics engine; the compiler + /// instance takes ownership of \arg Value. + void setTarget(TargetInfo *Value); + + /// } + /// @name File Manager + /// { + + bool hasFileManager() const { return FileMgr != 0; } + + FileManager &getFileManager() const { + assert(FileMgr && "Compiler instance has no file manager!"); + return *FileMgr; + } + + /// takeFileManager - Remove the current file manager and give ownership to + /// the caller. + FileManager *takeFileManager() { return FileMgr.take(); } + + /// setFileManager - Replace the current file manager; the compiler instance + /// takes ownership of \arg Value. + void setFileManager(FileManager *Value); + + /// } + /// @name Source Manager + /// { + + bool hasSourceManager() const { return SourceMgr != 0; } + + SourceManager &getSourceManager() const { + assert(SourceMgr && "Compiler instance has no source manager!"); + return *SourceMgr; + } + + /// takeSourceManager - Remove the current source manager and give ownership + /// to the caller. + SourceManager *takeSourceManager() { return SourceMgr.take(); } + + /// setSourceManager - Replace the current source manager; the compiler + /// instance takes ownership of \arg Value. + void setSourceManager(SourceManager *Value); + + /// } + /// @name Preprocessor + /// { + + bool hasPreprocessor() const { return PP != 0; } + + Preprocessor &getPreprocessor() const { + assert(PP && "Compiler instance has no preprocessor!"); + return *PP; + } + + /// takePreprocessor - Remove the current preprocessor and give ownership to + /// the caller. + Preprocessor *takePreprocessor() { return PP.take(); } + + /// setPreprocessor - Replace the current preprocessor; the compiler instance + /// takes ownership of \arg Value. + void setPreprocessor(Preprocessor *Value); + + /// } + /// @name ASTContext + /// { + + bool hasASTContext() const { return Context != 0; } + + ASTContext &getASTContext() const { + assert(Context && "Compiler instance has no AST context!"); + return *Context; + } + + /// takeASTContext - Remove the current AST context and give ownership to the + /// caller. + ASTContext *takeASTContext() { return Context.take(); } + + /// setASTContext - Replace the current AST context; the compiler instance + /// takes ownership of \arg Value. + void setASTContext(ASTContext *Value); + + /// } + /// @name ASTConsumer + /// { + + bool hasASTConsumer() const { return Consumer != 0; } + + 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. + ASTConsumer *takeASTConsumer() { return Consumer.take(); } + + /// setASTConsumer - Replace the current AST consumer; the compiler instance + /// takes ownership of \arg Value. + void setASTConsumer(ASTConsumer *Value); + + /// } + /// @name Code Completion + /// { + + bool hasCodeCompletionConsumer() const { return CompletionConsumer != 0; } + + CodeCompleteConsumer &getCodeCompletionConsumer() const { + assert(CompletionConsumer && + "Compiler instance has no code completion consumer!"); + return *CompletionConsumer; + } + + /// takeCodeCompletionConsumer - Remove the current code completion consumer + /// and give ownership to the caller. + CodeCompleteConsumer *takeCodeCompletionConsumer() { + return CompletionConsumer.take(); + } + + /// setCodeCompletionConsumer - Replace the current code completion consumer; + /// the compiler instance takes ownership of \arg Value. + void setCodeCompletionConsumer(CodeCompleteConsumer *Value); + + /// } + /// @name Output Files + /// { + + /// getOutputFileList - Get the list of (path, output stream) pairs of output + /// files; the path may be empty but the stream will always be non-null. + const std::list< std::pair<std::string, + llvm::raw_ostream*> > &getOutputFileList() const; + + /// addOutputFile - Add an output file onto the list of tracked output files. + /// + /// \param Path - The path to the output file, or empty. + /// \param OS - The output stream, which should be non-null. + void addOutputFile(llvm::StringRef Path, llvm::raw_ostream *OS); + + /// 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. + void createDiagnostics(int Argc, char **Argv); + + /// Create a Diagnostic object with a the TextDiagnosticPrinter. + /// + /// The \arg Argc and \arg Argv arguments are used only for logging purposes, + /// when the diagnostic options indicate that the compiler should output + /// logging information. + /// + /// Note that this creates an unowned DiagnosticClient, if using directly the + /// caller is responsible for releaseing the returned Diagnostic's client + /// eventually. + /// + /// \return The new object on success, or null on failure. + static Diagnostic *createDiagnostics(const DiagnosticOptions &Opts, + int Argc, char **Argv); + + /// 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(); + + /// Create the preprocessor, using the invocation, file, and source managers, + /// and replace any existing one with it. + void createPreprocessor(); + + /// Create a Preprocessor object. + /// + /// Note that this also creates a new HeaderSearch object which will be owned + /// by the resulting Preprocessor. + /// + /// \return The new object on success, or null on failure. + static Preprocessor *createPreprocessor(Diagnostic &, const LangOptions &, + const PreprocessorOptions &, + const HeaderSearchOptions &, + const DependencyOutputOptions &, + const TargetInfo &, + SourceManager &, FileManager &); + + /// 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(llvm::StringRef Path); + + /// Create an external AST source to read a PCH file. + /// + /// \return - The new object on success, or null on failure. + static ExternalASTSource * + createPCHExternalASTSource(llvm::StringRef Path, const std::string &Sysroot, + Preprocessor &PP, ASTContext &Context); + + /// 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 + /// \arg Filename, \arg Line, and \arg Column, to the given output stream \arg + /// OS. + static CodeCompleteConsumer * + createCodeCompletionConsumer(Preprocessor &PP, const std::string &Filename, + unsigned Line, unsigned Column, + bool UseDebugPrinter, bool ShowMacros, + llvm::raw_ostream &OS); + + /// Create the default output file (from the invocation's options) and add it + /// to the list of tracked output files. + llvm::raw_fd_ostream * + createDefaultOutputFile(bool Binary = true, llvm::StringRef BaseInput = "", + llvm::StringRef Extension = ""); + + /// Create a new output file and add it to the list of tracked output files, + /// optionally deriving the output path name. + llvm::raw_fd_ostream * + createOutputFile(llvm::StringRef OutputPath, bool Binary = true, + llvm::StringRef BaseInput = "", + llvm::StringRef Extension = ""); + + /// Create a new output file, optionally deriving the output path name. + /// + /// If \arg OutputPath is empty, then createOutputFile will derive an output + /// path location as \arg BaseInput, with any suffix removed, and \arg + /// Extension appended. + /// + /// \param OutputPath - If given, the path to the output file. + /// \param Error [out] - On failure, the error message. + /// \param BaseInput - If \arg 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 ResultPathName [out] - If given, the result path name will be + /// stored here on success. + static llvm::raw_fd_ostream * + createOutputFile(llvm::StringRef OutputPath, std::string &Error, + bool Binary = true, llvm::StringRef BaseInput = "", + llvm::StringRef Extension = "", + std::string *ResultPathName = 0); + + /// } + /// @name Initialization Utility Methods + /// { + + /// InitializeSourceManager - Initialize the source manager to set InputFile + /// as the main file. + /// + /// \return True on success. + bool InitializeSourceManager(llvm::StringRef InputFile); + + /// InitializeSourceManager - Initialize the source manager to set InputFile + /// as the main file. + /// + /// \return True on success. + static bool InitializeSourceManager(llvm::StringRef InputFile, + Diagnostic &Diags, + FileManager &FileMgr, + SourceManager &SourceMgr, + const FrontendOptions &Opts); + + /// } +}; + +} // end namespace clang + +#endif diff --git a/include/clang/Frontend/CompilerInvocation.h b/include/clang/Frontend/CompilerInvocation.h new file mode 100644 index 0000000..9d068c5 --- /dev/null +++ b/include/clang/Frontend/CompilerInvocation.h @@ -0,0 +1,150 @@ +//===-- 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/LangOptions.h" +#include "clang/Basic/TargetOptions.h" +#include "clang/CodeGen/CodeGenOptions.h" +#include "clang/Frontend/AnalysisConsumer.h" +#include "clang/Frontend/DependencyOutputOptions.h" +#include "clang/Frontend/DiagnosticOptions.h" +#include "clang/Frontend/FrontendOptions.h" +#include "clang/Frontend/HeaderSearchOptions.h" +#include "clang/Frontend/PreprocessorOptions.h" +#include "clang/Frontend/PreprocessorOutputOptions.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/StringMap.h" +#include <string> +#include <vector> + +namespace llvm { + template<typename T> class SmallVectorImpl; +} + +namespace clang { + +/// CompilerInvocation - 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 { + /// Options controlling the static analyzer. + AnalyzerOptions AnalyzerOpts; + + /// Options controlling IRgen and the backend. + CodeGenOptions CodeGenOpts; + + /// Options controlling dependency output. + DependencyOutputOptions DependencyOutputOpts; + + /// Options controlling the diagnostic engine. + DiagnosticOptions DiagnosticOpts; + + /// Options controlling the frontend itself. + FrontendOptions FrontendOpts; + + /// Options controlling the #include directive. + HeaderSearchOptions HeaderSearchOpts; + + /// Options controlling the language variant. + LangOptions LangOpts; + + /// Options controlling the preprocessor (aside from #include handling). + PreprocessorOptions PreprocessorOpts; + + /// Options controlling preprocessed output. + PreprocessorOutputOptions PreprocessorOutputOpts; + + /// Options controlling the target. + TargetOptions TargetOpts; + +public: + CompilerInvocation() {} + + /// @name Utility Methods + /// @{ + + /// CreateFromArgs - Create a compiler invocation from a list of input + /// options. + /// + /// FIXME: Documenting error behavior. + /// + /// \param Res [out] - The resulting invocation. + /// \param Args - The input argument strings. + static void CreateFromArgs(CompilerInvocation &Res, + const llvm::SmallVectorImpl<llvm::StringRef> &Args); + + /// toArgs - Convert the CompilerInvocation to a list of strings suitable for + /// passing to CreateFromArgs. + void toArgs(std::vector<std::string> &Res); + + /// @} + /// @name Option Subgroups + /// @{ + + AnalyzerOptions &getAnalyzerOpts() { return AnalyzerOpts; } + const AnalyzerOptions &getAnalyzerOpts() const { + return AnalyzerOpts; + } + + CodeGenOptions &getCodeGenOpts() { return CodeGenOpts; } + const CodeGenOptions &getCodeGenOpts() const { + return CodeGenOpts; + } + + DependencyOutputOptions &getDependencyOutputOpts() { + return DependencyOutputOpts; + } + const DependencyOutputOptions &getDependencyOutputOpts() const { + return DependencyOutputOpts; + } + + DiagnosticOptions &getDiagnosticOpts() { return DiagnosticOpts; } + const DiagnosticOptions &getDiagnosticOpts() const { return DiagnosticOpts; } + + HeaderSearchOptions &getHeaderSearchOpts() { return HeaderSearchOpts; } + const HeaderSearchOptions &getHeaderSearchOpts() const { + return HeaderSearchOpts; + } + + FrontendOptions &getFrontendOpts() { return FrontendOpts; } + const FrontendOptions &getFrontendOpts() const { + return FrontendOpts; + } + + LangOptions &getLangOpts() { return LangOpts; } + const LangOptions &getLangOpts() const { return LangOpts; } + + PreprocessorOptions &getPreprocessorOpts() { return PreprocessorOpts; } + const PreprocessorOptions &getPreprocessorOpts() const { + return PreprocessorOpts; + } + + PreprocessorOutputOptions &getPreprocessorOutputOpts() { + return PreprocessorOutputOpts; + } + const PreprocessorOutputOptions &getPreprocessorOutputOpts() const { + return PreprocessorOutputOpts; + } + + TargetOptions &getTargetOpts() { return TargetOpts; } + const TargetOptions &getTargetOpts() const { + return TargetOpts; + } + + /// @} +}; + +} // end namespace clang + +#endif diff --git a/include/clang/Frontend/DependencyOutputOptions.h b/include/clang/Frontend/DependencyOutputOptions.h new file mode 100644 index 0000000..ab8e49d --- /dev/null +++ b/include/clang/Frontend/DependencyOutputOptions.h @@ -0,0 +1,43 @@ +//===--- 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 { + +/// DependencyOutputOptions - Options for controlling the compiler dependency +/// file generation. +class DependencyOutputOptions { +public: + unsigned IncludeSystemHeaders : 1; ///< Include system header dependencies. + unsigned UsePhonyTargets : 1; ///< Include phony targets for each + /// dependency, which can avoid some 'make' + /// problems. + + /// The file to write depencency output to. + std::string OutputFile; + + /// 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; + +public: + DependencyOutputOptions() { + IncludeSystemHeaders = 0; + UsePhonyTargets = 0; + } +}; + +} // end namespace clang + +#endif diff --git a/include/clang/Frontend/DiagnosticOptions.h b/include/clang/Frontend/DiagnosticOptions.h index 58673e4..6346dc0 100644 --- a/include/clang/Frontend/DiagnosticOptions.h +++ b/include/clang/Frontend/DiagnosticOptions.h @@ -19,6 +19,10 @@ namespace clang { /// engine. class DiagnosticOptions { public: + unsigned IgnoreWarnings : 1; /// -w + unsigned NoRewriteMacros : 1; /// -Wno-rewrite-macros + unsigned Pedantic : 1; /// -pedantic + unsigned PedanticErrors : 1; /// -pedantic-errors unsigned ShowColumn : 1; /// Show column number on diagnostics. unsigned ShowLocation : 1; /// Show source location information. unsigned ShowCarets : 1; /// Show carets in diagnostics. @@ -27,20 +31,36 @@ public: unsigned ShowOptionNames : 1; /// Show the diagnostic name for mappable /// diagnostics. unsigned ShowColors : 1; /// Show diagnostics with ANSI color sequences. + unsigned VerifyDiagnostics; /// Check that diagnostics match the expected + /// diagnostics, indicated by markers in the + /// input source file. /// Column limit for formatting message diagnostics, or 0 if unused. unsigned MessageLength; + /// If non-empty, a file to log extended build information to, for development + /// testing and analysis. + std::string DumpBuildInformation; + + /// The list of -W... options used to alter the diagnostic mappings, with the + /// prefixes removed. + std::vector<std::string> Warnings; + public: DiagnosticOptions() { - ShowColumn = 1; - ShowLocation = 1; + IgnoreWarnings = 0; + MessageLength = 0; + NoRewriteMacros = 0; + Pedantic = 0; + PedanticErrors = 0; ShowCarets = 1; + ShowColors = 0; + ShowColumn = 1; ShowFixits = 1; - ShowSourceRanges = 0; + ShowLocation = 1; ShowOptionNames = 0; - ShowColors = 0; - MessageLength = 0; + ShowSourceRanges = 0; + VerifyDiagnostics = 0; } }; diff --git a/include/clang/Frontend/FrontendAction.h b/include/clang/Frontend/FrontendAction.h new file mode 100644 index 0000000..469ea53 --- /dev/null +++ b/include/clang/Frontend/FrontendAction.h @@ -0,0 +1,215 @@ +//===-- 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. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_FRONTEND_FRONTENDACTION_H +#define LLVM_CLANG_FRONTEND_FRONTENDACTION_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/OwningPtr.h" +#include <string> + +namespace llvm { +class Timer; +} + +namespace clang { +class ASTUnit; +class ASTConsumer; +class CompilerInstance; + +/// FrontendAction - Abstract base class for actions which can be performed by +/// the frontend. +class FrontendAction { + std::string CurrentFile; + llvm::OwningPtr<ASTUnit> CurrentASTUnit; + CompilerInstance *Instance; + llvm::Timer *CurrentTimer; + +protected: + /// @name Implementation Action Interface + /// @{ + + /// CreateASTConsumer - Create the AST consumer object for this action, if + /// supported. + /// + /// This routine is called as part of \see BeginSourceAction(), 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 0 on failure. + virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile) = 0; + + /// BeginSourceFileAction - Callback at the start of processing a single + /// input. + /// + /// \return True on success; on failure \see ExecutionAction() and + /// EndSourceFileAction() will not be called. + virtual bool BeginSourceFileAction(CompilerInstance &CI, + llvm::StringRef Filename) { + return true; + } + + /// ExecuteAction - Callback to run the program action, using the initialized + /// compiler instance. + /// + /// This routine is guaranteed to only be called between \see + /// BeginSourceFileAction() and \see EndSourceFileAction(). + virtual void ExecuteAction() = 0; + + /// EndSourceFileAction - Callback at the end of processing a single input; + /// this is guaranteed to only be called following a successful call to + /// BeginSourceFileAction (and BeingSourceFile). + virtual void EndSourceFileAction() {} + + /// @} + +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(!CurrentFile.empty() && "No current file!"); + return CurrentASTUnit != 0; + } + + const std::string &getCurrentFile() const { + assert(!CurrentFile.empty() && "No current file!"); + return CurrentFile; + } + + ASTUnit &getCurrentASTUnit() const { + assert(!CurrentASTUnit && "No current AST unit!"); + return *CurrentASTUnit; + } + + void setCurrentFile(llvm::StringRef Value, ASTUnit *AST = 0); + + /// @} + /// @name Timing Utilities + /// @{ + + llvm::Timer *getCurrentTimer() const { + return CurrentTimer; + } + + void setCurrentTimer(llvm::Timer *Value) { + CurrentTimer = Value; + } + + /// @} + /// @name Supported Modes + /// @{ + + /// usesPreprocessorOnly - Does this action only use the preprocessor? If so + /// no AST context will be created and this action will be invalid with PCH + /// inputs. + virtual bool usesPreprocessorOnly() const = 0; + + /// usesCompleteTranslationUnit - For AST based actions, should the + /// translation unit be completed? + virtual bool usesCompleteTranslationUnit() { return true; } + + /// hasPCHSupport - Does this action support use with PCH? + virtual bool hasPCHSupport() const { return !usesPreprocessorOnly(); } + + /// hasASTSupport - Does this action support use with AST files? + virtual bool hasASTSupport() const { return !usesPreprocessorOnly(); } + + /// hasCodeCompletionSupport - Does this action support use with code + /// completion? + virtual bool hasCodeCompletionSupport() const { return false; } + + /// @} + /// @name Public Action Interface + /// @{ + + /// BeginSourceFile - Prepare the action for processing the input file \arg + /// Filename; 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 Filename - The input filename, which will be made available to + /// clients via \see getCurrentFile(). + /// + /// \param IsAST - Indicates whether this is an AST input. AST inputs require + /// special handling, 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 \see BeginSourceFile() and \see EndSourceFile(). + /// + /// \return True on success; the compilation of this file should be aborted + /// and neither Execute nor EndSourceFile should be called. + bool BeginSourceFile(CompilerInstance &CI, llvm::StringRef Filename, + bool IsAST = false); + + /// Execute - Set the source managers main input file, and run the action. + void Execute(); + + /// EndSourceFile - Perform any per-file post processing, deallocate per-file + /// objects, and run statistics and output file cleanup code. + void EndSourceFile(); + + /// @} +}; + +/// ASTFrontendAction - Abstract base class to use for AST consumer based +/// frontend actios. +class ASTFrontendAction : public FrontendAction { + /// ExecuteAction - 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. + virtual void ExecuteAction(); + +public: + virtual bool usesPreprocessorOnly() const { return false; } +}; + +/// PreprocessorFrontendAction - Abstract base class to use for preprocessor +/// based frontend actions. +class PreprocessorFrontendAction : public FrontendAction { +protected: + /// CreateASTConsumer - Provide a default implementation which returns aborts, + /// this method should never be called by FrontendAction clients. + virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile); + +public: + virtual bool usesPreprocessorOnly() const { return true; } +}; + +} // end namespace clang + +#endif diff --git a/include/clang/Frontend/FrontendActions.h b/include/clang/Frontend/FrontendActions.h new file mode 100644 index 0000000..e755fe1 --- /dev/null +++ b/include/clang/Frontend/FrontendActions.h @@ -0,0 +1,216 @@ +//===-- 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" + +namespace clang { +class FixItRewriter; + +//===----------------------------------------------------------------------===// +// AST Consumer Actions +//===----------------------------------------------------------------------===// + +class AnalysisAction : public ASTFrontendAction { +protected: + virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile); +}; + +class ASTPrintAction : public ASTFrontendAction { +protected: + virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile); +}; + +class ASTPrintXMLAction : public ASTFrontendAction { +protected: + virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile); +}; + +class ASTDumpAction : public ASTFrontendAction { +protected: + virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile); +}; + +class ASTViewAction : public ASTFrontendAction { +protected: + virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile); +}; + +class DeclContextPrintAction : public ASTFrontendAction { +protected: + virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile); +}; + +class DumpRecordAction : public ASTFrontendAction { +protected: + virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile); +}; + +class FixItAction : public ASTFrontendAction { +private: + llvm::OwningPtr<FixItRewriter> Rewriter; + +protected: + + virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile); + + virtual bool BeginSourceFileAction(CompilerInstance &CI, + llvm::StringRef Filename); + + virtual void EndSourceFileAction(); + + virtual bool hasASTSupport() const { return false; } + +public: + FixItAction(); + ~FixItAction(); +}; + +class GeneratePCHAction : public ASTFrontendAction { +protected: + virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile); + + virtual bool usesCompleteTranslationUnit() { return false; } + + virtual bool hasASTSupport() const { return false; } +}; + +class HTMLPrintAction : public ASTFrontendAction { +protected: + virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile); +}; + +class InheritanceViewAction : public ASTFrontendAction { +protected: + virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile); +}; + +class RewriteObjCAction : public ASTFrontendAction { +protected: + virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile); +}; + +class RewriteBlocksAction : public ASTFrontendAction { +protected: + virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile); +}; + +class SyntaxOnlyAction : public ASTFrontendAction { +protected: + virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile); + +public: + virtual bool hasCodeCompletionSupport() const { return true; } +}; + +//===----------------------------------------------------------------------===// +// Code Gen AST Actions +//===----------------------------------------------------------------------===// + +class CodeGenAction : public ASTFrontendAction { +private: + unsigned Act; + +protected: + CodeGenAction(unsigned _Act); + + virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile); +}; + +class EmitAssemblyAction : public CodeGenAction { +public: + EmitAssemblyAction(); +}; + +class EmitBCAction : public CodeGenAction { +public: + EmitBCAction(); +}; + +class EmitLLVMAction : public CodeGenAction { +public: + EmitLLVMAction(); +}; + +class EmitLLVMOnlyAction : public CodeGenAction { +public: + EmitLLVMOnlyAction(); +}; + +//===----------------------------------------------------------------------===// +// Preprocessor Actions +//===----------------------------------------------------------------------===// + +class DumpRawTokensAction : public PreprocessorFrontendAction { +protected: + void ExecuteAction(); +}; + +class DumpTokensAction : public PreprocessorFrontendAction { +protected: + void ExecuteAction(); +}; + +class GeneratePTHAction : public PreprocessorFrontendAction { +protected: + void ExecuteAction(); +}; + +class ParseOnlyAction : public PreprocessorFrontendAction { +protected: + void ExecuteAction(); +}; + +class PreprocessOnlyAction : public PreprocessorFrontendAction { +protected: + void ExecuteAction(); +}; + +class PrintParseAction : public PreprocessorFrontendAction { +protected: + void ExecuteAction(); +}; + +class PrintPreprocessedAction : public PreprocessorFrontendAction { +protected: + void ExecuteAction(); + + virtual bool hasPCHSupport() const { return true; } +}; + +class RewriteMacrosAction : public PreprocessorFrontendAction { +protected: + void ExecuteAction(); +}; + +class RewriteTestAction : public PreprocessorFrontendAction { +protected: + void ExecuteAction(); +}; + +} // end namespace clang + +#endif diff --git a/include/clang/Frontend/FrontendOptions.h b/include/clang/Frontend/FrontendOptions.h new file mode 100644 index 0000000..197a2a0 --- /dev/null +++ b/include/clang/Frontend/FrontendOptions.h @@ -0,0 +1,131 @@ +//===--- 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 "llvm/ADT/StringRef.h" +#include <string> +#include <vector> + +namespace clang { + +namespace frontend { + enum ActionKind { + ASTDump, ///< Parse ASTs and dump them. + ASTPrint, ///< Parse ASTs and print them. + ASTPrintXML, ///< Parse ASTs and print them in XML. + ASTView, ///< Parse ASTs and view them in Graphviz. + DumpRawTokens, ///< Dump out raw tokens. + DumpRecordLayouts, ///< Dump record layout information. + 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 + FixIt, ///< Parse and apply any fixits to the source. + GeneratePCH, ///< Generate pre-compiled header. + GeneratePTH, ///< Generate pre-tokenized header. + InheritanceView, ///< View C++ inheritance for a specified class. + ParseNoop, ///< Parse with noop callbacks. + ParsePrintCallbacks, ///< Parse and print each callback. + ParseSyntaxOnly, ///< Parse and perform semantic analysis. + PluginAction, ///< Run a plugin action, \see ActionName. + PrintDeclContext, ///< Print DeclContext and their Decls. + PrintPreprocessedInput, ///< -E mode. + RewriteBlocks, ///< ObjC->C Rewriter for Blocks. + RewriteMacros, ///< Expand macros but not #includes. + RewriteObjC, ///< ObjC->C Rewriter. + RewriteTest, ///< Rewriter playground + RunAnalysis, ///< Run one or more source code analyses. + RunPreprocessorOnly ///< Just lex, no output. + }; +} + +/// FrontendOptions - Options for controlling the behavior of the frontend. +class FrontendOptions { +public: + 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_AST + }; + + unsigned DebugCodeCompletionPrinter : 1; ///< Use the debug printer for code + /// completion results. + unsigned DisableFree : 1; ///< Disable memory freeing on exit. + unsigned EmptyInputOnly : 1; ///< Force input files to be treated + /// as if they were empty, for timing + /// the frontend startup. + unsigned RelocatablePCH : 1; ///< When generating PCH files, + /// instruct the PCH writer to create + /// relocatable PCH files. + unsigned ShowMacrosInCodeCompletion : 1; ///< Show macros in code completion + /// results. + unsigned ShowStats : 1; ///< Show frontend performance + /// metrics and statistics. + unsigned ShowTimers : 1; ///< Show timers for individual + /// actions. + + /// The input files and their types. + std::vector<std::pair<InputKind, std::string> > Inputs; + + /// The output file, if any. + std::string OutputFile; + + /// If given, the name for a C++ class to view the inheritance of. + std::string ViewClassInheritance; + + /// A list of locations to apply fix-its at. + std::vector<ParsedSourceLocation> FixItLocations; + + /// 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; + +public: + FrontendOptions() { + DebugCodeCompletionPrinter = 0; + DisableFree = 0; + EmptyInputOnly = 0; + ProgramAction = frontend::ParseSyntaxOnly; + ActionName = ""; + RelocatablePCH = 0; + ShowMacrosInCodeCompletion = 0; + ShowStats = 0; + ShowTimers = 0; + } + + /// 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(llvm::StringRef Extension); +}; + +} // end namespace clang + +#endif diff --git a/include/clang/Frontend/FrontendPluginRegistry.h b/include/clang/Frontend/FrontendPluginRegistry.h new file mode 100644 index 0000000..8341492 --- /dev/null +++ b/include/clang/Frontend/FrontendPluginRegistry.h @@ -0,0 +1,23 @@ +//===-- 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_PLUGINFRONTENDACTION_H +#define LLVM_CLANG_FRONTEND_PLUGINFRONTENDACTION_H + +#include "clang/Frontend/FrontendAction.h" +#include "llvm/Support/Registry.h" + +namespace clang { + +/// The frontend plugin registry. +typedef llvm::Registry<FrontendAction> FrontendPluginRegistry; + +} // end namespace clang + +#endif diff --git a/include/clang/Frontend/HeaderSearchOptions.h b/include/clang/Frontend/HeaderSearchOptions.h new file mode 100644 index 0000000..2edc7e1 --- /dev/null +++ b/include/clang/Frontend/HeaderSearchOptions.h @@ -0,0 +1,87 @@ +//===--- HeaderSearchOptions.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_HEADERSEARCHOPTIONS_H +#define LLVM_CLANG_FRONTEND_HEADERSEARCHOPTIONS_H + +#include "llvm/ADT/StringRef.h" +#include <vector> + +namespace clang { + +namespace frontend { + /// IncludeDirGroup - Identifiers the group a include entry belongs to, which + /// represents its relative positive in the search list. + enum IncludeDirGroup { + Quoted = 0, ///< `#include ""` paths. Thing `gcc -iquote`. + Angled, ///< Paths for both `#include ""` and `#include <>`. (`-I`) + System, ///< Like Angled, but marks system directories. + After ///< Like System, but searched after the system directories. + }; +} + +/// HeaderSearchOptions - Helper class for storing options related to the +/// initialization of the HeaderSearch object. +class HeaderSearchOptions { +public: + struct Entry { + std::string Path; + frontend::IncludeDirGroup Group; + unsigned IsUserSupplied : 1; + unsigned IsFramework : 1; + + Entry(llvm::StringRef _Path, frontend::IncludeDirGroup _Group, + bool _IsUserSupplied, bool _IsFramework) + : Path(_Path), Group(_Group), IsUserSupplied(_IsUserSupplied), + IsFramework(_IsFramework) {} + }; + + /// If non-empty, the directory to use as a "virtual system root" for include + /// paths. + std::string Sysroot; + + /// User specified include entries. + std::vector<Entry> UserEntries; + + /// A (system-path) delimited list of include paths to be added from the + /// environment following the user specified includes (but prior to builtin + /// and standard includes). This is parsed in the same manner as the CPATH + /// environment variable for gcc. + std::string EnvIncPath; + + /// Per-language environmental include paths, see \see EnvIncPath. + std::string CEnvIncPath; + std::string ObjCEnvIncPath; + std::string CXXEnvIncPath; + std::string ObjCXXEnvIncPath; + + /// If non-empty, the path to the compiler builtin include directory, which + /// will be searched following the user and environment includes. + std::string BuiltinIncludePath; + + /// Include the system standard include search directories. + unsigned UseStandardIncludes : 1; + + /// Whether header search information should be output as for -v. + unsigned Verbose : 1; + +public: + HeaderSearchOptions(llvm::StringRef _Sysroot = "") + : Sysroot(_Sysroot), UseStandardIncludes(true) {} + + /// AddPath - Add the \arg Path path to the specified \arg Group list. + void AddPath(llvm::StringRef Path, frontend::IncludeDirGroup Group, + bool IsUserSupplied, bool IsFramework) { + UserEntries.push_back(Entry(Path, Group, IsUserSupplied, IsFramework)); + } +}; + +} // end namespace clang + +#endif diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h index cc8b3a0..85861fa 100644 --- a/include/clang/Frontend/PCHReader.h +++ b/include/clang/Frontend/PCHReader.h @@ -29,6 +29,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Bitcode/BitstreamReader.h" #include "llvm/System/DataTypes.h" #include <deque> @@ -78,7 +79,7 @@ public: /// \brief Receives the target triple. /// /// \returns true to indicate the target triple is invalid or false otherwise. - virtual bool ReadTargetTriple(const std::string &Triple) { + virtual bool ReadTargetTriple(llvm::StringRef Triple) { return false; } @@ -87,18 +88,18 @@ public: /// \param PCHPredef The start of the predefines buffer in the PCH /// file. /// - /// \param PCHPredefLen The length of the predefines buffer in the PCH - /// file. - /// /// \param PCHBufferID The FileID for the PCH predefines buffer. /// + /// \param OriginalFileName The original file name for the PCH, which will + /// appear as an entry in the predefines buffer. + /// /// \param SuggestedPredefines If necessary, additional definitions are added /// here. /// /// \returns true to indicate the predefines are invalid or false otherwise. - virtual bool ReadPredefinesBuffer(const char *PCHPredef, - unsigned PCHPredefLen, + virtual bool ReadPredefinesBuffer(llvm::StringRef PCHPredef, FileID PCHBufferID, + llvm::StringRef OriginalFileName, std::string &SuggestedPredefines) { return false; } @@ -123,10 +124,10 @@ public: : PP(PP), Reader(Reader), NumHeaderInfos(0) {} virtual bool ReadLanguageOptions(const LangOptions &LangOpts); - virtual bool ReadTargetTriple(const std::string &Triple); - virtual bool ReadPredefinesBuffer(const char *PCHPredef, - unsigned PCHPredefLen, + virtual bool ReadTargetTriple(llvm::StringRef Triple); + virtual bool ReadPredefinesBuffer(llvm::StringRef PCHPredef, FileID PCHBufferID, + llvm::StringRef OriginalFileName, std::string &SuggestedPredefines); virtual void ReadHeaderFileInfo(const HeaderFileInfo &HFI); virtual void ReadCounter(unsigned Value); @@ -312,10 +313,13 @@ private: /// the PCH file. llvm::SmallVector<uint64_t, 4> ObjCCategoryImpls; - /// \brief The original file name that was used to build the PCH - /// file. + /// \brief The original file name that was used to build the PCH file, which + /// may have been modified for relocatable-pch support. std::string OriginalFileName; + /// \brief The actual original file name that was used to build the PCH file. + std::string ActualOriginalFileName; + /// \brief Whether this precompiled header is a relocatable PCH file. bool RelocatablePCH; @@ -444,9 +448,7 @@ private: void MaybeAddSystemRootToFilename(std::string &Filename); PCHReadResult ReadPCHBlock(); - bool CheckPredefinesBuffer(const char *PCHPredef, - unsigned PCHPredefLen, - FileID PCHBufferID); + bool CheckPredefinesBuffer(llvm::StringRef PCHPredef, FileID PCHBufferID); bool ParseLineTable(llvm::SmallVectorImpl<uint64_t> &Record); PCHReadResult ReadSourceManagerBlock(); PCHReadResult ReadSLocEntryRecord(unsigned ID); @@ -625,13 +627,15 @@ public: /// \brief Retrieve the IdentifierInfo for the named identifier. /// - /// This routine builds a new IdentifierInfo for the given - /// identifier. If any declarations with this name are visible from - /// translation unit scope, their declarations will be deserialized - /// and introduced into the declaration chain of the - /// identifier. FIXME: if this identifier names a macro, deserialize - /// the macro. + /// This routine builds a new IdentifierInfo for the given identifier. If any + /// declarations with this name are visible from translation unit scope, their + /// declarations will be deserialized and introduced into the declaration + /// chain of the identifier. FIXME: if this identifier names a macro, + /// deserialize the macro. virtual IdentifierInfo* get(const char *NameStart, const char *NameEnd); + IdentifierInfo* get(llvm::StringRef Name) { + return get(Name.begin(), Name.end()); + } /// \brief Load the contents of the global method pool for a given /// selector. diff --git a/include/clang/Frontend/PCHWriter.h b/include/clang/Frontend/PCHWriter.h index 22427eb..b520f4b 100644 --- a/include/clang/Frontend/PCHWriter.h +++ b/include/clang/Frontend/PCHWriter.h @@ -52,7 +52,8 @@ struct UnsafeQualTypeDenseMapInfo { return QualType::getFromOpaquePtr((void*) 2); } static inline unsigned getHashValue(QualType T) { - assert(!T.getFastQualifiers() && "hash invalid for types with fast quals"); + assert(!T.getLocalFastQualifiers() && + "hash invalid for types with fast quals"); uintptr_t v = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr()); return (unsigned(v) >> 4) ^ (unsigned(v) >> 9); } diff --git a/include/clang/Frontend/PreprocessorOptions.h b/include/clang/Frontend/PreprocessorOptions.h new file mode 100644 index 0000000..f0c1d3c --- /dev/null +++ b/include/clang/Frontend/PreprocessorOptions.h @@ -0,0 +1,57 @@ +//===--- PreprocessorOptionms.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_PREPROCESSOROPTIONS_H_ +#define LLVM_CLANG_FRONTEND_PREPROCESSOROPTIONS_H_ + +#include "llvm/ADT/StringRef.h" +#include <cassert> +#include <string> +#include <vector> + +namespace clang { + +class Preprocessor; +class LangOptions; + +/// PreprocessorOptions - This class is used for passing the various options +/// used in preprocessor initialization to InitializePreprocessor(). +class PreprocessorOptions { +public: + std::vector<std::pair<std::string, bool/*isUndef*/> > Macros; + std::vector<std::string> Includes; + std::vector<std::string> MacroIncludes; + + unsigned UsePredefines : 1; /// Initialize the preprocessor with the compiler + /// and target specific predefines. + + /// The implicit PCH included at the start of the translation unit, or empty. + std::string ImplicitPCHInclude; + + /// The implicit PTH input included at the start of the translation unit, or + /// empty. + std::string ImplicitPTHInclude; + + /// If given, a PTH cache file to use for speeding up header parsing. + std::string TokenCache; + +public: + PreprocessorOptions() : UsePredefines(true) {} + + void addMacroDef(llvm::StringRef Name) { + Macros.push_back(std::make_pair(Name, false)); + } + void addMacroUndef(llvm::StringRef Name) { + Macros.push_back(std::make_pair(Name, true)); + } +}; + +} // end namespace clang + +#endif diff --git a/include/clang/Frontend/PreprocessorOutputOptions.h b/include/clang/Frontend/PreprocessorOutputOptions.h new file mode 100644 index 0000000..a712a3d --- /dev/null +++ b/include/clang/Frontend/PreprocessorOutputOptions.h @@ -0,0 +1,37 @@ +//===--- 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 ShowMacros : 1; ///< Print macro definitions. + unsigned ShowLineMarkers : 1; ///< Show #line markers. + unsigned ShowComments : 1; ///< Show comments. + unsigned ShowMacroComments : 1; ///< Show comments, even in macros. + +public: + PreprocessorOutputOptions() { + ShowCPP = 1; + ShowMacros = 0; + ShowLineMarkers = 1; + ShowComments = 0; + ShowMacroComments = 0; + } +}; + +} // end namespace clang + +#endif diff --git a/include/clang/Frontend/TextDiagnosticPrinter.h b/include/clang/Frontend/TextDiagnosticPrinter.h index 3c5c626..d727e48 100644 --- a/include/clang/Frontend/TextDiagnosticPrinter.h +++ b/include/clang/Frontend/TextDiagnosticPrinter.h @@ -34,12 +34,15 @@ class TextDiagnosticPrinter : public DiagnosticClient { SourceLocation LastWarningLoc; FullSourceLoc LastLoc; - bool LastCaretDiagnosticWasNote; + unsigned LastCaretDiagnosticWasNote : 1; + unsigned OwnsOutputStream : 1; public: - TextDiagnosticPrinter(llvm::raw_ostream &os, const DiagnosticOptions &diags); + TextDiagnosticPrinter(llvm::raw_ostream &os, const DiagnosticOptions &diags, + bool OwnsOutputStream = false); + virtual ~TextDiagnosticPrinter(); - void BeginSourceFile(const LangOptions &LO) { + void BeginSourceFile(const LangOptions &LO, const Preprocessor *PP) { LangOpts = &LO; } diff --git a/include/clang/Frontend/TypeXML.def b/include/clang/Frontend/TypeXML.def index 6aca15a..35f5deb 100644 --- a/include/clang/Frontend/TypeXML.def +++ b/include/clang/Frontend/TypeXML.def @@ -65,9 +65,9 @@ NODE_XML(QualType, "CvQualifiedType") ID_ATTRIBUTE_XML TYPE_ATTRIBUTE_XML(getTypePtr()) // the qualified type, e.g. for 'T* const' it's 'T*' - ATTRIBUTE_OPT_XML(isConstQualified(), "const") // boolean - ATTRIBUTE_OPT_XML(isVolatileQualified(), "volatile") // boolean - ATTRIBUTE_OPT_XML(isRestrictQualified(), "restrict") // boolean + ATTRIBUTE_OPT_XML(isLocalConstQualified(), "const") // boolean + ATTRIBUTE_OPT_XML(isLocalVolatileQualified(), "volatile") // boolean + ATTRIBUTE_OPT_XML(isLocalRestrictQualified(), "restrict") // boolean ATTRIBUTE_OPT_XML(getObjCGCAttr(), "objc_gc") // Qualifiers::GC ATTRIBUTE_OPT_XML(getAddressSpace(), "address_space") // unsigned END_NODE_XML diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h index 3c67028..27c14c9 100644 --- a/include/clang/Frontend/Utils.h +++ b/include/clang/Frontend/Utils.h @@ -1,4 +1,4 @@ -//===--- Utils.h - Misc utilities for the front-end------------------------===// +//===--- Utils.h - Misc utilities for the front-end -------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -14,42 +14,57 @@ #ifndef LLVM_CLANG_FRONTEND_UTILS_H #define LLVM_CLANG_FRONTEND_UTILS_H +#include "llvm/ADT/StringRef.h" #include <vector> #include <string> namespace llvm { +class Triple; class raw_ostream; class raw_fd_ostream; } namespace clang { -class Preprocessor; -class MinimalAction; -class TargetInfo; -class Diagnostic; class ASTConsumer; +class Decl; +class DependencyOutputOptions; +class Diagnostic; +class DiagnosticOptions; +class HeaderSearch; +class HeaderSearchOptions; class IdentifierTable; -class SourceManager; class LangOptions; -class Decl; +class MinimalAction; +class Preprocessor; +class PreprocessorOptions; +class PreprocessorOutputOptions; +class SourceManager; class Stmt; +class TargetInfo; + +/// Normalize \arg File for use in a user defined #include directive (in the +/// predefines buffer). +std::string NormalizeDashIncludePath(llvm::StringRef File); + +/// 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 HeaderSearchOptions &HSOpts); /// ProcessWarningOptions - Initialize the diagnostic client and process the /// warning options specified on the command line. -bool ProcessWarningOptions(Diagnostic &Diags, - std::vector<std::string> &Warnings, - bool Pedantic, bool PedanticErrors, - bool NoWarnings); - -/// DoPrintPreprocessedInput - Implement -E -dM mode. -void DoPrintMacros(Preprocessor &PP, llvm::raw_ostream* OS); +bool ProcessWarningOptions(Diagnostic &Diags, const DiagnosticOptions &Opts); /// DoPrintPreprocessedInput - Implement -E mode. void DoPrintPreprocessedInput(Preprocessor &PP, llvm::raw_ostream* OS, - bool EnableCommentOutput, - bool EnableMacroCommentOutput, - bool DisableLineMarkers, - bool DumpDefines); + const PreprocessorOutputOptions &Opts); /// RewriteMacrosInInput - Implement -rewrite-macros mode. void RewriteMacrosInInput(Preprocessor &PP, llvm::raw_ostream* OS); @@ -67,13 +82,12 @@ bool CheckDiagnostics(Preprocessor &PP); /// AttachDependencyFileGen - Create a dependency file generator, and attach /// it to the given preprocessor. This takes ownership of the output stream. -void AttachDependencyFileGen(Preprocessor *PP, llvm::raw_ostream *OS, - std::vector<std::string> &Targets, - bool IncludeSystemHeaders, bool PhonyTarget); +void AttachDependencyFileGen(Preprocessor &PP, + const DependencyOutputOptions &Opts); /// CacheTokens - Cache tokens for use with PCH. Note that this requires /// a seekable stream. -void CacheTokens(Preprocessor& PP, llvm::raw_fd_ostream* OS); +void CacheTokens(Preprocessor &PP, llvm::raw_fd_ostream* OS); } // end namespace clang diff --git a/include/clang/Frontend/VerifyDiagnosticsClient.h b/include/clang/Frontend/VerifyDiagnosticsClient.h new file mode 100644 index 0000000..6f7ebbe --- /dev/null +++ b/include/clang/Frontend/VerifyDiagnosticsClient.h @@ -0,0 +1,82 @@ +//===-- VerifyDiagnosticsClient.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_VERIFYDIAGNOSTICSCLIENT_H +#define LLVM_CLANG_FRONTEND_VERIFYDIAGNOSTICSCLIENT_H + +#include "clang/Basic/Diagnostic.h" +#include "llvm/ADT/OwningPtr.h" + +namespace clang { + +class Diagnostic; +class SourceMgr; +class TextDiagnosticBuffer; + +/// VerifyDiagnosticsClient - 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 "expected-{error,warning}" +/// to tag if it's an expected error 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: +/// +/// int A = B; // expected-error {{use of undeclared identifier 'B'}} +/// +/// 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. +/// +/// 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: +/// +/// void f(); // expected-note 2 {{previous declaration is here}} +/// +class VerifyDiagnosticsClient : public DiagnosticClient { +public: + Diagnostic &Diags; + llvm::OwningPtr<DiagnosticClient> PrimaryClient; + llvm::OwningPtr<TextDiagnosticBuffer> Buffer; + Preprocessor *CurrentPreprocessor; + unsigned NumErrors; + +private: + void CheckDiagnostics(); + +public: + /// Create a new verifying diagnostic client, which will issue errors to \arg + /// PrimaryClient when a diagnostic does not match what is expected (as + /// indicated in the source file). The verifying diagnostic client takes + /// ownership of \arg PrimaryClient. + VerifyDiagnosticsClient(Diagnostic &Diags, DiagnosticClient *PrimaryClient); + ~VerifyDiagnosticsClient(); + + virtual void BeginSourceFile(const LangOptions &LangOpts, + const Preprocessor *PP); + + virtual void EndSourceFile(); + + virtual void HandleDiagnostic(Diagnostic::Level DiagLevel, + const DiagnosticInfo &Info); + + /// HadErrors - Check if there were any mismatches in expected diagnostics. + bool HadErrors(); +}; + +} // end namspace clang + +#endif |