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