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 getDiagnostics()145 clang::DiagnosticsEngine &getDiagnostics() { return *mDiagEngine; } getTargetInfo()146 clang::TargetInfo const &getTargetInfo() const { return *mTarget; } getFileManager()147 clang::FileManager &getFileManager() { return *mFileMgr; } getSourceManager()148 clang::SourceManager &getSourceManager() { return *mSourceMgr; } getPreprocessor()149 clang::Preprocessor &getPreprocessor() { return *mPP; } getASTContext()150 clang::ASTContext &getASTContext() { return *mASTContext; } 151 getTargetOptions()152 inline clang::TargetOptions const &getTargetOptions() const 153 { return mTargetOpts; } 154 initDiagnostic()155 virtual void initDiagnostic() {} initPreprocessor()156 virtual void initPreprocessor() {} initASTContext()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 getInputFileName()186 std::string const &getInputFileName() const { return mInputFileName; } 187 setIncludePaths(const std::vector<std::string> & IncludePaths)188 void setIncludePaths(const std::vector<std::string> &IncludePaths) { 189 mIncludePaths = IncludePaths; 190 } 191 setOutputType(OutputType OT)192 void setOutputType(OutputType OT) { mOT = OT; } 193 194 bool setOutput(const char *OutputFile); 195 getOutputFileName()196 std::string const &getOutputFileName() const { 197 return mOutputFileName; 198 } 199 200 bool setDepOutput(const char *OutputFile); 201 setDepTargetBC(const char * TargetBCFile)202 void setDepTargetBC(const char *TargetBCFile) { 203 mDepTargetBCFileName = TargetBCFile; 204 } 205 setAdditionalDepTargets(std::vector<std::string> const & AdditionalDepTargets)206 void setAdditionalDepTargets( 207 std::vector<std::string> const &AdditionalDepTargets) { 208 mAdditionalDepTargets = AdditionalDepTargets; 209 } 210 appendGeneratedFileName(std::string const & GeneratedFileName)211 void appendGeneratedFileName(std::string const &GeneratedFileName) { 212 mGeneratedFileNames.push_back(GeneratedFileName); 213 } 214 215 int generateDepFile(); 216 217 int compile(); 218 getErrorMessage()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