slang_rs_object_ref_count.cpp revision 4464d825c11349068f2917f9ebee86b721423f3c
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 174b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "slang_rs_object_ref_count.h" 184b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 19e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <list> 20e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 214b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "clang/AST/DeclGroup.h" 224b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "clang/AST/Expr.h" 234b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "clang/AST/OperationKinds.h" 244b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "clang/AST/Stmt.h" 254b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "clang/AST/StmtVisitor.h" 264b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 274b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "slang_rs.h" 284b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "slang_rs_export_type.h" 294b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 30e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang { 314b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 321bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hinesclang::FunctionDecl *RSObjectRefCount::Scope:: 331bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSSetObjectFD[RSExportPrimitiveType::LastRSObjectType - 341bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSExportPrimitiveType::FirstRSObjectType + 1]; 351bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hinesclang::FunctionDecl *RSObjectRefCount::Scope:: 361bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSClearObjectFD[RSExportPrimitiveType::LastRSObjectType - 371bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSExportPrimitiveType::FirstRSObjectType + 1]; 381bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 391bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hinesvoid RSObjectRefCount::Scope::GetRSRefCountingFunctions( 401bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::ASTContext &C) { 411bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines for (unsigned i = 0; 421bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines i < (sizeof(RSClearObjectFD) / sizeof(clang::FunctionDecl*)); 431bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines i++) { 441bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSSetObjectFD[i] = NULL; 451bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSClearObjectFD[i] = NULL; 461bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 471bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 481bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl(); 491bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 501bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(), 511bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines E = TUDecl->decls_end(); I != E; I++) { 521bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if ((I->getKind() >= clang::Decl::firstFunction) && 531bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines (I->getKind() <= clang::Decl::lastFunction)) { 541bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::FunctionDecl *FD = static_cast<clang::FunctionDecl*>(*I); 551bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 561bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // points to RSSetObjectFD or RSClearObjectFD 571bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::FunctionDecl **RSObjectFD; 581bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 591bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if (FD->getName() == "rsSetObject") { 601bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines assert((FD->getNumParams() == 2) && 611bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines "Invalid rsSetObject function prototype (# params)"); 621bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSObjectFD = RSSetObjectFD; 631bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } else if (FD->getName() == "rsClearObject") { 641bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines assert((FD->getNumParams() == 1) && 651bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines "Invalid rsClearObject function prototype (# params)"); 661bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSObjectFD = RSClearObjectFD; 67e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines } else { 681bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines continue; 691bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 701bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 711bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines const clang::ParmVarDecl *PVD = FD->getParamDecl(0); 721bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::QualType PVT = PVD->getOriginalType(); 731bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // The first parameter must be a pointer like rs_allocation* 741bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines assert(PVT->isPointerType() && 751bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines "Invalid rs{Set,Clear}Object function prototype (pointer param)"); 761bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 771bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // The rs object type passed to the FD 781bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::QualType RST = PVT->getPointeeType(); 791bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSExportPrimitiveType::DataType DT = 801bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSExportPrimitiveType::GetRSSpecificType(RST.getTypePtr()); 811bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines assert(RSExportPrimitiveType::IsRSObjectType(DT) 821bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines && "must be RS object type"); 831bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 841bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSObjectFD[(DT - RSExportPrimitiveType::FirstRSObjectType)] = FD; 851bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 861bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 871bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 881bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 894464d825c11349068f2917f9ebee86b721423f3cStephen Hinesnamespace { 904464d825c11349068f2917f9ebee86b721423f3cStephen Hines 914464d825c11349068f2917f9ebee86b721423f3cStephen Hinesstatic void AppendToCompoundStatement(clang::ASTContext& C, 924464d825c11349068f2917f9ebee86b721423f3cStephen Hines clang::CompoundStmt *CS, 934464d825c11349068f2917f9ebee86b721423f3cStephen Hines std::list<clang::Expr*> &ExprList, 944464d825c11349068f2917f9ebee86b721423f3cStephen Hines bool InsertAtEndOfBlock) { 951bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Destructor code will be inserted before any return statement. 961bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Any subsequent statements in the compound statement are then placed 971bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // after our new code. 98e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines // TODO(srhines): This should also handle the case of goto/break/continue. 994464d825c11349068f2917f9ebee86b721423f3cStephen Hines 1004464d825c11349068f2917f9ebee86b721423f3cStephen Hines clang::CompoundStmt::body_iterator bI = CS->body_begin(); 1014464d825c11349068f2917f9ebee86b721423f3cStephen Hines clang::CompoundStmt::body_iterator bE = CS->body_end(); 1021bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1031bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines unsigned OldStmtCount = 0; 1044464d825c11349068f2917f9ebee86b721423f3cStephen Hines for (bI = CS->body_begin(); bI != bE; bI++) { 1051bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines OldStmtCount++; 1061bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1071bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1081bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines unsigned NewExprCount = ExprList.size(); 1091bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1101bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::Stmt **StmtList; 1111bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines StmtList = new clang::Stmt*[OldStmtCount+NewExprCount]; 1121bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1131bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines unsigned UpdatedStmtCount = 0; 1144464d825c11349068f2917f9ebee86b721423f3cStephen Hines bool FoundReturn = false; 1154464d825c11349068f2917f9ebee86b721423f3cStephen Hines for (bI = CS->body_begin(); bI != bE; bI++) { 1161bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if ((*bI)->getStmtClass() == clang::Stmt::ReturnStmtClass) { 1174464d825c11349068f2917f9ebee86b721423f3cStephen Hines FoundReturn = true; 1181bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines break; 1191bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1201bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines StmtList[UpdatedStmtCount++] = *bI; 1211bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1221bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1234464d825c11349068f2917f9ebee86b721423f3cStephen Hines // Always insert before a return that we found, or if we are told 1244464d825c11349068f2917f9ebee86b721423f3cStephen Hines // to insert at the end of the block 1254464d825c11349068f2917f9ebee86b721423f3cStephen Hines if (FoundReturn || InsertAtEndOfBlock) { 1264464d825c11349068f2917f9ebee86b721423f3cStephen Hines std::list<clang::Expr*>::const_iterator E = ExprList.end(); 1274464d825c11349068f2917f9ebee86b721423f3cStephen Hines for (std::list<clang::Expr*>::const_iterator I = ExprList.begin(), 1284464d825c11349068f2917f9ebee86b721423f3cStephen Hines E = ExprList.end(); 1294464d825c11349068f2917f9ebee86b721423f3cStephen Hines I != E; 1304464d825c11349068f2917f9ebee86b721423f3cStephen Hines I++) { 1314464d825c11349068f2917f9ebee86b721423f3cStephen Hines StmtList[UpdatedStmtCount++] = *I; 1324464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 1331bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1341bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1351bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Pick up anything left over after a return statement 1361bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines for ( ; bI != bE; bI++) { 1371bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines StmtList[UpdatedStmtCount++] = *bI; 1381bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1391bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1404464d825c11349068f2917f9ebee86b721423f3cStephen Hines CS->setStmts(C, StmtList, UpdatedStmtCount); 1411bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1421bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines delete [] StmtList; 1431bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1441bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines return; 1451bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 1461bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1474464d825c11349068f2917f9ebee86b721423f3cStephen Hines// This class visits a compound statement and inserts the ExprList containing 1484464d825c11349068f2917f9ebee86b721423f3cStephen Hines// destructors in proper locations. This includes inserting them before any 1494464d825c11349068f2917f9ebee86b721423f3cStephen Hines// return statement in any sub-block, at the end of the logical enclosing 1504464d825c11349068f2917f9ebee86b721423f3cStephen Hines// scope (compound statement), and/or before any break/continue statement that 1514464d825c11349068f2917f9ebee86b721423f3cStephen Hines// would resume outside the declared scope. We will not handle the case for 1524464d825c11349068f2917f9ebee86b721423f3cStephen Hines// goto statements that leave a local scope. 1534464d825c11349068f2917f9ebee86b721423f3cStephen Hines// TODO(srhines): Make this work properly for break/continue. 1544464d825c11349068f2917f9ebee86b721423f3cStephen Hinesclass DestructorVisitor : public clang::StmtVisitor<DestructorVisitor> { 1554464d825c11349068f2917f9ebee86b721423f3cStephen Hines private: 1564464d825c11349068f2917f9ebee86b721423f3cStephen Hines clang::ASTContext &mC; 1574464d825c11349068f2917f9ebee86b721423f3cStephen Hines std::list<clang::Expr*> &mExprList; 1584464d825c11349068f2917f9ebee86b721423f3cStephen Hines bool mTopLevel; 1594464d825c11349068f2917f9ebee86b721423f3cStephen Hines public: 1604464d825c11349068f2917f9ebee86b721423f3cStephen Hines DestructorVisitor(clang::ASTContext &C, std::list<clang::Expr*> &ExprList); 1614464d825c11349068f2917f9ebee86b721423f3cStephen Hines void VisitStmt(clang::Stmt *S); 1624464d825c11349068f2917f9ebee86b721423f3cStephen Hines void VisitCompoundStmt(clang::CompoundStmt *CS); 1634464d825c11349068f2917f9ebee86b721423f3cStephen Hines}; 1644464d825c11349068f2917f9ebee86b721423f3cStephen Hines 1654464d825c11349068f2917f9ebee86b721423f3cStephen HinesDestructorVisitor::DestructorVisitor(clang::ASTContext &C, 1664464d825c11349068f2917f9ebee86b721423f3cStephen Hines std::list<clang::Expr*> &ExprList) 1674464d825c11349068f2917f9ebee86b721423f3cStephen Hines : mC(C), 1684464d825c11349068f2917f9ebee86b721423f3cStephen Hines mExprList(ExprList), 1694464d825c11349068f2917f9ebee86b721423f3cStephen Hines mTopLevel(true) { 1704464d825c11349068f2917f9ebee86b721423f3cStephen Hines return; 1714464d825c11349068f2917f9ebee86b721423f3cStephen Hines} 1724464d825c11349068f2917f9ebee86b721423f3cStephen Hines 1734464d825c11349068f2917f9ebee86b721423f3cStephen Hinesvoid DestructorVisitor::VisitCompoundStmt(clang::CompoundStmt *CS) { 1744464d825c11349068f2917f9ebee86b721423f3cStephen Hines if (!CS->body_empty()) { 1754464d825c11349068f2917f9ebee86b721423f3cStephen Hines AppendToCompoundStatement(mC, CS, mExprList, mTopLevel); 1764464d825c11349068f2917f9ebee86b721423f3cStephen Hines mTopLevel = false; 1774464d825c11349068f2917f9ebee86b721423f3cStephen Hines VisitStmt(CS); 1784464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 1794464d825c11349068f2917f9ebee86b721423f3cStephen Hines return; 1804464d825c11349068f2917f9ebee86b721423f3cStephen Hines} 1814464d825c11349068f2917f9ebee86b721423f3cStephen Hines 1824464d825c11349068f2917f9ebee86b721423f3cStephen Hinesvoid DestructorVisitor::VisitStmt(clang::Stmt *S) { 1834464d825c11349068f2917f9ebee86b721423f3cStephen Hines for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end(); 1844464d825c11349068f2917f9ebee86b721423f3cStephen Hines I != E; 1854464d825c11349068f2917f9ebee86b721423f3cStephen Hines I++) { 1864464d825c11349068f2917f9ebee86b721423f3cStephen Hines if (clang::Stmt *Child = *I) { 1874464d825c11349068f2917f9ebee86b721423f3cStephen Hines Visit(Child); 1884464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 1894464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 1904464d825c11349068f2917f9ebee86b721423f3cStephen Hines return; 1914464d825c11349068f2917f9ebee86b721423f3cStephen Hines} 1924464d825c11349068f2917f9ebee86b721423f3cStephen Hines 1934464d825c11349068f2917f9ebee86b721423f3cStephen Hines} // namespace 1944464d825c11349068f2917f9ebee86b721423f3cStephen Hines 1951bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hinesvoid RSObjectRefCount::Scope::InsertLocalVarDestructors() { 1961bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines std::list<clang::Expr*> RSClearObjectCalls; 1971bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines for (std::list<clang::VarDecl*>::const_iterator I = mRSO.begin(), 1981bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines E = mRSO.end(); 1991bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines I != E; 2001bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines I++) { 2011bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::Expr *E = ClearRSObject(*I); 2021bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if (E) { 2031bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSClearObjectCalls.push_back(E); 2041bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 2051bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 2061bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if (RSClearObjectCalls.size() > 0) { 2074464d825c11349068f2917f9ebee86b721423f3cStephen Hines DestructorVisitor DV((*mRSO.begin())->getASTContext(), RSClearObjectCalls); 2084464d825c11349068f2917f9ebee86b721423f3cStephen Hines DV.Visit(mCS); 2091bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 2101bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines return; 2111bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 2121bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 2131bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hinesclang::Expr *RSObjectRefCount::Scope::ClearRSObject(clang::VarDecl *VD) { 2141bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::ASTContext &C = VD->getASTContext(); 2151bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::SourceLocation Loc = VD->getLocation(); 2161bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 2171bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSExportPrimitiveType::DataType DT = 2181bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSExportPrimitiveType::GetRSSpecificType(T); 2191bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 2201bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines assert((RSExportPrimitiveType::IsRSObjectType(DT)) && 2211bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines "Should be RS object"); 2221bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 2231bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Find the rsClearObject() for VD of RS object type DT 2241bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::FunctionDecl *ClearObjectFD = 2251bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSClearObjectFD[(DT - RSExportPrimitiveType::FirstRSObjectType)]; 2261bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines assert((ClearObjectFD != NULL) && 2271bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines "rsClearObject doesn't cover all RS object types"); 2281bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 2291bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::QualType ClearObjectFDType = ClearObjectFD->getType(); 2301bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::QualType ClearObjectFDArgType = 2311bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines ClearObjectFD->getParamDecl(0)->getOriginalType(); 2321bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 2331bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // We generate a call to rsClearObject passing &VD as the parameter 2341bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // (CallExpr 'void' 2351bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // (ImplicitCastExpr 'void (*)(rs_font *)' <FunctionToPointerDecay> 2361bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // (DeclRefExpr 'void (rs_font *)' FunctionDecl='rsClearObject')) 2371bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // (UnaryOperator 'rs_font *' prefix '&' 2381bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // (DeclRefExpr 'rs_font':'rs_font' Var='[var name]'))) 2391bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 2401bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Reference expr to target RS object variable 2411bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::DeclRefExpr *RefRSVar = 2421bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::DeclRefExpr::Create(C, 2431bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines NULL, 2441bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines VD->getQualifierRange(), 2451bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines VD, 2461bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines Loc, 2471bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines T->getCanonicalTypeInternal(), 2481bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines NULL); 2491bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 2501bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Get address of RSObject in VD 2511bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::Expr *AddrRefRSVar = 252e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines new(C) clang::UnaryOperator(RefRSVar, 253e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines clang::UO_AddrOf, 254e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines ClearObjectFDArgType, 255e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Loc); 2561bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 2571bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::Expr *RefRSClearObjectFD = 2581bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::DeclRefExpr::Create(C, 2591bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines NULL, 2601bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines ClearObjectFD->getQualifierRange(), 2611bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines ClearObjectFD, 2621bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines ClearObjectFD->getLocation(), 2631bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines ClearObjectFDType, 2641bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines NULL); 2651bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 2661bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::Expr *RSClearObjectFP = 2671bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::ImplicitCastExpr::Create(C, 2681bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines C.getPointerType(ClearObjectFDType), 2691bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::CK_FunctionToPointerDecay, 2701bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RefRSClearObjectFD, 2711bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines NULL, 2721bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::VK_RValue); 2731bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 2741bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::CallExpr *RSClearObjectCall = 275e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines new(C) clang::CallExpr(C, 276e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines RSClearObjectFP, 277e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines &AddrRefRSVar, 278e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 1, 279e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines ClearObjectFD->getCallResultType(), 280e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines clang::SourceLocation()); 2811bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 2821bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines return RSClearObjectCall; 2831bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 2841bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 2854b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesbool RSObjectRefCount::InitializeRSObject(clang::VarDecl *VD) { 2864b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 2874b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines RSExportPrimitiveType::DataType DT = 2884b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines RSExportPrimitiveType::GetRSSpecificType(T); 2894b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 2904b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (DT == RSExportPrimitiveType::DataTypeUnknown) 2914b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return false; 2924b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 2934b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (VD->hasInit()) { 294e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines // TODO(srhines): Update the reference count of RS object in initializer. 2954b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // This can potentially be done as part of the assignment pass. 2964b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } else { 2974b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *ZeroInitializer = 2984b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines CreateZeroInitializerForRSSpecificType(DT, 2994b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines VD->getASTContext(), 3004b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines VD->getLocation()); 3014b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 3024b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (ZeroInitializer) { 3034b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines ZeroInitializer->setType(T->getCanonicalTypeInternal()); 3044b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines VD->setInit(ZeroInitializer); 3054b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 3064b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 3074b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 3084b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return RSExportPrimitiveType::IsRSObjectType(DT); 3094b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 3104b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 3114b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesclang::Expr *RSObjectRefCount::CreateZeroInitializerForRSSpecificType( 3124b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines RSExportPrimitiveType::DataType DT, 3134b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ASTContext &C, 3144b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines const clang::SourceLocation &Loc) { 3154b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *Res = NULL; 3164b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines switch (DT) { 3174b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSElement: 3184b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSType: 3194b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSAllocation: 3204b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSSampler: 3214b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSScript: 3224b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMesh: 3234b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramFragment: 3244b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramVertex: 3254b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramRaster: 3264b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramStore: 3274b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSFont: { 3284b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (ImplicitCastExpr 'nullptr_t' 3294b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (IntegerLiteral 0))) 3304b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APInt Zero(C.getTypeSize(C.IntTy), 0); 3314b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, Zero, C.IntTy, Loc); 3324b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *CastToNull = 3334b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ImplicitCastExpr::Create(C, 3344b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines C.NullPtrTy, 3354b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::CK_IntegralToPointer, 3364b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Int0, 3374b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines NULL, 3384b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::VK_RValue); 3394b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 340e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Res = new(C) clang::InitListExpr(C, Loc, &CastToNull, 1, Loc); 3414b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines break; 3424b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 3434b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMatrix2x2: 3444b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMatrix3x3: 3454b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMatrix4x4: { 3464b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // RS matrix is not completely an RS object. They hold data by themselves. 3474b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (InitListExpr rs_matrix2x2 3484b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (InitListExpr float[4] 3494b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 3504b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 3514b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 3524b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0))) 3534b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::QualType FloatTy = C.FloatTy; 3544b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Constructor sets value to 0.0f by default 3554b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APFloat Val(C.getFloatTypeSemantics(FloatTy)); 3564b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::FloatingLiteral *Float0Val = 3574b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::FloatingLiteral::Create(C, 3584b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Val, 3594b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines /* isExact = */true, 3604b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines FloatTy, 3614b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Loc); 3624b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 3634b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines unsigned N = 0; 3644b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (DT == RSExportPrimitiveType::DataTypeRSMatrix2x2) 3654b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 2; 3664b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines else if (DT == RSExportPrimitiveType::DataTypeRSMatrix3x3) 3674b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 3; 3684b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines else if (DT == RSExportPrimitiveType::DataTypeRSMatrix4x4) 3694b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 4; 3704b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 3714b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Directly allocate 16 elements instead of dynamically allocate N*N 3724b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *InitVals[16]; 3734b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (unsigned i = 0; i < sizeof(InitVals) / sizeof(InitVals[0]); i++) 3744b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines InitVals[i] = Float0Val; 3754b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *InitExpr = 376e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines new(C) clang::InitListExpr(C, Loc, InitVals, N * N, Loc); 3774b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines InitExpr->setType(C.getConstantArrayType(FloatTy, 3784b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APInt(32, 4), 3794b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ArrayType::Normal, 3804b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines /* EltTypeQuals = */0)); 3814b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 382e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Res = new(C) clang::InitListExpr(C, Loc, &InitExpr, 1, Loc); 3834b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines break; 3844b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 3854b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnknown: 3864b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeFloat16: 3874b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeFloat32: 3884b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeFloat64: 3894b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned8: 3904b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned16: 3914b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned32: 3924b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned64: 3934b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned8: 3944b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned16: 3954b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned32: 3964b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned64: 3974b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeBoolean: 3984b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned565: 3994b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned5551: 4004b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned4444: 4014b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeMax: { 4024b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines assert(false && "Not RS object type!"); 4034b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 4044b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // No default case will enable compiler detecting the missing cases 4054b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 4064b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 4074b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return Res; 4084b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 4094b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 4104b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitDeclStmt(clang::DeclStmt *DS) { 4114b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (clang::DeclStmt::decl_iterator I = DS->decl_begin(), E = DS->decl_end(); 4124b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I != E; 4134b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I++) { 4144b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Decl *D = *I; 4154b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (D->getKind() == clang::Decl::Var) { 4164b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::VarDecl *VD = static_cast<clang::VarDecl*>(D); 4174b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (InitializeRSObject(VD)) 4184b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines getCurrentScope()->addRSObject(VD); 4194b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 4204b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 4214b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 4224b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 4234b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 4244b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitCompoundStmt(clang::CompoundStmt *CS) { 4254b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (!CS->body_empty()) { 4264b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Push a new scope 4274b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Scope *S = new Scope(CS); 4284b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines mScopeStack.push(S); 4294b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 4304b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines VisitStmt(CS); 4314b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 4324b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Destroy the scope 433e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines // TODO(srhines): Update reference count of the RS object refenced by 434e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines // getCurrentScope(). 4354b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines assert((getCurrentScope() == S) && "Corrupted scope stack!"); 4361bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines S->InsertLocalVarDestructors(); 4374b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines mScopeStack.pop(); 4384b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines delete S; 4394b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 4404b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 4414b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 4424b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 4434b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitBinAssign(clang::BinaryOperator *AS) { 444e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines // TODO(srhines): Update reference count 4454b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 4464b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 4474b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 4484b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitStmt(clang::Stmt *S) { 4494b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end(); 4504b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I != E; 4514b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I++) { 4524b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (clang::Stmt *Child = *I) { 4534b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Visit(Child); 4544b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 4554b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 4564b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 4574b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 4584b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 459e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 460