slang_rs_context.h revision 5e306b944425a952fe744f59d828538137a59375
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 ExportReduceList mExportReduce; 121 ExportReduceNewList mExportReduceNew; 122 ExportReduceNewResultTypeSet mExportReduceNewResultType; 123 ExportTypeMap mExportTypes; 124 125 clang::QualType mAllocationType; 126 clang::QualType mScriptCallType; 127 128 std::set<const clang::FunctionDecl *> mUsedByReducePragmaFns; 129 130 // Populated by markUsedByReducePragma(). 131 // Consumed by processReducePragmas(). 132 std::vector<clang::VarDecl *> mUsedByReducePragmaDummyVars; 133 134 public: 135 RSContext(clang::Preprocessor &PP, 136 clang::ASTContext &Ctx, 137 const clang::TargetInfo &Target, 138 PragmaList *Pragmas, 139 unsigned int TargetAPI, 140 bool Verbose); 141 142 enum CheckName { CheckNameNo, CheckNameYes }; 143 144 static bool isSyntheticName(const llvm::StringRef Name) { return Name.startswith(".rs."); } 145 146 inline clang::Preprocessor &getPreprocessor() const { return mPP; } 147 inline clang::ASTContext &getASTContext() const { return mCtx; } 148 inline clang::MangleContext &getMangleContext() const { 149 return *mMangleCtx; 150 } 151 inline const llvm::DataLayout *getDataLayout() const { return mDataLayout; } 152 inline llvm::LLVMContext &getLLVMContext() const { return mLLVMContext; } 153 inline const clang::SourceManager *getSourceManager() const { 154 return &mPP.getSourceManager(); 155 } 156 inline clang::DiagnosticsEngine *getDiagnostics() const { 157 return &mPP.getDiagnostics(); 158 } 159 inline unsigned int getTargetAPI() const { 160 return mTargetAPI; 161 } 162 163 inline bool getVerbose() const { 164 return mVerbose; 165 } 166 inline bool is64Bit() const { 167 return mIs64Bit; 168 } 169 170 inline void setLicenseNote(const std::string &S) { 171 mLicenseNote = new std::string(S); 172 } 173 inline const std::string *getLicenseNote() const { return mLicenseNote; } 174 175 inline void addExportType(const std::string &S) { 176 mNeedExportTypes.insert(S); 177 } 178 179 inline void setReflectJavaPackageName(const std::string &S) { 180 mReflectJavaPackageName = S; 181 } 182 inline const std::string &getReflectJavaPackageName() const { 183 return mReflectJavaPackageName; 184 } 185 186 inline void setRSPackageName(const std::string &S) { 187 mRSPackageName = S; 188 } 189 190 inline const std::string &getRSPackageName() const { return mRSPackageName; } 191 192 void setAllocationType(const clang::TypeDecl* TD); 193 inline const clang::QualType& getAllocationType() const { 194 return mAllocationType; 195 } 196 197 void setScriptCallType(const clang::TypeDecl* TD); 198 inline const clang::QualType& getScriptCallType() const { 199 return mScriptCallType; 200 } 201 202 bool addForEach(const clang::FunctionDecl* FD); 203 bool processExports(); 204 inline void newExportable(RSExportable *E) { 205 if (E != nullptr) 206 mExportables.push_back(E); 207 } 208 typedef ExportableList::iterator exportable_iterator; 209 exportable_iterator exportable_begin() { 210 return mExportables.begin(); 211 } 212 exportable_iterator exportable_end() { 213 return mExportables.end(); 214 } 215 216 typedef ExportVarList::const_iterator const_export_var_iterator; 217 const_export_var_iterator export_vars_begin() const { 218 return mExportVars.begin(); 219 } 220 const_export_var_iterator export_vars_end() const { 221 return mExportVars.end(); 222 } 223 inline bool hasExportVar() const { 224 return !mExportVars.empty(); 225 } 226 227 typedef ExportFuncList::const_iterator const_export_func_iterator; 228 const_export_func_iterator export_funcs_begin() const { 229 return mExportFuncs.begin(); 230 } 231 const_export_func_iterator export_funcs_end() const { 232 return mExportFuncs.end(); 233 } 234 inline bool hasExportFunc() const { return !mExportFuncs.empty(); } 235 236 typedef ExportForEachVector::const_iterator const_export_foreach_iterator; 237 const_export_foreach_iterator export_foreach_begin() const { 238 return mExportForEach.begin(); 239 } 240 const_export_foreach_iterator export_foreach_end() const { 241 return mExportForEach.end(); 242 } 243 inline bool hasExportForEach() const { return !mExportForEach.empty(); } 244 int getForEachSlotNumber(const clang::FunctionDecl* FD); 245 246 typedef ExportReduceList::const_iterator const_export_reduce_iterator; 247 const_export_reduce_iterator export_reduce_begin() const { 248 return mExportReduce.begin(); 249 } 250 const_export_reduce_iterator export_reduce_end() const { 251 return mExportReduce.end(); 252 } 253 inline bool hasExportReduce() const { return !mExportReduce.empty(); } 254 255 typedef ExportReduceNewList::const_iterator const_export_reduce_new_iterator; 256 const_export_reduce_new_iterator export_reduce_new_begin() const { 257 return mExportReduceNew.begin(); 258 } 259 const_export_reduce_new_iterator export_reduce_new_end() const { 260 return mExportReduceNew.end(); 261 } 262 inline bool hasExportReduceNew() const { return !mExportReduceNew.empty(); } 263 void addExportReduceNew(RSExportReduceNew *ReduceNew) { 264 mExportReduceNew.push_back(ReduceNew); 265 } 266 bool processReducePragmas(Backend *BE); 267 void markUsedByReducePragma(clang::FunctionDecl *FD, CheckName Check); 268 269 // If the type has already been inserted, has no effect. 270 void insertExportReduceNewResultType(RSExportType *Type) { mExportReduceNewResultType.insert(Type); } 271 272 template <class FilterIn, class Compare> 273 std::vector<RSExportType *> getReduceNewResultTypes(FilterIn Filt, Compare Comp) const { 274 std::vector<RSExportType *> Return; 275 std::copy_if(mExportReduceNewResultType.begin(), mExportReduceNewResultType.end(), std::back_inserter(Return), Filt); 276 std::sort(Return.begin(), Return.end(), Comp); 277 return Return; 278 } 279 280 typedef ExportTypeMap::iterator export_type_iterator; 281 typedef ExportTypeMap::const_iterator const_export_type_iterator; 282 export_type_iterator export_types_begin() { return mExportTypes.begin(); } 283 export_type_iterator export_types_end() { return mExportTypes.end(); } 284 const_export_type_iterator export_types_begin() const { 285 return mExportTypes.begin(); 286 } 287 const_export_type_iterator export_types_end() const { 288 return mExportTypes.end(); 289 } 290 inline bool hasExportType() const { return !mExportTypes.empty(); } 291 export_type_iterator findExportType(const llvm::StringRef &TypeName) { 292 return mExportTypes.find(TypeName); 293 } 294 const_export_type_iterator findExportType(const llvm::StringRef &TypeName) 295 const { 296 return mExportTypes.find(TypeName); 297 } 298 299 // Insert the specified Typename/Type pair into the map. If the key already 300 // exists in the map, return false and ignore the request, otherwise insert it 301 // and return true. 302 bool insertExportType(const llvm::StringRef &TypeName, RSExportType *Type); 303 304 int getVersion() const { return version; } 305 void setVersion(int v) { 306 version = v; 307 } 308 309 bool isCompatLib() const { 310 // If we are not targeting the actual Android Renderscript classes, 311 // we should reflect code that works with the compatibility library. 312 return (mRSPackageName.compare("android.renderscript") != 0); 313 } 314 315 void addPragma(const std::string &T, const std::string &V) { 316 mPragmas->push_back(make_pair(T, V)); 317 } 318 void setPrecision(const std::string &P) { mPrecision = P; } 319 std::string getPrecision() { return mPrecision; } 320 321 // Report an error or a warning to the user. 322 template <unsigned N> 323 clang::DiagnosticBuilder Report(clang::DiagnosticsEngine::Level Level, 324 const char (&Message)[N]) { 325 clang::DiagnosticsEngine *DiagEngine = getDiagnostics(); 326 return DiagEngine->Report(DiagEngine->getCustomDiagID(Level, Message)); 327 } 328 329 template <unsigned N> 330 clang::DiagnosticBuilder Report(clang::DiagnosticsEngine::Level Level, 331 const clang::SourceLocation Loc, 332 const char (&Message)[N]) { 333 clang::DiagnosticsEngine *DiagEngine = getDiagnostics(); 334 const clang::SourceManager *SM = getSourceManager(); 335 return DiagEngine->Report(clang::FullSourceLoc(Loc, *SM), 336 DiagEngine->getCustomDiagID(Level, Message)); 337 } 338 339 // Utility functions to report errors and warnings to make the calling code 340 // easier to read. 341 template <unsigned N> 342 clang::DiagnosticBuilder ReportError(const char (&Message)[N]) { 343 return Report<N>(clang::DiagnosticsEngine::Error, Message); 344 } 345 346 template <unsigned N> 347 clang::DiagnosticBuilder ReportError(const clang::SourceLocation Loc, 348 const char (&Message)[N]) { 349 return Report<N>(clang::DiagnosticsEngine::Error, Loc, Message); 350 } 351 352 template <unsigned N> 353 clang::DiagnosticBuilder ReportWarning(const char (&Message)[N]) { 354 return Report<N>(clang::DiagnosticsEngine::Warning, Message); 355 } 356 357 template <unsigned N> 358 clang::DiagnosticBuilder ReportWarning(const clang::SourceLocation Loc, 359 const char (&Message)[N]) { 360 return Report<N>(clang::DiagnosticsEngine::Warning, Loc, Message); 361 } 362 363 ~RSContext(); 364}; 365 366} // namespace slang 367 368#endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_CONTEXT_H_ NOLINT 369