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 62d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines void ReplaceRSObjectAssignment(clang::BinaryOperator *AS); 63c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 64d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines void AppendRSObjectInit(clang::VarDecl *VD, 65e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclStmt *DS, 66e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataType DT, 67e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *InitExpr); 68e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 691bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines void InsertLocalVarDestructors(); 701bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 713f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines static clang::Stmt *ClearRSObject(clang::VarDecl *VD, 723f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines clang::DeclContext *DC); 734b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines }; 744b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 75d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines clang::ASTContext &mCtx; 764b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines std::stack<Scope*> mScopeStack; 771bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines bool RSInitFD; 784b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 79f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // RSSetObjectFD and RSClearObjectFD holds FunctionDecl of rsSetObject() 80f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // and rsClearObject() in the current ASTContext. 81f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines static clang::FunctionDecl *RSSetObjectFD[]; 82f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines static clang::FunctionDecl *RSClearObjectFD[]; 83f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 844b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines inline Scope *getCurrentScope() { 854b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return mScopeStack.top(); 864b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 874b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 88f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Initialize RSSetObjectFD and RSClearObjectFD. 89f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines static void GetRSRefCountingFunctions(clang::ASTContext &C); 90f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 91f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Return false if the type of variable declared in VD does not contain 92f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // an RS object type. 93e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines static bool InitializeRSObject(clang::VarDecl *VD, 94e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataType *DT, 95e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr **InitExpr); 964b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 974b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Return a zero-initializer expr of the type DT. This processes both 984b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // RS matrix type and RS object type. 994b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines static clang::Expr *CreateZeroInitializerForRSSpecificType( 1004b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines RSExportPrimitiveType::DataType DT, 1014b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ASTContext &C, 1024b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines const clang::SourceLocation &Loc); 1034b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1044b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines public: 105d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines explicit RSObjectRefCount(clang::ASTContext &C) 106d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines : mCtx(C), 107d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines RSInitFD(false) { 1081bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines return; 1091bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1101bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 111d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines void Init() { 1121bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if (!RSInitFD) { 113d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines GetRSRefCountingFunctions(mCtx); 1141bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSInitFD = true; 1151bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1161bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines return; 1171bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1181bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 119f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines static clang::FunctionDecl *GetRSSetObjectFD( 120f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::DataType DT) { 121f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(RSExportPrimitiveType::IsRSObjectType(DT)); 122f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return RSSetObjectFD[(DT - RSExportPrimitiveType::FirstRSObjectType)]; 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 129f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines static clang::FunctionDecl *GetRSClearObjectFD( 130f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::DataType DT) { 131f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(RSExportPrimitiveType::IsRSObjectType(DT)); 132f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return RSClearObjectFD[(DT - RSExportPrimitiveType::FirstRSObjectType)]; 133f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 134f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 135f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines static clang::FunctionDecl *GetRSClearObjectFD(const clang::Type *T) { 136f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return GetRSClearObjectFD(RSExportPrimitiveType::GetRSSpecificType(T)); 137f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 138f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 1394b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines void VisitStmt(clang::Stmt *S); 1404b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines void VisitDeclStmt(clang::DeclStmt *DS); 1414b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines void VisitCompoundStmt(clang::CompoundStmt *CS); 1424b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines void VisitBinAssign(clang::BinaryOperator *AS); 1434b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // We believe that RS objects are never involved in CompoundAssignOperator. 1444b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // I.e., rs_allocation foo; foo += bar; 145688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 146688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines // Emit a global destructor to clean up RS objects. 147688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines clang::FunctionDecl *CreateStaticGlobalDtor(); 1484b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines}; 1494b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 150e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 151e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 152e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_OBJECT_REF_COUNT_H_ NOLINT 153