slang_rs_object_ref_count.cpp revision cc887ba8fe42cca706caae636932ae6a61a30ed2
14b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines/* 24b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * Copyright 2010, The Android Open Source Project 34b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * 44b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * Licensed under the Apache License, Version 2.0 (the "License"); 54b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * you may not use this file except in compliance with the License. 64b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * You may obtain a copy of the License at 74b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * 84b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * http://www.apache.org/licenses/LICENSE-2.0 94b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * 104b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * Unless required by applicable law or agreed to in writing, software 114b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * distributed under the License is distributed on an "AS IS" BASIS, 124b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * See the License for the specific language governing permissions and 144b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines * limitations under the License. 154b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines */ 164b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 174b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "slang_rs_object_ref_count.h" 184b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 19e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include <list> 20e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 214b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "clang/AST/DeclGroup.h" 224b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "clang/AST/Expr.h" 23be27482cdeaf08576bc39b72a15d35d13014a636Logan#include "clang/AST/NestedNameSpecifier.h" 244b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "clang/AST/OperationKinds.h" 254b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "clang/AST/Stmt.h" 264b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "clang/AST/StmtVisitor.h" 274b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 286e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h" 294b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "slang_rs.h" 30292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines#include "slang_rs_ast_replace.h" 314b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "slang_rs_export_type.h" 324b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 33e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang { 344b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 35f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesclang::FunctionDecl *RSObjectRefCount:: 361bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSSetObjectFD[RSExportPrimitiveType::LastRSObjectType - 371bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSExportPrimitiveType::FirstRSObjectType + 1]; 38f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesclang::FunctionDecl *RSObjectRefCount:: 391bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSClearObjectFD[RSExportPrimitiveType::LastRSObjectType - 401bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSExportPrimitiveType::FirstRSObjectType + 1]; 411bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 42f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesvoid RSObjectRefCount::GetRSRefCountingFunctions(clang::ASTContext &C) { 431bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines for (unsigned i = 0; 441bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines i < (sizeof(RSClearObjectFD) / sizeof(clang::FunctionDecl*)); 451bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines i++) { 461bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSSetObjectFD[i] = NULL; 471bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSClearObjectFD[i] = NULL; 481bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 491bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 501bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl(); 511bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 521bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(), 531bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines E = TUDecl->decls_end(); I != E; I++) { 541bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if ((I->getKind() >= clang::Decl::firstFunction) && 551bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines (I->getKind() <= clang::Decl::lastFunction)) { 561bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::FunctionDecl *FD = static_cast<clang::FunctionDecl*>(*I); 571bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 581bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // points to RSSetObjectFD or RSClearObjectFD 591bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::FunctionDecl **RSObjectFD; 601bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 611bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if (FD->getName() == "rsSetObject") { 626e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((FD->getNumParams() == 2) && 636e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "Invalid rsSetObject function prototype (# params)"); 641bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSObjectFD = RSSetObjectFD; 651bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } else if (FD->getName() == "rsClearObject") { 666e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((FD->getNumParams() == 1) && 676e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "Invalid rsClearObject function prototype (# params)"); 681bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSObjectFD = RSClearObjectFD; 69e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines } else { 701bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines continue; 711bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 721bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 731bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines const clang::ParmVarDecl *PVD = FD->getParamDecl(0); 741bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::QualType PVT = PVD->getOriginalType(); 751bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // The first parameter must be a pointer like rs_allocation* 766e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(PVT->isPointerType() && 776e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "Invalid rs{Set,Clear}Object function prototype (pointer param)"); 781bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 791bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // The rs object type passed to the FD 801bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::QualType RST = PVT->getPointeeType(); 811bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSExportPrimitiveType::DataType DT = 821bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSExportPrimitiveType::GetRSSpecificType(RST.getTypePtr()); 836e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(RSExportPrimitiveType::IsRSObjectType(DT) 841bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines && "must be RS object type"); 851bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 861bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSObjectFD[(DT - RSExportPrimitiveType::FirstRSObjectType)] = FD; 871bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 881bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 891bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 901bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 914464d825c11349068f2917f9ebee86b721423f3cStephen Hinesnamespace { 924464d825c11349068f2917f9ebee86b721423f3cStephen Hines 93292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines// This function constructs a new CompoundStmt from the input StmtList. 94292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesstatic clang::CompoundStmt* BuildCompoundStmt(clang::ASTContext &C, 95292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*> &StmtList, clang::SourceLocation Loc) { 96d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines unsigned NewStmtCount = StmtList.size(); 97292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines unsigned CompoundStmtCount = 0; 981bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 99292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines clang::Stmt **CompoundStmtList; 100292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines CompoundStmtList = new clang::Stmt*[NewStmtCount]; 1011bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 102292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*>::const_iterator I = StmtList.begin(); 103292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*>::const_iterator E = StmtList.end(); 104292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines for ( ; I != E; I++) { 105292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines CompoundStmtList[CompoundStmtCount++] = *I; 1061bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 107292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines slangAssert(CompoundStmtCount == NewStmtCount); 1081bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 109292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines clang::CompoundStmt *CS = new(C) clang::CompoundStmt(C, 110292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines CompoundStmtList, 111292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines CompoundStmtCount, 112292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines Loc, 113292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines Loc); 1141bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 115292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines delete [] CompoundStmtList; 1161bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 117292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return CS; 1181bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 1191bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 120292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesstatic void AppendAfterStmt(clang::ASTContext &C, 121e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CompoundStmt *CS, 122292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines clang::Stmt *S, 123292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*> &StmtList) { 124292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines slangAssert(CS); 125e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CompoundStmt::body_iterator bI = CS->body_begin(); 126292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines clang::CompoundStmt::body_iterator bE = CS->body_end(); 127292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines clang::Stmt **UpdatedStmtList = 128292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines new clang::Stmt*[CS->size() + StmtList.size()]; 129e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 130e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines unsigned UpdatedStmtCount = 0; 131e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines unsigned Once = 0; 132292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines for ( ; bI != bE; bI++) { 133292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if (!S && ((*bI)->getStmtClass() == clang::Stmt::ReturnStmtClass)) { 134292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // If we come across a return here, we don't have anything we can 135292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // reasonably replace. We should have already inserted our destructor 136292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // code in the proper spot, so we just clean up and return. 137292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines delete [] UpdatedStmtList; 138292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 139292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return; 140e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 141e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 142292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines UpdatedStmtList[UpdatedStmtCount++] = *bI; 143c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 144292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if ((*bI == S) && !Once) { 145292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines Once++; 146292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*>::const_iterator I = StmtList.begin(); 147292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*>::const_iterator E = StmtList.end(); 148292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines for ( ; I != E; I++) { 149292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines UpdatedStmtList[UpdatedStmtCount++] = *I; 150292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 151292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 152c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 153292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines slangAssert(Once <= 1); 154c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 155292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // When S is NULL, we are appending to the end of the CompoundStmt. 156292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if (!S) { 157292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines slangAssert(Once == 0); 158292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*>::const_iterator I = StmtList.begin(); 159292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*>::const_iterator E = StmtList.end(); 160292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines for ( ; I != E; I++) { 161292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines UpdatedStmtList[UpdatedStmtCount++] = *I; 162c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 163c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 164c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 165c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines CS->setStmts(C, UpdatedStmtList, UpdatedStmtCount); 166c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 167c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines delete [] UpdatedStmtList; 168c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 169c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines return; 170c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines} 171c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 172d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines// This class visits a compound statement and inserts the StmtList containing 1734464d825c11349068f2917f9ebee86b721423f3cStephen Hines// destructors in proper locations. This includes inserting them before any 1744464d825c11349068f2917f9ebee86b721423f3cStephen Hines// return statement in any sub-block, at the end of the logical enclosing 1754464d825c11349068f2917f9ebee86b721423f3cStephen Hines// scope (compound statement), and/or before any break/continue statement that 1764464d825c11349068f2917f9ebee86b721423f3cStephen Hines// would resume outside the declared scope. We will not handle the case for 1774464d825c11349068f2917f9ebee86b721423f3cStephen Hines// goto statements that leave a local scope. 178292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines// 179292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines// To accomplish these goals, it collects a list of sub-Stmt's that 180292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines// correspond to scope exit points. It then uses an RSASTReplace visitor to 181292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines// transform the AST, inserting appropriate destructors before each of those 182292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines// sub-Stmt's (and also before the exit of the outermost containing Stmt for 183292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines// the scope). 1844464d825c11349068f2917f9ebee86b721423f3cStephen Hinesclass DestructorVisitor : public clang::StmtVisitor<DestructorVisitor> { 1854464d825c11349068f2917f9ebee86b721423f3cStephen Hines private: 1864464d825c11349068f2917f9ebee86b721423f3cStephen Hines clang::ASTContext &mC; 187292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 188292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // The loop depth of the currently visited node. 189292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines int mLoopDepth; 190292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 191292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // The switch statement depth of the currently visited node. 192292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // Note that this is tracked separately from the loop depth because 193292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // SwitchStmt-contained ContinueStmt's should have destructors for the 194292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // corresponding loop scope. 195292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines int mSwitchDepth; 196292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 197292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // The outermost statement block that we are currently visiting. 198292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // This should always be a CompoundStmt. 199292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines clang::Stmt *mOuterStmt; 200292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 201292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // The list of destructors to execute for this scope. 202d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines std::list<clang::Stmt*> &mStmtList; 203292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 204292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // The stack of statements which should be replaced by a compound statement 205292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // containing the new destructor calls followed by the original Stmt. 206292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::stack<clang::Stmt*> mReplaceStmtStack; 207292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 2084464d825c11349068f2917f9ebee86b721423f3cStephen Hines public: 209292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines DestructorVisitor(clang::ASTContext &C, 210292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines clang::Stmt* OuterStmt, 211292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*> &StmtList); 212292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 213292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // This code walks the collected list of Stmts to replace and actually does 214292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // the replacement. It also finishes up by appending appropriate destructors 215292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // to the current outermost CompoundStmt. 216292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void InsertDestructors() { 217292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines clang::Stmt *S = NULL; 218292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines while (!mReplaceStmtStack.empty()) { 219292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines S = mReplaceStmtStack.top(); 220292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mReplaceStmtStack.pop(); 221292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 222292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mStmtList.push_back(S); 223292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines clang::CompoundStmt *CS = 224292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines BuildCompoundStmt(mC, mStmtList, S->getLocEnd()); 225292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mStmtList.pop_back(); 226292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 227292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines RSASTReplace R(mC); 228292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines R.ReplaceStmt(mOuterStmt, S, CS); 229292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 230292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines clang::CompoundStmt *CS = dyn_cast<clang::CompoundStmt>(mOuterStmt); 231292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines slangAssert(CS); 232292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if (CS) { 233292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines AppendAfterStmt(mC, CS, NULL, mStmtList); 234292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 235292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 236292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 2374464d825c11349068f2917f9ebee86b721423f3cStephen Hines void VisitStmt(clang::Stmt *S); 2384464d825c11349068f2917f9ebee86b721423f3cStephen Hines void VisitCompoundStmt(clang::CompoundStmt *CS); 239292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 240292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitBreakStmt(clang::BreakStmt *BS); 241292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitCaseStmt(clang::CaseStmt *CS); 242292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitContinueStmt(clang::ContinueStmt *CS); 243292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitDefaultStmt(clang::DefaultStmt *DS); 244292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitDoStmt(clang::DoStmt *DS); 245292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitForStmt(clang::ForStmt *FS); 246292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitIfStmt(clang::IfStmt *IS); 247292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitReturnStmt(clang::ReturnStmt *RS); 248292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitSwitchCase(clang::SwitchCase *SC); 249292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitSwitchStmt(clang::SwitchStmt *SS); 250292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitWhileStmt(clang::WhileStmt *WS); 2514464d825c11349068f2917f9ebee86b721423f3cStephen Hines}; 2524464d825c11349068f2917f9ebee86b721423f3cStephen Hines 2534464d825c11349068f2917f9ebee86b721423f3cStephen HinesDestructorVisitor::DestructorVisitor(clang::ASTContext &C, 254292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines clang::Stmt *OuterStmt, 255292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*> &StmtList) 2564464d825c11349068f2917f9ebee86b721423f3cStephen Hines : mC(C), 257292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth(0), 258292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mSwitchDepth(0), 259292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mOuterStmt(OuterStmt), 260292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mStmtList(StmtList) { 2614464d825c11349068f2917f9ebee86b721423f3cStephen Hines return; 2624464d825c11349068f2917f9ebee86b721423f3cStephen Hines} 2634464d825c11349068f2917f9ebee86b721423f3cStephen Hines 2644464d825c11349068f2917f9ebee86b721423f3cStephen Hinesvoid DestructorVisitor::VisitStmt(clang::Stmt *S) { 2654464d825c11349068f2917f9ebee86b721423f3cStephen Hines for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end(); 2664464d825c11349068f2917f9ebee86b721423f3cStephen Hines I != E; 2674464d825c11349068f2917f9ebee86b721423f3cStephen Hines I++) { 2684464d825c11349068f2917f9ebee86b721423f3cStephen Hines if (clang::Stmt *Child = *I) { 2694464d825c11349068f2917f9ebee86b721423f3cStephen Hines Visit(Child); 2704464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 2714464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 2724464d825c11349068f2917f9ebee86b721423f3cStephen Hines return; 2734464d825c11349068f2917f9ebee86b721423f3cStephen Hines} 2744464d825c11349068f2917f9ebee86b721423f3cStephen Hines 275292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitCompoundStmt(clang::CompoundStmt *CS) { 276292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(CS); 277292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return; 278292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 279292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 280292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitBreakStmt(clang::BreakStmt *BS) { 281292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(BS); 282292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if ((mLoopDepth == 0) && (mSwitchDepth == 0)) { 283292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mReplaceStmtStack.push(BS); 284292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 285292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return; 286292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 287292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 288292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitCaseStmt(clang::CaseStmt *CS) { 289292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(CS); 290292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return; 291292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 292292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 293292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitContinueStmt(clang::ContinueStmt *CS) { 294292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(CS); 295292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if (mLoopDepth == 0) { 296292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // Switch statements can have nested continues. 297292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mReplaceStmtStack.push(CS); 298292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 299292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return; 300292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 301292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 302292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitDefaultStmt(clang::DefaultStmt *DS) { 303292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(DS); 304292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return; 305292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 306292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 307292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitDoStmt(clang::DoStmt *DS) { 308292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth++; 309292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(DS); 310292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth--; 311292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return; 312292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 313292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 314292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitForStmt(clang::ForStmt *FS) { 315292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth++; 316292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(FS); 317292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth--; 318292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return; 319292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 320292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 321292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitIfStmt(clang::IfStmt *IS) { 322292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(IS); 323292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return; 324292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 325292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 326292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitReturnStmt(clang::ReturnStmt *RS) { 327292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mReplaceStmtStack.push(RS); 328292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return; 329292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 330292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 331292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitSwitchCase(clang::SwitchCase *SC) { 332292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines slangAssert(false && "Both case and default have specialized handlers"); 333292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(SC); 334292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return; 335292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 336292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 337292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitSwitchStmt(clang::SwitchStmt *SS) { 338292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mSwitchDepth++; 339292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(SS); 340292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mSwitchDepth--; 341292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return; 342292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 343292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 344292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitWhileStmt(clang::WhileStmt *WS) { 345292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth++; 346292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(WS); 347292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth--; 348292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return; 349292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 350292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 351f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesclang::Expr *ClearSingleRSObject(clang::ASTContext &C, 352f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSVar, 353f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc) { 354f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(RefRSVar); 355f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *T = RefRSVar->getType().getTypePtr(); 356f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(!T->isArrayType() && 357f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "Should not be destroying arrays with this function"); 358f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 359f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::FunctionDecl *ClearObjectFD = RSObjectRefCount::GetRSClearObjectFD(T); 360f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert((ClearObjectFD != NULL) && 361f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "rsClearObject doesn't cover all RS object types"); 362f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 363f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::QualType ClearObjectFDType = ClearObjectFD->getType(); 364f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::QualType ClearObjectFDArgType = 365f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD->getParamDecl(0)->getOriginalType(); 366f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 367f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Example destructor for "rs_font localFont;" 368f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // 369f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (CallExpr 'void' 370f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (ImplicitCastExpr 'void (*)(rs_font *)' <FunctionToPointerDecay> 371f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (DeclRefExpr 'void (rs_font *)' FunctionDecl='rsClearObject')) 372f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (UnaryOperator 'rs_font *' prefix '&' 373f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (DeclRefExpr 'rs_font':'rs_font' Var='localFont'))) 374f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 375f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Get address of targeted RS object 376f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *AddrRefRSVar = 377f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::UnaryOperator(RefRSVar, 378f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::UO_AddrOf, 379f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFDArgType, 380be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 381be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 382f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 383f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 384f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSClearObjectFD = 385f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclRefExpr::Create(C, 386be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 387f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD, 388f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD->getLocation(), 389be27482cdeaf08576bc39b72a15d35d13014a636Logan ClearObjectFDType, 390be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 391be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 392f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 393f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RSClearObjectFP = 394f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ImplicitCastExpr::Create(C, 395f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines C.getPointerType(ClearObjectFDType), 396f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::CK_FunctionToPointerDecay, 397f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSClearObjectFD, 398f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines NULL, 399f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::VK_RValue); 40003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 401f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::CallExpr *RSClearObjectCall = 402f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::CallExpr(C, 403f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectFP, 404f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines &AddrRefRSVar, 405f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 1, 406f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD->getCallResultType(), 407be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 408f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 409f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 410f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return RSClearObjectCall; 411f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines} 412f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 413f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic int ArrayDim(const clang::Type *T) { 41403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (!T || !T->isArrayType()) { 41503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return 0; 41603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 41703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 41803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines const clang::ConstantArrayType *CAT = 41903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines static_cast<const clang::ConstantArrayType *>(T); 4209d2c0fa6490e09b3ff5603796bce42d97788e5c8Stephen Hines return static_cast<int>(CAT->getSize().getSExtValue()); 42103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines} 42203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 423f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic clang::Stmt *ClearStructRSObject( 424f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ASTContext &C, 425f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC, 426f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSStruct, 427cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation SourceLoc, 428f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc); 429f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 430f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic clang::Stmt *ClearArrayRSObject( 431f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ASTContext &C, 432f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC, 433f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSArr, 434cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc, 435f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc) { 436f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *BaseType = RefRSArr->getType().getTypePtr(); 437f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(BaseType->isArrayType()); 438f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 439f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines int NumArrayElements = ArrayDim(BaseType); 440f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Actually extract out the base RS object type for use later 441f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines BaseType = BaseType->getArrayElementTypeNoTypeQual(); 44203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 44303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Stmt *StmtArray[2] = {NULL}; 44403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines int StmtCtr = 0; 44503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 44603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (NumArrayElements <= 0) { 44703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return NULL; 44803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 44903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 45003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Example destructor loop for "rs_font fontArr[10];" 45103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // 45203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (CompoundStmt 45303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclStmt "int rsIntIter") 45403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ForStmt 45503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (BinaryOperator 'int' '=' 45603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter') 45703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (IntegerLiteral 'int' 0)) 45803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (BinaryOperator 'int' '<' 45903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter') 46003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (IntegerLiteral 'int' 10) 46103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // NULL << CondVar >> 46203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (UnaryOperator 'int' postfix '++' 46303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter')) 46403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (CallExpr 'void' 46503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ImplicitCastExpr 'void (*)(rs_font *)' <FunctionToPointerDecay> 46603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'void (rs_font *)' FunctionDecl='rsClearObject')) 46703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (UnaryOperator 'rs_font *' prefix '&' 46803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ArraySubscriptExpr 'rs_font':'rs_font' 46903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ImplicitCastExpr 'rs_font *' <ArrayToPointerDecay> 47003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'rs_font [10]' Var='fontArr')) 47103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter'))))))) 47203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 47303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Create helper variable for iterating through elements 47403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::IdentifierInfo& II = C.Idents.get("rsIntIter"); 47503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VarDecl *IIVD = 47603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VarDecl::Create(C, 477f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 478cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, 47903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 48003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines &II, 48103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 48203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.getTrivialTypeSourceInfo(C.IntTy), 48303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::SC_None, 48403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::SC_None); 48503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Decl *IID = (clang::Decl *)IIVD; 48603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 48703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclGroupRef DGR = clang::DeclGroupRef::Create(C, &IID, 1); 48803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines StmtArray[StmtCtr++] = new(C) clang::DeclStmt(DGR, Loc, Loc); 48903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 49003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Form the actual destructor loop 49103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // for (Init; Cond; Inc) 49203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // RSClearObjectCall; 49303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 49403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Init -> "rsIntIter = 0" 49503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclRefExpr *RefrsIntIter = 49603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclRefExpr::Create(C, 497be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 49803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines IIVD, 49903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 500be27482cdeaf08576bc39b72a15d35d13014a636Logan C.IntTy, 501be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 502be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 50303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 50403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, 50503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), 0), C.IntTy, Loc); 50603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 50703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BinaryOperator *Init = 50803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 50903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Int0, 51003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BO_Assign, 51103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 512be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 513be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 51403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 51503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 51603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Cond -> "rsIntIter < NumArrayElements" 51703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *NumArrayElementsExpr = clang::IntegerLiteral::Create(C, 51803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), NumArrayElements), C.IntTy, Loc); 51903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 52003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BinaryOperator *Cond = 52103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 52203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NumArrayElementsExpr, 52303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BO_LT, 52403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 525be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 526be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 52703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 52803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 52903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Inc -> "rsIntIter++" 53003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::UnaryOperator *Inc = 53103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::UnaryOperator(RefrsIntIter, 53203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::UO_PostInc, 53303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 534be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 535be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 53603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 53703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 53803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Body -> "rsClearObject(&VD[rsIntIter]);" 53903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Destructor loop operates on individual array elements 54003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 541f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSArrPtr = 54203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::ImplicitCastExpr::Create(C, 543f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines C.getPointerType(BaseType->getCanonicalTypeInternal()), 54403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::CK_ArrayToPointerDecay, 545f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSArr, 54603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, 54703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VK_RValue); 54803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 549f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSArrPtrSubscript = 550f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::ArraySubscriptExpr(RefRSArrPtr, 55103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines RefrsIntIter, 552f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines BaseType->getCanonicalTypeInternal(), 553be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 554be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 555f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 55603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 557f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::DataType DT = 558f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::GetRSSpecificType(BaseType); 559f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 560f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Stmt *RSClearObjectCall = NULL; 561f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (BaseType->isArrayType()) { 562f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectCall = 563cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao ClearArrayRSObject(C, DC, RefRSArrPtrSubscript, StartLoc, Loc); 564f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else if (DT == RSExportPrimitiveType::DataTypeUnknown) { 565f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectCall = 566cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao ClearStructRSObject(C, DC, RefRSArrPtrSubscript, StartLoc, Loc); 567f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 568f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectCall = ClearSingleRSObject(C, RefRSArrPtrSubscript, Loc); 569f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 57003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 57103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::ForStmt *DestructorLoop = 57203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::ForStmt(C, 57303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Init, 57403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Cond, 57503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, // no condVar 57603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Inc, 57703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines RSClearObjectCall, 57803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 57903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 58003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 58103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 58203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines StmtArray[StmtCtr++] = DestructorLoop; 5836e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(StmtCtr == 2); 58403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 58503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::CompoundStmt *CS = 58603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::CompoundStmt(C, StmtArray, StmtCtr, Loc, Loc); 58703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 58803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return CS; 58903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines} 59003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 5912bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesstatic unsigned CountRSObjectTypes(const clang::Type *T) { 592f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(T); 593f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines unsigned RSObjectCount = 0; 594f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 595f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (T->isArrayType()) { 5962bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return CountRSObjectTypes(T->getArrayElementTypeNoTypeQual()); 597f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 598f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 599f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::DataType DT = 600f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::GetRSSpecificType(T); 601f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (DT != RSExportPrimitiveType::DataTypeUnknown) { 602f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return (RSExportPrimitiveType::IsRSObjectType(DT) ? 1 : 0); 603f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 604f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 605f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (!T->isStructureType()) { 606f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return 0; 607f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 608f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 609f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::RecordDecl *RD = T->getAsStructureType()->getDecl(); 610f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RD = RD->getDefinition(); 611f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 612f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FE = RD->field_end(); 613f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI != FE; 614f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI++) { 615f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::FieldDecl *FD = *FI; 616f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 6172bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (CountRSObjectTypes(FT)) { 618f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Sub-structs should only count once (as should arrays, etc.) 619f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectCount++; 620f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 621f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 622f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 623f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return RSObjectCount; 624f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines} 625f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 626f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic clang::Stmt *ClearStructRSObject( 627f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ASTContext &C, 628f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC, 629f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSStruct, 630cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc, 631f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc) { 632f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *BaseType = RefRSStruct->getType().getTypePtr(); 633f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 634f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(!BaseType->isArrayType()); 635f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 636f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Structs should show up as unknown primitive types 6379be9360d8e02b52ed669afbd69f9becb575c3f0dAlex Sakhartchouk slangAssert(RSExportPrimitiveType::GetRSSpecificType(BaseType) == 6389be9360d8e02b52ed669afbd69f9becb575c3f0dAlex Sakhartchouk RSExportPrimitiveType::DataTypeUnknown); 639f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 6402bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines unsigned FieldsToDestroy = CountRSObjectTypes(BaseType); 641f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 642f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines unsigned StmtCount = 0; 643f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Stmt **StmtArray = new clang::Stmt*[FieldsToDestroy]; 6442bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines for (unsigned i = 0; i < FieldsToDestroy; i++) { 6452bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[i] = NULL; 6462bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 647f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 648f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Populate StmtArray by creating a destructor for each RS object field 649f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::RecordDecl *RD = BaseType->getAsStructureType()->getDecl(); 650f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RD = RD->getDefinition(); 651f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 652f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FE = RD->field_end(); 653f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI != FE; 654f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI++) { 655f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // We just look through all field declarations to see if we find a 656f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // declaration for an RS object type (or an array of one). 657f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool IsArrayType = false; 658f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::FieldDecl *FD = *FI; 659f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 660f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *OrigType = FT; 661f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines while (FT && FT->isArrayType()) { 662f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 663f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines IsArrayType = true; 664f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 665f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 666f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (RSExportPrimitiveType::IsRSObjectType(FT)) { 667f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair FoundDecl = 668f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair::make(FD, clang::AS_none); 669f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr *RSObjectMember = 670f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr::Create(C, 671f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSStruct, 672f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines false, 673be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 674f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FD, 675f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FoundDecl, 676f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclarationNameInfo(), 677f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines NULL, 678be27482cdeaf08576bc39b72a15d35d13014a636Logan OrigType->getCanonicalTypeInternal(), 679be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 680be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary); 681f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 682f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(StmtCount < FieldsToDestroy); 683f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 684f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (IsArrayType) { 685f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearArrayRSObject(C, 686f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 687f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 688cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, 689f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 690f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 691f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearSingleRSObject(C, 692f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 693f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 694f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 6952bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else if (FT->isStructureType() && CountRSObjectTypes(FT)) { 696f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // In this case, we have a nested struct. We may not end up filling all 697f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // of the spaces in StmtArray (sub-structs should handle themselves 698f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // with separate compound statements). 699f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair FoundDecl = 700f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair::make(FD, clang::AS_none); 701f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr *RSObjectMember = 702f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr::Create(C, 703f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSStruct, 704f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines false, 705be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 706f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FD, 707f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FoundDecl, 708f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclarationNameInfo(), 709f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines NULL, 710be27482cdeaf08576bc39b72a15d35d13014a636Logan OrigType->getCanonicalTypeInternal(), 711be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 712be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary); 713f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 714f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (IsArrayType) { 715f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearArrayRSObject(C, 716f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 717f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 718cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, 719f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 720f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 721f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearStructRSObject(C, 722f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 723f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 724cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, 725f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 726f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 727f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 728f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 729f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 730f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(StmtCount > 0); 731f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::CompoundStmt *CS = 732f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::CompoundStmt(C, StmtArray, StmtCount, Loc, Loc); 733f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 734f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines delete [] StmtArray; 735f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 736f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return CS; 737f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines} 738f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 7392bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesstatic clang::Stmt *CreateSingleRSSetObject(clang::ASTContext &C, 7402bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Diagnostic *Diags, 7412bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *DstExpr, 7422bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *SrcExpr, 743cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc, 7442bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SourceLocation Loc) { 7452bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *T = DstExpr->getType().getTypePtr(); 7462bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::FunctionDecl *SetObjectFD = RSObjectRefCount::GetRSSetObjectFD(T); 7476e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((SetObjectFD != NULL) && 7486e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "rsSetObject doesn't cover all RS object types"); 749c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 750c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType SetObjectFDType = SetObjectFD->getType(); 751c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType SetObjectFDArgType[2]; 752c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDArgType[0] = SetObjectFD->getParamDecl(0)->getOriginalType(); 753c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDArgType[1] = SetObjectFD->getParamDecl(1)->getOriginalType(); 754c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 755c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Expr *RefRSSetObjectFD = 756c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::DeclRefExpr::Create(C, 757be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 758c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFD, 759c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines Loc, 760be27482cdeaf08576bc39b72a15d35d13014a636Logan SetObjectFDType, 761be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 762be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 763c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 764c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Expr *RSSetObjectFP = 765c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::ImplicitCastExpr::Create(C, 766c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines C.getPointerType(SetObjectFDType), 767c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::CK_FunctionToPointerDecay, 768c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RefRSSetObjectFD, 769c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines NULL, 770c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::VK_RValue); 771c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 772c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Expr *ArgList[2]; 7732bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines ArgList[0] = new(C) clang::UnaryOperator(DstExpr, 774c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::UO_AddrOf, 775c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDArgType[0], 776be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 777be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 778c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines Loc); 7792bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines ArgList[1] = SrcExpr; 780c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 781c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::CallExpr *RSSetObjectCall = 782c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines new(C) clang::CallExpr(C, 783c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RSSetObjectFP, 784c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines ArgList, 785c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 2, 786c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFD->getCallResultType(), 787be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 788c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines Loc); 789c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 7902bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return RSSetObjectCall; 7912bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines} 7922bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7932bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesstatic clang::Stmt *CreateStructRSSetObject(clang::ASTContext &C, 7942bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Diagnostic *Diags, 7952bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *LHS, 7962bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *RHS, 797cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc, 7982bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SourceLocation Loc); 7992bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8002bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesstatic clang::Stmt *CreateArrayRSSetObject(clang::ASTContext &C, 8012bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Diagnostic *Diags, 8022bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *DstArr, 8032bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *SrcArr, 804cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc, 8052bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SourceLocation Loc) { 8062bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclContext *DC = NULL; 8072bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *BaseType = DstArr->getType().getTypePtr(); 8082bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(BaseType->isArrayType()); 8092bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8102bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines int NumArrayElements = ArrayDim(BaseType); 8112bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Actually extract out the base RS object type for use later 8122bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines BaseType = BaseType->getArrayElementTypeNoTypeQual(); 8132bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8142bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Stmt *StmtArray[2] = {NULL}; 8152bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines int StmtCtr = 0; 8162bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8172bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (NumArrayElements <= 0) { 8182bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return NULL; 8192bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 8202bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8212bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Create helper variable for iterating through elements 8222bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::IdentifierInfo& II = C.Idents.get("rsIntIter"); 8232bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VarDecl *IIVD = 8242bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VarDecl::Create(C, 8252bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines DC, 826cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, 8272bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 8282bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines &II, 8292bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 8302bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.getTrivialTypeSourceInfo(C.IntTy), 8312bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SC_None, 8322bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SC_None); 8332bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Decl *IID = (clang::Decl *)IIVD; 8342bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8352bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclGroupRef DGR = clang::DeclGroupRef::Create(C, &IID, 1); 8362bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCtr++] = new(C) clang::DeclStmt(DGR, Loc, Loc); 8372bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8382bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Form the actual loop 8392bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // for (Init; Cond; Inc) 8402bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // RSSetObjectCall; 8412bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8422bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Init -> "rsIntIter = 0" 8432bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclRefExpr *RefrsIntIter = 8442bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclRefExpr::Create(C, 845be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 8462bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines IIVD, 8472bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 848be27482cdeaf08576bc39b72a15d35d13014a636Logan C.IntTy, 849be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 850be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 8512bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8522bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, 8532bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), 0), C.IntTy, Loc); 8542bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8552bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BinaryOperator *Init = 8562bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 8572bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Int0, 8582bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BO_Assign, 8592bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 860be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 861be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 8622bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 8632bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8642bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Cond -> "rsIntIter < NumArrayElements" 8652bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *NumArrayElementsExpr = clang::IntegerLiteral::Create(C, 8662bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), NumArrayElements), C.IntTy, Loc); 8672bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8682bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BinaryOperator *Cond = 8692bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 8702bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NumArrayElementsExpr, 8712bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BO_LT, 8722bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 873be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 874be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 8752bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 8762bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8772bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Inc -> "rsIntIter++" 8782bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::UnaryOperator *Inc = 8792bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::UnaryOperator(RefrsIntIter, 8802bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::UO_PostInc, 8812bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 882be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 883be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 8842bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 8852bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8862bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Body -> "rsSetObject(&Dst[rsIntIter], Src[rsIntIter]);" 8872bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Loop operates on individual array elements 8882bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8892bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *DstArrPtr = 8902bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ImplicitCastExpr::Create(C, 8912bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.getPointerType(BaseType->getCanonicalTypeInternal()), 8922bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::CK_ArrayToPointerDecay, 8932bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines DstArr, 8942bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NULL, 8952bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VK_RValue); 8962bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8972bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *DstArrPtrSubscript = 8982bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::ArraySubscriptExpr(DstArrPtr, 8992bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RefrsIntIter, 9002bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines BaseType->getCanonicalTypeInternal(), 901be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 902be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 9032bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 9042bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9052bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *SrcArrPtr = 9062bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ImplicitCastExpr::Create(C, 9072bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.getPointerType(BaseType->getCanonicalTypeInternal()), 9082bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::CK_ArrayToPointerDecay, 9092bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines SrcArr, 9102bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NULL, 9112bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VK_RValue); 9122bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9132bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *SrcArrPtrSubscript = 9142bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::ArraySubscriptExpr(SrcArrPtr, 9152bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RefrsIntIter, 9162bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines BaseType->getCanonicalTypeInternal(), 917be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 918be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 9192bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 9202bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9212bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSExportPrimitiveType::DataType DT = 9222bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSExportPrimitiveType::GetRSSpecificType(BaseType); 9232bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9242bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Stmt *RSSetObjectCall = NULL; 9252bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (BaseType->isArrayType()) { 9262bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSSetObjectCall = CreateArrayRSSetObject(C, Diags, DstArrPtrSubscript, 927cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao SrcArrPtrSubscript, 928cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, Loc); 9292bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else if (DT == RSExportPrimitiveType::DataTypeUnknown) { 9302bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSSetObjectCall = CreateStructRSSetObject(C, Diags, DstArrPtrSubscript, 931cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao SrcArrPtrSubscript, 932cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, Loc); 9332bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else { 9342bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSSetObjectCall = CreateSingleRSSetObject(C, Diags, DstArrPtrSubscript, 935cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao SrcArrPtrSubscript, 936cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, Loc); 9372bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 9382bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9392bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ForStmt *DestructorLoop = 9402bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::ForStmt(C, 9412bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Init, 9422bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Cond, 9432bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NULL, // no condVar 9442bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Inc, 9452bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSSetObjectCall, 9462bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 9472bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 9482bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 9492bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9502bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCtr++] = DestructorLoop; 9512bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(StmtCtr == 2); 9522bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9532bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::CompoundStmt *CS = 9542bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::CompoundStmt(C, StmtArray, StmtCtr, Loc, Loc); 9552bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9562bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return CS; 9572bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines} 9582bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9592bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesstatic clang::Stmt *CreateStructRSSetObject(clang::ASTContext &C, 9602bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Diagnostic *Diags, 9612bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *LHS, 9622bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *RHS, 963cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc, 9642bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SourceLocation Loc) { 9652bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::QualType QT = LHS->getType(); 9662bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *T = QT.getTypePtr(); 9672bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(T->isStructureType()); 9682bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(!RSExportPrimitiveType::IsRSObjectType(T)); 9692bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9702bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Keep an extra slot for the original copy (memcpy) 9712bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines unsigned FieldsToSet = CountRSObjectTypes(T) + 1; 9722bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9732bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines unsigned StmtCount = 0; 9742bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Stmt **StmtArray = new clang::Stmt*[FieldsToSet]; 9752bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines for (unsigned i = 0; i < FieldsToSet; i++) { 9762bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[i] = NULL; 9772bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 9782bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9792bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::RecordDecl *RD = T->getAsStructureType()->getDecl(); 9802bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RD = RD->getDefinition(); 9812bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 9822bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FE = RD->field_end(); 9832bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FI != FE; 9842bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FI++) { 9852bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines bool IsArrayType = false; 9862bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::FieldDecl *FD = *FI; 9872bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 9882bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *OrigType = FT; 9892bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9902bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (!CountRSObjectTypes(FT)) { 9912bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Skip to next if we don't have any viable RS object types 9922bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines continue; 9932bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 9942bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9952bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclAccessPair FoundDecl = 9962bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclAccessPair::make(FD, clang::AS_none); 9972bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr *DstMember = 9982bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr::Create(C, 9992bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines LHS, 10002bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines false, 1001be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 10022bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FD, 10032bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FoundDecl, 10042bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclarationNameInfo(), 10052bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NULL, 1006be27482cdeaf08576bc39b72a15d35d13014a636Logan OrigType->getCanonicalTypeInternal(), 1007be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1008be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary); 10092bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10102bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr *SrcMember = 10112bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr::Create(C, 10122bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RHS, 10132bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines false, 1014be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 10152bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FD, 10162bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FoundDecl, 10172bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclarationNameInfo(), 10182bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NULL, 1019be27482cdeaf08576bc39b72a15d35d13014a636Logan OrigType->getCanonicalTypeInternal(), 1020be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1021be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary); 10222bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10232bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (FT->isArrayType()) { 10242bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 10252bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines IsArrayType = true; 10262bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 10272bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10282bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSExportPrimitiveType::DataType DT = 10292bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSExportPrimitiveType::GetRSSpecificType(FT); 10302bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10312bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (IsArrayType) { 1032832429f6bf4592cfc2ce58f2462f1e8ecdbaaf52Stephen Hines Diags->Report(clang::FullSourceLoc(Loc, C.getSourceManager()), 1033832429f6bf4592cfc2ce58f2462f1e8ecdbaaf52Stephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 1034832429f6bf4592cfc2ce58f2462f1e8ecdbaaf52Stephen Hines "Arrays of RS object types within structures cannot be copied")); 10352bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // TODO(srhines): Support setting arrays of RS objects 10362bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // StmtArray[StmtCount++] = 1037cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao // CreateArrayRSSetObject(C, Diags, DstMember, SrcMember, StartLoc, Loc); 10382bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else if (DT == RSExportPrimitiveType::DataTypeUnknown) { 10392bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCount++] = 1040cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao CreateStructRSSetObject(C, Diags, DstMember, SrcMember, 1041cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, Loc); 10422bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else if (RSExportPrimitiveType::IsRSObjectType(DT)) { 10432bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCount++] = 1044cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao CreateSingleRSSetObject(C, Diags, DstMember, SrcMember, 1045cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, Loc); 10462bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else { 10472bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(false); 10482bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 10492bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 10502bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10512bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(StmtCount > 0 && StmtCount < FieldsToSet); 10522bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10532bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // We still need to actually do the overall struct copy. For simplicity, 10542bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // we just do a straight-up assignment (which will still preserve all 10552bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // the proper RS object reference counts). 10562bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BinaryOperator *CopyStruct = 1057be27482cdeaf08576bc39b72a15d35d13014a636Logan new(C) clang::BinaryOperator(LHS, RHS, clang::BO_Assign, QT, 1058be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, clang::OK_Ordinary, Loc); 10592bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCount++] = CopyStruct; 10602bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10612bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::CompoundStmt *CS = 10622bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::CompoundStmt(C, StmtArray, StmtCount, Loc, Loc); 10632bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10642bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines delete [] StmtArray; 10652bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10662bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return CS; 10672bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines} 10682bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10692bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines} // namespace 10702bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10712bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesvoid RSObjectRefCount::Scope::ReplaceRSObjectAssignment( 10722bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BinaryOperator *AS, 10732bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Diagnostic *Diags) { 10742bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10752bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::QualType QT = AS->getType(); 10762bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10772bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ASTContext &C = RSObjectRefCount::GetRSSetObjectFD( 10782bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSExportPrimitiveType::DataTypeRSFont)->getASTContext(); 10792bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 1080832429f6bf4592cfc2ce58f2462f1e8ecdbaaf52Stephen Hines clang::SourceLocation Loc = AS->getExprLoc(); 1081cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc = AS->getExprLoc(); 10822bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Stmt *UpdatedStmt = NULL; 10832bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10842bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (!RSExportPrimitiveType::IsRSObjectType(QT.getTypePtr())) { 10852bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // By definition, this is a struct assignment if we get here 10862bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines UpdatedStmt = 1087cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao CreateStructRSSetObject(C, Diags, AS->getLHS(), AS->getRHS(), 1088cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, Loc); 10892bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else { 10902bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines UpdatedStmt = 1091cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao CreateSingleRSSetObject(C, Diags, AS->getLHS(), AS->getRHS(), 1092cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, Loc); 10932bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 1094e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1095292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines RSASTReplace R(C); 1096292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines R.ReplaceStmt(mCS, AS, UpdatedStmt); 1097e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return; 1098e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines} 1099e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1100e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hinesvoid RSObjectRefCount::Scope::AppendRSObjectInit( 1101a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::Diagnostic *Diags, 1102e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::VarDecl *VD, 1103e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclStmt *DS, 1104e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataType DT, 1105e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *InitExpr) { 11066e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(VD); 1107e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1108e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (!InitExpr) { 1109e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return; 1110e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 1111e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1112a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::ASTContext &C = RSObjectRefCount::GetRSSetObjectFD( 1113a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines RSExportPrimitiveType::DataTypeRSFont)->getASTContext(); 1114a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::SourceLocation Loc = RSObjectRefCount::GetRSSetObjectFD( 1115a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines RSExportPrimitiveType::DataTypeRSFont)->getLocation(); 1116cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc = RSObjectRefCount::GetRSSetObjectFD( 1117cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao RSExportPrimitiveType::DataTypeRSFont)->getInnerLocStart(); 1118a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines 1119f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (DT == RSExportPrimitiveType::DataTypeIsStruct) { 1120a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 1121a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::DeclRefExpr *RefRSVar = 1122a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::DeclRefExpr::Create(C, 1123be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 1124a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines VD, 1125a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines Loc, 1126be27482cdeaf08576bc39b72a15d35d13014a636Logan T->getCanonicalTypeInternal(), 1127be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1128be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 1129a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines 1130a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::Stmt *RSSetObjectOps = 1131cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao CreateStructRSSetObject(C, Diags, RefRSVar, InitExpr, StartLoc, Loc); 1132a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines 1133292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*> StmtList; 1134292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines StmtList.push_back(RSSetObjectOps); 1135292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines AppendAfterStmt(C, mCS, DS, StmtList); 1136f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return; 1137f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 1138f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 1139f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::FunctionDecl *SetObjectFD = RSObjectRefCount::GetRSSetObjectFD(DT); 11406e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((SetObjectFD != NULL) && 11416e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "rsSetObject doesn't cover all RS object types"); 1142e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1143e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::QualType SetObjectFDType = SetObjectFD->getType(); 1144e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::QualType SetObjectFDArgType[2]; 1145e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDArgType[0] = SetObjectFD->getParamDecl(0)->getOriginalType(); 1146e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDArgType[1] = SetObjectFD->getParamDecl(1)->getOriginalType(); 1147e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1148e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *RefRSSetObjectFD = 1149e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr::Create(C, 1150be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 1151e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFD, 1152e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc, 1153be27482cdeaf08576bc39b72a15d35d13014a636Logan SetObjectFDType, 1154be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1155be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 1156e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1157e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *RSSetObjectFP = 1158e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::ImplicitCastExpr::Create(C, 1159e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines C.getPointerType(SetObjectFDType), 1160e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CK_FunctionToPointerDecay, 1161e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RefRSSetObjectFD, 1162e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines NULL, 1163e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::VK_RValue); 1164e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1165e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 1166e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr *RefRSVar = 1167e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr::Create(C, 1168be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 1169e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD, 1170e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc, 1171be27482cdeaf08576bc39b72a15d35d13014a636Logan T->getCanonicalTypeInternal(), 1172be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1173be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 1174e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1175e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *ArgList[2]; 1176e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ArgList[0] = new(C) clang::UnaryOperator(RefRSVar, 1177e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::UO_AddrOf, 1178e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDArgType[0], 1179be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1180be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 1181e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc); 1182e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ArgList[1] = InitExpr; 1183e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1184e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CallExpr *RSSetObjectCall = 1185e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines new(C) clang::CallExpr(C, 1186e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSSetObjectFP, 1187e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ArgList, 1188e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 2, 1189e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFD->getCallResultType(), 1190be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1191e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc); 1192e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1193292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*> StmtList; 1194292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines StmtList.push_back(RSSetObjectCall); 1195292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines AppendAfterStmt(C, mCS, DS, StmtList); 1196c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 1197c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines return; 1198c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines} 1199c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 12001bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hinesvoid RSObjectRefCount::Scope::InsertLocalVarDestructors() { 1201d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines std::list<clang::Stmt*> RSClearObjectCalls; 12021bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines for (std::list<clang::VarDecl*>::const_iterator I = mRSO.begin(), 12031bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines E = mRSO.end(); 12041bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines I != E; 12051bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines I++) { 1206a858cb6f3d9223d65bf73e1230c6324ded4095f6Stephen Hines clang::Stmt *S = ClearRSObject(*I); 1207a858cb6f3d9223d65bf73e1230c6324ded4095f6Stephen Hines if (S) { 1208a858cb6f3d9223d65bf73e1230c6324ded4095f6Stephen Hines RSClearObjectCalls.push_back(S); 12091bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 12101bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 12111bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if (RSClearObjectCalls.size() > 0) { 1212292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines DestructorVisitor DV((*mRSO.begin())->getASTContext(), 1213292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mCS, 1214292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines RSClearObjectCalls); 12154464d825c11349068f2917f9ebee86b721423f3cStephen Hines DV.Visit(mCS); 1216292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines DV.InsertDestructors(); 12171bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 12181bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines return; 12191bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 12201bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1221d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hinesclang::Stmt *RSObjectRefCount::Scope::ClearRSObject(clang::VarDecl *VD) { 1222f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(VD); 12231bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::ASTContext &C = VD->getASTContext(); 1224f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC = VD->getDeclContext(); 12251bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::SourceLocation Loc = VD->getLocation(); 1226cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc = VD->getInnerLocStart(); 12271bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 122803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 12291bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Reference expr to target RS object variable 12301bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::DeclRefExpr *RefRSVar = 12311bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::DeclRefExpr::Create(C, 1232be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 12331bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines VD, 12341bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines Loc, 1235be27482cdeaf08576bc39b72a15d35d13014a636Logan T->getCanonicalTypeInternal(), 1236be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1237be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 12381bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1239f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (T->isArrayType()) { 1240cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao return ClearArrayRSObject(C, DC, RefRSVar, StartLoc, Loc); 1241f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 12421bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1243f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::DataType DT = 1244f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::GetRSSpecificType(T); 12451bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1246f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (DT == RSExportPrimitiveType::DataTypeUnknown || 1247f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DT == RSExportPrimitiveType::DataTypeIsStruct) { 1248cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao return ClearStructRSObject(C, DC, RefRSVar, StartLoc, Loc); 1249f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 12501bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1251f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert((RSExportPrimitiveType::IsRSObjectType(DT)) && 1252f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "Should be RS object"); 12531bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1254f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return ClearSingleRSObject(C, RefRSVar, Loc); 12551bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 12561bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1257e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hinesbool RSObjectRefCount::InitializeRSObject(clang::VarDecl *VD, 1258e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataType *DT, 1259e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr **InitExpr) { 12606e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(VD && DT && InitExpr); 12614b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 12622d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines 12632d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines // Loop through array types to get to base type 12642d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines while (T && T->isArrayType()) { 12652d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines T = T->getArrayElementTypeNoTypeQual(); 12662d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines } 12672d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines 1268f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool DataTypeIsStructWithRSObject = false; 1269e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines *DT = RSExportPrimitiveType::GetRSSpecificType(T); 12704b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1271e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (*DT == RSExportPrimitiveType::DataTypeUnknown) { 1272feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (RSExportPrimitiveType::IsStructureTypeWithRSObject(T)) { 1273feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines *DT = RSExportPrimitiveType::DataTypeIsStruct; 1274f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DataTypeIsStructWithRSObject = true; 1275feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } else { 1276feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines return false; 1277feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 12782d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines } 12794b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1280f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool DataTypeIsRSObject = false; 1281f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (DataTypeIsStructWithRSObject) { 1282f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DataTypeIsRSObject = true; 1283f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 1284f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DataTypeIsRSObject = RSExportPrimitiveType::IsRSObjectType(*DT); 1285f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 1286e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines *InitExpr = VD->getInit(); 1287e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1288e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (!DataTypeIsRSObject && *InitExpr) { 1289e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines // If we already have an initializer for a matrix type, we are done. 1290e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return DataTypeIsRSObject; 12914b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 12924b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1293e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *ZeroInitializer = 1294e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines CreateZeroInitializerForRSSpecificType(*DT, 1295e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->getASTContext(), 1296e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->getLocation()); 1297e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1298e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (ZeroInitializer) { 1299e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ZeroInitializer->setType(T->getCanonicalTypeInternal()); 1300e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->setInit(ZeroInitializer); 1301e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 1302e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1303e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return DataTypeIsRSObject; 13044b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 13054b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 13064b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesclang::Expr *RSObjectRefCount::CreateZeroInitializerForRSSpecificType( 13074b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines RSExportPrimitiveType::DataType DT, 13084b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ASTContext &C, 13094b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines const clang::SourceLocation &Loc) { 13104b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *Res = NULL; 13114b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines switch (DT) { 1312feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines case RSExportPrimitiveType::DataTypeIsStruct: 13134b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSElement: 13144b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSType: 13154b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSAllocation: 13164b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSSampler: 13174b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSScript: 13184b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMesh: 13194b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramFragment: 13204b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramVertex: 13214b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramRaster: 13224b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramStore: 13234b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSFont: { 13244b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (ImplicitCastExpr 'nullptr_t' 13254b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (IntegerLiteral 0))) 13264b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APInt Zero(C.getTypeSize(C.IntTy), 0); 13274b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, Zero, C.IntTy, Loc); 13284b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *CastToNull = 13294b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ImplicitCastExpr::Create(C, 13304b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines C.NullPtrTy, 13314b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::CK_IntegralToPointer, 13324b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Int0, 13334b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines NULL, 13344b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::VK_RValue); 13354b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1336e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Res = new(C) clang::InitListExpr(C, Loc, &CastToNull, 1, Loc); 13374b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines break; 13384b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 13394b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMatrix2x2: 13404b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMatrix3x3: 13414b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMatrix4x4: { 13424b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // RS matrix is not completely an RS object. They hold data by themselves. 13434b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (InitListExpr rs_matrix2x2 13444b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (InitListExpr float[4] 13454b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 13464b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 13474b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 13484b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0))) 13494b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::QualType FloatTy = C.FloatTy; 13504b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Constructor sets value to 0.0f by default 13514b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APFloat Val(C.getFloatTypeSemantics(FloatTy)); 13524b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::FloatingLiteral *Float0Val = 13534b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::FloatingLiteral::Create(C, 13544b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Val, 13554b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines /* isExact = */true, 13564b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines FloatTy, 13574b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Loc); 13584b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 13594b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines unsigned N = 0; 13604b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (DT == RSExportPrimitiveType::DataTypeRSMatrix2x2) 13614b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 2; 13624b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines else if (DT == RSExportPrimitiveType::DataTypeRSMatrix3x3) 13634b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 3; 13644b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines else if (DT == RSExportPrimitiveType::DataTypeRSMatrix4x4) 13654b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 4; 13664b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 13674b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Directly allocate 16 elements instead of dynamically allocate N*N 13684b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *InitVals[16]; 13694b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (unsigned i = 0; i < sizeof(InitVals) / sizeof(InitVals[0]); i++) 13704b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines InitVals[i] = Float0Val; 13714b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *InitExpr = 1372e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines new(C) clang::InitListExpr(C, Loc, InitVals, N * N, Loc); 13734b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines InitExpr->setType(C.getConstantArrayType(FloatTy, 13744b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APInt(32, 4), 13754b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ArrayType::Normal, 13764b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines /* EltTypeQuals = */0)); 13774b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1378e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Res = new(C) clang::InitListExpr(C, Loc, &InitExpr, 1, Loc); 13794b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines break; 13804b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 13814b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnknown: 13824b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeFloat16: 13834b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeFloat32: 13844b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeFloat64: 13854b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned8: 13864b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned16: 13874b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned32: 13884b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned64: 13894b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned8: 13904b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned16: 13914b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned32: 13924b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned64: 13934b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeBoolean: 13944b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned565: 13954b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned5551: 13964b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned4444: 13974b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeMax: { 13986e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Not RS object type!"); 13994b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 14004b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // No default case will enable compiler detecting the missing cases 14014b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 14024b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 14034b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return Res; 14044b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 14054b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 14064b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitDeclStmt(clang::DeclStmt *DS) { 14074b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (clang::DeclStmt::decl_iterator I = DS->decl_begin(), E = DS->decl_end(); 14084b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I != E; 14094b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I++) { 14104b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Decl *D = *I; 14114b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (D->getKind() == clang::Decl::Var) { 14124b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::VarDecl *VD = static_cast<clang::VarDecl*>(D); 1413e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataType DT = 1414e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataTypeUnknown; 1415e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *InitExpr = NULL; 1416e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (InitializeRSObject(VD, &DT, &InitExpr)) { 14174b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines getCurrentScope()->addRSObject(VD); 1418a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines getCurrentScope()->AppendRSObjectInit(mDiags, VD, DS, DT, InitExpr); 1419e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 14204b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 14214b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 14224b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 14234b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 14244b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 14254b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitCompoundStmt(clang::CompoundStmt *CS) { 14264b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (!CS->body_empty()) { 14274b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Push a new scope 14284b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Scope *S = new Scope(CS); 14294b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines mScopeStack.push(S); 14304b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 14314b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines VisitStmt(CS); 14324b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 14334b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Destroy the scope 14346e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((getCurrentScope() == S) && "Corrupted scope stack!"); 14351bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines S->InsertLocalVarDestructors(); 14364b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines mScopeStack.pop(); 14374b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines delete S; 14384b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 14394b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 14404b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 14414b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 14424b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitBinAssign(clang::BinaryOperator *AS) { 1443c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType QT = AS->getType(); 1444c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 14452bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (CountRSObjectTypes(QT.getTypePtr())) { 14462bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines getCurrentScope()->ReplaceRSObjectAssignment(AS, mDiags); 1447c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 1448c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 14494b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 14504b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 14514b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 14524b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitStmt(clang::Stmt *S) { 14534b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end(); 14544b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I != E; 14554b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I++) { 14564b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (clang::Stmt *Child = *I) { 14574b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Visit(Child); 14584b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 14594b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 14604b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 14614b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 14624b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1463e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 1464