blob: eb200b8993cc931b3b2a92ae9ad2648f69e5d965 [file] [log] [blame]
Stephen Hines4b32ffd2010-11-05 18:47:11 -07001/*
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
Stephen Hinese639eb52010-11-08 19:27:20 -080017#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>
Stephen Hines4b32ffd2010-11-05 18:47:11 -070021#include <stack>
22
23#include "clang/AST/StmtVisitor.h"
24
Stephen Hinesf2174cf2011-02-09 23:21:37 -080025#include "slang_assert.h"
Stephen Hines4b32ffd2010-11-05 18:47:11 -070026#include "slang_rs_export_type.h"
27
Stephen Hines4b32ffd2010-11-05 18:47:11 -070028namespace clang {
29 class Expr;
Stephen Hinesd5f9d6c2010-12-15 16:11:29 -080030 class Stmt;
Stephen Hines4b32ffd2010-11-05 18:47:11 -070031}
32
Stephen Hinese639eb52010-11-08 19:27:20 -080033namespace slang {
34
Stephen Hines292e00a2011-03-18 19:11:30 -070035// 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.
Stephen Hines4b32ffd2010-11-05 18:47:11 -070045class RSObjectRefCount : public clang::StmtVisitor<RSObjectRefCount> {
46 private:
47 class Scope {
48 private:
49 clang::CompoundStmt *mCS; // Associated compound statement ({ ... })
Stephen Hines1bdd4972010-11-08 17:35:08 -080050 std::list<clang::VarDecl*> mRSO; // Declared RS objects in this scope
51
Stephen Hines4b32ffd2010-11-05 18:47:11 -070052 public:
Stephen Hinese639eb52010-11-08 19:27:20 -080053 explicit Scope(clang::CompoundStmt *CS) : mCS(CS) {
Stephen Hines4b32ffd2010-11-05 18:47:11 -070054 }
55
Stephen Hines1bdd4972010-11-08 17:35:08 -080056 inline void addRSObject(clang::VarDecl* VD) {
57 mRSO.push_back(VD);
Stephen Hines4b32ffd2010-11-05 18:47:11 -070058 }
Stephen Hines1bdd4972010-11-08 17:35:08 -080059
Stephen Hinesd0b5edd2011-04-18 16:38:03 -070060 void ReplaceRSObjectAssignment(clang::BinaryOperator *AS);
Stephen Hinesc202d2d2011-01-26 11:57:57 -080061
Stephen Hinesd0b5edd2011-04-18 16:38:03 -070062 void AppendRSObjectInit(clang::VarDecl *VD,
Stephen Hinese79fb5e2011-02-01 19:12:43 -080063 clang::DeclStmt *DS,
Jean-Luc Brouilletcec9b652014-05-14 19:33:57 -070064 DataType DT,
Stephen Hinese79fb5e2011-02-01 19:12:43 -080065 clang::Expr *InitExpr);
66
Stephen Hines1bdd4972010-11-08 17:35:08 -080067 void InsertLocalVarDestructors();
Stephen Hines1bdd4972010-11-08 17:35:08 -080068
Stephen Hines3f175af2011-09-16 16:26:29 -070069 static clang::Stmt *ClearRSObject(clang::VarDecl *VD,
70 clang::DeclContext *DC);
Stephen Hines4b32ffd2010-11-05 18:47:11 -070071 };
72
Stephen Hinesd0b5edd2011-04-18 16:38:03 -070073 clang::ASTContext &mCtx;
Stephen Hines4b32ffd2010-11-05 18:47:11 -070074 std::stack<Scope*> mScopeStack;
Stephen Hines1bdd4972010-11-08 17:35:08 -080075 bool RSInitFD;
Stephen Hines4b32ffd2010-11-05 18:47:11 -070076
Stephen Hinesf2174cf2011-02-09 23:21:37 -080077 // RSSetObjectFD and RSClearObjectFD holds FunctionDecl of rsSetObject()
78 // and rsClearObject() in the current ASTContext.
79 static clang::FunctionDecl *RSSetObjectFD[];
80 static clang::FunctionDecl *RSClearObjectFD[];
81
Stephen Hines4b32ffd2010-11-05 18:47:11 -070082 inline Scope *getCurrentScope() {
83 return mScopeStack.top();
84 }
85
Stephen Hinesf2174cf2011-02-09 23:21:37 -080086 // Initialize RSSetObjectFD and RSClearObjectFD.
87 static void GetRSRefCountingFunctions(clang::ASTContext &C);
88
Stephen Hinesf2174cf2011-02-09 23:21:37 -080089 // Return false if the type of variable declared in VD does not contain
90 // an RS object type.
Stephen Hinese79fb5e2011-02-01 19:12:43 -080091 static bool InitializeRSObject(clang::VarDecl *VD,
Jean-Luc Brouilletcec9b652014-05-14 19:33:57 -070092 DataType *DT,
Stephen Hinese79fb5e2011-02-01 19:12:43 -080093 clang::Expr **InitExpr);
Stephen Hines4b32ffd2010-11-05 18:47:11 -070094
95 // Return a zero-initializer expr of the type DT. This processes both
96 // RS matrix type and RS object type.
97 static clang::Expr *CreateZeroInitializerForRSSpecificType(
Jean-Luc Brouilletcec9b652014-05-14 19:33:57 -070098 DataType DT,
Stephen Hines4b32ffd2010-11-05 18:47:11 -070099 clang::ASTContext &C,
100 const clang::SourceLocation &Loc);
101
102 public:
Stephen Hinesd0b5edd2011-04-18 16:38:03 -0700103 explicit RSObjectRefCount(clang::ASTContext &C)
104 : mCtx(C),
105 RSInitFD(false) {
Stephen Hines1bdd4972010-11-08 17:35:08 -0800106 }
107
Stephen Hinesd0b5edd2011-04-18 16:38:03 -0700108 void Init() {
Stephen Hines1bdd4972010-11-08 17:35:08 -0800109 if (!RSInitFD) {
Stephen Hinesd0b5edd2011-04-18 16:38:03 -0700110 GetRSRefCountingFunctions(mCtx);
Stephen Hines1bdd4972010-11-08 17:35:08 -0800111 RSInitFD = true;
112 }
Stephen Hines1bdd4972010-11-08 17:35:08 -0800113 }
114
Jean-Luc Brouilletcec9b652014-05-14 19:33:57 -0700115 static clang::FunctionDecl *GetRSSetObjectFD(DataType DT) {
Stephen Hinesf2174cf2011-02-09 23:21:37 -0800116 slangAssert(RSExportPrimitiveType::IsRSObjectType(DT));
Jean-Luc Brouilletcec9b652014-05-14 19:33:57 -0700117 if (DT >= 0 && DT < DataTypeMax) {
Jean-Luc Brouillet474655a2014-04-28 15:25:51 -0700118 return RSSetObjectFD[DT];
119 } else {
120 slangAssert(false && "incorrect type");
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700121 return nullptr;
Jean-Luc Brouillet474655a2014-04-28 15:25:51 -0700122 }
Stephen Hinesf2174cf2011-02-09 23:21:37 -0800123 }
124
125 static clang::FunctionDecl *GetRSSetObjectFD(const clang::Type *T) {
126 return GetRSSetObjectFD(RSExportPrimitiveType::GetRSSpecificType(T));
127 }
128
Jean-Luc Brouilletcec9b652014-05-14 19:33:57 -0700129 static clang::FunctionDecl *GetRSClearObjectFD(DataType DT) {
Stephen Hinesf2174cf2011-02-09 23:21:37 -0800130 slangAssert(RSExportPrimitiveType::IsRSObjectType(DT));
Jean-Luc Brouilletcec9b652014-05-14 19:33:57 -0700131 if (DT >= 0 && DT < DataTypeMax) {
Jean-Luc Brouillet474655a2014-04-28 15:25:51 -0700132 return RSClearObjectFD[DT];
133 } else {
134 slangAssert(false && "incorrect type");
Chris Wailes5abbe0e2014-08-12 15:58:29 -0700135 return nullptr;
Jean-Luc Brouillet474655a2014-04-28 15:25:51 -0700136 }
Stephen Hinesf2174cf2011-02-09 23:21:37 -0800137 }
138
139 static clang::FunctionDecl *GetRSClearObjectFD(const clang::Type *T) {
140 return GetRSClearObjectFD(RSExportPrimitiveType::GetRSSpecificType(T));
141 }
142
Stephen Hines4b32ffd2010-11-05 18:47:11 -0700143 void VisitStmt(clang::Stmt *S);
144 void VisitDeclStmt(clang::DeclStmt *DS);
145 void VisitCompoundStmt(clang::CompoundStmt *CS);
146 void VisitBinAssign(clang::BinaryOperator *AS);
Stephen Hines4b32ffd2010-11-05 18:47:11 -0700147 // We believe that RS objects are never involved in CompoundAssignOperator.
148 // I.e., rs_allocation foo; foo += bar;
Stephen Hines688e64b2011-08-23 16:01:25 -0700149
150 // Emit a global destructor to clean up RS objects.
151 clang::FunctionDecl *CreateStaticGlobalDtor();
Stephen Hines4b32ffd2010-11-05 18:47:11 -0700152};
153
Stephen Hinese639eb52010-11-08 19:27:20 -0800154} // namespace slang
155
156#endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_OBJECT_REF_COUNT_H_ NOLINT