slang_rs_context.h revision 40bac5d72af8fe32ab3d0bb38aafb5c65d8d9dfa
1/* 2 * Copyright 2010-2012, 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_RS_CONTEXT_H_ // NOLINT 18#define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_CONTEXT_H_ 19 20#include <cstdio> 21#include <list> 22#include <map> 23#include <set> 24#include <string> 25#include <unordered_set> 26#include <vector> 27 28#include "clang/Lex/Preprocessor.h" 29#include "clang/AST/Mangle.h" 30 31#include "llvm/ADT/StringSet.h" 32#include "llvm/ADT/StringMap.h" 33 34#include "slang_pragma_list.h" 35 36namespace llvm { 37 class LLVMContext; 38 class DataLayout; 39} // namespace llvm 40 41namespace clang { 42 class VarDecl; 43 class ASTContext; 44 class TargetInfo; 45 class FunctionDecl; 46 class QualType; 47 class SourceManager; 48 class TypeDecl; 49 class FunctionDecl; 50} // namespace clang 51 52namespace slang { 53 class Backend; 54 class RSExportable; 55 class RSExportVar; 56 class RSExportFunc; 57 class RSExportForEach; 58 class RSExportReduce; 59 class RSExportReduceNew; 60 class RSExportType; 61 62class RSContext { 63 typedef llvm::StringSet<> NeedExportVarSet; 64 typedef llvm::StringSet<> NeedExportFuncSet; 65 typedef llvm::StringSet<> NeedExportTypeSet; 66 67 public: 68 typedef std::list<RSExportable*> ExportableList; 69 typedef std::list<RSExportVar*> ExportVarList; 70 typedef std::list<RSExportFunc*> ExportFuncList; 71 typedef std::vector<RSExportForEach*> ExportForEachVector; 72 typedef std::list<RSExportReduce*> ExportReduceList; 73 typedef std::list<RSExportReduceNew*> ExportReduceNewList; 74 75 // WARNING: Sorted by pointer value, resulting in unpredictable order 76 typedef std::unordered_set<RSExportType*> ExportReduceNewResultTypeSet; 77 78 typedef llvm::StringMap<RSExportType*> ExportTypeMap; 79 80 private: 81 clang::Preprocessor &mPP; 82 clang::ASTContext &mCtx; 83 PragmaList *mPragmas; 84 // Precision specified via pragma, either rs_fp_full or rs_fp_relaxed. If 85 // empty, rs_fp_full is assumed. 86 std::string mPrecision; 87 unsigned int mTargetAPI; 88 bool mVerbose; 89 90 llvm::DataLayout *mDataLayout; 91 llvm::LLVMContext &mLLVMContext; 92 93 ExportableList mExportables; 94 95 NeedExportTypeSet mNeedExportTypes; 96 97 std::string *mLicenseNote; 98 std::string mReflectJavaPackageName; 99 std::string mReflectJavaPathName; 100 101 std::string mRSPackageName; 102 103 int version; 104 105 std::unique_ptr<clang::MangleContext> mMangleCtx; 106 107 bool mIs64Bit; 108 109 bool processExportVar(const clang::VarDecl *VD); 110 bool processExportFunc(const clang::FunctionDecl *FD); 111 bool processExportType(const llvm::StringRef &Name); 112 113 int getForEachSlotNumber(const clang::StringRef& funcName); 114 unsigned mNextSlot; 115 116 ExportVarList mExportVars; 117 ExportFuncList mExportFuncs; 118 std::map<llvm::StringRef, unsigned> mExportForEachMap; 119 ExportForEachVector mExportForEach; 120 ExportForEachVector::iterator mFirstOldStyleKernel; 121 ExportReduceList mExportReduce; 122 ExportReduceNewList mExportReduceNew; 123 ExportReduceNewResultTypeSet mExportReduceNewResultType; 124 ExportTypeMap mExportTypes; 125 126 clang::QualType mAllocationType; 127 clang::QualType mScriptCallType; 128 129 std::set<const clang::FunctionDecl *> mUsedByReducePragmaFns; 130 131 // Populated by markUsedByReducePragma(). 132 // Consumed by processReducePragmas(). 133 std::vector<clang::VarDecl *> mUsedByReducePragmaDummyVars; 134 135 public: 136 RSContext(clang::Preprocessor &PP, 137 clang::ASTContext &Ctx, 138 const clang::TargetInfo &Target, 139 PragmaList *Pragmas, 140 unsigned int TargetAPI, 141 bool Verbose); 142 143 enum CheckName { CheckNameNo, CheckNameYes }; 144 145 static bool isSyntheticName(const llvm::StringRef Name) { return Name.startswith(".rs."); } 146 147 inline clang::Preprocessor &getPreprocessor() const { return mPP; } 148 inline clang::ASTContext &getASTContext() const { return mCtx; } 149 inline clang::MangleContext &getMangleContext() const { 150 return *mMangleCtx; 151 } 152 inline const llvm::DataLayout *getDataLayout() const { return mDataLayout; } 153 inline llvm::LLVMContext &getLLVMContext() const { return mLLVMContext; } 154 inline const clang::SourceManager *getSourceManager() const { 155 return &mPP.getSourceManager(); 156 } 157 inline clang::DiagnosticsEngine *getDiagnostics() const { 158 return &mPP.getDiagnostics(); 159 } 160 inline unsigned int getTargetAPI() const { 161 return mTargetAPI; 162 } 163 164 inline bool getVerbose() const { 165 return mVerbose; 166 } 167 inline bool is64Bit() const { 168 return mIs64Bit; 169 } 170 171 inline void setLicenseNote(const std::string &S) { 172 mLicenseNote = new std::string(S); 173 } 174 inline const std::string *getLicenseNote() const { return mLicenseNote; } 175 176 inline void addExportType(const std::string &S) { 177 mNeedExportTypes.insert(S); 178 } 179 180 inline void setReflectJavaPackageName(const std::string &S) { 181 mReflectJavaPackageName = S; 182 } 183 inline const std::string &getReflectJavaPackageName() const { 184 return mReflectJavaPackageName; 185 } 186 187 inline void setRSPackageName(const std::string &S) { 188 mRSPackageName = S; 189 } 190 191 inline const std::string &getRSPackageName() const { return mRSPackageName; } 192 193 void setAllocationType(const clang::TypeDecl* TD); 194 inline const clang::QualType& getAllocationType() const { 195 return mAllocationType; 196 } 197 198 void setScriptCallType(const clang::TypeDecl* TD); 199 inline const clang::QualType& getScriptCallType() const { 200 return mScriptCallType; 201 } 202 203 bool addForEach(const clang::FunctionDecl* FD); 204 bool processExports(); 205 inline void newExportable(RSExportable *E) { 206 if (E != nullptr) 207 mExportables.push_back(E); 208 } 209 typedef ExportableList::iterator exportable_iterator; 210 exportable_iterator exportable_begin() { 211 return mExportables.begin(); 212 } 213 exportable_iterator exportable_end() { 214 return mExportables.end(); 215 } 216 217 typedef ExportVarList::const_iterator const_export_var_iterator; 218 const_export_var_iterator export_vars_begin() const { 219 return mExportVars.begin(); 220 } 221 const_export_var_iterator export_vars_end() const { 222 return mExportVars.end(); 223 } 224 inline bool hasExportVar() const { 225 return !mExportVars.empty(); 226 } 227 228 typedef ExportFuncList::const_iterator const_export_func_iterator; 229 const_export_func_iterator export_funcs_begin() const { 230 return mExportFuncs.begin(); 231 } 232 const_export_func_iterator export_funcs_end() const { 233 return mExportFuncs.end(); 234 } 235 inline bool hasExportFunc() const { return !mExportFuncs.empty(); } 236 237 typedef ExportForEachVector::const_iterator const_export_foreach_iterator; 238 const_export_foreach_iterator export_foreach_begin() const { 239 return mExportForEach.begin(); 240 } 241 const_export_foreach_iterator export_foreach_end() const { 242 return mExportForEach.end(); 243 } 244 inline bool hasExportForEach() const { return !mExportForEach.empty(); } 245 int getForEachSlotNumber(const clang::FunctionDecl* FD); 246 247 typedef ExportReduceList::const_iterator const_export_reduce_iterator; 248 const_export_reduce_iterator export_reduce_begin() const { 249 return mExportReduce.begin(); 250 } 251 const_export_reduce_iterator export_reduce_end() const { 252 return mExportReduce.end(); 253 } 254 inline bool hasExportReduce() const { return !mExportReduce.empty(); } 255 256 typedef ExportReduceNewList::const_iterator const_export_reduce_new_iterator; 257 const_export_reduce_new_iterator export_reduce_new_begin() const { 258 return mExportReduceNew.begin(); 259 } 260 const_export_reduce_new_iterator export_reduce_new_end() const { 261 return mExportReduceNew.end(); 262 } 263 inline bool hasExportReduceNew() const { return !mExportReduceNew.empty(); } 264 void addExportReduceNew(RSExportReduceNew *ReduceNew) { 265 mExportReduceNew.push_back(ReduceNew); 266 } 267 bool processReducePragmas(Backend *BE); 268 void markUsedByReducePragma(clang::FunctionDecl *FD, CheckName Check); 269 270 // If the type has already been inserted, has no effect. 271 void insertExportReduceNewResultType(RSExportType *Type) { mExportReduceNewResultType.insert(Type); } 272 273 template <class FilterIn, class Compare> 274 std::vector<RSExportType *> getReduceNewResultTypes(FilterIn Filt, Compare Comp) const { 275 std::vector<RSExportType *> Return; 276 std::copy_if(mExportReduceNewResultType.begin(), mExportReduceNewResultType.end(), std::back_inserter(Return), Filt); 277 std::sort(Return.begin(), Return.end(), Comp); 278 auto ReturnNewEndIter = std::unique(Return.begin(), Return.end(), 279 [Comp](const RSExportType *a, const RSExportType *b) { 280 return !Comp(a, b) && !Comp(b, a); 281 }); 282 Return.erase(ReturnNewEndIter, Return.end()); 283 return Return; 284 } 285 286 typedef ExportTypeMap::iterator export_type_iterator; 287 typedef ExportTypeMap::const_iterator const_export_type_iterator; 288 export_type_iterator export_types_begin() { return mExportTypes.begin(); } 289 export_type_iterator export_types_end() { return mExportTypes.end(); } 290 const_export_type_iterator export_types_begin() const { 291 return mExportTypes.begin(); 292 } 293 const_export_type_iterator export_types_end() const { 294 return mExportTypes.end(); 295 } 296 inline bool hasExportType() const { return !mExportTypes.empty(); } 297 export_type_iterator findExportType(const llvm::StringRef &TypeName) { 298 return mExportTypes.find(TypeName); 299 } 300 const_export_type_iterator findExportType(const llvm::StringRef &TypeName) 301 const { 302 return mExportTypes.find(TypeName); 303 } 304 305 // Insert the specified Typename/Type pair into the map. If the key already 306 // exists in the map, return false and ignore the request, otherwise insert it 307 // and return true. 308 bool insertExportType(const llvm::StringRef &TypeName, RSExportType *Type); 309 310 int getVersion() const { return version; } 311 void setVersion(int v) { 312 version = v; 313 } 314 315 bool isCompatLib() const { 316 // If we are not targeting the actual Android Renderscript classes, 317 // we should reflect code that works with the compatibility library. 318 return (mRSPackageName.compare("android.renderscript") != 0); 319 } 320 321 void addPragma(const std::string &T, const std::string &V) { 322 mPragmas->push_back(make_pair(T, V)); 323 } 324 void setPrecision(const std::string &P) { mPrecision = P; } 325 std::string getPrecision() { return mPrecision; } 326 327 // Report an error or a warning to the user. 328 template <unsigned N> 329 clang::DiagnosticBuilder Report(clang::DiagnosticsEngine::Level Level, 330 const char (&Message)[N]) { 331 clang::DiagnosticsEngine *DiagEngine = getDiagnostics(); 332 return DiagEngine->Report(DiagEngine->getCustomDiagID(Level, Message)); 333 } 334 335 template <unsigned N> 336 clang::DiagnosticBuilder Report(clang::DiagnosticsEngine::Level Level, 337 const clang::SourceLocation Loc, 338 const char (&Message)[N]) { 339 clang::DiagnosticsEngine *DiagEngine = getDiagnostics(); 340 const clang::SourceManager *SM = getSourceManager(); 341 return DiagEngine->Report(clang::FullSourceLoc(Loc, *SM), 342 DiagEngine->getCustomDiagID(Level, Message)); 343 } 344 345 // Utility functions to report errors and warnings to make the calling code 346 // easier to read. 347 template <unsigned N> 348 clang::DiagnosticBuilder ReportError(const char (&Message)[N]) { 349 return Report<N>(clang::DiagnosticsEngine::Error, Message); 350 } 351 352 template <unsigned N> 353 clang::DiagnosticBuilder ReportError(const clang::SourceLocation Loc, 354 const char (&Message)[N]) { 355 return Report<N>(clang::DiagnosticsEngine::Error, Loc, Message); 356 } 357 358 template <unsigned N> 359 clang::DiagnosticBuilder ReportWarning(const char (&Message)[N]) { 360 return Report<N>(clang::DiagnosticsEngine::Warning, Message); 361 } 362 363 template <unsigned N> 364 clang::DiagnosticBuilder ReportWarning(const clang::SourceLocation Loc, 365 const char (&Message)[N]) { 366 return Report<N>(clang::DiagnosticsEngine::Warning, Loc, Message); 367 } 368 369 ~RSContext(); 370}; 371 372} // namespace slang 373 374#endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_CONTEXT_H_ NOLINT 375