blob: 1e87ca12288e4b96306f3e4335665af4da8a51e1 [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 return;
55 }
56
Stephen Hines1bdd4972010-11-08 17:35:08 -080057 inline void addRSObject(clang::VarDecl* VD) {
58 mRSO.push_back(VD);
Stephen Hines4b32ffd2010-11-05 18:47:11 -070059 return;
60 }
Stephen Hines1bdd4972010-11-08 17:35:08 -080061
Stephen Hinesd0b5edd2011-04-18 16:38:03 -070062 void ReplaceRSObjectAssignment(clang::BinaryOperator *AS);
Stephen Hinesc202d2d2011-01-26 11:57:57 -080063
Stephen Hinesd0b5edd2011-04-18 16:38:03 -070064 void AppendRSObjectInit(clang::VarDecl *VD,
Stephen Hinese79fb5e2011-02-01 19:12:43 -080065 clang::DeclStmt *DS,
66 RSExportPrimitiveType::DataType DT,
67 clang::Expr *InitExpr);
68
Stephen Hines1bdd4972010-11-08 17:35:08 -080069 void InsertLocalVarDestructors();
Stephen Hines1bdd4972010-11-08 17:35:08 -080070
Stephen Hines3f175af2011-09-16 16:26:29 -070071 static clang::Stmt *ClearRSObject(clang::VarDecl *VD,
72 clang::DeclContext *DC);
Stephen Hines4b32ffd2010-11-05 18:47:11 -070073 };
74
Stephen Hinesd0b5edd2011-04-18 16:38:03 -070075 clang::ASTContext &mCtx;
Stephen Hines4b32ffd2010-11-05 18:47:11 -070076 std::stack<Scope*> mScopeStack;
Stephen Hines1bdd4972010-11-08 17:35:08 -080077 bool RSInitFD;
Stephen Hines4b32ffd2010-11-05 18:47:11 -070078
Stephen Hinesf2174cf2011-02-09 23:21:37 -080079 // RSSetObjectFD and RSClearObjectFD holds FunctionDecl of rsSetObject()
80 // and rsClearObject() in the current ASTContext.
81 static clang::FunctionDecl *RSSetObjectFD[];
82 static clang::FunctionDecl *RSClearObjectFD[];
83
Stephen Hines4b32ffd2010-11-05 18:47:11 -070084 inline Scope *getCurrentScope() {
85 return mScopeStack.top();
86 }
87
Stephen Hinesf2174cf2011-02-09 23:21:37 -080088 // Initialize RSSetObjectFD and RSClearObjectFD.
89 static void GetRSRefCountingFunctions(clang::ASTContext &C);
90
Stephen Hinesf2174cf2011-02-09 23:21:37 -080091 // Return false if the type of variable declared in VD does not contain
92 // an RS object type.
Stephen Hinese79fb5e2011-02-01 19:12:43 -080093 static bool InitializeRSObject(clang::VarDecl *VD,
94 RSExportPrimitiveType::DataType *DT,
95 clang::Expr **InitExpr);
Stephen Hines4b32ffd2010-11-05 18:47:11 -070096
97 // Return a zero-initializer expr of the type DT. This processes both
98 // RS matrix type and RS object type.
99 static clang::Expr *CreateZeroInitializerForRSSpecificType(
100 RSExportPrimitiveType::DataType DT,
101 clang::ASTContext &C,
102 const clang::SourceLocation &Loc);
103
104 public:
Stephen Hinesd0b5edd2011-04-18 16:38:03 -0700105 explicit RSObjectRefCount(clang::ASTContext &C)
106 : mCtx(C),
107 RSInitFD(false) {
Stephen Hines1bdd4972010-11-08 17:35:08 -0800108 return;
109 }
110
Stephen Hinesd0b5edd2011-04-18 16:38:03 -0700111 void Init() {
Stephen Hines1bdd4972010-11-08 17:35:08 -0800112 if (!RSInitFD) {
Stephen Hinesd0b5edd2011-04-18 16:38:03 -0700113 GetRSRefCountingFunctions(mCtx);
Stephen Hines1bdd4972010-11-08 17:35:08 -0800114 RSInitFD = true;
115 }
116 return;
117 }
118
Stephen Hinesf2174cf2011-02-09 23:21:37 -0800119 static clang::FunctionDecl *GetRSSetObjectFD(
120 RSExportPrimitiveType::DataType DT) {
121 slangAssert(RSExportPrimitiveType::IsRSObjectType(DT));
122 return RSSetObjectFD[(DT - RSExportPrimitiveType::FirstRSObjectType)];
123 }
124
125 static clang::FunctionDecl *GetRSSetObjectFD(const clang::Type *T) {
126 return GetRSSetObjectFD(RSExportPrimitiveType::GetRSSpecificType(T));
127 }
128
129 static clang::FunctionDecl *GetRSClearObjectFD(
130 RSExportPrimitiveType::DataType DT) {
131 slangAssert(RSExportPrimitiveType::IsRSObjectType(DT));
132 return RSClearObjectFD[(DT - RSExportPrimitiveType::FirstRSObjectType)];
133 }
134
135 static clang::FunctionDecl *GetRSClearObjectFD(const clang::Type *T) {
136 return GetRSClearObjectFD(RSExportPrimitiveType::GetRSSpecificType(T));
137 }
138
Stephen Hines4b32ffd2010-11-05 18:47:11 -0700139 void VisitStmt(clang::Stmt *S);
140 void VisitDeclStmt(clang::DeclStmt *DS);
141 void VisitCompoundStmt(clang::CompoundStmt *CS);
142 void VisitBinAssign(clang::BinaryOperator *AS);
Stephen Hines4b32ffd2010-11-05 18:47:11 -0700143 // We believe that RS objects are never involved in CompoundAssignOperator.
144 // I.e., rs_allocation foo; foo += bar;
Stephen Hines688e64b2011-08-23 16:01:25 -0700145
146 // Emit a global destructor to clean up RS objects.
147 clang::FunctionDecl *CreateStaticGlobalDtor();
Stephen Hines4b32ffd2010-11-05 18:47:11 -0700148};
149
Stephen Hinese639eb52010-11-08 19:27:20 -0800150} // namespace slang
151
152#endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_OBJECT_REF_COUNT_H_ NOLINT