14b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines/* 24b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * Copyright 2010, The Android Open Source Project 34b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * 44b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * Licensed under the Apache License, Version 2.0 (the "License"); 54b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * you may not use this file except in compliance with the License. 64b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * You may obtain a copy of the License at 74b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * 84b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * http://www.apache.org/licenses/LICENSE-2.0 94b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * 104b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * Unless required by applicable law or agreed to in writing, software 114b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * distributed under the License is distributed on an "AS IS" BASIS, 124b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * See the License for the specific language governing permissions and 144b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * limitations under the License. 154b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines */ 164b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 17e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_OBJECT_REF_COUNT_H_ // NOLINT 18e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_OBJECT_REF_COUNT_H_ 19e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 20e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <list> 214b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include <stack> 224b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 234b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "clang/AST/StmtVisitor.h" 244b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 25f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines#include "slang_assert.h" 264b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "slang_rs_export_type.h" 274b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 284b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesnamespace clang { 294b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines class Expr; 30d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines class Stmt; 314b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 324b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 33e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang { 34e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 35292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines// This class provides the overall reference counting mechanism for handling 36292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines// local variables of RS object types (rs_font, rs_allocation, ...). This 37292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines// class ensures that appropriate functions (rsSetObject, rsClearObject) are 38292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines// called at proper points in the object's lifetime. 39292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines// 1) Each local object of appropriate type must be zero-initialized (to 40292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines// prevent corruption) during subsequent rsSetObject()/rsClearObject() calls. 41292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines// 2) Assignments using these types must also be converted into the 42292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines// appropriate (possibly a series of) rsSetObject() calls. 43292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines// 3) Finally, each local object must call rsClearObject() when it goes out 44292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines// of scope. 454b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesclass RSObjectRefCount : public clang::StmtVisitor<RSObjectRefCount> { 464b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines private: 474b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines class Scope { 484b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines private: 494b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::CompoundStmt *mCS; // Associated compound statement ({ ... }) 501bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines std::list<clang::VarDecl*> mRSO; // Declared RS objects in this scope 511bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 524b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines public: 53e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines explicit Scope(clang::CompoundStmt *CS) : mCS(CS) { 544b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 554b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 561bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines inline void addRSObject(clang::VarDecl* VD) { 571bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines mRSO.push_back(VD); 584b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 591bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 60d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines void ReplaceRSObjectAssignment(clang::BinaryOperator *AS); 61c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 62d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines void AppendRSObjectInit(clang::VarDecl *VD, 63e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclStmt *DS, 64cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT, 65e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *InitExpr); 66e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 671bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines void InsertLocalVarDestructors(); 681bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 693f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines static clang::Stmt *ClearRSObject(clang::VarDecl *VD, 703f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines clang::DeclContext *DC); 714b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines }; 724b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 73d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines clang::ASTContext &mCtx; 744b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines std::stack<Scope*> mScopeStack; 751bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines bool RSInitFD; 764b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 77f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // RSSetObjectFD and RSClearObjectFD holds FunctionDecl of rsSetObject() 78f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // and rsClearObject() in the current ASTContext. 79f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines static clang::FunctionDecl *RSSetObjectFD[]; 80f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines static clang::FunctionDecl *RSClearObjectFD[]; 81f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 824b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines inline Scope *getCurrentScope() { 834b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return mScopeStack.top(); 844b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 854b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 86f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Initialize RSSetObjectFD and RSClearObjectFD. 87f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines static void GetRSRefCountingFunctions(clang::ASTContext &C); 88f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 89f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Return false if the type of variable declared in VD does not contain 90f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // an RS object type. 91e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines static bool InitializeRSObject(clang::VarDecl *VD, 92cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType *DT, 93e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr **InitExpr); 944b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 954b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Return a zero-initializer expr of the type DT. This processes both 964b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // RS matrix type and RS object type. 974b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines static clang::Expr *CreateZeroInitializerForRSSpecificType( 98cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT, 994b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ASTContext &C, 1004b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines const clang::SourceLocation &Loc); 1014b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1024b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines public: 103d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines explicit RSObjectRefCount(clang::ASTContext &C) 104d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines : mCtx(C), 105d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines RSInitFD(false) { 1061bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1071bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 108d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines void Init() { 1091bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if (!RSInitFD) { 110d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines GetRSRefCountingFunctions(mCtx); 1111bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSInitFD = true; 1121bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1131bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1141bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 115cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet static clang::FunctionDecl *GetRSSetObjectFD(DataType DT) { 116f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(RSExportPrimitiveType::IsRSObjectType(DT)); 117cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet if (DT >= 0 && DT < DataTypeMax) { 118474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return RSSetObjectFD[DT]; 119474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet } else { 120474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet slangAssert(false && "incorrect type"); 1215abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 122474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet } 123f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 124f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 125f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines static clang::FunctionDecl *GetRSSetObjectFD(const clang::Type *T) { 126f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return GetRSSetObjectFD(RSExportPrimitiveType::GetRSSpecificType(T)); 127f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 128f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 129cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet static clang::FunctionDecl *GetRSClearObjectFD(DataType DT) { 130f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(RSExportPrimitiveType::IsRSObjectType(DT)); 131cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet if (DT >= 0 && DT < DataTypeMax) { 132474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet return RSClearObjectFD[DT]; 133474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet } else { 134474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet slangAssert(false && "incorrect type"); 1355abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 136474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet } 137f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 138f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 139f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines static clang::FunctionDecl *GetRSClearObjectFD(const clang::Type *T) { 140f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return GetRSClearObjectFD(RSExportPrimitiveType::GetRSSpecificType(T)); 141f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 142f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 1434b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines void VisitStmt(clang::Stmt *S); 1444b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines void VisitDeclStmt(clang::DeclStmt *DS); 1454b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines void VisitCompoundStmt(clang::CompoundStmt *CS); 1464b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines void VisitBinAssign(clang::BinaryOperator *AS); 1474b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // We believe that RS objects are never involved in CompoundAssignOperator. 1484b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // I.e., rs_allocation foo; foo += bar; 149688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 150688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines // Emit a global destructor to clean up RS objects. 151688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines clang::FunctionDecl *CreateStaticGlobalDtor(); 1524b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines}; 1534b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 154e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 155e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 156e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_OBJECT_REF_COUNT_H_ NOLINT 157