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