slang_rs_object_ref_count.cpp revision 292e00a0259ac28cac1055cb6077cf6fc7c6743c
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, 427f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc); 428f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 429f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic clang::Stmt *ClearArrayRSObject( 430f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ASTContext &C, 431f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC, 432f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSArr, 433f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc) { 434f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *BaseType = RefRSArr->getType().getTypePtr(); 435f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(BaseType->isArrayType()); 436f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 437f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines int NumArrayElements = ArrayDim(BaseType); 438f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Actually extract out the base RS object type for use later 439f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines BaseType = BaseType->getArrayElementTypeNoTypeQual(); 44003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 44103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Stmt *StmtArray[2] = {NULL}; 44203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines int StmtCtr = 0; 44303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 44403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (NumArrayElements <= 0) { 44503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return NULL; 44603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 44703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 44803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Example destructor loop for "rs_font fontArr[10];" 44903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // 45003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (CompoundStmt 45103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclStmt "int rsIntIter") 45203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ForStmt 45303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (BinaryOperator 'int' '=' 45403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter') 45503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (IntegerLiteral 'int' 0)) 45603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (BinaryOperator 'int' '<' 45703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter') 45803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (IntegerLiteral 'int' 10) 45903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // NULL << CondVar >> 46003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (UnaryOperator 'int' postfix '++' 46103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter')) 46203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (CallExpr 'void' 46303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ImplicitCastExpr 'void (*)(rs_font *)' <FunctionToPointerDecay> 46403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'void (rs_font *)' FunctionDecl='rsClearObject')) 46503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (UnaryOperator 'rs_font *' prefix '&' 46603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ArraySubscriptExpr 'rs_font':'rs_font' 46703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ImplicitCastExpr 'rs_font *' <ArrayToPointerDecay> 46803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'rs_font [10]' Var='fontArr')) 46903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter'))))))) 47003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 47103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Create helper variable for iterating through elements 47203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::IdentifierInfo& II = C.Idents.get("rsIntIter"); 47303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VarDecl *IIVD = 47403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VarDecl::Create(C, 475f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 47603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 47703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines &II, 47803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 47903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.getTrivialTypeSourceInfo(C.IntTy), 48003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::SC_None, 48103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::SC_None); 48203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Decl *IID = (clang::Decl *)IIVD; 48303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 48403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclGroupRef DGR = clang::DeclGroupRef::Create(C, &IID, 1); 48503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines StmtArray[StmtCtr++] = new(C) clang::DeclStmt(DGR, Loc, Loc); 48603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 48703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Form the actual destructor loop 48803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // for (Init; Cond; Inc) 48903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // RSClearObjectCall; 49003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 49103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Init -> "rsIntIter = 0" 49203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclRefExpr *RefrsIntIter = 49303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclRefExpr::Create(C, 494be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 49503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines IIVD, 49603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 497be27482cdeaf08576bc39b72a15d35d13014a636Logan C.IntTy, 498be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 499be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 50003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 50103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, 50203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), 0), C.IntTy, Loc); 50303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 50403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BinaryOperator *Init = 50503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 50603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Int0, 50703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BO_Assign, 50803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 509be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 510be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 51103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 51203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 51303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Cond -> "rsIntIter < NumArrayElements" 51403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *NumArrayElementsExpr = clang::IntegerLiteral::Create(C, 51503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), NumArrayElements), C.IntTy, Loc); 51603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 51703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BinaryOperator *Cond = 51803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 51903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NumArrayElementsExpr, 52003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BO_LT, 52103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 522be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 523be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 52403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 52503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 52603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Inc -> "rsIntIter++" 52703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::UnaryOperator *Inc = 52803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::UnaryOperator(RefrsIntIter, 52903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::UO_PostInc, 53003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 531be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 532be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 53303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 53403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 53503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Body -> "rsClearObject(&VD[rsIntIter]);" 53603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Destructor loop operates on individual array elements 53703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 538f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSArrPtr = 53903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::ImplicitCastExpr::Create(C, 540f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines C.getPointerType(BaseType->getCanonicalTypeInternal()), 54103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::CK_ArrayToPointerDecay, 542f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSArr, 54303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, 54403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VK_RValue); 54503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 546f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSArrPtrSubscript = 547f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::ArraySubscriptExpr(RefRSArrPtr, 54803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines RefrsIntIter, 549f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines BaseType->getCanonicalTypeInternal(), 550be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 551be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 552f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 55303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 554f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::DataType DT = 555f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::GetRSSpecificType(BaseType); 556f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 557f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Stmt *RSClearObjectCall = NULL; 558f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (BaseType->isArrayType()) { 559f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectCall = 560be27482cdeaf08576bc39b72a15d35d13014a636Logan ClearArrayRSObject(C, DC, RefRSArrPtrSubscript, Loc); 561f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else if (DT == RSExportPrimitiveType::DataTypeUnknown) { 562f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectCall = 563be27482cdeaf08576bc39b72a15d35d13014a636Logan ClearStructRSObject(C, DC, RefRSArrPtrSubscript, Loc); 564f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 565f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectCall = ClearSingleRSObject(C, RefRSArrPtrSubscript, Loc); 566f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 56703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 56803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::ForStmt *DestructorLoop = 56903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::ForStmt(C, 57003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Init, 57103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Cond, 57203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, // no condVar 57303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Inc, 57403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines RSClearObjectCall, 57503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 57603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 57703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 57803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 57903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines StmtArray[StmtCtr++] = DestructorLoop; 5806e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(StmtCtr == 2); 58103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 58203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::CompoundStmt *CS = 58303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::CompoundStmt(C, StmtArray, StmtCtr, Loc, Loc); 58403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 58503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return CS; 58603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines} 58703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 5882bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesstatic unsigned CountRSObjectTypes(const clang::Type *T) { 589f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(T); 590f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines unsigned RSObjectCount = 0; 591f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 592f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (T->isArrayType()) { 5932bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return CountRSObjectTypes(T->getArrayElementTypeNoTypeQual()); 594f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 595f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 596f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::DataType DT = 597f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::GetRSSpecificType(T); 598f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (DT != RSExportPrimitiveType::DataTypeUnknown) { 599f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return (RSExportPrimitiveType::IsRSObjectType(DT) ? 1 : 0); 600f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 601f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 602f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (!T->isStructureType()) { 603f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return 0; 604f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 605f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 606f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::RecordDecl *RD = T->getAsStructureType()->getDecl(); 607f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RD = RD->getDefinition(); 608f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 609f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FE = RD->field_end(); 610f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI != FE; 611f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI++) { 612f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::FieldDecl *FD = *FI; 613f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 6142bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (CountRSObjectTypes(FT)) { 615f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Sub-structs should only count once (as should arrays, etc.) 616f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectCount++; 617f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 618f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 619f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 620f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return RSObjectCount; 621f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines} 622f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 623f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic clang::Stmt *ClearStructRSObject( 624f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ASTContext &C, 625f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC, 626f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSStruct, 627f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc) { 628f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *BaseType = RefRSStruct->getType().getTypePtr(); 629f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 630f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(!BaseType->isArrayType()); 631f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 632f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Structs should show up as unknown primitive types 6339be9360d8e02b52ed669afbd69f9becb575c3f0dAlex Sakhartchouk slangAssert(RSExportPrimitiveType::GetRSSpecificType(BaseType) == 6349be9360d8e02b52ed669afbd69f9becb575c3f0dAlex Sakhartchouk RSExportPrimitiveType::DataTypeUnknown); 635f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 6362bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines unsigned FieldsToDestroy = CountRSObjectTypes(BaseType); 637f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 638f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines unsigned StmtCount = 0; 639f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Stmt **StmtArray = new clang::Stmt*[FieldsToDestroy]; 6402bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines for (unsigned i = 0; i < FieldsToDestroy; i++) { 6412bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[i] = NULL; 6422bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 643f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 644f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Populate StmtArray by creating a destructor for each RS object field 645f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::RecordDecl *RD = BaseType->getAsStructureType()->getDecl(); 646f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RD = RD->getDefinition(); 647f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 648f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FE = RD->field_end(); 649f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI != FE; 650f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI++) { 651f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // We just look through all field declarations to see if we find a 652f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // declaration for an RS object type (or an array of one). 653f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool IsArrayType = false; 654f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::FieldDecl *FD = *FI; 655f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 656f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *OrigType = FT; 657f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines while (FT && FT->isArrayType()) { 658f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 659f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines IsArrayType = true; 660f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 661f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 662f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (RSExportPrimitiveType::IsRSObjectType(FT)) { 663f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair FoundDecl = 664f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair::make(FD, clang::AS_none); 665f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr *RSObjectMember = 666f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr::Create(C, 667f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSStruct, 668f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines false, 669be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 670f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FD, 671f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FoundDecl, 672f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclarationNameInfo(), 673f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines NULL, 674be27482cdeaf08576bc39b72a15d35d13014a636Logan OrigType->getCanonicalTypeInternal(), 675be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 676be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary); 677f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 678f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(StmtCount < FieldsToDestroy); 679f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 680f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (IsArrayType) { 681f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearArrayRSObject(C, 682f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 683f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 684f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 685f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 686f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearSingleRSObject(C, 687f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 688f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 689f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 6902bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else if (FT->isStructureType() && CountRSObjectTypes(FT)) { 691f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // In this case, we have a nested struct. We may not end up filling all 692f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // of the spaces in StmtArray (sub-structs should handle themselves 693f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // with separate compound statements). 694f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair FoundDecl = 695f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair::make(FD, clang::AS_none); 696f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr *RSObjectMember = 697f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr::Create(C, 698f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSStruct, 699f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines false, 700be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 701f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FD, 702f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FoundDecl, 703f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclarationNameInfo(), 704f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines NULL, 705be27482cdeaf08576bc39b72a15d35d13014a636Logan OrigType->getCanonicalTypeInternal(), 706be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 707be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary); 708f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 709f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (IsArrayType) { 710f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearArrayRSObject(C, 711f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 712f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 713f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 714f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 715f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearStructRSObject(C, 716f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 717f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 718f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 719f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 720f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 721f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 722f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 723f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(StmtCount > 0); 724f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::CompoundStmt *CS = 725f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::CompoundStmt(C, StmtArray, StmtCount, Loc, Loc); 726f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 727f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines delete [] StmtArray; 728f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 729f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return CS; 730f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines} 731f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 7322bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesstatic clang::Stmt *CreateSingleRSSetObject(clang::ASTContext &C, 7332bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Diagnostic *Diags, 7342bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *DstExpr, 7352bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *SrcExpr, 7362bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SourceLocation Loc) { 7372bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *T = DstExpr->getType().getTypePtr(); 7382bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::FunctionDecl *SetObjectFD = RSObjectRefCount::GetRSSetObjectFD(T); 7396e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((SetObjectFD != NULL) && 7406e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "rsSetObject doesn't cover all RS object types"); 741c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 742c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType SetObjectFDType = SetObjectFD->getType(); 743c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType SetObjectFDArgType[2]; 744c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDArgType[0] = SetObjectFD->getParamDecl(0)->getOriginalType(); 745c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDArgType[1] = SetObjectFD->getParamDecl(1)->getOriginalType(); 746c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 747c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Expr *RefRSSetObjectFD = 748c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::DeclRefExpr::Create(C, 749be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 750c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFD, 751c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines Loc, 752be27482cdeaf08576bc39b72a15d35d13014a636Logan SetObjectFDType, 753be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 754be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 755c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 756c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Expr *RSSetObjectFP = 757c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::ImplicitCastExpr::Create(C, 758c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines C.getPointerType(SetObjectFDType), 759c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::CK_FunctionToPointerDecay, 760c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RefRSSetObjectFD, 761c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines NULL, 762c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::VK_RValue); 763c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 764c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Expr *ArgList[2]; 7652bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines ArgList[0] = new(C) clang::UnaryOperator(DstExpr, 766c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::UO_AddrOf, 767c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDArgType[0], 768be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 769be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 770c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines Loc); 7712bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines ArgList[1] = SrcExpr; 772c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 773c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::CallExpr *RSSetObjectCall = 774c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines new(C) clang::CallExpr(C, 775c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RSSetObjectFP, 776c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines ArgList, 777c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 2, 778c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFD->getCallResultType(), 779be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 780c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines Loc); 781c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 7822bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return RSSetObjectCall; 7832bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines} 7842bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7852bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesstatic clang::Stmt *CreateStructRSSetObject(clang::ASTContext &C, 7862bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Diagnostic *Diags, 7872bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *LHS, 7882bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *RHS, 7892bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SourceLocation Loc); 7902bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 7912bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesstatic clang::Stmt *CreateArrayRSSetObject(clang::ASTContext &C, 7922bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Diagnostic *Diags, 7932bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *DstArr, 7942bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *SrcArr, 7952bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SourceLocation Loc) { 7962bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclContext *DC = NULL; 7972bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *BaseType = DstArr->getType().getTypePtr(); 7982bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(BaseType->isArrayType()); 7992bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8002bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines int NumArrayElements = ArrayDim(BaseType); 8012bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Actually extract out the base RS object type for use later 8022bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines BaseType = BaseType->getArrayElementTypeNoTypeQual(); 8032bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8042bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Stmt *StmtArray[2] = {NULL}; 8052bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines int StmtCtr = 0; 8062bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8072bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (NumArrayElements <= 0) { 8082bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return NULL; 8092bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 8102bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8112bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Create helper variable for iterating through elements 8122bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::IdentifierInfo& II = C.Idents.get("rsIntIter"); 8132bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VarDecl *IIVD = 8142bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VarDecl::Create(C, 8152bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines DC, 8162bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 8172bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines &II, 8182bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 8192bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.getTrivialTypeSourceInfo(C.IntTy), 8202bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SC_None, 8212bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SC_None); 8222bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Decl *IID = (clang::Decl *)IIVD; 8232bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8242bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclGroupRef DGR = clang::DeclGroupRef::Create(C, &IID, 1); 8252bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCtr++] = new(C) clang::DeclStmt(DGR, Loc, Loc); 8262bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8272bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Form the actual loop 8282bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // for (Init; Cond; Inc) 8292bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // RSSetObjectCall; 8302bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8312bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Init -> "rsIntIter = 0" 8322bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclRefExpr *RefrsIntIter = 8332bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclRefExpr::Create(C, 834be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 8352bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines IIVD, 8362bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 837be27482cdeaf08576bc39b72a15d35d13014a636Logan C.IntTy, 838be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 839be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 8402bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8412bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, 8422bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), 0), C.IntTy, Loc); 8432bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8442bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BinaryOperator *Init = 8452bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 8462bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Int0, 8472bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BO_Assign, 8482bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 849be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 850be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 8512bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 8522bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8532bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Cond -> "rsIntIter < NumArrayElements" 8542bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *NumArrayElementsExpr = clang::IntegerLiteral::Create(C, 8552bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), NumArrayElements), C.IntTy, Loc); 8562bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8572bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BinaryOperator *Cond = 8582bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 8592bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NumArrayElementsExpr, 8602bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BO_LT, 8612bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 862be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 863be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 8642bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 8652bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8662bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Inc -> "rsIntIter++" 8672bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::UnaryOperator *Inc = 8682bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::UnaryOperator(RefrsIntIter, 8692bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::UO_PostInc, 8702bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 871be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 872be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 8732bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 8742bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8752bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Body -> "rsSetObject(&Dst[rsIntIter], Src[rsIntIter]);" 8762bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Loop operates on individual array elements 8772bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8782bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *DstArrPtr = 8792bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ImplicitCastExpr::Create(C, 8802bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.getPointerType(BaseType->getCanonicalTypeInternal()), 8812bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::CK_ArrayToPointerDecay, 8822bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines DstArr, 8832bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NULL, 8842bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VK_RValue); 8852bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8862bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *DstArrPtrSubscript = 8872bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::ArraySubscriptExpr(DstArrPtr, 8882bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RefrsIntIter, 8892bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines BaseType->getCanonicalTypeInternal(), 890be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 891be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 8922bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 8932bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8942bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *SrcArrPtr = 8952bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ImplicitCastExpr::Create(C, 8962bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.getPointerType(BaseType->getCanonicalTypeInternal()), 8972bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::CK_ArrayToPointerDecay, 8982bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines SrcArr, 8992bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NULL, 9002bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VK_RValue); 9012bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9022bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *SrcArrPtrSubscript = 9032bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::ArraySubscriptExpr(SrcArrPtr, 9042bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RefrsIntIter, 9052bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines BaseType->getCanonicalTypeInternal(), 906be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 907be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 9082bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 9092bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9102bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSExportPrimitiveType::DataType DT = 9112bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSExportPrimitiveType::GetRSSpecificType(BaseType); 9122bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9132bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Stmt *RSSetObjectCall = NULL; 9142bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (BaseType->isArrayType()) { 9152bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSSetObjectCall = CreateArrayRSSetObject(C, Diags, DstArrPtrSubscript, 9162bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines SrcArrPtrSubscript, Loc); 9172bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else if (DT == RSExportPrimitiveType::DataTypeUnknown) { 9182bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSSetObjectCall = CreateStructRSSetObject(C, Diags, DstArrPtrSubscript, 9192bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines SrcArrPtrSubscript, Loc); 9202bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else { 9212bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSSetObjectCall = CreateSingleRSSetObject(C, Diags, DstArrPtrSubscript, 9222bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines SrcArrPtrSubscript, Loc); 9232bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 9242bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9252bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ForStmt *DestructorLoop = 9262bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::ForStmt(C, 9272bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Init, 9282bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Cond, 9292bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NULL, // no condVar 9302bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Inc, 9312bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSSetObjectCall, 9322bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 9332bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 9342bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 9352bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9362bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCtr++] = DestructorLoop; 9372bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(StmtCtr == 2); 9382bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9392bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::CompoundStmt *CS = 9402bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::CompoundStmt(C, StmtArray, StmtCtr, Loc, Loc); 9412bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9422bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return CS; 9432bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines} 9442bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9452bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesstatic clang::Stmt *CreateStructRSSetObject(clang::ASTContext &C, 9462bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Diagnostic *Diags, 9472bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *LHS, 9482bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *RHS, 9492bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SourceLocation Loc) { 9502bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::QualType QT = LHS->getType(); 9512bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *T = QT.getTypePtr(); 9522bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(T->isStructureType()); 9532bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(!RSExportPrimitiveType::IsRSObjectType(T)); 9542bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9552bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Keep an extra slot for the original copy (memcpy) 9562bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines unsigned FieldsToSet = CountRSObjectTypes(T) + 1; 9572bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9582bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines unsigned StmtCount = 0; 9592bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Stmt **StmtArray = new clang::Stmt*[FieldsToSet]; 9602bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines for (unsigned i = 0; i < FieldsToSet; i++) { 9612bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[i] = NULL; 9622bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 9632bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9642bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::RecordDecl *RD = T->getAsStructureType()->getDecl(); 9652bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RD = RD->getDefinition(); 9662bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 9672bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FE = RD->field_end(); 9682bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FI != FE; 9692bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FI++) { 9702bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines bool IsArrayType = false; 9712bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::FieldDecl *FD = *FI; 9722bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 9732bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *OrigType = FT; 9742bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9752bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (!CountRSObjectTypes(FT)) { 9762bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Skip to next if we don't have any viable RS object types 9772bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines continue; 9782bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 9792bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9802bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclAccessPair FoundDecl = 9812bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclAccessPair::make(FD, clang::AS_none); 9822bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr *DstMember = 9832bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr::Create(C, 9842bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines LHS, 9852bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines false, 986be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 9872bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FD, 9882bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FoundDecl, 9892bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclarationNameInfo(), 9902bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NULL, 991be27482cdeaf08576bc39b72a15d35d13014a636Logan OrigType->getCanonicalTypeInternal(), 992be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 993be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary); 9942bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9952bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr *SrcMember = 9962bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr::Create(C, 9972bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RHS, 9982bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines false, 999be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 10002bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FD, 10012bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FoundDecl, 10022bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclarationNameInfo(), 10032bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NULL, 1004be27482cdeaf08576bc39b72a15d35d13014a636Logan OrigType->getCanonicalTypeInternal(), 1005be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1006be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary); 10072bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10082bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (FT->isArrayType()) { 10092bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 10102bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines IsArrayType = true; 10112bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 10122bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10132bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSExportPrimitiveType::DataType DT = 10142bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSExportPrimitiveType::GetRSSpecificType(FT); 10152bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10162bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (IsArrayType) { 1017832429f6bf4592cfc2ce58f2462f1e8ecdbaaf52Stephen Hines Diags->Report(clang::FullSourceLoc(Loc, C.getSourceManager()), 1018832429f6bf4592cfc2ce58f2462f1e8ecdbaaf52Stephen Hines Diags->getCustomDiagID(clang::Diagnostic::Error, 1019832429f6bf4592cfc2ce58f2462f1e8ecdbaaf52Stephen Hines "Arrays of RS object types within structures cannot be copied")); 10202bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // TODO(srhines): Support setting arrays of RS objects 10212bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // StmtArray[StmtCount++] = 10222bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // CreateArrayRSSetObject(C, Diags, DstMember, SrcMember, Loc); 10232bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else if (DT == RSExportPrimitiveType::DataTypeUnknown) { 10242bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCount++] = 10252bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines CreateStructRSSetObject(C, Diags, DstMember, SrcMember, Loc); 10262bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else if (RSExportPrimitiveType::IsRSObjectType(DT)) { 10272bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCount++] = 10282bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines CreateSingleRSSetObject(C, Diags, DstMember, SrcMember, Loc); 10292bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else { 10302bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(false); 10312bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 10322bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 10332bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10342bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(StmtCount > 0 && StmtCount < FieldsToSet); 10352bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10362bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // We still need to actually do the overall struct copy. For simplicity, 10372bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // we just do a straight-up assignment (which will still preserve all 10382bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // the proper RS object reference counts). 10392bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BinaryOperator *CopyStruct = 1040be27482cdeaf08576bc39b72a15d35d13014a636Logan new(C) clang::BinaryOperator(LHS, RHS, clang::BO_Assign, QT, 1041be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, clang::OK_Ordinary, Loc); 10422bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCount++] = CopyStruct; 10432bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10442bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::CompoundStmt *CS = 10452bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::CompoundStmt(C, StmtArray, StmtCount, Loc, Loc); 10462bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10472bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines delete [] StmtArray; 10482bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10492bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return CS; 10502bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines} 10512bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10522bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines} // namespace 10532bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10542bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesvoid RSObjectRefCount::Scope::ReplaceRSObjectAssignment( 10552bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BinaryOperator *AS, 10562bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Diagnostic *Diags) { 10572bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10582bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::QualType QT = AS->getType(); 10592bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10602bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ASTContext &C = RSObjectRefCount::GetRSSetObjectFD( 10612bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSExportPrimitiveType::DataTypeRSFont)->getASTContext(); 10622bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 1063832429f6bf4592cfc2ce58f2462f1e8ecdbaaf52Stephen Hines clang::SourceLocation Loc = AS->getExprLoc(); 10642bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Stmt *UpdatedStmt = NULL; 10652bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10662bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (!RSExportPrimitiveType::IsRSObjectType(QT.getTypePtr())) { 10672bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // By definition, this is a struct assignment if we get here 10682bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines UpdatedStmt = 10692bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines CreateStructRSSetObject(C, Diags, AS->getLHS(), AS->getRHS(), Loc); 10702bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else { 10712bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines UpdatedStmt = 10722bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines CreateSingleRSSetObject(C, Diags, AS->getLHS(), AS->getRHS(), Loc); 10732bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 1074e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1075292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines RSASTReplace R(C); 1076292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines R.ReplaceStmt(mCS, AS, UpdatedStmt); 1077e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return; 1078e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines} 1079e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1080e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hinesvoid RSObjectRefCount::Scope::AppendRSObjectInit( 1081a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::Diagnostic *Diags, 1082e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::VarDecl *VD, 1083e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclStmt *DS, 1084e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataType DT, 1085e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *InitExpr) { 10866e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(VD); 1087e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1088e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (!InitExpr) { 1089e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return; 1090e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 1091e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1092a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::ASTContext &C = RSObjectRefCount::GetRSSetObjectFD( 1093a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines RSExportPrimitiveType::DataTypeRSFont)->getASTContext(); 1094a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::SourceLocation Loc = RSObjectRefCount::GetRSSetObjectFD( 1095a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines RSExportPrimitiveType::DataTypeRSFont)->getLocation(); 1096a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines 1097f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (DT == RSExportPrimitiveType::DataTypeIsStruct) { 1098a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 1099a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::DeclRefExpr *RefRSVar = 1100a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::DeclRefExpr::Create(C, 1101be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 1102a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines VD, 1103a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines Loc, 1104be27482cdeaf08576bc39b72a15d35d13014a636Logan T->getCanonicalTypeInternal(), 1105be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1106be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 1107a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines 1108a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::Stmt *RSSetObjectOps = 1109a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines CreateStructRSSetObject(C, Diags, RefRSVar, InitExpr, Loc); 1110a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines 1111292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*> StmtList; 1112292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines StmtList.push_back(RSSetObjectOps); 1113292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines AppendAfterStmt(C, mCS, DS, StmtList); 1114f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return; 1115f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 1116f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 1117f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::FunctionDecl *SetObjectFD = RSObjectRefCount::GetRSSetObjectFD(DT); 11186e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((SetObjectFD != NULL) && 11196e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "rsSetObject doesn't cover all RS object types"); 1120e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1121e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::QualType SetObjectFDType = SetObjectFD->getType(); 1122e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::QualType SetObjectFDArgType[2]; 1123e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDArgType[0] = SetObjectFD->getParamDecl(0)->getOriginalType(); 1124e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDArgType[1] = SetObjectFD->getParamDecl(1)->getOriginalType(); 1125e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1126e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *RefRSSetObjectFD = 1127e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr::Create(C, 1128be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 1129e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFD, 1130e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc, 1131be27482cdeaf08576bc39b72a15d35d13014a636Logan SetObjectFDType, 1132be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1133be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 1134e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1135e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *RSSetObjectFP = 1136e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::ImplicitCastExpr::Create(C, 1137e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines C.getPointerType(SetObjectFDType), 1138e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CK_FunctionToPointerDecay, 1139e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RefRSSetObjectFD, 1140e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines NULL, 1141e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::VK_RValue); 1142e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1143e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 1144e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr *RefRSVar = 1145e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr::Create(C, 1146be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 1147e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD, 1148e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc, 1149be27482cdeaf08576bc39b72a15d35d13014a636Logan T->getCanonicalTypeInternal(), 1150be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1151be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 1152e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1153e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *ArgList[2]; 1154e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ArgList[0] = new(C) clang::UnaryOperator(RefRSVar, 1155e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::UO_AddrOf, 1156e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDArgType[0], 1157be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1158be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 1159e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc); 1160e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ArgList[1] = InitExpr; 1161e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1162e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CallExpr *RSSetObjectCall = 1163e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines new(C) clang::CallExpr(C, 1164e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSSetObjectFP, 1165e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ArgList, 1166e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 2, 1167e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFD->getCallResultType(), 1168be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1169e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc); 1170e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1171292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*> StmtList; 1172292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines StmtList.push_back(RSSetObjectCall); 1173292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines AppendAfterStmt(C, mCS, DS, StmtList); 1174c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 1175c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines return; 1176c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines} 1177c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 11781bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hinesvoid RSObjectRefCount::Scope::InsertLocalVarDestructors() { 1179d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines std::list<clang::Stmt*> RSClearObjectCalls; 11801bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines for (std::list<clang::VarDecl*>::const_iterator I = mRSO.begin(), 11811bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines E = mRSO.end(); 11821bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines I != E; 11831bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines I++) { 1184a858cb6f3d9223d65bf73e1230c6324ded4095f6Stephen Hines clang::Stmt *S = ClearRSObject(*I); 1185a858cb6f3d9223d65bf73e1230c6324ded4095f6Stephen Hines if (S) { 1186a858cb6f3d9223d65bf73e1230c6324ded4095f6Stephen Hines RSClearObjectCalls.push_back(S); 11871bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 11881bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 11891bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if (RSClearObjectCalls.size() > 0) { 1190292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines DestructorVisitor DV((*mRSO.begin())->getASTContext(), 1191292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mCS, 1192292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines RSClearObjectCalls); 11934464d825c11349068f2917f9ebee86b721423f3cStephen Hines DV.Visit(mCS); 1194292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines DV.InsertDestructors(); 11951bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 11961bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines return; 11971bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 11981bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1199d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hinesclang::Stmt *RSObjectRefCount::Scope::ClearRSObject(clang::VarDecl *VD) { 1200f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(VD); 12011bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::ASTContext &C = VD->getASTContext(); 1202f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC = VD->getDeclContext(); 12031bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::SourceLocation Loc = VD->getLocation(); 12041bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 120503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 12061bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Reference expr to target RS object variable 12071bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::DeclRefExpr *RefRSVar = 12081bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::DeclRefExpr::Create(C, 1209be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 12101bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines VD, 12111bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines Loc, 1212be27482cdeaf08576bc39b72a15d35d13014a636Logan T->getCanonicalTypeInternal(), 1213be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1214be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 12151bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1216f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (T->isArrayType()) { 1217be27482cdeaf08576bc39b72a15d35d13014a636Logan return ClearArrayRSObject(C, DC, RefRSVar, Loc); 1218f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 12191bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1220f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::DataType DT = 1221f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::GetRSSpecificType(T); 12221bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1223f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (DT == RSExportPrimitiveType::DataTypeUnknown || 1224f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DT == RSExportPrimitiveType::DataTypeIsStruct) { 1225be27482cdeaf08576bc39b72a15d35d13014a636Logan return ClearStructRSObject(C, DC, RefRSVar, Loc); 1226f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 12271bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1228f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert((RSExportPrimitiveType::IsRSObjectType(DT)) && 1229f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "Should be RS object"); 12301bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1231f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return ClearSingleRSObject(C, RefRSVar, Loc); 12321bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 12331bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1234e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hinesbool RSObjectRefCount::InitializeRSObject(clang::VarDecl *VD, 1235e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataType *DT, 1236e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr **InitExpr) { 12376e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(VD && DT && InitExpr); 12384b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 12392d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines 12402d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines // Loop through array types to get to base type 12412d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines while (T && T->isArrayType()) { 12422d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines T = T->getArrayElementTypeNoTypeQual(); 12432d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines } 12442d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines 1245f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool DataTypeIsStructWithRSObject = false; 1246e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines *DT = RSExportPrimitiveType::GetRSSpecificType(T); 12474b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1248e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (*DT == RSExportPrimitiveType::DataTypeUnknown) { 1249feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (RSExportPrimitiveType::IsStructureTypeWithRSObject(T)) { 1250feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines *DT = RSExportPrimitiveType::DataTypeIsStruct; 1251f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DataTypeIsStructWithRSObject = true; 1252feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } else { 1253feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines return false; 1254feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 12552d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines } 12564b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1257f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool DataTypeIsRSObject = false; 1258f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (DataTypeIsStructWithRSObject) { 1259f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DataTypeIsRSObject = true; 1260f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 1261f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DataTypeIsRSObject = RSExportPrimitiveType::IsRSObjectType(*DT); 1262f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 1263e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines *InitExpr = VD->getInit(); 1264e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1265e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (!DataTypeIsRSObject && *InitExpr) { 1266e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines // If we already have an initializer for a matrix type, we are done. 1267e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return DataTypeIsRSObject; 12684b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 12694b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1270e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *ZeroInitializer = 1271e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines CreateZeroInitializerForRSSpecificType(*DT, 1272e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->getASTContext(), 1273e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->getLocation()); 1274e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1275e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (ZeroInitializer) { 1276e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ZeroInitializer->setType(T->getCanonicalTypeInternal()); 1277e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->setInit(ZeroInitializer); 1278e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 1279e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1280e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return DataTypeIsRSObject; 12814b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 12824b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 12834b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesclang::Expr *RSObjectRefCount::CreateZeroInitializerForRSSpecificType( 12844b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines RSExportPrimitiveType::DataType DT, 12854b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ASTContext &C, 12864b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines const clang::SourceLocation &Loc) { 12874b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *Res = NULL; 12884b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines switch (DT) { 1289feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines case RSExportPrimitiveType::DataTypeIsStruct: 12904b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSElement: 12914b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSType: 12924b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSAllocation: 12934b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSSampler: 12944b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSScript: 12954b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMesh: 12964b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramFragment: 12974b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramVertex: 12984b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramRaster: 12994b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramStore: 13004b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSFont: { 13014b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (ImplicitCastExpr 'nullptr_t' 13024b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (IntegerLiteral 0))) 13034b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APInt Zero(C.getTypeSize(C.IntTy), 0); 13044b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, Zero, C.IntTy, Loc); 13054b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *CastToNull = 13064b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ImplicitCastExpr::Create(C, 13074b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines C.NullPtrTy, 13084b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::CK_IntegralToPointer, 13094b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Int0, 13104b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines NULL, 13114b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::VK_RValue); 13124b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1313e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Res = new(C) clang::InitListExpr(C, Loc, &CastToNull, 1, Loc); 13144b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines break; 13154b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 13164b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMatrix2x2: 13174b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMatrix3x3: 13184b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMatrix4x4: { 13194b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // RS matrix is not completely an RS object. They hold data by themselves. 13204b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (InitListExpr rs_matrix2x2 13214b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (InitListExpr float[4] 13224b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 13234b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 13244b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 13254b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0))) 13264b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::QualType FloatTy = C.FloatTy; 13274b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Constructor sets value to 0.0f by default 13284b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APFloat Val(C.getFloatTypeSemantics(FloatTy)); 13294b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::FloatingLiteral *Float0Val = 13304b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::FloatingLiteral::Create(C, 13314b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Val, 13324b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines /* isExact = */true, 13334b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines FloatTy, 13344b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Loc); 13354b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 13364b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines unsigned N = 0; 13374b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (DT == RSExportPrimitiveType::DataTypeRSMatrix2x2) 13384b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 2; 13394b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines else if (DT == RSExportPrimitiveType::DataTypeRSMatrix3x3) 13404b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 3; 13414b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines else if (DT == RSExportPrimitiveType::DataTypeRSMatrix4x4) 13424b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 4; 13434b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 13444b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Directly allocate 16 elements instead of dynamically allocate N*N 13454b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *InitVals[16]; 13464b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (unsigned i = 0; i < sizeof(InitVals) / sizeof(InitVals[0]); i++) 13474b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines InitVals[i] = Float0Val; 13484b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *InitExpr = 1349e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines new(C) clang::InitListExpr(C, Loc, InitVals, N * N, Loc); 13504b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines InitExpr->setType(C.getConstantArrayType(FloatTy, 13514b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APInt(32, 4), 13524b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ArrayType::Normal, 13534b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines /* EltTypeQuals = */0)); 13544b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1355e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Res = new(C) clang::InitListExpr(C, Loc, &InitExpr, 1, Loc); 13564b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines break; 13574b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 13584b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnknown: 13594b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeFloat16: 13604b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeFloat32: 13614b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeFloat64: 13624b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned8: 13634b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned16: 13644b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned32: 13654b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned64: 13664b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned8: 13674b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned16: 13684b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned32: 13694b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned64: 13704b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeBoolean: 13714b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned565: 13724b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned5551: 13734b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned4444: 13744b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeMax: { 13756e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Not RS object type!"); 13764b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 13774b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // No default case will enable compiler detecting the missing cases 13784b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 13794b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 13804b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return Res; 13814b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 13824b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 13834b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitDeclStmt(clang::DeclStmt *DS) { 13844b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (clang::DeclStmt::decl_iterator I = DS->decl_begin(), E = DS->decl_end(); 13854b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I != E; 13864b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I++) { 13874b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Decl *D = *I; 13884b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (D->getKind() == clang::Decl::Var) { 13894b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::VarDecl *VD = static_cast<clang::VarDecl*>(D); 1390e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataType DT = 1391e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataTypeUnknown; 1392e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *InitExpr = NULL; 1393e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (InitializeRSObject(VD, &DT, &InitExpr)) { 13944b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines getCurrentScope()->addRSObject(VD); 1395a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines getCurrentScope()->AppendRSObjectInit(mDiags, VD, DS, DT, InitExpr); 1396e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 13974b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 13984b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 13994b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 14004b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 14014b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 14024b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitCompoundStmt(clang::CompoundStmt *CS) { 14034b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (!CS->body_empty()) { 14044b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Push a new scope 14054b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Scope *S = new Scope(CS); 14064b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines mScopeStack.push(S); 14074b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 14084b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines VisitStmt(CS); 14094b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 14104b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Destroy the scope 14116e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((getCurrentScope() == S) && "Corrupted scope stack!"); 14121bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines S->InsertLocalVarDestructors(); 14134b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines mScopeStack.pop(); 14144b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines delete S; 14154b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 14164b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 14174b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 14184b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 14194b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitBinAssign(clang::BinaryOperator *AS) { 1420c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType QT = AS->getType(); 1421c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 14222bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (CountRSObjectTypes(QT.getTypePtr())) { 14232bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines getCurrentScope()->ReplaceRSObjectAssignment(AS, mDiags); 1424c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 1425c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 14264b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 14274b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 14284b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 14294b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitStmt(clang::Stmt *S) { 14304b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end(); 14314b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I != E; 14324b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I++) { 14334b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (clang::Stmt *Child = *I) { 14344b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Visit(Child); 14354b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 14364b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 14374b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 14384b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 14394b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1440e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 1441