Home | History | Annotate | Download | only in slang
      1 /*
      2  * Copyright 2010, The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *     http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_H_  // NOLINT
     18 #define _FRAMEWORKS_COMPILE_SLANG_SLANG_H_
     19 
     20 #include <cstdio>
     21 #include <string>
     22 #include <vector>
     23 
     24 #include "clang/Basic/TargetOptions.h"
     25 
     26 #include "llvm/ADT/IntrusiveRefCntPtr.h"
     27 #include "llvm/ADT/OwningPtr.h"
     28 #include "llvm/ADT/StringRef.h"
     29 
     30 #include "slang_diagnostic_buffer.h"
     31 #include "slang_pragma_recorder.h"
     32 
     33 namespace llvm {
     34   class tool_output_file;
     35 }
     36 
     37 namespace clang {
     38   class Diagnostic;
     39   class FileManager;
     40   class FileSystemOptions;
     41   class SourceManager;
     42   class LangOptions;
     43   class Preprocessor;
     44   class TargetOptions;
     45   class CodeGenOptions;
     46   class ASTContext;
     47   class ASTConsumer;
     48   class Backend;
     49   class TargetInfo;
     50 }
     51 
     52 namespace slang {
     53 
     54 class Slang {
     55   static clang::LangOptions LangOpts;
     56   static clang::CodeGenOptions CodeGenOpts;
     57 
     58   static bool GlobalInitialized;
     59 
     60   static void LLVMErrorHandler(void *UserData, const std::string &Message);
     61 
     62  public:
     63   typedef enum {
     64     OT_Dependency,
     65     OT_Assembly,
     66     OT_LLVMAssembly,
     67     OT_Bitcode,
     68     OT_Nothing,
     69     OT_Object,
     70 
     71     OT_Default = OT_Bitcode
     72   } OutputType;
     73 
     74  private:
     75   bool mInitialized;
     76 
     77   // The diagnostics engine instance (for status reporting during compilation)
     78   llvm::IntrusiveRefCntPtr<clang::Diagnostic> mDiagnostics;
     79   // The diagnostics id
     80   llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> mDiagIDs;
     81   // The clients of diagnostics engine. The ownership is taken by the
     82   // mDiagnostics after creation.
     83   DiagnosticBuffer *mDiagClient;
     84   void createDiagnostic();
     85 
     86   // The target being compiled for
     87   clang::TargetOptions mTargetOpts;
     88   llvm::OwningPtr<clang::TargetInfo> mTarget;
     89   void createTarget(const std::string &Triple, const std::string &CPU,
     90                     const std::vector<std::string> &Features);
     91 
     92   // Below is for parsing and code generation
     93 
     94   // The file manager (for prepocessor doing the job such as header file search)
     95   llvm::OwningPtr<clang::FileManager> mFileMgr;
     96   llvm::OwningPtr<clang::FileSystemOptions> mFileSysOpt;
     97   void createFileManager();
     98 
     99   // The source manager (responsible for the source code handling)
    100   llvm::OwningPtr<clang::SourceManager> mSourceMgr;
    101   void createSourceManager();
    102 
    103   // The preprocessor (source code preprocessor)
    104   llvm::OwningPtr<clang::Preprocessor> mPP;
    105   void createPreprocessor();
    106 
    107   // The AST context (the context to hold long-lived AST nodes)
    108   llvm::OwningPtr<clang::ASTContext> mASTContext;
    109   void createASTContext();
    110 
    111   // The AST consumer, responsible for code generation
    112   llvm::OwningPtr<clang::ASTConsumer> mBackend;
    113 
    114   // Input file name
    115   std::string mInputFileName;
    116   std::string mOutputFileName;
    117 
    118   std::string mDepOutputFileName;
    119   std::string mDepTargetBCFileName;
    120   std::vector<std::string> mAdditionalDepTargets;
    121   std::vector<std::string> mGeneratedFileNames;
    122 
    123   OutputType mOT;
    124 
    125   // Output stream
    126   llvm::OwningPtr<llvm::tool_output_file> mOS;
    127   // Dependency output stream
    128   llvm::OwningPtr<llvm::tool_output_file> mDOS;
    129 
    130   std::vector<std::string> mIncludePaths;
    131 
    132  protected:
    133   PragmaList mPragmas;
    134 
    135   inline clang::Diagnostic &getDiagnostics() { return *mDiagnostics; }
    136   inline const clang::TargetInfo &getTargetInfo() const { return *mTarget; }
    137   inline clang::FileManager &getFileManager() { return *mFileMgr; }
    138   inline clang::SourceManager &getSourceManager() { return *mSourceMgr; }
    139   inline clang::Preprocessor &getPreprocessor() { return *mPP; }
    140   inline clang::ASTContext &getASTContext() { return *mASTContext; }
    141 
    142   inline const clang::TargetOptions &getTargetOptions() const
    143     { return mTargetOpts; }
    144 
    145   virtual void initDiagnostic() {}
    146   virtual void initPreprocessor() {}
    147   virtual void initASTContext() {}
    148 
    149   virtual clang::ASTConsumer
    150   *createBackend(const clang::CodeGenOptions& CodeGenOpts,
    151                  llvm::raw_ostream *OS,
    152                  OutputType OT);
    153 
    154  public:
    155   static const llvm::StringRef PragmaMetadataName;
    156 
    157   static void GlobalInitialization();
    158 
    159   Slang();
    160 
    161   void init(const std::string &Triple, const std::string &CPU,
    162             const std::vector<std::string> &Features);
    163 
    164   bool setInputSource(llvm::StringRef InputFile, const char *Text,
    165                       size_t TextLength);
    166 
    167   bool setInputSource(llvm::StringRef InputFile);
    168 
    169   inline const std::string &getInputFileName() const { return mInputFileName; }
    170 
    171   inline void setIncludePaths(const std::vector<std::string> &IncludePaths) {
    172     mIncludePaths = IncludePaths;
    173   }
    174 
    175   inline void setOutputType(OutputType OT) { mOT = OT; }
    176 
    177   bool setOutput(const char *OutputFile);
    178   inline const std::string &getOutputFileName() const {
    179     return mOutputFileName;
    180   }
    181 
    182   bool setDepOutput(const char *OutputFile);
    183   inline void setDepTargetBC(const char *TargetBCFile) {
    184     mDepTargetBCFileName = TargetBCFile;
    185   }
    186   inline void setAdditionalDepTargets(
    187       const std::vector<std::string> &AdditionalDepTargets) {
    188     mAdditionalDepTargets = AdditionalDepTargets;
    189   }
    190   inline void appendGeneratedFileName(
    191       const std::string &GeneratedFileName) {
    192     mGeneratedFileNames.push_back(GeneratedFileName);
    193   }
    194 
    195   int generateDepFile();
    196   int compile();
    197 
    198   inline const char *getErrorMessage() { return mDiagClient->str().c_str(); }
    199 
    200   // Reset the slang compiler state such that it can be reused to compile
    201   // another file
    202   virtual void reset();
    203 
    204   virtual ~Slang();
    205 };
    206 
    207 }  // namespace slang
    208 
    209 #endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_H_  NOLINT
    210