• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
28 namespace clang {
29   class Expr;
30   class Stmt;
31 }
32 
33 namespace 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.
45 class 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:
Scope(clang::CompoundStmt * CS)53     explicit Scope(clang::CompoundStmt *CS) : mCS(CS) {
54       return;
55     }
56 
addRSObject(clang::VarDecl * VD)57     inline void addRSObject(clang::VarDecl* VD) {
58       mRSO.push_back(VD);
59       return;
60     }
61 
62     void ReplaceRSObjectAssignment(clang::BinaryOperator *AS);
63 
64     void AppendRSObjectInit(clang::VarDecl *VD,
65                             clang::DeclStmt *DS,
66                             RSExportPrimitiveType::DataType DT,
67                             clang::Expr *InitExpr);
68 
69     void InsertLocalVarDestructors();
70 
71     static clang::Stmt *ClearRSObject(clang::VarDecl *VD,
72                                       clang::DeclContext *DC);
73   };
74 
75   clang::ASTContext &mCtx;
76   std::stack<Scope*> mScopeStack;
77   bool RSInitFD;
78 
79   // 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 
getCurrentScope()84   inline Scope *getCurrentScope() {
85     return mScopeStack.top();
86   }
87 
88   // Initialize RSSetObjectFD and RSClearObjectFD.
89   static void GetRSRefCountingFunctions(clang::ASTContext &C);
90 
91   // Return false if the type of variable declared in VD does not contain
92   // an RS object type.
93   static bool InitializeRSObject(clang::VarDecl *VD,
94                                  RSExportPrimitiveType::DataType *DT,
95                                  clang::Expr **InitExpr);
96 
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:
RSObjectRefCount(clang::ASTContext & C)105   explicit RSObjectRefCount(clang::ASTContext &C)
106       : mCtx(C),
107         RSInitFD(false) {
108     return;
109   }
110 
Init()111   void Init() {
112     if (!RSInitFD) {
113       GetRSRefCountingFunctions(mCtx);
114       RSInitFD = true;
115     }
116     return;
117   }
118 
GetRSSetObjectFD(RSExportPrimitiveType::DataType DT)119   static clang::FunctionDecl *GetRSSetObjectFD(
120       RSExportPrimitiveType::DataType DT) {
121     slangAssert(RSExportPrimitiveType::IsRSObjectType(DT));
122     return RSSetObjectFD[(DT - RSExportPrimitiveType::FirstRSObjectType)];
123   }
124 
GetRSSetObjectFD(const clang::Type * T)125   static clang::FunctionDecl *GetRSSetObjectFD(const clang::Type *T) {
126     return GetRSSetObjectFD(RSExportPrimitiveType::GetRSSpecificType(T));
127   }
128 
GetRSClearObjectFD(RSExportPrimitiveType::DataType DT)129   static clang::FunctionDecl *GetRSClearObjectFD(
130       RSExportPrimitiveType::DataType DT) {
131     slangAssert(RSExportPrimitiveType::IsRSObjectType(DT));
132     return RSClearObjectFD[(DT - RSExportPrimitiveType::FirstRSObjectType)];
133   }
134 
GetRSClearObjectFD(const clang::Type * T)135   static clang::FunctionDecl *GetRSClearObjectFD(const clang::Type *T) {
136     return GetRSClearObjectFD(RSExportPrimitiveType::GetRSSpecificType(T));
137   }
138 
139   void VisitStmt(clang::Stmt *S);
140   void VisitDeclStmt(clang::DeclStmt *DS);
141   void VisitCompoundStmt(clang::CompoundStmt *CS);
142   void VisitBinAssign(clang::BinaryOperator *AS);
143   // We believe that RS objects are never involved in CompoundAssignOperator.
144   // I.e., rs_allocation foo; foo += bar;
145 
146   // Emit a global destructor to clean up RS objects.
147   clang::FunctionDecl *CreateStaticGlobalDtor();
148 };
149 
150 }  // namespace slang
151 
152 #endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_OBJECT_REF_COUNT_H_  NOLINT
153