slang_rs_object_ref_count.cpp revision be27482cdeaf08576bc39b72a15d35d13014a636
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" 23be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "clang/AST/NestedNameSpecifier.h" 244b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "clang/AST/OperationKinds.h" 254b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "clang/AST/Stmt.h" 264b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "clang/AST/StmtVisitor.h" 274b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 286e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h" 294b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "slang_rs.h" 304b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "slang_rs_export_type.h" 314b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 32e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang { 334b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 34f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesclang::FunctionDecl *RSObjectRefCount:: 351bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSSetObjectFD[RSExportPrimitiveType::LastRSObjectType - 361bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSExportPrimitiveType::FirstRSObjectType + 1]; 37f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesclang::FunctionDecl *RSObjectRefCount:: 381bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSClearObjectFD[RSExportPrimitiveType::LastRSObjectType - 391bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSExportPrimitiveType::FirstRSObjectType + 1]; 401bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 41f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesvoid RSObjectRefCount::GetRSRefCountingFunctions(clang::ASTContext &C) { 421bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines for (unsigned i = 0; 431bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines i < (sizeof(RSClearObjectFD) / sizeof(clang::FunctionDecl*)); 441bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines i++) { 451bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSSetObjectFD[i] = NULL; 461bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSClearObjectFD[i] = NULL; 471bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 481bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 491bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl(); 501bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 511bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(), 521bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines E = TUDecl->decls_end(); I != E; I++) { 531bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if ((I->getKind() >= clang::Decl::firstFunction) && 541bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines (I->getKind() <= clang::Decl::lastFunction)) { 551bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::FunctionDecl *FD = static_cast<clang::FunctionDecl*>(*I); 561bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 571bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // points to RSSetObjectFD or RSClearObjectFD 581bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::FunctionDecl **RSObjectFD; 591bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 601bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if (FD->getName() == "rsSetObject") { 616e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((FD->getNumParams() == 2) && 626e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "Invalid rsSetObject function prototype (# params)"); 631bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSObjectFD = RSSetObjectFD; 641bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } else if (FD->getName() == "rsClearObject") { 656e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((FD->getNumParams() == 1) && 666e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "Invalid rsClearObject function prototype (# params)"); 671bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSObjectFD = RSClearObjectFD; 68e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines } else { 691bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines continue; 701bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 711bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 721bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines const clang::ParmVarDecl *PVD = FD->getParamDecl(0); 731bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::QualType PVT = PVD->getOriginalType(); 741bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // The first parameter must be a pointer like rs_allocation* 756e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(PVT->isPointerType() && 766e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "Invalid rs{Set,Clear}Object function prototype (pointer param)"); 771bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 781bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // The rs object type passed to the FD 791bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::QualType RST = PVT->getPointeeType(); 801bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSExportPrimitiveType::DataType DT = 811bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSExportPrimitiveType::GetRSSpecificType(RST.getTypePtr()); 826e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(RSExportPrimitiveType::IsRSObjectType(DT) 831bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines && "must be RS object type"); 841bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 851bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSObjectFD[(DT - RSExportPrimitiveType::FirstRSObjectType)] = FD; 861bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 871bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 881bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 891bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 904464d825c11349068f2917f9ebee86b721423f3cStephen Hinesnamespace { 914464d825c11349068f2917f9ebee86b721423f3cStephen Hines 924464d825c11349068f2917f9ebee86b721423f3cStephen Hinesstatic void AppendToCompoundStatement(clang::ASTContext& C, 934464d825c11349068f2917f9ebee86b721423f3cStephen Hines clang::CompoundStmt *CS, 94d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines std::list<clang::Stmt*> &StmtList, 954464d825c11349068f2917f9ebee86b721423f3cStephen Hines bool InsertAtEndOfBlock) { 961bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Destructor code will be inserted before any return statement. 971bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Any subsequent statements in the compound statement are then placed 981bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // after our new code. 99e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines // TODO(srhines): This should also handle the case of goto/break/continue. 1004464d825c11349068f2917f9ebee86b721423f3cStephen Hines 1014464d825c11349068f2917f9ebee86b721423f3cStephen Hines clang::CompoundStmt::body_iterator bI = CS->body_begin(); 1021bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1031bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines unsigned OldStmtCount = 0; 10403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines for (bI = CS->body_begin(); bI != CS->body_end(); bI++) { 1051bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines OldStmtCount++; 1061bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1071bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 108d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines unsigned NewStmtCount = StmtList.size(); 1091bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 110d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines clang::Stmt **UpdatedStmtList; 111d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines UpdatedStmtList = new clang::Stmt*[OldStmtCount+NewStmtCount]; 1121bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1131bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines unsigned UpdatedStmtCount = 0; 1144464d825c11349068f2917f9ebee86b721423f3cStephen Hines bool FoundReturn = false; 11503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines for (bI = CS->body_begin(); bI != CS->body_end(); bI++) { 1161bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if ((*bI)->getStmtClass() == clang::Stmt::ReturnStmtClass) { 1174464d825c11349068f2917f9ebee86b721423f3cStephen Hines FoundReturn = true; 1181bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines break; 1191bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 120d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines UpdatedStmtList[UpdatedStmtCount++] = *bI; 1211bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1221bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1234464d825c11349068f2917f9ebee86b721423f3cStephen Hines // Always insert before a return that we found, or if we are told 1244464d825c11349068f2917f9ebee86b721423f3cStephen Hines // to insert at the end of the block 1254464d825c11349068f2917f9ebee86b721423f3cStephen Hines if (FoundReturn || InsertAtEndOfBlock) { 12603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines std::list<clang::Stmt*>::const_iterator I = StmtList.begin(); 12703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines for (std::list<clang::Stmt*>::const_iterator I = StmtList.begin(); 12803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines I != StmtList.end(); 1294464d825c11349068f2917f9ebee86b721423f3cStephen Hines I++) { 130d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines UpdatedStmtList[UpdatedStmtCount++] = *I; 1314464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 1321bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1331bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1341bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Pick up anything left over after a return statement 13503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines for ( ; bI != CS->body_end(); bI++) { 136d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines UpdatedStmtList[UpdatedStmtCount++] = *bI; 1371bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1381bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 139d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines CS->setStmts(C, UpdatedStmtList, UpdatedStmtCount); 1401bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 141d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines delete [] UpdatedStmtList; 1421bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1431bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines return; 1441bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 1451bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 146e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hinesstatic void AppendAfterStmt(clang::ASTContext& C, 147e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CompoundStmt *CS, 148e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Stmt *OldStmt, 149e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Stmt *NewStmt) { 1506e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(CS && OldStmt && NewStmt); 151e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CompoundStmt::body_iterator bI = CS->body_begin(); 152e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines unsigned StmtCount = 1; // Take into account new statement 153e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines for (bI = CS->body_begin(); bI != CS->body_end(); bI++) { 154e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines StmtCount++; 155e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 156e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 157e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Stmt **UpdatedStmtList = new clang::Stmt*[StmtCount]; 158e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 159e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines unsigned UpdatedStmtCount = 0; 160e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines unsigned Once = 0; 161e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines for (bI = CS->body_begin(); bI != CS->body_end(); bI++) { 162e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines UpdatedStmtList[UpdatedStmtCount++] = *bI; 163e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (*bI == OldStmt) { 164e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Once++; 1656e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(Once == 1); 166e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines UpdatedStmtList[UpdatedStmtCount++] = NewStmt; 167e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 168e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 169e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 170e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines CS->setStmts(C, UpdatedStmtList, UpdatedStmtCount); 171e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 172e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines delete [] UpdatedStmtList; 173e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 174e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return; 175e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines} 176e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 177e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hinesstatic void ReplaceInCompoundStmt(clang::ASTContext& C, 178c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::CompoundStmt *CS, 179c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Stmt* OldStmt, 180c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Stmt* NewStmt) { 181c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::CompoundStmt::body_iterator bI = CS->body_begin(); 182c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 183c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines unsigned StmtCount = 0; 184c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines for (bI = CS->body_begin(); bI != CS->body_end(); bI++) { 185c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines StmtCount++; 186c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 187c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 188c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Stmt **UpdatedStmtList = new clang::Stmt*[StmtCount]; 189c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 190c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines unsigned UpdatedStmtCount = 0; 191c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines for (bI = CS->body_begin(); bI != CS->body_end(); bI++) { 192c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines if (*bI == OldStmt) { 193c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines UpdatedStmtList[UpdatedStmtCount++] = NewStmt; 194c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } else { 195c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines UpdatedStmtList[UpdatedStmtCount++] = *bI; 196c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 197c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 198c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 199c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines CS->setStmts(C, UpdatedStmtList, UpdatedStmtCount); 200c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 201c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines delete [] UpdatedStmtList; 202c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 203c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines return; 204c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines} 205c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 206c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 207d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines// This class visits a compound statement and inserts the StmtList containing 2084464d825c11349068f2917f9ebee86b721423f3cStephen Hines// destructors in proper locations. This includes inserting them before any 2094464d825c11349068f2917f9ebee86b721423f3cStephen Hines// return statement in any sub-block, at the end of the logical enclosing 2104464d825c11349068f2917f9ebee86b721423f3cStephen Hines// scope (compound statement), and/or before any break/continue statement that 2114464d825c11349068f2917f9ebee86b721423f3cStephen Hines// would resume outside the declared scope. We will not handle the case for 2124464d825c11349068f2917f9ebee86b721423f3cStephen Hines// goto statements that leave a local scope. 2134464d825c11349068f2917f9ebee86b721423f3cStephen Hines// TODO(srhines): Make this work properly for break/continue. 2144464d825c11349068f2917f9ebee86b721423f3cStephen Hinesclass DestructorVisitor : public clang::StmtVisitor<DestructorVisitor> { 2154464d825c11349068f2917f9ebee86b721423f3cStephen Hines private: 2164464d825c11349068f2917f9ebee86b721423f3cStephen Hines clang::ASTContext &mC; 217d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines std::list<clang::Stmt*> &mStmtList; 2184464d825c11349068f2917f9ebee86b721423f3cStephen Hines bool mTopLevel; 2194464d825c11349068f2917f9ebee86b721423f3cStephen Hines public: 220d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines DestructorVisitor(clang::ASTContext &C, std::list<clang::Stmt*> &StmtList); 2214464d825c11349068f2917f9ebee86b721423f3cStephen Hines void VisitStmt(clang::Stmt *S); 2224464d825c11349068f2917f9ebee86b721423f3cStephen Hines void VisitCompoundStmt(clang::CompoundStmt *CS); 2234464d825c11349068f2917f9ebee86b721423f3cStephen Hines}; 2244464d825c11349068f2917f9ebee86b721423f3cStephen Hines 2254464d825c11349068f2917f9ebee86b721423f3cStephen HinesDestructorVisitor::DestructorVisitor(clang::ASTContext &C, 226d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines std::list<clang::Stmt*> &StmtList) 2274464d825c11349068f2917f9ebee86b721423f3cStephen Hines : mC(C), 228d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines mStmtList(StmtList), 2294464d825c11349068f2917f9ebee86b721423f3cStephen Hines mTopLevel(true) { 2304464d825c11349068f2917f9ebee86b721423f3cStephen Hines return; 2314464d825c11349068f2917f9ebee86b721423f3cStephen Hines} 2324464d825c11349068f2917f9ebee86b721423f3cStephen Hines 2334464d825c11349068f2917f9ebee86b721423f3cStephen Hinesvoid DestructorVisitor::VisitCompoundStmt(clang::CompoundStmt *CS) { 2344464d825c11349068f2917f9ebee86b721423f3cStephen Hines if (!CS->body_empty()) { 235d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines AppendToCompoundStatement(mC, CS, mStmtList, mTopLevel); 2364464d825c11349068f2917f9ebee86b721423f3cStephen Hines mTopLevel = false; 2374464d825c11349068f2917f9ebee86b721423f3cStephen Hines VisitStmt(CS); 2384464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 2394464d825c11349068f2917f9ebee86b721423f3cStephen Hines return; 2404464d825c11349068f2917f9ebee86b721423f3cStephen Hines} 2414464d825c11349068f2917f9ebee86b721423f3cStephen Hines 2424464d825c11349068f2917f9ebee86b721423f3cStephen Hinesvoid DestructorVisitor::VisitStmt(clang::Stmt *S) { 2434464d825c11349068f2917f9ebee86b721423f3cStephen Hines for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end(); 2444464d825c11349068f2917f9ebee86b721423f3cStephen Hines I != E; 2454464d825c11349068f2917f9ebee86b721423f3cStephen Hines I++) { 2464464d825c11349068f2917f9ebee86b721423f3cStephen Hines if (clang::Stmt *Child = *I) { 2474464d825c11349068f2917f9ebee86b721423f3cStephen Hines Visit(Child); 2484464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 2494464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 2504464d825c11349068f2917f9ebee86b721423f3cStephen Hines return; 2514464d825c11349068f2917f9ebee86b721423f3cStephen Hines} 2524464d825c11349068f2917f9ebee86b721423f3cStephen Hines 253f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesclang::Expr *ClearSingleRSObject(clang::ASTContext &C, 254f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSVar, 255f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc) { 256f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(RefRSVar); 257f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *T = RefRSVar->getType().getTypePtr(); 258f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(!T->isArrayType() && 259f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "Should not be destroying arrays with this function"); 260f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 261f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::FunctionDecl *ClearObjectFD = RSObjectRefCount::GetRSClearObjectFD(T); 262f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert((ClearObjectFD != NULL) && 263f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "rsClearObject doesn't cover all RS object types"); 264f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 265f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::QualType ClearObjectFDType = ClearObjectFD->getType(); 266f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::QualType ClearObjectFDArgType = 267f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD->getParamDecl(0)->getOriginalType(); 268f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 269f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Example destructor for "rs_font localFont;" 270f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // 271f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (CallExpr 'void' 272f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (ImplicitCastExpr 'void (*)(rs_font *)' <FunctionToPointerDecay> 273f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (DeclRefExpr 'void (rs_font *)' FunctionDecl='rsClearObject')) 274f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (UnaryOperator 'rs_font *' prefix '&' 275f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (DeclRefExpr 'rs_font':'rs_font' Var='localFont'))) 276f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 277f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Get address of targeted RS object 278f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *AddrRefRSVar = 279f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::UnaryOperator(RefRSVar, 280f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::UO_AddrOf, 281f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFDArgType, 282be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 283be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 284f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 285f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 286f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSClearObjectFD = 287f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclRefExpr::Create(C, 288be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 289f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD, 290f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD->getLocation(), 291be27482cdeaf08576bc39b72a15d35d13014a636Logan ClearObjectFDType, 292be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 293be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 294f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 295f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RSClearObjectFP = 296f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ImplicitCastExpr::Create(C, 297f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines C.getPointerType(ClearObjectFDType), 298f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::CK_FunctionToPointerDecay, 299f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSClearObjectFD, 300f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines NULL, 301f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::VK_RValue); 30203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 303f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::CallExpr *RSClearObjectCall = 304f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::CallExpr(C, 305f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectFP, 306f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines &AddrRefRSVar, 307f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 1, 308f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD->getCallResultType(), 309be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 310f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 311f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 312f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return RSClearObjectCall; 313f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines} 314f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 315f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic int ArrayDim(const clang::Type *T) { 31603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (!T || !T->isArrayType()) { 31703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return 0; 31803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 31903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 32003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines const clang::ConstantArrayType *CAT = 32103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines static_cast<const clang::ConstantArrayType *>(T); 3229d2c0fa6490e09b3ff5603796bce42d97788e5c8Stephen Hines return static_cast<int>(CAT->getSize().getSExtValue()); 32303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines} 32403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 325f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic clang::Stmt *ClearStructRSObject( 326f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ASTContext &C, 327f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC, 328f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSStruct, 329f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc); 330f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 331f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic clang::Stmt *ClearArrayRSObject( 332f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ASTContext &C, 333f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC, 334f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSArr, 335f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc) { 336f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *BaseType = RefRSArr->getType().getTypePtr(); 337f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(BaseType->isArrayType()); 338f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 339f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines int NumArrayElements = ArrayDim(BaseType); 340f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Actually extract out the base RS object type for use later 341f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines BaseType = BaseType->getArrayElementTypeNoTypeQual(); 34203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 34303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Stmt *StmtArray[2] = {NULL}; 34403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines int StmtCtr = 0; 34503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 34603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (NumArrayElements <= 0) { 34703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return NULL; 34803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 34903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 35003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Example destructor loop for "rs_font fontArr[10];" 35103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // 35203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (CompoundStmt 35303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclStmt "int rsIntIter") 35403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ForStmt 35503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (BinaryOperator 'int' '=' 35603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter') 35703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (IntegerLiteral 'int' 0)) 35803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (BinaryOperator 'int' '<' 35903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter') 36003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (IntegerLiteral 'int' 10) 36103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // NULL << CondVar >> 36203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (UnaryOperator 'int' postfix '++' 36303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter')) 36403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (CallExpr 'void' 36503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ImplicitCastExpr 'void (*)(rs_font *)' <FunctionToPointerDecay> 36603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'void (rs_font *)' FunctionDecl='rsClearObject')) 36703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (UnaryOperator 'rs_font *' prefix '&' 36803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ArraySubscriptExpr 'rs_font':'rs_font' 36903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ImplicitCastExpr 'rs_font *' <ArrayToPointerDecay> 37003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'rs_font [10]' Var='fontArr')) 37103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter'))))))) 37203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 37303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Create helper variable for iterating through elements 37403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::IdentifierInfo& II = C.Idents.get("rsIntIter"); 37503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VarDecl *IIVD = 37603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VarDecl::Create(C, 377f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 37803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 37903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines &II, 38003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 38103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.getTrivialTypeSourceInfo(C.IntTy), 38203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::SC_None, 38303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::SC_None); 38403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Decl *IID = (clang::Decl *)IIVD; 38503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 38603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclGroupRef DGR = clang::DeclGroupRef::Create(C, &IID, 1); 38703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines StmtArray[StmtCtr++] = new(C) clang::DeclStmt(DGR, Loc, Loc); 38803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 38903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Form the actual destructor loop 39003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // for (Init; Cond; Inc) 39103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // RSClearObjectCall; 39203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 39303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Init -> "rsIntIter = 0" 39403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclRefExpr *RefrsIntIter = 39503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclRefExpr::Create(C, 396be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 39703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines IIVD, 39803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 399be27482cdeaf08576bc39b72a15d35d13014a636Logan C.IntTy, 400be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 401be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 40203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 40303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, 40403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), 0), C.IntTy, Loc); 40503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 40603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BinaryOperator *Init = 40703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 40803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Int0, 40903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BO_Assign, 41003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 411be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 412be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 41303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 41403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 41503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Cond -> "rsIntIter < NumArrayElements" 41603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *NumArrayElementsExpr = clang::IntegerLiteral::Create(C, 41703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), NumArrayElements), C.IntTy, Loc); 41803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 41903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BinaryOperator *Cond = 42003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 42103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NumArrayElementsExpr, 42203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BO_LT, 42303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 424be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 425be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 42603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 42703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 42803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Inc -> "rsIntIter++" 42903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::UnaryOperator *Inc = 43003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::UnaryOperator(RefrsIntIter, 43103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::UO_PostInc, 43203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 433be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 434be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 43503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 43603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 43703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Body -> "rsClearObject(&VD[rsIntIter]);" 43803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Destructor loop operates on individual array elements 43903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 440f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSArrPtr = 44103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::ImplicitCastExpr::Create(C, 442f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines C.getPointerType(BaseType->getCanonicalTypeInternal()), 44303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::CK_ArrayToPointerDecay, 444f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSArr, 44503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, 44603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VK_RValue); 44703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 448f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSArrPtrSubscript = 449f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::ArraySubscriptExpr(RefRSArrPtr, 45003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines RefrsIntIter, 451f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines BaseType->getCanonicalTypeInternal(), 452be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 453be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 454f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 45503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 456f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::DataType DT = 457f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::GetRSSpecificType(BaseType); 458f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 459f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Stmt *RSClearObjectCall = NULL; 460f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (BaseType->isArrayType()) { 461f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectCall = 462be27482cdeaf08576bc39b72a15d35d13014a636Logan ClearArrayRSObject(C, DC, RefRSArrPtrSubscript, Loc); 463f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else if (DT == RSExportPrimitiveType::DataTypeUnknown) { 464f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectCall = 465be27482cdeaf08576bc39b72a15d35d13014a636Logan ClearStructRSObject(C, DC, RefRSArrPtrSubscript, Loc); 466f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 467f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectCall = ClearSingleRSObject(C, RefRSArrPtrSubscript, Loc); 468f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 46903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 47003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::ForStmt *DestructorLoop = 47103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::ForStmt(C, 47203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Init, 47303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Cond, 47403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, // no condVar 47503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Inc, 47603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines RSClearObjectCall, 47703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 47803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 47903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 48003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 48103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines StmtArray[StmtCtr++] = DestructorLoop; 4826e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(StmtCtr == 2); 48303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 48403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::CompoundStmt *CS = 48503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::CompoundStmt(C, StmtArray, StmtCtr, Loc, Loc); 48603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 48703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return CS; 48803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines} 48903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 4902bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesstatic unsigned CountRSObjectTypes(const clang::Type *T) { 491f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(T); 492f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines unsigned RSObjectCount = 0; 493f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 494f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (T->isArrayType()) { 4952bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return CountRSObjectTypes(T->getArrayElementTypeNoTypeQual()); 496f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 497f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 498f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::DataType DT = 499f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::GetRSSpecificType(T); 500f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (DT != RSExportPrimitiveType::DataTypeUnknown) { 501f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return (RSExportPrimitiveType::IsRSObjectType(DT) ? 1 : 0); 502f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 503f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 504f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (!T->isStructureType()) { 505f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return 0; 506f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 507f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 508f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::RecordDecl *RD = T->getAsStructureType()->getDecl(); 509f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RD = RD->getDefinition(); 510f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 511f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FE = RD->field_end(); 512f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI != FE; 513f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI++) { 514f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::FieldDecl *FD = *FI; 515f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 5162bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (CountRSObjectTypes(FT)) { 517f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Sub-structs should only count once (as should arrays, etc.) 518f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectCount++; 519f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 520f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 521f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 522f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return RSObjectCount; 523f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines} 524f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 525f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic clang::Stmt *ClearStructRSObject( 526f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ASTContext &C, 527f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC, 528f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSStruct, 529f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc) { 530f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *BaseType = RefRSStruct->getType().getTypePtr(); 531f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 532f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(!BaseType->isArrayType()); 533f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 534f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::DataType DT = 535f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::GetRSSpecificType(BaseType); 536f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 537f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Structs should show up as unknown primitive types 538f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(DT == RSExportPrimitiveType::DataTypeUnknown); 539f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 5402bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines unsigned FieldsToDestroy = CountRSObjectTypes(BaseType); 541f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 542f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines unsigned StmtCount = 0; 543f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Stmt **StmtArray = new clang::Stmt*[FieldsToDestroy]; 5442bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines for (unsigned i = 0; i < FieldsToDestroy; i++) { 5452bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[i] = NULL; 5462bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 547f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 548f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Populate StmtArray by creating a destructor for each RS object field 549f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::RecordDecl *RD = BaseType->getAsStructureType()->getDecl(); 550f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RD = RD->getDefinition(); 551f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 552f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FE = RD->field_end(); 553f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI != FE; 554f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI++) { 555f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // We just look through all field declarations to see if we find a 556f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // declaration for an RS object type (or an array of one). 557f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool IsArrayType = false; 558f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::FieldDecl *FD = *FI; 559f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 560f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *OrigType = FT; 561f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines while (FT && FT->isArrayType()) { 562f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 563f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines IsArrayType = true; 564f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 565f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 566f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (RSExportPrimitiveType::IsRSObjectType(FT)) { 567f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair FoundDecl = 568f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair::make(FD, clang::AS_none); 569f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr *RSObjectMember = 570f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr::Create(C, 571f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSStruct, 572f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines false, 573be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 574f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FD, 575f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FoundDecl, 576f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclarationNameInfo(), 577f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines NULL, 578be27482cdeaf08576bc39b72a15d35d13014a636Logan OrigType->getCanonicalTypeInternal(), 579be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 580be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary); 581f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 582f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(StmtCount < FieldsToDestroy); 583f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 584f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (IsArrayType) { 585f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearArrayRSObject(C, 586f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 587f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 588f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 589f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 590f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearSingleRSObject(C, 591f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 592f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 593f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 5942bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else if (FT->isStructureType() && CountRSObjectTypes(FT)) { 595f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // In this case, we have a nested struct. We may not end up filling all 596f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // of the spaces in StmtArray (sub-structs should handle themselves 597f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // with separate compound statements). 598f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair FoundDecl = 599f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair::make(FD, clang::AS_none); 600f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr *RSObjectMember = 601f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr::Create(C, 602f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSStruct, 603f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines false, 604be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 605f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FD, 606f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FoundDecl, 607f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclarationNameInfo(), 608f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines NULL, 609be27482cdeaf08576bc39b72a15d35d13014a636Logan OrigType->getCanonicalTypeInternal(), 610be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 611be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary); 612f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 613f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (IsArrayType) { 614f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearArrayRSObject(C, 615f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 616f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 617f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 618f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 619f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearStructRSObject(C, 620f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 621f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 622f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 623f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 624f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 625f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 626f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 627f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(StmtCount > 0); 628f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::CompoundStmt *CS = 629f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::CompoundStmt(C, StmtArray, StmtCount, Loc, Loc); 630f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 631f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines delete [] StmtArray; 632f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 633f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return CS; 634f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines} 635f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 6362bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesstatic clang::Stmt *CreateSingleRSSetObject(clang::ASTContext &C, 6372bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Diagnostic *Diags, 6382bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *DstExpr, 6392bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *SrcExpr, 6402bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SourceLocation Loc) { 6412bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *T = DstExpr->getType().getTypePtr(); 6422bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::FunctionDecl *SetObjectFD = RSObjectRefCount::GetRSSetObjectFD(T); 6436e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((SetObjectFD != NULL) && 6446e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "rsSetObject doesn't cover all RS object types"); 645c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 646c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType SetObjectFDType = SetObjectFD->getType(); 647c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType SetObjectFDArgType[2]; 648c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDArgType[0] = SetObjectFD->getParamDecl(0)->getOriginalType(); 649c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDArgType[1] = SetObjectFD->getParamDecl(1)->getOriginalType(); 650c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 651c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Expr *RefRSSetObjectFD = 652c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::DeclRefExpr::Create(C, 653be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 654c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFD, 655c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines Loc, 656be27482cdeaf08576bc39b72a15d35d13014a636Logan SetObjectFDType, 657be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 658be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 659c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 660c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Expr *RSSetObjectFP = 661c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::ImplicitCastExpr::Create(C, 662c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines C.getPointerType(SetObjectFDType), 663c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::CK_FunctionToPointerDecay, 664c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RefRSSetObjectFD, 665c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines NULL, 666c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::VK_RValue); 667c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 668c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Expr *ArgList[2]; 6692bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines ArgList[0] = new(C) clang::UnaryOperator(DstExpr, 670c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::UO_AddrOf, 671c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDArgType[0], 672be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 673be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 674c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines Loc); 6752bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines ArgList[1] = SrcExpr; 676c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 677c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::CallExpr *RSSetObjectCall = 678c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines new(C) clang::CallExpr(C, 679c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RSSetObjectFP, 680c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines ArgList, 681c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 2, 682c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFD->getCallResultType(), 683be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 684c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines Loc); 685c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 6862bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return RSSetObjectCall; 6872bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines} 6882bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 6892bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesstatic clang::Stmt *CreateStructRSSetObject(clang::ASTContext &C, 6902bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Diagnostic *Diags, 6912bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *LHS, 6922bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *RHS, 6932bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SourceLocation Loc); 6942bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 6952bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesstatic clang::Stmt *CreateArrayRSSetObject(clang::ASTContext &C, 6962bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Diagnostic *Diags, 6972bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *DstArr, 6982bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *SrcArr, 6992bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SourceLocation Loc) { 7002bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclContext *DC = NULL; 7012bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *BaseType = DstArr->getType().getTypePtr(); 7022bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(BaseType->isArrayType()); 7032bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7042bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines int NumArrayElements = ArrayDim(BaseType); 7052bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Actually extract out the base RS object type for use later 7062bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines BaseType = BaseType->getArrayElementTypeNoTypeQual(); 7072bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7082bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Stmt *StmtArray[2] = {NULL}; 7092bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines int StmtCtr = 0; 7102bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7112bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (NumArrayElements <= 0) { 7122bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return NULL; 7132bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 7142bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7152bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Create helper variable for iterating through elements 7162bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::IdentifierInfo& II = C.Idents.get("rsIntIter"); 7172bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VarDecl *IIVD = 7182bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VarDecl::Create(C, 7192bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines DC, 7202bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 7212bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines &II, 7222bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 7232bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.getTrivialTypeSourceInfo(C.IntTy), 7242bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SC_None, 7252bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SC_None); 7262bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Decl *IID = (clang::Decl *)IIVD; 7272bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7282bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclGroupRef DGR = clang::DeclGroupRef::Create(C, &IID, 1); 7292bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCtr++] = new(C) clang::DeclStmt(DGR, Loc, Loc); 7302bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7312bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Form the actual loop 7322bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // for (Init; Cond; Inc) 7332bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // RSSetObjectCall; 7342bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7352bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Init -> "rsIntIter = 0" 7362bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclRefExpr *RefrsIntIter = 7372bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclRefExpr::Create(C, 738be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 7392bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines IIVD, 7402bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 741be27482cdeaf08576bc39b72a15d35d13014a636Logan C.IntTy, 742be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 743be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 7442bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7452bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, 7462bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), 0), C.IntTy, Loc); 7472bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7482bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BinaryOperator *Init = 7492bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 7502bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Int0, 7512bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BO_Assign, 7522bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 753be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 754be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 7552bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 7562bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7572bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Cond -> "rsIntIter < NumArrayElements" 7582bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *NumArrayElementsExpr = clang::IntegerLiteral::Create(C, 7592bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), NumArrayElements), C.IntTy, Loc); 7602bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7612bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BinaryOperator *Cond = 7622bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 7632bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NumArrayElementsExpr, 7642bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BO_LT, 7652bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 766be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 767be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 7682bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 7692bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7702bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Inc -> "rsIntIter++" 7712bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::UnaryOperator *Inc = 7722bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::UnaryOperator(RefrsIntIter, 7732bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::UO_PostInc, 7742bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 775be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 776be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 7772bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 7782bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7792bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Body -> "rsSetObject(&Dst[rsIntIter], Src[rsIntIter]);" 7802bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Loop operates on individual array elements 7812bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7822bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *DstArrPtr = 7832bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ImplicitCastExpr::Create(C, 7842bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.getPointerType(BaseType->getCanonicalTypeInternal()), 7852bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::CK_ArrayToPointerDecay, 7862bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines DstArr, 7872bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NULL, 7882bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VK_RValue); 7892bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7902bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *DstArrPtrSubscript = 7912bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::ArraySubscriptExpr(DstArrPtr, 7922bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RefrsIntIter, 7932bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines BaseType->getCanonicalTypeInternal(), 794be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 795be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 7962bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 7972bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7982bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *SrcArrPtr = 7992bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ImplicitCastExpr::Create(C, 8002bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.getPointerType(BaseType->getCanonicalTypeInternal()), 8012bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::CK_ArrayToPointerDecay, 8022bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines SrcArr, 8032bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NULL, 8042bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VK_RValue); 8052bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8062bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *SrcArrPtrSubscript = 8072bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::ArraySubscriptExpr(SrcArrPtr, 8082bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RefrsIntIter, 8092bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines BaseType->getCanonicalTypeInternal(), 810be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 811be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 8122bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 8132bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8142bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSExportPrimitiveType::DataType DT = 8152bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSExportPrimitiveType::GetRSSpecificType(BaseType); 8162bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8172bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Stmt *RSSetObjectCall = NULL; 8182bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (BaseType->isArrayType()) { 8192bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSSetObjectCall = CreateArrayRSSetObject(C, Diags, DstArrPtrSubscript, 8202bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines SrcArrPtrSubscript, Loc); 8212bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else if (DT == RSExportPrimitiveType::DataTypeUnknown) { 8222bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSSetObjectCall = CreateStructRSSetObject(C, Diags, DstArrPtrSubscript, 8232bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines SrcArrPtrSubscript, Loc); 8242bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else { 8252bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSSetObjectCall = CreateSingleRSSetObject(C, Diags, DstArrPtrSubscript, 8262bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines SrcArrPtrSubscript, Loc); 8272bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 8282bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8292bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ForStmt *DestructorLoop = 8302bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::ForStmt(C, 8312bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Init, 8322bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Cond, 8332bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NULL, // no condVar 8342bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Inc, 8352bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSSetObjectCall, 8362bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 8372bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 8382bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 8392bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8402bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCtr++] = DestructorLoop; 8412bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(StmtCtr == 2); 8422bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8432bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::CompoundStmt *CS = 8442bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::CompoundStmt(C, StmtArray, StmtCtr, Loc, Loc); 8452bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8462bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return CS; 8472bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines} 8482bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8492bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesstatic clang::Stmt *CreateStructRSSetObject(clang::ASTContext &C, 8502bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Diagnostic *Diags, 8512bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *LHS, 8522bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *RHS, 8532bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SourceLocation Loc) { 8542bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::QualType QT = LHS->getType(); 8552bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *T = QT.getTypePtr(); 8562bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(T->isStructureType()); 8572bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(!RSExportPrimitiveType::IsRSObjectType(T)); 8582bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8592bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Keep an extra slot for the original copy (memcpy) 8602bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines unsigned FieldsToSet = CountRSObjectTypes(T) + 1; 8612bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8622bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines unsigned StmtCount = 0; 8632bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Stmt **StmtArray = new clang::Stmt*[FieldsToSet]; 8642bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines for (unsigned i = 0; i < FieldsToSet; i++) { 8652bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[i] = NULL; 8662bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 8672bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8682bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::RecordDecl *RD = T->getAsStructureType()->getDecl(); 8692bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RD = RD->getDefinition(); 8702bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 8712bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FE = RD->field_end(); 8722bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FI != FE; 8732bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FI++) { 8742bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines bool IsArrayType = false; 8752bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::FieldDecl *FD = *FI; 8762bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 8772bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *OrigType = FT; 8782bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8792bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (!CountRSObjectTypes(FT)) { 8802bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Skip to next if we don't have any viable RS object types 8812bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines continue; 8822bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 8832bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8842bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclAccessPair FoundDecl = 8852bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclAccessPair::make(FD, clang::AS_none); 8862bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr *DstMember = 8872bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr::Create(C, 8882bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines LHS, 8892bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines false, 890be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 8912bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FD, 8922bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FoundDecl, 8932bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclarationNameInfo(), 8942bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NULL, 895be27482cdeaf08576bc39b72a15d35d13014a636Logan OrigType->getCanonicalTypeInternal(), 896be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 897be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary); 8982bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8992bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr *SrcMember = 9002bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr::Create(C, 9012bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RHS, 9022bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines false, 903be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 9042bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FD, 9052bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FoundDecl, 9062bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclarationNameInfo(), 9072bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NULL, 908be27482cdeaf08576bc39b72a15d35d13014a636Logan OrigType->getCanonicalTypeInternal(), 909be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 910be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary); 9112bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9122bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (FT->isArrayType()) { 9132bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 9142bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines IsArrayType = true; 9152bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 9162bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9172bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSExportPrimitiveType::DataType DT = 9182bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSExportPrimitiveType::GetRSSpecificType(FT); 9192bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9202bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (IsArrayType) { 921832429f6bf4592cfc2ce58f2462f1e8ecdbaaf52Stephen Hines Diags->Report(clang::FullSourceLoc(Loc, C.getSourceManager()), 922832429f6bf4592cfc2ce58f2462f1e8ecdbaaf52Stephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 923832429f6bf4592cfc2ce58f2462f1e8ecdbaaf52Stephen Hines "Arrays of RS object types within structures cannot be copied")); 9242bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // TODO(srhines): Support setting arrays of RS objects 9252bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // StmtArray[StmtCount++] = 9262bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // CreateArrayRSSetObject(C, Diags, DstMember, SrcMember, Loc); 9272bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else if (DT == RSExportPrimitiveType::DataTypeUnknown) { 9282bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCount++] = 9292bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines CreateStructRSSetObject(C, Diags, DstMember, SrcMember, Loc); 9302bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else if (RSExportPrimitiveType::IsRSObjectType(DT)) { 9312bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCount++] = 9322bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines CreateSingleRSSetObject(C, Diags, DstMember, SrcMember, Loc); 9332bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else { 9342bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(false); 9352bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 9362bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 9372bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9382bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(StmtCount > 0 && StmtCount < FieldsToSet); 9392bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9402bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // We still need to actually do the overall struct copy. For simplicity, 9412bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // we just do a straight-up assignment (which will still preserve all 9422bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // the proper RS object reference counts). 9432bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BinaryOperator *CopyStruct = 944be27482cdeaf08576bc39b72a15d35d13014a636Logan new(C) clang::BinaryOperator(LHS, RHS, clang::BO_Assign, QT, 945be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, clang::OK_Ordinary, Loc); 9462bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCount++] = CopyStruct; 9472bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9482bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::CompoundStmt *CS = 9492bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::CompoundStmt(C, StmtArray, StmtCount, Loc, Loc); 9502bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9512bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines delete [] StmtArray; 9522bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9532bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return CS; 9542bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines} 9552bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9562bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines} // namespace 9572bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9582bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesvoid RSObjectRefCount::Scope::ReplaceRSObjectAssignment( 9592bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BinaryOperator *AS, 9602bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Diagnostic *Diags) { 9612bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9622bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::QualType QT = AS->getType(); 9632bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9642bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ASTContext &C = RSObjectRefCount::GetRSSetObjectFD( 9652bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSExportPrimitiveType::DataTypeRSFont)->getASTContext(); 9662bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 967832429f6bf4592cfc2ce58f2462f1e8ecdbaaf52Stephen Hines clang::SourceLocation Loc = AS->getExprLoc(); 9682bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Stmt *UpdatedStmt = NULL; 9692bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9702bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (!RSExportPrimitiveType::IsRSObjectType(QT.getTypePtr())) { 9712bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // By definition, this is a struct assignment if we get here 9722bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines UpdatedStmt = 9732bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines CreateStructRSSetObject(C, Diags, AS->getLHS(), AS->getRHS(), Loc); 9742bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else { 9752bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines UpdatedStmt = 9762bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines CreateSingleRSSetObject(C, Diags, AS->getLHS(), AS->getRHS(), Loc); 9772bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 978e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 9792bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines ReplaceInCompoundStmt(C, mCS, AS, UpdatedStmt); 980e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return; 981e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines} 982e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 983e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hinesvoid RSObjectRefCount::Scope::AppendRSObjectInit( 984a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::Diagnostic *Diags, 985e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::VarDecl *VD, 986e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclStmt *DS, 987e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataType DT, 988e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *InitExpr) { 9896e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(VD); 990e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 991e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (!InitExpr) { 992e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return; 993e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 994e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 995a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::ASTContext &C = RSObjectRefCount::GetRSSetObjectFD( 996a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines RSExportPrimitiveType::DataTypeRSFont)->getASTContext(); 997a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::SourceLocation Loc = RSObjectRefCount::GetRSSetObjectFD( 998a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines RSExportPrimitiveType::DataTypeRSFont)->getLocation(); 999a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines 1000f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (DT == RSExportPrimitiveType::DataTypeIsStruct) { 1001f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // TODO(srhines): Skip struct initialization right now 1002a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 1003a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::DeclRefExpr *RefRSVar = 1004a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::DeclRefExpr::Create(C, 1005be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 1006a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines VD, 1007a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines Loc, 1008be27482cdeaf08576bc39b72a15d35d13014a636Logan T->getCanonicalTypeInternal(), 1009be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1010be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 1011a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines 1012a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::Stmt *RSSetObjectOps = 1013a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines CreateStructRSSetObject(C, Diags, RefRSVar, InitExpr, Loc); 1014a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines 1015a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines AppendAfterStmt(C, mCS, DS, RSSetObjectOps); 1016f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return; 1017f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 1018f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 1019f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::FunctionDecl *SetObjectFD = RSObjectRefCount::GetRSSetObjectFD(DT); 10206e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((SetObjectFD != NULL) && 10216e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "rsSetObject doesn't cover all RS object types"); 1022e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1023e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::QualType SetObjectFDType = SetObjectFD->getType(); 1024e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::QualType SetObjectFDArgType[2]; 1025e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDArgType[0] = SetObjectFD->getParamDecl(0)->getOriginalType(); 1026e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDArgType[1] = SetObjectFD->getParamDecl(1)->getOriginalType(); 1027e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1028e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *RefRSSetObjectFD = 1029e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr::Create(C, 1030be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 1031e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFD, 1032e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc, 1033be27482cdeaf08576bc39b72a15d35d13014a636Logan SetObjectFDType, 1034be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1035be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 1036e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1037e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *RSSetObjectFP = 1038e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::ImplicitCastExpr::Create(C, 1039e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines C.getPointerType(SetObjectFDType), 1040e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CK_FunctionToPointerDecay, 1041e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RefRSSetObjectFD, 1042e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines NULL, 1043e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::VK_RValue); 1044e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1045e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 1046e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr *RefRSVar = 1047e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr::Create(C, 1048be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 1049e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD, 1050e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc, 1051be27482cdeaf08576bc39b72a15d35d13014a636Logan T->getCanonicalTypeInternal(), 1052be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1053be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 1054e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1055e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *ArgList[2]; 1056e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ArgList[0] = new(C) clang::UnaryOperator(RefRSVar, 1057e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::UO_AddrOf, 1058e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDArgType[0], 1059be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1060be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 1061e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc); 1062e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ArgList[1] = InitExpr; 1063e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1064e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CallExpr *RSSetObjectCall = 1065e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines new(C) clang::CallExpr(C, 1066e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSSetObjectFP, 1067e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ArgList, 1068e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 2, 1069e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFD->getCallResultType(), 1070be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1071e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc); 1072e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1073e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines AppendAfterStmt(C, mCS, DS, RSSetObjectCall); 1074c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 1075c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines return; 1076c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines} 1077c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 10781bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hinesvoid RSObjectRefCount::Scope::InsertLocalVarDestructors() { 1079d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines std::list<clang::Stmt*> RSClearObjectCalls; 10801bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines for (std::list<clang::VarDecl*>::const_iterator I = mRSO.begin(), 10811bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines E = mRSO.end(); 10821bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines I != E; 10831bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines I++) { 1084a858cb6f3d9223d65bf73e1230c6324ded4095f6Stephen Hines clang::Stmt *S = ClearRSObject(*I); 1085a858cb6f3d9223d65bf73e1230c6324ded4095f6Stephen Hines if (S) { 1086a858cb6f3d9223d65bf73e1230c6324ded4095f6Stephen Hines RSClearObjectCalls.push_back(S); 10871bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 10881bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 10891bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if (RSClearObjectCalls.size() > 0) { 10904464d825c11349068f2917f9ebee86b721423f3cStephen Hines DestructorVisitor DV((*mRSO.begin())->getASTContext(), RSClearObjectCalls); 10914464d825c11349068f2917f9ebee86b721423f3cStephen Hines DV.Visit(mCS); 10921bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 10931bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines return; 10941bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 10951bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1096d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hinesclang::Stmt *RSObjectRefCount::Scope::ClearRSObject(clang::VarDecl *VD) { 1097f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(VD); 10981bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::ASTContext &C = VD->getASTContext(); 1099f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC = VD->getDeclContext(); 11001bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::SourceLocation Loc = VD->getLocation(); 11011bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 110203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 11031bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Reference expr to target RS object variable 11041bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::DeclRefExpr *RefRSVar = 11051bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::DeclRefExpr::Create(C, 1106be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 11071bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines VD, 11081bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines Loc, 1109be27482cdeaf08576bc39b72a15d35d13014a636Logan T->getCanonicalTypeInternal(), 1110be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1111be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 11121bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1113f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (T->isArrayType()) { 1114be27482cdeaf08576bc39b72a15d35d13014a636Logan return ClearArrayRSObject(C, DC, RefRSVar, Loc); 1115f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 11161bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1117f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::DataType DT = 1118f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::GetRSSpecificType(T); 11191bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1120f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (DT == RSExportPrimitiveType::DataTypeUnknown || 1121f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DT == RSExportPrimitiveType::DataTypeIsStruct) { 1122be27482cdeaf08576bc39b72a15d35d13014a636Logan return ClearStructRSObject(C, DC, RefRSVar, Loc); 1123f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 11241bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1125f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert((RSExportPrimitiveType::IsRSObjectType(DT)) && 1126f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "Should be RS object"); 11271bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1128f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return ClearSingleRSObject(C, RefRSVar, Loc); 11291bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 11301bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1131e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hinesbool RSObjectRefCount::InitializeRSObject(clang::VarDecl *VD, 1132e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataType *DT, 1133e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr **InitExpr) { 11346e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(VD && DT && InitExpr); 11354b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 11362d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines 11372d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines // Loop through array types to get to base type 11382d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines while (T && T->isArrayType()) { 11392d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines T = T->getArrayElementTypeNoTypeQual(); 11402d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines } 11412d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines 1142f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool DataTypeIsStructWithRSObject = false; 1143e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines *DT = RSExportPrimitiveType::GetRSSpecificType(T); 11444b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1145e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (*DT == RSExportPrimitiveType::DataTypeUnknown) { 1146feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (RSExportPrimitiveType::IsStructureTypeWithRSObject(T)) { 1147feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines *DT = RSExportPrimitiveType::DataTypeIsStruct; 1148f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DataTypeIsStructWithRSObject = true; 1149feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } else { 1150feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines return false; 1151feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 11522d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines } 11534b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1154f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool DataTypeIsRSObject = false; 1155f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (DataTypeIsStructWithRSObject) { 1156f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DataTypeIsRSObject = true; 1157f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 1158f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DataTypeIsRSObject = RSExportPrimitiveType::IsRSObjectType(*DT); 1159f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 1160e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines *InitExpr = VD->getInit(); 1161e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1162e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (!DataTypeIsRSObject && *InitExpr) { 1163e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines // If we already have an initializer for a matrix type, we are done. 1164e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return DataTypeIsRSObject; 11654b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 11664b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1167e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *ZeroInitializer = 1168e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines CreateZeroInitializerForRSSpecificType(*DT, 1169e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->getASTContext(), 1170e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->getLocation()); 1171e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1172e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (ZeroInitializer) { 1173e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ZeroInitializer->setType(T->getCanonicalTypeInternal()); 1174e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->setInit(ZeroInitializer); 1175e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 1176e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1177e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return DataTypeIsRSObject; 11784b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 11794b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 11804b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesclang::Expr *RSObjectRefCount::CreateZeroInitializerForRSSpecificType( 11814b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines RSExportPrimitiveType::DataType DT, 11824b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ASTContext &C, 11834b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines const clang::SourceLocation &Loc) { 11844b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *Res = NULL; 11854b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines switch (DT) { 1186feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines case RSExportPrimitiveType::DataTypeIsStruct: 11874b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSElement: 11884b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSType: 11894b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSAllocation: 11904b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSSampler: 11914b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSScript: 11924b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMesh: 11934b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramFragment: 11944b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramVertex: 11954b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramRaster: 11964b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramStore: 11974b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSFont: { 11984b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (ImplicitCastExpr 'nullptr_t' 11994b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (IntegerLiteral 0))) 12004b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APInt Zero(C.getTypeSize(C.IntTy), 0); 12014b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, Zero, C.IntTy, Loc); 12024b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *CastToNull = 12034b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ImplicitCastExpr::Create(C, 12044b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines C.NullPtrTy, 12054b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::CK_IntegralToPointer, 12064b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Int0, 12074b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines NULL, 12084b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::VK_RValue); 12094b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1210e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Res = new(C) clang::InitListExpr(C, Loc, &CastToNull, 1, Loc); 12114b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines break; 12124b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 12134b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMatrix2x2: 12144b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMatrix3x3: 12154b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMatrix4x4: { 12164b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // RS matrix is not completely an RS object. They hold data by themselves. 12174b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (InitListExpr rs_matrix2x2 12184b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (InitListExpr float[4] 12194b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 12204b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 12214b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 12224b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0))) 12234b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::QualType FloatTy = C.FloatTy; 12244b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Constructor sets value to 0.0f by default 12254b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APFloat Val(C.getFloatTypeSemantics(FloatTy)); 12264b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::FloatingLiteral *Float0Val = 12274b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::FloatingLiteral::Create(C, 12284b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Val, 12294b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines /* isExact = */true, 12304b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines FloatTy, 12314b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Loc); 12324b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 12334b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines unsigned N = 0; 12344b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (DT == RSExportPrimitiveType::DataTypeRSMatrix2x2) 12354b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 2; 12364b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines else if (DT == RSExportPrimitiveType::DataTypeRSMatrix3x3) 12374b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 3; 12384b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines else if (DT == RSExportPrimitiveType::DataTypeRSMatrix4x4) 12394b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 4; 12404b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 12414b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Directly allocate 16 elements instead of dynamically allocate N*N 12424b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *InitVals[16]; 12434b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (unsigned i = 0; i < sizeof(InitVals) / sizeof(InitVals[0]); i++) 12444b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines InitVals[i] = Float0Val; 12454b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *InitExpr = 1246e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines new(C) clang::InitListExpr(C, Loc, InitVals, N * N, Loc); 12474b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines InitExpr->setType(C.getConstantArrayType(FloatTy, 12484b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APInt(32, 4), 12494b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ArrayType::Normal, 12504b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines /* EltTypeQuals = */0)); 12514b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1252e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Res = new(C) clang::InitListExpr(C, Loc, &InitExpr, 1, Loc); 12534b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines break; 12544b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 12554b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnknown: 12564b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeFloat16: 12574b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeFloat32: 12584b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeFloat64: 12594b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned8: 12604b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned16: 12614b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned32: 12624b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned64: 12634b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned8: 12644b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned16: 12654b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned32: 12664b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned64: 12674b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeBoolean: 12684b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned565: 12694b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned5551: 12704b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned4444: 12714b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeMax: { 12726e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Not RS object type!"); 12734b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 12744b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // No default case will enable compiler detecting the missing cases 12754b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 12764b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 12774b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return Res; 12784b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 12794b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 12804b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitDeclStmt(clang::DeclStmt *DS) { 12814b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (clang::DeclStmt::decl_iterator I = DS->decl_begin(), E = DS->decl_end(); 12824b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I != E; 12834b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I++) { 12844b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Decl *D = *I; 12854b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (D->getKind() == clang::Decl::Var) { 12864b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::VarDecl *VD = static_cast<clang::VarDecl*>(D); 1287e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataType DT = 1288e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataTypeUnknown; 1289e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *InitExpr = NULL; 1290e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (InitializeRSObject(VD, &DT, &InitExpr)) { 12914b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines getCurrentScope()->addRSObject(VD); 1292a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines getCurrentScope()->AppendRSObjectInit(mDiags, VD, DS, DT, InitExpr); 1293e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 12944b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 12954b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 12964b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 12974b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 12984b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 12994b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitCompoundStmt(clang::CompoundStmt *CS) { 13004b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (!CS->body_empty()) { 13014b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Push a new scope 13024b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Scope *S = new Scope(CS); 13034b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines mScopeStack.push(S); 13044b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 13054b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines VisitStmt(CS); 13064b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 13074b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Destroy the scope 13086e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((getCurrentScope() == S) && "Corrupted scope stack!"); 13091bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines S->InsertLocalVarDestructors(); 13104b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines mScopeStack.pop(); 13114b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines delete S; 13124b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 13134b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 13144b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 13154b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 13164b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitBinAssign(clang::BinaryOperator *AS) { 1317c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType QT = AS->getType(); 1318c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 13192bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (CountRSObjectTypes(QT.getTypePtr())) { 13202bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines getCurrentScope()->ReplaceRSObjectAssignment(AS, mDiags); 1321c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 1322c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 13234b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 13244b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 13254b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 13264b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitStmt(clang::Stmt *S) { 13274b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end(); 13284b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I != E; 13294b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I++) { 13304b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (clang::Stmt *Child = *I) { 13314b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Visit(Child); 13324b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 13334b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 13344b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 13354b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 13364b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1337e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 1338