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 #include "clang/Lex/ModuleLoader.h"
     26 
     27 #include "llvm/ADT/IntrusiveRefCntPtr.h"
     28 #include "llvm/ADT/OwningPtr.h"
     29 #include "llvm/ADT/StringRef.h"
     30 
     31 #include "slang_diagnostic_buffer.h"
     32 #include "slang_pragma_recorder.h"
     33 
     34 namespace llvm {
     35   class tool_output_file;
     36 }
     37 
     38 namespace clang {
     39   class ASTConsumer;
     40   class ASTContext;
     41   class Backend;
     42   class CodeGenOptions;
     43   class Diagnostic;
     44   class DiagnosticsEngine;
     45   class FileManager;
     46   class FileSystemOptions;
     47   class LangOptions;
     48   class Preprocessor;
     49   class SourceManager;
     50   class TargetInfo;
     51   class TargetOptions;
     52 }
     53 
     54 namespace slang {
     55 
     56 class Slang : public clang::ModuleLoader {
     57   static clang::LangOptions LangOpts;
     58   static clang::CodeGenOptions CodeGenOpts;
     59 
     60   static bool GlobalInitialized;
     61 
     62   static void LLVMErrorHandler(void *UserData, const std::string &Message);
     63 
     64  public:
     65   enum OutputType {
     66     OT_Dependency,
     67     OT_Assembly,
     68     OT_LLVMAssembly,
     69     OT_Bitcode,
     70     OT_Nothing,
     71     OT_Object,
     72 
     73     OT_Default = OT_Bitcode
     74   };
     75 
     76  private:
     77   bool mInitialized;
     78 
     79   // Diagnostics Mediator (An interface for both Producer and Consumer)
     80   llvm::OwningPtr<clang::Diagnostic> mDiag;
     81 
     82   // Diagnostics ID
     83   llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> mDiagIDs;
     84 
     85   // Diagnostics Engine (Producer and Diagnostics Reporter)
     86   llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> mDiagEngine;
     87 
     88   // Diagnostics Consumer
     89   // NOTE: The ownership is taken by mDiagEngine after creation.
     90   DiagnosticBuffer *mDiagClient;
     91 
     92   void createDiagnostic();
     93 
     94 
     95   // The target being compiled for
     96   clang::TargetOptions mTargetOpts;
     97   llvm::OwningPtr<clang::TargetInfo> mTarget;
     98   void createTarget(std::string const &Triple, std::string const &CPU,
     99                     std::vector<std::string> const &Features);
    100 
    101 
    102   // File manager (for prepocessor doing the job such as header file search)
    103   llvm::OwningPtr<clang::FileManager> mFileMgr;
    104   llvm::OwningPtr<clang::FileSystemOptions> mFileSysOpt;
    105   void createFileManager();
    106 
    107 
    108   // Source manager (responsible for the source code handling)
    109   llvm::OwningPtr<clang::SourceManager> mSourceMgr;
    110   void createSourceManager();
    111 
    112 
    113   // Preprocessor (source code preprocessor)
    114   llvm::OwningPtr<clang::Preprocessor> mPP;
    115   void createPreprocessor();
    116 
    117 
    118   // AST context (the context to hold long-lived AST nodes)
    119   llvm::OwningPtr<clang::ASTContext> mASTContext;
    120   void createASTContext();
    121 
    122 
    123   // AST consumer, responsible for code generation
    124   llvm::OwningPtr<clang::ASTConsumer> mBackend;
    125 
    126 
    127   // File names
    128   std::string mInputFileName;
    129   std::string mOutputFileName;
    130 
    131   std::string mDepOutputFileName;
    132   std::string mDepTargetBCFileName;
    133   std::vector<std::string> mAdditionalDepTargets;
    134   std::vector<std::string> mGeneratedFileNames;
    135 
    136   OutputType mOT;
    137 
    138   // Output stream
    139   llvm::OwningPtr<llvm::tool_output_file> mOS;
    140 
    141   // Dependency output stream
    142   llvm::OwningPtr<llvm::tool_output_file> mDOS;
    143 
    144   std::vector<std::string> mIncludePaths;
    145 
    146  protected:
    147   PragmaList mPragmas;
    148 
    149   clang::DiagnosticsEngine &getDiagnostics() { return *mDiagEngine; }
    150   clang::TargetInfo const &getTargetInfo() const { return *mTarget; }
    151   clang::FileManager &getFileManager() { return *mFileMgr; }
    152   clang::SourceManager &getSourceManager() { return *mSourceMgr; }
    153   clang::Preprocessor &getPreprocessor() { return *mPP; }
    154   clang::ASTContext &getASTContext() { return *mASTContext; }
    155 
    156   inline clang::TargetOptions const &getTargetOptions() const
    157     { return mTargetOpts; }
    158 
    159   virtual void initDiagnostic() {}
    160   virtual void initPreprocessor() {}
    161   virtual void initASTContext() {}
    162 
    163   virtual clang::ASTConsumer *
    164     createBackend(const clang::CodeGenOptions& CodeGenOpts,
    165                   llvm::raw_ostream *OS,
    166                   OutputType OT);
    167 
    168  public:
    169   static const llvm::StringRef PragmaMetadataName;
    170 
    171   static void GlobalInitialization();
    172 
    173   Slang();
    174 
    175   void init(const std::string &Triple, const std::string &CPU,
    176             const std::vector<std::string> &Features);
    177 
    178   virtual clang::ModuleKey loadModule(clang::SourceLocation ImportLoc,
    179                                       clang::IdentifierInfo &ModuleName,
    180                                       clang::SourceLocation ModuleNameLoc);
    181 
    182   bool setInputSource(llvm::StringRef InputFile, const char *Text,
    183                       size_t TextLength);
    184 
    185   bool setInputSource(llvm::StringRef InputFile);
    186 
    187   std::string const &getInputFileName() const { return mInputFileName; }
    188 
    189   void setIncludePaths(const std::vector<std::string> &IncludePaths) {
    190     mIncludePaths = IncludePaths;
    191   }
    192 
    193   void setOutputType(OutputType OT) { mOT = OT; }
    194 
    195   bool setOutput(const char *OutputFile);
    196 
    197   std::string const &getOutputFileName() const {
    198     return mOutputFileName;
    199   }
    200 
    201   bool setDepOutput(const char *OutputFile);
    202 
    203   void setDepTargetBC(const char *TargetBCFile) {
    204     mDepTargetBCFileName = TargetBCFile;
    205   }
    206 
    207   void setAdditionalDepTargets(
    208       std::vector<std::string> const &AdditionalDepTargets) {
    209     mAdditionalDepTargets = AdditionalDepTargets;
    210   }
    211 
    212   void appendGeneratedFileName(std::string const &GeneratedFileName) {
    213     mGeneratedFileNames.push_back(GeneratedFileName);
    214   }
    215 
    216   int generateDepFile();
    217 
    218   int compile();
    219 
    220   char const *getErrorMessage() { return mDiagClient->str().c_str(); }
    221 
    222   // Reset the slang compiler state such that it can be reused to compile
    223   // another file
    224   virtual void reset();
    225 
    226   virtual ~Slang();
    227 };
    228 
    229 }  // namespace slang
    230 
    231 #endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_H_  NOLINT
    232