slang_rs_object_ref_count.h revision 292e00a0259ac28cac1055cb6077cf6fc7c6743c
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 return; 554b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 564b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 571bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines inline void addRSObject(clang::VarDecl* VD) { 581bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines mRSO.push_back(VD); 594b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 604b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 611bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 622bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines void ReplaceRSObjectAssignment(clang::BinaryOperator *AS, 632bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Diagnostic *Diags); 64c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 65a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines void AppendRSObjectInit(clang::Diagnostic *Diags, 66a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::VarDecl *VD, 67e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclStmt *DS, 68e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataType DT, 69e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *InitExpr); 70e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 711bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines void InsertLocalVarDestructors(); 721bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 73d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines static clang::Stmt *ClearRSObject(clang::VarDecl *VD); 744b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines }; 754b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 764b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines std::stack<Scope*> mScopeStack; 771bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines bool RSInitFD; 782bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Diagnostic *mDiags; 794b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 80f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // RSSetObjectFD and RSClearObjectFD holds FunctionDecl of rsSetObject() 81f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // and rsClearObject() in the current ASTContext. 82f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines static clang::FunctionDecl *RSSetObjectFD[]; 83f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines static clang::FunctionDecl *RSClearObjectFD[]; 84f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 854b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines inline Scope *getCurrentScope() { 864b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return mScopeStack.top(); 874b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 884b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 89f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Initialize RSSetObjectFD and RSClearObjectFD. 90f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines static void GetRSRefCountingFunctions(clang::ASTContext &C); 91f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 92f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Return false if the type of variable declared in VD does not contain 93f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // an RS object type. 94e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines static bool InitializeRSObject(clang::VarDecl *VD, 95e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataType *DT, 96e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr **InitExpr); 974b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 984b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Return a zero-initializer expr of the type DT. This processes both 994b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // RS matrix type and RS object type. 1004b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines static clang::Expr *CreateZeroInitializerForRSSpecificType( 1014b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines RSExportPrimitiveType::DataType DT, 1024b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ASTContext &C, 1034b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines const clang::SourceLocation &Loc); 1044b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1054b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines public: 1061bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSObjectRefCount() 1071bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines : RSInitFD(false) { 1081bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines return; 1091bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1101bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1112bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines void Init(clang::ASTContext &C, clang::Diagnostic *Diags) { 1121bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if (!RSInitFD) { 113f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines GetRSRefCountingFunctions(C); 1142bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines mDiags = Diags; 1151bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSInitFD = true; 1161bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1171bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines return; 1181bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1191bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 120f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines static clang::FunctionDecl *GetRSSetObjectFD( 121f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::DataType DT) { 122f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(RSExportPrimitiveType::IsRSObjectType(DT)); 123f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return RSSetObjectFD[(DT - RSExportPrimitiveType::FirstRSObjectType)]; 124f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 125f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 126f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines static clang::FunctionDecl *GetRSSetObjectFD(const clang::Type *T) { 127f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return GetRSSetObjectFD(RSExportPrimitiveType::GetRSSpecificType(T)); 128f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 129f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 130f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines static clang::FunctionDecl *GetRSClearObjectFD( 131f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::DataType DT) { 132f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(RSExportPrimitiveType::IsRSObjectType(DT)); 133f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return RSClearObjectFD[(DT - RSExportPrimitiveType::FirstRSObjectType)]; 134f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 135f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 136f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines static clang::FunctionDecl *GetRSClearObjectFD(const clang::Type *T) { 137f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return GetRSClearObjectFD(RSExportPrimitiveType::GetRSSpecificType(T)); 138f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 139f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 1404b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines void VisitStmt(clang::Stmt *S); 1414b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines void VisitDeclStmt(clang::DeclStmt *DS); 1424b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines void VisitCompoundStmt(clang::CompoundStmt *CS); 1434b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines void VisitBinAssign(clang::BinaryOperator *AS); 1444b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1454b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // We believe that RS objects are never involved in CompoundAssignOperator. 1464b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // I.e., rs_allocation foo; foo += bar; 1474b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines}; 1484b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 149e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 150e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 151e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_OBJECT_REF_COUNT_H_ NOLINT 152