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