slang_rs_object_ref_count.cpp revision cd57c5447d831a237d0917a0d687749e6348a46d
14b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines/* 24b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * Copyright 2010, The Android Open Source Project 34b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * 44b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * Licensed under the Apache License, Version 2.0 (the "License"); 54b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * you may not use this file except in compliance with the License. 64b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * You may obtain a copy of the License at 74b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * 84b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * http://www.apache.org/licenses/LICENSE-2.0 94b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * 104b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * Unless required by applicable law or agreed to in writing, software 114b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * distributed under the License is distributed on an "AS IS" BASIS, 124b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * See the License for the specific language governing permissions and 144b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * limitations under the License. 154b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines */ 164b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 174b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "slang_rs_object_ref_count.h" 184b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 19e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <list> 20e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 214b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "clang/AST/DeclGroup.h" 224b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "clang/AST/Expr.h" 23be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "clang/AST/NestedNameSpecifier.h" 244b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "clang/AST/OperationKinds.h" 254b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "clang/AST/Stmt.h" 264b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "clang/AST/StmtVisitor.h" 274b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 286e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h" 298024ed54c23c08534434da14d3be99c3efcc5754Jean-Luc Brouillet#include "slang.h" 30292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines#include "slang_rs_ast_replace.h" 314b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "slang_rs_export_type.h" 324b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 33e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang { 344b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 35474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet/* Even though those two arrays are of size DataTypeMax, only entries that 36474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet * correspond to object types will be set. 37474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet */ 38474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouilletclang::FunctionDecl * 39cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc BrouilletRSObjectRefCount::RSSetObjectFD[DataTypeMax]; 40474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouilletclang::FunctionDecl * 41cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc BrouilletRSObjectRefCount::RSClearObjectFD[DataTypeMax]; 421bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 43f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesvoid RSObjectRefCount::GetRSRefCountingFunctions(clang::ASTContext &C) { 44cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet for (unsigned i = 0; i < DataTypeMax; i++) { 455abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes RSSetObjectFD[i] = nullptr; 465abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes RSClearObjectFD[i] = nullptr; 471bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 481bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 491bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl(); 501bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 511bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(), 521bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines E = TUDecl->decls_end(); I != E; I++) { 531bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if ((I->getKind() >= clang::Decl::firstFunction) && 541bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines (I->getKind() <= clang::Decl::lastFunction)) { 551bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::FunctionDecl *FD = static_cast<clang::FunctionDecl*>(*I); 561bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 571bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // points to RSSetObjectFD or RSClearObjectFD 581bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::FunctionDecl **RSObjectFD; 591bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 601bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if (FD->getName() == "rsSetObject") { 616e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((FD->getNumParams() == 2) && 626e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "Invalid rsSetObject function prototype (# params)"); 631bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSObjectFD = RSSetObjectFD; 641bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } else if (FD->getName() == "rsClearObject") { 656e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((FD->getNumParams() == 1) && 666e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "Invalid rsClearObject function prototype (# params)"); 671bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSObjectFD = RSClearObjectFD; 68e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines } else { 691bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines continue; 701bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 711bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 721bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines const clang::ParmVarDecl *PVD = FD->getParamDecl(0); 731bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::QualType PVT = PVD->getOriginalType(); 741bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // The first parameter must be a pointer like rs_allocation* 756e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(PVT->isPointerType() && 766e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "Invalid rs{Set,Clear}Object function prototype (pointer param)"); 771bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 781bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // The rs object type passed to the FD 791bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::QualType RST = PVT->getPointeeType(); 80cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT = RSExportPrimitiveType::GetRSSpecificType(RST.getTypePtr()); 816e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(RSExportPrimitiveType::IsRSObjectType(DT) 821bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines && "must be RS object type"); 831bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 84cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet if (DT >= 0 && DT < DataTypeMax) { 85474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet RSObjectFD[DT] = FD; 86474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet } else { 87474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet slangAssert(false && "incorrect type"); 88474655a402e70cb329e1bcd4ebbe00bdc5be4206Jean-Luc Brouillet } 891bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 901bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 911bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 921bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 934464d825c11349068f2917f9ebee86b721423f3cStephen Hinesnamespace { 944464d825c11349068f2917f9ebee86b721423f3cStephen Hines 95292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines// This function constructs a new CompoundStmt from the input StmtList. 96292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesstatic clang::CompoundStmt* BuildCompoundStmt(clang::ASTContext &C, 97292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*> &StmtList, clang::SourceLocation Loc) { 98d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines unsigned NewStmtCount = StmtList.size(); 99292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines unsigned CompoundStmtCount = 0; 1001bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 101292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines clang::Stmt **CompoundStmtList; 102292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines CompoundStmtList = new clang::Stmt*[NewStmtCount]; 1031bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 104292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*>::const_iterator I = StmtList.begin(); 105292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*>::const_iterator E = StmtList.end(); 106292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines for ( ; I != E; I++) { 107292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines CompoundStmtList[CompoundStmtCount++] = *I; 1081bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 109292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines slangAssert(CompoundStmtCount == NewStmtCount); 1101bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 11123c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines clang::CompoundStmt *CS = new(C) clang::CompoundStmt( 11223c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines C, llvm::makeArrayRef(CompoundStmtList, CompoundStmtCount), Loc, Loc); 1131bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 114292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines delete [] CompoundStmtList; 1151bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 116292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return CS; 1171bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 1181bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 119292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesstatic void AppendAfterStmt(clang::ASTContext &C, 120e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CompoundStmt *CS, 121292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines clang::Stmt *S, 122292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*> &StmtList) { 123292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines slangAssert(CS); 124e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CompoundStmt::body_iterator bI = CS->body_begin(); 125292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines clang::CompoundStmt::body_iterator bE = CS->body_end(); 126292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines clang::Stmt **UpdatedStmtList = 127292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines new clang::Stmt*[CS->size() + StmtList.size()]; 128e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 129e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines unsigned UpdatedStmtCount = 0; 130e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines unsigned Once = 0; 131292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines for ( ; bI != bE; bI++) { 132292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if (!S && ((*bI)->getStmtClass() == clang::Stmt::ReturnStmtClass)) { 133292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // If we come across a return here, we don't have anything we can 134292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // reasonably replace. We should have already inserted our destructor 135292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // code in the proper spot, so we just clean up and return. 136292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines delete [] UpdatedStmtList; 137292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 138292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return; 139e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 140e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 141292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines UpdatedStmtList[UpdatedStmtCount++] = *bI; 142c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 143292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if ((*bI == S) && !Once) { 144292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines Once++; 145292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*>::const_iterator I = StmtList.begin(); 146292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*>::const_iterator E = StmtList.end(); 147292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines for ( ; I != E; I++) { 148292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines UpdatedStmtList[UpdatedStmtCount++] = *I; 149292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 150292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 151c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 152292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines slangAssert(Once <= 1); 153c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 1545abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes // When S is nullptr, we are appending to the end of the CompoundStmt. 155292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if (!S) { 156292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines slangAssert(Once == 0); 157292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*>::const_iterator I = StmtList.begin(); 158292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*>::const_iterator E = StmtList.end(); 159292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines for ( ; I != E; I++) { 160292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines UpdatedStmtList[UpdatedStmtCount++] = *I; 161c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 162c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 163c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 164c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines CS->setStmts(C, UpdatedStmtList, UpdatedStmtCount); 165c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 166c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines delete [] UpdatedStmtList; 167c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines} 168c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 169a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines// This class visits a compound statement and inserts DtorStmt 170a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines// in proper locations. This includes inserting it before any 1714464d825c11349068f2917f9ebee86b721423f3cStephen Hines// return statement in any sub-block, at the end of the logical enclosing 1724464d825c11349068f2917f9ebee86b721423f3cStephen Hines// scope (compound statement), and/or before any break/continue statement that 1734464d825c11349068f2917f9ebee86b721423f3cStephen Hines// would resume outside the declared scope. We will not handle the case for 1744464d825c11349068f2917f9ebee86b721423f3cStephen Hines// goto statements that leave a local scope. 175292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines// 176292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines// To accomplish these goals, it collects a list of sub-Stmt's that 177292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines// correspond to scope exit points. It then uses an RSASTReplace visitor to 178292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines// transform the AST, inserting appropriate destructors before each of those 179292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines// sub-Stmt's (and also before the exit of the outermost containing Stmt for 180292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines// the scope). 1814464d825c11349068f2917f9ebee86b721423f3cStephen Hinesclass DestructorVisitor : public clang::StmtVisitor<DestructorVisitor> { 1824464d825c11349068f2917f9ebee86b721423f3cStephen Hines private: 183d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines clang::ASTContext &mCtx; 184292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 185292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // The loop depth of the currently visited node. 186292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines int mLoopDepth; 187292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 188292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // The switch statement depth of the currently visited node. 189292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // Note that this is tracked separately from the loop depth because 190292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // SwitchStmt-contained ContinueStmt's should have destructors for the 191292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // corresponding loop scope. 192292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines int mSwitchDepth; 193292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 194292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // The outermost statement block that we are currently visiting. 195292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // This should always be a CompoundStmt. 196292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines clang::Stmt *mOuterStmt; 197292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 198a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines // The destructor to execute for this scope/variable. 199a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines clang::Stmt* mDtorStmt; 200292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 201292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // The stack of statements which should be replaced by a compound statement 202a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines // containing the new destructor call followed by the original Stmt. 203292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::stack<clang::Stmt*> mReplaceStmtStack; 204292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 205a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines // The source location for the variable declaration that we are trying to 206a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines // insert destructors for. Note that InsertDestructors() will not generate 207a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines // destructor calls for source locations that occur lexically before this 208a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines // location. 209a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines clang::SourceLocation mVarLoc; 210a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines 2114464d825c11349068f2917f9ebee86b721423f3cStephen Hines public: 212292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines DestructorVisitor(clang::ASTContext &C, 213292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines clang::Stmt* OuterStmt, 214a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines clang::Stmt* DtorStmt, 215a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines clang::SourceLocation VarLoc); 216292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 217292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // This code walks the collected list of Stmts to replace and actually does 218a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines // the replacement. It also finishes up by appending the destructor to the 219a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines // current outermost CompoundStmt. 220292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void InsertDestructors() { 2215abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes clang::Stmt *S = nullptr; 222a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines clang::SourceManager &SM = mCtx.getSourceManager(); 223a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines std::list<clang::Stmt *> StmtList; 224a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines StmtList.push_back(mDtorStmt); 225a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines 226292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines while (!mReplaceStmtStack.empty()) { 227292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines S = mReplaceStmtStack.top(); 228292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mReplaceStmtStack.pop(); 229292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 230a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines // Skip all source locations that occur before the variable's 231a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines // declaration, since it won't have been initialized yet. 232a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines if (SM.isBeforeInTranslationUnit(S->getLocStart(), mVarLoc)) { 233a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines continue; 234a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines } 235a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines 236a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines StmtList.push_back(S); 237292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines clang::CompoundStmt *CS = 238a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines BuildCompoundStmt(mCtx, StmtList, S->getLocEnd()); 239a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines StmtList.pop_back(); 240292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 241d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines RSASTReplace R(mCtx); 242292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines R.ReplaceStmt(mOuterStmt, S, CS); 243292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 244ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien clang::CompoundStmt *CS = 245ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien llvm::dyn_cast<clang::CompoundStmt>(mOuterStmt); 246292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines slangAssert(CS); 2475abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes AppendAfterStmt(mCtx, CS, nullptr, StmtList); 248292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 249292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 2504464d825c11349068f2917f9ebee86b721423f3cStephen Hines void VisitStmt(clang::Stmt *S); 2514464d825c11349068f2917f9ebee86b721423f3cStephen Hines void VisitCompoundStmt(clang::CompoundStmt *CS); 252292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 253292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitBreakStmt(clang::BreakStmt *BS); 254292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitCaseStmt(clang::CaseStmt *CS); 255292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitContinueStmt(clang::ContinueStmt *CS); 256292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitDefaultStmt(clang::DefaultStmt *DS); 257292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitDoStmt(clang::DoStmt *DS); 258292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitForStmt(clang::ForStmt *FS); 259292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitIfStmt(clang::IfStmt *IS); 260292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitReturnStmt(clang::ReturnStmt *RS); 261292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitSwitchCase(clang::SwitchCase *SC); 262292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitSwitchStmt(clang::SwitchStmt *SS); 263292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitWhileStmt(clang::WhileStmt *WS); 2644464d825c11349068f2917f9ebee86b721423f3cStephen Hines}; 2654464d825c11349068f2917f9ebee86b721423f3cStephen Hines 2664464d825c11349068f2917f9ebee86b721423f3cStephen HinesDestructorVisitor::DestructorVisitor(clang::ASTContext &C, 267292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines clang::Stmt *OuterStmt, 268a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines clang::Stmt *DtorStmt, 269a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines clang::SourceLocation VarLoc) 270d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines : mCtx(C), 271292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth(0), 272292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mSwitchDepth(0), 273292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mOuterStmt(OuterStmt), 274a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines mDtorStmt(DtorStmt), 275a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines mVarLoc(VarLoc) { 2764464d825c11349068f2917f9ebee86b721423f3cStephen Hines} 2774464d825c11349068f2917f9ebee86b721423f3cStephen Hines 2784464d825c11349068f2917f9ebee86b721423f3cStephen Hinesvoid DestructorVisitor::VisitStmt(clang::Stmt *S) { 2794464d825c11349068f2917f9ebee86b721423f3cStephen Hines for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end(); 2804464d825c11349068f2917f9ebee86b721423f3cStephen Hines I != E; 2814464d825c11349068f2917f9ebee86b721423f3cStephen Hines I++) { 2824464d825c11349068f2917f9ebee86b721423f3cStephen Hines if (clang::Stmt *Child = *I) { 2834464d825c11349068f2917f9ebee86b721423f3cStephen Hines Visit(Child); 2844464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 2854464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 2864464d825c11349068f2917f9ebee86b721423f3cStephen Hines} 2874464d825c11349068f2917f9ebee86b721423f3cStephen Hines 288292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitCompoundStmt(clang::CompoundStmt *CS) { 289292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(CS); 290292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 291292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 292292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitBreakStmt(clang::BreakStmt *BS) { 293292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(BS); 294292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if ((mLoopDepth == 0) && (mSwitchDepth == 0)) { 295292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mReplaceStmtStack.push(BS); 296292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 297292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 298292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 299292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitCaseStmt(clang::CaseStmt *CS) { 300292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(CS); 301292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 302292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 303292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitContinueStmt(clang::ContinueStmt *CS) { 304292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(CS); 305292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if (mLoopDepth == 0) { 306292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // Switch statements can have nested continues. 307292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mReplaceStmtStack.push(CS); 308292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 309292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 310292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 311292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitDefaultStmt(clang::DefaultStmt *DS) { 312292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(DS); 313292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 314292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 315292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitDoStmt(clang::DoStmt *DS) { 316292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth++; 317292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(DS); 318292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth--; 319292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 320292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 321292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitForStmt(clang::ForStmt *FS) { 322292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth++; 323292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(FS); 324292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth--; 325292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 326292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 327292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitIfStmt(clang::IfStmt *IS) { 328292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(IS); 329292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 330292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 331292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitReturnStmt(clang::ReturnStmt *RS) { 332292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mReplaceStmtStack.push(RS); 333292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 334292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 335292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitSwitchCase(clang::SwitchCase *SC) { 336292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines slangAssert(false && "Both case and default have specialized handlers"); 337292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(SC); 338292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 339292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 340292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitSwitchStmt(clang::SwitchStmt *SS) { 341292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mSwitchDepth++; 342292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(SS); 343292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mSwitchDepth--; 344292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 345292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 346292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitWhileStmt(clang::WhileStmt *WS) { 347292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth++; 348292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(WS); 349292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth--; 350292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 351292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 352f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesclang::Expr *ClearSingleRSObject(clang::ASTContext &C, 353f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSVar, 354f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc) { 355f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(RefRSVar); 356f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *T = RefRSVar->getType().getTypePtr(); 357f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(!T->isArrayType() && 358f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "Should not be destroying arrays with this function"); 359f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 360f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::FunctionDecl *ClearObjectFD = RSObjectRefCount::GetRSClearObjectFD(T); 3615abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes slangAssert((ClearObjectFD != nullptr) && 362f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "rsClearObject doesn't cover all RS object types"); 363f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 364f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::QualType ClearObjectFDType = ClearObjectFD->getType(); 365f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::QualType ClearObjectFDArgType = 366f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD->getParamDecl(0)->getOriginalType(); 367f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 368f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Example destructor for "rs_font localFont;" 369f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // 370f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (CallExpr 'void' 371f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (ImplicitCastExpr 'void (*)(rs_font *)' <FunctionToPointerDecay> 372f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (DeclRefExpr 'void (rs_font *)' FunctionDecl='rsClearObject')) 373f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (UnaryOperator 'rs_font *' prefix '&' 374f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (DeclRefExpr 'rs_font':'rs_font' Var='localFont'))) 375f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 376f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Get address of targeted RS object 377f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *AddrRefRSVar = 378f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::UnaryOperator(RefRSVar, 379f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::UO_AddrOf, 380f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFDArgType, 381be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 382be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 383f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 384f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 385f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSClearObjectFD = 386f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclRefExpr::Create(C, 387be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 3880444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 389f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD, 390e2597ac5a8ba7a45a1d5f342973cd43a3a1932cfShih-wei Liao false, 391f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD->getLocation(), 392be27482cdeaf08576bc39b72a15d35d13014a636Logan ClearObjectFDType, 393be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 3945abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr); 395f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 396f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RSClearObjectFP = 397f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ImplicitCastExpr::Create(C, 398f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines C.getPointerType(ClearObjectFDType), 399f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::CK_FunctionToPointerDecay, 400f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSClearObjectFD, 4015abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 402f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::VK_RValue); 40303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 4041dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines llvm::SmallVector<clang::Expr*, 1> ArgList; 4051dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines ArgList.push_back(AddrRefRSVar); 4061dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines 407f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::CallExpr *RSClearObjectCall = 408f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::CallExpr(C, 409f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectFP, 4101dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines ArgList, 411f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD->getCallResultType(), 412be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 413f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 414f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 415f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return RSClearObjectCall; 416f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines} 417f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 418f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic int ArrayDim(const clang::Type *T) { 41903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (!T || !T->isArrayType()) { 42003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return 0; 42103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 42203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 42303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines const clang::ConstantArrayType *CAT = 42403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines static_cast<const clang::ConstantArrayType *>(T); 4259d2c0fa6490e09b3ff5603796bce42d97788e5c8Stephen Hines return static_cast<int>(CAT->getSize().getSExtValue()); 42603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines} 42703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 428f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic clang::Stmt *ClearStructRSObject( 429f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ASTContext &C, 430f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC, 431f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSStruct, 432d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines clang::SourceLocation StartLoc, 433f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc); 434f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 435f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic clang::Stmt *ClearArrayRSObject( 436f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ASTContext &C, 437f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC, 438f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSArr, 439cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc, 440f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc) { 441f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *BaseType = RefRSArr->getType().getTypePtr(); 442f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(BaseType->isArrayType()); 443f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 444f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines int NumArrayElements = ArrayDim(BaseType); 445f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Actually extract out the base RS object type for use later 446f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines BaseType = BaseType->getArrayElementTypeNoTypeQual(); 44703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 44803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (NumArrayElements <= 0) { 4495abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 45003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 45103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 45203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Example destructor loop for "rs_font fontArr[10];" 45303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // 454cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (ForStmt 455cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (DeclStmt 456cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (VarDecl used rsIntIter 'int' cinit 457cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (IntegerLiteral 'int' 0))) 458cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (BinaryOperator 'int' '<' 459cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (ImplicitCastExpr int LValueToRValue 46003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter')) 461cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (IntegerLiteral 'int' 10) 462cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // nullptr << CondVar >> 463cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (UnaryOperator 'int' postfix '++' 464cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (DeclRefExpr 'int' Var='rsIntIter')) 465cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (CallExpr 'void' 466cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (ImplicitCastExpr 'void (*)(rs_font *)' <FunctionToPointerDecay> 467cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (DeclRefExpr 'void (rs_font *)' FunctionDecl='rsClearObject')) 468cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (UnaryOperator 'rs_font *' prefix '&' 469cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (ArraySubscriptExpr 'rs_font':'rs_font' 470cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (ImplicitCastExpr 'rs_font *' <ArrayToPointerDecay> 471cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (DeclRefExpr 'rs_font [10]' Var='fontArr')) 472cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // (DeclRefExpr 'int' Var='rsIntIter')))))) 47303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 47403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Create helper variable for iterating through elements 475cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines static unsigned sIterCounter = 0; 476cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines std::stringstream UniqueIterName; 477cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines UniqueIterName << "rsIntIter" << sIterCounter++; 478cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::IdentifierInfo *II = &C.Idents.get(UniqueIterName.str()); 47903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VarDecl *IIVD = 48003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VarDecl::Create(C, 481f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 482cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, 48303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 484cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines II, 48503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 48603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.getTrivialTypeSourceInfo(C.IntTy), 48703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::SC_None); 488cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar // Mark "rsIntIter" as used 489cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar IIVD->markUsed(C); 49003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 49103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Form the actual destructor loop 49203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // for (Init; Cond; Inc) 49303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // RSClearObjectCall; 49403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 495cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // Init -> "int rsIntIter = 0" 496cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, 497cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines llvm::APInt(C.getTypeSize(C.IntTy), 0), C.IntTy, Loc); 498cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines IIVD->setInit(Int0); 499cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines 500cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::Decl *IID = (clang::Decl *)IIVD; 501cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::DeclGroupRef DGR = clang::DeclGroupRef::Create(C, &IID, 1); 502cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::Stmt *Init = new(C) clang::DeclStmt(DGR, Loc, Loc); 503cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines 504cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines // Cond -> "rsIntIter < NumArrayElements" 505cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::DeclRefExpr *RefrsIntIterLValue = 50603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclRefExpr::Create(C, 507be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 5080444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 50903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines IIVD, 510e2597ac5a8ba7a45a1d5f342973cd43a3a1932cfShih-wei Liao false, 51103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 512be27482cdeaf08576bc39b72a15d35d13014a636Logan C.IntTy, 513cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::VK_LValue, 5145abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr); 51503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 516cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::Expr *RefrsIntIterRValue = 517cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::ImplicitCastExpr::Create(C, 518cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines RefrsIntIterLValue->getType(), 519cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::CK_LValueToRValue, 520cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines RefrsIntIterLValue, 521cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines nullptr, 522cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines clang::VK_RValue); 52303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 52403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *NumArrayElementsExpr = clang::IntegerLiteral::Create(C, 52503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), NumArrayElements), C.IntTy, Loc); 52603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 52703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BinaryOperator *Cond = 528cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines new(C) clang::BinaryOperator(RefrsIntIterRValue, 52903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NumArrayElementsExpr, 53003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BO_LT, 53103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 532be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 533be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 53423c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines Loc, 53523c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines false); 53603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 53703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Inc -> "rsIntIter++" 53803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::UnaryOperator *Inc = 539cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines new(C) clang::UnaryOperator(RefrsIntIterLValue, 54003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::UO_PostInc, 54103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 542be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 543be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 54403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 54503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 54603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Body -> "rsClearObject(&VD[rsIntIter]);" 54703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Destructor loop operates on individual array elements 54803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 549f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSArrPtr = 55003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::ImplicitCastExpr::Create(C, 551f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines C.getPointerType(BaseType->getCanonicalTypeInternal()), 55203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::CK_ArrayToPointerDecay, 553f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSArr, 5545abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 55503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VK_RValue); 55603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 557f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSArrPtrSubscript = 558f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::ArraySubscriptExpr(RefRSArrPtr, 559cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines RefrsIntIterRValue, 560f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines BaseType->getCanonicalTypeInternal(), 561be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 562be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 563f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 56403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 565cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT = RSExportPrimitiveType::GetRSSpecificType(BaseType); 566f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 5675abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes clang::Stmt *RSClearObjectCall = nullptr; 568f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (BaseType->isArrayType()) { 569f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectCall = 570cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao ClearArrayRSObject(C, DC, RefRSArrPtrSubscript, StartLoc, Loc); 571cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet } else if (DT == DataTypeUnknown) { 572f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectCall = 573cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao ClearStructRSObject(C, DC, RefRSArrPtrSubscript, StartLoc, Loc); 574f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 575f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectCall = ClearSingleRSObject(C, RefRSArrPtrSubscript, Loc); 576f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 57703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 57803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::ForStmt *DestructorLoop = 57903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::ForStmt(C, 58003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Init, 58103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Cond, 5825abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, // no condVar 58303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Inc, 58403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines RSClearObjectCall, 58503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 58603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 58703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 58803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 589cd57c5447d831a237d0917a0d687749e6348a46dStephen Hines return DestructorLoop; 59003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines} 59103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 592d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hinesstatic unsigned CountRSObjectTypes(clang::ASTContext &C, 593d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines const clang::Type *T, 594d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines clang::SourceLocation Loc) { 595f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(T); 596f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines unsigned RSObjectCount = 0; 597f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 598f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (T->isArrayType()) { 599d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines return CountRSObjectTypes(C, T->getArrayElementTypeNoTypeQual(), Loc); 600f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 601f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 602cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT = RSExportPrimitiveType::GetRSSpecificType(T); 603cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet if (DT != DataTypeUnknown) { 604f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return (RSExportPrimitiveType::IsRSObjectType(DT) ? 1 : 0); 605f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 606f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 607d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines if (T->isUnionType()) { 608d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines clang::RecordDecl *RD = T->getAsUnionType()->getDecl(); 609d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines RD = RD->getDefinition(); 610d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 611d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines FE = RD->field_end(); 612d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines FI != FE; 613d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines FI++) { 614d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines const clang::FieldDecl *FD = *FI; 615d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 616d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines if (CountRSObjectTypes(C, FT, Loc)) { 61778e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines slangAssert(false && "can't have unions with RS object types!"); 618d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines return 0; 619d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines } 620d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines } 621d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines } 622d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines 623f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (!T->isStructureType()) { 624f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return 0; 625f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 626f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 627f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::RecordDecl *RD = T->getAsStructureType()->getDecl(); 628f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RD = RD->getDefinition(); 629f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 630f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FE = RD->field_end(); 631f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI != FE; 632f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI++) { 633f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::FieldDecl *FD = *FI; 634f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 635d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines if (CountRSObjectTypes(C, FT, Loc)) { 636f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Sub-structs should only count once (as should arrays, etc.) 637f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectCount++; 638f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 639f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 640f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 641f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return RSObjectCount; 642f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines} 643f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 644f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic clang::Stmt *ClearStructRSObject( 645f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ASTContext &C, 646f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC, 647f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSStruct, 648cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc, 649f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc) { 650f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *BaseType = RefRSStruct->getType().getTypePtr(); 651f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 652f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(!BaseType->isArrayType()); 653f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 654f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Structs should show up as unknown primitive types 6559be9360d8e02b52ed669afbd69f9becb575c3f0dAlex Sakhartchouk slangAssert(RSExportPrimitiveType::GetRSSpecificType(BaseType) == 656cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataTypeUnknown); 657f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 658d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines unsigned FieldsToDestroy = CountRSObjectTypes(C, BaseType, Loc); 659b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines slangAssert(FieldsToDestroy != 0); 660f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 661f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines unsigned StmtCount = 0; 662f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Stmt **StmtArray = new clang::Stmt*[FieldsToDestroy]; 6632bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines for (unsigned i = 0; i < FieldsToDestroy; i++) { 6645abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes StmtArray[i] = nullptr; 6652bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 666f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 667f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Populate StmtArray by creating a destructor for each RS object field 668f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::RecordDecl *RD = BaseType->getAsStructureType()->getDecl(); 669f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RD = RD->getDefinition(); 670f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 671f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FE = RD->field_end(); 672f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI != FE; 673f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI++) { 674f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // We just look through all field declarations to see if we find a 675f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // declaration for an RS object type (or an array of one). 676f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool IsArrayType = false; 677f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::FieldDecl *FD = *FI; 678f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 679f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *OrigType = FT; 680f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines while (FT && FT->isArrayType()) { 681f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 682f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines IsArrayType = true; 683f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 684f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 685cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar // Pass a DeclarationNameInfo with a valid DeclName, since name equality 686cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar // gets asserted during CodeGen. 687cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar clang::DeclarationNameInfo FDDeclNameInfo(FD->getDeclName(), 688cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar FD->getLocation()); 689cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar 690f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (RSExportPrimitiveType::IsRSObjectType(FT)) { 691f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair FoundDecl = 692f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair::make(FD, clang::AS_none); 693f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr *RSObjectMember = 694f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr::Create(C, 695f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSStruct, 696f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines false, 6970b7545898dcfe2979f2c13afd12d276fc736412dStephen Hines clang::SourceLocation(), 698be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 6990444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 700f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FD, 701f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FoundDecl, 702cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar FDDeclNameInfo, 7035abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 704be27482cdeaf08576bc39b72a15d35d13014a636Logan OrigType->getCanonicalTypeInternal(), 705be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 706be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary); 707f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 708f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(StmtCount < FieldsToDestroy); 709f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 710f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (IsArrayType) { 711f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearArrayRSObject(C, 712f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 713f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 714cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, 715f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 716f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 717f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearSingleRSObject(C, 718f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 719f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 720f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 721d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines } else if (FT->isStructureType() && CountRSObjectTypes(C, FT, Loc)) { 722f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // In this case, we have a nested struct. We may not end up filling all 723f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // of the spaces in StmtArray (sub-structs should handle themselves 724f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // with separate compound statements). 725f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair FoundDecl = 726f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair::make(FD, clang::AS_none); 727f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr *RSObjectMember = 728f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr::Create(C, 729f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSStruct, 730f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines false, 7310b7545898dcfe2979f2c13afd12d276fc736412dStephen Hines clang::SourceLocation(), 732be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 7330444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 734f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FD, 735f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FoundDecl, 736f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclarationNameInfo(), 7375abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 738be27482cdeaf08576bc39b72a15d35d13014a636Logan OrigType->getCanonicalTypeInternal(), 739be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 740be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary); 741f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 742f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (IsArrayType) { 743f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearArrayRSObject(C, 744f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 745f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 746cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, 747f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 748f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 749f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearStructRSObject(C, 750f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 751f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 752cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, 753f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 754f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 755f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 756f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 757f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 758f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(StmtCount > 0); 75923c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines clang::CompoundStmt *CS = new(C) clang::CompoundStmt( 76023c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines C, llvm::makeArrayRef(StmtArray, StmtCount), Loc, Loc); 761f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 762f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines delete [] StmtArray; 763f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 764f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return CS; 765f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines} 766f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 7672bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesstatic clang::Stmt *CreateSingleRSSetObject(clang::ASTContext &C, 7682bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *DstExpr, 7692bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *SrcExpr, 770cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc, 7712bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SourceLocation Loc) { 7722bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *T = DstExpr->getType().getTypePtr(); 7732bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::FunctionDecl *SetObjectFD = RSObjectRefCount::GetRSSetObjectFD(T); 7745abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes slangAssert((SetObjectFD != nullptr) && 7756e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "rsSetObject doesn't cover all RS object types"); 776c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 777c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType SetObjectFDType = SetObjectFD->getType(); 778c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType SetObjectFDArgType[2]; 779c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDArgType[0] = SetObjectFD->getParamDecl(0)->getOriginalType(); 780c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDArgType[1] = SetObjectFD->getParamDecl(1)->getOriginalType(); 781c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 782c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Expr *RefRSSetObjectFD = 783c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::DeclRefExpr::Create(C, 784be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 7850444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 786c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFD, 787e2597ac5a8ba7a45a1d5f342973cd43a3a1932cfShih-wei Liao false, 788c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines Loc, 789be27482cdeaf08576bc39b72a15d35d13014a636Logan SetObjectFDType, 790be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 7915abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr); 792c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 793c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Expr *RSSetObjectFP = 794c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::ImplicitCastExpr::Create(C, 795c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines C.getPointerType(SetObjectFDType), 796c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::CK_FunctionToPointerDecay, 797c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RefRSSetObjectFD, 7985abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 799c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::VK_RValue); 800c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 8011dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines llvm::SmallVector<clang::Expr*, 2> ArgList; 8021dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines ArgList.push_back(new(C) clang::UnaryOperator(DstExpr, 8031dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines clang::UO_AddrOf, 8041dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines SetObjectFDArgType[0], 8051dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines clang::VK_RValue, 8061dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines clang::OK_Ordinary, 8071dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines Loc)); 8081dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines ArgList.push_back(SrcExpr); 809c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 810c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::CallExpr *RSSetObjectCall = 811c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines new(C) clang::CallExpr(C, 812c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RSSetObjectFP, 813c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines ArgList, 814c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFD->getCallResultType(), 815be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 816c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines Loc); 817c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 8182bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return RSSetObjectCall; 8192bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines} 8202bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8212bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesstatic clang::Stmt *CreateStructRSSetObject(clang::ASTContext &C, 8222bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *LHS, 8232bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *RHS, 824cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc, 8252bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SourceLocation Loc); 8262bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 827246fa17206bf78c59a64b2f7d98a6716d5345b81Al Sutton/*static clang::Stmt *CreateArrayRSSetObject(clang::ASTContext &C, 8282bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *DstArr, 8292bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *SrcArr, 830cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc, 8312bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SourceLocation Loc) { 8325abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes clang::DeclContext *DC = nullptr; 8332bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *BaseType = DstArr->getType().getTypePtr(); 8342bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(BaseType->isArrayType()); 8352bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8362bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines int NumArrayElements = ArrayDim(BaseType); 8372bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Actually extract out the base RS object type for use later 8382bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines BaseType = BaseType->getArrayElementTypeNoTypeQual(); 8392bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8405abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes clang::Stmt *StmtArray[2] = {nullptr}; 8412bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines int StmtCtr = 0; 8422bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8432bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (NumArrayElements <= 0) { 8445abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 8452bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 8462bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8472bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Create helper variable for iterating through elements 8482bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::IdentifierInfo& II = C.Idents.get("rsIntIter"); 8492bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VarDecl *IIVD = 8502bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VarDecl::Create(C, 8512bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines DC, 852cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, 8532bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 8542bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines &II, 8552bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 8562bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.getTrivialTypeSourceInfo(C.IntTy), 8572bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SC_None, 8582bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SC_None); 8592bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Decl *IID = (clang::Decl *)IIVD; 8602bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8612bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclGroupRef DGR = clang::DeclGroupRef::Create(C, &IID, 1); 8622bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCtr++] = new(C) clang::DeclStmt(DGR, Loc, Loc); 8632bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8642bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Form the actual loop 8652bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // for (Init; Cond; Inc) 8662bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // RSSetObjectCall; 8672bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8682bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Init -> "rsIntIter = 0" 8692bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclRefExpr *RefrsIntIter = 8702bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclRefExpr::Create(C, 871be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 8722bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines IIVD, 8732bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 874be27482cdeaf08576bc39b72a15d35d13014a636Logan C.IntTy, 875be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 8765abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr); 8772bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8782bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, 8792bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), 0), C.IntTy, Loc); 8802bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8812bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BinaryOperator *Init = 8822bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 8832bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Int0, 8842bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BO_Assign, 8852bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 886be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 887be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 8882bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 8892bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8902bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Cond -> "rsIntIter < NumArrayElements" 8912bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *NumArrayElementsExpr = clang::IntegerLiteral::Create(C, 8922bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), NumArrayElements), C.IntTy, Loc); 8932bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8942bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BinaryOperator *Cond = 8952bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 8962bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NumArrayElementsExpr, 8972bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BO_LT, 8982bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 899be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 900be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 9012bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 9022bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9032bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Inc -> "rsIntIter++" 9042bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::UnaryOperator *Inc = 9052bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::UnaryOperator(RefrsIntIter, 9062bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::UO_PostInc, 9072bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 908be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 909be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 9102bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 9112bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9122bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Body -> "rsSetObject(&Dst[rsIntIter], Src[rsIntIter]);" 9132bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Loop operates on individual array elements 9142bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9152bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *DstArrPtr = 9162bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ImplicitCastExpr::Create(C, 9172bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.getPointerType(BaseType->getCanonicalTypeInternal()), 9182bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::CK_ArrayToPointerDecay, 9192bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines DstArr, 9205abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 9212bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VK_RValue); 9222bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9232bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *DstArrPtrSubscript = 9242bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::ArraySubscriptExpr(DstArrPtr, 9252bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RefrsIntIter, 9262bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines BaseType->getCanonicalTypeInternal(), 927be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 928be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 9292bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 9302bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9312bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *SrcArrPtr = 9322bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ImplicitCastExpr::Create(C, 9332bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.getPointerType(BaseType->getCanonicalTypeInternal()), 9342bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::CK_ArrayToPointerDecay, 9352bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines SrcArr, 9365abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 9372bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VK_RValue); 9382bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9392bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *SrcArrPtrSubscript = 9402bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::ArraySubscriptExpr(SrcArrPtr, 9412bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RefrsIntIter, 9422bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines BaseType->getCanonicalTypeInternal(), 943be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 944be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 9452bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 9462bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 947cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT = RSExportPrimitiveType::GetRSSpecificType(BaseType); 9482bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9495abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes clang::Stmt *RSSetObjectCall = nullptr; 9502bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (BaseType->isArrayType()) { 951d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines RSSetObjectCall = CreateArrayRSSetObject(C, DstArrPtrSubscript, 952cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao SrcArrPtrSubscript, 953cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, Loc); 954cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet } else if (DT == DataTypeUnknown) { 955d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines RSSetObjectCall = CreateStructRSSetObject(C, DstArrPtrSubscript, 956cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao SrcArrPtrSubscript, 957cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, Loc); 9582bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else { 959d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines RSSetObjectCall = CreateSingleRSSetObject(C, DstArrPtrSubscript, 960cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao SrcArrPtrSubscript, 961cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, Loc); 9622bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 9632bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9642bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ForStmt *DestructorLoop = 9652bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::ForStmt(C, 9662bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Init, 9672bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Cond, 9685abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, // no condVar 9692bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Inc, 9702bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSSetObjectCall, 9712bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 9722bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 9732bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 9742bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9752bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCtr++] = DestructorLoop; 9762bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(StmtCtr == 2); 9772bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9782bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::CompoundStmt *CS = 9792bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::CompoundStmt(C, StmtArray, StmtCtr, Loc, Loc); 9802bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9812bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return CS; 982246fa17206bf78c59a64b2f7d98a6716d5345b81Al Sutton} */ 9832bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9842bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesstatic clang::Stmt *CreateStructRSSetObject(clang::ASTContext &C, 9852bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *LHS, 9862bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *RHS, 987cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc, 9882bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SourceLocation Loc) { 9892bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::QualType QT = LHS->getType(); 9902bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *T = QT.getTypePtr(); 9912bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(T->isStructureType()); 9922bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(!RSExportPrimitiveType::IsRSObjectType(T)); 9932bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9942bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Keep an extra slot for the original copy (memcpy) 995d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines unsigned FieldsToSet = CountRSObjectTypes(C, T, Loc) + 1; 9962bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9972bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines unsigned StmtCount = 0; 9982bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Stmt **StmtArray = new clang::Stmt*[FieldsToSet]; 9992bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines for (unsigned i = 0; i < FieldsToSet; i++) { 10005abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes StmtArray[i] = nullptr; 10012bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 10022bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10032bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::RecordDecl *RD = T->getAsStructureType()->getDecl(); 10042bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RD = RD->getDefinition(); 10052bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 10062bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FE = RD->field_end(); 10072bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FI != FE; 10082bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FI++) { 10092bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines bool IsArrayType = false; 10102bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::FieldDecl *FD = *FI; 10112bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 10122bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *OrigType = FT; 10132bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 1014d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines if (!CountRSObjectTypes(C, FT, Loc)) { 10152bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Skip to next if we don't have any viable RS object types 10162bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines continue; 10172bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 10182bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10192bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclAccessPair FoundDecl = 10202bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclAccessPair::make(FD, clang::AS_none); 10212bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr *DstMember = 10222bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr::Create(C, 10232bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines LHS, 10242bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines false, 10250b7545898dcfe2979f2c13afd12d276fc736412dStephen Hines clang::SourceLocation(), 1026be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 10270444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 10282bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FD, 10292bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FoundDecl, 10302bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclarationNameInfo(), 10315abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 1032be27482cdeaf08576bc39b72a15d35d13014a636Logan OrigType->getCanonicalTypeInternal(), 1033be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1034be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary); 10352bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10362bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr *SrcMember = 10372bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr::Create(C, 10382bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RHS, 10392bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines false, 10400b7545898dcfe2979f2c13afd12d276fc736412dStephen Hines clang::SourceLocation(), 1041be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 10420444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 10432bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FD, 10442bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FoundDecl, 10452bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclarationNameInfo(), 10465abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 1047be27482cdeaf08576bc39b72a15d35d13014a636Logan OrigType->getCanonicalTypeInternal(), 1048be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1049be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary); 10502bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10512bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (FT->isArrayType()) { 10522bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 10532bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines IsArrayType = true; 10542bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 10552bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 1056cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT = RSExportPrimitiveType::GetRSSpecificType(FT); 10572bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10582bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (IsArrayType) { 10599207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine &DiagEngine = C.getDiagnostics(); 10609207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine.Report( 10619207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::FullSourceLoc(Loc, C.getSourceManager()), 10629207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine.getCustomDiagID( 10639207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine::Error, 10649207a2e495c8363606861e4f034504ec5c153dabLogan Chien "Arrays of RS object types within structures cannot be copied")); 10652bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // TODO(srhines): Support setting arrays of RS objects 10662bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // StmtArray[StmtCount++] = 1067d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines // CreateArrayRSSetObject(C, DstMember, SrcMember, StartLoc, Loc); 1068cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet } else if (DT == DataTypeUnknown) { 10692bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCount++] = 1070d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines CreateStructRSSetObject(C, DstMember, SrcMember, StartLoc, Loc); 10712bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else if (RSExportPrimitiveType::IsRSObjectType(DT)) { 10722bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCount++] = 1073d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines CreateSingleRSSetObject(C, DstMember, SrcMember, StartLoc, Loc); 10742bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else { 10752bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(false); 10762bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 10772bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 10782bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 1079b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines slangAssert(StmtCount < FieldsToSet); 10802bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10812bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // We still need to actually do the overall struct copy. For simplicity, 10822bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // we just do a straight-up assignment (which will still preserve all 10832bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // the proper RS object reference counts). 10842bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BinaryOperator *CopyStruct = 1085be27482cdeaf08576bc39b72a15d35d13014a636Logan new(C) clang::BinaryOperator(LHS, RHS, clang::BO_Assign, QT, 108623c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines clang::VK_RValue, clang::OK_Ordinary, Loc, 108723c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines false); 10882bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCount++] = CopyStruct; 10892bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 109023c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines clang::CompoundStmt *CS = new(C) clang::CompoundStmt( 109123c4358f12bd9d0ba7166eceebd683db95a41b3fStephen Hines C, llvm::makeArrayRef(StmtArray, StmtCount), Loc, Loc); 10922bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10932bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines delete [] StmtArray; 10942bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10952bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return CS; 10962bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines} 10972bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10982bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines} // namespace 10992bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 11002bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesvoid RSObjectRefCount::Scope::ReplaceRSObjectAssignment( 1101d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines clang::BinaryOperator *AS) { 11022bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 11032bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::QualType QT = AS->getType(); 11042bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 11052bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ASTContext &C = RSObjectRefCount::GetRSSetObjectFD( 11069ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines DataTypeRSAllocation)->getASTContext(); 11072bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 1108832429f6bf4592cfc2ce58f2462f1e8ecdbaaf52Stephen Hines clang::SourceLocation Loc = AS->getExprLoc(); 11099f1d0aa55669b75a718ad2e962fc8c3d8df1a5f4Stephen Hines clang::SourceLocation StartLoc = AS->getLHS()->getExprLoc(); 11105abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes clang::Stmt *UpdatedStmt = nullptr; 11112bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 11122bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (!RSExportPrimitiveType::IsRSObjectType(QT.getTypePtr())) { 11132bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // By definition, this is a struct assignment if we get here 11142bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines UpdatedStmt = 1115d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines CreateStructRSSetObject(C, AS->getLHS(), AS->getRHS(), StartLoc, Loc); 11162bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else { 11172bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines UpdatedStmt = 1118d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines CreateSingleRSSetObject(C, AS->getLHS(), AS->getRHS(), StartLoc, Loc); 11192bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 1120e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1121292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines RSASTReplace R(C); 1122292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines R.ReplaceStmt(mCS, AS, UpdatedStmt); 1123e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines} 1124e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1125e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hinesvoid RSObjectRefCount::Scope::AppendRSObjectInit( 1126e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::VarDecl *VD, 1127e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclStmt *DS, 1128cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT, 1129e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *InitExpr) { 11306e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(VD); 1131e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1132e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (!InitExpr) { 1133e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return; 1134e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 1135e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1136a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::ASTContext &C = RSObjectRefCount::GetRSSetObjectFD( 11379ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines DataTypeRSAllocation)->getASTContext(); 1138a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::SourceLocation Loc = RSObjectRefCount::GetRSSetObjectFD( 11399ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines DataTypeRSAllocation)->getLocation(); 1140cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc = RSObjectRefCount::GetRSSetObjectFD( 11419ae18b2bbee0b08afd400542e863dd665ff76059Stephen Hines DataTypeRSAllocation)->getInnerLocStart(); 1142a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines 1143cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet if (DT == DataTypeIsStruct) { 1144a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 1145a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::DeclRefExpr *RefRSVar = 1146a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::DeclRefExpr::Create(C, 1147be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 11480444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 1149a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines VD, 1150e2597ac5a8ba7a45a1d5f342973cd43a3a1932cfShih-wei Liao false, 1151a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines Loc, 1152be27482cdeaf08576bc39b72a15d35d13014a636Logan T->getCanonicalTypeInternal(), 1153be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 11545abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr); 1155a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines 1156a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::Stmt *RSSetObjectOps = 1157d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines CreateStructRSSetObject(C, RefRSVar, InitExpr, StartLoc, Loc); 1158a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines 1159292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*> StmtList; 1160292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines StmtList.push_back(RSSetObjectOps); 1161292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines AppendAfterStmt(C, mCS, DS, StmtList); 1162f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return; 1163f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 1164f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 1165f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::FunctionDecl *SetObjectFD = RSObjectRefCount::GetRSSetObjectFD(DT); 11665abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes slangAssert((SetObjectFD != nullptr) && 11676e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "rsSetObject doesn't cover all RS object types"); 1168e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1169e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::QualType SetObjectFDType = SetObjectFD->getType(); 1170e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::QualType SetObjectFDArgType[2]; 1171e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDArgType[0] = SetObjectFD->getParamDecl(0)->getOriginalType(); 1172e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDArgType[1] = SetObjectFD->getParamDecl(1)->getOriginalType(); 1173e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1174e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *RefRSSetObjectFD = 1175e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr::Create(C, 1176be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 11770444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 1178e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFD, 1179e2597ac5a8ba7a45a1d5f342973cd43a3a1932cfShih-wei Liao false, 1180e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc, 1181be27482cdeaf08576bc39b72a15d35d13014a636Logan SetObjectFDType, 1182be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 11835abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr); 1184e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1185e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *RSSetObjectFP = 1186e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::ImplicitCastExpr::Create(C, 1187e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines C.getPointerType(SetObjectFDType), 1188e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CK_FunctionToPointerDecay, 1189e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RefRSSetObjectFD, 11905abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 1191e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::VK_RValue); 1192e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1193e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 1194e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr *RefRSVar = 1195e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr::Create(C, 1196be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 11970444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 1198e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD, 1199e2597ac5a8ba7a45a1d5f342973cd43a3a1932cfShih-wei Liao false, 1200e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc, 1201be27482cdeaf08576bc39b72a15d35d13014a636Logan T->getCanonicalTypeInternal(), 1202be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 12035abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr); 1204e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 12051dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines llvm::SmallVector<clang::Expr*, 2> ArgList; 12061dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines ArgList.push_back(new(C) clang::UnaryOperator(RefRSVar, 12071dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines clang::UO_AddrOf, 12081dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines SetObjectFDArgType[0], 12091dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines clang::VK_RValue, 12101dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines clang::OK_Ordinary, 12111dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines Loc)); 12121dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines ArgList.push_back(InitExpr); 1213e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1214e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CallExpr *RSSetObjectCall = 1215e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines new(C) clang::CallExpr(C, 1216e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSSetObjectFP, 1217e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ArgList, 1218e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFD->getCallResultType(), 1219be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1220e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc); 1221e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1222292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*> StmtList; 1223292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines StmtList.push_back(RSSetObjectCall); 1224292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines AppendAfterStmt(C, mCS, DS, StmtList); 1225c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines} 1226c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 12271bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hinesvoid RSObjectRefCount::Scope::InsertLocalVarDestructors() { 12281bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines for (std::list<clang::VarDecl*>::const_iterator I = mRSO.begin(), 12291bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines E = mRSO.end(); 12301bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines I != E; 12311bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines I++) { 1232a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines clang::VarDecl *VD = *I; 12333f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines clang::Stmt *RSClearObjectCall = ClearRSObject(VD, VD->getDeclContext()); 1234a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines if (RSClearObjectCall) { 1235cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar clang::ASTContext &C = (*mRSO.begin())->getASTContext(); 1236cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar // Mark VD as used. It might be unused, except for the destructor. 1237cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar // 'markUsed' has side-effects that are caused only if VD is not already 1238cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar // used. Hence no need for an extra check here. 1239cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar VD->markUsed(C); 1240cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar DestructorVisitor DV(C, 1241a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines mCS, 1242a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines RSClearObjectCall, 1243a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines VD->getSourceRange().getBegin()); 1244a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines DV.Visit(mCS); 1245a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines DV.InsertDestructors(); 12461bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 12471bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 12481bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 12491bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 12503f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hinesclang::Stmt *RSObjectRefCount::Scope::ClearRSObject( 12513f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines clang::VarDecl *VD, 12523f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines clang::DeclContext *DC) { 1253f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(VD); 12541bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::ASTContext &C = VD->getASTContext(); 12551bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::SourceLocation Loc = VD->getLocation(); 1256cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc = VD->getInnerLocStart(); 12571bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 125803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 12591bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Reference expr to target RS object variable 12601bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::DeclRefExpr *RefRSVar = 12611bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::DeclRefExpr::Create(C, 1262be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 12630444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 12641bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines VD, 1265e2597ac5a8ba7a45a1d5f342973cd43a3a1932cfShih-wei Liao false, 12661bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines Loc, 1267be27482cdeaf08576bc39b72a15d35d13014a636Logan T->getCanonicalTypeInternal(), 1268be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 12695abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr); 12701bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1271f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (T->isArrayType()) { 1272cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao return ClearArrayRSObject(C, DC, RefRSVar, StartLoc, Loc); 1273f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 12741bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1275cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT = RSExportPrimitiveType::GetRSSpecificType(T); 12761bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1277cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet if (DT == DataTypeUnknown || 1278cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DT == DataTypeIsStruct) { 1279cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao return ClearStructRSObject(C, DC, RefRSVar, StartLoc, Loc); 1280f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 12811bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1282f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert((RSExportPrimitiveType::IsRSObjectType(DT)) && 1283f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "Should be RS object"); 12841bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1285f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return ClearSingleRSObject(C, RefRSVar, Loc); 12861bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 12871bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1288e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hinesbool RSObjectRefCount::InitializeRSObject(clang::VarDecl *VD, 1289cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType *DT, 1290e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr **InitExpr) { 12916e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(VD && DT && InitExpr); 12924b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 12932d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines 12942d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines // Loop through array types to get to base type 12952d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines while (T && T->isArrayType()) { 12962d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines T = T->getArrayElementTypeNoTypeQual(); 12972d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines } 12982d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines 1299f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool DataTypeIsStructWithRSObject = false; 1300e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines *DT = RSExportPrimitiveType::GetRSSpecificType(T); 13014b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1302cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet if (*DT == DataTypeUnknown) { 1303feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (RSExportPrimitiveType::IsStructureTypeWithRSObject(T)) { 1304cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet *DT = DataTypeIsStruct; 1305f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DataTypeIsStructWithRSObject = true; 1306feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } else { 1307feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines return false; 1308feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 13092d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines } 13104b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1311f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool DataTypeIsRSObject = false; 1312f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (DataTypeIsStructWithRSObject) { 1313f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DataTypeIsRSObject = true; 1314f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 1315f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DataTypeIsRSObject = RSExportPrimitiveType::IsRSObjectType(*DT); 1316f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 1317e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines *InitExpr = VD->getInit(); 1318e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1319e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (!DataTypeIsRSObject && *InitExpr) { 1320e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines // If we already have an initializer for a matrix type, we are done. 1321e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return DataTypeIsRSObject; 13224b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 13234b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1324e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *ZeroInitializer = 1325e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines CreateZeroInitializerForRSSpecificType(*DT, 1326e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->getASTContext(), 1327e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->getLocation()); 1328e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1329e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (ZeroInitializer) { 1330e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ZeroInitializer->setType(T->getCanonicalTypeInternal()); 1331e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->setInit(ZeroInitializer); 1332e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 1333e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1334e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return DataTypeIsRSObject; 13354b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 13364b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 13374b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesclang::Expr *RSObjectRefCount::CreateZeroInitializerForRSSpecificType( 1338cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT, 13394b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ASTContext &C, 13404b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines const clang::SourceLocation &Loc) { 13415abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes clang::Expr *Res = nullptr; 13424b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines switch (DT) { 1343cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeIsStruct: 1344cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeRSElement: 1345cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeRSType: 1346cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeRSAllocation: 1347cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeRSSampler: 1348cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeRSScript: 1349cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeRSMesh: 1350cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeRSPath: 1351cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeRSProgramFragment: 1352cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeRSProgramVertex: 1353cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeRSProgramRaster: 1354cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeRSProgramStore: 1355cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeRSFont: { 13564b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (ImplicitCastExpr 'nullptr_t' 13574b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (IntegerLiteral 0))) 13584b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APInt Zero(C.getTypeSize(C.IntTy), 0); 13594b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, Zero, C.IntTy, Loc); 13604b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *CastToNull = 13614b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ImplicitCastExpr::Create(C, 13624b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines C.NullPtrTy, 13634b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::CK_IntegralToPointer, 13644b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Int0, 13655abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes nullptr, 13664b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::VK_RValue); 13674b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 13681dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines llvm::SmallVector<clang::Expr*, 1>InitList; 13691dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines InitList.push_back(CastToNull); 13701dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines 13711dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines Res = new(C) clang::InitListExpr(C, Loc, InitList, Loc); 13724b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines break; 13734b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 1374cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeRSMatrix2x2: 1375cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeRSMatrix3x3: 1376cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeRSMatrix4x4: { 13774b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // RS matrix is not completely an RS object. They hold data by themselves. 13784b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (InitListExpr rs_matrix2x2 13794b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (InitListExpr float[4] 13804b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 13814b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 13824b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 13834b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0))) 13844b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::QualType FloatTy = C.FloatTy; 13854b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Constructor sets value to 0.0f by default 13864b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APFloat Val(C.getFloatTypeSemantics(FloatTy)); 13874b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::FloatingLiteral *Float0Val = 13884b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::FloatingLiteral::Create(C, 13894b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Val, 13904b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines /* isExact = */true, 13914b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines FloatTy, 13924b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Loc); 13934b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 13944b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines unsigned N = 0; 1395cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet if (DT == DataTypeRSMatrix2x2) 13964b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 2; 1397cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet else if (DT == DataTypeRSMatrix3x3) 13984b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 3; 1399cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet else if (DT == DataTypeRSMatrix4x4) 14004b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 4; 14011dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines unsigned N_2 = N * N; 14024b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 14031dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines // Assume we are going to be allocating 16 elements, since 4x4 is max. 14041dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines llvm::SmallVector<clang::Expr*, 16> InitVals; 14051dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines for (unsigned i = 0; i < N_2; i++) 14061dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines InitVals.push_back(Float0Val); 14074b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *InitExpr = 14081dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines new(C) clang::InitListExpr(C, Loc, InitVals, Loc); 14094b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines InitExpr->setType(C.getConstantArrayType(FloatTy, 14101dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines llvm::APInt(32, N_2), 14114b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ArrayType::Normal, 14124b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines /* EltTypeQuals = */0)); 14131dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines llvm::SmallVector<clang::Expr*, 1> InitExprVec; 14141dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines InitExprVec.push_back(InitExpr); 14154b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 14161dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines Res = new(C) clang::InitListExpr(C, Loc, InitExprVec, Loc); 14174b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines break; 14184b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 1419cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeUnknown: 1420cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeFloat16: 1421cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeFloat32: 1422cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeFloat64: 1423cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeSigned8: 1424cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeSigned16: 1425cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeSigned32: 1426cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeSigned64: 1427cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeUnsigned8: 1428cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeUnsigned16: 1429cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeUnsigned32: 1430cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeUnsigned64: 1431cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeBoolean: 1432cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeUnsigned565: 1433cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeUnsigned5551: 1434cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeUnsigned4444: 1435cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet case DataTypeMax: { 14366e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Not RS object type!"); 14374b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 14384b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // No default case will enable compiler detecting the missing cases 14394b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 14404b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 14414b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return Res; 14424b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 14434b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 14444b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitDeclStmt(clang::DeclStmt *DS) { 14454b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (clang::DeclStmt::decl_iterator I = DS->decl_begin(), E = DS->decl_end(); 14464b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I != E; 14474b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I++) { 14484b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Decl *D = *I; 14494b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (D->getKind() == clang::Decl::Var) { 14504b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::VarDecl *VD = static_cast<clang::VarDecl*>(D); 1451cec9b65aa890dea58e39951900ae13efb8d11703Jean-Luc Brouillet DataType DT = DataTypeUnknown; 14525abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes clang::Expr *InitExpr = nullptr; 1453e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (InitializeRSObject(VD, &DT, &InitExpr)) { 1454b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines // We need to zero-init all RS object types (including matrices), ... 1455d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines getCurrentScope()->AppendRSObjectInit(VD, DS, DT, InitExpr); 1456b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines // ... but, only add to the list of RS objects if we have some 1457b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines // non-matrix RS object fields. 1458b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines if (CountRSObjectTypes(mCtx, VD->getType().getTypePtr(), 1459b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines VD->getLocation())) { 1460b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines getCurrentScope()->addRSObject(VD); 1461b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines } 1462e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 14634b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 14644b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 14654b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 14664b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 14674b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitCompoundStmt(clang::CompoundStmt *CS) { 14684b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (!CS->body_empty()) { 14694b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Push a new scope 14704b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Scope *S = new Scope(CS); 14714b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines mScopeStack.push(S); 14724b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 14734b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines VisitStmt(CS); 14744b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 14754b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Destroy the scope 14766e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((getCurrentScope() == S) && "Corrupted scope stack!"); 14771bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines S->InsertLocalVarDestructors(); 14784b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines mScopeStack.pop(); 14794b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines delete S; 14804b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 14814b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 14824b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 14834b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitBinAssign(clang::BinaryOperator *AS) { 1484c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType QT = AS->getType(); 1485c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 1486d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines if (CountRSObjectTypes(mCtx, QT.getTypePtr(), AS->getExprLoc())) { 1487d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines getCurrentScope()->ReplaceRSObjectAssignment(AS); 1488c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 14894b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 14904b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 14914b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitStmt(clang::Stmt *S) { 14924b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end(); 14934b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I != E; 14944b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I++) { 14954b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (clang::Stmt *Child = *I) { 14964b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Visit(Child); 14974b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 14984b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 14994b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 15004b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1501688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines// This function walks the list of global variables and (potentially) creates 1502688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines// a single global static destructor function that properly decrements 1503688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines// reference counts on the contained RS object types. 1504688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hinesclang::FunctionDecl *RSObjectRefCount::CreateStaticGlobalDtor() { 1505688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines Init(); 1506688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 1507688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines clang::DeclContext *DC = mCtx.getTranslationUnitDecl(); 1508688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines clang::SourceLocation loc; 1509688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 15103f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines llvm::StringRef SR(".rs.dtor"); 15113f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines clang::IdentifierInfo &II = mCtx.Idents.get(SR); 15123f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines clang::DeclarationName N(&II); 15133f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines clang::FunctionProtoType::ExtProtoInfo EPI; 151482d7288620fade361dd8f7408b5db54a55c2c794Stephen Hines clang::QualType T = mCtx.getFunctionType(mCtx.VoidTy, 151582d7288620fade361dd8f7408b5db54a55c2c794Stephen Hines llvm::ArrayRef<clang::QualType>(), EPI); 15165abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes clang::FunctionDecl *FD = nullptr; 15173f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines 1518688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines // Generate rsClearObject() call chains for every global variable 1519688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines // (whether static or extern). 1520688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines std::list<clang::Stmt *> StmtList; 1521688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines for (clang::DeclContext::decl_iterator I = DC->decls_begin(), 1522688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines E = DC->decls_end(); I != E; I++) { 1523688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines clang::VarDecl *VD = llvm::dyn_cast<clang::VarDecl>(*I); 1524688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines if (VD) { 1525688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines if (CountRSObjectTypes(mCtx, VD->getType().getTypePtr(), loc)) { 15263f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines if (!FD) { 15273f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines // Only create FD if we are going to use it. 15285abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes FD = clang::FunctionDecl::Create(mCtx, DC, loc, loc, N, T, nullptr, 15294b3f3bada7155de983e7d92fa8b20091629b3bb3Stephen Hines clang::SC_None); 15303f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines } 1531cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar // Mark VD as used. It might be unused, except for the destructor. 1532cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar // 'markUsed' has side-effects that are caused only if VD is not already 1533cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar // used. Hence no need for an extra check here. 1534cc4d93488b344cbdb0d65c3af076f02dbf2ceb00Pirama Arumuga Nainar VD->markUsed(mCtx); 15353f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines // Make sure to create any helpers within the function's DeclContext, 15363f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines // not the one associated with the global translation unit. 15373f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines clang::Stmt *RSClearObjectCall = Scope::ClearRSObject(VD, FD); 1538688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines StmtList.push_back(RSClearObjectCall); 1539688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines } 1540688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines } 1541688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines } 1542688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 1543688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines // Nothing needs to be destroyed, so don't emit a dtor. 1544688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines if (StmtList.empty()) { 15455abbe0e9ca2508260b627ffef2bf01e2554e8357Chris Wailes return nullptr; 1546688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines } 1547688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 1548688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines clang::CompoundStmt *CS = BuildCompoundStmt(mCtx, StmtList, loc); 1549688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 1550688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines FD->setBody(CS); 1551688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 1552688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines return FD; 1553688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines} 1554688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 1555e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 1556