slang_rs_object_ref_count.h revision 292e00a0259ac28cac1055cb6077cf6fc7c6743c
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
622bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines    void ReplaceRSObjectAssignment(clang::BinaryOperator *AS,
632bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines                                   clang::Diagnostic *Diags);
64c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines
65a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines    void AppendRSObjectInit(clang::Diagnostic *Diags,
66a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines                            clang::VarDecl *VD,
67e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines                            clang::DeclStmt *DS,
68e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines                            RSExportPrimitiveType::DataType DT,
69e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines                            clang::Expr *InitExpr);
70e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines
711bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines    void InsertLocalVarDestructors();
721bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines
73d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines    static clang::Stmt *ClearRSObject(clang::VarDecl *VD);
744b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines  };
754b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines
764b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines  std::stack<Scope*> mScopeStack;
771bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines  bool RSInitFD;
782bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines  clang::Diagnostic *mDiags;
794b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines
80f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  // RSSetObjectFD and RSClearObjectFD holds FunctionDecl of rsSetObject()
81f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  // and rsClearObject() in the current ASTContext.
82f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  static clang::FunctionDecl *RSSetObjectFD[];
83f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  static clang::FunctionDecl *RSClearObjectFD[];
84f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
854b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines  inline Scope *getCurrentScope() {
864b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines    return mScopeStack.top();
874b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines  }
884b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines
89f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  // Initialize RSSetObjectFD and RSClearObjectFD.
90f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  static void GetRSRefCountingFunctions(clang::ASTContext &C);
91f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
92f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  // Return false if the type of variable declared in VD does not contain
93f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  // an RS object type.
94e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines  static bool InitializeRSObject(clang::VarDecl *VD,
95e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines                                 RSExportPrimitiveType::DataType *DT,
96e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines                                 clang::Expr **InitExpr);
974b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines
984b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines  // Return a zero-initializer expr of the type DT. This processes both
994b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines  // RS matrix type and RS object type.
1004b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines  static clang::Expr *CreateZeroInitializerForRSSpecificType(
1014b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines      RSExportPrimitiveType::DataType DT,
1024b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines      clang::ASTContext &C,
1034b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines      const clang::SourceLocation &Loc);
1044b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines
1054b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines public:
1061bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines  RSObjectRefCount()
1071bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines      : RSInitFD(false) {
1081bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines    return;
1091bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines  }
1101bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines
1112bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines  void Init(clang::ASTContext &C, clang::Diagnostic *Diags) {
1121bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines    if (!RSInitFD) {
113f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines      GetRSRefCountingFunctions(C);
1142bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines      mDiags = Diags;
1151bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines      RSInitFD = true;
1161bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines    }
1171bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines    return;
1181bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines  }
1191bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines
120f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  static clang::FunctionDecl *GetRSSetObjectFD(
121f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines      RSExportPrimitiveType::DataType DT) {
122f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    slangAssert(RSExportPrimitiveType::IsRSObjectType(DT));
123f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    return RSSetObjectFD[(DT - RSExportPrimitiveType::FirstRSObjectType)];
124f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  }
125f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
126f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  static clang::FunctionDecl *GetRSSetObjectFD(const clang::Type *T) {
127f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    return GetRSSetObjectFD(RSExportPrimitiveType::GetRSSpecificType(T));
128f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  }
129f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
130f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  static clang::FunctionDecl *GetRSClearObjectFD(
131f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines      RSExportPrimitiveType::DataType DT) {
132f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    slangAssert(RSExportPrimitiveType::IsRSObjectType(DT));
133f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    return RSClearObjectFD[(DT - RSExportPrimitiveType::FirstRSObjectType)];
134f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  }
135f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
136f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  static clang::FunctionDecl *GetRSClearObjectFD(const clang::Type *T) {
137f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    return GetRSClearObjectFD(RSExportPrimitiveType::GetRSSpecificType(T));
138f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  }
139f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
1404b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines  void VisitStmt(clang::Stmt *S);
1414b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines  void VisitDeclStmt(clang::DeclStmt *DS);
1424b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines  void VisitCompoundStmt(clang::CompoundStmt *CS);
1434b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines  void VisitBinAssign(clang::BinaryOperator *AS);
1444b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines
1454b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines  // We believe that RS objects are never involved in CompoundAssignOperator.
1464b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines  // I.e., rs_allocation foo; foo += bar;
1474b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines};
1484b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines
149e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace slang
150e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
151e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_OBJECT_REF_COUNT_H_  NOLINT
152