slang_rs_object_ref_count.cpp revision 03981a308201b9123512297c8b9562a0f29bdf31
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, 93d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines std::list<clang::Stmt*> &StmtList, 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(); 1011bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1021bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines unsigned OldStmtCount = 0; 10303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines for (bI = CS->body_begin(); bI != CS->body_end(); bI++) { 1041bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines OldStmtCount++; 1051bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1061bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 107d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines unsigned NewStmtCount = StmtList.size(); 1081bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 109d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines clang::Stmt **UpdatedStmtList; 110d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines UpdatedStmtList = new clang::Stmt*[OldStmtCount+NewStmtCount]; 1111bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1121bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines unsigned UpdatedStmtCount = 0; 1134464d825c11349068f2917f9ebee86b721423f3cStephen Hines bool FoundReturn = false; 11403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines for (bI = CS->body_begin(); bI != CS->body_end(); bI++) { 1151bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if ((*bI)->getStmtClass() == clang::Stmt::ReturnStmtClass) { 1164464d825c11349068f2917f9ebee86b721423f3cStephen Hines FoundReturn = true; 1171bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines break; 1181bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 119d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines UpdatedStmtList[UpdatedStmtCount++] = *bI; 1201bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1211bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1224464d825c11349068f2917f9ebee86b721423f3cStephen Hines // Always insert before a return that we found, or if we are told 1234464d825c11349068f2917f9ebee86b721423f3cStephen Hines // to insert at the end of the block 1244464d825c11349068f2917f9ebee86b721423f3cStephen Hines if (FoundReturn || InsertAtEndOfBlock) { 12503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines std::list<clang::Stmt*>::const_iterator I = StmtList.begin(); 12603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines for (std::list<clang::Stmt*>::const_iterator I = StmtList.begin(); 12703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines I != StmtList.end(); 1284464d825c11349068f2917f9ebee86b721423f3cStephen Hines I++) { 129d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines UpdatedStmtList[UpdatedStmtCount++] = *I; 1304464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 1311bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1321bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1331bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Pick up anything left over after a return statement 13403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines for ( ; bI != CS->body_end(); bI++) { 135d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines UpdatedStmtList[UpdatedStmtCount++] = *bI; 1361bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1371bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 138d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines CS->setStmts(C, UpdatedStmtList, UpdatedStmtCount); 1391bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 140d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines delete [] UpdatedStmtList; 1411bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1421bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines return; 1431bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 1441bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 145d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines// This class visits a compound statement and inserts the StmtList containing 1464464d825c11349068f2917f9ebee86b721423f3cStephen Hines// destructors in proper locations. This includes inserting them before any 1474464d825c11349068f2917f9ebee86b721423f3cStephen Hines// return statement in any sub-block, at the end of the logical enclosing 1484464d825c11349068f2917f9ebee86b721423f3cStephen Hines// scope (compound statement), and/or before any break/continue statement that 1494464d825c11349068f2917f9ebee86b721423f3cStephen Hines// would resume outside the declared scope. We will not handle the case for 1504464d825c11349068f2917f9ebee86b721423f3cStephen Hines// goto statements that leave a local scope. 1514464d825c11349068f2917f9ebee86b721423f3cStephen Hines// TODO(srhines): Make this work properly for break/continue. 1524464d825c11349068f2917f9ebee86b721423f3cStephen Hinesclass DestructorVisitor : public clang::StmtVisitor<DestructorVisitor> { 1534464d825c11349068f2917f9ebee86b721423f3cStephen Hines private: 1544464d825c11349068f2917f9ebee86b721423f3cStephen Hines clang::ASTContext &mC; 155d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines std::list<clang::Stmt*> &mStmtList; 1564464d825c11349068f2917f9ebee86b721423f3cStephen Hines bool mTopLevel; 1574464d825c11349068f2917f9ebee86b721423f3cStephen Hines public: 158d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines DestructorVisitor(clang::ASTContext &C, std::list<clang::Stmt*> &StmtList); 1594464d825c11349068f2917f9ebee86b721423f3cStephen Hines void VisitStmt(clang::Stmt *S); 1604464d825c11349068f2917f9ebee86b721423f3cStephen Hines void VisitCompoundStmt(clang::CompoundStmt *CS); 1614464d825c11349068f2917f9ebee86b721423f3cStephen Hines}; 1624464d825c11349068f2917f9ebee86b721423f3cStephen Hines 1634464d825c11349068f2917f9ebee86b721423f3cStephen HinesDestructorVisitor::DestructorVisitor(clang::ASTContext &C, 164d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines std::list<clang::Stmt*> &StmtList) 1654464d825c11349068f2917f9ebee86b721423f3cStephen Hines : mC(C), 166d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines mStmtList(StmtList), 1674464d825c11349068f2917f9ebee86b721423f3cStephen Hines mTopLevel(true) { 1684464d825c11349068f2917f9ebee86b721423f3cStephen Hines return; 1694464d825c11349068f2917f9ebee86b721423f3cStephen Hines} 1704464d825c11349068f2917f9ebee86b721423f3cStephen Hines 1714464d825c11349068f2917f9ebee86b721423f3cStephen Hinesvoid DestructorVisitor::VisitCompoundStmt(clang::CompoundStmt *CS) { 1724464d825c11349068f2917f9ebee86b721423f3cStephen Hines if (!CS->body_empty()) { 173d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines AppendToCompoundStatement(mC, CS, mStmtList, mTopLevel); 1744464d825c11349068f2917f9ebee86b721423f3cStephen Hines mTopLevel = false; 1754464d825c11349068f2917f9ebee86b721423f3cStephen Hines VisitStmt(CS); 1764464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 1774464d825c11349068f2917f9ebee86b721423f3cStephen Hines return; 1784464d825c11349068f2917f9ebee86b721423f3cStephen Hines} 1794464d825c11349068f2917f9ebee86b721423f3cStephen Hines 1804464d825c11349068f2917f9ebee86b721423f3cStephen Hinesvoid DestructorVisitor::VisitStmt(clang::Stmt *S) { 1814464d825c11349068f2917f9ebee86b721423f3cStephen Hines for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end(); 1824464d825c11349068f2917f9ebee86b721423f3cStephen Hines I != E; 1834464d825c11349068f2917f9ebee86b721423f3cStephen Hines I++) { 1844464d825c11349068f2917f9ebee86b721423f3cStephen Hines if (clang::Stmt *Child = *I) { 1854464d825c11349068f2917f9ebee86b721423f3cStephen Hines Visit(Child); 1864464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 1874464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 1884464d825c11349068f2917f9ebee86b721423f3cStephen Hines return; 1894464d825c11349068f2917f9ebee86b721423f3cStephen Hines} 1904464d825c11349068f2917f9ebee86b721423f3cStephen Hines 19103981a308201b9123512297c8b9562a0f29bdf31Stephen Hinesstatic int ArrayDim(clang::VarDecl *VD) { 19203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 19303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 19403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (!T || !T->isArrayType()) { 19503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return 0; 19603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 19703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 19803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines const clang::ConstantArrayType *CAT = 19903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines static_cast<const clang::ConstantArrayType *>(T); 20003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return (int)CAT->getSize().getSExtValue(); 20103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines} 20203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 20303981a308201b9123512297c8b9562a0f29bdf31Stephen Hinesstatic clang::Stmt *ClearArrayRSObject(clang::VarDecl *VD, 20403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines const clang::Type *T, 20503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::FunctionDecl *ClearObjectFD) { 20603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::ASTContext &C = VD->getASTContext(); 20703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::SourceRange Range = VD->getQualifierRange(); 20803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::SourceLocation Loc = Range.getEnd(); 20903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 21003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Stmt *StmtArray[2] = {NULL}; 21103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines int StmtCtr = 0; 21203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 21303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines int NumArrayElements = ArrayDim(VD); 21403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (NumArrayElements <= 0) { 21503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return NULL; 21603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 21703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 21803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Example destructor loop for "rs_font fontArr[10];" 21903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // 22003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (CompoundStmt 22103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclStmt "int rsIntIter") 22203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ForStmt 22303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (BinaryOperator 'int' '=' 22403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter') 22503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (IntegerLiteral 'int' 0)) 22603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (BinaryOperator 'int' '<' 22703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter') 22803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (IntegerLiteral 'int' 10) 22903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // NULL << CondVar >> 23003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (UnaryOperator 'int' postfix '++' 23103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter')) 23203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (CallExpr 'void' 23303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ImplicitCastExpr 'void (*)(rs_font *)' <FunctionToPointerDecay> 23403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'void (rs_font *)' FunctionDecl='rsClearObject')) 23503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (UnaryOperator 'rs_font *' prefix '&' 23603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ArraySubscriptExpr 'rs_font':'rs_font' 23703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ImplicitCastExpr 'rs_font *' <ArrayToPointerDecay> 23803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'rs_font [10]' Var='fontArr')) 23903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter'))))))) 24003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 24103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Create helper variable for iterating through elements 24203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::IdentifierInfo& II = C.Idents.get("rsIntIter"); 24303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VarDecl *IIVD = 24403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VarDecl::Create(C, 24503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines VD->getDeclContext(), 24603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 24703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines &II, 24803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 24903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.getTrivialTypeSourceInfo(C.IntTy), 25003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::SC_None, 25103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::SC_None); 25203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Decl *IID = (clang::Decl *)IIVD; 25303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 25403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclGroupRef DGR = clang::DeclGroupRef::Create(C, &IID, 1); 25503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines StmtArray[StmtCtr++] = new(C) clang::DeclStmt(DGR, Loc, Loc); 25603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 25703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Form the actual destructor loop 25803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // for (Init; Cond; Inc) 25903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // RSClearObjectCall; 26003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 26103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Init -> "rsIntIter = 0" 26203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclRefExpr *RefrsIntIter = 26303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclRefExpr::Create(C, 26403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, 26503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Range, 26603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines IIVD, 26703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 26803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy); 26903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 27003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, 27103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), 0), C.IntTy, Loc); 27203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 27303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BinaryOperator *Init = 27403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 27503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Int0, 27603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BO_Assign, 27703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 27803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 27903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 28003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Cond -> "rsIntIter < NumArrayElements" 28103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *NumArrayElementsExpr = clang::IntegerLiteral::Create(C, 28203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), NumArrayElements), C.IntTy, Loc); 28303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 28403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BinaryOperator *Cond = 28503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 28603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NumArrayElementsExpr, 28703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BO_LT, 28803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 28903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 29003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 29103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Inc -> "rsIntIter++" 29203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::UnaryOperator *Inc = 29303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::UnaryOperator(RefrsIntIter, 29403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::UO_PostInc, 29503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 29603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 29703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 29803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Body -> "rsClearObject(&VD[rsIntIter]);" 29903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Destructor loop operates on individual array elements 30003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::QualType ClearObjectFDType = ClearObjectFD->getType(); 30103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::QualType ClearObjectFDArgType = 30203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ClearObjectFD->getParamDecl(0)->getOriginalType(); 30303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 30403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines const clang::Type *VT = RSExportType::GetTypeOfDecl(VD); 30503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclRefExpr *RefRSVar = 30603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclRefExpr::Create(C, 30703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, 30803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Range, 30903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines VD, 31003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 31103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines VT->getCanonicalTypeInternal()); 31203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 31303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *RefRSVarPtr = 31403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::ImplicitCastExpr::Create(C, 31503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.getPointerType(T->getCanonicalTypeInternal()), 31603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::CK_ArrayToPointerDecay, 31703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines RefRSVar, 31803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, 31903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VK_RValue); 32003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 32103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *RefRSVarPtrSubscript = 32203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::ArraySubscriptExpr(RefRSVarPtr, 32303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines RefrsIntIter, 32403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines T->getCanonicalTypeInternal(), 32503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines VD->getLocation()); 32603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 32703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *AddrRefRSVarPtrSubscript = 32803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::UnaryOperator(RefRSVarPtrSubscript, 32903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::UO_AddrOf, 33003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ClearObjectFDArgType, 33103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines VD->getLocation()); 33203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 33303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *RefRSClearObjectFD = 33403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclRefExpr::Create(C, 33503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, 33603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Range, 33703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ClearObjectFD, 33803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 33903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ClearObjectFDType); 34003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 34103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *RSClearObjectFP = 34203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::ImplicitCastExpr::Create(C, 34303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.getPointerType(ClearObjectFDType), 34403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::CK_FunctionToPointerDecay, 34503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines RefRSClearObjectFD, 34603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, 34703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VK_RValue); 34803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 34903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::CallExpr *RSClearObjectCall = 35003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::CallExpr(C, 35103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines RSClearObjectFP, 35203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines &AddrRefRSVarPtrSubscript, 35303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 1, 35403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ClearObjectFD->getCallResultType(), 35503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 35603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 35703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::ForStmt *DestructorLoop = 35803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::ForStmt(C, 35903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Init, 36003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Cond, 36103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, // no condVar 36203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Inc, 36303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines RSClearObjectCall, 36403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 36503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 36603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 36703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 36803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines StmtArray[StmtCtr++] = DestructorLoop; 36903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines assert(StmtCtr == 2); 37003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 37103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::CompoundStmt *CS = 37203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::CompoundStmt(C, StmtArray, StmtCtr, Loc, Loc); 37303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 37403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return CS; 37503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines} 37603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 3774464d825c11349068f2917f9ebee86b721423f3cStephen Hines} // namespace 3784464d825c11349068f2917f9ebee86b721423f3cStephen Hines 3791bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hinesvoid RSObjectRefCount::Scope::InsertLocalVarDestructors() { 380d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines std::list<clang::Stmt*> RSClearObjectCalls; 3811bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines for (std::list<clang::VarDecl*>::const_iterator I = mRSO.begin(), 3821bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines E = mRSO.end(); 3831bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines I != E; 3841bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines I++) { 385d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines clang::Stmt *E = ClearRSObject(*I); 3861bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if (E) { 3871bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSClearObjectCalls.push_back(E); 3881bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 3891bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 3901bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if (RSClearObjectCalls.size() > 0) { 3914464d825c11349068f2917f9ebee86b721423f3cStephen Hines DestructorVisitor DV((*mRSO.begin())->getASTContext(), RSClearObjectCalls); 3924464d825c11349068f2917f9ebee86b721423f3cStephen Hines DV.Visit(mCS); 3931bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 3941bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines return; 3951bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 3961bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 397d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hinesclang::Stmt *RSObjectRefCount::Scope::ClearRSObject(clang::VarDecl *VD) { 39803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines bool IsArrayType = false; 3991bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::ASTContext &C = VD->getASTContext(); 4001bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::SourceLocation Loc = VD->getLocation(); 4011bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 40203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 40303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Loop through array types to get to base type 40403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines while (T && T->isArrayType()) { 40503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines T = T->getArrayElementTypeNoTypeQual(); 40603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines IsArrayType = true; 40703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 40803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 4091bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSExportPrimitiveType::DataType DT = 4101bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSExportPrimitiveType::GetRSSpecificType(T); 4111bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 4121bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines assert((RSExportPrimitiveType::IsRSObjectType(DT)) && 4131bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines "Should be RS object"); 4141bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 4151bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Find the rsClearObject() for VD of RS object type DT 4161bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::FunctionDecl *ClearObjectFD = 4171bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSClearObjectFD[(DT - RSExportPrimitiveType::FirstRSObjectType)]; 4181bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines assert((ClearObjectFD != NULL) && 4191bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines "rsClearObject doesn't cover all RS object types"); 4201bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 42103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (IsArrayType) { 42203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return ClearArrayRSObject(VD, T, ClearObjectFD); 42303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 42403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 4251bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::QualType ClearObjectFDType = ClearObjectFD->getType(); 4261bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::QualType ClearObjectFDArgType = 4271bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines ClearObjectFD->getParamDecl(0)->getOriginalType(); 4281bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 42903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Example destructor for "rs_font localFont;" 43003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // 4311bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // (CallExpr 'void' 4321bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // (ImplicitCastExpr 'void (*)(rs_font *)' <FunctionToPointerDecay> 4331bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // (DeclRefExpr 'void (rs_font *)' FunctionDecl='rsClearObject')) 4341bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // (UnaryOperator 'rs_font *' prefix '&' 43503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'rs_font':'rs_font' Var='localFont'))) 4361bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 4371bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Reference expr to target RS object variable 4381bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::DeclRefExpr *RefRSVar = 4391bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::DeclRefExpr::Create(C, 4401bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines NULL, 4411bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines VD->getQualifierRange(), 4421bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines VD, 4431bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines Loc, 44403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines T->getCanonicalTypeInternal()); 4451bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 4461bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Get address of RSObject in VD 4471bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::Expr *AddrRefRSVar = 448e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines new(C) clang::UnaryOperator(RefRSVar, 449e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines clang::UO_AddrOf, 450e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines ClearObjectFDArgType, 451e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Loc); 4521bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 4531bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::Expr *RefRSClearObjectFD = 4541bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::DeclRefExpr::Create(C, 4551bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines NULL, 4561bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines ClearObjectFD->getQualifierRange(), 4571bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines ClearObjectFD, 4581bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines ClearObjectFD->getLocation(), 45903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ClearObjectFDType); 4601bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 4611bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::Expr *RSClearObjectFP = 4621bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::ImplicitCastExpr::Create(C, 4631bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines C.getPointerType(ClearObjectFDType), 4641bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::CK_FunctionToPointerDecay, 4651bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RefRSClearObjectFD, 4661bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines NULL, 4671bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::VK_RValue); 4681bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 4691bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::CallExpr *RSClearObjectCall = 470e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines new(C) clang::CallExpr(C, 471e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines RSClearObjectFP, 472e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines &AddrRefRSVar, 473e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 1, 474e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines ClearObjectFD->getCallResultType(), 475e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines clang::SourceLocation()); 4761bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 4771bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines return RSClearObjectCall; 4781bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 4791bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 4804b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesbool RSObjectRefCount::InitializeRSObject(clang::VarDecl *VD) { 4812d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines bool IsArrayType = false; 4824b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 4832d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines 4842d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines // Loop through array types to get to base type 4852d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines while (T && T->isArrayType()) { 4862d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines T = T->getArrayElementTypeNoTypeQual(); 4872d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines IsArrayType = true; 4882d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines } 4892d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines 4904b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines RSExportPrimitiveType::DataType DT = 4914b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines RSExportPrimitiveType::GetRSSpecificType(T); 4924b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 4932d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines if (DT == RSExportPrimitiveType::DataTypeUnknown) { 4944b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return false; 4952d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines } 4964b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 4974b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (VD->hasInit()) { 498e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines // TODO(srhines): Update the reference count of RS object in initializer. 4994b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // This can potentially be done as part of the assignment pass. 5004b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } else { 5014b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *ZeroInitializer = 5024b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines CreateZeroInitializerForRSSpecificType(DT, 5034b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines VD->getASTContext(), 5044b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines VD->getLocation()); 5054b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 5064b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (ZeroInitializer) { 5074b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines ZeroInitializer->setType(T->getCanonicalTypeInternal()); 5084b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines VD->setInit(ZeroInitializer); 5094b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 5104b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 5114b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 51203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return RSExportPrimitiveType::IsRSObjectType(DT); 5134b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 5144b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 5154b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesclang::Expr *RSObjectRefCount::CreateZeroInitializerForRSSpecificType( 5164b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines RSExportPrimitiveType::DataType DT, 5174b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ASTContext &C, 5184b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines const clang::SourceLocation &Loc) { 5194b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *Res = NULL; 5204b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines switch (DT) { 5214b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSElement: 5224b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSType: 5234b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSAllocation: 5244b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSSampler: 5254b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSScript: 5264b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMesh: 5274b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramFragment: 5284b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramVertex: 5294b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramRaster: 5304b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramStore: 5314b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSFont: { 5324b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (ImplicitCastExpr 'nullptr_t' 5334b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (IntegerLiteral 0))) 5344b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APInt Zero(C.getTypeSize(C.IntTy), 0); 5354b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, Zero, C.IntTy, Loc); 5364b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *CastToNull = 5374b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ImplicitCastExpr::Create(C, 5384b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines C.NullPtrTy, 5394b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::CK_IntegralToPointer, 5404b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Int0, 5414b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines NULL, 5424b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::VK_RValue); 5434b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 544e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Res = new(C) clang::InitListExpr(C, Loc, &CastToNull, 1, Loc); 5454b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines break; 5464b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 5474b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMatrix2x2: 5484b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMatrix3x3: 5494b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMatrix4x4: { 5504b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // RS matrix is not completely an RS object. They hold data by themselves. 5514b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (InitListExpr rs_matrix2x2 5524b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (InitListExpr float[4] 5534b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 5544b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 5554b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 5564b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0))) 5574b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::QualType FloatTy = C.FloatTy; 5584b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Constructor sets value to 0.0f by default 5594b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APFloat Val(C.getFloatTypeSemantics(FloatTy)); 5604b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::FloatingLiteral *Float0Val = 5614b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::FloatingLiteral::Create(C, 5624b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Val, 5634b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines /* isExact = */true, 5644b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines FloatTy, 5654b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Loc); 5664b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 5674b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines unsigned N = 0; 5684b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (DT == RSExportPrimitiveType::DataTypeRSMatrix2x2) 5694b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 2; 5704b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines else if (DT == RSExportPrimitiveType::DataTypeRSMatrix3x3) 5714b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 3; 5724b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines else if (DT == RSExportPrimitiveType::DataTypeRSMatrix4x4) 5734b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 4; 5744b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 5754b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Directly allocate 16 elements instead of dynamically allocate N*N 5764b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *InitVals[16]; 5774b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (unsigned i = 0; i < sizeof(InitVals) / sizeof(InitVals[0]); i++) 5784b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines InitVals[i] = Float0Val; 5794b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *InitExpr = 580e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines new(C) clang::InitListExpr(C, Loc, InitVals, N * N, Loc); 5814b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines InitExpr->setType(C.getConstantArrayType(FloatTy, 5824b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APInt(32, 4), 5834b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ArrayType::Normal, 5844b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines /* EltTypeQuals = */0)); 5854b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 586e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Res = new(C) clang::InitListExpr(C, Loc, &InitExpr, 1, Loc); 5874b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines break; 5884b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 5894b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnknown: 5904b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeFloat16: 5914b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeFloat32: 5924b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeFloat64: 5934b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned8: 5944b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned16: 5954b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned32: 5964b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned64: 5974b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned8: 5984b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned16: 5994b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned32: 6004b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned64: 6014b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeBoolean: 6024b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned565: 6034b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned5551: 6044b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned4444: 6054b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeMax: { 6064b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines assert(false && "Not RS object type!"); 6074b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 6084b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // No default case will enable compiler detecting the missing cases 6094b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 6104b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 6114b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return Res; 6124b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 6134b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 6144b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitDeclStmt(clang::DeclStmt *DS) { 6154b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (clang::DeclStmt::decl_iterator I = DS->decl_begin(), E = DS->decl_end(); 6164b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I != E; 6174b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I++) { 6184b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Decl *D = *I; 6194b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (D->getKind() == clang::Decl::Var) { 6204b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::VarDecl *VD = static_cast<clang::VarDecl*>(D); 6214b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (InitializeRSObject(VD)) 6224b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines getCurrentScope()->addRSObject(VD); 6234b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 6244b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 6254b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 6264b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 6274b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 6284b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitCompoundStmt(clang::CompoundStmt *CS) { 6294b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (!CS->body_empty()) { 6304b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Push a new scope 6314b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Scope *S = new Scope(CS); 6324b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines mScopeStack.push(S); 6334b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 6344b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines VisitStmt(CS); 6354b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 6364b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Destroy the scope 637e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines // TODO(srhines): Update reference count of the RS object refenced by 638e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines // getCurrentScope(). 6394b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines assert((getCurrentScope() == S) && "Corrupted scope stack!"); 6401bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines S->InsertLocalVarDestructors(); 6414b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines mScopeStack.pop(); 6424b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines delete S; 6434b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 6444b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 6454b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 6464b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 6474b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitBinAssign(clang::BinaryOperator *AS) { 648e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines // TODO(srhines): Update reference count 6494b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 6504b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 6514b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 6524b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitStmt(clang::Stmt *S) { 6534b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end(); 6544b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I != E; 6554b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I++) { 6564b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (clang::Stmt *Child = *I) { 6574b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Visit(Child); 6584b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 6594b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 6604b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 6614b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 6624b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 663e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 664