slang_rs_object_ref_count.h revision 292e00a0259ac28cac1055cb6077cf6fc7c6743c
1/* 2 * Copyright 2010, 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_OBJECT_REF_COUNT_H_ // NOLINT 18#define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_OBJECT_REF_COUNT_H_ 19 20#include <list> 21#include <stack> 22 23#include "clang/AST/StmtVisitor.h" 24 25#include "slang_assert.h" 26#include "slang_rs_export_type.h" 27 28namespace clang { 29 class Expr; 30 class Stmt; 31} 32 33namespace slang { 34 35// This class provides the overall reference counting mechanism for handling 36// local variables of RS object types (rs_font, rs_allocation, ...). This 37// class ensures that appropriate functions (rsSetObject, rsClearObject) are 38// called at proper points in the object's lifetime. 39// 1) Each local object of appropriate type must be zero-initialized (to 40// prevent corruption) during subsequent rsSetObject()/rsClearObject() calls. 41// 2) Assignments using these types must also be converted into the 42// appropriate (possibly a series of) rsSetObject() calls. 43// 3) Finally, each local object must call rsClearObject() when it goes out 44// of scope. 45class RSObjectRefCount : public clang::StmtVisitor<RSObjectRefCount> { 46 private: 47 class Scope { 48 private: 49 clang::CompoundStmt *mCS; // Associated compound statement ({ ... }) 50 std::list<clang::VarDecl*> mRSO; // Declared RS objects in this scope 51 52 public: 53 explicit Scope(clang::CompoundStmt *CS) : mCS(CS) { 54 return; 55 } 56 57 inline void addRSObject(clang::VarDecl* VD) { 58 mRSO.push_back(VD); 59 return; 60 } 61 62 void ReplaceRSObjectAssignment(clang::BinaryOperator *AS, 63 clang::Diagnostic *Diags); 64 65 void AppendRSObjectInit(clang::Diagnostic *Diags, 66 clang::VarDecl *VD, 67 clang::DeclStmt *DS, 68 RSExportPrimitiveType::DataType DT, 69 clang::Expr *InitExpr); 70 71 void InsertLocalVarDestructors(); 72 73 static clang::Stmt *ClearRSObject(clang::VarDecl *VD); 74 }; 75 76 std::stack<Scope*> mScopeStack; 77 bool RSInitFD; 78 clang::Diagnostic *mDiags; 79 80 // RSSetObjectFD and RSClearObjectFD holds FunctionDecl of rsSetObject() 81 // and rsClearObject() in the current ASTContext. 82 static clang::FunctionDecl *RSSetObjectFD[]; 83 static clang::FunctionDecl *RSClearObjectFD[]; 84 85 inline Scope *getCurrentScope() { 86 return mScopeStack.top(); 87 } 88 89 // Initialize RSSetObjectFD and RSClearObjectFD. 90 static void GetRSRefCountingFunctions(clang::ASTContext &C); 91 92 // Return false if the type of variable declared in VD does not contain 93 // an RS object type. 94 static bool InitializeRSObject(clang::VarDecl *VD, 95 RSExportPrimitiveType::DataType *DT, 96 clang::Expr **InitExpr); 97 98 // Return a zero-initializer expr of the type DT. This processes both 99 // RS matrix type and RS object type. 100 static clang::Expr *CreateZeroInitializerForRSSpecificType( 101 RSExportPrimitiveType::DataType DT, 102 clang::ASTContext &C, 103 const clang::SourceLocation &Loc); 104 105 public: 106 RSObjectRefCount() 107 : RSInitFD(false) { 108 return; 109 } 110 111 void Init(clang::ASTContext &C, clang::Diagnostic *Diags) { 112 if (!RSInitFD) { 113 GetRSRefCountingFunctions(C); 114 mDiags = Diags; 115 RSInitFD = true; 116 } 117 return; 118 } 119 120 static clang::FunctionDecl *GetRSSetObjectFD( 121 RSExportPrimitiveType::DataType DT) { 122 slangAssert(RSExportPrimitiveType::IsRSObjectType(DT)); 123 return RSSetObjectFD[(DT - RSExportPrimitiveType::FirstRSObjectType)]; 124 } 125 126 static clang::FunctionDecl *GetRSSetObjectFD(const clang::Type *T) { 127 return GetRSSetObjectFD(RSExportPrimitiveType::GetRSSpecificType(T)); 128 } 129 130 static clang::FunctionDecl *GetRSClearObjectFD( 131 RSExportPrimitiveType::DataType DT) { 132 slangAssert(RSExportPrimitiveType::IsRSObjectType(DT)); 133 return RSClearObjectFD[(DT - RSExportPrimitiveType::FirstRSObjectType)]; 134 } 135 136 static clang::FunctionDecl *GetRSClearObjectFD(const clang::Type *T) { 137 return GetRSClearObjectFD(RSExportPrimitiveType::GetRSSpecificType(T)); 138 } 139 140 void VisitStmt(clang::Stmt *S); 141 void VisitDeclStmt(clang::DeclStmt *DS); 142 void VisitCompoundStmt(clang::CompoundStmt *CS); 143 void VisitBinAssign(clang::BinaryOperator *AS); 144 145 // We believe that RS objects are never involved in CompoundAssignOperator. 146 // I.e., rs_allocation foo; foo += bar; 147}; 148 149} // namespace slang 150 151#endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_OBJECT_REF_COUNT_H_ NOLINT 152