slang.h revision 3fe4027f9acbc5047f8e7ca8f1575e3a6af76cf8
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 <list> 22#include <string> 23#include <utility> 24#include <vector> 25 26#include "llvm/ADT/StringMap.h" 27 28#include "slang_rs_reflect_utils.h" 29#include "slang_version.h" 30 31// Terrible workaround for TargetOptions.h not using llvm::RefCountedBase! 32#include "llvm/ADT/IntrusiveRefCntPtr.h" 33using llvm::RefCountedBase; 34 35#include "clang/Basic/LangOptions.h" 36#include "clang/Basic/TargetOptions.h" 37#include "clang/Frontend/CodeGenOptions.h" 38#include "clang/Lex/ModuleLoader.h" 39 40#include "llvm/ADT/StringRef.h" 41 42#include "llvm/Target/TargetMachine.h" 43 44#include "slang_diagnostic_buffer.h" 45#include "slang_pragma_recorder.h" 46 47namespace llvm { 48 class tool_output_file; 49} 50 51namespace clang { 52 class ASTConsumer; 53 class ASTContext; 54 class Backend; 55 class CodeGenOptions; 56 class Diagnostic; 57 class DiagnosticsEngine; 58 class FileManager; 59 class FileSystemOptions; 60 class LangOptions; 61 class Preprocessor; 62 class SourceManager; 63 class TargetInfo; 64} // namespace clang 65 66namespace slang { 67 68class RSCCOptions; 69class RSContext; 70class RSExportRecordType; 71 72class Slang : public clang::ModuleLoader { 73 public: 74 enum OutputType { 75 OT_Dependency, 76 OT_Assembly, 77 OT_LLVMAssembly, 78 OT_Bitcode, 79 OT_Nothing, 80 OT_Object, 81 82 OT_Default = OT_Bitcode 83 }; 84 85 private: 86 // Language options (define the language feature for compiler such as C99) 87 clang::LangOptions LangOpts; 88 // Code generation options for the compiler 89 clang::CodeGenOptions CodeGenOpts; 90 91 // Returns true if this is a Filterscript file. 92 static bool isFilterscript(const char *Filename); 93 94 // Diagnostics Engine (Producer and Diagnostics Reporter) 95 clang::DiagnosticsEngine *mDiagEngine; 96 97 // Diagnostics Consumer 98 // NOTE: The ownership is taken by mDiagEngine after creation. 99 DiagnosticBuffer *mDiagClient; 100 101 // The target being compiled for 102 std::shared_ptr<clang::TargetOptions> mTargetOpts; 103 std::unique_ptr<clang::TargetInfo> mTarget; 104 void createTarget(uint32_t BitWidth); 105 106 // File manager (for prepocessor doing the job such as header file search) 107 std::unique_ptr<clang::FileManager> mFileMgr; 108 std::unique_ptr<clang::FileSystemOptions> mFileSysOpt; 109 void createFileManager(); 110 111 // Source manager (responsible for the source code handling) 112 std::unique_ptr<clang::SourceManager> mSourceMgr; 113 void createSourceManager(); 114 115 // Preprocessor (source code preprocessor) 116 std::unique_ptr<clang::Preprocessor> mPP; 117 void createPreprocessor(); 118 119 // AST context (the context to hold long-lived AST nodes) 120 std::unique_ptr<clang::ASTContext> mASTContext; 121 void createASTContext(); 122 123 // AST consumer, responsible for code generation 124 std::unique_ptr<clang::ASTConsumer> mBackend; 125 126 // File names 127 std::string mInputFileName; 128 std::string mOutputFileName; 129 std::string mOutput32FileName; 130 131 std::string mDepOutputFileName; 132 std::string mDepTargetBCFileName; 133 std::vector<std::string> mAdditionalDepTargets; 134 135 OutputType mOT; 136 137 // Output stream 138 std::unique_ptr<llvm::tool_output_file> mOS; 139 140 // Dependency output stream 141 std::unique_ptr<llvm::tool_output_file> mDOS; 142 143 std::vector<std::string> mIncludePaths; 144 145 // Context for Renderscript 146 RSContext *mRSContext; 147 148 bool mAllowRSPrefix; 149 150 unsigned int mTargetAPI; 151 152 bool mVerbose; 153 154 bool mIsFilterscript; 155 156 // Collect generated filenames (without the .java) for dependency generation 157 std::vector<std::string> mGeneratedFileNames; 158 159 PragmaList mPragmas; 160 161 // FIXME: Should be std::list<RSExportable *> here. But currently we only 162 // check ODR on record type. 163 // 164 // ReflectedDefinitions maps record type name to a pair: 165 // <its RSExportRecordType instance, 166 // the first file contains this record type definition> 167 typedef std::pair<RSExportRecordType*, const char*> ReflectedDefinitionTy; 168 typedef llvm::StringMap<ReflectedDefinitionTy> ReflectedDefinitionListTy; 169 ReflectedDefinitionListTy ReflectedDefinitions; 170 171 bool generateJavaBitcodeAccessor(const std::string &OutputPathBase, 172 const std::string &PackageName, 173 const std::string *LicenseNote); 174 175 // CurInputFile is the pointer to a char array holding the input filename 176 // and is valid before compile() ends. 177 bool checkODR(const char *CurInputFile); 178 179 clang::DiagnosticsEngine &getDiagnostics() { return *mDiagEngine; } 180 clang::TargetInfo const &getTargetInfo() const { return *mTarget; } 181 clang::FileManager &getFileManager() { return *mFileMgr; } 182 clang::SourceManager &getSourceManager() { return *mSourceMgr; } 183 clang::Preprocessor &getPreprocessor() { return *mPP; } 184 clang::ASTContext &getASTContext() { return *mASTContext; } 185 186 inline clang::TargetOptions const &getTargetOptions() const 187 { return *mTargetOpts.get(); } 188 189 void initPreprocessor(); 190 void initASTContext(); 191 192 clang::ASTConsumer *createBackend(const RSCCOptions &Opts, 193 const clang::CodeGenOptions &CodeGenOpts, 194 llvm::raw_ostream *OS, 195 OutputType OT); 196 197 public: 198 static const llvm::StringRef PragmaMetadataName; 199 200 static void GlobalInitialization(); 201 202 static bool IsRSHeaderFile(const char *File); 203 // FIXME: Determine whether a location is in RS header (i.e., one of the RS 204 // built-in APIs) should only need its names (we need a "list" of RS 205 // built-in APIs). 206 static bool IsLocInRSHeaderFile(const clang::SourceLocation &Loc, 207 const clang::SourceManager &SourceMgr); 208 209 Slang(uint32_t BitWidth, clang::DiagnosticsEngine *DiagEngine, 210 DiagnosticBuffer *DiagClient); 211 212 virtual ~Slang(); 213 214 bool setInputSource(llvm::StringRef InputFile); 215 216 std::string const &getInputFileName() const { return mInputFileName; } 217 218 void setIncludePaths(const std::vector<std::string> &IncludePaths) { 219 mIncludePaths = IncludePaths; 220 } 221 222 void setOutputType(OutputType OT) { mOT = OT; } 223 224 bool setOutput(const char *OutputFile); 225 226 bool setDepOutput(const char *OutputFile); 227 228 void setDepTargetBC(const char *TargetBCFile) { 229 mDepTargetBCFileName = TargetBCFile; 230 } 231 232 void setAdditionalDepTargets( 233 std::vector<std::string> const &AdditionalDepTargets) { 234 mAdditionalDepTargets = AdditionalDepTargets; 235 } 236 237 void appendGeneratedFileName(std::string const &GeneratedFileName) { 238 mGeneratedFileNames.push_back(GeneratedFileName); 239 } 240 241 int generateDepFile(bool PhonyTarget); 242 243 int compile(const RSCCOptions &Opts); 244 245 char const *getErrorMessage() { return mDiagClient->str().c_str(); } 246 247 void setDebugMetadataEmission(bool EmitDebug); 248 249 void setOptimizationLevel(llvm::CodeGenOpt::Level OptimizationLevel); 250 251 // Compile bunch of RS files given in the llvm-rs-cc arguments. Return true if 252 // all given input files are successfully compiled without errors. 253 // 254 // @IOFiles - List of pairs of <input file path, output file path>. 255 // 256 // @DepFiles - List of pairs of <output dep. file path, dependent bitcode 257 // target>. If @OutputDep is true, this parameter must be given 258 // with the same number of pairs given in @IOFiles. 259 // 260 // @Opts - Selection of options defined from invoking llvm-rs-cc 261 bool 262 compile(const std::list<std::pair<const char *, const char *>> &IOFiles64, 263 const std::list<std::pair<const char *, const char *>> &IOFiles32, 264 const std::list<std::pair<const char *, const char *>> &DepFiles, 265 const RSCCOptions &Opts, 266 clang::DiagnosticOptions &DiagOpts); 267 268 clang::ModuleLoadResult loadModule(clang::SourceLocation ImportLoc, 269 clang::ModuleIdPath Path, 270 clang::Module::NameVisibilityKind VK, 271 bool IsInclusionDirective) override; 272 273 void makeModuleVisible(clang::Module *Mod, 274 clang::Module::NameVisibilityKind Visibility, 275 clang::SourceLocation ImportLoc, 276 bool Complain = false) override {} 277 278 clang::GlobalModuleIndex * 279 loadGlobalModuleIndex(clang::SourceLocation TriggerLoc) override { 280 // We don't support C++ modules for RenderScript. 281 return nullptr; 282 } 283 284 bool lookupMissingImports(llvm::StringRef Name, 285 clang::SourceLocation TriggerLoc) override { 286 // We don't support C++ modules for RenderScript. 287 return false; 288 } 289}; 290 291} // namespace slang 292 293#endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_H_ NOLINT 294