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