slang_rs_object_ref_count.h revision f2174cfd6a556b51aadf2b8765e50df080e8f18e
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
354b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesclass RSObjectRefCount : public clang::StmtVisitor<RSObjectRefCount> {
364b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines private:
374b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines  class Scope {
384b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines   private:
394b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines    clang::CompoundStmt *mCS;      // Associated compound statement ({ ... })
401bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines    std::list<clang::VarDecl*> mRSO;  // Declared RS objects in this scope
411bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines
424b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines   public:
43e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines    explicit Scope(clang::CompoundStmt *CS) : mCS(CS) {
444b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines      return;
454b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines    }
464b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines
471bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines    inline void addRSObject(clang::VarDecl* VD) {
481bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines      mRSO.push_back(VD);
494b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines      return;
504b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines    }
511bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines
52c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines    void ReplaceRSObjectAssignment(clang::BinaryOperator *AS);
53c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines
54e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines    void AppendRSObjectInit(clang::VarDecl *VD,
55e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines                            clang::DeclStmt *DS,
56e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines                            RSExportPrimitiveType::DataType DT,
57e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines                            clang::Expr *InitExpr);
58e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines
591bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines    void InsertLocalVarDestructors();
601bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines
61d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines    static clang::Stmt *ClearRSObject(clang::VarDecl *VD);
624b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines  };
634b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines
644b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines  std::stack<Scope*> mScopeStack;
651bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines  bool RSInitFD;
664b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines
67f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  // RSSetObjectFD and RSClearObjectFD holds FunctionDecl of rsSetObject()
68f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  // and rsClearObject() in the current ASTContext.
69f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  static clang::FunctionDecl *RSSetObjectFD[];
70f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  static clang::FunctionDecl *RSClearObjectFD[];
71f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
724b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines  inline Scope *getCurrentScope() {
734b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines    return mScopeStack.top();
744b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines  }
754b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines
76f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  // Initialize RSSetObjectFD and RSClearObjectFD.
77f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  static void GetRSRefCountingFunctions(clang::ASTContext &C);
78f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
79e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  // TODO(srhines): Composite types and arrays based on RS object types need
80e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines  // to be handled for both zero-initialization + clearing.
811bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines
82f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  // Return false if the type of variable declared in VD does not contain
83f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  // an RS object type.
84e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines  static bool InitializeRSObject(clang::VarDecl *VD,
85e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines                                 RSExportPrimitiveType::DataType *DT,
86e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines                                 clang::Expr **InitExpr);
874b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines
884b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines  // Return a zero-initializer expr of the type DT. This processes both
894b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines  // RS matrix type and RS object type.
904b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines  static clang::Expr *CreateZeroInitializerForRSSpecificType(
914b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines      RSExportPrimitiveType::DataType DT,
924b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines      clang::ASTContext &C,
934b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines      const clang::SourceLocation &Loc);
944b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines
954b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines public:
961bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines  RSObjectRefCount()
971bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines      : RSInitFD(false) {
981bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines    return;
991bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines  }
1001bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines
1011bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines  void Init(clang::ASTContext &C) {
1021bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines    if (!RSInitFD) {
103f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines      GetRSRefCountingFunctions(C);
1041bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines      RSInitFD = true;
1051bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines    }
1061bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines    return;
1071bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines  }
1081bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines
109f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  static clang::FunctionDecl *GetRSSetObjectFD(
110f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines      RSExportPrimitiveType::DataType DT) {
111f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    slangAssert(RSExportPrimitiveType::IsRSObjectType(DT));
112f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    return RSSetObjectFD[(DT - RSExportPrimitiveType::FirstRSObjectType)];
113f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  }
114f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
115f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  static clang::FunctionDecl *GetRSSetObjectFD(const clang::Type *T) {
116f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    return GetRSSetObjectFD(RSExportPrimitiveType::GetRSSpecificType(T));
117f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  }
118f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
119f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  static clang::FunctionDecl *GetRSClearObjectFD(
120f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines      RSExportPrimitiveType::DataType DT) {
121f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    slangAssert(RSExportPrimitiveType::IsRSObjectType(DT));
122f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    return RSClearObjectFD[(DT - RSExportPrimitiveType::FirstRSObjectType)];
123f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  }
124f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
125f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  static clang::FunctionDecl *GetRSClearObjectFD(const clang::Type *T) {
126f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines    return GetRSClearObjectFD(RSExportPrimitiveType::GetRSSpecificType(T));
127f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines  }
128f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines
1294b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines  void VisitStmt(clang::Stmt *S);
1304b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines  void VisitDeclStmt(clang::DeclStmt *DS);
1314b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines  void VisitCompoundStmt(clang::CompoundStmt *CS);
1324b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines  void VisitBinAssign(clang::BinaryOperator *AS);
1334b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines
1344b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines  // We believe that RS objects are never involved in CompoundAssignOperator.
1354b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines  // I.e., rs_allocation foo; foo += bar;
1364b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines};
1374b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines
138e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace slang
139e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
140e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#endif  // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_OBJECT_REF_COUNT_H_  NOLINT
141