slang_rs.cpp revision cf6af6abc1de499920571308b14a27e19cf57097
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#include "slang_rs.h" 18 19#include <cstring> 20 21#include "clang/Frontend/FrontendDiagnostic.h" 22 23#include "clang/Sema/SemaDiagnostic.h" 24 25#include "slang_rs_backend.h" 26#include "slang_rs_context.h" 27 28using namespace slang; 29 30#define RS_HEADER_SUFFIX "rsh" 31 32#define ENUM_RS_HEADER() \ 33 RS_HEADER_ENTRY(rs_types) \ 34 RS_HEADER_ENTRY(rs_cl) \ 35 RS_HEADER_ENTRY(rs_core) \ 36 RS_HEADER_ENTRY(rs_math) 37 38#define RS_HEADER_ENTRY(x) \ 39 extern const char x ## _header[]; \ 40 extern unsigned x ## _header_size; 41ENUM_RS_HEADER() 42#undef RS_HEADER_ENTRY 43 44bool SlangRS::reflectToJava(const std::string &OutputPathBase, 45 const std::string &OutputPackageName, 46 std::string *RealPackageName) { 47 return mRSContext->reflectToJava(OutputPathBase, 48 OutputPackageName, 49 getInputFileName(), 50 getOutputFileName(), 51 RealPackageName); 52} 53 54bool SlangRS::generateBitcodeAccessor(const std::string &OutputPathBase, 55 const std::string &PackageName) { 56 RSSlangReflectUtils::BitCodeAccessorContext BCAccessorContext; 57 58 BCAccessorContext.rsFileName = getInputFileName().c_str(); 59 BCAccessorContext.bcFileName = getOutputFileName().c_str(); 60 BCAccessorContext.reflectPath = OutputPathBase.c_str(); 61 BCAccessorContext.packageName = PackageName.c_str(); 62 BCAccessorContext.bcStorage = BCST_JAVA_CODE; // Must be BCST_JAVA_CODE 63 64 return RSSlangReflectUtils::GenerateBitCodeAccessor(BCAccessorContext); 65} 66 67 68void SlangRS::initDiagnostic() { 69 clang::Diagnostic &Diag = getDiagnostics(); 70 if (Diag.setDiagnosticGroupMapping("implicit-function-declaration", 71 clang::diag::MAP_ERROR)) 72 Diag.Report(clang::diag::warn_unknown_warning_option) 73 << "implicit-function-declaration"; 74 75 Diag.setDiagnosticMapping( 76 clang::diag::ext_typecheck_convert_discards_qualifiers, 77 clang::diag::MAP_ERROR); 78 return; 79} 80 81void SlangRS::initPreprocessor() { 82 clang::Preprocessor &PP = getPreprocessor(); 83 84 std::string RSH; 85#define RS_HEADER_ENTRY(x) \ 86 RSH.append("#line 1 \"" #x "."RS_HEADER_SUFFIX"\"\n"); \ 87 RSH.append(x ## _header, x ## _header_size); 88ENUM_RS_HEADER() 89#undef RS_HEADER_ENTRY 90 PP.setPredefines(RSH); 91 92 return; 93} 94 95void SlangRS::initASTContext() { 96 mRSContext = new RSContext(&getPreprocessor(), 97 &getASTContext(), 98 &getTargetInfo()); 99 return; 100} 101 102clang::ASTConsumer 103*SlangRS::createBackend(const clang::CodeGenOptions& CodeGenOpts, 104 llvm::raw_ostream *OS, 105 Slang::OutputType OT) { 106 return new RSBackend(mRSContext, 107 getDiagnostics(), 108 CodeGenOpts, 109 getTargetOptions(), 110 mPragmas, 111 OS, 112 OT, 113 getSourceManager(), 114 mAllowRSPrefix); 115} 116 117bool SlangRS::IsRSHeaderFile(const char *File) { 118#define RS_HEADER_ENTRY(x) \ 119 if (::strcmp(File, #x "."RS_HEADER_SUFFIX) == 0) \ 120 return true; 121ENUM_RS_HEADER() 122#undef RS_HEADER_ENTRY 123 // Deal with rs_graphics.rsh special case 124 if (::strcmp(File, "rs_graphics."RS_HEADER_SUFFIX) == 0) 125 return true; 126 return false; 127} 128 129SlangRS::SlangRS(const std::string &Triple, const std::string &CPU, 130 const std::vector<std::string> &Features) 131 : Slang(Triple, CPU, Features), 132 mRSContext(NULL), 133 mAllowRSPrefix(false) { 134 return; 135} 136 137bool SlangRS::compile( 138 const std::list<std::pair<const char*, const char*> > &IOFiles, 139 const std::list<std::pair<const char*, const char*> > &DepFiles, 140 const std::vector<std::string> &IncludePaths, 141 const std::vector<std::string> &AdditionalDepTargets, 142 Slang::OutputType OutputType, BitCodeStorageType BitcodeStorage, 143 bool AllowRSPrefix, bool OutputDep, 144 const std::string &JavaReflectionPathBase, 145 const std::string &JavaReflectionPackageName) { 146 if (IOFiles.empty()) 147 return true; 148 149 if (OutputDep && (DepFiles.size() != IOFiles.size())) { 150 fprintf(stderr, "SlangRS::compile() : Invalid parameter for output " 151 "dependencies files.\n"); 152 return false; 153 } 154 155 std::string RealPackageName; 156 157 const char *InputFile, *OutputFile, *BCOutputFile, *DepOutputFile; 158 std::list<std::pair<const char*, const char*> >::const_iterator 159 IOFileIter = IOFiles.begin(), DepFileIter = DepFiles.begin(); 160 161 setIncludePaths(IncludePaths); 162 setOutputType(OutputType); 163 if (OutputDep) 164 setAdditionalDepTargets(AdditionalDepTargets); 165 166 mAllowRSPrefix = AllowRSPrefix; 167 168 for (unsigned i = 0, e = IOFiles.size(); i != e; i++) { 169 InputFile = IOFileIter->first; 170 OutputFile = IOFileIter->second; 171 172 reset(); 173 174 if (!setInputSource(InputFile)) 175 return false; 176 177 if (!setOutput(OutputFile)) 178 return false; 179 180 if (OutputDep) { 181 BCOutputFile = DepFileIter->first; 182 DepOutputFile = DepFileIter->second; 183 184 setDepTargetBC(BCOutputFile); 185 186 if (!setDepOutput(DepOutputFile)) 187 return false; 188 189 if (generateDepFile() > 0) 190 return false; 191 192 DepFileIter++; 193 } 194 195 if (Slang::compile() > 0) 196 return false; 197 198 if (OutputType != Slang::OT_Dependency) { 199 if (!reflectToJava(JavaReflectionPathBase, 200 JavaReflectionPackageName, 201 &RealPackageName)) 202 return false; 203 204 if ((OutputType == Slang::OT_Bitcode) && 205 (BitcodeStorage == BCST_JAVA_CODE) && 206 !generateBitcodeAccessor(JavaReflectionPathBase, 207 RealPackageName.c_str())) 208 return false; 209 } 210 211 IOFileIter++; 212 } 213 214 return true; 215} 216 217SlangRS::~SlangRS() { 218 delete mRSContext; 219 return; 220} 221