slang_rs_object_ref_count.cpp revision feaca06fcb0772e9e972a0d61b17259fc5124d50
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 145e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hinesstatic void AppendAfterStmt(clang::ASTContext& C, 146e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CompoundStmt *CS, 147e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Stmt *OldStmt, 148e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Stmt *NewStmt) { 149e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines assert(CS && OldStmt && NewStmt); 150e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CompoundStmt::body_iterator bI = CS->body_begin(); 151e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines unsigned StmtCount = 1; // Take into account new statement 152e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines for (bI = CS->body_begin(); bI != CS->body_end(); bI++) { 153e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines StmtCount++; 154e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 155e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 156e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Stmt **UpdatedStmtList = new clang::Stmt*[StmtCount]; 157e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 158e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines unsigned UpdatedStmtCount = 0; 159e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines unsigned Once = 0; 160e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines for (bI = CS->body_begin(); bI != CS->body_end(); bI++) { 161e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines UpdatedStmtList[UpdatedStmtCount++] = *bI; 162e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (*bI == OldStmt) { 163e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Once++; 164e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines assert(Once == 1); 165e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines UpdatedStmtList[UpdatedStmtCount++] = NewStmt; 166e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 167e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 168e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 169e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines CS->setStmts(C, UpdatedStmtList, UpdatedStmtCount); 170e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 171e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines delete [] UpdatedStmtList; 172e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 173e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return; 174e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines} 175e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 176e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hinesstatic void ReplaceInCompoundStmt(clang::ASTContext& C, 177c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::CompoundStmt *CS, 178c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Stmt* OldStmt, 179c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Stmt* NewStmt) { 180c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::CompoundStmt::body_iterator bI = CS->body_begin(); 181c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 182c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines unsigned StmtCount = 0; 183c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines for (bI = CS->body_begin(); bI != CS->body_end(); bI++) { 184c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines StmtCount++; 185c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 186c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 187c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Stmt **UpdatedStmtList = new clang::Stmt*[StmtCount]; 188c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 189c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines unsigned UpdatedStmtCount = 0; 190c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines for (bI = CS->body_begin(); bI != CS->body_end(); bI++) { 191c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines if (*bI == OldStmt) { 192c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines UpdatedStmtList[UpdatedStmtCount++] = NewStmt; 193c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } else { 194c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines UpdatedStmtList[UpdatedStmtCount++] = *bI; 195c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 196c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 197c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 198c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines CS->setStmts(C, UpdatedStmtList, UpdatedStmtCount); 199c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 200c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines delete [] UpdatedStmtList; 201c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 202c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines return; 203c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines} 204c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 205c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 206d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines// This class visits a compound statement and inserts the StmtList containing 2074464d825c11349068f2917f9ebee86b721423f3cStephen Hines// destructors in proper locations. This includes inserting them before any 2084464d825c11349068f2917f9ebee86b721423f3cStephen Hines// return statement in any sub-block, at the end of the logical enclosing 2094464d825c11349068f2917f9ebee86b721423f3cStephen Hines// scope (compound statement), and/or before any break/continue statement that 2104464d825c11349068f2917f9ebee86b721423f3cStephen Hines// would resume outside the declared scope. We will not handle the case for 2114464d825c11349068f2917f9ebee86b721423f3cStephen Hines// goto statements that leave a local scope. 2124464d825c11349068f2917f9ebee86b721423f3cStephen Hines// TODO(srhines): Make this work properly for break/continue. 2134464d825c11349068f2917f9ebee86b721423f3cStephen Hinesclass DestructorVisitor : public clang::StmtVisitor<DestructorVisitor> { 2144464d825c11349068f2917f9ebee86b721423f3cStephen Hines private: 2154464d825c11349068f2917f9ebee86b721423f3cStephen Hines clang::ASTContext &mC; 216d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines std::list<clang::Stmt*> &mStmtList; 2174464d825c11349068f2917f9ebee86b721423f3cStephen Hines bool mTopLevel; 2184464d825c11349068f2917f9ebee86b721423f3cStephen Hines public: 219d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines DestructorVisitor(clang::ASTContext &C, std::list<clang::Stmt*> &StmtList); 2204464d825c11349068f2917f9ebee86b721423f3cStephen Hines void VisitStmt(clang::Stmt *S); 2214464d825c11349068f2917f9ebee86b721423f3cStephen Hines void VisitCompoundStmt(clang::CompoundStmt *CS); 2224464d825c11349068f2917f9ebee86b721423f3cStephen Hines}; 2234464d825c11349068f2917f9ebee86b721423f3cStephen Hines 2244464d825c11349068f2917f9ebee86b721423f3cStephen HinesDestructorVisitor::DestructorVisitor(clang::ASTContext &C, 225d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines std::list<clang::Stmt*> &StmtList) 2264464d825c11349068f2917f9ebee86b721423f3cStephen Hines : mC(C), 227d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines mStmtList(StmtList), 2284464d825c11349068f2917f9ebee86b721423f3cStephen Hines mTopLevel(true) { 2294464d825c11349068f2917f9ebee86b721423f3cStephen Hines return; 2304464d825c11349068f2917f9ebee86b721423f3cStephen Hines} 2314464d825c11349068f2917f9ebee86b721423f3cStephen Hines 2324464d825c11349068f2917f9ebee86b721423f3cStephen Hinesvoid DestructorVisitor::VisitCompoundStmt(clang::CompoundStmt *CS) { 2334464d825c11349068f2917f9ebee86b721423f3cStephen Hines if (!CS->body_empty()) { 234d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines AppendToCompoundStatement(mC, CS, mStmtList, mTopLevel); 2354464d825c11349068f2917f9ebee86b721423f3cStephen Hines mTopLevel = false; 2364464d825c11349068f2917f9ebee86b721423f3cStephen Hines VisitStmt(CS); 2374464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 2384464d825c11349068f2917f9ebee86b721423f3cStephen Hines return; 2394464d825c11349068f2917f9ebee86b721423f3cStephen Hines} 2404464d825c11349068f2917f9ebee86b721423f3cStephen Hines 2414464d825c11349068f2917f9ebee86b721423f3cStephen Hinesvoid DestructorVisitor::VisitStmt(clang::Stmt *S) { 2424464d825c11349068f2917f9ebee86b721423f3cStephen Hines for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end(); 2434464d825c11349068f2917f9ebee86b721423f3cStephen Hines I != E; 2444464d825c11349068f2917f9ebee86b721423f3cStephen Hines I++) { 2454464d825c11349068f2917f9ebee86b721423f3cStephen Hines if (clang::Stmt *Child = *I) { 2464464d825c11349068f2917f9ebee86b721423f3cStephen Hines Visit(Child); 2474464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 2484464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 2494464d825c11349068f2917f9ebee86b721423f3cStephen Hines return; 2504464d825c11349068f2917f9ebee86b721423f3cStephen Hines} 2514464d825c11349068f2917f9ebee86b721423f3cStephen Hines 25203981a308201b9123512297c8b9562a0f29bdf31Stephen Hinesstatic int ArrayDim(clang::VarDecl *VD) { 25303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 25403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 25503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (!T || !T->isArrayType()) { 25603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return 0; 25703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 25803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 25903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines const clang::ConstantArrayType *CAT = 26003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines static_cast<const clang::ConstantArrayType *>(T); 2619d2c0fa6490e09b3ff5603796bce42d97788e5c8Stephen Hines return static_cast<int>(CAT->getSize().getSExtValue()); 26203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines} 26303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 26403981a308201b9123512297c8b9562a0f29bdf31Stephen Hinesstatic clang::Stmt *ClearArrayRSObject(clang::VarDecl *VD, 26503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines const clang::Type *T, 26603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::FunctionDecl *ClearObjectFD) { 26703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::ASTContext &C = VD->getASTContext(); 26803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::SourceRange Range = VD->getQualifierRange(); 26903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::SourceLocation Loc = Range.getEnd(); 27003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 27103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Stmt *StmtArray[2] = {NULL}; 27203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines int StmtCtr = 0; 27303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 27403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines int NumArrayElements = ArrayDim(VD); 27503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (NumArrayElements <= 0) { 27603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return NULL; 27703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 27803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 27903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Example destructor loop for "rs_font fontArr[10];" 28003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // 28103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (CompoundStmt 28203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclStmt "int rsIntIter") 28303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ForStmt 28403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (BinaryOperator 'int' '=' 28503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter') 28603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (IntegerLiteral 'int' 0)) 28703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (BinaryOperator 'int' '<' 28803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter') 28903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (IntegerLiteral 'int' 10) 29003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // NULL << CondVar >> 29103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (UnaryOperator 'int' postfix '++' 29203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter')) 29303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (CallExpr 'void' 29403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ImplicitCastExpr 'void (*)(rs_font *)' <FunctionToPointerDecay> 29503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'void (rs_font *)' FunctionDecl='rsClearObject')) 29603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (UnaryOperator 'rs_font *' prefix '&' 29703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ArraySubscriptExpr 'rs_font':'rs_font' 29803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ImplicitCastExpr 'rs_font *' <ArrayToPointerDecay> 29903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'rs_font [10]' Var='fontArr')) 30003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter'))))))) 30103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 30203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Create helper variable for iterating through elements 30303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::IdentifierInfo& II = C.Idents.get("rsIntIter"); 30403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VarDecl *IIVD = 30503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VarDecl::Create(C, 30603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines VD->getDeclContext(), 30703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 30803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines &II, 30903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 31003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.getTrivialTypeSourceInfo(C.IntTy), 31103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::SC_None, 31203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::SC_None); 31303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Decl *IID = (clang::Decl *)IIVD; 31403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 31503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclGroupRef DGR = clang::DeclGroupRef::Create(C, &IID, 1); 31603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines StmtArray[StmtCtr++] = new(C) clang::DeclStmt(DGR, Loc, Loc); 31703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 31803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Form the actual destructor loop 31903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // for (Init; Cond; Inc) 32003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // RSClearObjectCall; 32103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 32203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Init -> "rsIntIter = 0" 32303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclRefExpr *RefrsIntIter = 32403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclRefExpr::Create(C, 32503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, 32603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Range, 32703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines IIVD, 32803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 32903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy); 33003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 33103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, 33203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), 0), C.IntTy, Loc); 33303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 33403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BinaryOperator *Init = 33503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 33603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Int0, 33703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BO_Assign, 33803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 33903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 34003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 34103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Cond -> "rsIntIter < NumArrayElements" 34203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *NumArrayElementsExpr = clang::IntegerLiteral::Create(C, 34303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), NumArrayElements), C.IntTy, Loc); 34403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 34503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BinaryOperator *Cond = 34603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 34703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NumArrayElementsExpr, 34803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BO_LT, 34903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 35003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 35103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 35203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Inc -> "rsIntIter++" 35303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::UnaryOperator *Inc = 35403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::UnaryOperator(RefrsIntIter, 35503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::UO_PostInc, 35603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 35703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 35803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 35903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Body -> "rsClearObject(&VD[rsIntIter]);" 36003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Destructor loop operates on individual array elements 36103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::QualType ClearObjectFDType = ClearObjectFD->getType(); 36203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::QualType ClearObjectFDArgType = 36303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ClearObjectFD->getParamDecl(0)->getOriginalType(); 36403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 36503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines const clang::Type *VT = RSExportType::GetTypeOfDecl(VD); 36603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclRefExpr *RefRSVar = 36703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclRefExpr::Create(C, 36803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, 36903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Range, 37003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines VD, 37103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 37203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines VT->getCanonicalTypeInternal()); 37303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 37403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *RefRSVarPtr = 37503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::ImplicitCastExpr::Create(C, 37603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.getPointerType(T->getCanonicalTypeInternal()), 37703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::CK_ArrayToPointerDecay, 37803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines RefRSVar, 37903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, 38003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VK_RValue); 38103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 38203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *RefRSVarPtrSubscript = 38303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::ArraySubscriptExpr(RefRSVarPtr, 38403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines RefrsIntIter, 38503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines T->getCanonicalTypeInternal(), 38603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines VD->getLocation()); 38703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 38803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *AddrRefRSVarPtrSubscript = 38903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::UnaryOperator(RefRSVarPtrSubscript, 39003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::UO_AddrOf, 39103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ClearObjectFDArgType, 39203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines VD->getLocation()); 39303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 39403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *RefRSClearObjectFD = 39503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclRefExpr::Create(C, 39603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, 39703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Range, 39803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ClearObjectFD, 39903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 40003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ClearObjectFDType); 40103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 40203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *RSClearObjectFP = 40303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::ImplicitCastExpr::Create(C, 40403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.getPointerType(ClearObjectFDType), 40503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::CK_FunctionToPointerDecay, 40603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines RefRSClearObjectFD, 40703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, 40803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VK_RValue); 40903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 41003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::CallExpr *RSClearObjectCall = 41103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::CallExpr(C, 41203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines RSClearObjectFP, 41303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines &AddrRefRSVarPtrSubscript, 41403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 1, 41503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ClearObjectFD->getCallResultType(), 41603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 41703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 41803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::ForStmt *DestructorLoop = 41903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::ForStmt(C, 42003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Init, 42103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Cond, 42203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, // no condVar 42303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Inc, 42403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines RSClearObjectCall, 42503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 42603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 42703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 42803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 42903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines StmtArray[StmtCtr++] = DestructorLoop; 43003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines assert(StmtCtr == 2); 43103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 43203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::CompoundStmt *CS = 43303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::CompoundStmt(C, StmtArray, StmtCtr, Loc, Loc); 43403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 43503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return CS; 43603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines} 43703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 4384464d825c11349068f2917f9ebee86b721423f3cStephen Hines} // namespace 4394464d825c11349068f2917f9ebee86b721423f3cStephen Hines 440c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hinesvoid RSObjectRefCount::Scope::ReplaceRSObjectAssignment( 441c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::BinaryOperator *AS) { 442c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 443c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType QT = AS->getType(); 444c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RSExportPrimitiveType::DataType DT = 445c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RSExportPrimitiveType::GetRSSpecificType(QT.getTypePtr()); 446c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 447c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::FunctionDecl *SetObjectFD = 448c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RSSetObjectFD[(DT - RSExportPrimitiveType::FirstRSObjectType)]; 449c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines assert((SetObjectFD != NULL) && 450c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines "rsSetObject doesn't cover all RS object types"); 451c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::ASTContext &C = SetObjectFD->getASTContext(); 452c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 453c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType SetObjectFDType = SetObjectFD->getType(); 454c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType SetObjectFDArgType[2]; 455c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDArgType[0] = SetObjectFD->getParamDecl(0)->getOriginalType(); 456c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDArgType[1] = SetObjectFD->getParamDecl(1)->getOriginalType(); 457c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 458c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::SourceLocation Loc = SetObjectFD->getLocation(); 459c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Expr *RefRSSetObjectFD = 460c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::DeclRefExpr::Create(C, 461c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines NULL, 462c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFD->getQualifierRange(), 463c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFD, 464c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines Loc, 465c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDType); 466c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 467c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Expr *RSSetObjectFP = 468c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::ImplicitCastExpr::Create(C, 469c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines C.getPointerType(SetObjectFDType), 470c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::CK_FunctionToPointerDecay, 471c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RefRSSetObjectFD, 472c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines NULL, 473c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::VK_RValue); 474c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 475c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Expr *ArgList[2]; 476c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines ArgList[0] = new(C) clang::UnaryOperator(AS->getLHS(), 477c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::UO_AddrOf, 478c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDArgType[0], 479c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines Loc); 480c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines ArgList[1] = AS->getRHS(); 481c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 482c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::CallExpr *RSSetObjectCall = 483c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines new(C) clang::CallExpr(C, 484c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RSSetObjectFP, 485c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines ArgList, 486c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 2, 487c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFD->getCallResultType(), 488c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines Loc); 489c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 490e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ReplaceInCompoundStmt(C, mCS, AS, RSSetObjectCall); 491e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 492e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return; 493e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines} 494e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 495e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hinesvoid RSObjectRefCount::Scope::AppendRSObjectInit( 496e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::VarDecl *VD, 497e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclStmt *DS, 498e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataType DT, 499e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *InitExpr) { 500e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines assert(VD); 501e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 502e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (!InitExpr) { 503e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return; 504e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 505e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 506e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::FunctionDecl *SetObjectFD = 507e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSSetObjectFD[(DT - RSExportPrimitiveType::FirstRSObjectType)]; 508e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines assert((SetObjectFD != NULL) && 509e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines "rsSetObject doesn't cover all RS object types"); 510e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::ASTContext &C = SetObjectFD->getASTContext(); 511e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 512e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::QualType SetObjectFDType = SetObjectFD->getType(); 513e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::QualType SetObjectFDArgType[2]; 514e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDArgType[0] = SetObjectFD->getParamDecl(0)->getOriginalType(); 515e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDArgType[1] = SetObjectFD->getParamDecl(1)->getOriginalType(); 516e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 517e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::SourceLocation Loc = SetObjectFD->getLocation(); 518e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *RefRSSetObjectFD = 519e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr::Create(C, 520e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines NULL, 521e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFD->getQualifierRange(), 522e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFD, 523e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc, 524e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDType); 525e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 526e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *RSSetObjectFP = 527e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::ImplicitCastExpr::Create(C, 528e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines C.getPointerType(SetObjectFDType), 529e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CK_FunctionToPointerDecay, 530e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RefRSSetObjectFD, 531e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines NULL, 532e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::VK_RValue); 533e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 534e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 535e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr *RefRSVar = 536e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr::Create(C, 537e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines NULL, 538e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->getQualifierRange(), 539e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD, 540e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc, 541e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines T->getCanonicalTypeInternal()); 542e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 543e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *ArgList[2]; 544e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ArgList[0] = new(C) clang::UnaryOperator(RefRSVar, 545e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::UO_AddrOf, 546e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDArgType[0], 547e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc); 548e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ArgList[1] = InitExpr; 549e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 550e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CallExpr *RSSetObjectCall = 551e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines new(C) clang::CallExpr(C, 552e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSSetObjectFP, 553e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ArgList, 554e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 2, 555e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFD->getCallResultType(), 556e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc); 557e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 558e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines AppendAfterStmt(C, mCS, DS, RSSetObjectCall); 559c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 560c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines return; 561c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines} 562c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 5631bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hinesvoid RSObjectRefCount::Scope::InsertLocalVarDestructors() { 564d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines std::list<clang::Stmt*> RSClearObjectCalls; 5651bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines for (std::list<clang::VarDecl*>::const_iterator I = mRSO.begin(), 5661bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines E = mRSO.end(); 5671bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines I != E; 5681bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines I++) { 569a858cb6f3d9223d65bf73e1230c6324ded4095f6Stephen Hines clang::Stmt *S = ClearRSObject(*I); 570a858cb6f3d9223d65bf73e1230c6324ded4095f6Stephen Hines if (S) { 571a858cb6f3d9223d65bf73e1230c6324ded4095f6Stephen Hines RSClearObjectCalls.push_back(S); 5721bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 5731bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 5741bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if (RSClearObjectCalls.size() > 0) { 5754464d825c11349068f2917f9ebee86b721423f3cStephen Hines DestructorVisitor DV((*mRSO.begin())->getASTContext(), RSClearObjectCalls); 5764464d825c11349068f2917f9ebee86b721423f3cStephen Hines DV.Visit(mCS); 5771bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 5781bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines return; 5791bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 5801bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 581d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hinesclang::Stmt *RSObjectRefCount::Scope::ClearRSObject(clang::VarDecl *VD) { 58203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines bool IsArrayType = false; 5831bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::ASTContext &C = VD->getASTContext(); 5841bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::SourceLocation Loc = VD->getLocation(); 5851bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 58603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 58703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Loop through array types to get to base type 58803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines while (T && T->isArrayType()) { 58903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines T = T->getArrayElementTypeNoTypeQual(); 59003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines IsArrayType = true; 59103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 59203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 5931bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSExportPrimitiveType::DataType DT = 5941bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSExportPrimitiveType::GetRSSpecificType(T); 5951bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 5961bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines assert((RSExportPrimitiveType::IsRSObjectType(DT)) && 5971bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines "Should be RS object"); 5981bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 5991bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Find the rsClearObject() for VD of RS object type DT 6001bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::FunctionDecl *ClearObjectFD = 6011bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSClearObjectFD[(DT - RSExportPrimitiveType::FirstRSObjectType)]; 6021bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines assert((ClearObjectFD != NULL) && 6031bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines "rsClearObject doesn't cover all RS object types"); 6041bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 60503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (IsArrayType) { 60603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return ClearArrayRSObject(VD, T, ClearObjectFD); 60703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 60803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 6091bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::QualType ClearObjectFDType = ClearObjectFD->getType(); 6101bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::QualType ClearObjectFDArgType = 6111bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines ClearObjectFD->getParamDecl(0)->getOriginalType(); 6121bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 61303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Example destructor for "rs_font localFont;" 61403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // 6151bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // (CallExpr 'void' 6161bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // (ImplicitCastExpr 'void (*)(rs_font *)' <FunctionToPointerDecay> 6171bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // (DeclRefExpr 'void (rs_font *)' FunctionDecl='rsClearObject')) 6181bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // (UnaryOperator 'rs_font *' prefix '&' 61903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'rs_font':'rs_font' Var='localFont'))) 6201bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 6211bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Reference expr to target RS object variable 6221bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::DeclRefExpr *RefRSVar = 6231bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::DeclRefExpr::Create(C, 6241bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines NULL, 6251bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines VD->getQualifierRange(), 6261bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines VD, 6271bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines Loc, 62803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines T->getCanonicalTypeInternal()); 6291bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 6301bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Get address of RSObject in VD 6311bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::Expr *AddrRefRSVar = 632e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines new(C) clang::UnaryOperator(RefRSVar, 633e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines clang::UO_AddrOf, 634e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines ClearObjectFDArgType, 635e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Loc); 6361bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 6371bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::Expr *RefRSClearObjectFD = 6381bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::DeclRefExpr::Create(C, 6391bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines NULL, 6401bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines ClearObjectFD->getQualifierRange(), 6411bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines ClearObjectFD, 6421bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines ClearObjectFD->getLocation(), 64303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines ClearObjectFDType); 6441bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 6451bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::Expr *RSClearObjectFP = 6461bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::ImplicitCastExpr::Create(C, 6471bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines C.getPointerType(ClearObjectFDType), 6481bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::CK_FunctionToPointerDecay, 6491bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RefRSClearObjectFD, 6501bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines NULL, 6511bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::VK_RValue); 6521bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 6531bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::CallExpr *RSClearObjectCall = 654e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines new(C) clang::CallExpr(C, 655e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines RSClearObjectFP, 656e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines &AddrRefRSVar, 657e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 1, 658e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines ClearObjectFD->getCallResultType(), 659e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines clang::SourceLocation()); 6601bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 6611bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines return RSClearObjectCall; 6621bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 6631bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 664e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hinesbool RSObjectRefCount::InitializeRSObject(clang::VarDecl *VD, 665e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataType *DT, 666e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr **InitExpr) { 667e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines assert(VD && DT && InitExpr); 6684b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 6692d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines 6702d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines // Loop through array types to get to base type 6712d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines while (T && T->isArrayType()) { 6722d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines T = T->getArrayElementTypeNoTypeQual(); 6732d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines } 6742d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines 675e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines *DT = RSExportPrimitiveType::GetRSSpecificType(T); 6764b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 677e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (*DT == RSExportPrimitiveType::DataTypeUnknown) { 678feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (RSExportPrimitiveType::IsStructureTypeWithRSObject(T)) { 679feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines *DT = RSExportPrimitiveType::DataTypeIsStruct; 680feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } else { 681feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines return false; 682feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 6832d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines } 6844b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 685e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines bool DataTypeIsRSObject = RSExportPrimitiveType::IsRSObjectType(*DT); 686e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines *InitExpr = VD->getInit(); 687e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 688e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (!DataTypeIsRSObject && *InitExpr) { 689e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines // If we already have an initializer for a matrix type, we are done. 690e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return DataTypeIsRSObject; 6914b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 6924b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 693e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *ZeroInitializer = 694e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines CreateZeroInitializerForRSSpecificType(*DT, 695e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->getASTContext(), 696e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->getLocation()); 697e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 698e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (ZeroInitializer) { 699e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ZeroInitializer->setType(T->getCanonicalTypeInternal()); 700e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->setInit(ZeroInitializer); 701e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 702e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 703e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return DataTypeIsRSObject; 7044b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 7054b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 7064b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesclang::Expr *RSObjectRefCount::CreateZeroInitializerForRSSpecificType( 7074b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines RSExportPrimitiveType::DataType DT, 7084b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ASTContext &C, 7094b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines const clang::SourceLocation &Loc) { 7104b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *Res = NULL; 7114b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines switch (DT) { 712feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines case RSExportPrimitiveType::DataTypeIsStruct: 7134b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSElement: 7144b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSType: 7154b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSAllocation: 7164b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSSampler: 7174b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSScript: 7184b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMesh: 7194b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramFragment: 7204b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramVertex: 7214b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramRaster: 7224b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramStore: 7234b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSFont: { 7244b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (ImplicitCastExpr 'nullptr_t' 7254b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (IntegerLiteral 0))) 7264b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APInt Zero(C.getTypeSize(C.IntTy), 0); 7274b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, Zero, C.IntTy, Loc); 7284b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *CastToNull = 7294b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ImplicitCastExpr::Create(C, 7304b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines C.NullPtrTy, 7314b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::CK_IntegralToPointer, 7324b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Int0, 7334b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines NULL, 7344b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::VK_RValue); 7354b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 736e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Res = new(C) clang::InitListExpr(C, Loc, &CastToNull, 1, Loc); 7374b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines break; 7384b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 7394b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMatrix2x2: 7404b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMatrix3x3: 7414b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMatrix4x4: { 7424b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // RS matrix is not completely an RS object. They hold data by themselves. 7434b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (InitListExpr rs_matrix2x2 7444b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (InitListExpr float[4] 7454b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 7464b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 7474b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 7484b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0))) 7494b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::QualType FloatTy = C.FloatTy; 7504b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Constructor sets value to 0.0f by default 7514b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APFloat Val(C.getFloatTypeSemantics(FloatTy)); 7524b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::FloatingLiteral *Float0Val = 7534b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::FloatingLiteral::Create(C, 7544b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Val, 7554b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines /* isExact = */true, 7564b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines FloatTy, 7574b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Loc); 7584b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 7594b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines unsigned N = 0; 7604b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (DT == RSExportPrimitiveType::DataTypeRSMatrix2x2) 7614b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 2; 7624b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines else if (DT == RSExportPrimitiveType::DataTypeRSMatrix3x3) 7634b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 3; 7644b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines else if (DT == RSExportPrimitiveType::DataTypeRSMatrix4x4) 7654b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 4; 7664b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 7674b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Directly allocate 16 elements instead of dynamically allocate N*N 7684b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *InitVals[16]; 7694b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (unsigned i = 0; i < sizeof(InitVals) / sizeof(InitVals[0]); i++) 7704b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines InitVals[i] = Float0Val; 7714b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *InitExpr = 772e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines new(C) clang::InitListExpr(C, Loc, InitVals, N * N, Loc); 7734b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines InitExpr->setType(C.getConstantArrayType(FloatTy, 7744b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APInt(32, 4), 7754b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ArrayType::Normal, 7764b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines /* EltTypeQuals = */0)); 7774b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 778e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Res = new(C) clang::InitListExpr(C, Loc, &InitExpr, 1, Loc); 7794b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines break; 7804b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 7814b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnknown: 7824b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeFloat16: 7834b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeFloat32: 7844b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeFloat64: 7854b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned8: 7864b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned16: 7874b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned32: 7884b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned64: 7894b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned8: 7904b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned16: 7914b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned32: 7924b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned64: 7934b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeBoolean: 7944b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned565: 7954b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned5551: 7964b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned4444: 7974b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeMax: { 7984b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines assert(false && "Not RS object type!"); 7994b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 8004b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // No default case will enable compiler detecting the missing cases 8014b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 8024b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 8034b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return Res; 8044b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 8054b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 8064b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitDeclStmt(clang::DeclStmt *DS) { 8074b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (clang::DeclStmt::decl_iterator I = DS->decl_begin(), E = DS->decl_end(); 8084b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I != E; 8094b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I++) { 8104b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Decl *D = *I; 8114b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (D->getKind() == clang::Decl::Var) { 8124b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::VarDecl *VD = static_cast<clang::VarDecl*>(D); 813e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataType DT = 814e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataTypeUnknown; 815e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *InitExpr = NULL; 816e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (InitializeRSObject(VD, &DT, &InitExpr)) { 8174b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines getCurrentScope()->addRSObject(VD); 818e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines getCurrentScope()->AppendRSObjectInit(VD, DS, DT, InitExpr); 819e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 8204b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 8214b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 8224b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 8234b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 8244b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 8254b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitCompoundStmt(clang::CompoundStmt *CS) { 8264b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (!CS->body_empty()) { 8274b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Push a new scope 8284b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Scope *S = new Scope(CS); 8294b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines mScopeStack.push(S); 8304b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 8314b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines VisitStmt(CS); 8324b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 8334b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Destroy the scope 8344b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines assert((getCurrentScope() == S) && "Corrupted scope stack!"); 8351bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines S->InsertLocalVarDestructors(); 8364b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines mScopeStack.pop(); 8374b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines delete S; 8384b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 8394b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 8404b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 8414b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 8424b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitBinAssign(clang::BinaryOperator *AS) { 843c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType QT = AS->getType(); 844c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RSExportPrimitiveType::DataType DT = 845c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RSExportPrimitiveType::GetRSSpecificType(QT.getTypePtr()); 846c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 847c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines if (RSExportPrimitiveType::IsRSObjectType(DT)) { 848c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines getCurrentScope()->ReplaceRSObjectAssignment(AS); 849c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 850c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 8514b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 8524b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 8534b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 8544b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitStmt(clang::Stmt *S) { 8554b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end(); 8564b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I != E; 8574b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I++) { 8584b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (clang::Stmt *Child = *I) { 8594b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Visit(Child); 8604b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 8614b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 8624b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 8634b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 8644b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 865e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 866