slang_rs_object_ref_count.cpp revision 579e4f481774275980d6e3fbb7978c674da6d302
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" 234b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "clang/AST/Stmt.h" 244b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "clang/AST/StmtVisitor.h" 254b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 266e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h" 278024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang.h" 28292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines#include "slang_rs_ast_replace.h" 294b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "slang_rs_export_type.h" 304b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 31e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang { 324b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 33474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet/* Even though those two arrays are of size DataTypeMax, only entries that 34474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet * correspond to object types will be set. 35474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet */ 36474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouilletclang::FunctionDecl * 37cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc BrouilletRSObjectRefCount::RSSetObjectFD[DataTypeMax]; 38474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouilletclang::FunctionDecl * 39cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc BrouilletRSObjectRefCount::RSClearObjectFD[DataTypeMax]; 401bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 41f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesvoid RSObjectRefCount::GetRSRefCountingFunctions(clang::ASTContext &C) { 42cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet for (unsigned i = 0; i < DataTypeMax; i++) { 435abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes RSSetObjectFD[i] = nullptr; 445abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes RSClearObjectFD[i] = nullptr; 451bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 461bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 471bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl(); 481bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 491bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(), 501bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines E = TUDecl->decls_end(); I != E; I++) { 511bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if ((I->getKind() >= clang::Decl::firstFunction) && 521bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines (I->getKind() <= clang::Decl::lastFunction)) { 531bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::FunctionDecl *FD = static_cast<clang::FunctionDecl*>(*I); 541bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 551bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // points to RSSetObjectFD or RSClearObjectFD 561bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::FunctionDecl **RSObjectFD; 571bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 581bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if (FD->getName() == "rsSetObject") { 596e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((FD->getNumParams() == 2) && 606e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "Invalid rsSetObject function prototype (# params)"); 611bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSObjectFD = RSSetObjectFD; 621bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } else if (FD->getName() == "rsClearObject") { 636e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((FD->getNumParams() == 1) && 646e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "Invalid rsClearObject function prototype (# params)"); 651bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSObjectFD = RSClearObjectFD; 66e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines } else { 671bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines continue; 681bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 691bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 701bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines const clang::ParmVarDecl *PVD = FD->getParamDecl(0); 711bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::QualType PVT = PVD->getOriginalType(); 721bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // The first parameter must be a pointer like rs_allocation* 736e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(PVT->isPointerType() && 746e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "Invalid rs{Set,Clear}Object function prototype (pointer param)"); 751bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 761bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // The rs object type passed to the FD 771bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::QualType RST = PVT->getPointeeType(); 78cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT = RSExportPrimitiveType::GetRSSpecificType(RST.getTypePtr()); 796e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(RSExportPrimitiveType::IsRSObjectType(DT) 801bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines && "must be RS object type"); 811bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 82cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet if (DT >= 0 && DT < DataTypeMax) { 83474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet RSObjectFD[DT] = FD; 84474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet } else { 85474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet slangAssert(false && "incorrect type"); 86474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet } 871bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 881bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 891bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 901bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 914464d825c11349068f2917f9ebee86b721423f3cStephen Hinesnamespace { 924464d825c11349068f2917f9ebee86b721423f3cStephen Hines 93b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Niunsigned CountRSObjectTypes(const clang::Type *T); 94b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 95b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Niclang::Stmt *CreateSingleRSSetObject(clang::ASTContext &C, 96b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Expr *DstExpr, 97b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Expr *SrcExpr, 98b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::SourceLocation StartLoc, 99b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::SourceLocation Loc); 100b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 101292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines// This function constructs a new CompoundStmt from the input StmtList. 102b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Niclang::CompoundStmt* BuildCompoundStmt(clang::ASTContext &C, 103579e4f481774275980d6e3fbb7978c674da6d302Yang Ni std::vector<clang::Stmt*> &StmtList, clang::SourceLocation Loc) { 104d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines unsigned NewStmtCount = StmtList.size(); 105292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines unsigned CompoundStmtCount = 0; 1061bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 107292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines clang::Stmt **CompoundStmtList; 108292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines CompoundStmtList = new clang::Stmt*[NewStmtCount]; 1091bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 110579e4f481774275980d6e3fbb7978c674da6d302Yang Ni std::vector<clang::Stmt*>::const_iterator I = StmtList.begin(); 111579e4f481774275980d6e3fbb7978c674da6d302Yang Ni std::vector<clang::Stmt*>::const_iterator E = StmtList.end(); 112292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines for ( ; I != E; I++) { 113292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines CompoundStmtList[CompoundStmtCount++] = *I; 1141bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 115292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines slangAssert(CompoundStmtCount == NewStmtCount); 1161bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 11723c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines clang::CompoundStmt *CS = new(C) clang::CompoundStmt( 11823c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines C, llvm::makeArrayRef(CompoundStmtList, CompoundStmtCount), Loc, Loc); 1191bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 120292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines delete [] CompoundStmtList; 1211bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 122292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return CS; 1231bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 1241bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 125b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Nivoid AppendAfterStmt(clang::ASTContext &C, 126b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::CompoundStmt *CS, 127b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Stmt *S, 128b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni std::list<clang::Stmt*> &StmtList) { 129292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines slangAssert(CS); 130e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CompoundStmt::body_iterator bI = CS->body_begin(); 131292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines clang::CompoundStmt::body_iterator bE = CS->body_end(); 132292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines clang::Stmt **UpdatedStmtList = 133292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines new clang::Stmt*[CS->size() + StmtList.size()]; 134e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 135e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines unsigned UpdatedStmtCount = 0; 136e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines unsigned Once = 0; 137292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines for ( ; bI != bE; bI++) { 138292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if (!S && ((*bI)->getStmtClass() == clang::Stmt::ReturnStmtClass)) { 139292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // If we come across a return here, we don't have anything we can 140292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // reasonably replace. We should have already inserted our destructor 141292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // code in the proper spot, so we just clean up and return. 142292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines delete [] UpdatedStmtList; 143292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 144292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return; 145e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 146e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 147292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines UpdatedStmtList[UpdatedStmtCount++] = *bI; 148c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 149292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if ((*bI == S) && !Once) { 150292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines Once++; 151292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*>::const_iterator I = StmtList.begin(); 152292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*>::const_iterator E = StmtList.end(); 153292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines for ( ; I != E; I++) { 154292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines UpdatedStmtList[UpdatedStmtCount++] = *I; 155292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 156292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 157c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 158292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines slangAssert(Once <= 1); 159c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 1605abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes // When S is nullptr, we are appending to the end of the CompoundStmt. 161292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if (!S) { 162292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines slangAssert(Once == 0); 163292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*>::const_iterator I = StmtList.begin(); 164292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*>::const_iterator E = StmtList.end(); 165292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines for ( ; I != E; I++) { 166292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines UpdatedStmtList[UpdatedStmtCount++] = *I; 167c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 168c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 169c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 17098cfae456bb1831336bce2b21979a04e2e31fed4Pirama Arumuga Nainar CS->setStmts(C, llvm::makeArrayRef(UpdatedStmtList, UpdatedStmtCount)); 171c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 172c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines delete [] UpdatedStmtList; 173c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines} 174c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 175b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni// This class visits a compound statement and collects a list of all the exiting 176b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni// statements, such as any return statement in any sub-block, and any 177b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni// break/continue statement that would resume outside the current scope. 178b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni// We do not handle the case for goto statements that leave a local scope. 1794464d825c11349068f2917f9ebee86b721423f3cStephen Hinesclass DestructorVisitor : public clang::StmtVisitor<DestructorVisitor> { 1804464d825c11349068f2917f9ebee86b721423f3cStephen Hines private: 181292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // The loop depth of the currently visited node. 182292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines int mLoopDepth; 183292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 184292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // The switch statement depth of the currently visited node. 185292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // Note that this is tracked separately from the loop depth because 186292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // SwitchStmt-contained ContinueStmt's should have destructors for the 187292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // corresponding loop scope. 188292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines int mSwitchDepth; 189292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 190b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // Output of the visitor: the statements that should be replaced by compound 191b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // statements, each of which contains rsClearObject() calls followed by the 192b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // original statement. 193b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni std::vector<clang::Stmt*> mExitingStmts; 194a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines 1954464d825c11349068f2917f9ebee86b721423f3cStephen Hines public: 196b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni DestructorVisitor() : mLoopDepth(0), mSwitchDepth(0) {} 197292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 198b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni const std::vector<clang::Stmt*>& getExitingStmts() const { 199b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni return mExitingStmts; 200292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 201292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 2024464d825c11349068f2917f9ebee86b721423f3cStephen Hines void VisitStmt(clang::Stmt *S); 203292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitBreakStmt(clang::BreakStmt *BS); 204292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitContinueStmt(clang::ContinueStmt *CS); 205292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitDoStmt(clang::DoStmt *DS); 206292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitForStmt(clang::ForStmt *FS); 207292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitReturnStmt(clang::ReturnStmt *RS); 208292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitSwitchStmt(clang::SwitchStmt *SS); 209292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitWhileStmt(clang::WhileStmt *WS); 2104464d825c11349068f2917f9ebee86b721423f3cStephen Hines}; 2114464d825c11349068f2917f9ebee86b721423f3cStephen Hines 2124464d825c11349068f2917f9ebee86b721423f3cStephen Hinesvoid DestructorVisitor::VisitStmt(clang::Stmt *S) { 21356916bec2734a6059e1d0f58959514c825c746f7Yang Ni for (clang::Stmt* Child : S->children()) { 21456916bec2734a6059e1d0f58959514c825c746f7Yang Ni if (Child) { 2154464d825c11349068f2917f9ebee86b721423f3cStephen Hines Visit(Child); 2164464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 2174464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 2184464d825c11349068f2917f9ebee86b721423f3cStephen Hines} 2194464d825c11349068f2917f9ebee86b721423f3cStephen Hines 220292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitBreakStmt(clang::BreakStmt *BS) { 221292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(BS); 222292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if ((mLoopDepth == 0) && (mSwitchDepth == 0)) { 223b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni mExitingStmts.push_back(BS); 224292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 225292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 226292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 227292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitContinueStmt(clang::ContinueStmt *CS) { 228292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(CS); 229292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if (mLoopDepth == 0) { 230292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // Switch statements can have nested continues. 231b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni mExitingStmts.push_back(CS); 232292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 233292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 234292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 235292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitDoStmt(clang::DoStmt *DS) { 236292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth++; 237292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(DS); 238292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth--; 239292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 240292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 241292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitForStmt(clang::ForStmt *FS) { 242292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth++; 243292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(FS); 244292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth--; 245292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 246292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 247292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitReturnStmt(clang::ReturnStmt *RS) { 248b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni mExitingStmts.push_back(RS); 249292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 250292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 251292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitSwitchStmt(clang::SwitchStmt *SS) { 252292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mSwitchDepth++; 253292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(SS); 254292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mSwitchDepth--; 255292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 256292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 257292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitWhileStmt(clang::WhileStmt *WS) { 258292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth++; 259292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(WS); 260292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth--; 261292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 262292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 263f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesclang::Expr *ClearSingleRSObject(clang::ASTContext &C, 264f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSVar, 265f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc) { 266f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(RefRSVar); 267f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *T = RefRSVar->getType().getTypePtr(); 268f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(!T->isArrayType() && 269f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "Should not be destroying arrays with this function"); 270f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 271f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::FunctionDecl *ClearObjectFD = RSObjectRefCount::GetRSClearObjectFD(T); 2725abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes slangAssert((ClearObjectFD != nullptr) && 273f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "rsClearObject doesn't cover all RS object types"); 274f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 275f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::QualType ClearObjectFDType = ClearObjectFD->getType(); 276f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::QualType ClearObjectFDArgType = 277f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD->getParamDecl(0)->getOriginalType(); 278f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 279f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Example destructor for "rs_font localFont;" 280f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // 281f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (CallExpr 'void' 282f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (ImplicitCastExpr 'void (*)(rs_font *)' <FunctionToPointerDecay> 283f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (DeclRefExpr 'void (rs_font *)' FunctionDecl='rsClearObject')) 284f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (UnaryOperator 'rs_font *' prefix '&' 285f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (DeclRefExpr 'rs_font':'rs_font' Var='localFont'))) 286f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 287f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Get address of targeted RS object 288f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *AddrRefRSVar = 289f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::UnaryOperator(RefRSVar, 290f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::UO_AddrOf, 291f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFDArgType, 292be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 293be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 294f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 295f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 296f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSClearObjectFD = 297f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclRefExpr::Create(C, 298be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 2990444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 300f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD, 301e2597ac5a8ba7a45a1d5f342973cd43a3a1932cfShih-wei Liao false, 302f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD->getLocation(), 303be27482cdeaf08576bc39b72a15d35d13014a636Logan ClearObjectFDType, 304be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 3055abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr); 306f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 307f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RSClearObjectFP = 308f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ImplicitCastExpr::Create(C, 309f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines C.getPointerType(ClearObjectFDType), 310f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::CK_FunctionToPointerDecay, 311f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSClearObjectFD, 3125abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 313f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::VK_RValue); 31403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 3151dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines llvm::SmallVector<clang::Expr*, 1> ArgList; 3161dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines ArgList.push_back(AddrRefRSVar); 3171dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines 318f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::CallExpr *RSClearObjectCall = 319f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::CallExpr(C, 320f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectFP, 3211dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines ArgList, 322f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD->getCallResultType(), 323be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 324f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 325f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 326f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return RSClearObjectCall; 327f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines} 328f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 329f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic int ArrayDim(const clang::Type *T) { 33003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (!T || !T->isArrayType()) { 33103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return 0; 33203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 33303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 33403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines const clang::ConstantArrayType *CAT = 33503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines static_cast<const clang::ConstantArrayType *>(T); 3369d2c0fa6490e09b3ff5603796bce42d97788e5c8Stephen Hines return static_cast<int>(CAT->getSize().getSExtValue()); 33703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines} 33803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 339b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Niclang::Stmt *ClearStructRSObject( 340f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ASTContext &C, 341f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC, 342f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSStruct, 343d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines clang::SourceLocation StartLoc, 344f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc); 345f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 346b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Niclang::Stmt *ClearArrayRSObject( 347f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ASTContext &C, 348f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC, 349f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSArr, 350cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc, 351f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc) { 352f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *BaseType = RefRSArr->getType().getTypePtr(); 353f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(BaseType->isArrayType()); 354f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 355f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines int NumArrayElements = ArrayDim(BaseType); 356f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Actually extract out the base RS object type for use later 357f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines BaseType = BaseType->getArrayElementTypeNoTypeQual(); 35803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 35903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (NumArrayElements <= 0) { 3605abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 36103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 36203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 36303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Example destructor loop for "rs_font fontArr[10];" 36403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // 365cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (ForStmt 366cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (DeclStmt 367cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (VarDecl used rsIntIter 'int' cinit 368cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (IntegerLiteral 'int' 0))) 369cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (BinaryOperator 'int' '<' 370cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (ImplicitCastExpr int LValueToRValue 37103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter')) 372cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (IntegerLiteral 'int' 10) 373cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // nullptr << CondVar >> 374cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (UnaryOperator 'int' postfix '++' 375cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (DeclRefExpr 'int' Var='rsIntIter')) 376cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (CallExpr 'void' 377cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (ImplicitCastExpr 'void (*)(rs_font *)' <FunctionToPointerDecay> 378cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (DeclRefExpr 'void (rs_font *)' FunctionDecl='rsClearObject')) 379cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (UnaryOperator 'rs_font *' prefix '&' 380cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (ArraySubscriptExpr 'rs_font':'rs_font' 381cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (ImplicitCastExpr 'rs_font *' <ArrayToPointerDecay> 382cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (DeclRefExpr 'rs_font [10]' Var='fontArr')) 383cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (DeclRefExpr 'int' Var='rsIntIter')))))) 38403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 38503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Create helper variable for iterating through elements 386cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines static unsigned sIterCounter = 0; 387cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines std::stringstream UniqueIterName; 388cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines UniqueIterName << "rsIntIter" << sIterCounter++; 389cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::IdentifierInfo *II = &C.Idents.get(UniqueIterName.str()); 39003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VarDecl *IIVD = 39103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VarDecl::Create(C, 392f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 393cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, 39403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 395cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines II, 39603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 39703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.getTrivialTypeSourceInfo(C.IntTy), 39803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::SC_None); 399cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar // Mark "rsIntIter" as used 400cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar IIVD->markUsed(C); 40103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 40203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Form the actual destructor loop 40303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // for (Init; Cond; Inc) 40403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // RSClearObjectCall; 40503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 406cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // Init -> "int rsIntIter = 0" 407cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, 408cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines llvm::APInt(C.getTypeSize(C.IntTy), 0), C.IntTy, Loc); 409cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines IIVD->setInit(Int0); 410cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines 411cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::Decl *IID = (clang::Decl *)IIVD; 412cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::DeclGroupRef DGR = clang::DeclGroupRef::Create(C, &IID, 1); 413cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::Stmt *Init = new(C) clang::DeclStmt(DGR, Loc, Loc); 414cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines 415cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // Cond -> "rsIntIter < NumArrayElements" 416cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::DeclRefExpr *RefrsIntIterLValue = 41703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclRefExpr::Create(C, 418be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 4190444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 42003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines IIVD, 421e2597ac5a8ba7a45a1d5f342973cd43a3a1932cfShih-wei Liao false, 42203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 423be27482cdeaf08576bc39b72a15d35d13014a636Logan C.IntTy, 424cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::VK_LValue, 4255abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr); 42603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 427cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::Expr *RefrsIntIterRValue = 428cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::ImplicitCastExpr::Create(C, 429cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines RefrsIntIterLValue->getType(), 430cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::CK_LValueToRValue, 431cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines RefrsIntIterLValue, 432cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines nullptr, 433cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::VK_RValue); 43403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 43503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *NumArrayElementsExpr = clang::IntegerLiteral::Create(C, 43603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), NumArrayElements), C.IntTy, Loc); 43703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 43803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BinaryOperator *Cond = 439cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines new(C) clang::BinaryOperator(RefrsIntIterRValue, 44003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NumArrayElementsExpr, 44103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BO_LT, 44203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 443be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 444be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 44523c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines Loc, 44623c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines false); 44703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 44803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Inc -> "rsIntIter++" 44903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::UnaryOperator *Inc = 450cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines new(C) clang::UnaryOperator(RefrsIntIterLValue, 45103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::UO_PostInc, 45203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 453be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 454be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 45503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 45603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 45703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Body -> "rsClearObject(&VD[rsIntIter]);" 45803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Destructor loop operates on individual array elements 45903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 460f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSArrPtr = 46103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::ImplicitCastExpr::Create(C, 462f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines C.getPointerType(BaseType->getCanonicalTypeInternal()), 46303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::CK_ArrayToPointerDecay, 464f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSArr, 4655abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 46603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VK_RValue); 46703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 468f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSArrPtrSubscript = 469f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::ArraySubscriptExpr(RefRSArrPtr, 470cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines RefrsIntIterRValue, 471f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines BaseType->getCanonicalTypeInternal(), 472be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 473be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 474f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 47503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 476cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT = RSExportPrimitiveType::GetRSSpecificType(BaseType); 477f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 4785abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes clang::Stmt *RSClearObjectCall = nullptr; 479f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (BaseType->isArrayType()) { 480f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectCall = 481cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao ClearArrayRSObject(C, DC, RefRSArrPtrSubscript, StartLoc, Loc); 482cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet } else if (DT == DataTypeUnknown) { 483f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectCall = 484cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao ClearStructRSObject(C, DC, RefRSArrPtrSubscript, StartLoc, Loc); 485f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 486f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectCall = ClearSingleRSObject(C, RefRSArrPtrSubscript, Loc); 487f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 48803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 48903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::ForStmt *DestructorLoop = 49003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::ForStmt(C, 49103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Init, 49203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Cond, 4935abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, // no condVar 49403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Inc, 49503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines RSClearObjectCall, 49603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 49703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 49803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 49903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 500cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines return DestructorLoop; 50103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines} 50203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 503b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Niunsigned CountRSObjectTypes(const clang::Type *T) { 504f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(T); 505f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines unsigned RSObjectCount = 0; 506f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 507f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (T->isArrayType()) { 50865f23ed862e1a1e16477ba740f295ff4a83ac822David Gross return CountRSObjectTypes(T->getArrayElementTypeNoTypeQual()); 509f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 510f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 511cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT = RSExportPrimitiveType::GetRSSpecificType(T); 512cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet if (DT != DataTypeUnknown) { 513f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return (RSExportPrimitiveType::IsRSObjectType(DT) ? 1 : 0); 514f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 515f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 516d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines if (T->isUnionType()) { 517d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines clang::RecordDecl *RD = T->getAsUnionType()->getDecl(); 518d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines RD = RD->getDefinition(); 519d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 520d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines FE = RD->field_end(); 521d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines FI != FE; 522d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines FI++) { 523d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines const clang::FieldDecl *FD = *FI; 524d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 52565f23ed862e1a1e16477ba740f295ff4a83ac822David Gross if (CountRSObjectTypes(FT)) { 52678e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines slangAssert(false && "can't have unions with RS object types!"); 527d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines return 0; 528d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines } 529d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines } 530d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines } 531d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines 532f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (!T->isStructureType()) { 533f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return 0; 534f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 535f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 536f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::RecordDecl *RD = T->getAsStructureType()->getDecl(); 537f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RD = RD->getDefinition(); 538f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 539f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FE = RD->field_end(); 540f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI != FE; 541f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI++) { 542f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::FieldDecl *FD = *FI; 543f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 54465f23ed862e1a1e16477ba740f295ff4a83ac822David Gross if (CountRSObjectTypes(FT)) { 545f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Sub-structs should only count once (as should arrays, etc.) 546f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectCount++; 547f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 548f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 549f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 550f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return RSObjectCount; 551f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines} 552f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 553b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Niclang::Stmt *ClearStructRSObject( 554f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ASTContext &C, 555f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC, 556f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSStruct, 557cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc, 558f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc) { 559f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *BaseType = RefRSStruct->getType().getTypePtr(); 560f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 561f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(!BaseType->isArrayType()); 562f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 563f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Structs should show up as unknown primitive types 5649be9360d8e02b52ed669afbd69f9becb575c3f0dAlex Sakhartchouk slangAssert(RSExportPrimitiveType::GetRSSpecificType(BaseType) == 565cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataTypeUnknown); 566f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 56765f23ed862e1a1e16477ba740f295ff4a83ac822David Gross unsigned FieldsToDestroy = CountRSObjectTypes(BaseType); 568b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines slangAssert(FieldsToDestroy != 0); 569f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 570f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines unsigned StmtCount = 0; 571f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Stmt **StmtArray = new clang::Stmt*[FieldsToDestroy]; 5722bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines for (unsigned i = 0; i < FieldsToDestroy; i++) { 5735abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes StmtArray[i] = nullptr; 5742bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 575f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 576f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Populate StmtArray by creating a destructor for each RS object field 577f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::RecordDecl *RD = BaseType->getAsStructureType()->getDecl(); 578f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RD = RD->getDefinition(); 579f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 580f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FE = RD->field_end(); 581f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI != FE; 582f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI++) { 583f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // We just look through all field declarations to see if we find a 584f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // declaration for an RS object type (or an array of one). 585f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool IsArrayType = false; 586f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::FieldDecl *FD = *FI; 587f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 588f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *OrigType = FT; 589f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines while (FT && FT->isArrayType()) { 590f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 591f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines IsArrayType = true; 592f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 593f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 594cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar // Pass a DeclarationNameInfo with a valid DeclName, since name equality 595cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar // gets asserted during CodeGen. 596cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar clang::DeclarationNameInfo FDDeclNameInfo(FD->getDeclName(), 597cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar FD->getLocation()); 598cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar 599f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (RSExportPrimitiveType::IsRSObjectType(FT)) { 600f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair FoundDecl = 601f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair::make(FD, clang::AS_none); 602f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr *RSObjectMember = 603f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr::Create(C, 604f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSStruct, 605f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines false, 6060b7545898dcfe2979f2c13afd12d276fc736412dStephen Hines clang::SourceLocation(), 607be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 6080444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 609f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FD, 610f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FoundDecl, 611cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar FDDeclNameInfo, 6125abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 613be27482cdeaf08576bc39b72a15d35d13014a636Logan OrigType->getCanonicalTypeInternal(), 614be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 615be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary); 616f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 617f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(StmtCount < FieldsToDestroy); 618f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 619f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (IsArrayType) { 620f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearArrayRSObject(C, 621f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 622f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 623cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, 624f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 625f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 626f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearSingleRSObject(C, 627f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 628f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 629f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 63065f23ed862e1a1e16477ba740f295ff4a83ac822David Gross } else if (FT->isStructureType() && CountRSObjectTypes(FT)) { 631f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // In this case, we have a nested struct. We may not end up filling all 632f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // of the spaces in StmtArray (sub-structs should handle themselves 633f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // with separate compound statements). 634f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair FoundDecl = 635f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair::make(FD, clang::AS_none); 636f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr *RSObjectMember = 637f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr::Create(C, 638f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSStruct, 639f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines false, 6400b7545898dcfe2979f2c13afd12d276fc736412dStephen Hines clang::SourceLocation(), 641be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 6420444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 643f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FD, 644f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FoundDecl, 645f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclarationNameInfo(), 6465abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 647be27482cdeaf08576bc39b72a15d35d13014a636Logan OrigType->getCanonicalTypeInternal(), 648be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 649be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary); 650f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 651f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (IsArrayType) { 652f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearArrayRSObject(C, 653f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 654f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 655cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, 656f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 657f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 658f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearStructRSObject(C, 659f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 660f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 661cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, 662f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 663f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 664f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 665f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 666f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 667f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(StmtCount > 0); 66823c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines clang::CompoundStmt *CS = new(C) clang::CompoundStmt( 66923c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines C, llvm::makeArrayRef(StmtArray, StmtCount), Loc, Loc); 670f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 671f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines delete [] StmtArray; 672f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 673f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return CS; 674f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines} 675f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 676b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Niclang::Stmt *CreateSingleRSSetObject(clang::ASTContext &C, 677b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Expr *DstExpr, 678b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Expr *SrcExpr, 679b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::SourceLocation StartLoc, 680b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::SourceLocation Loc) { 6812bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *T = DstExpr->getType().getTypePtr(); 6822bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::FunctionDecl *SetObjectFD = RSObjectRefCount::GetRSSetObjectFD(T); 6835abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes slangAssert((SetObjectFD != nullptr) && 6846e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "rsSetObject doesn't cover all RS object types"); 685c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 686c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType SetObjectFDType = SetObjectFD->getType(); 687c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType SetObjectFDArgType[2]; 688c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDArgType[0] = SetObjectFD->getParamDecl(0)->getOriginalType(); 689c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDArgType[1] = SetObjectFD->getParamDecl(1)->getOriginalType(); 690c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 691c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Expr *RefRSSetObjectFD = 692c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::DeclRefExpr::Create(C, 693be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 6940444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 695c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFD, 696e2597ac5a8ba7a45a1d5f342973cd43a3a1932cfShih-wei Liao false, 697c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines Loc, 698be27482cdeaf08576bc39b72a15d35d13014a636Logan SetObjectFDType, 699be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 7005abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr); 701c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 702c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Expr *RSSetObjectFP = 703c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::ImplicitCastExpr::Create(C, 704c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines C.getPointerType(SetObjectFDType), 705c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::CK_FunctionToPointerDecay, 706c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RefRSSetObjectFD, 7075abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 708c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::VK_RValue); 709c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 7101dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines llvm::SmallVector<clang::Expr*, 2> ArgList; 7111dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines ArgList.push_back(new(C) clang::UnaryOperator(DstExpr, 7121dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines clang::UO_AddrOf, 7131dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines SetObjectFDArgType[0], 7141dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines clang::VK_RValue, 7151dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines clang::OK_Ordinary, 7161dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines Loc)); 7171dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines ArgList.push_back(SrcExpr); 718c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 719c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::CallExpr *RSSetObjectCall = 720c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines new(C) clang::CallExpr(C, 721c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RSSetObjectFP, 722c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines ArgList, 723c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFD->getCallResultType(), 724be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 725c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines Loc); 726c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 7272bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return RSSetObjectCall; 7282bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines} 7292bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 730b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Niclang::Stmt *CreateStructRSSetObject(clang::ASTContext &C, 731b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Expr *LHS, 732b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Expr *RHS, 733b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::SourceLocation StartLoc, 734b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::SourceLocation Loc); 7352bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 736246fa17206bf78c59a64b2f7d98a6716d5345b81Al Sutton/*static clang::Stmt *CreateArrayRSSetObject(clang::ASTContext &C, 7372bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *DstArr, 7382bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *SrcArr, 739cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc, 7402bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SourceLocation Loc) { 7415abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes clang::DeclContext *DC = nullptr; 7422bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *BaseType = DstArr->getType().getTypePtr(); 7432bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(BaseType->isArrayType()); 7442bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7452bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines int NumArrayElements = ArrayDim(BaseType); 7462bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Actually extract out the base RS object type for use later 7472bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines BaseType = BaseType->getArrayElementTypeNoTypeQual(); 7482bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7495abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes clang::Stmt *StmtArray[2] = {nullptr}; 7502bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines int StmtCtr = 0; 7512bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7522bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (NumArrayElements <= 0) { 7535abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 7542bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 7552bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7562bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Create helper variable for iterating through elements 7572bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::IdentifierInfo& II = C.Idents.get("rsIntIter"); 7582bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VarDecl *IIVD = 7592bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VarDecl::Create(C, 7602bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines DC, 761cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, 7622bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 7632bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines &II, 7642bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 7652bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.getTrivialTypeSourceInfo(C.IntTy), 7662bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SC_None, 7672bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SC_None); 7682bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Decl *IID = (clang::Decl *)IIVD; 7692bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7702bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclGroupRef DGR = clang::DeclGroupRef::Create(C, &IID, 1); 7712bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCtr++] = new(C) clang::DeclStmt(DGR, Loc, Loc); 7722bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7732bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Form the actual loop 7742bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // for (Init; Cond; Inc) 7752bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // RSSetObjectCall; 7762bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7772bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Init -> "rsIntIter = 0" 7782bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclRefExpr *RefrsIntIter = 7792bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclRefExpr::Create(C, 780be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 7812bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines IIVD, 7822bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 783be27482cdeaf08576bc39b72a15d35d13014a636Logan C.IntTy, 784be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 7855abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr); 7862bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7872bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, 7882bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), 0), C.IntTy, Loc); 7892bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7902bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BinaryOperator *Init = 7912bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 7922bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Int0, 7932bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BO_Assign, 7942bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 795be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 796be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 7972bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 7982bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7992bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Cond -> "rsIntIter < NumArrayElements" 8002bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *NumArrayElementsExpr = clang::IntegerLiteral::Create(C, 8012bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), NumArrayElements), C.IntTy, Loc); 8022bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8032bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BinaryOperator *Cond = 8042bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 8052bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NumArrayElementsExpr, 8062bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BO_LT, 8072bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 808be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 809be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 8102bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 8112bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8122bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Inc -> "rsIntIter++" 8132bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::UnaryOperator *Inc = 8142bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::UnaryOperator(RefrsIntIter, 8152bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::UO_PostInc, 8162bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 817be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 818be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 8192bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 8202bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8212bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Body -> "rsSetObject(&Dst[rsIntIter], Src[rsIntIter]);" 8222bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Loop operates on individual array elements 8232bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8242bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *DstArrPtr = 8252bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ImplicitCastExpr::Create(C, 8262bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.getPointerType(BaseType->getCanonicalTypeInternal()), 8272bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::CK_ArrayToPointerDecay, 8282bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines DstArr, 8295abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 8302bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VK_RValue); 8312bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8322bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *DstArrPtrSubscript = 8332bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::ArraySubscriptExpr(DstArrPtr, 8342bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RefrsIntIter, 8352bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines BaseType->getCanonicalTypeInternal(), 836be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 837be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 8382bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 8392bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8402bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *SrcArrPtr = 8412bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ImplicitCastExpr::Create(C, 8422bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.getPointerType(BaseType->getCanonicalTypeInternal()), 8432bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::CK_ArrayToPointerDecay, 8442bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines SrcArr, 8455abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 8462bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VK_RValue); 8472bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8482bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *SrcArrPtrSubscript = 8492bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::ArraySubscriptExpr(SrcArrPtr, 8502bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RefrsIntIter, 8512bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines BaseType->getCanonicalTypeInternal(), 852be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 853be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 8542bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 8552bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 856cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT = RSExportPrimitiveType::GetRSSpecificType(BaseType); 8572bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8585abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes clang::Stmt *RSSetObjectCall = nullptr; 8592bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (BaseType->isArrayType()) { 860d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines RSSetObjectCall = CreateArrayRSSetObject(C, DstArrPtrSubscript, 861cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao SrcArrPtrSubscript, 862cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, Loc); 863cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet } else if (DT == DataTypeUnknown) { 864d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines RSSetObjectCall = CreateStructRSSetObject(C, DstArrPtrSubscript, 865cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao SrcArrPtrSubscript, 866cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, Loc); 8672bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else { 868d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines RSSetObjectCall = CreateSingleRSSetObject(C, DstArrPtrSubscript, 869cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao SrcArrPtrSubscript, 870cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, Loc); 8712bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 8722bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8732bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ForStmt *DestructorLoop = 8742bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::ForStmt(C, 8752bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Init, 8762bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Cond, 8775abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, // no condVar 8782bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Inc, 8792bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSSetObjectCall, 8802bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 8812bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 8822bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 8832bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8842bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCtr++] = DestructorLoop; 8852bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(StmtCtr == 2); 8862bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8872bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::CompoundStmt *CS = 8882bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::CompoundStmt(C, StmtArray, StmtCtr, Loc, Loc); 8892bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8902bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return CS; 891246fa17206bf78c59a64b2f7d98a6716d5345b81Al Sutton} */ 8922bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 893b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Niclang::Stmt *CreateStructRSSetObject(clang::ASTContext &C, 894b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Expr *LHS, 895b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Expr *RHS, 896b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::SourceLocation StartLoc, 897b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::SourceLocation Loc) { 8982bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::QualType QT = LHS->getType(); 8992bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *T = QT.getTypePtr(); 9002bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(T->isStructureType()); 9012bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(!RSExportPrimitiveType::IsRSObjectType(T)); 9022bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9032bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Keep an extra slot for the original copy (memcpy) 90465f23ed862e1a1e16477ba740f295ff4a83ac822David Gross unsigned FieldsToSet = CountRSObjectTypes(T) + 1; 9052bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9062bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines unsigned StmtCount = 0; 9072bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Stmt **StmtArray = new clang::Stmt*[FieldsToSet]; 9082bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines for (unsigned i = 0; i < FieldsToSet; i++) { 9095abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes StmtArray[i] = nullptr; 9102bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 9112bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9122bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::RecordDecl *RD = T->getAsStructureType()->getDecl(); 9132bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RD = RD->getDefinition(); 9142bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 9152bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FE = RD->field_end(); 9162bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FI != FE; 9172bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FI++) { 9182bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines bool IsArrayType = false; 9192bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::FieldDecl *FD = *FI; 9202bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 9212bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *OrigType = FT; 9222bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 92365f23ed862e1a1e16477ba740f295ff4a83ac822David Gross if (!CountRSObjectTypes(FT)) { 9242bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Skip to next if we don't have any viable RS object types 9252bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines continue; 9262bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 9272bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9282bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclAccessPair FoundDecl = 9292bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclAccessPair::make(FD, clang::AS_none); 9302bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr *DstMember = 9312bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr::Create(C, 9322bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines LHS, 9332bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines false, 9340b7545898dcfe2979f2c13afd12d276fc736412dStephen Hines clang::SourceLocation(), 935be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 9360444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 9372bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FD, 9382bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FoundDecl, 939c9344ace5050b7d5ee9a677ce996fc0b731c0830I-Jui (Ray) Sung clang::DeclarationNameInfo( 940c9344ace5050b7d5ee9a677ce996fc0b731c0830I-Jui (Ray) Sung FD->getDeclName(), 941c9344ace5050b7d5ee9a677ce996fc0b731c0830I-Jui (Ray) Sung clang::SourceLocation()), 9425abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 943be27482cdeaf08576bc39b72a15d35d13014a636Logan OrigType->getCanonicalTypeInternal(), 944be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 945be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary); 9462bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9472bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr *SrcMember = 9482bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr::Create(C, 9492bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RHS, 9502bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines false, 9510b7545898dcfe2979f2c13afd12d276fc736412dStephen Hines clang::SourceLocation(), 952be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 9530444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 9542bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FD, 9552bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FoundDecl, 956824b3ce35d55cc8b1f7f33874d22d328e05bd497I-Jui (Ray) Sung clang::DeclarationNameInfo( 957824b3ce35d55cc8b1f7f33874d22d328e05bd497I-Jui (Ray) Sung FD->getDeclName(), 958824b3ce35d55cc8b1f7f33874d22d328e05bd497I-Jui (Ray) Sung clang::SourceLocation()), 9595abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 960be27482cdeaf08576bc39b72a15d35d13014a636Logan OrigType->getCanonicalTypeInternal(), 961be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 962be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary); 9632bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9642bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (FT->isArrayType()) { 9652bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 9662bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines IsArrayType = true; 9672bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 9682bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 969cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT = RSExportPrimitiveType::GetRSSpecificType(FT); 9702bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9712bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (IsArrayType) { 9729207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine &DiagEngine = C.getDiagnostics(); 9739207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine.Report( 9749207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::FullSourceLoc(Loc, C.getSourceManager()), 9759207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine.getCustomDiagID( 9769207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine::Error, 9779207a2e495c8363606861e4f034504ec5c153dabLogan Chien "Arrays of RS object types within structures cannot be copied")); 9782bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // TODO(srhines): Support setting arrays of RS objects 9792bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // StmtArray[StmtCount++] = 980d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines // CreateArrayRSSetObject(C, DstMember, SrcMember, StartLoc, Loc); 981cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet } else if (DT == DataTypeUnknown) { 9822bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCount++] = 983d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines CreateStructRSSetObject(C, DstMember, SrcMember, StartLoc, Loc); 9842bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else if (RSExportPrimitiveType::IsRSObjectType(DT)) { 9852bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCount++] = 986d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines CreateSingleRSSetObject(C, DstMember, SrcMember, StartLoc, Loc); 9872bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else { 9882bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(false); 9892bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 9902bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 9912bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 992b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines slangAssert(StmtCount < FieldsToSet); 9932bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9942bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // We still need to actually do the overall struct copy. For simplicity, 9952bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // we just do a straight-up assignment (which will still preserve all 9962bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // the proper RS object reference counts). 9972bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BinaryOperator *CopyStruct = 998be27482cdeaf08576bc39b72a15d35d13014a636Logan new(C) clang::BinaryOperator(LHS, RHS, clang::BO_Assign, QT, 99923c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines clang::VK_RValue, clang::OK_Ordinary, Loc, 100023c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines false); 10012bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCount++] = CopyStruct; 10022bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 100323c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines clang::CompoundStmt *CS = new(C) clang::CompoundStmt( 100423c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines C, llvm::makeArrayRef(StmtArray, StmtCount), Loc, Loc); 10052bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10062bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines delete [] StmtArray; 10072bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10082bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return CS; 10092bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines} 10102bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10112bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines} // namespace 10122bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 1013b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Nivoid RSObjectRefCount::Scope::InsertStmt(const clang::ASTContext &C, 1014b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Stmt *NewStmt) { 1015b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni std::vector<clang::Stmt*> newBody; 1016b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni for (clang::Stmt* S1 : mCS->body()) { 1017b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni if (S1 == mCurrent) { 1018b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni newBody.push_back(NewStmt); 1019b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1020b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni newBody.push_back(S1); 1021b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 102298cfae456bb1831336bce2b21979a04e2e31fed4Pirama Arumuga Nainar mCS->setStmts(C, newBody); 1023b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni} 1024b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1025b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Nivoid RSObjectRefCount::Scope::ReplaceStmt(const clang::ASTContext &C, 1026b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Stmt *NewStmt) { 1027b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni std::vector<clang::Stmt*> newBody; 1028b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni for (clang::Stmt* S1 : mCS->body()) { 1029b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni if (S1 == mCurrent) { 1030b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni newBody.push_back(NewStmt); 1031b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } else { 1032b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni newBody.push_back(S1); 1033b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1034b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 103598cfae456bb1831336bce2b21979a04e2e31fed4Pirama Arumuga Nainar mCS->setStmts(C, newBody); 1036b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni} 1037b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1038b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Nivoid RSObjectRefCount::Scope::ReplaceExpr(const clang::ASTContext& C, 1039b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Expr* OldExpr, 1040b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Expr* NewExpr) { 1041b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni RSASTReplace R(C); 1042b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni R.ReplaceStmt(mCurrent, OldExpr, NewExpr); 1043b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni} 1044b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 10452bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesvoid RSObjectRefCount::Scope::ReplaceRSObjectAssignment( 1046d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines clang::BinaryOperator *AS) { 10472bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10482bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::QualType QT = AS->getType(); 10492bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10502bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ASTContext &C = RSObjectRefCount::GetRSSetObjectFD( 10519ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines DataTypeRSAllocation)->getASTContext(); 10522bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 1053832429f6bf4592cfc2ce58f2462f1e8ecdbaaf52Stephen Hines clang::SourceLocation Loc = AS->getExprLoc(); 10549f1d0aa55669b75a718ad2e962fc8c3d8df1a5f4Stephen Hines clang::SourceLocation StartLoc = AS->getLHS()->getExprLoc(); 10555abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes clang::Stmt *UpdatedStmt = nullptr; 10562bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10572bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (!RSExportPrimitiveType::IsRSObjectType(QT.getTypePtr())) { 10582bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // By definition, this is a struct assignment if we get here 10592bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines UpdatedStmt = 1060d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines CreateStructRSSetObject(C, AS->getLHS(), AS->getRHS(), StartLoc, Loc); 10612bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else { 10622bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines UpdatedStmt = 1063d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines CreateSingleRSSetObject(C, AS->getLHS(), AS->getRHS(), StartLoc, Loc); 10642bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 1065e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1066292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines RSASTReplace R(C); 1067292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines R.ReplaceStmt(mCS, AS, UpdatedStmt); 1068e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines} 1069e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1070e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hinesvoid RSObjectRefCount::Scope::AppendRSObjectInit( 1071e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::VarDecl *VD, 1072e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclStmt *DS, 1073cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT, 1074e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *InitExpr) { 10756e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(VD); 1076e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1077e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (!InitExpr) { 1078e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return; 1079e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 1080e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1081a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::ASTContext &C = RSObjectRefCount::GetRSSetObjectFD( 10829ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines DataTypeRSAllocation)->getASTContext(); 1083a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::SourceLocation Loc = RSObjectRefCount::GetRSSetObjectFD( 10849ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines DataTypeRSAllocation)->getLocation(); 1085cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc = RSObjectRefCount::GetRSSetObjectFD( 10869ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines DataTypeRSAllocation)->getInnerLocStart(); 1087a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines 1088cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet if (DT == DataTypeIsStruct) { 1089a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 1090a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::DeclRefExpr *RefRSVar = 1091a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::DeclRefExpr::Create(C, 1092be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 10930444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 1094a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines VD, 1095e2597ac5a8ba7a45a1d5f342973cd43a3a1932cfShih-wei Liao false, 1096a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines Loc, 1097be27482cdeaf08576bc39b72a15d35d13014a636Logan T->getCanonicalTypeInternal(), 1098be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 10995abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr); 1100a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines 1101a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::Stmt *RSSetObjectOps = 1102d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines CreateStructRSSetObject(C, RefRSVar, InitExpr, StartLoc, Loc); 1103cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // Fix for b/37363420; consider: 1104cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // 1105cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // struct foo { rs_matrix m; }; 1106cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // void bar() { 1107cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // struct foo M = {...}; 1108cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // } 1109cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // 1110cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // slang modifies that declaration with initialization to a 1111cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // declaration plus an assignment of the initialization values. 1112cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // 1113cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // void bar() { 1114cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // struct foo M = {}; 1115cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // M = {...}; // by CreateStructRSSetObject() above 1116cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // } 1117cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // 1118cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // the slang-generated statement (M = {...}) is a use of M, and we 1119cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung // need to mark M (clang::VarDecl *VD) as used. 1120cdb3b2cd64b380eabae8be265a3aa8eae30d9b46I-Jui (Ray) Sung VD->markUsed(C); 1121a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines 1122292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*> StmtList; 1123292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines StmtList.push_back(RSSetObjectOps); 1124292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines AppendAfterStmt(C, mCS, DS, StmtList); 1125f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return; 1126f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 1127f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 1128f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::FunctionDecl *SetObjectFD = RSObjectRefCount::GetRSSetObjectFD(DT); 11295abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes slangAssert((SetObjectFD != nullptr) && 11306e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "rsSetObject doesn't cover all RS object types"); 1131e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1132e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::QualType SetObjectFDType = SetObjectFD->getType(); 1133e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::QualType SetObjectFDArgType[2]; 1134e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDArgType[0] = SetObjectFD->getParamDecl(0)->getOriginalType(); 1135e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDArgType[1] = SetObjectFD->getParamDecl(1)->getOriginalType(); 1136e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1137e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *RefRSSetObjectFD = 1138e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr::Create(C, 1139be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 11400444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 1141e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFD, 1142e2597ac5a8ba7a45a1d5f342973cd43a3a1932cfShih-wei Liao false, 1143e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc, 1144be27482cdeaf08576bc39b72a15d35d13014a636Logan SetObjectFDType, 1145be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 11465abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr); 1147e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1148e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *RSSetObjectFP = 1149e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::ImplicitCastExpr::Create(C, 1150e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines C.getPointerType(SetObjectFDType), 1151e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CK_FunctionToPointerDecay, 1152e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RefRSSetObjectFD, 11535abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 1154e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::VK_RValue); 1155e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1156e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 1157e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr *RefRSVar = 1158e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr::Create(C, 1159be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 11600444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 1161e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD, 1162e2597ac5a8ba7a45a1d5f342973cd43a3a1932cfShih-wei Liao false, 1163e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc, 1164be27482cdeaf08576bc39b72a15d35d13014a636Logan T->getCanonicalTypeInternal(), 1165be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 11665abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr); 1167e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 11681dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines llvm::SmallVector<clang::Expr*, 2> ArgList; 11691dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines ArgList.push_back(new(C) clang::UnaryOperator(RefRSVar, 11701dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines clang::UO_AddrOf, 11711dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines SetObjectFDArgType[0], 11721dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines clang::VK_RValue, 11731dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines clang::OK_Ordinary, 11741dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines Loc)); 11751dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines ArgList.push_back(InitExpr); 1176e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1177e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CallExpr *RSSetObjectCall = 1178e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines new(C) clang::CallExpr(C, 1179e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSSetObjectFP, 1180e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ArgList, 1181e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFD->getCallResultType(), 1182be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1183e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc); 1184e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1185292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*> StmtList; 1186292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines StmtList.push_back(RSSetObjectCall); 1187292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines AppendAfterStmt(C, mCS, DS, StmtList); 1188c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines} 1189c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 11901bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hinesvoid RSObjectRefCount::Scope::InsertLocalVarDestructors() { 1191b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni if (mRSO.empty()) { 1192b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni return; 1193b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1194b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1195b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::DeclContext* DC = mRSO.front()->getDeclContext(); 1196b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::ASTContext& C = DC->getParentASTContext(); 1197b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::SourceManager& SM = C.getSourceManager(); 1198b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1199b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni const auto& OccursBefore = [&SM] (clang::SourceLocation L1, clang::SourceLocation L2)->bool { 1200b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni return SM.isBeforeInTranslationUnit(L1, L2); 1201b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni }; 1202b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni typedef std::map<clang::SourceLocation, clang::Stmt*, decltype(OccursBefore)> DMap; 1203b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1204b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni DMap dtors(OccursBefore); 1205b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1206b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // Create rsClearObject calls. Note the DMap entries are sorted by the SourceLocation. 1207b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni for (clang::VarDecl* VD : mRSO) { 1208b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::SourceLocation Loc = VD->getSourceRange().getBegin(); 1209b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Stmt* RSClearObjectCall = ClearRSObject(VD, DC); 1210b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni dtors.insert(std::make_pair(Loc, RSClearObjectCall)); 1211b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1212b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1213b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni DestructorVisitor Visitor; 1214b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni Visitor.Visit(mCS); 1215b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1216b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // Replace each exiting statement with a block that contains the original statement 1217b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // and added rsClearObject() calls before it. 1218b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni for (clang::Stmt* S : Visitor.getExitingStmts()) { 1219b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1220b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni const clang::SourceLocation currentLoc = S->getLocStart(); 1221b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1222b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni DMap::iterator firstDtorIter = dtors.begin(); 1223b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni DMap::iterator currentDtorIter = firstDtorIter; 1224b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni DMap::iterator lastDtorIter = dtors.end(); 1225b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1226b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni while (currentDtorIter != lastDtorIter && 1227b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni OccursBefore(currentDtorIter->first, currentLoc)) { 1228b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni currentDtorIter++; 12291bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1230b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1231b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni if (currentDtorIter == firstDtorIter) { 1232b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni continue; 1233b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1234b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1235579e4f481774275980d6e3fbb7978c674da6d302Yang Ni std::vector<clang::Stmt*> Stmts; 1236b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1237b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // Insert rsClearObject() calls for all rsObjects declared before the current statement 1238b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni for(DMap::iterator it = firstDtorIter; it != currentDtorIter; it++) { 1239b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni Stmts.push_back(it->second); 1240b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1241b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni Stmts.push_back(S); 1242b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1243b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni RSASTReplace R(C); 1244b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::CompoundStmt* CS = BuildCompoundStmt(C, Stmts, S->getLocEnd()); 1245b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni R.ReplaceStmt(mCS, S, CS); 12461bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1247b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1248b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni std::list<clang::Stmt*> Stmts; 1249b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni for(auto LocCallPair : dtors) { 1250b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni Stmts.push_back(LocCallPair.second); 1251b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1252b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni AppendAfterStmt(C, mCS, nullptr, Stmts); 12531bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 12541bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 12553f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hinesclang::Stmt *RSObjectRefCount::Scope::ClearRSObject( 12563f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines clang::VarDecl *VD, 12573f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines clang::DeclContext *DC) { 1258f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(VD); 12591bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::ASTContext &C = VD->getASTContext(); 12601bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::SourceLocation Loc = VD->getLocation(); 1261cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc = VD->getInnerLocStart(); 12621bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 126303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 12641bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Reference expr to target RS object variable 12651bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::DeclRefExpr *RefRSVar = 12661bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::DeclRefExpr::Create(C, 1267be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 12680444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 12691bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines VD, 1270e2597ac5a8ba7a45a1d5f342973cd43a3a1932cfShih-wei Liao false, 12711bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines Loc, 1272be27482cdeaf08576bc39b72a15d35d13014a636Logan T->getCanonicalTypeInternal(), 1273be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 12745abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr); 12751bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1276f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (T->isArrayType()) { 1277cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao return ClearArrayRSObject(C, DC, RefRSVar, StartLoc, Loc); 1278f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 12791bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1280cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT = RSExportPrimitiveType::GetRSSpecificType(T); 12811bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1282cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet if (DT == DataTypeUnknown || 1283cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DT == DataTypeIsStruct) { 1284cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao return ClearStructRSObject(C, DC, RefRSVar, StartLoc, Loc); 1285f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 12861bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1287f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert((RSExportPrimitiveType::IsRSObjectType(DT)) && 1288f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "Should be RS object"); 12891bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1290f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return ClearSingleRSObject(C, RefRSVar, Loc); 12911bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 12921bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1293e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hinesbool RSObjectRefCount::InitializeRSObject(clang::VarDecl *VD, 1294cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType *DT, 1295e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr **InitExpr) { 12966e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(VD && DT && InitExpr); 12974b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 12982d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines 12992d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines // Loop through array types to get to base type 13002d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines while (T && T->isArrayType()) { 13012d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines T = T->getArrayElementTypeNoTypeQual(); 13022d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines } 13032d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines 1304f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool DataTypeIsStructWithRSObject = false; 1305e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines *DT = RSExportPrimitiveType::GetRSSpecificType(T); 13064b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1307cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet if (*DT == DataTypeUnknown) { 1308feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (RSExportPrimitiveType::IsStructureTypeWithRSObject(T)) { 1309cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet *DT = DataTypeIsStruct; 1310f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DataTypeIsStructWithRSObject = true; 1311feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } else { 1312feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines return false; 1313feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 13142d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines } 13154b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1316f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool DataTypeIsRSObject = false; 1317f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (DataTypeIsStructWithRSObject) { 1318f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DataTypeIsRSObject = true; 1319f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 1320f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DataTypeIsRSObject = RSExportPrimitiveType::IsRSObjectType(*DT); 1321f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 1322e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines *InitExpr = VD->getInit(); 1323e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1324e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (!DataTypeIsRSObject && *InitExpr) { 1325e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines // If we already have an initializer for a matrix type, we are done. 1326e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return DataTypeIsRSObject; 13274b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 13284b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1329e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *ZeroInitializer = 1330d9ed6b51a3fe997aefdcd360f8bfc40b17c9ab91Stephen Hines CreateEmptyInitListExpr(VD->getASTContext(), VD->getLocation()); 1331e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1332e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (ZeroInitializer) { 1333e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ZeroInitializer->setType(T->getCanonicalTypeInternal()); 1334e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->setInit(ZeroInitializer); 1335e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 1336e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1337e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return DataTypeIsRSObject; 13384b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 13394b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1340d9ed6b51a3fe997aefdcd360f8bfc40b17c9ab91Stephen Hinesclang::Expr *RSObjectRefCount::CreateEmptyInitListExpr( 13414b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ASTContext &C, 13424b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines const clang::SourceLocation &Loc) { 13434b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1344d9ed6b51a3fe997aefdcd360f8bfc40b17c9ab91Stephen Hines // We can cheaply construct a zero initializer by just creating an empty 1345d9ed6b51a3fe997aefdcd360f8bfc40b17c9ab91Stephen Hines // initializer list. Clang supports this extension to C(99), and will create 1346d9ed6b51a3fe997aefdcd360f8bfc40b17c9ab91Stephen Hines // any necessary constructs to zero out the entire variable. 1347d9ed6b51a3fe997aefdcd360f8bfc40b17c9ab91Stephen Hines llvm::SmallVector<clang::Expr*, 1> EmptyInitList; 1348d9ed6b51a3fe997aefdcd360f8bfc40b17c9ab91Stephen Hines return new(C) clang::InitListExpr(C, Loc, EmptyInitList, Loc); 13494b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 13504b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1351579e4f481774275980d6e3fbb7978c674da6d302Yang Niclang::DeclRefExpr *RSObjectRefCount::CreateGuard(clang::ASTContext &C, 1352579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::DeclContext *DC, 1353579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::Expr *E, 1354579e4f481774275980d6e3fbb7978c674da6d302Yang Ni const llvm::Twine &VarName, 1355579e4f481774275980d6e3fbb7978c674da6d302Yang Ni std::vector<clang::Stmt*> &NewStmts) { 1356579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::SourceLocation Loc = E->getLocStart(); 1357579e4f481774275980d6e3fbb7978c674da6d302Yang Ni const clang::QualType Ty = E->getType(); 1358579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::VarDecl* TmpDecl = clang::VarDecl::Create( 13595767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni C, // AST context 13605767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni DC, // Decl context 13615767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni Loc, // Start location 13625767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni Loc, // Id location 1363579e4f481774275980d6e3fbb7978c674da6d302Yang Ni &C.Idents.get(VarName.str()), // Id 1364579e4f481774275980d6e3fbb7978c674da6d302Yang Ni Ty, // Type 1365579e4f481774275980d6e3fbb7978c674da6d302Yang Ni C.getTrivialTypeSourceInfo(Ty), // Type info 13665767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni clang::SC_None // Storage class 13675767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni ); 1368579e4f481774275980d6e3fbb7978c674da6d302Yang Ni const clang::Type *T = Ty.getTypePtr(); 13695767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni clang::Expr *ZeroInitializer = 1370d9ed6b51a3fe997aefdcd360f8bfc40b17c9ab91Stephen Hines RSObjectRefCount::CreateEmptyInitListExpr(C, Loc); 13715767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni ZeroInitializer->setType(T->getCanonicalTypeInternal()); 1372579e4f481774275980d6e3fbb7978c674da6d302Yang Ni TmpDecl->setInit(ZeroInitializer); 1373579e4f481774275980d6e3fbb7978c674da6d302Yang Ni TmpDecl->markUsed(C); 1374579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::Decl* Decls[] = { TmpDecl }; 13755767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni const clang::DeclGroupRef DGR = clang::DeclGroupRef::Create( 13765767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni C, Decls, sizeof(Decls) / sizeof(*Decls)); 13775767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni clang::DeclStmt* DS = new (C) clang::DeclStmt(DGR, Loc, Loc); 13785767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni NewStmts.push_back(DS); 13795767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni 13805767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni clang::DeclRefExpr* DRE = clang::DeclRefExpr::Create( 13815767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni C, 13825767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni clang::NestedNameSpecifierLoc(), // QualifierLoc 13835767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni Loc, // TemplateKWLoc 1384579e4f481774275980d6e3fbb7978c674da6d302Yang Ni TmpDecl, 13855767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni false, // RefersToEnclosingVariableOrCapture 13865767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni Loc, // NameLoc 1387579e4f481774275980d6e3fbb7978c674da6d302Yang Ni Ty, 13885767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni clang::VK_LValue 13895767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni ); 1390579e4f481774275980d6e3fbb7978c674da6d302Yang Ni 1391579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::Stmt *UpdatedStmt = nullptr; 1392579e4f481774275980d6e3fbb7978c674da6d302Yang Ni if (!RSExportPrimitiveType::IsRSObjectType(Ty.getTypePtr())) { 1393579e4f481774275980d6e3fbb7978c674da6d302Yang Ni // By definition, this is a struct assignment if we get here 1394579e4f481774275980d6e3fbb7978c674da6d302Yang Ni UpdatedStmt = 1395579e4f481774275980d6e3fbb7978c674da6d302Yang Ni CreateStructRSSetObject(C, DRE, E, Loc, Loc); 1396579e4f481774275980d6e3fbb7978c674da6d302Yang Ni } else { 1397579e4f481774275980d6e3fbb7978c674da6d302Yang Ni UpdatedStmt = 1398579e4f481774275980d6e3fbb7978c674da6d302Yang Ni CreateSingleRSSetObject(C, DRE, E, Loc, Loc); 1399579e4f481774275980d6e3fbb7978c674da6d302Yang Ni } 1400579e4f481774275980d6e3fbb7978c674da6d302Yang Ni NewStmts.push_back(UpdatedStmt); 1401579e4f481774275980d6e3fbb7978c674da6d302Yang Ni 1402579e4f481774275980d6e3fbb7978c674da6d302Yang Ni return DRE; 1403579e4f481774275980d6e3fbb7978c674da6d302Yang Ni} 1404579e4f481774275980d6e3fbb7978c674da6d302Yang Ni 1405579e4f481774275980d6e3fbb7978c674da6d302Yang Nivoid RSObjectRefCount::CreateParameterGuard(clang::ASTContext &C, 1406579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::DeclContext *DC, 1407579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::ParmVarDecl *PD, 1408579e4f481774275980d6e3fbb7978c674da6d302Yang Ni std::vector<clang::Stmt*> &NewStmts) { 1409579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::SourceLocation Loc = PD->getLocStart(); 1410579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::DeclRefExpr* ParamDRE = clang::DeclRefExpr::Create( 1411579e4f481774275980d6e3fbb7978c674da6d302Yang Ni C, 1412579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::NestedNameSpecifierLoc(), // QualifierLoc 1413579e4f481774275980d6e3fbb7978c674da6d302Yang Ni Loc, // TemplateKWLoc 1414579e4f481774275980d6e3fbb7978c674da6d302Yang Ni PD, 1415579e4f481774275980d6e3fbb7978c674da6d302Yang Ni false, // RefersToEnclosingVariableOrCapture 1416579e4f481774275980d6e3fbb7978c674da6d302Yang Ni Loc, // NameLoc 1417579e4f481774275980d6e3fbb7978c674da6d302Yang Ni PD->getType(), 1418579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::VK_RValue 1419579e4f481774275980d6e3fbb7978c674da6d302Yang Ni ); 1420579e4f481774275980d6e3fbb7978c674da6d302Yang Ni 1421579e4f481774275980d6e3fbb7978c674da6d302Yang Ni CreateGuard(C, DC, ParamDRE, 1422579e4f481774275980d6e3fbb7978c674da6d302Yang Ni llvm::Twine(".rs.param.") + llvm::Twine(PD->getName()), NewStmts); 1423579e4f481774275980d6e3fbb7978c674da6d302Yang Ni} 1424579e4f481774275980d6e3fbb7978c674da6d302Yang Ni 1425579e4f481774275980d6e3fbb7978c674da6d302Yang Nivoid RSObjectRefCount::HandleParamsAndLocals(clang::FunctionDecl *FD) { 1426579e4f481774275980d6e3fbb7978c674da6d302Yang Ni std::vector<clang::Stmt*> NewStmts; 1427579e4f481774275980d6e3fbb7978c674da6d302Yang Ni std::list<clang::ParmVarDecl*> ObjParams; 1428579e4f481774275980d6e3fbb7978c674da6d302Yang Ni for (clang::ParmVarDecl *Param : FD->parameters()) { 1429579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::QualType QT = Param->getType(); 1430579e4f481774275980d6e3fbb7978c674da6d302Yang Ni if (CountRSObjectTypes(QT.getTypePtr())) { 1431579e4f481774275980d6e3fbb7978c674da6d302Yang Ni // Ignore non-object types 1432579e4f481774275980d6e3fbb7978c674da6d302Yang Ni RSObjectRefCount::CreateParameterGuard(mCtx, FD, Param, NewStmts); 1433579e4f481774275980d6e3fbb7978c674da6d302Yang Ni ObjParams.push_back(Param); 1434579e4f481774275980d6e3fbb7978c674da6d302Yang Ni } 1435579e4f481774275980d6e3fbb7978c674da6d302Yang Ni } 1436579e4f481774275980d6e3fbb7978c674da6d302Yang Ni 1437579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::Stmt *OldBody = FD->getBody(); 1438579e4f481774275980d6e3fbb7978c674da6d302Yang Ni if (ObjParams.empty()) { 1439579e4f481774275980d6e3fbb7978c674da6d302Yang Ni Visit(OldBody); 1440579e4f481774275980d6e3fbb7978c674da6d302Yang Ni return; 1441579e4f481774275980d6e3fbb7978c674da6d302Yang Ni } 1442579e4f481774275980d6e3fbb7978c674da6d302Yang Ni 1443579e4f481774275980d6e3fbb7978c674da6d302Yang Ni NewStmts.push_back(OldBody); 1444579e4f481774275980d6e3fbb7978c674da6d302Yang Ni 1445579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::SourceLocation Loc = FD->getLocStart(); 1446579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::CompoundStmt *NewBody = BuildCompoundStmt(mCtx, NewStmts, Loc); 1447579e4f481774275980d6e3fbb7978c674da6d302Yang Ni Scope S(NewBody); 1448579e4f481774275980d6e3fbb7978c674da6d302Yang Ni for (clang::ParmVarDecl *Param : ObjParams) { 1449579e4f481774275980d6e3fbb7978c674da6d302Yang Ni S.addRSObject(Param); 1450579e4f481774275980d6e3fbb7978c674da6d302Yang Ni } 1451579e4f481774275980d6e3fbb7978c674da6d302Yang Ni mScopeStack.push_back(&S); 1452579e4f481774275980d6e3fbb7978c674da6d302Yang Ni 1453579e4f481774275980d6e3fbb7978c674da6d302Yang Ni // To avoid adding unnecessary ref counting artifacts to newly added temporary 1454579e4f481774275980d6e3fbb7978c674da6d302Yang Ni // local variables for parameters, visits only the old function body here. 1455579e4f481774275980d6e3fbb7978c674da6d302Yang Ni Visit(OldBody); 1456579e4f481774275980d6e3fbb7978c674da6d302Yang Ni 1457579e4f481774275980d6e3fbb7978c674da6d302Yang Ni FD->setBody(NewBody); 1458579e4f481774275980d6e3fbb7978c674da6d302Yang Ni 1459579e4f481774275980d6e3fbb7978c674da6d302Yang Ni S.InsertLocalVarDestructors(); 1460579e4f481774275980d6e3fbb7978c674da6d302Yang Ni mScopeStack.pop_back(); 1461579e4f481774275980d6e3fbb7978c674da6d302Yang Ni} 1462579e4f481774275980d6e3fbb7978c674da6d302Yang Ni 1463579e4f481774275980d6e3fbb7978c674da6d302Yang Niclang::CompoundStmt* RSObjectRefCount::CreateRetStmtWithTempVar( 1464579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::ASTContext& C, 1465579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::DeclContext* DC, 1466579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::ReturnStmt* RS, 1467579e4f481774275980d6e3fbb7978c674da6d302Yang Ni const unsigned id) { 1468579e4f481774275980d6e3fbb7978c674da6d302Yang Ni std::vector<clang::Stmt*> NewStmts; 1469579e4f481774275980d6e3fbb7978c674da6d302Yang Ni // Since we insert rsClearObj() calls before the return statement, we need 1470579e4f481774275980d6e3fbb7978c674da6d302Yang Ni // to make sure none of the cleared RS objects are referenced in the 1471579e4f481774275980d6e3fbb7978c674da6d302Yang Ni // return statement. 1472579e4f481774275980d6e3fbb7978c674da6d302Yang Ni // For that, we create a new local variable named .rs.retval, assign the 1473579e4f481774275980d6e3fbb7978c674da6d302Yang Ni // original return expression to it, make all necessary rsClearObj() 1474579e4f481774275980d6e3fbb7978c674da6d302Yang Ni // calls, then return .rs.retval. Note rsClearObj() is not called on 1475579e4f481774275980d6e3fbb7978c674da6d302Yang Ni // .rs.retval. 1476579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::SourceLocation Loc = RS->getLocStart(); 1477579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::Expr* RetVal = RS->getRetValue(); 1478579e4f481774275980d6e3fbb7978c674da6d302Yang Ni const clang::QualType RetTy = RetVal->getType(); 1479579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::DeclRefExpr *DRE = CreateGuard(C, DC, RetVal, 1480579e4f481774275980d6e3fbb7978c674da6d302Yang Ni llvm::Twine(".rs.retval") + llvm::Twine(id), 1481579e4f481774275980d6e3fbb7978c674da6d302Yang Ni NewStmts); 14825767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni 14835767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni // Creates a new return statement 1484579e4f481774275980d6e3fbb7978c674da6d302Yang Ni clang::ReturnStmt* NewRet = new (C) clang::ReturnStmt(Loc); 14855767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni clang::Expr* CastExpr = clang::ImplicitCastExpr::Create( 14865767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni C, 14875767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni RetTy, 14885767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni clang::CK_LValueToRValue, 14895767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni DRE, 14905767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni nullptr, 14915767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni clang::VK_RValue 14925767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni ); 14935767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni NewRet->setRetValue(CastExpr); 14945767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni NewStmts.push_back(NewRet); 14955767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni 14965767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni return BuildCompoundStmt(C, NewStmts, Loc); 14975767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni} 14985767c359bac779b5d76d668ca5699fd5a0e3efc5Yang Ni 14994b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitDeclStmt(clang::DeclStmt *DS) { 1500b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni VisitStmt(DS); 1501b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni getCurrentScope()->setCurrentStmt(DS); 15024b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (clang::DeclStmt::decl_iterator I = DS->decl_begin(), E = DS->decl_end(); 15034b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I != E; 15044b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I++) { 15054b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Decl *D = *I; 15064b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (D->getKind() == clang::Decl::Var) { 15074b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::VarDecl *VD = static_cast<clang::VarDecl*>(D); 1508cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT = DataTypeUnknown; 15095abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes clang::Expr *InitExpr = nullptr; 1510e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (InitializeRSObject(VD, &DT, &InitExpr)) { 1511b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines // We need to zero-init all RS object types (including matrices), ... 1512d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines getCurrentScope()->AppendRSObjectInit(VD, DS, DT, InitExpr); 1513b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines // ... but, only add to the list of RS objects if we have some 1514b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines // non-matrix RS object fields. 151565f23ed862e1a1e16477ba740f295ff4a83ac822David Gross if (CountRSObjectTypes(VD->getType().getTypePtr())) { 1516b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines getCurrentScope()->addRSObject(VD); 1517b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines } 1518e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 15194b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 15204b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 15214b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 15224b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1523b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Nivoid RSObjectRefCount::VisitCallExpr(clang::CallExpr* CE) { 1524b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::QualType RetTy; 1525b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni const clang::FunctionDecl* FD = CE->getDirectCallee(); 1526b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1527b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni if (FD) { 1528b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // Direct calls 1529b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1530b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni RetTy = FD->getReturnType(); 1531b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } else { 1532b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // Indirect calls through function pointers 1533b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1534b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni const clang::Expr* Callee = CE->getCallee(); 1535b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni const clang::Type* CalleeType = Callee->getType().getTypePtr(); 1536b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni const clang::PointerType* PtrType = CalleeType->getAs<clang::PointerType>(); 1537b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1538b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni if (!PtrType) { 1539b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni return; 1540b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1541b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1542b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni const clang::Type* PointeeType = PtrType->getPointeeType().getTypePtr(); 1543b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni const clang::FunctionType* FuncType = PointeeType->getAs<clang::FunctionType>(); 1544b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1545b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni if (!FuncType) { 1546b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni return; 1547b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1548b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1549b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni RetTy = FuncType->getReturnType(); 1550b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1551b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 15529e580014469e0c87e95fcb31e78738a336b1f200Yang Ni // The RenderScript runtime API maintains the invariant that the sysRef of a new RS object would 15539e580014469e0c87e95fcb31e78738a336b1f200Yang Ni // be 1, with the exception of rsGetAllocation() (deprecated in API 22), which leaves the sysRef 15549e580014469e0c87e95fcb31e78738a336b1f200Yang Ni // 0 for a new allocation. It is the responsibility of the callee of the API to decrement the 15559e580014469e0c87e95fcb31e78738a336b1f200Yang Ni // sysRef when a reference of the RS object goes out of scope. The compiler generates code to do 15569e580014469e0c87e95fcb31e78738a336b1f200Yang Ni // just that, by creating a temporary variable named ".rs.tmpN" with the result of 15579e580014469e0c87e95fcb31e78738a336b1f200Yang Ni // an RS-object-returning API directly assigned to it, and calling rsClearObject() on .rs.tmpN 15589e580014469e0c87e95fcb31e78738a336b1f200Yang Ni // right before it exits the current scope. Such code generation is skipped for rsGetAllocation() 15599e580014469e0c87e95fcb31e78738a336b1f200Yang Ni // to avoid decrementing its sysRef below zero. 15609e580014469e0c87e95fcb31e78738a336b1f200Yang Ni 15619e580014469e0c87e95fcb31e78738a336b1f200Yang Ni if (CountRSObjectTypes(RetTy.getTypePtr())==0 || 15629e580014469e0c87e95fcb31e78738a336b1f200Yang Ni (FD && FD->getName() == "rsGetAllocation")) { 1563b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni return; 1564b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1565b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1566b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::SourceLocation Loc = CE->getSourceRange().getBegin(); 1567b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni std::stringstream ss; 1568b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni ss << ".rs.tmp" << getNextID(); 1569b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni llvm::StringRef VarName(ss.str()); 1570b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1571b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::VarDecl* TempVarDecl = clang::VarDecl::Create( 1572b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni mCtx, // AST context 1573b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni GetDeclContext(), // Decl context 1574b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni Loc, // Start location 1575b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni Loc, // Id location 1576b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni &mCtx.Idents.get(VarName), // Id 1577b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni RetTy, // Type 1578b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni mCtx.getTrivialTypeSourceInfo(RetTy), // Type info 1579b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::SC_None // Storage class 1580b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni ); 1581b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni TempVarDecl->setInit(CE); 1582041656a24663cb4f7a61a598e848f217c893cebfStephen Hines TempVarDecl->markUsed(mCtx); 1583b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Decl* Decls[] = { TempVarDecl }; 1584b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni const clang::DeclGroupRef DGR = clang::DeclGroupRef::Create( 1585b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni mCtx, Decls, sizeof(Decls) / sizeof(*Decls)); 1586b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::DeclStmt* DS = new (mCtx) clang::DeclStmt(DGR, Loc, Loc); 1587b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1588b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni getCurrentScope()->InsertStmt(mCtx, DS); 1589b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1590b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::DeclRefExpr* DRE = clang::DeclRefExpr::Create( 1591b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni mCtx, // AST context 1592b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::NestedNameSpecifierLoc(), // QualifierLoc 1593b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni Loc, // TemplateKWLoc 1594b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni TempVarDecl, 1595b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni false, // RefersToEnclosingVariableOrCapture 1596b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni Loc, // NameLoc 1597b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni RetTy, 1598b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::VK_LValue 1599b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni ); 1600b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Expr* CastExpr = clang::ImplicitCastExpr::Create( 1601b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni mCtx, 1602b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni RetTy, 1603b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::CK_LValueToRValue, 1604b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni DRE, 1605b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni nullptr, 1606b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::VK_RValue 1607b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni ); 1608b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1609b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni getCurrentScope()->ReplaceExpr(mCtx, CE, CastExpr); 1610b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1611b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // Register TempVarDecl for destruction call (rsClearObj). 1612b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni getCurrentScope()->addRSObject(TempVarDecl); 1613b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni} 1614b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 16154b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitCompoundStmt(clang::CompoundStmt *CS) { 1616b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni if (!emptyScope()) { 1617b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni getCurrentScope()->setCurrentStmt(CS); 1618b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1619b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 16204b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (!CS->body_empty()) { 16214b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Push a new scope 16224b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Scope *S = new Scope(CS); 1623b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni mScopeStack.push_back(S); 16244b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 16254b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines VisitStmt(CS); 16264b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 16274b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Destroy the scope 16286e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((getCurrentScope() == S) && "Corrupted scope stack!"); 16291bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines S->InsertLocalVarDestructors(); 1630b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni mScopeStack.pop_back(); 16314b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines delete S; 16324b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 16334b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 16344b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 16354b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitBinAssign(clang::BinaryOperator *AS) { 1636b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni getCurrentScope()->setCurrentStmt(AS); 1637c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType QT = AS->getType(); 1638c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 163965f23ed862e1a1e16477ba740f295ff4a83ac822David Gross if (CountRSObjectTypes(QT.getTypePtr())) { 1640d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines getCurrentScope()->ReplaceRSObjectAssignment(AS); 1641c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 16424b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 16434b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1644b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Nivoid RSObjectRefCount::VisitReturnStmt(clang::ReturnStmt *RS) { 1645b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni getCurrentScope()->setCurrentStmt(RS); 1646b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1647b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // If there is no local rsObject declared so far, no need to transform the 1648b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // return statement. 1649b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1650b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni bool RSObjDeclared = false; 1651b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1652b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni for (const Scope* S : mScopeStack) { 1653b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni if (S->hasRSObject()) { 1654b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni RSObjDeclared = true; 1655b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni break; 1656b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1657b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1658b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1659b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni if (!RSObjDeclared) { 1660b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni return; 1661b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1662b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1663b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // If the return statement does not return anything, or if it does not return 1664b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // a rsObject, no need to transform it. 1665b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1666b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::Expr* RetVal = RS->getRetValue(); 1667b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni if (!RetVal || CountRSObjectTypes(RetVal->getType().getTypePtr()) == 0) { 1668b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni return; 1669b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni } 1670b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1671b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // Transform the return statement so that it does not potentially return or 1672b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni // reference a rsObject that has been cleared. 1673b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1674b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni clang::CompoundStmt* NewRS; 1675b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni NewRS = CreateRetStmtWithTempVar(mCtx, GetDeclContext(), RS, getNextID()); 1676b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 1677b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni getCurrentScope()->ReplaceStmt(mCtx, NewRS); 1678b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni} 1679b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni 16804b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitStmt(clang::Stmt *S) { 1681b478c3dd0a47dc4c0c884d911819c9cf53c46649Yang Ni getCurrentScope()->setCurrentStmt(S); 16824b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end(); 16834b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I != E; 16844b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I++) { 16854b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (clang::Stmt *Child = *I) { 16864b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Visit(Child); 16874b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 16884b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 16894b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 16904b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1691688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines// This function walks the list of global variables and (potentially) creates 1692688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines// a single global static destructor function that properly decrements 1693688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines// reference counts on the contained RS object types. 1694688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hinesclang::FunctionDecl *RSObjectRefCount::CreateStaticGlobalDtor() { 1695688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines Init(); 1696688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 1697688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines clang::DeclContext *DC = mCtx.getTranslationUnitDecl(); 1698688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines clang::SourceLocation loc; 1699688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 17003f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines llvm::StringRef SR(".rs.dtor"); 17013f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines clang::IdentifierInfo &II = mCtx.Idents.get(SR); 17023f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines clang::DeclarationName N(&II); 17033f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines clang::FunctionProtoType::ExtProtoInfo EPI; 170482d7288620fade361dd8f7408b5db54a55c2c794Stephen Hines clang::QualType T = mCtx.getFunctionType(mCtx.VoidTy, 170582d7288620fade361dd8f7408b5db54a55c2c794Stephen Hines llvm::ArrayRef<clang::QualType>(), EPI); 17065abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes clang::FunctionDecl *FD = nullptr; 17073f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines 1708688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines // Generate rsClearObject() call chains for every global variable 1709688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines // (whether static or extern). 1710579e4f481774275980d6e3fbb7978c674da6d302Yang Ni std::vector<clang::Stmt *> StmtList; 1711688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines for (clang::DeclContext::decl_iterator I = DC->decls_begin(), 1712688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines E = DC->decls_end(); I != E; I++) { 1713688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines clang::VarDecl *VD = llvm::dyn_cast<clang::VarDecl>(*I); 1714688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines if (VD) { 171565f23ed862e1a1e16477ba740f295ff4a83ac822David Gross if (CountRSObjectTypes(VD->getType().getTypePtr())) { 17163f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines if (!FD) { 17173f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines // Only create FD if we are going to use it. 17185abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes FD = clang::FunctionDecl::Create(mCtx, DC, loc, loc, N, T, nullptr, 17194b3f3bada7155de983e7d92fa8b20091629b3bb3Stephen Hines clang::SC_None); 17203f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines } 1721cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar // Mark VD as used. It might be unused, except for the destructor. 1722cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar // 'markUsed' has side-effects that are caused only if VD is not already 1723cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar // used. Hence no need for an extra check here. 1724cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar VD->markUsed(mCtx); 17253f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines // Make sure to create any helpers within the function's DeclContext, 17263f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines // not the one associated with the global translation unit. 17273f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines clang::Stmt *RSClearObjectCall = Scope::ClearRSObject(VD, FD); 1728688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines StmtList.push_back(RSClearObjectCall); 1729688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines } 1730688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines } 1731688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines } 1732688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 1733688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines // Nothing needs to be destroyed, so don't emit a dtor. 1734688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines if (StmtList.empty()) { 17355abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 1736688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines } 1737688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 1738688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines clang::CompoundStmt *CS = BuildCompoundStmt(mCtx, StmtList, loc); 1739688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 1740688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines FD->setBody(CS); 1741c8f5b2dad5c4ad2294d180b562d486342f29fb55I-Jui (Ray) Sung // We need some way to tell if this FD is generated by slang 1742c8f5b2dad5c4ad2294d180b562d486342f29fb55I-Jui (Ray) Sung FD->setImplicit(); 1743688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 1744688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines return FD; 1745688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines} 1746688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 174765f23ed862e1a1e16477ba740f295ff4a83ac822David Grossbool HasRSObjectType(const clang::Type *T) { 174865f23ed862e1a1e16477ba740f295ff4a83ac822David Gross return CountRSObjectTypes(T) != 0; 174965f23ed862e1a1e16477ba740f295ff4a83ac822David Gross} 175065f23ed862e1a1e16477ba740f295ff4a83ac822David Gross 1751e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 1752