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 194b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "clang/AST/DeclGroup.h" 204b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "clang/AST/Expr.h" 21be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "clang/AST/NestedNameSpecifier.h" 224b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "clang/AST/OperationKinds.h" 23f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni#include "clang/AST/RecursiveASTVisitor.h" 244b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "clang/AST/Stmt.h" 254b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "clang/AST/StmtVisitor.h" 264b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 276e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h" 288024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang.h" 29292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines#include "slang_rs_ast_replace.h" 304b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "slang_rs_export_type.h" 314b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 32e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang { 334b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 34474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet/* Even though those two arrays are of size DataTypeMax, only entries that 35474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet * correspond to object types will be set. 36474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet */ 37474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouilletclang::FunctionDecl * 38cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc BrouilletRSObjectRefCount::RSSetObjectFD[DataTypeMax]; 39474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouilletclang::FunctionDecl * 40cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc BrouilletRSObjectRefCount::RSClearObjectFD[DataTypeMax]; 411bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 42f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesvoid RSObjectRefCount::GetRSRefCountingFunctions(clang::ASTContext &C) { 43cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet for (unsigned i = 0; i < DataTypeMax; i++) { 445abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes RSSetObjectFD[i] = nullptr; 455abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes RSClearObjectFD[i] = nullptr; 461bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 471bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 481bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl(); 491bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 501bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(), 511bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines E = TUDecl->decls_end(); I != E; I++) { 521bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if ((I->getKind() >= clang::Decl::firstFunction) && 531bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines (I->getKind() <= clang::Decl::lastFunction)) { 541bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::FunctionDecl *FD = static_cast<clang::FunctionDecl*>(*I); 551bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 561bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // points to RSSetObjectFD or RSClearObjectFD 571bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::FunctionDecl **RSObjectFD; 581bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 591bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if (FD->getName() == "rsSetObject") { 606e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((FD->getNumParams() == 2) && 616e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "Invalid rsSetObject function prototype (# params)"); 621bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSObjectFD = RSSetObjectFD; 631bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } else if (FD->getName() == "rsClearObject") { 646e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((FD->getNumParams() == 1) && 656e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "Invalid rsClearObject function prototype (# params)"); 661bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSObjectFD = RSClearObjectFD; 67e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines } else { 681bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines continue; 691bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 701bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 711bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines const clang::ParmVarDecl *PVD = FD->getParamDecl(0); 721bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::QualType PVT = PVD->getOriginalType(); 731bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // The first parameter must be a pointer like rs_allocation* 746e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(PVT->isPointerType() && 756e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "Invalid rs{Set,Clear}Object function prototype (pointer param)"); 761bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 771bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // The rs object type passed to the FD 781bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::QualType RST = PVT->getPointeeType(); 79cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT = RSExportPrimitiveType::GetRSSpecificType(RST.getTypePtr()); 806e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(RSExportPrimitiveType::IsRSObjectType(DT) 811bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines && "must be RS object type"); 821bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 83cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet if (DT >= 0 && DT < DataTypeMax) { 84474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet RSObjectFD[DT] = FD; 85474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet } else { 86474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet slangAssert(false && "incorrect type"); 87474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet } 881bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 891bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 901bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 911bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 924464d825c11349068f2917f9ebee86b721423f3cStephen Hinesnamespace { 934464d825c11349068f2917f9ebee86b721423f3cStephen Hines 94b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Niunsigned CountRSObjectTypes(const clang::Type *T); 95b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 96b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Niclang::Stmt *CreateSingleRSSetObject(clang::ASTContext &C, 97b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Expr *DstExpr, 98b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Expr *SrcExpr, 99b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::SourceLocation StartLoc, 100b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::SourceLocation Loc); 101b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 102292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines// This function constructs a new CompoundStmt from the input StmtList. 103b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Niclang::CompoundStmt* BuildCompoundStmt(clang::ASTContext &C, 104579e4f481774275980d6e3fbb7978c674da6d302Yang Ni std::vector<clang::Stmt*> &StmtList, clang::SourceLocation Loc) { 105d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines unsigned NewStmtCount = StmtList.size(); 106292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines unsigned CompoundStmtCount = 0; 1071bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 108292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines clang::Stmt **CompoundStmtList; 109292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines CompoundStmtList = new clang::Stmt*[NewStmtCount]; 1101bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 111579e4f481774275980d6e3fbb7978c674da6d302Yang Ni std::vector<clang::Stmt*>::const_iterator I = StmtList.begin(); 112579e4f481774275980d6e3fbb7978c674da6d302Yang Ni std::vector<clang::Stmt*>::const_iterator E = StmtList.end(); 113292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines for ( ; I != E; I++) { 114292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines CompoundStmtList[CompoundStmtCount++] = *I; 1151bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 116292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines slangAssert(CompoundStmtCount == NewStmtCount); 1171bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 11823c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines clang::CompoundStmt *CS = new(C) clang::CompoundStmt( 11923c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines C, llvm::makeArrayRef(CompoundStmtList, CompoundStmtCount), Loc, Loc); 1201bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 121292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines delete [] CompoundStmtList; 1221bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 123292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return CS; 1241bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 1251bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 126b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Nivoid AppendAfterStmt(clang::ASTContext &C, 127b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::CompoundStmt *CS, 128b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Stmt *S, 129b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni std::list<clang::Stmt*> &StmtList) { 130292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines slangAssert(CS); 131e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CompoundStmt::body_iterator bI = CS->body_begin(); 132292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines clang::CompoundStmt::body_iterator bE = CS->body_end(); 133292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines clang::Stmt **UpdatedStmtList = 134292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines new clang::Stmt*[CS->size() + StmtList.size()]; 135e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 136e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines unsigned UpdatedStmtCount = 0; 137e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines unsigned Once = 0; 138292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines for ( ; bI != bE; bI++) { 139292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if (!S && ((*bI)->getStmtClass() == clang::Stmt::ReturnStmtClass)) { 140292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // If we come across a return here, we don't have anything we can 141292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // reasonably replace. We should have already inserted our destructor 142292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // code in the proper spot, so we just clean up and return. 143292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines delete [] UpdatedStmtList; 144292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 145292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return; 146e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 147e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 148292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines UpdatedStmtList[UpdatedStmtCount++] = *bI; 149c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 150292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if ((*bI == S) && !Once) { 151292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines Once++; 152292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*>::const_iterator I = StmtList.begin(); 153292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*>::const_iterator E = StmtList.end(); 154292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines for ( ; I != E; I++) { 155292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines UpdatedStmtList[UpdatedStmtCount++] = *I; 156292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 157292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 158c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 159292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines slangAssert(Once <= 1); 160c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 1615abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes // When S is nullptr, we are appending to the end of the CompoundStmt. 162292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if (!S) { 163292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines slangAssert(Once == 0); 164292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*>::const_iterator I = StmtList.begin(); 165292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*>::const_iterator E = StmtList.end(); 166292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines for ( ; I != E; I++) { 167292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines UpdatedStmtList[UpdatedStmtCount++] = *I; 168c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 169c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 170c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 17198cfae456bb1831336bce2b21979a04e2e31fed4Pirama Arumuga Nainar CS->setStmts(C, llvm::makeArrayRef(UpdatedStmtList, UpdatedStmtCount)); 172c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 173c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines delete [] UpdatedStmtList; 174c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines} 175c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 176b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni// This class visits a compound statement and collects a list of all the exiting 177b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni// statements, such as any return statement in any sub-block, and any 178b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni// break/continue statement that would resume outside the current scope. 179b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni// We do not handle the case for goto statements that leave a local scope. 1804464d825c11349068f2917f9ebee86b721423f3cStephen Hinesclass DestructorVisitor : public clang::StmtVisitor<DestructorVisitor> { 1814464d825c11349068f2917f9ebee86b721423f3cStephen Hines private: 182292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // The loop depth of the currently visited node. 183292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines int mLoopDepth; 184292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 185292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // The switch statement depth of the currently visited node. 186292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // Note that this is tracked separately from the loop depth because 187292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // SwitchStmt-contained ContinueStmt's should have destructors for the 188292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // corresponding loop scope. 189292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines int mSwitchDepth; 190292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 191b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // Output of the visitor: the statements that should be replaced by compound 192b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // statements, each of which contains rsClearObject() calls followed by the 193b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // original statement. 194b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni std::vector<clang::Stmt*> mExitingStmts; 195a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines 1964464d825c11349068f2917f9ebee86b721423f3cStephen Hines public: 197b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni DestructorVisitor() : mLoopDepth(0), mSwitchDepth(0) {} 198292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 199b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni const std::vector<clang::Stmt*>& getExitingStmts() const { 200b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni return mExitingStmts; 201292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 202292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 2034464d825c11349068f2917f9ebee86b721423f3cStephen Hines void VisitStmt(clang::Stmt *S); 204292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitBreakStmt(clang::BreakStmt *BS); 205292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitContinueStmt(clang::ContinueStmt *CS); 206292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitDoStmt(clang::DoStmt *DS); 207292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitForStmt(clang::ForStmt *FS); 208292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitReturnStmt(clang::ReturnStmt *RS); 209292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitSwitchStmt(clang::SwitchStmt *SS); 210292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitWhileStmt(clang::WhileStmt *WS); 2114464d825c11349068f2917f9ebee86b721423f3cStephen Hines}; 2124464d825c11349068f2917f9ebee86b721423f3cStephen Hines 2134464d825c11349068f2917f9ebee86b721423f3cStephen Hinesvoid DestructorVisitor::VisitStmt(clang::Stmt *S) { 21456916bec2734a6059e1d0f58959514c825c746f7Yang Ni for (clang::Stmt* Child : S->children()) { 21556916bec2734a6059e1d0f58959514c825c746f7Yang Ni if (Child) { 2164464d825c11349068f2917f9ebee86b721423f3cStephen Hines Visit(Child); 2174464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 2184464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 2194464d825c11349068f2917f9ebee86b721423f3cStephen Hines} 2204464d825c11349068f2917f9ebee86b721423f3cStephen Hines 221292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitBreakStmt(clang::BreakStmt *BS) { 222292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(BS); 223292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if ((mLoopDepth == 0) && (mSwitchDepth == 0)) { 224b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni mExitingStmts.push_back(BS); 225292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 226292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 227292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 228292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitContinueStmt(clang::ContinueStmt *CS) { 229292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(CS); 230292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if (mLoopDepth == 0) { 231292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // Switch statements can have nested continues. 232b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni mExitingStmts.push_back(CS); 233292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 234292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 235292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 236292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitDoStmt(clang::DoStmt *DS) { 237292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth++; 238292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(DS); 239292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth--; 240292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 241292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 242292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitForStmt(clang::ForStmt *FS) { 243292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth++; 244292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(FS); 245292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth--; 246292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 247292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 248292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitReturnStmt(clang::ReturnStmt *RS) { 249b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni mExitingStmts.push_back(RS); 250292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 251292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 252292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitSwitchStmt(clang::SwitchStmt *SS) { 253292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mSwitchDepth++; 254292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(SS); 255292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mSwitchDepth--; 256292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 257292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 258292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitWhileStmt(clang::WhileStmt *WS) { 259292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth++; 260292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(WS); 261292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth--; 262292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 263292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 264f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesclang::Expr *ClearSingleRSObject(clang::ASTContext &C, 265f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSVar, 266f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc) { 267f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(RefRSVar); 268f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *T = RefRSVar->getType().getTypePtr(); 269f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(!T->isArrayType() && 270f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "Should not be destroying arrays with this function"); 271f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 272f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::FunctionDecl *ClearObjectFD = RSObjectRefCount::GetRSClearObjectFD(T); 2735abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes slangAssert((ClearObjectFD != nullptr) && 274f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "rsClearObject doesn't cover all RS object types"); 275f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 276f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::QualType ClearObjectFDType = ClearObjectFD->getType(); 277f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::QualType ClearObjectFDArgType = 278f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD->getParamDecl(0)->getOriginalType(); 279f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 280f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Example destructor for "rs_font localFont;" 281f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // 282f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (CallExpr 'void' 283f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (ImplicitCastExpr 'void (*)(rs_font *)' <FunctionToPointerDecay> 284f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (DeclRefExpr 'void (rs_font *)' FunctionDecl='rsClearObject')) 285f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (UnaryOperator 'rs_font *' prefix '&' 286f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (DeclRefExpr 'rs_font':'rs_font' Var='localFont'))) 287f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 288f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Get address of targeted RS object 289f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *AddrRefRSVar = 290f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::UnaryOperator(RefRSVar, 291f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::UO_AddrOf, 292f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFDArgType, 293be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 294be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 295f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 296f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 297f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSClearObjectFD = 298f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclRefExpr::Create(C, 299be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 3000444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 301f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD, 302e2597ac5a8ba7a45a1d5f342973cd43a3a1932cfShih-wei Liao false, 303f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD->getLocation(), 304be27482cdeaf08576bc39b72a15d35d13014a636Logan ClearObjectFDType, 305be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 3065abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr); 307f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 308f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RSClearObjectFP = 309f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ImplicitCastExpr::Create(C, 310f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines C.getPointerType(ClearObjectFDType), 311f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::CK_FunctionToPointerDecay, 312f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSClearObjectFD, 3135abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 314f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::VK_RValue); 31503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 3161dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines llvm::SmallVector<clang::Expr*, 1> ArgList; 3171dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines ArgList.push_back(AddrRefRSVar); 3181dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines 319f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::CallExpr *RSClearObjectCall = 320f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::CallExpr(C, 321f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectFP, 3221dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines ArgList, 323f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD->getCallResultType(), 324be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 325f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 326f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 327f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return RSClearObjectCall; 328f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines} 329f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 330f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic int ArrayDim(const clang::Type *T) { 33103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (!T || !T->isArrayType()) { 33203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return 0; 33303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 33403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 33503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines const clang::ConstantArrayType *CAT = 33603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines static_cast<const clang::ConstantArrayType *>(T); 3379d2c0fa6490e09b3ff5603796bce42d97788e5c8Stephen Hines return static_cast<int>(CAT->getSize().getSExtValue()); 33803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines} 33903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 340b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Niclang::Stmt *ClearStructRSObject( 341f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ASTContext &C, 342f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC, 343f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSStruct, 344d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines clang::SourceLocation StartLoc, 345f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc); 346f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 347b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Niclang::Stmt *ClearArrayRSObject( 348f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ASTContext &C, 349f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC, 350f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSArr, 351cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc, 352f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc) { 353f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *BaseType = RefRSArr->getType().getTypePtr(); 354f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(BaseType->isArrayType()); 355f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 356f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines int NumArrayElements = ArrayDim(BaseType); 357f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Actually extract out the base RS object type for use later 358f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines BaseType = BaseType->getArrayElementTypeNoTypeQual(); 35903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 36003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (NumArrayElements <= 0) { 3615abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 36203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 36303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 36403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Example destructor loop for "rs_font fontArr[10];" 36503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // 366cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (ForStmt 367cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (DeclStmt 368cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (VarDecl used rsIntIter 'int' cinit 369cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (IntegerLiteral 'int' 0))) 370cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (BinaryOperator 'int' '<' 371cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (ImplicitCastExpr int LValueToRValue 37203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter')) 373cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (IntegerLiteral 'int' 10) 374cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // nullptr << CondVar >> 375cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (UnaryOperator 'int' postfix '++' 376cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (DeclRefExpr 'int' Var='rsIntIter')) 377cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (CallExpr 'void' 378cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (ImplicitCastExpr 'void (*)(rs_font *)' <FunctionToPointerDecay> 379cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (DeclRefExpr 'void (rs_font *)' FunctionDecl='rsClearObject')) 380cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (UnaryOperator 'rs_font *' prefix '&' 381cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (ArraySubscriptExpr 'rs_font':'rs_font' 382cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (ImplicitCastExpr 'rs_font *' <ArrayToPointerDecay> 383cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (DeclRefExpr 'rs_font [10]' Var='fontArr')) 384cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (DeclRefExpr 'int' Var='rsIntIter')))))) 38503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 38603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Create helper variable for iterating through elements 387cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines static unsigned sIterCounter = 0; 388cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines std::stringstream UniqueIterName; 389cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines UniqueIterName << "rsIntIter" << sIterCounter++; 390cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::IdentifierInfo *II = &C.Idents.get(UniqueIterName.str()); 39103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VarDecl *IIVD = 39203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VarDecl::Create(C, 393f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 394cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, 39503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 396cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines II, 39703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 39803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.getTrivialTypeSourceInfo(C.IntTy), 39903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::SC_None); 400cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar // Mark "rsIntIter" as used 401cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar IIVD->markUsed(C); 40203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 40303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Form the actual destructor loop 40403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // for (Init; Cond; Inc) 40503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // RSClearObjectCall; 40603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 407cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // Init -> "int rsIntIter = 0" 408cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, 409cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines llvm::APInt(C.getTypeSize(C.IntTy), 0), C.IntTy, Loc); 410cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines IIVD->setInit(Int0); 411cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines 412cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::Decl *IID = (clang::Decl *)IIVD; 413cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::DeclGroupRef DGR = clang::DeclGroupRef::Create(C, &IID, 1); 414cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::Stmt *Init = new(C) clang::DeclStmt(DGR, Loc, Loc); 415cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines 416cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // Cond -> "rsIntIter < NumArrayElements" 417cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::DeclRefExpr *RefrsIntIterLValue = 41803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclRefExpr::Create(C, 419be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 4200444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 42103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines IIVD, 422e2597ac5a8ba7a45a1d5f342973cd43a3a1932cfShih-wei Liao false, 42303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 424be27482cdeaf08576bc39b72a15d35d13014a636Logan C.IntTy, 425cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::VK_LValue, 4265abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr); 42703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 428cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::Expr *RefrsIntIterRValue = 429cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::ImplicitCastExpr::Create(C, 430cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines RefrsIntIterLValue->getType(), 431cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::CK_LValueToRValue, 432cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines RefrsIntIterLValue, 433cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines nullptr, 434cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::VK_RValue); 43503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 43603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *NumArrayElementsExpr = clang::IntegerLiteral::Create(C, 43703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), NumArrayElements), C.IntTy, Loc); 43803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 43903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BinaryOperator *Cond = 440cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines new(C) clang::BinaryOperator(RefrsIntIterRValue, 44103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NumArrayElementsExpr, 44203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BO_LT, 44303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 444be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 445be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 44623c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines Loc, 44723c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines false); 44803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 44903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Inc -> "rsIntIter++" 45003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::UnaryOperator *Inc = 451cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines new(C) clang::UnaryOperator(RefrsIntIterLValue, 45203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::UO_PostInc, 45303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 454be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 455be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 45603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 45703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 45803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Body -> "rsClearObject(&VD[rsIntIter]);" 45903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Destructor loop operates on individual array elements 46003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 461f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSArrPtr = 46203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::ImplicitCastExpr::Create(C, 463f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines C.getPointerType(BaseType->getCanonicalTypeInternal()), 46403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::CK_ArrayToPointerDecay, 465f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSArr, 4665abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 46703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VK_RValue); 46803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 469f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSArrPtrSubscript = 470f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::ArraySubscriptExpr(RefRSArrPtr, 471cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines RefrsIntIterRValue, 472f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines BaseType->getCanonicalTypeInternal(), 473be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 474be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 475f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 47603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 477cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT = RSExportPrimitiveType::GetRSSpecificType(BaseType); 478f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 4795abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes clang::Stmt *RSClearObjectCall = nullptr; 480f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (BaseType->isArrayType()) { 481f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectCall = 482cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao ClearArrayRSObject(C, DC, RefRSArrPtrSubscript, StartLoc, Loc); 483cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet } else if (DT == DataTypeUnknown) { 484f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectCall = 485cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao ClearStructRSObject(C, DC, RefRSArrPtrSubscript, StartLoc, Loc); 486f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 487f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectCall = ClearSingleRSObject(C, RefRSArrPtrSubscript, Loc); 488f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 48903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 49003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::ForStmt *DestructorLoop = 49103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::ForStmt(C, 49203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Init, 49303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Cond, 4945abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, // no condVar 49503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Inc, 49603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines RSClearObjectCall, 49703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 49803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 49903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 50003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 501cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines return DestructorLoop; 50203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines} 50303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 504b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Niunsigned CountRSObjectTypes(const clang::Type *T) { 505f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(T); 506f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines unsigned RSObjectCount = 0; 507f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 508f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (T->isArrayType()) { 50965f23ed862e1a1e16477ba740f295ff4a83ac822David Gross return CountRSObjectTypes(T->getArrayElementTypeNoTypeQual()); 510f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 511f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 512cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT = RSExportPrimitiveType::GetRSSpecificType(T); 513cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet if (DT != DataTypeUnknown) { 514f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return (RSExportPrimitiveType::IsRSObjectType(DT) ? 1 : 0); 515f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 516f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 517d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines if (T->isUnionType()) { 518d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines clang::RecordDecl *RD = T->getAsUnionType()->getDecl(); 519d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines RD = RD->getDefinition(); 520d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 521d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines FE = RD->field_end(); 522d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines FI != FE; 523d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines FI++) { 524d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines const clang::FieldDecl *FD = *FI; 525d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 52665f23ed862e1a1e16477ba740f295ff4a83ac822David Gross if (CountRSObjectTypes(FT)) { 52778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines slangAssert(false && "can't have unions with RS object types!"); 528d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines return 0; 529d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines } 530d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines } 531d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines } 532d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines 533f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (!T->isStructureType()) { 534f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return 0; 535f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 536f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 537f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::RecordDecl *RD = T->getAsStructureType()->getDecl(); 538f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RD = RD->getDefinition(); 539f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 540f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FE = RD->field_end(); 541f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI != FE; 542f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI++) { 543f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::FieldDecl *FD = *FI; 544f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 54565f23ed862e1a1e16477ba740f295ff4a83ac822David Gross if (CountRSObjectTypes(FT)) { 546f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Sub-structs should only count once (as should arrays, etc.) 547f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectCount++; 548f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 549f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 550f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 551f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return RSObjectCount; 552f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines} 553f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 554b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Niclang::Stmt *ClearStructRSObject( 555f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ASTContext &C, 556f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC, 557f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSStruct, 558cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc, 559f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc) { 560f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *BaseType = RefRSStruct->getType().getTypePtr(); 561f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 562f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(!BaseType->isArrayType()); 563f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 564f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Structs should show up as unknown primitive types 5659be9360d8e02b52ed669afbd69f9becb575c3f0dAlex Sakhartchouk slangAssert(RSExportPrimitiveType::GetRSSpecificType(BaseType) == 566cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataTypeUnknown); 567f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 56865f23ed862e1a1e16477ba740f295ff4a83ac822David Gross unsigned FieldsToDestroy = CountRSObjectTypes(BaseType); 569b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines slangAssert(FieldsToDestroy != 0); 570f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 571f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines unsigned StmtCount = 0; 572f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Stmt **StmtArray = new clang::Stmt*[FieldsToDestroy]; 5732bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines for (unsigned i = 0; i < FieldsToDestroy; i++) { 5745abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes StmtArray[i] = nullptr; 5752bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 576f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 577f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Populate StmtArray by creating a destructor for each RS object field 578f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::RecordDecl *RD = BaseType->getAsStructureType()->getDecl(); 579f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RD = RD->getDefinition(); 580f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 581f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FE = RD->field_end(); 582f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI != FE; 583f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI++) { 584f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // We just look through all field declarations to see if we find a 585f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // declaration for an RS object type (or an array of one). 586f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool IsArrayType = false; 587f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::FieldDecl *FD = *FI; 588f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 589f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *OrigType = FT; 590f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines while (FT && FT->isArrayType()) { 591f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 592f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines IsArrayType = true; 593f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 594f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 595cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar // Pass a DeclarationNameInfo with a valid DeclName, since name equality 596cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar // gets asserted during CodeGen. 597cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar clang::DeclarationNameInfo FDDeclNameInfo(FD->getDeclName(), 598cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar FD->getLocation()); 599cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar 600f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (RSExportPrimitiveType::IsRSObjectType(FT)) { 601f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair FoundDecl = 602f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair::make(FD, clang::AS_none); 603f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr *RSObjectMember = 604f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr::Create(C, 605f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSStruct, 606f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines false, 6070b7545898dcfe2979f2c13afd12d276fc736412dStephen Hines clang::SourceLocation(), 608be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 6090444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 610f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FD, 611f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FoundDecl, 612cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar FDDeclNameInfo, 6135abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 614be27482cdeaf08576bc39b72a15d35d13014a636Logan OrigType->getCanonicalTypeInternal(), 615be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 616be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary); 617f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 618f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(StmtCount < FieldsToDestroy); 619f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 620f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (IsArrayType) { 621f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearArrayRSObject(C, 622f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 623f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 624cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, 625f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 626f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 627f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearSingleRSObject(C, 628f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 629f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 630f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 63165f23ed862e1a1e16477ba740f295ff4a83ac822David Gross } else if (FT->isStructureType() && CountRSObjectTypes(FT)) { 632f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // In this case, we have a nested struct. We may not end up filling all 633f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // of the spaces in StmtArray (sub-structs should handle themselves 634f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // with separate compound statements). 635f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair FoundDecl = 636f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair::make(FD, clang::AS_none); 637f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr *RSObjectMember = 638f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr::Create(C, 639f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSStruct, 640f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines false, 6410b7545898dcfe2979f2c13afd12d276fc736412dStephen Hines clang::SourceLocation(), 642be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 6430444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 644f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FD, 645f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FoundDecl, 646f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclarationNameInfo(), 6475abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 648be27482cdeaf08576bc39b72a15d35d13014a636Logan OrigType->getCanonicalTypeInternal(), 649be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 650be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary); 651f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 652f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (IsArrayType) { 653f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearArrayRSObject(C, 654f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 655f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 656cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, 657f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 658f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 659f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearStructRSObject(C, 660f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 661f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 662cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, 663f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 664f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 665f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 666f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 667f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 668f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(StmtCount > 0); 66923c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines clang::CompoundStmt *CS = new(C) clang::CompoundStmt( 67023c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines C, llvm::makeArrayRef(StmtArray, StmtCount), Loc, Loc); 671f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 672f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines delete [] StmtArray; 673f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 674f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return CS; 675f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines} 676f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 677b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Niclang::Stmt *CreateSingleRSSetObject(clang::ASTContext &C, 678b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Expr *DstExpr, 679b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Expr *SrcExpr, 680b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::SourceLocation StartLoc, 681b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::SourceLocation Loc) { 6822bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *T = DstExpr->getType().getTypePtr(); 6832bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::FunctionDecl *SetObjectFD = RSObjectRefCount::GetRSSetObjectFD(T); 6845abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes slangAssert((SetObjectFD != nullptr) && 6856e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "rsSetObject doesn't cover all RS object types"); 686c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 687c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType SetObjectFDType = SetObjectFD->getType(); 688c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType SetObjectFDArgType[2]; 689c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDArgType[0] = SetObjectFD->getParamDecl(0)->getOriginalType(); 690c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDArgType[1] = SetObjectFD->getParamDecl(1)->getOriginalType(); 691c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 692c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Expr *RefRSSetObjectFD = 693c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::DeclRefExpr::Create(C, 694be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 6950444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 696c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFD, 697e2597ac5a8ba7a45a1d5f342973cd43a3a1932cfShih-wei Liao false, 698c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines Loc, 699be27482cdeaf08576bc39b72a15d35d13014a636Logan SetObjectFDType, 700be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 7015abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr); 702c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 703c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Expr *RSSetObjectFP = 704c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::ImplicitCastExpr::Create(C, 705c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines C.getPointerType(SetObjectFDType), 706c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::CK_FunctionToPointerDecay, 707c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RefRSSetObjectFD, 7085abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 709c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::VK_RValue); 710c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 7111dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines llvm::SmallVector<clang::Expr*, 2> ArgList; 7121dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines ArgList.push_back(new(C) clang::UnaryOperator(DstExpr, 7131dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines clang::UO_AddrOf, 7141dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines SetObjectFDArgType[0], 7151dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines clang::VK_RValue, 7161dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines clang::OK_Ordinary, 7171dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines Loc)); 7181dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines ArgList.push_back(SrcExpr); 719c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 720c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::CallExpr *RSSetObjectCall = 721c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines new(C) clang::CallExpr(C, 722c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RSSetObjectFP, 723c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines ArgList, 724c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFD->getCallResultType(), 725be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 726c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines Loc); 727c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 7282bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return RSSetObjectCall; 7292bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines} 7302bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 731b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Niclang::Stmt *CreateStructRSSetObject(clang::ASTContext &C, 732b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Expr *LHS, 733b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Expr *RHS, 734b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::SourceLocation StartLoc, 735b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::SourceLocation Loc); 7362bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 737246fa17206bf78c59a64b2f7d98a6716d5345b81Al Sutton/*static clang::Stmt *CreateArrayRSSetObject(clang::ASTContext &C, 7382bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *DstArr, 7392bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *SrcArr, 740cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc, 7412bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SourceLocation Loc) { 7425abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes clang::DeclContext *DC = nullptr; 7432bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *BaseType = DstArr->getType().getTypePtr(); 7442bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(BaseType->isArrayType()); 7452bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7462bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines int NumArrayElements = ArrayDim(BaseType); 7472bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Actually extract out the base RS object type for use later 7482bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines BaseType = BaseType->getArrayElementTypeNoTypeQual(); 7492bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7505abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes clang::Stmt *StmtArray[2] = {nullptr}; 7512bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines int StmtCtr = 0; 7522bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7532bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (NumArrayElements <= 0) { 7545abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 7552bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 7562bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7572bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Create helper variable for iterating through elements 7582bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::IdentifierInfo& II = C.Idents.get("rsIntIter"); 7592bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VarDecl *IIVD = 7602bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VarDecl::Create(C, 7612bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines DC, 762cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, 7632bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 7642bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines &II, 7652bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 7662bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.getTrivialTypeSourceInfo(C.IntTy), 7672bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SC_None, 7682bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SC_None); 7692bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Decl *IID = (clang::Decl *)IIVD; 7702bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7712bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclGroupRef DGR = clang::DeclGroupRef::Create(C, &IID, 1); 7722bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCtr++] = new(C) clang::DeclStmt(DGR, Loc, Loc); 7732bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7742bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Form the actual loop 7752bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // for (Init; Cond; Inc) 7762bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // RSSetObjectCall; 7772bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7782bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Init -> "rsIntIter = 0" 7792bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclRefExpr *RefrsIntIter = 7802bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclRefExpr::Create(C, 781be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 7822bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines IIVD, 7832bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 784be27482cdeaf08576bc39b72a15d35d13014a636Logan C.IntTy, 785be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 7865abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr); 7872bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7882bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, 7892bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), 0), C.IntTy, Loc); 7902bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7912bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BinaryOperator *Init = 7922bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 7932bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Int0, 7942bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BO_Assign, 7952bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 796be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 797be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 7982bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 7992bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8002bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Cond -> "rsIntIter < NumArrayElements" 8012bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *NumArrayElementsExpr = clang::IntegerLiteral::Create(C, 8022bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), NumArrayElements), C.IntTy, Loc); 8032bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8042bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BinaryOperator *Cond = 8052bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 8062bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NumArrayElementsExpr, 8072bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BO_LT, 8082bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 809be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 810be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 8112bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 8122bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8132bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Inc -> "rsIntIter++" 8142bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::UnaryOperator *Inc = 8152bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::UnaryOperator(RefrsIntIter, 8162bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::UO_PostInc, 8172bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 818be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 819be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 8202bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 8212bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8222bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Body -> "rsSetObject(&Dst[rsIntIter], Src[rsIntIter]);" 8232bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Loop operates on individual array elements 8242bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8252bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *DstArrPtr = 8262bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ImplicitCastExpr::Create(C, 8272bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.getPointerType(BaseType->getCanonicalTypeInternal()), 8282bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::CK_ArrayToPointerDecay, 8292bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines DstArr, 8305abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 8312bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VK_RValue); 8322bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8332bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *DstArrPtrSubscript = 8342bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::ArraySubscriptExpr(DstArrPtr, 8352bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RefrsIntIter, 8362bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines BaseType->getCanonicalTypeInternal(), 837be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 838be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 8392bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 8402bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8412bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *SrcArrPtr = 8422bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ImplicitCastExpr::Create(C, 8432bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.getPointerType(BaseType->getCanonicalTypeInternal()), 8442bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::CK_ArrayToPointerDecay, 8452bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines SrcArr, 8465abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 8472bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VK_RValue); 8482bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8492bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *SrcArrPtrSubscript = 8502bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::ArraySubscriptExpr(SrcArrPtr, 8512bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RefrsIntIter, 8522bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines BaseType->getCanonicalTypeInternal(), 853be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 854be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 8552bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 8562bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 857cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT = RSExportPrimitiveType::GetRSSpecificType(BaseType); 8582bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8595abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes clang::Stmt *RSSetObjectCall = nullptr; 8602bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (BaseType->isArrayType()) { 861d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines RSSetObjectCall = CreateArrayRSSetObject(C, DstArrPtrSubscript, 862cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao SrcArrPtrSubscript, 863cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, Loc); 864cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet } else if (DT == DataTypeUnknown) { 865d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines RSSetObjectCall = CreateStructRSSetObject(C, DstArrPtrSubscript, 866cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao SrcArrPtrSubscript, 867cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, Loc); 8682bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else { 869d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines RSSetObjectCall = CreateSingleRSSetObject(C, DstArrPtrSubscript, 870cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao SrcArrPtrSubscript, 871cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, Loc); 8722bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 8732bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8742bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ForStmt *DestructorLoop = 8752bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::ForStmt(C, 8762bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Init, 8772bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Cond, 8785abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, // no condVar 8792bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Inc, 8802bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSSetObjectCall, 8812bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 8822bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 8832bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 8842bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8852bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCtr++] = DestructorLoop; 8862bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(StmtCtr == 2); 8872bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8882bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::CompoundStmt *CS = 8892bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::CompoundStmt(C, StmtArray, StmtCtr, Loc, Loc); 8902bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8912bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return CS; 892246fa17206bf78c59a64b2f7d98a6716d5345b81Al Sutton} */ 8932bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 894b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Niclang::Stmt *CreateStructRSSetObject(clang::ASTContext &C, 895b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Expr *LHS, 896b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Expr *RHS, 897b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::SourceLocation StartLoc, 898b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::SourceLocation Loc) { 8992bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::QualType QT = LHS->getType(); 9002bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *T = QT.getTypePtr(); 9012bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(T->isStructureType()); 9022bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(!RSExportPrimitiveType::IsRSObjectType(T)); 9032bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9042bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Keep an extra slot for the original copy (memcpy) 90565f23ed862e1a1e16477ba740f295ff4a83ac822David Gross unsigned FieldsToSet = CountRSObjectTypes(T) + 1; 9062bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9072bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines unsigned StmtCount = 0; 9082bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Stmt **StmtArray = new clang::Stmt*[FieldsToSet]; 9092bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines for (unsigned i = 0; i < FieldsToSet; i++) { 9105abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes StmtArray[i] = nullptr; 9112bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 9122bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9132bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::RecordDecl *RD = T->getAsStructureType()->getDecl(); 9142bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RD = RD->getDefinition(); 9152bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 9162bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FE = RD->field_end(); 9172bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FI != FE; 9182bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FI++) { 9192bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines bool IsArrayType = false; 9202bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::FieldDecl *FD = *FI; 9212bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 9222bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *OrigType = FT; 9232bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 92465f23ed862e1a1e16477ba740f295ff4a83ac822David Gross if (!CountRSObjectTypes(FT)) { 9252bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Skip to next if we don't have any viable RS object types 9262bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines continue; 9272bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 9282bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9292bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclAccessPair FoundDecl = 9302bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclAccessPair::make(FD, clang::AS_none); 9312bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr *DstMember = 9322bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr::Create(C, 9332bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines LHS, 9342bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines false, 9350b7545898dcfe2979f2c13afd12d276fc736412dStephen Hines clang::SourceLocation(), 936be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 9370444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 9382bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FD, 9392bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FoundDecl, 940c9344ace5050b7d5ee9a677ce996fc0b731c0830I-Jui (Ray) Sung clang::DeclarationNameInfo( 941c9344ace5050b7d5ee9a677ce996fc0b731c0830I-Jui (Ray) Sung FD->getDeclName(), 942c9344ace5050b7d5ee9a677ce996fc0b731c0830I-Jui (Ray) Sung clang::SourceLocation()), 9435abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 944be27482cdeaf08576bc39b72a15d35d13014a636Logan OrigType->getCanonicalTypeInternal(), 945be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 946be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary); 9472bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9482bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr *SrcMember = 9492bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr::Create(C, 9502bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RHS, 9512bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines false, 9520b7545898dcfe2979f2c13afd12d276fc736412dStephen Hines clang::SourceLocation(), 953be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 9540444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 9552bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FD, 9562bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FoundDecl, 957824b3ce35d55cc8b1f7f33874d22d328e05bd497I-Jui (Ray) Sung clang::DeclarationNameInfo( 958824b3ce35d55cc8b1f7f33874d22d328e05bd497I-Jui (Ray) Sung FD->getDeclName(), 959824b3ce35d55cc8b1f7f33874d22d328e05bd497I-Jui (Ray) Sung clang::SourceLocation()), 9605abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 961be27482cdeaf08576bc39b72a15d35d13014a636Logan OrigType->getCanonicalTypeInternal(), 962be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 963be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary); 9642bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9652bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (FT->isArrayType()) { 9662bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 9672bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines IsArrayType = true; 9682bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 9692bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 970cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT = RSExportPrimitiveType::GetRSSpecificType(FT); 9712bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9722bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (IsArrayType) { 9739207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine &DiagEngine = C.getDiagnostics(); 9749207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine.Report( 9759207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::FullSourceLoc(Loc, C.getSourceManager()), 9769207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine.getCustomDiagID( 9779207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine::Error, 9789207a2e495c8363606861e4f034504ec5c153dabLogan Chien "Arrays of RS object types within structures cannot be copied")); 9792bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // TODO(srhines): Support setting arrays of RS objects 9802bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // StmtArray[StmtCount++] = 981d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines // CreateArrayRSSetObject(C, DstMember, SrcMember, StartLoc, Loc); 982cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet } else if (DT == DataTypeUnknown) { 9832bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCount++] = 984d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines CreateStructRSSetObject(C, DstMember, SrcMember, StartLoc, Loc); 9852bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else if (RSExportPrimitiveType::IsRSObjectType(DT)) { 9862bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCount++] = 987d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines CreateSingleRSSetObject(C, DstMember, SrcMember, StartLoc, Loc); 9882bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else { 9892bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(false); 9902bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 9912bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 9922bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 993b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines slangAssert(StmtCount < FieldsToSet); 9942bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9952bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // We still need to actually do the overall struct copy. For simplicity, 9962bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // we just do a straight-up assignment (which will still preserve all 9972bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // the proper RS object reference counts). 9982bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BinaryOperator *CopyStruct = 999be27482cdeaf08576bc39b72a15d35d13014a636Logan new(C) clang::BinaryOperator(LHS, RHS, clang::BO_Assign, QT, 100023c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines clang::VK_RValue, clang::OK_Ordinary, Loc, 100123c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines false); 10022bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCount++] = CopyStruct; 10032bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 100423c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines clang::CompoundStmt *CS = new(C) clang::CompoundStmt( 100523c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines C, llvm::makeArrayRef(StmtArray, StmtCount), Loc, Loc); 10062bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10072bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines delete [] StmtArray; 10082bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10092bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return CS; 10102bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines} 10112bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10122bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines} // namespace 10132bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 1014b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Nivoid RSObjectRefCount::Scope::InsertStmt(const clang::ASTContext &C, 1015b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Stmt *NewStmt) { 1016b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni std::vector<clang::Stmt*> newBody; 1017b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni for (clang::Stmt* S1 : mCS->body()) { 1018b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni if (S1 == mCurrent) { 1019b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni newBody.push_back(NewStmt); 1020b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1021b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni newBody.push_back(S1); 1022b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 102398cfae456bb1831336bce2b21979a04e2e31fed4Pirama Arumuga Nainar mCS->setStmts(C, newBody); 1024b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni} 1025b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1026b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Nivoid RSObjectRefCount::Scope::ReplaceStmt(const clang::ASTContext &C, 1027b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Stmt *NewStmt) { 1028b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni std::vector<clang::Stmt*> newBody; 1029b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni for (clang::Stmt* S1 : mCS->body()) { 1030b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni if (S1 == mCurrent) { 1031b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni newBody.push_back(NewStmt); 1032b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } else { 1033b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni newBody.push_back(S1); 1034b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1035b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 103698cfae456bb1831336bce2b21979a04e2e31fed4Pirama Arumuga Nainar mCS->setStmts(C, newBody); 1037b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni} 1038b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1039b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Nivoid RSObjectRefCount::Scope::ReplaceExpr(const clang::ASTContext& C, 1040b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Expr* OldExpr, 1041b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Expr* NewExpr) { 1042b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni RSASTReplace R(C); 1043b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni R.ReplaceStmt(mCurrent, OldExpr, NewExpr); 1044b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni} 1045b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 10462bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesvoid RSObjectRefCount::Scope::ReplaceRSObjectAssignment( 1047d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines clang::BinaryOperator *AS) { 10482bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10492bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::QualType QT = AS->getType(); 10502bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10512bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ASTContext &C = RSObjectRefCount::GetRSSetObjectFD( 10529ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines DataTypeRSAllocation)->getASTContext(); 10532bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 1054832429f6bf4592cfc2ce58f2462f1e8ecdbaaf52Stephen Hines clang::SourceLocation Loc = AS->getExprLoc(); 10559f1d0aa55669b75a718ad2e962fc8c3d8df1a5f4Stephen Hines clang::SourceLocation StartLoc = AS->getLHS()->getExprLoc(); 10565abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes clang::Stmt *UpdatedStmt = nullptr; 10572bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10582bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (!RSExportPrimitiveType::IsRSObjectType(QT.getTypePtr())) { 10592bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // By definition, this is a struct assignment if we get here 10602bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines UpdatedStmt = 1061d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines CreateStructRSSetObject(C, AS->getLHS(), AS->getRHS(), StartLoc, Loc); 10622bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else { 10632bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines UpdatedStmt = 1064d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines CreateSingleRSSetObject(C, AS->getLHS(), AS->getRHS(), StartLoc, Loc); 10652bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 1066e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1067292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines RSASTReplace R(C); 1068292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines R.ReplaceStmt(mCS, AS, UpdatedStmt); 1069e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines} 1070e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1071e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hinesvoid RSObjectRefCount::Scope::AppendRSObjectInit( 1072e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::VarDecl *VD, 1073e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclStmt *DS, 1074cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT, 1075e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *InitExpr) { 10766e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(VD); 1077e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1078e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (!InitExpr) { 1079e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return; 1080e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 1081e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1082a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::ASTContext &C = RSObjectRefCount::GetRSSetObjectFD( 10839ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines DataTypeRSAllocation)->getASTContext(); 1084a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::SourceLocation Loc = RSObjectRefCount::GetRSSetObjectFD( 10859ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines DataTypeRSAllocation)->getLocation(); 1086cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc = RSObjectRefCount::GetRSSetObjectFD( 10879ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines DataTypeRSAllocation)->getInnerLocStart(); 1088a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines 1089cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet if (DT == DataTypeIsStruct) { 1090a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 1091a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::DeclRefExpr *RefRSVar = 1092a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::DeclRefExpr::Create(C, 1093be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 10940444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 1095a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines VD, 1096e2597ac5a8ba7a45a1d5f342973cd43a3a1932cfShih-wei Liao false, 1097a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines Loc, 1098be27482cdeaf08576bc39b72a15d35d13014a636Logan T->getCanonicalTypeInternal(), 1099be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 11005abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr); 1101a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines 1102a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::Stmt *RSSetObjectOps = 1103d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines CreateStructRSSetObject(C, RefRSVar, InitExpr, StartLoc, Loc); 1104cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // Fix for b/37363420; consider: 1105cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // 1106cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // struct foo { rs_matrix m; }; 1107cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // void bar() { 1108cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // struct foo M = {...}; 1109cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // } 1110cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // 1111cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // slang modifies that declaration with initialization to a 1112cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // declaration plus an assignment of the initialization values. 1113cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // 1114cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // void bar() { 1115cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // struct foo M = {}; 1116cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // M = {...}; // by CreateStructRSSetObject() above 1117cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // } 1118cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // 1119cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // the slang-generated statement (M = {...}) is a use of M, and we 1120cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // need to mark M (clang::VarDecl *VD) as used. 1121cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung VD->markUsed(C); 1122a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines 1123292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*> StmtList; 1124292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines StmtList.push_back(RSSetObjectOps); 1125292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines AppendAfterStmt(C, mCS, DS, StmtList); 1126f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return; 1127f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 1128f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 1129f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::FunctionDecl *SetObjectFD = RSObjectRefCount::GetRSSetObjectFD(DT); 11305abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes slangAssert((SetObjectFD != nullptr) && 11316e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "rsSetObject doesn't cover all RS object types"); 1132e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1133e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::QualType SetObjectFDType = SetObjectFD->getType(); 1134e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::QualType SetObjectFDArgType[2]; 1135e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDArgType[0] = SetObjectFD->getParamDecl(0)->getOriginalType(); 1136e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDArgType[1] = SetObjectFD->getParamDecl(1)->getOriginalType(); 1137e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1138e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *RefRSSetObjectFD = 1139e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr::Create(C, 1140be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 11410444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 1142e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFD, 1143e2597ac5a8ba7a45a1d5f342973cd43a3a1932cfShih-wei Liao false, 1144e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc, 1145be27482cdeaf08576bc39b72a15d35d13014a636Logan SetObjectFDType, 1146be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 11475abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr); 1148e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1149e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *RSSetObjectFP = 1150e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::ImplicitCastExpr::Create(C, 1151e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines C.getPointerType(SetObjectFDType), 1152e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CK_FunctionToPointerDecay, 1153e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RefRSSetObjectFD, 11545abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 1155e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::VK_RValue); 1156e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1157e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 1158e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr *RefRSVar = 1159e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr::Create(C, 1160be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 11610444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 1162e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD, 1163e2597ac5a8ba7a45a1d5f342973cd43a3a1932cfShih-wei Liao false, 1164e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc, 1165be27482cdeaf08576bc39b72a15d35d13014a636Logan T->getCanonicalTypeInternal(), 1166be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 11675abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr); 1168e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 11691dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines llvm::SmallVector<clang::Expr*, 2> ArgList; 11701dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines ArgList.push_back(new(C) clang::UnaryOperator(RefRSVar, 11711dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines clang::UO_AddrOf, 11721dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines SetObjectFDArgType[0], 11731dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines clang::VK_RValue, 11741dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines clang::OK_Ordinary, 11751dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines Loc)); 11761dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines ArgList.push_back(InitExpr); 1177e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1178e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CallExpr *RSSetObjectCall = 1179e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines new(C) clang::CallExpr(C, 1180e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSSetObjectFP, 1181e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ArgList, 1182e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFD->getCallResultType(), 1183be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1184e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc); 1185e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1186292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*> StmtList; 1187292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines StmtList.push_back(RSSetObjectCall); 1188292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines AppendAfterStmt(C, mCS, DS, StmtList); 1189c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines} 1190c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 11911bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hinesvoid RSObjectRefCount::Scope::InsertLocalVarDestructors() { 1192b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni if (mRSO.empty()) { 1193b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni return; 1194b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1195b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1196b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::DeclContext* DC = mRSO.front()->getDeclContext(); 1197b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::ASTContext& C = DC->getParentASTContext(); 1198b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::SourceManager& SM = C.getSourceManager(); 1199b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1200b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni const auto& OccursBefore = [&SM] (clang::SourceLocation L1, clang::SourceLocation L2)->bool { 1201b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni return SM.isBeforeInTranslationUnit(L1, L2); 1202b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni }; 1203b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni typedef std::map<clang::SourceLocation, clang::Stmt*, decltype(OccursBefore)> DMap; 1204b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1205b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni DMap dtors(OccursBefore); 1206b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1207b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // Create rsClearObject calls. Note the DMap entries are sorted by the SourceLocation. 1208b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni for (clang::VarDecl* VD : mRSO) { 1209b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::SourceLocation Loc = VD->getSourceRange().getBegin(); 1210b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Stmt* RSClearObjectCall = ClearRSObject(VD, DC); 1211b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni dtors.insert(std::make_pair(Loc, RSClearObjectCall)); 1212b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1213b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1214b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni DestructorVisitor Visitor; 1215b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni Visitor.Visit(mCS); 1216b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1217b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // Replace each exiting statement with a block that contains the original statement 1218b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // and added rsClearObject() calls before it. 1219b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni for (clang::Stmt* S : Visitor.getExitingStmts()) { 1220b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1221b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni const clang::SourceLocation currentLoc = S->getLocStart(); 1222b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1223b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni DMap::iterator firstDtorIter = dtors.begin(); 1224b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni DMap::iterator currentDtorIter = firstDtorIter; 1225b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni DMap::iterator lastDtorIter = dtors.end(); 1226b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1227b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni while (currentDtorIter != lastDtorIter && 1228b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni OccursBefore(currentDtorIter->first, currentLoc)) { 1229b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni currentDtorIter++; 12301bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1231b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1232b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni if (currentDtorIter == firstDtorIter) { 1233b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni continue; 1234b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1235b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1236579e4f481774275980d6e3fbb7978c674da6d302Yang Ni std::vector<clang::Stmt*> Stmts; 1237b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1238b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // Insert rsClearObject() calls for all rsObjects declared before the current statement 1239b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni for(DMap::iterator it = firstDtorIter; it != currentDtorIter; it++) { 1240b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni Stmts.push_back(it->second); 1241b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1242b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni Stmts.push_back(S); 1243b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1244b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni RSASTReplace R(C); 1245b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::CompoundStmt* CS = BuildCompoundStmt(C, Stmts, S->getLocEnd()); 1246b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni R.ReplaceStmt(mCS, S, CS); 12471bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1248b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1249b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni std::list<clang::Stmt*> Stmts; 1250b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni for(auto LocCallPair : dtors) { 1251b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni Stmts.push_back(LocCallPair.second); 1252b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1253b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni AppendAfterStmt(C, mCS, nullptr, Stmts); 12541bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 12551bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 12563f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hinesclang::Stmt *RSObjectRefCount::Scope::ClearRSObject( 12573f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines clang::VarDecl *VD, 12583f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines clang::DeclContext *DC) { 1259f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(VD); 12601bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::ASTContext &C = VD->getASTContext(); 12611bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::SourceLocation Loc = VD->getLocation(); 1262cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc = VD->getInnerLocStart(); 12631bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 126403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 12651bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Reference expr to target RS object variable 12661bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::DeclRefExpr *RefRSVar = 12671bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::DeclRefExpr::Create(C, 1268be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 12690444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 12701bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines VD, 1271e2597ac5a8ba7a45a1d5f342973cd43a3a1932cfShih-wei Liao false, 12721bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines Loc, 1273be27482cdeaf08576bc39b72a15d35d13014a636Logan T->getCanonicalTypeInternal(), 1274be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 12755abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr); 12761bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1277f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (T->isArrayType()) { 1278cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao return ClearArrayRSObject(C, DC, RefRSVar, StartLoc, Loc); 1279f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 12801bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1281cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT = RSExportPrimitiveType::GetRSSpecificType(T); 12821bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1283cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet if (DT == DataTypeUnknown || 1284cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DT == DataTypeIsStruct) { 1285cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao return ClearStructRSObject(C, DC, RefRSVar, StartLoc, Loc); 1286f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 12871bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1288f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert((RSExportPrimitiveType::IsRSObjectType(DT)) && 1289f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "Should be RS object"); 12901bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1291f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return ClearSingleRSObject(C, RefRSVar, Loc); 12921bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 12931bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1294e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hinesbool RSObjectRefCount::InitializeRSObject(clang::VarDecl *VD, 1295cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType *DT, 1296e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr **InitExpr) { 12976e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(VD && DT && InitExpr); 12984b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 12992d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines 13002d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines // Loop through array types to get to base type 13012d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines while (T && T->isArrayType()) { 13022d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines T = T->getArrayElementTypeNoTypeQual(); 13032d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines } 13042d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines 1305f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool DataTypeIsStructWithRSObject = false; 1306e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines *DT = RSExportPrimitiveType::GetRSSpecificType(T); 13074b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1308cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet if (*DT == DataTypeUnknown) { 1309feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (RSExportPrimitiveType::IsStructureTypeWithRSObject(T)) { 1310cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet *DT = DataTypeIsStruct; 1311f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DataTypeIsStructWithRSObject = true; 1312feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } else { 1313feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines return false; 1314feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 13152d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines } 13164b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1317f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool DataTypeIsRSObject = false; 1318f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (DataTypeIsStructWithRSObject) { 1319f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DataTypeIsRSObject = true; 1320f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 1321f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DataTypeIsRSObject = RSExportPrimitiveType::IsRSObjectType(*DT); 1322f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 1323e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines *InitExpr = VD->getInit(); 1324e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1325e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (!DataTypeIsRSObject && *InitExpr) { 1326e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines // If we already have an initializer for a matrix type, we are done. 1327e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return DataTypeIsRSObject; 13284b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 13294b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1330e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *ZeroInitializer = 1331d9ed6b51a3fe997aefdcd360f8bfc40b17c9ab91Stephen Hines CreateEmptyInitListExpr(VD->getASTContext(), VD->getLocation()); 1332e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1333e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (ZeroInitializer) { 1334e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ZeroInitializer->setType(T->getCanonicalTypeInternal()); 1335e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->setInit(ZeroInitializer); 1336e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 1337e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1338e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return DataTypeIsRSObject; 13394b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 13404b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1341d9ed6b51a3fe997aefdcd360f8bfc40b17c9ab91Stephen Hinesclang::Expr *RSObjectRefCount::CreateEmptyInitListExpr( 13424b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ASTContext &C, 13434b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines const clang::SourceLocation &Loc) { 13444b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1345d9ed6b51a3fe997aefdcd360f8bfc40b17c9ab91Stephen Hines // We can cheaply construct a zero initializer by just creating an empty 1346d9ed6b51a3fe997aefdcd360f8bfc40b17c9ab91Stephen Hines // initializer list. Clang supports this extension to C(99), and will create 1347d9ed6b51a3fe997aefdcd360f8bfc40b17c9ab91Stephen Hines // any necessary constructs to zero out the entire variable. 1348d9ed6b51a3fe997aefdcd360f8bfc40b17c9ab91Stephen Hines llvm::SmallVector<clang::Expr*, 1> EmptyInitList; 1349d9ed6b51a3fe997aefdcd360f8bfc40b17c9ab91Stephen Hines return new(C) clang::InitListExpr(C, Loc, EmptyInitList, Loc); 13504b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 13514b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1352579e4f481774275980d6e3fbb7978c674da6d302Yang Niclang::DeclRefExpr *RSObjectRefCount::CreateGuard(clang::ASTContext &C, 1353579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::DeclContext *DC, 1354579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::Expr *E, 1355579e4f481774275980d6e3fbb7978c674da6d302Yang Ni const llvm::Twine &VarName, 1356579e4f481774275980d6e3fbb7978c674da6d302Yang Ni std::vector<clang::Stmt*> &NewStmts) { 1357579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::SourceLocation Loc = E->getLocStart(); 1358579e4f481774275980d6e3fbb7978c674da6d302Yang Ni const clang::QualType Ty = E->getType(); 1359579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::VarDecl* TmpDecl = clang::VarDecl::Create( 13605767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni C, // AST context 13615767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni DC, // Decl context 13625767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni Loc, // Start location 13635767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni Loc, // Id location 1364579e4f481774275980d6e3fbb7978c674da6d302Yang Ni &C.Idents.get(VarName.str()), // Id 1365579e4f481774275980d6e3fbb7978c674da6d302Yang Ni Ty, // Type 1366579e4f481774275980d6e3fbb7978c674da6d302Yang Ni C.getTrivialTypeSourceInfo(Ty), // Type info 13675767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni clang::SC_None // Storage class 13685767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni ); 1369579e4f481774275980d6e3fbb7978c674da6d302Yang Ni const clang::Type *T = Ty.getTypePtr(); 13705767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni clang::Expr *ZeroInitializer = 1371d9ed6b51a3fe997aefdcd360f8bfc40b17c9ab91Stephen Hines RSObjectRefCount::CreateEmptyInitListExpr(C, Loc); 13725767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni ZeroInitializer->setType(T->getCanonicalTypeInternal()); 1373579e4f481774275980d6e3fbb7978c674da6d302Yang Ni TmpDecl->setInit(ZeroInitializer); 1374579e4f481774275980d6e3fbb7978c674da6d302Yang Ni TmpDecl->markUsed(C); 1375579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::Decl* Decls[] = { TmpDecl }; 13765767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni const clang::DeclGroupRef DGR = clang::DeclGroupRef::Create( 13775767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni C, Decls, sizeof(Decls) / sizeof(*Decls)); 13785767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni clang::DeclStmt* DS = new (C) clang::DeclStmt(DGR, Loc, Loc); 13795767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni NewStmts.push_back(DS); 13805767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni 13815767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni clang::DeclRefExpr* DRE = clang::DeclRefExpr::Create( 13825767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni C, 13835767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni clang::NestedNameSpecifierLoc(), // QualifierLoc 13845767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni Loc, // TemplateKWLoc 1385579e4f481774275980d6e3fbb7978c674da6d302Yang Ni TmpDecl, 13865767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni false, // RefersToEnclosingVariableOrCapture 13875767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni Loc, // NameLoc 1388579e4f481774275980d6e3fbb7978c674da6d302Yang Ni Ty, 13895767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni clang::VK_LValue 13905767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni ); 1391579e4f481774275980d6e3fbb7978c674da6d302Yang Ni 1392579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::Stmt *UpdatedStmt = nullptr; 1393f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni if (CountRSObjectTypes(Ty.getTypePtr()) == 0) { 1394f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni // The expression E is not an RS object itself. Instead of calling 1395f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni // rsSetObject(), create an assignment statement to set the value of the 1396f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni // temporary "guard" variable to the expression. 1397f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni // This can happen if called from RSObjectRefCount::VisitReturnStmt(), 1398f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni // when the return expression is not an RS object but references one. 1399f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni UpdatedStmt = 1400f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni new(C) clang::BinaryOperator(DRE, E, clang::BO_Assign, Ty, 1401f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni clang::VK_RValue, clang::OK_Ordinary, Loc, 1402f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni false); 1403f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni 1404f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni } else if (!RSExportPrimitiveType::IsRSObjectType(Ty.getTypePtr())) { 1405579e4f481774275980d6e3fbb7978c674da6d302Yang Ni // By definition, this is a struct assignment if we get here 1406579e4f481774275980d6e3fbb7978c674da6d302Yang Ni UpdatedStmt = 1407579e4f481774275980d6e3fbb7978c674da6d302Yang Ni CreateStructRSSetObject(C, DRE, E, Loc, Loc); 1408579e4f481774275980d6e3fbb7978c674da6d302Yang Ni } else { 1409579e4f481774275980d6e3fbb7978c674da6d302Yang Ni UpdatedStmt = 1410579e4f481774275980d6e3fbb7978c674da6d302Yang Ni CreateSingleRSSetObject(C, DRE, E, Loc, Loc); 1411579e4f481774275980d6e3fbb7978c674da6d302Yang Ni } 1412579e4f481774275980d6e3fbb7978c674da6d302Yang Ni NewStmts.push_back(UpdatedStmt); 1413579e4f481774275980d6e3fbb7978c674da6d302Yang Ni 1414579e4f481774275980d6e3fbb7978c674da6d302Yang Ni return DRE; 1415579e4f481774275980d6e3fbb7978c674da6d302Yang Ni} 1416579e4f481774275980d6e3fbb7978c674da6d302Yang Ni 1417579e4f481774275980d6e3fbb7978c674da6d302Yang Nivoid RSObjectRefCount::CreateParameterGuard(clang::ASTContext &C, 1418579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::DeclContext *DC, 1419579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::ParmVarDecl *PD, 1420579e4f481774275980d6e3fbb7978c674da6d302Yang Ni std::vector<clang::Stmt*> &NewStmts) { 1421579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::SourceLocation Loc = PD->getLocStart(); 1422579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::DeclRefExpr* ParamDRE = clang::DeclRefExpr::Create( 1423579e4f481774275980d6e3fbb7978c674da6d302Yang Ni C, 1424579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::NestedNameSpecifierLoc(), // QualifierLoc 1425579e4f481774275980d6e3fbb7978c674da6d302Yang Ni Loc, // TemplateKWLoc 1426579e4f481774275980d6e3fbb7978c674da6d302Yang Ni PD, 1427579e4f481774275980d6e3fbb7978c674da6d302Yang Ni false, // RefersToEnclosingVariableOrCapture 1428579e4f481774275980d6e3fbb7978c674da6d302Yang Ni Loc, // NameLoc 1429579e4f481774275980d6e3fbb7978c674da6d302Yang Ni PD->getType(), 1430579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::VK_RValue 1431579e4f481774275980d6e3fbb7978c674da6d302Yang Ni ); 1432579e4f481774275980d6e3fbb7978c674da6d302Yang Ni 1433579e4f481774275980d6e3fbb7978c674da6d302Yang Ni CreateGuard(C, DC, ParamDRE, 1434579e4f481774275980d6e3fbb7978c674da6d302Yang Ni llvm::Twine(".rs.param.") + llvm::Twine(PD->getName()), NewStmts); 1435579e4f481774275980d6e3fbb7978c674da6d302Yang Ni} 1436579e4f481774275980d6e3fbb7978c674da6d302Yang Ni 1437579e4f481774275980d6e3fbb7978c674da6d302Yang Nivoid RSObjectRefCount::HandleParamsAndLocals(clang::FunctionDecl *FD) { 1438579e4f481774275980d6e3fbb7978c674da6d302Yang Ni std::vector<clang::Stmt*> NewStmts; 1439579e4f481774275980d6e3fbb7978c674da6d302Yang Ni std::list<clang::ParmVarDecl*> ObjParams; 1440579e4f481774275980d6e3fbb7978c674da6d302Yang Ni for (clang::ParmVarDecl *Param : FD->parameters()) { 1441579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::QualType QT = Param->getType(); 1442579e4f481774275980d6e3fbb7978c674da6d302Yang Ni if (CountRSObjectTypes(QT.getTypePtr())) { 1443579e4f481774275980d6e3fbb7978c674da6d302Yang Ni // Ignore non-object types 1444579e4f481774275980d6e3fbb7978c674da6d302Yang Ni RSObjectRefCount::CreateParameterGuard(mCtx, FD, Param, NewStmts); 1445579e4f481774275980d6e3fbb7978c674da6d302Yang Ni ObjParams.push_back(Param); 1446579e4f481774275980d6e3fbb7978c674da6d302Yang Ni } 1447579e4f481774275980d6e3fbb7978c674da6d302Yang Ni } 1448579e4f481774275980d6e3fbb7978c674da6d302Yang Ni 1449579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::Stmt *OldBody = FD->getBody(); 1450579e4f481774275980d6e3fbb7978c674da6d302Yang Ni if (ObjParams.empty()) { 1451579e4f481774275980d6e3fbb7978c674da6d302Yang Ni Visit(OldBody); 1452579e4f481774275980d6e3fbb7978c674da6d302Yang Ni return; 1453579e4f481774275980d6e3fbb7978c674da6d302Yang Ni } 1454579e4f481774275980d6e3fbb7978c674da6d302Yang Ni 1455579e4f481774275980d6e3fbb7978c674da6d302Yang Ni NewStmts.push_back(OldBody); 1456579e4f481774275980d6e3fbb7978c674da6d302Yang Ni 1457579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::SourceLocation Loc = FD->getLocStart(); 1458579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::CompoundStmt *NewBody = BuildCompoundStmt(mCtx, NewStmts, Loc); 1459579e4f481774275980d6e3fbb7978c674da6d302Yang Ni Scope S(NewBody); 1460579e4f481774275980d6e3fbb7978c674da6d302Yang Ni for (clang::ParmVarDecl *Param : ObjParams) { 1461579e4f481774275980d6e3fbb7978c674da6d302Yang Ni S.addRSObject(Param); 1462579e4f481774275980d6e3fbb7978c674da6d302Yang Ni } 1463579e4f481774275980d6e3fbb7978c674da6d302Yang Ni mScopeStack.push_back(&S); 1464579e4f481774275980d6e3fbb7978c674da6d302Yang Ni 1465579e4f481774275980d6e3fbb7978c674da6d302Yang Ni // To avoid adding unnecessary ref counting artifacts to newly added temporary 1466579e4f481774275980d6e3fbb7978c674da6d302Yang Ni // local variables for parameters, visits only the old function body here. 1467579e4f481774275980d6e3fbb7978c674da6d302Yang Ni Visit(OldBody); 1468579e4f481774275980d6e3fbb7978c674da6d302Yang Ni 1469579e4f481774275980d6e3fbb7978c674da6d302Yang Ni FD->setBody(NewBody); 1470579e4f481774275980d6e3fbb7978c674da6d302Yang Ni 1471579e4f481774275980d6e3fbb7978c674da6d302Yang Ni S.InsertLocalVarDestructors(); 1472579e4f481774275980d6e3fbb7978c674da6d302Yang Ni mScopeStack.pop_back(); 1473579e4f481774275980d6e3fbb7978c674da6d302Yang Ni} 1474579e4f481774275980d6e3fbb7978c674da6d302Yang Ni 1475579e4f481774275980d6e3fbb7978c674da6d302Yang Niclang::CompoundStmt* RSObjectRefCount::CreateRetStmtWithTempVar( 1476579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::ASTContext& C, 1477579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::DeclContext* DC, 1478579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::ReturnStmt* RS, 1479579e4f481774275980d6e3fbb7978c674da6d302Yang Ni const unsigned id) { 1480579e4f481774275980d6e3fbb7978c674da6d302Yang Ni std::vector<clang::Stmt*> NewStmts; 1481579e4f481774275980d6e3fbb7978c674da6d302Yang Ni // Since we insert rsClearObj() calls before the return statement, we need 1482579e4f481774275980d6e3fbb7978c674da6d302Yang Ni // to make sure none of the cleared RS objects are referenced in the 1483579e4f481774275980d6e3fbb7978c674da6d302Yang Ni // return statement. 1484579e4f481774275980d6e3fbb7978c674da6d302Yang Ni // For that, we create a new local variable named .rs.retval, assign the 1485579e4f481774275980d6e3fbb7978c674da6d302Yang Ni // original return expression to it, make all necessary rsClearObj() 1486579e4f481774275980d6e3fbb7978c674da6d302Yang Ni // calls, then return .rs.retval. Note rsClearObj() is not called on 1487579e4f481774275980d6e3fbb7978c674da6d302Yang Ni // .rs.retval. 1488579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::SourceLocation Loc = RS->getLocStart(); 1489579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::Expr* RetVal = RS->getRetValue(); 1490579e4f481774275980d6e3fbb7978c674da6d302Yang Ni const clang::QualType RetTy = RetVal->getType(); 1491579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::DeclRefExpr *DRE = CreateGuard(C, DC, RetVal, 1492579e4f481774275980d6e3fbb7978c674da6d302Yang Ni llvm::Twine(".rs.retval") + llvm::Twine(id), 1493579e4f481774275980d6e3fbb7978c674da6d302Yang Ni NewStmts); 14945767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni 14955767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni // Creates a new return statement 1496579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::ReturnStmt* NewRet = new (C) clang::ReturnStmt(Loc); 14975767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni clang::Expr* CastExpr = clang::ImplicitCastExpr::Create( 14985767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni C, 14995767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni RetTy, 15005767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni clang::CK_LValueToRValue, 15015767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni DRE, 15025767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni nullptr, 15035767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni clang::VK_RValue 15045767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni ); 15055767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni NewRet->setRetValue(CastExpr); 15065767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni NewStmts.push_back(NewRet); 15075767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni 15085767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni return BuildCompoundStmt(C, NewStmts, Loc); 15095767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni} 15105767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni 15114b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitDeclStmt(clang::DeclStmt *DS) { 1512b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni VisitStmt(DS); 1513b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni getCurrentScope()->setCurrentStmt(DS); 15144b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (clang::DeclStmt::decl_iterator I = DS->decl_begin(), E = DS->decl_end(); 15154b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I != E; 15164b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I++) { 15174b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Decl *D = *I; 15184b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (D->getKind() == clang::Decl::Var) { 15194b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::VarDecl *VD = static_cast<clang::VarDecl*>(D); 1520cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT = DataTypeUnknown; 15215abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes clang::Expr *InitExpr = nullptr; 1522e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (InitializeRSObject(VD, &DT, &InitExpr)) { 1523b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines // We need to zero-init all RS object types (including matrices), ... 1524d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines getCurrentScope()->AppendRSObjectInit(VD, DS, DT, InitExpr); 1525b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines // ... but, only add to the list of RS objects if we have some 1526b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines // non-matrix RS object fields. 152765f23ed862e1a1e16477ba740f295ff4a83ac822David Gross if (CountRSObjectTypes(VD->getType().getTypePtr())) { 1528b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines getCurrentScope()->addRSObject(VD); 1529b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines } 1530e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 15314b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 15324b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 15334b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 15344b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1535b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Nivoid RSObjectRefCount::VisitCallExpr(clang::CallExpr* CE) { 1536b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::QualType RetTy; 1537b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni const clang::FunctionDecl* FD = CE->getDirectCallee(); 1538b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1539b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni if (FD) { 1540b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // Direct calls 1541b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1542b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni RetTy = FD->getReturnType(); 1543b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } else { 1544b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // Indirect calls through function pointers 1545b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1546b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni const clang::Expr* Callee = CE->getCallee(); 1547b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni const clang::Type* CalleeType = Callee->getType().getTypePtr(); 1548b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni const clang::PointerType* PtrType = CalleeType->getAs<clang::PointerType>(); 1549b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1550b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni if (!PtrType) { 1551b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni return; 1552b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1553b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1554b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni const clang::Type* PointeeType = PtrType->getPointeeType().getTypePtr(); 1555b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni const clang::FunctionType* FuncType = PointeeType->getAs<clang::FunctionType>(); 1556b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1557b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni if (!FuncType) { 1558b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni return; 1559b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1560b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1561b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni RetTy = FuncType->getReturnType(); 1562b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1563b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 15649e580014469e0c87e95fcb31e78738a336b1f200Yang Ni // The RenderScript runtime API maintains the invariant that the sysRef of a new RS object would 15659e580014469e0c87e95fcb31e78738a336b1f200Yang Ni // be 1, with the exception of rsGetAllocation() (deprecated in API 22), which leaves the sysRef 15669e580014469e0c87e95fcb31e78738a336b1f200Yang Ni // 0 for a new allocation. It is the responsibility of the callee of the API to decrement the 15679e580014469e0c87e95fcb31e78738a336b1f200Yang Ni // sysRef when a reference of the RS object goes out of scope. The compiler generates code to do 15689e580014469e0c87e95fcb31e78738a336b1f200Yang Ni // just that, by creating a temporary variable named ".rs.tmpN" with the result of 15699e580014469e0c87e95fcb31e78738a336b1f200Yang Ni // an RS-object-returning API directly assigned to it, and calling rsClearObject() on .rs.tmpN 15709e580014469e0c87e95fcb31e78738a336b1f200Yang Ni // right before it exits the current scope. Such code generation is skipped for rsGetAllocation() 15719e580014469e0c87e95fcb31e78738a336b1f200Yang Ni // to avoid decrementing its sysRef below zero. 15729e580014469e0c87e95fcb31e78738a336b1f200Yang Ni 15739e580014469e0c87e95fcb31e78738a336b1f200Yang Ni if (CountRSObjectTypes(RetTy.getTypePtr())==0 || 15749e580014469e0c87e95fcb31e78738a336b1f200Yang Ni (FD && FD->getName() == "rsGetAllocation")) { 1575b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni return; 1576b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1577b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1578b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::SourceLocation Loc = CE->getSourceRange().getBegin(); 1579b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni std::stringstream ss; 1580b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni ss << ".rs.tmp" << getNextID(); 1581b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni llvm::StringRef VarName(ss.str()); 1582b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1583b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::VarDecl* TempVarDecl = clang::VarDecl::Create( 1584b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni mCtx, // AST context 1585b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni GetDeclContext(), // Decl context 1586b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni Loc, // Start location 1587b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni Loc, // Id location 1588b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni &mCtx.Idents.get(VarName), // Id 1589b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni RetTy, // Type 1590b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni mCtx.getTrivialTypeSourceInfo(RetTy), // Type info 1591b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::SC_None // Storage class 1592b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni ); 1593b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni TempVarDecl->setInit(CE); 1594041656a24663cb4f7a61a598e848f217c893cebfStephen Hines TempVarDecl->markUsed(mCtx); 1595b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Decl* Decls[] = { TempVarDecl }; 1596b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni const clang::DeclGroupRef DGR = clang::DeclGroupRef::Create( 1597b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni mCtx, Decls, sizeof(Decls) / sizeof(*Decls)); 1598b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::DeclStmt* DS = new (mCtx) clang::DeclStmt(DGR, Loc, Loc); 1599b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1600b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni getCurrentScope()->InsertStmt(mCtx, DS); 1601b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1602b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::DeclRefExpr* DRE = clang::DeclRefExpr::Create( 1603b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni mCtx, // AST context 1604b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::NestedNameSpecifierLoc(), // QualifierLoc 1605b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni Loc, // TemplateKWLoc 1606b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni TempVarDecl, 1607b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni false, // RefersToEnclosingVariableOrCapture 1608b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni Loc, // NameLoc 1609b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni RetTy, 1610b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::VK_LValue 1611b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni ); 1612b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Expr* CastExpr = clang::ImplicitCastExpr::Create( 1613b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni mCtx, 1614b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni RetTy, 1615b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::CK_LValueToRValue, 1616b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni DRE, 1617b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni nullptr, 1618b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::VK_RValue 1619b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni ); 1620b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1621b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni getCurrentScope()->ReplaceExpr(mCtx, CE, CastExpr); 1622b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1623b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // Register TempVarDecl for destruction call (rsClearObj). 1624b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni getCurrentScope()->addRSObject(TempVarDecl); 1625b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni} 1626b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 16274b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitCompoundStmt(clang::CompoundStmt *CS) { 1628b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni if (!emptyScope()) { 1629b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni getCurrentScope()->setCurrentStmt(CS); 1630b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1631b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 16324b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (!CS->body_empty()) { 16334b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Push a new scope 16344b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Scope *S = new Scope(CS); 1635b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni mScopeStack.push_back(S); 16364b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 16374b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines VisitStmt(CS); 16384b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 16394b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Destroy the scope 16406e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((getCurrentScope() == S) && "Corrupted scope stack!"); 16411bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines S->InsertLocalVarDestructors(); 1642b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni mScopeStack.pop_back(); 16434b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines delete S; 16444b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 16454b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 16464b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 16474b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitBinAssign(clang::BinaryOperator *AS) { 1648b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni getCurrentScope()->setCurrentStmt(AS); 1649c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType QT = AS->getType(); 1650c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 165165f23ed862e1a1e16477ba740f295ff4a83ac822David Gross if (CountRSObjectTypes(QT.getTypePtr())) { 1652d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines getCurrentScope()->ReplaceRSObjectAssignment(AS); 1653c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 16544b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 16554b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1656f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ninamespace { 1657f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni 1658f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Niclass FindRSObjRefVisitor : public clang::RecursiveASTVisitor<FindRSObjRefVisitor> { 1659f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Nipublic: 1660f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni explicit FindRSObjRefVisitor() : mRefRSObj(false) {} 1661f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni bool VisitExpr(clang::Expr* Expression) { 1662f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni if (CountRSObjectTypes(Expression->getType().getTypePtr()) > 0) { 1663f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni mRefRSObj = true; 1664f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni // Found a reference to an RS object. Stop the AST traversal. 1665f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni return false; 1666f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni } 1667f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni return true; 1668f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni } 1669f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni 1670f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni bool foundRSObjRef() const { return mRefRSObj; } 1671f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni 1672f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Niprivate: 1673f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni bool mRefRSObj; 1674f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni}; 1675f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni 1676f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni} // anonymous namespace 1677f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni 1678b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Nivoid RSObjectRefCount::VisitReturnStmt(clang::ReturnStmt *RS) { 1679b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni getCurrentScope()->setCurrentStmt(RS); 1680b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1681b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // If there is no local rsObject declared so far, no need to transform the 1682b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // return statement. 1683b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1684b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni bool RSObjDeclared = false; 1685b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1686b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni for (const Scope* S : mScopeStack) { 1687b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni if (S->hasRSObject()) { 1688b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni RSObjDeclared = true; 1689b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni break; 1690b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1691b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1692b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1693b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni if (!RSObjDeclared) { 1694b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni return; 1695b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1696b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1697f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni FindRSObjRefVisitor visitor; 1698f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni 1699f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni visitor.TraverseStmt(RS); 1700f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni 1701f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni // If the return statement does not return anything, or if it does not reference 1702b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // a rsObject, no need to transform it. 1703b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1704f6d3e58d364ae3d97a9cf468ca926259193c9018Yang Ni if (!visitor.foundRSObjRef()) { 1705b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni return; 1706b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1707b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1708b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // Transform the return statement so that it does not potentially return or 1709b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // reference a rsObject that has been cleared. 1710b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1711b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::CompoundStmt* NewRS; 1712b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni NewRS = CreateRetStmtWithTempVar(mCtx, GetDeclContext(), RS, getNextID()); 1713b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1714b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni getCurrentScope()->ReplaceStmt(mCtx, NewRS); 1715b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni} 1716b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 17174b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitStmt(clang::Stmt *S) { 1718b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni getCurrentScope()->setCurrentStmt(S); 17194b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end(); 17204b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I != E; 17214b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I++) { 17224b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (clang::Stmt *Child = *I) { 17234b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Visit(Child); 17244b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 17254b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 17264b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 17274b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1728688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines// This function walks the list of global variables and (potentially) creates 1729688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines// a single global static destructor function that properly decrements 1730688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines// reference counts on the contained RS object types. 1731688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hinesclang::FunctionDecl *RSObjectRefCount::CreateStaticGlobalDtor() { 1732688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines Init(); 1733688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 1734688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines clang::DeclContext *DC = mCtx.getTranslationUnitDecl(); 1735688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines clang::SourceLocation loc; 1736688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 17373f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines llvm::StringRef SR(".rs.dtor"); 17383f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines clang::IdentifierInfo &II = mCtx.Idents.get(SR); 17393f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines clang::DeclarationName N(&II); 17403f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines clang::FunctionProtoType::ExtProtoInfo EPI; 174182d7288620fade361dd8f7408b5db54a55c2c794Stephen Hines clang::QualType T = mCtx.getFunctionType(mCtx.VoidTy, 174282d7288620fade361dd8f7408b5db54a55c2c794Stephen Hines llvm::ArrayRef<clang::QualType>(), EPI); 17435abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes clang::FunctionDecl *FD = nullptr; 17443f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines 1745688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines // Generate rsClearObject() call chains for every global variable 1746688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines // (whether static or extern). 1747579e4f481774275980d6e3fbb7978c674da6d302Yang Ni std::vector<clang::Stmt *> StmtList; 1748688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines for (clang::DeclContext::decl_iterator I = DC->decls_begin(), 1749688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines E = DC->decls_end(); I != E; I++) { 1750688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines clang::VarDecl *VD = llvm::dyn_cast<clang::VarDecl>(*I); 1751688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines if (VD) { 175265f23ed862e1a1e16477ba740f295ff4a83ac822David Gross if (CountRSObjectTypes(VD->getType().getTypePtr())) { 17533f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines if (!FD) { 17543f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines // Only create FD if we are going to use it. 17555abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes FD = clang::FunctionDecl::Create(mCtx, DC, loc, loc, N, T, nullptr, 17564b3f3bada7155de983e7d92fa8b20091629b3bb3Stephen Hines clang::SC_None); 17573f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines } 1758cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar // Mark VD as used. It might be unused, except for the destructor. 1759cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar // 'markUsed' has side-effects that are caused only if VD is not already 1760cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar // used. Hence no need for an extra check here. 1761cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar VD->markUsed(mCtx); 17623f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines // Make sure to create any helpers within the function's DeclContext, 17633f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines // not the one associated with the global translation unit. 17643f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines clang::Stmt *RSClearObjectCall = Scope::ClearRSObject(VD, FD); 1765688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines StmtList.push_back(RSClearObjectCall); 1766688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines } 1767688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines } 1768688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines } 1769688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 1770688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines // Nothing needs to be destroyed, so don't emit a dtor. 1771688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines if (StmtList.empty()) { 17725abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 1773688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines } 1774688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 1775688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines clang::CompoundStmt *CS = BuildCompoundStmt(mCtx, StmtList, loc); 1776688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 1777688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines FD->setBody(CS); 1778c8f5b2dad5c4ad2294d180b562d486342f29fb55I-Jui (Ray) Sung // We need some way to tell if this FD is generated by slang 1779c8f5b2dad5c4ad2294d180b562d486342f29fb55I-Jui (Ray) Sung FD->setImplicit(); 1780688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 1781688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines return FD; 1782688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines} 1783688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 178465f23ed862e1a1e16477ba740f295ff4a83ac822David Grossbool HasRSObjectType(const clang::Type *T) { 178565f23ed862e1a1e16477ba740f295ff4a83ac822David Gross return CountRSObjectTypes(T) != 0; 178665f23ed862e1a1e16477ba740f295ff4a83ac822David Gross} 178765f23ed862e1a1e16477ba740f295ff4a83ac822David Gross 1788e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 1789