slang_rs_object_ref_count.cpp revision 6e6578a360497f78a181e63d7783422a9c9bfb15
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 276e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h" 284b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "slang_rs.h" 294b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "slang_rs_export_type.h" 304b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 31e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang { 324b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 331bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hinesclang::FunctionDecl *RSObjectRefCount::Scope:: 341bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSSetObjectFD[RSExportPrimitiveType::LastRSObjectType - 351bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSExportPrimitiveType::FirstRSObjectType + 1]; 361bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hinesclang::FunctionDecl *RSObjectRefCount::Scope:: 371bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSClearObjectFD[RSExportPrimitiveType::LastRSObjectType - 381bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSExportPrimitiveType::FirstRSObjectType + 1]; 391bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 401bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hinesvoid RSObjectRefCount::Scope::GetRSRefCountingFunctions( 411bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::ASTContext &C) { 421bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines for (unsigned i = 0; 431bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines i < (sizeof(RSClearObjectFD) / sizeof(clang::FunctionDecl*)); 441bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines i++) { 451bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSSetObjectFD[i] = NULL; 461bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSClearObjectFD[i] = NULL; 471bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 481bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 491bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl(); 501bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 511bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(), 521bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines E = TUDecl->decls_end(); I != E; I++) { 531bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if ((I->getKind() >= clang::Decl::firstFunction) && 541bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines (I->getKind() <= clang::Decl::lastFunction)) { 551bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::FunctionDecl *FD = static_cast<clang::FunctionDecl*>(*I); 561bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 571bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // points to RSSetObjectFD or RSClearObjectFD 581bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::FunctionDecl **RSObjectFD; 591bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 601bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if (FD->getName() == "rsSetObject") { 616e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((FD->getNumParams() == 2) && 626e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "Invalid rsSetObject function prototype (# params)"); 631bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSObjectFD = RSSetObjectFD; 641bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } else if (FD->getName() == "rsClearObject") { 656e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((FD->getNumParams() == 1) && 666e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "Invalid rsClearObject function prototype (# params)"); 671bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSObjectFD = RSClearObjectFD; 68e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines } else { 691bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines continue; 701bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 711bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 721bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines const clang::ParmVarDecl *PVD = FD->getParamDecl(0); 731bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::QualType PVT = PVD->getOriginalType(); 741bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // The first parameter must be a pointer like rs_allocation* 756e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(PVT->isPointerType() && 766e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "Invalid rs{Set,Clear}Object function prototype (pointer param)"); 771bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 781bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // The rs object type passed to the FD 791bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::QualType RST = PVT->getPointeeType(); 801bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSExportPrimitiveType::DataType DT = 811bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSExportPrimitiveType::GetRSSpecificType(RST.getTypePtr()); 826e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(RSExportPrimitiveType::IsRSObjectType(DT) 831bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines && "must be RS object type"); 841bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 851bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSObjectFD[(DT - RSExportPrimitiveType::FirstRSObjectType)] = FD; 861bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 871bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 881bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 891bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 904464d825c11349068f2917f9ebee86b721423f3cStephen Hinesnamespace { 914464d825c11349068f2917f9ebee86b721423f3cStephen Hines 924464d825c11349068f2917f9ebee86b721423f3cStephen Hinesstatic void AppendToCompoundStatement(clang::ASTContext& C, 934464d825c11349068f2917f9ebee86b721423f3cStephen Hines clang::CompoundStmt *CS, 94d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines std::list<clang::Stmt*> &StmtList, 954464d825c11349068f2917f9ebee86b721423f3cStephen Hines bool InsertAtEndOfBlock) { 961bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Destructor code will be inserted before any return statement. 971bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Any subsequent statements in the compound statement are then placed 981bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // after our new code. 99e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines // TODO(srhines): This should also handle the case of goto/break/continue. 1004464d825c11349068f2917f9ebee86b721423f3cStephen Hines 1014464d825c11349068f2917f9ebee86b721423f3cStephen Hines clang::CompoundStmt::body_iterator bI = CS->body_begin(); 1021bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1031bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines unsigned OldStmtCount = 0; 10403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines for (bI = CS->body_begin(); bI != CS->body_end(); bI++) { 1051bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines OldStmtCount++; 1061bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1071bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 108d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines unsigned NewStmtCount = StmtList.size(); 1091bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 110d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines clang::Stmt **UpdatedStmtList; 111d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines UpdatedStmtList = new clang::Stmt*[OldStmtCount+NewStmtCount]; 1121bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1131bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines unsigned UpdatedStmtCount = 0; 1144464d825c11349068f2917f9ebee86b721423f3cStephen Hines bool FoundReturn = false; 11503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines for (bI = CS->body_begin(); bI != CS->body_end(); bI++) { 1161bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if ((*bI)->getStmtClass() == clang::Stmt::ReturnStmtClass) { 1174464d825c11349068f2917f9ebee86b721423f3cStephen Hines FoundReturn = true; 1181bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines break; 1191bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 120d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines UpdatedStmtList[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) { 12603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines std::list<clang::Stmt*>::const_iterator I = StmtList.begin(); 12703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines for (std::list<clang::Stmt*>::const_iterator I = StmtList.begin(); 12803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines I != StmtList.end(); 1294464d825c11349068f2917f9ebee86b721423f3cStephen Hines I++) { 130d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines UpdatedStmtList[UpdatedStmtCount++] = *I; 1314464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 1321bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1331bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1341bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Pick up anything left over after a return statement 13503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines for ( ; bI != CS->body_end(); bI++) { 136d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines UpdatedStmtList[UpdatedStmtCount++] = *bI; 1371bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1381bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 139d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines CS->setStmts(C, UpdatedStmtList, UpdatedStmtCount); 1401bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 141d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines delete [] UpdatedStmtList; 1421bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1431bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines return; 1441bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 1451bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 146e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hinesstatic void AppendAfterStmt(clang::ASTContext& C, 147e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CompoundStmt *CS, 148e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Stmt *OldStmt, 149e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Stmt *NewStmt) { 1506e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(CS && OldStmt && NewStmt); 151e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CompoundStmt::body_iterator bI = CS->body_begin(); 152e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines unsigned StmtCount = 1; // Take into account new statement 153e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines for (bI = CS->body_begin(); bI != CS->body_end(); bI++) { 154e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines StmtCount++; 155e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 156e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 157e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Stmt **UpdatedStmtList = new clang::Stmt*[StmtCount]; 158e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 159e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines unsigned UpdatedStmtCount = 0; 160e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines unsigned Once = 0; 161e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines for (bI = CS->body_begin(); bI != CS->body_end(); bI++) { 162e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines UpdatedStmtList[UpdatedStmtCount++] = *bI; 163e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (*bI == OldStmt) { 164e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Once++; 1656e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(Once == 1); 166e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines UpdatedStmtList[UpdatedStmtCount++] = NewStmt; 167e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 168e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 169e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 170e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines CS->setStmts(C, UpdatedStmtList, UpdatedStmtCount); 171e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 172e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines delete [] UpdatedStmtList; 173e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 174e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return; 175e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines} 176e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 177e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hinesstatic void ReplaceInCompoundStmt(clang::ASTContext& C, 178c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::CompoundStmt *CS, 179c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Stmt* OldStmt, 180c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Stmt* NewStmt) { 181c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::CompoundStmt::body_iterator bI = CS->body_begin(); 182c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 183c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines unsigned StmtCount = 0; 184c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines for (bI = CS->body_begin(); bI != CS->body_end(); bI++) { 185c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines StmtCount++; 186c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 187c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 188c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Stmt **UpdatedStmtList = new clang::Stmt*[StmtCount]; 189c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 190c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines unsigned UpdatedStmtCount = 0; 191c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines for (bI = CS->body_begin(); bI != CS->body_end(); bI++) { 192c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines if (*bI == OldStmt) { 193c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines UpdatedStmtList[UpdatedStmtCount++] = NewStmt; 194c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } else { 195c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines UpdatedStmtList[UpdatedStmtCount++] = *bI; 196c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 197c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 198c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 199c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines CS->setStmts(C, UpdatedStmtList, UpdatedStmtCount); 200c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 201c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines delete [] UpdatedStmtList; 202c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 203c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines return; 204c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines} 205c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 206c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 207d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines// This class visits a compound statement and inserts the StmtList containing 2084464d825c11349068f2917f9ebee86b721423f3cStephen Hines// destructors in proper locations. This includes inserting them before any 2094464d825c11349068f2917f9ebee86b721423f3cStephen Hines// return statement in any sub-block, at the end of the logical enclosing 2104464d825c11349068f2917f9ebee86b721423f3cStephen Hines// scope (compound statement), and/or before any break/continue statement that 2114464d825c11349068f2917f9ebee86b721423f3cStephen Hines// would resume outside the declared scope. We will not handle the case for 2124464d825c11349068f2917f9ebee86b721423f3cStephen Hines// goto statements that leave a local scope. 2134464d825c11349068f2917f9ebee86b721423f3cStephen Hines// TODO(srhines): Make this work properly for break/continue. 2144464d825c11349068f2917f9ebee86b721423f3cStephen Hinesclass DestructorVisitor : public clang::StmtVisitor<DestructorVisitor> { 2154464d825c11349068f2917f9ebee86b721423f3cStephen Hines private: 2164464d825c11349068f2917f9ebee86b721423f3cStephen Hines clang::ASTContext &mC; 217d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines std::list<clang::Stmt*> &mStmtList; 2184464d825c11349068f2917f9ebee86b721423f3cStephen Hines bool mTopLevel; 2194464d825c11349068f2917f9ebee86b721423f3cStephen Hines public: 220d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines DestructorVisitor(clang::ASTContext &C, std::list<clang::Stmt*> &StmtList); 2214464d825c11349068f2917f9ebee86b721423f3cStephen Hines void VisitStmt(clang::Stmt *S); 2224464d825c11349068f2917f9ebee86b721423f3cStephen Hines void VisitCompoundStmt(clang::CompoundStmt *CS); 2234464d825c11349068f2917f9ebee86b721423f3cStephen Hines}; 2244464d825c11349068f2917f9ebee86b721423f3cStephen Hines 2254464d825c11349068f2917f9ebee86b721423f3cStephen HinesDestructorVisitor::DestructorVisitor(clang::ASTContext &C, 226d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines std::list<clang::Stmt*> &StmtList) 2274464d825c11349068f2917f9ebee86b721423f3cStephen Hines : mC(C), 228d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines mStmtList(StmtList), 2294464d825c11349068f2917f9ebee86b721423f3cStephen Hines mTopLevel(true) { 2304464d825c11349068f2917f9ebee86b721423f3cStephen Hines return; 2314464d825c11349068f2917f9ebee86b721423f3cStephen Hines} 2324464d825c11349068f2917f9ebee86b721423f3cStephen Hines 2334464d825c11349068f2917f9ebee86b721423f3cStephen Hinesvoid DestructorVisitor::VisitCompoundStmt(clang::CompoundStmt *CS) { 2344464d825c11349068f2917f9ebee86b721423f3cStephen Hines if (!CS->body_empty()) { 235d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines AppendToCompoundStatement(mC, CS, mStmtList, mTopLevel); 2364464d825c11349068f2917f9ebee86b721423f3cStephen Hines mTopLevel = false; 2374464d825c11349068f2917f9ebee86b721423f3cStephen Hines VisitStmt(CS); 2384464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 2394464d825c11349068f2917f9ebee86b721423f3cStephen Hines return; 2404464d825c11349068f2917f9ebee86b721423f3cStephen Hines} 2414464d825c11349068f2917f9ebee86b721423f3cStephen Hines 2424464d825c11349068f2917f9ebee86b721423f3cStephen Hinesvoid DestructorVisitor::VisitStmt(clang::Stmt *S) { 2434464d825c11349068f2917f9ebee86b721423f3cStephen Hines for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end(); 2444464d825c11349068f2917f9ebee86b721423f3cStephen Hines I != E; 2454464d825c11349068f2917f9ebee86b721423f3cStephen Hines I++) { 2464464d825c11349068f2917f9ebee86b721423f3cStephen Hines if (clang::Stmt *Child = *I) { 2474464d825c11349068f2917f9ebee86b721423f3cStephen Hines Visit(Child); 2484464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 2494464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 2504464d825c11349068f2917f9ebee86b721423f3cStephen Hines return; 2514464d825c11349068f2917f9ebee86b721423f3cStephen Hines} 2524464d825c11349068f2917f9ebee86b721423f3cStephen Hines 25303981a308201b9123512297c8b9562a0f29bdf31Stephen Hinesstatic int ArrayDim(clang::VarDecl *VD) { 25403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 25503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 25603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (!T || !T->isArrayType()) { 25703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return 0; 25803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 25903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 26003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines const clang::ConstantArrayType *CAT = 26103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines static_cast<const clang::ConstantArrayType *>(T); 2629d2c0fa6490e09b3ff5603796bce42d97788e5c8Stephen Hines return static_cast<int>(CAT->getSize().getSExtValue()); 26303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines} 26403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 26503981a308201b9123512297c8b9562a0f29bdf31Stephen Hinesstatic clang::Stmt *ClearArrayRSObject(clang::VarDecl *VD, 26603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines const clang::Type *T, 26703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::FunctionDecl *ClearObjectFD) { 26803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::ASTContext &C = VD->getASTContext(); 26903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::SourceRange Range = VD->getQualifierRange(); 27003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::SourceLocation Loc = Range.getEnd(); 27103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 27203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Stmt *StmtArray[2] = {NULL}; 27303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines int StmtCtr = 0; 27403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 27503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines int NumArrayElements = ArrayDim(VD); 27603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (NumArrayElements <= 0) { 27703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return NULL; 27803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 27903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 28003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Example destructor loop for "rs_font fontArr[10];" 28103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // 28203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (CompoundStmt 28303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclStmt "int rsIntIter") 28403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ForStmt 28503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (BinaryOperator 'int' '=' 28603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter') 28703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (IntegerLiteral 'int' 0)) 28803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (BinaryOperator 'int' '<' 28903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter') 29003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (IntegerLiteral 'int' 10) 29103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // NULL << CondVar >> 29203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (UnaryOperator 'int' postfix '++' 29303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter')) 29403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (CallExpr 'void' 29503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ImplicitCastExpr 'void (*)(rs_font *)' <FunctionToPointerDecay> 29603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'void (rs_font *)' FunctionDecl='rsClearObject')) 29703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (UnaryOperator 'rs_font *' prefix '&' 29803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ArraySubscriptExpr 'rs_font':'rs_font' 29903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ImplicitCastExpr 'rs_font *' <ArrayToPointerDecay> 30003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'rs_font [10]' Var='fontArr')) 30103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter'))))))) 30203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 30303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Create helper variable for iterating through elements 30403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::IdentifierInfo& II = C.Idents.get("rsIntIter"); 30503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VarDecl *IIVD = 30603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VarDecl::Create(C, 30703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines VD->getDeclContext(), 30803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 30903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines &II, 31003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 31103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.getTrivialTypeSourceInfo(C.IntTy), 31203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::SC_None, 31303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::SC_None); 31403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Decl *IID = (clang::Decl *)IIVD; 31503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 31603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclGroupRef DGR = clang::DeclGroupRef::Create(C, &IID, 1); 31703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines StmtArray[StmtCtr++] = new(C) clang::DeclStmt(DGR, Loc, Loc); 31803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 31903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Form the actual destructor loop 32003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // for (Init; Cond; Inc) 32103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // RSClearObjectCall; 32203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 32303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Init -> "rsIntIter = 0" 32403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclRefExpr *RefrsIntIter = 32503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclRefExpr::Create(C, 32603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, 32703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Range, 32803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines IIVD, 32903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 33003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy); 33103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 33203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, 33303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), 0), C.IntTy, Loc); 33403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 33503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BinaryOperator *Init = 33603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 33703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Int0, 33803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BO_Assign, 33903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 34003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 34103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 34203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Cond -> "rsIntIter < NumArrayElements" 34303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *NumArrayElementsExpr = clang::IntegerLiteral::Create(C, 34403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), NumArrayElements), C.IntTy, Loc); 34503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 34603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BinaryOperator *Cond = 34703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 34803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NumArrayElementsExpr, 34903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BO_LT, 35003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 35103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 35203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 35303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Inc -> "rsIntIter++" 35403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::UnaryOperator *Inc = 35503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::UnaryOperator(RefrsIntIter, 35603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::UO_PostInc, 35703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 35803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 35903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 36003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Body -> "rsClearObject(&VD[rsIntIter]);" 36103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Destructor loop operates on individual array elements 36203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::QualType ClearObjectFDType = ClearObjectFD->getType(); 36303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::QualType ClearObjectFDArgType = 36403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ClearObjectFD->getParamDecl(0)->getOriginalType(); 36503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 36603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines const clang::Type *VT = RSExportType::GetTypeOfDecl(VD); 36703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclRefExpr *RefRSVar = 36803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclRefExpr::Create(C, 36903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, 37003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Range, 37103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines VD, 37203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 37303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines VT->getCanonicalTypeInternal()); 37403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 37503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *RefRSVarPtr = 37603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::ImplicitCastExpr::Create(C, 37703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.getPointerType(T->getCanonicalTypeInternal()), 37803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::CK_ArrayToPointerDecay, 37903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines RefRSVar, 38003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, 38103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VK_RValue); 38203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 38303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *RefRSVarPtrSubscript = 38403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::ArraySubscriptExpr(RefRSVarPtr, 38503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines RefrsIntIter, 38603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines T->getCanonicalTypeInternal(), 38703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines VD->getLocation()); 38803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 38903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *AddrRefRSVarPtrSubscript = 39003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::UnaryOperator(RefRSVarPtrSubscript, 39103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::UO_AddrOf, 39203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ClearObjectFDArgType, 39303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines VD->getLocation()); 39403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 39503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *RefRSClearObjectFD = 39603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclRefExpr::Create(C, 39703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, 39803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Range, 39903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ClearObjectFD, 40003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 40103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ClearObjectFDType); 40203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 40303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *RSClearObjectFP = 40403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::ImplicitCastExpr::Create(C, 40503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.getPointerType(ClearObjectFDType), 40603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::CK_FunctionToPointerDecay, 40703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines RefRSClearObjectFD, 40803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, 40903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VK_RValue); 41003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 41103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::CallExpr *RSClearObjectCall = 41203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::CallExpr(C, 41303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines RSClearObjectFP, 41403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines &AddrRefRSVarPtrSubscript, 41503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 1, 41603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ClearObjectFD->getCallResultType(), 41703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 41803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 41903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::ForStmt *DestructorLoop = 42003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::ForStmt(C, 42103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Init, 42203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Cond, 42303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, // no condVar 42403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Inc, 42503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines RSClearObjectCall, 42603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 42703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 42803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 42903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 43003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines StmtArray[StmtCtr++] = DestructorLoop; 4316e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(StmtCtr == 2); 43203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 43303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::CompoundStmt *CS = 43403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::CompoundStmt(C, StmtArray, StmtCtr, Loc, Loc); 43503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 43603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return CS; 43703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines} 43803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 4394464d825c11349068f2917f9ebee86b721423f3cStephen Hines} // namespace 4404464d825c11349068f2917f9ebee86b721423f3cStephen Hines 441c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hinesvoid RSObjectRefCount::Scope::ReplaceRSObjectAssignment( 442c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::BinaryOperator *AS) { 443c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 444c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType QT = AS->getType(); 445c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RSExportPrimitiveType::DataType DT = 446c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RSExportPrimitiveType::GetRSSpecificType(QT.getTypePtr()); 447c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 448c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::FunctionDecl *SetObjectFD = 449c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RSSetObjectFD[(DT - RSExportPrimitiveType::FirstRSObjectType)]; 4506e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((SetObjectFD != NULL) && 4516e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "rsSetObject doesn't cover all RS object types"); 452c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::ASTContext &C = SetObjectFD->getASTContext(); 453c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 454c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType SetObjectFDType = SetObjectFD->getType(); 455c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType SetObjectFDArgType[2]; 456c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDArgType[0] = SetObjectFD->getParamDecl(0)->getOriginalType(); 457c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDArgType[1] = SetObjectFD->getParamDecl(1)->getOriginalType(); 458c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 459c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::SourceLocation Loc = SetObjectFD->getLocation(); 460c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Expr *RefRSSetObjectFD = 461c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::DeclRefExpr::Create(C, 462c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines NULL, 463c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFD->getQualifierRange(), 464c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFD, 465c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines Loc, 466c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDType); 467c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 468c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Expr *RSSetObjectFP = 469c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::ImplicitCastExpr::Create(C, 470c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines C.getPointerType(SetObjectFDType), 471c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::CK_FunctionToPointerDecay, 472c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RefRSSetObjectFD, 473c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines NULL, 474c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::VK_RValue); 475c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 476c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Expr *ArgList[2]; 477c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines ArgList[0] = new(C) clang::UnaryOperator(AS->getLHS(), 478c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::UO_AddrOf, 479c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDArgType[0], 480c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines Loc); 481c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines ArgList[1] = AS->getRHS(); 482c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 483c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::CallExpr *RSSetObjectCall = 484c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines new(C) clang::CallExpr(C, 485c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RSSetObjectFP, 486c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines ArgList, 487c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 2, 488c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFD->getCallResultType(), 489c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines Loc); 490c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 491e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ReplaceInCompoundStmt(C, mCS, AS, RSSetObjectCall); 492e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 493e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return; 494e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines} 495e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 496e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hinesvoid RSObjectRefCount::Scope::AppendRSObjectInit( 497e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::VarDecl *VD, 498e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclStmt *DS, 499e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataType DT, 500e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *InitExpr) { 5016e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(VD); 502e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 503e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (!InitExpr) { 504e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return; 505e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 506e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 507e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::FunctionDecl *SetObjectFD = 508e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSSetObjectFD[(DT - RSExportPrimitiveType::FirstRSObjectType)]; 5096e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((SetObjectFD != NULL) && 5106e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "rsSetObject doesn't cover all RS object types"); 511e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::ASTContext &C = SetObjectFD->getASTContext(); 512e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 513e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::QualType SetObjectFDType = SetObjectFD->getType(); 514e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::QualType SetObjectFDArgType[2]; 515e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDArgType[0] = SetObjectFD->getParamDecl(0)->getOriginalType(); 516e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDArgType[1] = SetObjectFD->getParamDecl(1)->getOriginalType(); 517e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 518e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::SourceLocation Loc = SetObjectFD->getLocation(); 519e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *RefRSSetObjectFD = 520e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr::Create(C, 521e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines NULL, 522e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFD->getQualifierRange(), 523e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFD, 524e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc, 525e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDType); 526e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 527e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *RSSetObjectFP = 528e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::ImplicitCastExpr::Create(C, 529e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines C.getPointerType(SetObjectFDType), 530e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CK_FunctionToPointerDecay, 531e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RefRSSetObjectFD, 532e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines NULL, 533e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::VK_RValue); 534e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 535e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 536e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr *RefRSVar = 537e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr::Create(C, 538e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines NULL, 539e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->getQualifierRange(), 540e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD, 541e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc, 542e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines T->getCanonicalTypeInternal()); 543e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 544e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *ArgList[2]; 545e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ArgList[0] = new(C) clang::UnaryOperator(RefRSVar, 546e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::UO_AddrOf, 547e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDArgType[0], 548e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc); 549e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ArgList[1] = InitExpr; 550e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 551e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CallExpr *RSSetObjectCall = 552e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines new(C) clang::CallExpr(C, 553e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSSetObjectFP, 554e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ArgList, 555e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 2, 556e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFD->getCallResultType(), 557e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc); 558e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 559e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines AppendAfterStmt(C, mCS, DS, RSSetObjectCall); 560c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 561c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines return; 562c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines} 563c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 5641bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hinesvoid RSObjectRefCount::Scope::InsertLocalVarDestructors() { 565d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines std::list<clang::Stmt*> RSClearObjectCalls; 5661bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines for (std::list<clang::VarDecl*>::const_iterator I = mRSO.begin(), 5671bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines E = mRSO.end(); 5681bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines I != E; 5691bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines I++) { 570a858cb6f3d9223d65bf73e1230c6324ded4095f6Stephen Hines clang::Stmt *S = ClearRSObject(*I); 571a858cb6f3d9223d65bf73e1230c6324ded4095f6Stephen Hines if (S) { 572a858cb6f3d9223d65bf73e1230c6324ded4095f6Stephen Hines RSClearObjectCalls.push_back(S); 5731bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 5741bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 5751bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if (RSClearObjectCalls.size() > 0) { 5764464d825c11349068f2917f9ebee86b721423f3cStephen Hines DestructorVisitor DV((*mRSO.begin())->getASTContext(), RSClearObjectCalls); 5774464d825c11349068f2917f9ebee86b721423f3cStephen Hines DV.Visit(mCS); 5781bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 5791bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines return; 5801bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 5811bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 582d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hinesclang::Stmt *RSObjectRefCount::Scope::ClearRSObject(clang::VarDecl *VD) { 58303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines bool IsArrayType = false; 5841bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::ASTContext &C = VD->getASTContext(); 5851bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::SourceLocation Loc = VD->getLocation(); 5861bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 58703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 58803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Loop through array types to get to base type 58903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines while (T && T->isArrayType()) { 59003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines T = T->getArrayElementTypeNoTypeQual(); 59103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines IsArrayType = true; 59203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 59303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 5941bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSExportPrimitiveType::DataType DT = 5951bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSExportPrimitiveType::GetRSSpecificType(T); 5961bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 5976e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((RSExportPrimitiveType::IsRSObjectType(DT)) && 5986e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "Should be RS object"); 5991bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 6001bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Find the rsClearObject() for VD of RS object type DT 6011bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::FunctionDecl *ClearObjectFD = 6021bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSClearObjectFD[(DT - RSExportPrimitiveType::FirstRSObjectType)]; 6036e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((ClearObjectFD != NULL) && 6046e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "rsClearObject doesn't cover all RS object types"); 6051bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 60603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (IsArrayType) { 60703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return ClearArrayRSObject(VD, T, ClearObjectFD); 60803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 60903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 6101bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::QualType ClearObjectFDType = ClearObjectFD->getType(); 6111bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::QualType ClearObjectFDArgType = 6121bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines ClearObjectFD->getParamDecl(0)->getOriginalType(); 6131bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 61403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Example destructor for "rs_font localFont;" 61503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // 6161bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // (CallExpr 'void' 6171bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // (ImplicitCastExpr 'void (*)(rs_font *)' <FunctionToPointerDecay> 6181bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // (DeclRefExpr 'void (rs_font *)' FunctionDecl='rsClearObject')) 6191bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // (UnaryOperator 'rs_font *' prefix '&' 62003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'rs_font':'rs_font' Var='localFont'))) 6211bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 6221bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Reference expr to target RS object variable 6231bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::DeclRefExpr *RefRSVar = 6241bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::DeclRefExpr::Create(C, 6251bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines NULL, 6261bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines VD->getQualifierRange(), 6271bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines VD, 6281bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines Loc, 62903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines T->getCanonicalTypeInternal()); 6301bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 6311bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Get address of RSObject in VD 6321bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::Expr *AddrRefRSVar = 633e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines new(C) clang::UnaryOperator(RefRSVar, 634e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines clang::UO_AddrOf, 635e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines ClearObjectFDArgType, 636e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Loc); 6371bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 6381bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::Expr *RefRSClearObjectFD = 6391bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::DeclRefExpr::Create(C, 6401bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines NULL, 6411bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines ClearObjectFD->getQualifierRange(), 6421bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines ClearObjectFD, 6431bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines ClearObjectFD->getLocation(), 64403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ClearObjectFDType); 6451bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 6461bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::Expr *RSClearObjectFP = 6471bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::ImplicitCastExpr::Create(C, 6481bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines C.getPointerType(ClearObjectFDType), 6491bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::CK_FunctionToPointerDecay, 6501bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RefRSClearObjectFD, 6511bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines NULL, 6521bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::VK_RValue); 6531bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 6541bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::CallExpr *RSClearObjectCall = 655e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines new(C) clang::CallExpr(C, 656e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines RSClearObjectFP, 657e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines &AddrRefRSVar, 658e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 1, 659e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines ClearObjectFD->getCallResultType(), 660e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines clang::SourceLocation()); 6611bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 6621bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines return RSClearObjectCall; 6631bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 6641bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 665e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hinesbool RSObjectRefCount::InitializeRSObject(clang::VarDecl *VD, 666e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataType *DT, 667e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr **InitExpr) { 6686e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(VD && DT && InitExpr); 6694b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 6702d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines 6712d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines // Loop through array types to get to base type 6722d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines while (T && T->isArrayType()) { 6732d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines T = T->getArrayElementTypeNoTypeQual(); 6742d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines } 6752d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines 676e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines *DT = RSExportPrimitiveType::GetRSSpecificType(T); 6774b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 678e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (*DT == RSExportPrimitiveType::DataTypeUnknown) { 679feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (RSExportPrimitiveType::IsStructureTypeWithRSObject(T)) { 680feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines *DT = RSExportPrimitiveType::DataTypeIsStruct; 681feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } else { 682feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines return false; 683feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 6842d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines } 6854b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 686e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines bool DataTypeIsRSObject = RSExportPrimitiveType::IsRSObjectType(*DT); 687e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines *InitExpr = VD->getInit(); 688e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 689e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (!DataTypeIsRSObject && *InitExpr) { 690e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines // If we already have an initializer for a matrix type, we are done. 691e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return DataTypeIsRSObject; 6924b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 6934b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 694e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *ZeroInitializer = 695e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines CreateZeroInitializerForRSSpecificType(*DT, 696e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->getASTContext(), 697e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->getLocation()); 698e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 699e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (ZeroInitializer) { 700e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ZeroInitializer->setType(T->getCanonicalTypeInternal()); 701e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->setInit(ZeroInitializer); 702e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 703e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 704e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return DataTypeIsRSObject; 7054b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 7064b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 7074b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesclang::Expr *RSObjectRefCount::CreateZeroInitializerForRSSpecificType( 7084b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines RSExportPrimitiveType::DataType DT, 7094b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ASTContext &C, 7104b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines const clang::SourceLocation &Loc) { 7114b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *Res = NULL; 7124b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines switch (DT) { 713feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines case RSExportPrimitiveType::DataTypeIsStruct: 7144b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSElement: 7154b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSType: 7164b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSAllocation: 7174b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSSampler: 7184b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSScript: 7194b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMesh: 7204b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramFragment: 7214b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramVertex: 7224b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramRaster: 7234b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramStore: 7244b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSFont: { 7254b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (ImplicitCastExpr 'nullptr_t' 7264b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (IntegerLiteral 0))) 7274b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APInt Zero(C.getTypeSize(C.IntTy), 0); 7284b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, Zero, C.IntTy, Loc); 7294b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *CastToNull = 7304b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ImplicitCastExpr::Create(C, 7314b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines C.NullPtrTy, 7324b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::CK_IntegralToPointer, 7334b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Int0, 7344b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines NULL, 7354b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::VK_RValue); 7364b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 737e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Res = new(C) clang::InitListExpr(C, Loc, &CastToNull, 1, Loc); 7384b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines break; 7394b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 7404b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMatrix2x2: 7414b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMatrix3x3: 7424b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMatrix4x4: { 7434b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // RS matrix is not completely an RS object. They hold data by themselves. 7444b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (InitListExpr rs_matrix2x2 7454b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (InitListExpr float[4] 7464b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 7474b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 7484b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 7494b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0))) 7504b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::QualType FloatTy = C.FloatTy; 7514b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Constructor sets value to 0.0f by default 7524b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APFloat Val(C.getFloatTypeSemantics(FloatTy)); 7534b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::FloatingLiteral *Float0Val = 7544b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::FloatingLiteral::Create(C, 7554b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Val, 7564b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines /* isExact = */true, 7574b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines FloatTy, 7584b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Loc); 7594b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 7604b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines unsigned N = 0; 7614b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (DT == RSExportPrimitiveType::DataTypeRSMatrix2x2) 7624b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 2; 7634b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines else if (DT == RSExportPrimitiveType::DataTypeRSMatrix3x3) 7644b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 3; 7654b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines else if (DT == RSExportPrimitiveType::DataTypeRSMatrix4x4) 7664b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 4; 7674b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 7684b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Directly allocate 16 elements instead of dynamically allocate N*N 7694b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *InitVals[16]; 7704b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (unsigned i = 0; i < sizeof(InitVals) / sizeof(InitVals[0]); i++) 7714b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines InitVals[i] = Float0Val; 7724b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *InitExpr = 773e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines new(C) clang::InitListExpr(C, Loc, InitVals, N * N, Loc); 7744b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines InitExpr->setType(C.getConstantArrayType(FloatTy, 7754b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APInt(32, 4), 7764b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ArrayType::Normal, 7774b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines /* EltTypeQuals = */0)); 7784b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 779e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Res = new(C) clang::InitListExpr(C, Loc, &InitExpr, 1, Loc); 7804b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines break; 7814b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 7824b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnknown: 7834b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeFloat16: 7844b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeFloat32: 7854b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeFloat64: 7864b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned8: 7874b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned16: 7884b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned32: 7894b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned64: 7904b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned8: 7914b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned16: 7924b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned32: 7934b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned64: 7944b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeBoolean: 7954b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned565: 7964b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned5551: 7974b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned4444: 7984b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeMax: { 7996e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Not RS object type!"); 8004b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 8014b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // No default case will enable compiler detecting the missing cases 8024b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 8034b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 8044b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return Res; 8054b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 8064b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 8074b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitDeclStmt(clang::DeclStmt *DS) { 8084b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (clang::DeclStmt::decl_iterator I = DS->decl_begin(), E = DS->decl_end(); 8094b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I != E; 8104b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I++) { 8114b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Decl *D = *I; 8124b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (D->getKind() == clang::Decl::Var) { 8134b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::VarDecl *VD = static_cast<clang::VarDecl*>(D); 814e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataType DT = 815e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataTypeUnknown; 816e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *InitExpr = NULL; 817e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (InitializeRSObject(VD, &DT, &InitExpr)) { 8184b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines getCurrentScope()->addRSObject(VD); 819e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines getCurrentScope()->AppendRSObjectInit(VD, DS, DT, InitExpr); 820e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 8214b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 8224b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 8234b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 8244b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 8254b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 8264b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitCompoundStmt(clang::CompoundStmt *CS) { 8274b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (!CS->body_empty()) { 8284b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Push a new scope 8294b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Scope *S = new Scope(CS); 8304b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines mScopeStack.push(S); 8314b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 8324b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines VisitStmt(CS); 8334b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 8344b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Destroy the scope 8356e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((getCurrentScope() == S) && "Corrupted scope stack!"); 8361bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines S->InsertLocalVarDestructors(); 8374b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines mScopeStack.pop(); 8384b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines delete S; 8394b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 8404b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 8414b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 8424b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 8434b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitBinAssign(clang::BinaryOperator *AS) { 844c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType QT = AS->getType(); 845c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RSExportPrimitiveType::DataType DT = 846c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RSExportPrimitiveType::GetRSSpecificType(QT.getTypePtr()); 847c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 848c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines if (RSExportPrimitiveType::IsRSObjectType(DT)) { 849c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines getCurrentScope()->ReplaceRSObjectAssignment(AS); 850c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 851c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 8524b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 8534b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 8544b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 8554b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitStmt(clang::Stmt *S) { 8564b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end(); 8574b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I != E; 8584b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I++) { 8594b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (clang::Stmt *Child = *I) { 8604b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Visit(Child); 8614b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 8624b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 8634b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 8644b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 8654b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 866e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 867