slang_rs_object_ref_count.cpp revision 2bb67db8364162b30e6920baddf6c2e890b3ce79
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 33f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesclang::FunctionDecl *RSObjectRefCount:: 341bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSSetObjectFD[RSExportPrimitiveType::LastRSObjectType - 351bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSExportPrimitiveType::FirstRSObjectType + 1]; 36f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesclang::FunctionDecl *RSObjectRefCount:: 371bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSClearObjectFD[RSExportPrimitiveType::LastRSObjectType - 381bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSExportPrimitiveType::FirstRSObjectType + 1]; 391bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 40f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesvoid RSObjectRefCount::GetRSRefCountingFunctions(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") { 606e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((FD->getNumParams() == 2) && 616e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "Invalid rsSetObject function prototype (# params)"); 621bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSObjectFD = RSSetObjectFD; 631bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } else if (FD->getName() == "rsClearObject") { 646e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((FD->getNumParams() == 1) && 656e6578a360497f78a181e63d7783422a9c9bfb15Stephen 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* 746e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(PVT->isPointerType() && 756e6578a360497f78a181e63d7783422a9c9bfb15Stephen 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()); 816e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(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) { 1496e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(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++; 1646e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(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 252f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesclang::Expr *ClearSingleRSObject(clang::ASTContext &C, 253f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSVar, 254f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc) { 255f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(RefRSVar); 256f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *T = RefRSVar->getType().getTypePtr(); 257f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(!T->isArrayType() && 258f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "Should not be destroying arrays with this function"); 259f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 260f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::FunctionDecl *ClearObjectFD = RSObjectRefCount::GetRSClearObjectFD(T); 261f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert((ClearObjectFD != NULL) && 262f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "rsClearObject doesn't cover all RS object types"); 263f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 264f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::QualType ClearObjectFDType = ClearObjectFD->getType(); 265f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::QualType ClearObjectFDArgType = 266f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD->getParamDecl(0)->getOriginalType(); 267f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 268f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Example destructor for "rs_font localFont;" 269f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // 270f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (CallExpr 'void' 271f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (ImplicitCastExpr 'void (*)(rs_font *)' <FunctionToPointerDecay> 272f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (DeclRefExpr 'void (rs_font *)' FunctionDecl='rsClearObject')) 273f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (UnaryOperator 'rs_font *' prefix '&' 274f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (DeclRefExpr 'rs_font':'rs_font' Var='localFont'))) 275f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 276f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Get address of targeted RS object 277f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *AddrRefRSVar = 278f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::UnaryOperator(RefRSVar, 279f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::UO_AddrOf, 280f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFDArgType, 281f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 282f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 283f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSClearObjectFD = 284f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclRefExpr::Create(C, 285f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines NULL, 286f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD->getQualifierRange(), 287f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD, 288f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD->getLocation(), 289f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFDType); 290f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 291f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RSClearObjectFP = 292f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ImplicitCastExpr::Create(C, 293f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines C.getPointerType(ClearObjectFDType), 294f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::CK_FunctionToPointerDecay, 295f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSClearObjectFD, 296f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines NULL, 297f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::VK_RValue); 29803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 299f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::CallExpr *RSClearObjectCall = 300f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::CallExpr(C, 301f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectFP, 302f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines &AddrRefRSVar, 303f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 1, 304f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD->getCallResultType(), 305f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 306f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 307f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return RSClearObjectCall; 308f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines} 309f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 310f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic int ArrayDim(const clang::Type *T) { 31103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (!T || !T->isArrayType()) { 31203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return 0; 31303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 31403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 31503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines const clang::ConstantArrayType *CAT = 31603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines static_cast<const clang::ConstantArrayType *>(T); 3179d2c0fa6490e09b3ff5603796bce42d97788e5c8Stephen Hines return static_cast<int>(CAT->getSize().getSExtValue()); 31803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines} 31903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 320f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic clang::Stmt *ClearStructRSObject( 321f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ASTContext &C, 322f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC, 323f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSStruct, 324f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceRange Range, 325f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc); 326f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 327f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic clang::Stmt *ClearArrayRSObject( 328f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ASTContext &C, 329f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC, 330f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSArr, 331f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceRange Range, 332f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc) { 333f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *BaseType = RefRSArr->getType().getTypePtr(); 334f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(BaseType->isArrayType()); 335f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 336f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines int NumArrayElements = ArrayDim(BaseType); 337f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Actually extract out the base RS object type for use later 338f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines BaseType = BaseType->getArrayElementTypeNoTypeQual(); 33903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 34003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Stmt *StmtArray[2] = {NULL}; 34103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines int StmtCtr = 0; 34203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 34303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (NumArrayElements <= 0) { 34403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return NULL; 34503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 34603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 34703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Example destructor loop for "rs_font fontArr[10];" 34803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // 34903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (CompoundStmt 35003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclStmt "int rsIntIter") 35103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ForStmt 35203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (BinaryOperator 'int' '=' 35303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter') 35403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (IntegerLiteral 'int' 0)) 35503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (BinaryOperator 'int' '<' 35603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter') 35703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (IntegerLiteral 'int' 10) 35803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // NULL << CondVar >> 35903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (UnaryOperator 'int' postfix '++' 36003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter')) 36103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (CallExpr 'void' 36203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ImplicitCastExpr 'void (*)(rs_font *)' <FunctionToPointerDecay> 36303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'void (rs_font *)' FunctionDecl='rsClearObject')) 36403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (UnaryOperator 'rs_font *' prefix '&' 36503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ArraySubscriptExpr 'rs_font':'rs_font' 36603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ImplicitCastExpr 'rs_font *' <ArrayToPointerDecay> 36703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'rs_font [10]' Var='fontArr')) 36803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter'))))))) 36903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 37003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Create helper variable for iterating through elements 37103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::IdentifierInfo& II = C.Idents.get("rsIntIter"); 37203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VarDecl *IIVD = 37303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VarDecl::Create(C, 374f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 37503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 37603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines &II, 37703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 37803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.getTrivialTypeSourceInfo(C.IntTy), 37903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::SC_None, 38003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::SC_None); 38103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Decl *IID = (clang::Decl *)IIVD; 38203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 38303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclGroupRef DGR = clang::DeclGroupRef::Create(C, &IID, 1); 38403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines StmtArray[StmtCtr++] = new(C) clang::DeclStmt(DGR, Loc, Loc); 38503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 38603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Form the actual destructor loop 38703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // for (Init; Cond; Inc) 38803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // RSClearObjectCall; 38903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 39003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Init -> "rsIntIter = 0" 39103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclRefExpr *RefrsIntIter = 39203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclRefExpr::Create(C, 39303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, 39403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Range, 39503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines IIVD, 39603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 39703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy); 39803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 39903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, 40003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), 0), C.IntTy, Loc); 40103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 40203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BinaryOperator *Init = 40303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 40403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Int0, 40503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BO_Assign, 40603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 40703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 40803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 40903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Cond -> "rsIntIter < NumArrayElements" 41003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *NumArrayElementsExpr = clang::IntegerLiteral::Create(C, 41103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), NumArrayElements), C.IntTy, Loc); 41203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 41303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BinaryOperator *Cond = 41403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 41503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NumArrayElementsExpr, 41603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BO_LT, 41703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 41803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 41903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 42003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Inc -> "rsIntIter++" 42103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::UnaryOperator *Inc = 42203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::UnaryOperator(RefrsIntIter, 42303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::UO_PostInc, 42403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 42503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 42603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 42703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Body -> "rsClearObject(&VD[rsIntIter]);" 42803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Destructor loop operates on individual array elements 42903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 430f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSArrPtr = 43103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::ImplicitCastExpr::Create(C, 432f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines C.getPointerType(BaseType->getCanonicalTypeInternal()), 43303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::CK_ArrayToPointerDecay, 434f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSArr, 43503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, 43603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VK_RValue); 43703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 438f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSArrPtrSubscript = 439f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::ArraySubscriptExpr(RefRSArrPtr, 44003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines RefrsIntIter, 441f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines BaseType->getCanonicalTypeInternal(), 442f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 44303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 444f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::DataType DT = 445f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::GetRSSpecificType(BaseType); 446f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 447f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Stmt *RSClearObjectCall = NULL; 448f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (BaseType->isArrayType()) { 449f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectCall = 450f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearArrayRSObject(C, DC, RefRSArrPtrSubscript, Range, Loc); 451f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else if (DT == RSExportPrimitiveType::DataTypeUnknown) { 452f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectCall = 453f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearStructRSObject(C, DC, RefRSArrPtrSubscript, Range, Loc); 454f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 455f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectCall = ClearSingleRSObject(C, RefRSArrPtrSubscript, Loc); 456f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 45703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 45803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::ForStmt *DestructorLoop = 45903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::ForStmt(C, 46003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Init, 46103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Cond, 46203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, // no condVar 46303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Inc, 46403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines RSClearObjectCall, 46503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 46603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 46703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 46803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 46903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines StmtArray[StmtCtr++] = DestructorLoop; 4706e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(StmtCtr == 2); 47103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 47203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::CompoundStmt *CS = 47303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::CompoundStmt(C, StmtArray, StmtCtr, Loc, Loc); 47403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 47503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return CS; 47603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines} 47703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 4782bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesstatic unsigned CountRSObjectTypes(const clang::Type *T) { 479f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(T); 480f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines unsigned RSObjectCount = 0; 481f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 482f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (T->isArrayType()) { 4832bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return CountRSObjectTypes(T->getArrayElementTypeNoTypeQual()); 484f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 485f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 486f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::DataType DT = 487f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::GetRSSpecificType(T); 488f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (DT != RSExportPrimitiveType::DataTypeUnknown) { 489f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return (RSExportPrimitiveType::IsRSObjectType(DT) ? 1 : 0); 490f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 491f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 492f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (!T->isStructureType()) { 493f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return 0; 494f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 495f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 496f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::RecordDecl *RD = T->getAsStructureType()->getDecl(); 497f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RD = RD->getDefinition(); 498f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 499f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FE = RD->field_end(); 500f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI != FE; 501f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI++) { 502f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::FieldDecl *FD = *FI; 503f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 5042bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (CountRSObjectTypes(FT)) { 505f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Sub-structs should only count once (as should arrays, etc.) 506f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectCount++; 507f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 508f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 509f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 510f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return RSObjectCount; 511f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines} 512f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 513f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic clang::Stmt *ClearStructRSObject( 514f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ASTContext &C, 515f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC, 516f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSStruct, 517f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceRange Range, 518f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc) { 519f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *BaseType = RefRSStruct->getType().getTypePtr(); 520f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 521f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(!BaseType->isArrayType()); 522f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 523f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::DataType DT = 524f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::GetRSSpecificType(BaseType); 525f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 526f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Structs should show up as unknown primitive types 527f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(DT == RSExportPrimitiveType::DataTypeUnknown); 528f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 5292bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines unsigned FieldsToDestroy = CountRSObjectTypes(BaseType); 530f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 531f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines unsigned StmtCount = 0; 532f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Stmt **StmtArray = new clang::Stmt*[FieldsToDestroy]; 5332bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines for (unsigned i = 0; i < FieldsToDestroy; i++) { 5342bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[i] = NULL; 5352bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 536f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 537f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Populate StmtArray by creating a destructor for each RS object field 538f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::RecordDecl *RD = BaseType->getAsStructureType()->getDecl(); 539f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RD = RD->getDefinition(); 540f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 541f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FE = RD->field_end(); 542f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI != FE; 543f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI++) { 544f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // We just look through all field declarations to see if we find a 545f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // declaration for an RS object type (or an array of one). 546f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool IsArrayType = false; 547f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::FieldDecl *FD = *FI; 548f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 549f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *OrigType = FT; 550f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines while (FT && FT->isArrayType()) { 551f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 552f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines IsArrayType = true; 553f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 554f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 555f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (RSExportPrimitiveType::IsRSObjectType(FT)) { 556f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair FoundDecl = 557f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair::make(FD, clang::AS_none); 558f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr *RSObjectMember = 559f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr::Create(C, 560f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSStruct, 561f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines false, 562f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines NULL, 563f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Range, 564f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FD, 565f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FoundDecl, 566f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclarationNameInfo(), 567f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines NULL, 568f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines OrigType->getCanonicalTypeInternal()); 569f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 570f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(StmtCount < FieldsToDestroy); 571f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 572f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (IsArrayType) { 573f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearArrayRSObject(C, 574f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 575f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 576f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Range, 577f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 578f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 579f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearSingleRSObject(C, 580f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 581f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 582f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 5832bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else if (FT->isStructureType() && CountRSObjectTypes(FT)) { 584f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // In this case, we have a nested struct. We may not end up filling all 585f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // of the spaces in StmtArray (sub-structs should handle themselves 586f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // with separate compound statements). 587f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair FoundDecl = 588f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair::make(FD, clang::AS_none); 589f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr *RSObjectMember = 590f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr::Create(C, 591f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSStruct, 592f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines false, 593f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines NULL, 594f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Range, 595f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FD, 596f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FoundDecl, 597f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclarationNameInfo(), 598f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines NULL, 599f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines OrigType->getCanonicalTypeInternal()); 600f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 601f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (IsArrayType) { 602f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearArrayRSObject(C, 603f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 604f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 605f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Range, 606f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 607f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 608f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearStructRSObject(C, 609f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 610f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 611f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Range, 612f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 613f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 614f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 615f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 616f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 617f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(StmtCount > 0); 618f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::CompoundStmt *CS = 619f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::CompoundStmt(C, StmtArray, StmtCount, Loc, Loc); 620f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 621f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines delete [] StmtArray; 622f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 623f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return CS; 624f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines} 625f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 6262bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesstatic clang::Stmt *CreateSingleRSSetObject(clang::ASTContext &C, 6272bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Diagnostic *Diags, 6282bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *DstExpr, 6292bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *SrcExpr, 6302bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SourceLocation Loc) { 6312bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *T = DstExpr->getType().getTypePtr(); 6322bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::FunctionDecl *SetObjectFD = RSObjectRefCount::GetRSSetObjectFD(T); 6336e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((SetObjectFD != NULL) && 6346e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "rsSetObject doesn't cover all RS object types"); 635c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 636c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType SetObjectFDType = SetObjectFD->getType(); 637c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType SetObjectFDArgType[2]; 638c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDArgType[0] = SetObjectFD->getParamDecl(0)->getOriginalType(); 639c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDArgType[1] = SetObjectFD->getParamDecl(1)->getOriginalType(); 640c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 641c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Expr *RefRSSetObjectFD = 642c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::DeclRefExpr::Create(C, 643c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines NULL, 644c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFD->getQualifierRange(), 645c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFD, 646c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines Loc, 647c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDType); 648c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 649c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Expr *RSSetObjectFP = 650c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::ImplicitCastExpr::Create(C, 651c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines C.getPointerType(SetObjectFDType), 652c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::CK_FunctionToPointerDecay, 653c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RefRSSetObjectFD, 654c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines NULL, 655c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::VK_RValue); 656c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 657c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Expr *ArgList[2]; 6582bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines ArgList[0] = new(C) clang::UnaryOperator(DstExpr, 659c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::UO_AddrOf, 660c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDArgType[0], 661c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines Loc); 6622bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines ArgList[1] = SrcExpr; 663c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 664c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::CallExpr *RSSetObjectCall = 665c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines new(C) clang::CallExpr(C, 666c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RSSetObjectFP, 667c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines ArgList, 668c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 2, 669c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFD->getCallResultType(), 670c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines Loc); 671c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 6722bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return RSSetObjectCall; 6732bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines} 6742bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 6752bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesstatic clang::Stmt *CreateStructRSSetObject(clang::ASTContext &C, 6762bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Diagnostic *Diags, 6772bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *LHS, 6782bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *RHS, 6792bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SourceLocation Loc); 6802bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 6812bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesstatic clang::Stmt *CreateArrayRSSetObject(clang::ASTContext &C, 6822bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Diagnostic *Diags, 6832bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *DstArr, 6842bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *SrcArr, 6852bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SourceLocation Loc) { 6862bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclContext *DC = NULL; 6872bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SourceRange Range; 6882bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *BaseType = DstArr->getType().getTypePtr(); 6892bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(BaseType->isArrayType()); 6902bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 6912bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines int NumArrayElements = ArrayDim(BaseType); 6922bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Actually extract out the base RS object type for use later 6932bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines BaseType = BaseType->getArrayElementTypeNoTypeQual(); 6942bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 6952bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Stmt *StmtArray[2] = {NULL}; 6962bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines int StmtCtr = 0; 6972bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 6982bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (NumArrayElements <= 0) { 6992bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return NULL; 7002bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 7012bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7022bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Create helper variable for iterating through elements 7032bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::IdentifierInfo& II = C.Idents.get("rsIntIter"); 7042bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VarDecl *IIVD = 7052bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VarDecl::Create(C, 7062bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines DC, 7072bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 7082bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines &II, 7092bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 7102bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.getTrivialTypeSourceInfo(C.IntTy), 7112bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SC_None, 7122bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SC_None); 7132bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Decl *IID = (clang::Decl *)IIVD; 7142bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7152bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclGroupRef DGR = clang::DeclGroupRef::Create(C, &IID, 1); 7162bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCtr++] = new(C) clang::DeclStmt(DGR, Loc, Loc); 7172bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7182bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Form the actual loop 7192bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // for (Init; Cond; Inc) 7202bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // RSSetObjectCall; 7212bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7222bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Init -> "rsIntIter = 0" 7232bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclRefExpr *RefrsIntIter = 7242bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclRefExpr::Create(C, 7252bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NULL, 7262bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Range, 7272bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines IIVD, 7282bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 7292bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy); 7302bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7312bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, 7322bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), 0), C.IntTy, Loc); 7332bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7342bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BinaryOperator *Init = 7352bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 7362bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Int0, 7372bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BO_Assign, 7382bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 7392bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 7402bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7412bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Cond -> "rsIntIter < NumArrayElements" 7422bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *NumArrayElementsExpr = clang::IntegerLiteral::Create(C, 7432bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), NumArrayElements), C.IntTy, Loc); 7442bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7452bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BinaryOperator *Cond = 7462bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 7472bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NumArrayElementsExpr, 7482bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BO_LT, 7492bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 7502bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 7512bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7522bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Inc -> "rsIntIter++" 7532bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::UnaryOperator *Inc = 7542bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::UnaryOperator(RefrsIntIter, 7552bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::UO_PostInc, 7562bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 7572bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 7582bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7592bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Body -> "rsSetObject(&Dst[rsIntIter], Src[rsIntIter]);" 7602bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Loop operates on individual array elements 7612bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7622bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *DstArrPtr = 7632bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ImplicitCastExpr::Create(C, 7642bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.getPointerType(BaseType->getCanonicalTypeInternal()), 7652bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::CK_ArrayToPointerDecay, 7662bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines DstArr, 7672bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NULL, 7682bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VK_RValue); 7692bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7702bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *DstArrPtrSubscript = 7712bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::ArraySubscriptExpr(DstArrPtr, 7722bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RefrsIntIter, 7732bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines BaseType->getCanonicalTypeInternal(), 7742bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 7752bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7762bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *SrcArrPtr = 7772bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ImplicitCastExpr::Create(C, 7782bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.getPointerType(BaseType->getCanonicalTypeInternal()), 7792bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::CK_ArrayToPointerDecay, 7802bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines SrcArr, 7812bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NULL, 7822bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VK_RValue); 7832bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7842bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *SrcArrPtrSubscript = 7852bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::ArraySubscriptExpr(SrcArrPtr, 7862bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RefrsIntIter, 7872bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines BaseType->getCanonicalTypeInternal(), 7882bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 7892bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7902bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSExportPrimitiveType::DataType DT = 7912bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSExportPrimitiveType::GetRSSpecificType(BaseType); 7922bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7932bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Stmt *RSSetObjectCall = NULL; 7942bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (BaseType->isArrayType()) { 7952bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSSetObjectCall = CreateArrayRSSetObject(C, Diags, DstArrPtrSubscript, 7962bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines SrcArrPtrSubscript, Loc); 7972bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else if (DT == RSExportPrimitiveType::DataTypeUnknown) { 7982bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSSetObjectCall = CreateStructRSSetObject(C, Diags, DstArrPtrSubscript, 7992bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines SrcArrPtrSubscript, Loc); 8002bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else { 8012bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSSetObjectCall = CreateSingleRSSetObject(C, Diags, DstArrPtrSubscript, 8022bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines SrcArrPtrSubscript, Loc); 8032bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 8042bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8052bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ForStmt *DestructorLoop = 8062bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::ForStmt(C, 8072bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Init, 8082bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Cond, 8092bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NULL, // no condVar 8102bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Inc, 8112bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSSetObjectCall, 8122bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 8132bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 8142bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 8152bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8162bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCtr++] = DestructorLoop; 8172bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(StmtCtr == 2); 8182bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8192bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::CompoundStmt *CS = 8202bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::CompoundStmt(C, StmtArray, StmtCtr, Loc, Loc); 8212bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8222bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return CS; 8232bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines} 8242bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8252bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesstatic clang::Stmt *CreateStructRSSetObject(clang::ASTContext &C, 8262bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Diagnostic *Diags, 8272bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *LHS, 8282bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *RHS, 8292bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SourceLocation Loc) { 8302bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SourceRange Range; 8312bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::QualType QT = LHS->getType(); 8322bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *T = QT.getTypePtr(); 8332bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(T->isStructureType()); 8342bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(!RSExportPrimitiveType::IsRSObjectType(T)); 8352bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8362bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Keep an extra slot for the original copy (memcpy) 8372bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines unsigned FieldsToSet = CountRSObjectTypes(T) + 1; 8382bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8392bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines unsigned StmtCount = 0; 8402bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Stmt **StmtArray = new clang::Stmt*[FieldsToSet]; 8412bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines for (unsigned i = 0; i < FieldsToSet; i++) { 8422bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[i] = NULL; 8432bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 8442bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8452bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::RecordDecl *RD = T->getAsStructureType()->getDecl(); 8462bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RD = RD->getDefinition(); 8472bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 8482bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FE = RD->field_end(); 8492bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FI != FE; 8502bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FI++) { 8512bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines bool IsArrayType = false; 8522bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::FieldDecl *FD = *FI; 8532bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 8542bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *OrigType = FT; 8552bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8562bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (!CountRSObjectTypes(FT)) { 8572bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Skip to next if we don't have any viable RS object types 8582bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines continue; 8592bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 8602bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8612bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclAccessPair FoundDecl = 8622bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclAccessPair::make(FD, clang::AS_none); 8632bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr *DstMember = 8642bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr::Create(C, 8652bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines LHS, 8662bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines false, 8672bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NULL, 8682bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Range, 8692bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FD, 8702bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FoundDecl, 8712bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclarationNameInfo(), 8722bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NULL, 8732bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines OrigType->getCanonicalTypeInternal()); 8742bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8752bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr *SrcMember = 8762bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr::Create(C, 8772bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RHS, 8782bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines false, 8792bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NULL, 8802bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Range, 8812bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FD, 8822bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FoundDecl, 8832bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclarationNameInfo(), 8842bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NULL, 8852bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines OrigType->getCanonicalTypeInternal()); 8862bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8872bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (FT->isArrayType()) { 8882bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 8892bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines IsArrayType = true; 8902bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 8912bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8922bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSExportPrimitiveType::DataType DT = 8932bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSExportPrimitiveType::GetRSSpecificType(FT); 8942bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8952bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (IsArrayType) { 8962bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Diags->Report(Diags->getCustomDiagID(clang::Diagnostic::Error, 8972bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines "Arrays of RS object types within structures cannot be copied")); 8982bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // TODO(srhines): Support setting arrays of RS objects 8992bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // StmtArray[StmtCount++] = 9002bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // CreateArrayRSSetObject(C, Diags, DstMember, SrcMember, Loc); 9012bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else if (DT == RSExportPrimitiveType::DataTypeUnknown) { 9022bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCount++] = 9032bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines CreateStructRSSetObject(C, Diags, DstMember, SrcMember, Loc); 9042bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else if (RSExportPrimitiveType::IsRSObjectType(DT)) { 9052bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCount++] = 9062bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines CreateSingleRSSetObject(C, Diags, DstMember, SrcMember, Loc); 9072bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else { 9082bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(false); 9092bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 9102bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 9112bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9122bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(StmtCount > 0 && StmtCount < FieldsToSet); 9132bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9142bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // We still need to actually do the overall struct copy. For simplicity, 9152bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // we just do a straight-up assignment (which will still preserve all 9162bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // the proper RS object reference counts). 9172bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BinaryOperator *CopyStruct = 9182bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::BinaryOperator(LHS, RHS, clang::BO_Assign, QT, Loc); 9192bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCount++] = CopyStruct; 9202bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9212bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::CompoundStmt *CS = 9222bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::CompoundStmt(C, StmtArray, StmtCount, Loc, Loc); 9232bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9242bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines delete [] StmtArray; 9252bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9262bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return CS; 9272bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines} 9282bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9292bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines} // namespace 9302bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9312bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesvoid RSObjectRefCount::Scope::ReplaceRSObjectAssignment( 9322bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BinaryOperator *AS, 9332bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Diagnostic *Diags) { 9342bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9352bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::QualType QT = AS->getType(); 9362bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9372bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ASTContext &C = RSObjectRefCount::GetRSSetObjectFD( 9382bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSExportPrimitiveType::DataTypeRSFont)->getASTContext(); 9392bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9402bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SourceLocation Loc = AS->getLocEnd(); 9412bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Stmt *UpdatedStmt = NULL; 9422bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9432bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (!RSExportPrimitiveType::IsRSObjectType(QT.getTypePtr())) { 9442bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // By definition, this is a struct assignment if we get here 9452bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines UpdatedStmt = 9462bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines CreateStructRSSetObject(C, Diags, AS->getLHS(), AS->getRHS(), Loc); 9472bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else { 9482bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines UpdatedStmt = 9492bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines CreateSingleRSSetObject(C, Diags, AS->getLHS(), AS->getRHS(), Loc); 9502bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 951e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 9522bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines ReplaceInCompoundStmt(C, mCS, AS, UpdatedStmt); 953e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return; 954e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines} 955e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 956e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hinesvoid RSObjectRefCount::Scope::AppendRSObjectInit( 957e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::VarDecl *VD, 958e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclStmt *DS, 959e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataType DT, 960e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *InitExpr) { 9616e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(VD); 962e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 963e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (!InitExpr) { 964e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return; 965e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 966e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 967f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (DT == RSExportPrimitiveType::DataTypeIsStruct) { 968f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // TODO(srhines): Skip struct initialization right now 969f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return; 970f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 971f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 972f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::FunctionDecl *SetObjectFD = RSObjectRefCount::GetRSSetObjectFD(DT); 9736e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((SetObjectFD != NULL) && 9746e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "rsSetObject doesn't cover all RS object types"); 975e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::ASTContext &C = SetObjectFD->getASTContext(); 976e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 977e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::QualType SetObjectFDType = SetObjectFD->getType(); 978e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::QualType SetObjectFDArgType[2]; 979e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDArgType[0] = SetObjectFD->getParamDecl(0)->getOriginalType(); 980e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDArgType[1] = SetObjectFD->getParamDecl(1)->getOriginalType(); 981e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 982e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::SourceLocation Loc = SetObjectFD->getLocation(); 983e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *RefRSSetObjectFD = 984e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr::Create(C, 985e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines NULL, 986e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFD->getQualifierRange(), 987e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFD, 988e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc, 989e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDType); 990e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 991e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *RSSetObjectFP = 992e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::ImplicitCastExpr::Create(C, 993e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines C.getPointerType(SetObjectFDType), 994e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CK_FunctionToPointerDecay, 995e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RefRSSetObjectFD, 996e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines NULL, 997e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::VK_RValue); 998e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 999e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 1000e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr *RefRSVar = 1001e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr::Create(C, 1002e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines NULL, 1003e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->getQualifierRange(), 1004e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD, 1005e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc, 1006e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines T->getCanonicalTypeInternal()); 1007e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1008e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *ArgList[2]; 1009e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ArgList[0] = new(C) clang::UnaryOperator(RefRSVar, 1010e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::UO_AddrOf, 1011e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDArgType[0], 1012e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc); 1013e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ArgList[1] = InitExpr; 1014e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1015e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CallExpr *RSSetObjectCall = 1016e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines new(C) clang::CallExpr(C, 1017e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSSetObjectFP, 1018e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ArgList, 1019e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 2, 1020e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFD->getCallResultType(), 1021e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc); 1022e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1023e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines AppendAfterStmt(C, mCS, DS, RSSetObjectCall); 1024c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 1025c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines return; 1026c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines} 1027c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 10281bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hinesvoid RSObjectRefCount::Scope::InsertLocalVarDestructors() { 1029d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines std::list<clang::Stmt*> RSClearObjectCalls; 10301bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines for (std::list<clang::VarDecl*>::const_iterator I = mRSO.begin(), 10311bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines E = mRSO.end(); 10321bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines I != E; 10331bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines I++) { 1034a858cb6f3d9223d65bf73e1230c6324ded4095f6Stephen Hines clang::Stmt *S = ClearRSObject(*I); 1035a858cb6f3d9223d65bf73e1230c6324ded4095f6Stephen Hines if (S) { 1036a858cb6f3d9223d65bf73e1230c6324ded4095f6Stephen Hines RSClearObjectCalls.push_back(S); 10371bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 10381bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 10391bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if (RSClearObjectCalls.size() > 0) { 10404464d825c11349068f2917f9ebee86b721423f3cStephen Hines DestructorVisitor DV((*mRSO.begin())->getASTContext(), RSClearObjectCalls); 10414464d825c11349068f2917f9ebee86b721423f3cStephen Hines DV.Visit(mCS); 10421bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 10431bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines return; 10441bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 10451bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1046d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hinesclang::Stmt *RSObjectRefCount::Scope::ClearRSObject(clang::VarDecl *VD) { 1047f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(VD); 10481bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::ASTContext &C = VD->getASTContext(); 1049f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC = VD->getDeclContext(); 1050f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceRange Range = VD->getQualifierRange(); 10511bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::SourceLocation Loc = VD->getLocation(); 10521bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 105303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 10541bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Reference expr to target RS object variable 10551bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::DeclRefExpr *RefRSVar = 10561bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::DeclRefExpr::Create(C, 10571bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines NULL, 1058f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Range, 10591bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines VD, 10601bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines Loc, 106103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines T->getCanonicalTypeInternal()); 10621bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1063f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (T->isArrayType()) { 1064f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return ClearArrayRSObject(C, DC, RefRSVar, Range, Loc); 1065f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 10661bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1067f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::DataType DT = 1068f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::GetRSSpecificType(T); 10691bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1070f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (DT == RSExportPrimitiveType::DataTypeUnknown || 1071f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DT == RSExportPrimitiveType::DataTypeIsStruct) { 1072f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return ClearStructRSObject(C, DC, RefRSVar, Range, Loc); 1073f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 10741bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1075f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert((RSExportPrimitiveType::IsRSObjectType(DT)) && 1076f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "Should be RS object"); 10771bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1078f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return ClearSingleRSObject(C, RefRSVar, Loc); 10791bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 10801bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1081e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hinesbool RSObjectRefCount::InitializeRSObject(clang::VarDecl *VD, 1082e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataType *DT, 1083e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr **InitExpr) { 10846e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(VD && DT && InitExpr); 10854b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 10862d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines 10872d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines // Loop through array types to get to base type 10882d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines while (T && T->isArrayType()) { 10892d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines T = T->getArrayElementTypeNoTypeQual(); 10902d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines } 10912d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines 1092f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool DataTypeIsStructWithRSObject = false; 1093e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines *DT = RSExportPrimitiveType::GetRSSpecificType(T); 10944b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1095e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (*DT == RSExportPrimitiveType::DataTypeUnknown) { 1096feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (RSExportPrimitiveType::IsStructureTypeWithRSObject(T)) { 1097feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines *DT = RSExportPrimitiveType::DataTypeIsStruct; 1098f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DataTypeIsStructWithRSObject = true; 1099feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } else { 1100feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines return false; 1101feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 11022d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines } 11034b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1104f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool DataTypeIsRSObject = false; 1105f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (DataTypeIsStructWithRSObject) { 1106f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DataTypeIsRSObject = true; 1107f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 1108f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DataTypeIsRSObject = RSExportPrimitiveType::IsRSObjectType(*DT); 1109f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 1110e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines *InitExpr = VD->getInit(); 1111e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1112e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (!DataTypeIsRSObject && *InitExpr) { 1113e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines // If we already have an initializer for a matrix type, we are done. 1114e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return DataTypeIsRSObject; 11154b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 11164b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1117e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *ZeroInitializer = 1118e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines CreateZeroInitializerForRSSpecificType(*DT, 1119e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->getASTContext(), 1120e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->getLocation()); 1121e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1122e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (ZeroInitializer) { 1123e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ZeroInitializer->setType(T->getCanonicalTypeInternal()); 1124e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->setInit(ZeroInitializer); 1125e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 1126e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1127e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return DataTypeIsRSObject; 11284b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 11294b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 11304b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesclang::Expr *RSObjectRefCount::CreateZeroInitializerForRSSpecificType( 11314b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines RSExportPrimitiveType::DataType DT, 11324b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ASTContext &C, 11334b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines const clang::SourceLocation &Loc) { 11344b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *Res = NULL; 11354b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines switch (DT) { 1136feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines case RSExportPrimitiveType::DataTypeIsStruct: 11374b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSElement: 11384b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSType: 11394b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSAllocation: 11404b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSSampler: 11414b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSScript: 11424b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMesh: 11434b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramFragment: 11444b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramVertex: 11454b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramRaster: 11464b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramStore: 11474b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSFont: { 11484b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (ImplicitCastExpr 'nullptr_t' 11494b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (IntegerLiteral 0))) 11504b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APInt Zero(C.getTypeSize(C.IntTy), 0); 11514b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, Zero, C.IntTy, Loc); 11524b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *CastToNull = 11534b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ImplicitCastExpr::Create(C, 11544b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines C.NullPtrTy, 11554b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::CK_IntegralToPointer, 11564b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Int0, 11574b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines NULL, 11584b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::VK_RValue); 11594b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1160e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Res = new(C) clang::InitListExpr(C, Loc, &CastToNull, 1, Loc); 11614b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines break; 11624b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 11634b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMatrix2x2: 11644b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMatrix3x3: 11654b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMatrix4x4: { 11664b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // RS matrix is not completely an RS object. They hold data by themselves. 11674b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (InitListExpr rs_matrix2x2 11684b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (InitListExpr float[4] 11694b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 11704b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 11714b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 11724b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0))) 11734b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::QualType FloatTy = C.FloatTy; 11744b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Constructor sets value to 0.0f by default 11754b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APFloat Val(C.getFloatTypeSemantics(FloatTy)); 11764b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::FloatingLiteral *Float0Val = 11774b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::FloatingLiteral::Create(C, 11784b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Val, 11794b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines /* isExact = */true, 11804b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines FloatTy, 11814b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Loc); 11824b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 11834b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines unsigned N = 0; 11844b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (DT == RSExportPrimitiveType::DataTypeRSMatrix2x2) 11854b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 2; 11864b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines else if (DT == RSExportPrimitiveType::DataTypeRSMatrix3x3) 11874b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 3; 11884b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines else if (DT == RSExportPrimitiveType::DataTypeRSMatrix4x4) 11894b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 4; 11904b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 11914b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Directly allocate 16 elements instead of dynamically allocate N*N 11924b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *InitVals[16]; 11934b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (unsigned i = 0; i < sizeof(InitVals) / sizeof(InitVals[0]); i++) 11944b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines InitVals[i] = Float0Val; 11954b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *InitExpr = 1196e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines new(C) clang::InitListExpr(C, Loc, InitVals, N * N, Loc); 11974b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines InitExpr->setType(C.getConstantArrayType(FloatTy, 11984b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APInt(32, 4), 11994b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ArrayType::Normal, 12004b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines /* EltTypeQuals = */0)); 12014b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1202e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Res = new(C) clang::InitListExpr(C, Loc, &InitExpr, 1, Loc); 12034b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines break; 12044b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 12054b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnknown: 12064b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeFloat16: 12074b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeFloat32: 12084b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeFloat64: 12094b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned8: 12104b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned16: 12114b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned32: 12124b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned64: 12134b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned8: 12144b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned16: 12154b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned32: 12164b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned64: 12174b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeBoolean: 12184b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned565: 12194b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned5551: 12204b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned4444: 12214b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeMax: { 12226e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Not RS object type!"); 12234b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 12244b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // No default case will enable compiler detecting the missing cases 12254b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 12264b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 12274b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return Res; 12284b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 12294b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 12304b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitDeclStmt(clang::DeclStmt *DS) { 12314b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (clang::DeclStmt::decl_iterator I = DS->decl_begin(), E = DS->decl_end(); 12324b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I != E; 12334b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I++) { 12344b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Decl *D = *I; 12354b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (D->getKind() == clang::Decl::Var) { 12364b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::VarDecl *VD = static_cast<clang::VarDecl*>(D); 1237e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataType DT = 1238e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataTypeUnknown; 1239e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *InitExpr = NULL; 1240e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (InitializeRSObject(VD, &DT, &InitExpr)) { 12414b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines getCurrentScope()->addRSObject(VD); 1242e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines getCurrentScope()->AppendRSObjectInit(VD, DS, DT, InitExpr); 1243e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 12444b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 12454b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 12464b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 12474b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 12484b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 12494b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitCompoundStmt(clang::CompoundStmt *CS) { 12504b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (!CS->body_empty()) { 12514b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Push a new scope 12524b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Scope *S = new Scope(CS); 12534b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines mScopeStack.push(S); 12544b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 12554b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines VisitStmt(CS); 12564b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 12574b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Destroy the scope 12586e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((getCurrentScope() == S) && "Corrupted scope stack!"); 12591bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines S->InsertLocalVarDestructors(); 12604b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines mScopeStack.pop(); 12614b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines delete S; 12624b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 12634b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 12644b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 12654b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 12664b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitBinAssign(clang::BinaryOperator *AS) { 1267c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType QT = AS->getType(); 1268c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 12692bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (CountRSObjectTypes(QT.getTypePtr())) { 12702bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines getCurrentScope()->ReplaceRSObjectAssignment(AS, mDiags); 1271c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 1272c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 12734b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 12744b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 12754b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 12764b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitStmt(clang::Stmt *S) { 12774b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end(); 12784b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I != E; 12794b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I++) { 12804b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (clang::Stmt *Child = *I) { 12814b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Visit(Child); 12824b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 12834b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 12844b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 12854b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 12864b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1287e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 1288