slang_rs_object_ref_count.cpp revision b0fabe574945bfa85e688e77e9dcb5341fe08840
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 172a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines// This class visits a compound statement and inserts DtorStmt 173a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines// in proper locations. This includes inserting it 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: 186d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines clang::ASTContext &mCtx; 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 201a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines // The destructor to execute for this scope/variable. 202a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines clang::Stmt* mDtorStmt; 203292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 204292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // The stack of statements which should be replaced by a compound statement 205a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines // containing the new destructor call followed by the original Stmt. 206292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::stack<clang::Stmt*> mReplaceStmtStack; 207292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 208a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines // The source location for the variable declaration that we are trying to 209a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines // insert destructors for. Note that InsertDestructors() will not generate 210a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines // destructor calls for source locations that occur lexically before this 211a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines // location. 212a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines clang::SourceLocation mVarLoc; 213a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines 2144464d825c11349068f2917f9ebee86b721423f3cStephen Hines public: 215292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines DestructorVisitor(clang::ASTContext &C, 216292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines clang::Stmt* OuterStmt, 217a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines clang::Stmt* DtorStmt, 218a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines clang::SourceLocation VarLoc); 219292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 220292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // This code walks the collected list of Stmts to replace and actually does 221a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines // the replacement. It also finishes up by appending the destructor to the 222a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines // current outermost CompoundStmt. 223292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void InsertDestructors() { 224292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines clang::Stmt *S = NULL; 225a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines clang::SourceManager &SM = mCtx.getSourceManager(); 226a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines std::list<clang::Stmt *> StmtList; 227a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines StmtList.push_back(mDtorStmt); 228a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines 229292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines while (!mReplaceStmtStack.empty()) { 230292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines S = mReplaceStmtStack.top(); 231292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mReplaceStmtStack.pop(); 232292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 233a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines // Skip all source locations that occur before the variable's 234a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines // declaration, since it won't have been initialized yet. 235a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines if (SM.isBeforeInTranslationUnit(S->getLocStart(), mVarLoc)) { 236a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines continue; 237a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines } 238a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines 239a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines StmtList.push_back(S); 240292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines clang::CompoundStmt *CS = 241a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines BuildCompoundStmt(mCtx, StmtList, S->getLocEnd()); 242a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines StmtList.pop_back(); 243292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 244d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines RSASTReplace R(mCtx); 245292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines R.ReplaceStmt(mOuterStmt, S, CS); 246292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 247ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien clang::CompoundStmt *CS = 248ab992e59a36a18df49bf4878968ef0598299afd3Logan Chien llvm::dyn_cast<clang::CompoundStmt>(mOuterStmt); 249292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines slangAssert(CS); 250a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines AppendAfterStmt(mCtx, CS, NULL, StmtList); 251292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 252292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 2534464d825c11349068f2917f9ebee86b721423f3cStephen Hines void VisitStmt(clang::Stmt *S); 2544464d825c11349068f2917f9ebee86b721423f3cStephen Hines void VisitCompoundStmt(clang::CompoundStmt *CS); 255292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 256292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitBreakStmt(clang::BreakStmt *BS); 257292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitCaseStmt(clang::CaseStmt *CS); 258292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitContinueStmt(clang::ContinueStmt *CS); 259292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitDefaultStmt(clang::DefaultStmt *DS); 260292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitDoStmt(clang::DoStmt *DS); 261292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitForStmt(clang::ForStmt *FS); 262292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitIfStmt(clang::IfStmt *IS); 263292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitReturnStmt(clang::ReturnStmt *RS); 264292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitSwitchCase(clang::SwitchCase *SC); 265292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitSwitchStmt(clang::SwitchStmt *SS); 266292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines void VisitWhileStmt(clang::WhileStmt *WS); 2674464d825c11349068f2917f9ebee86b721423f3cStephen Hines}; 2684464d825c11349068f2917f9ebee86b721423f3cStephen Hines 2694464d825c11349068f2917f9ebee86b721423f3cStephen HinesDestructorVisitor::DestructorVisitor(clang::ASTContext &C, 270292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines clang::Stmt *OuterStmt, 271a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines clang::Stmt *DtorStmt, 272a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines clang::SourceLocation VarLoc) 273d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines : mCtx(C), 274292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth(0), 275292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mSwitchDepth(0), 276292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mOuterStmt(OuterStmt), 277a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines mDtorStmt(DtorStmt), 278a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines mVarLoc(VarLoc) { 2794464d825c11349068f2917f9ebee86b721423f3cStephen Hines return; 2804464d825c11349068f2917f9ebee86b721423f3cStephen Hines} 2814464d825c11349068f2917f9ebee86b721423f3cStephen Hines 2824464d825c11349068f2917f9ebee86b721423f3cStephen Hinesvoid DestructorVisitor::VisitStmt(clang::Stmt *S) { 2834464d825c11349068f2917f9ebee86b721423f3cStephen Hines for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end(); 2844464d825c11349068f2917f9ebee86b721423f3cStephen Hines I != E; 2854464d825c11349068f2917f9ebee86b721423f3cStephen Hines I++) { 2864464d825c11349068f2917f9ebee86b721423f3cStephen Hines if (clang::Stmt *Child = *I) { 2874464d825c11349068f2917f9ebee86b721423f3cStephen Hines Visit(Child); 2884464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 2894464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 2904464d825c11349068f2917f9ebee86b721423f3cStephen Hines return; 2914464d825c11349068f2917f9ebee86b721423f3cStephen Hines} 2924464d825c11349068f2917f9ebee86b721423f3cStephen Hines 293292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitCompoundStmt(clang::CompoundStmt *CS) { 294292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(CS); 295292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return; 296292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 297292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 298292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitBreakStmt(clang::BreakStmt *BS) { 299292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(BS); 300292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if ((mLoopDepth == 0) && (mSwitchDepth == 0)) { 301292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mReplaceStmtStack.push(BS); 302292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 303292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return; 304292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 305292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 306292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitCaseStmt(clang::CaseStmt *CS) { 307292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(CS); 308292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return; 309292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 310292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 311292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitContinueStmt(clang::ContinueStmt *CS) { 312292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(CS); 313292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines if (mLoopDepth == 0) { 314292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines // Switch statements can have nested continues. 315292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mReplaceStmtStack.push(CS); 316292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines } 317292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return; 318292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 319292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 320292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitDefaultStmt(clang::DefaultStmt *DS) { 321292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(DS); 322292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return; 323292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 324292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 325292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitDoStmt(clang::DoStmt *DS) { 326292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth++; 327292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(DS); 328292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth--; 329292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return; 330292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 331292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 332292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitForStmt(clang::ForStmt *FS) { 333292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth++; 334292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(FS); 335292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth--; 336292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return; 337292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 338292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 339292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitIfStmt(clang::IfStmt *IS) { 340292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(IS); 341292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return; 342292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 343292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 344292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitReturnStmt(clang::ReturnStmt *RS) { 345292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mReplaceStmtStack.push(RS); 346292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return; 347292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 348292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 349292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitSwitchCase(clang::SwitchCase *SC) { 350292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines slangAssert(false && "Both case and default have specialized handlers"); 351292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(SC); 352292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return; 353292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 354292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 355292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitSwitchStmt(clang::SwitchStmt *SS) { 356292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mSwitchDepth++; 357292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(SS); 358292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mSwitchDepth--; 359292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return; 360292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 361292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 362292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hinesvoid DestructorVisitor::VisitWhileStmt(clang::WhileStmt *WS) { 363292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth++; 364292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines VisitStmt(WS); 365292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines mLoopDepth--; 366292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines return; 367292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines} 368292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines 369f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesclang::Expr *ClearSingleRSObject(clang::ASTContext &C, 370f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSVar, 371f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc) { 372f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(RefRSVar); 373f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *T = RefRSVar->getType().getTypePtr(); 374f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(!T->isArrayType() && 375f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "Should not be destroying arrays with this function"); 376f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 377f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::FunctionDecl *ClearObjectFD = RSObjectRefCount::GetRSClearObjectFD(T); 378f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert((ClearObjectFD != NULL) && 379f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "rsClearObject doesn't cover all RS object types"); 380f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 381f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::QualType ClearObjectFDType = ClearObjectFD->getType(); 382f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::QualType ClearObjectFDArgType = 383f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD->getParamDecl(0)->getOriginalType(); 384f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 385f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Example destructor for "rs_font localFont;" 386f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // 387f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (CallExpr 'void' 388f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (ImplicitCastExpr 'void (*)(rs_font *)' <FunctionToPointerDecay> 389f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (DeclRefExpr 'void (rs_font *)' FunctionDecl='rsClearObject')) 390f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (UnaryOperator 'rs_font *' prefix '&' 391f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (DeclRefExpr 'rs_font':'rs_font' Var='localFont'))) 392f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 393f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Get address of targeted RS object 394f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *AddrRefRSVar = 395f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::UnaryOperator(RefRSVar, 396f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::UO_AddrOf, 397f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFDArgType, 398be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 399be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 400f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 401f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 402f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSClearObjectFD = 403f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclRefExpr::Create(C, 404be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 4050444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 406f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD, 407e2597ac5a8ba7a45a1d5f342973cd43a3a1932cfShih-wei Liao false, 408f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD->getLocation(), 409be27482cdeaf08576bc39b72a15d35d13014a636Logan ClearObjectFDType, 410be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 411be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 412f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 413f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RSClearObjectFP = 414f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ImplicitCastExpr::Create(C, 415f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines C.getPointerType(ClearObjectFDType), 416f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::CK_FunctionToPointerDecay, 417f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSClearObjectFD, 418f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines NULL, 419f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::VK_RValue); 42003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 4211dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines llvm::SmallVector<clang::Expr*, 1> ArgList; 4221dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines ArgList.push_back(AddrRefRSVar); 4231dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines 424f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::CallExpr *RSClearObjectCall = 425f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::CallExpr(C, 426f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectFP, 4271dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines ArgList, 428f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD->getCallResultType(), 429be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 430f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 431f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 432f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return RSClearObjectCall; 433f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines} 434f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 435f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic int ArrayDim(const clang::Type *T) { 43603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (!T || !T->isArrayType()) { 43703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return 0; 43803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 43903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 44003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines const clang::ConstantArrayType *CAT = 44103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines static_cast<const clang::ConstantArrayType *>(T); 4429d2c0fa6490e09b3ff5603796bce42d97788e5c8Stephen Hines return static_cast<int>(CAT->getSize().getSExtValue()); 44303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines} 44403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 445f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic clang::Stmt *ClearStructRSObject( 446f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ASTContext &C, 447f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC, 448f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSStruct, 449d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines clang::SourceLocation StartLoc, 450f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc); 451f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 452f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic clang::Stmt *ClearArrayRSObject( 453f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ASTContext &C, 454f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC, 455f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSArr, 456cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc, 457f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc) { 458f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *BaseType = RefRSArr->getType().getTypePtr(); 459f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(BaseType->isArrayType()); 460f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 461f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines int NumArrayElements = ArrayDim(BaseType); 462f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Actually extract out the base RS object type for use later 463f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines BaseType = BaseType->getArrayElementTypeNoTypeQual(); 46403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 46503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Stmt *StmtArray[2] = {NULL}; 46603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines int StmtCtr = 0; 46703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 46803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (NumArrayElements <= 0) { 46903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return NULL; 47003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 47103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 47203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Example destructor loop for "rs_font fontArr[10];" 47303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // 47403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (CompoundStmt 47503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclStmt "int rsIntIter") 47603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ForStmt 47703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (BinaryOperator 'int' '=' 47803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter') 47903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (IntegerLiteral 'int' 0)) 48003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (BinaryOperator 'int' '<' 48103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter') 48203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (IntegerLiteral 'int' 10) 48303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // NULL << CondVar >> 48403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (UnaryOperator 'int' postfix '++' 48503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter')) 48603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (CallExpr 'void' 48703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ImplicitCastExpr 'void (*)(rs_font *)' <FunctionToPointerDecay> 48803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'void (rs_font *)' FunctionDecl='rsClearObject')) 48903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (UnaryOperator 'rs_font *' prefix '&' 49003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ArraySubscriptExpr 'rs_font':'rs_font' 49103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ImplicitCastExpr 'rs_font *' <ArrayToPointerDecay> 49203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'rs_font [10]' Var='fontArr')) 49303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter'))))))) 49403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 49503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Create helper variable for iterating through elements 49603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::IdentifierInfo& II = C.Idents.get("rsIntIter"); 49703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VarDecl *IIVD = 49803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VarDecl::Create(C, 499f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 500cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, 50103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 50203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines &II, 50303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 50403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.getTrivialTypeSourceInfo(C.IntTy), 50503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::SC_None, 50603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::SC_None); 50703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Decl *IID = (clang::Decl *)IIVD; 50803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 50903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclGroupRef DGR = clang::DeclGroupRef::Create(C, &IID, 1); 51003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines StmtArray[StmtCtr++] = new(C) clang::DeclStmt(DGR, Loc, Loc); 51103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 51203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Form the actual destructor loop 51303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // for (Init; Cond; Inc) 51403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // RSClearObjectCall; 51503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 51603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Init -> "rsIntIter = 0" 51703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclRefExpr *RefrsIntIter = 51803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclRefExpr::Create(C, 519be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 5200444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 52103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines IIVD, 522e2597ac5a8ba7a45a1d5f342973cd43a3a1932cfShih-wei Liao false, 52303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 524be27482cdeaf08576bc39b72a15d35d13014a636Logan C.IntTy, 525be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 526be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 52703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 52803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, 52903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), 0), C.IntTy, Loc); 53003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 53103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BinaryOperator *Init = 53203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 53303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Int0, 53403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BO_Assign, 53503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 536be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 537be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 53803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 53903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 54003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Cond -> "rsIntIter < NumArrayElements" 54103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *NumArrayElementsExpr = clang::IntegerLiteral::Create(C, 54203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), NumArrayElements), C.IntTy, Loc); 54303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 54403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BinaryOperator *Cond = 54503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 54603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NumArrayElementsExpr, 54703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BO_LT, 54803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 549be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 550be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 55103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 55203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 55303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Inc -> "rsIntIter++" 55403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::UnaryOperator *Inc = 55503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::UnaryOperator(RefrsIntIter, 55603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::UO_PostInc, 55703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 558be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 559be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 56003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 56103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 56203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Body -> "rsClearObject(&VD[rsIntIter]);" 56303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Destructor loop operates on individual array elements 56403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 565f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSArrPtr = 56603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::ImplicitCastExpr::Create(C, 567f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines C.getPointerType(BaseType->getCanonicalTypeInternal()), 56803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::CK_ArrayToPointerDecay, 569f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSArr, 57003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, 57103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VK_RValue); 57203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 573f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSArrPtrSubscript = 574f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::ArraySubscriptExpr(RefRSArrPtr, 57503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines RefrsIntIter, 576f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines BaseType->getCanonicalTypeInternal(), 577be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 578be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 579f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 58003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 581f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::DataType DT = 582f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::GetRSSpecificType(BaseType); 583f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 584f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Stmt *RSClearObjectCall = NULL; 585f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (BaseType->isArrayType()) { 586f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectCall = 587cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao ClearArrayRSObject(C, DC, RefRSArrPtrSubscript, StartLoc, Loc); 588f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else if (DT == RSExportPrimitiveType::DataTypeUnknown) { 589f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectCall = 590cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao ClearStructRSObject(C, DC, RefRSArrPtrSubscript, StartLoc, Loc); 591f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 592f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectCall = ClearSingleRSObject(C, RefRSArrPtrSubscript, Loc); 593f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 59403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 59503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::ForStmt *DestructorLoop = 59603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::ForStmt(C, 59703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Init, 59803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Cond, 59903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, // no condVar 60003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Inc, 60103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines RSClearObjectCall, 60203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 60303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 60403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 60503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 60603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines StmtArray[StmtCtr++] = DestructorLoop; 6076e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(StmtCtr == 2); 60803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 60903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::CompoundStmt *CS = 61003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::CompoundStmt(C, StmtArray, StmtCtr, Loc, Loc); 61103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 61203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return CS; 61303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines} 61403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 615d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hinesstatic unsigned CountRSObjectTypes(clang::ASTContext &C, 616d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines const clang::Type *T, 617d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines clang::SourceLocation Loc) { 618f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(T); 619f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines unsigned RSObjectCount = 0; 620f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 621f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (T->isArrayType()) { 622d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines return CountRSObjectTypes(C, T->getArrayElementTypeNoTypeQual(), Loc); 623f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 624f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 625f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::DataType DT = 626f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::GetRSSpecificType(T); 627f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (DT != RSExportPrimitiveType::DataTypeUnknown) { 628f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return (RSExportPrimitiveType::IsRSObjectType(DT) ? 1 : 0); 629f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 630f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 631d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines if (T->isUnionType()) { 632d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines clang::RecordDecl *RD = T->getAsUnionType()->getDecl(); 633d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines RD = RD->getDefinition(); 634d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 635d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines FE = RD->field_end(); 636d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines FI != FE; 637d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines FI++) { 638d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines const clang::FieldDecl *FD = *FI; 639d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 640d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines if (CountRSObjectTypes(C, FT, Loc)) { 64178e69cb06b9b0683b2ac9dcafde87b867690ef2fStephen Hines slangAssert(false && "can't have unions with RS object types!"); 642d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines return 0; 643d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines } 644d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines } 645d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines } 646d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines 647f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (!T->isStructureType()) { 648f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return 0; 649f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 650f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 651f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::RecordDecl *RD = T->getAsStructureType()->getDecl(); 652f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RD = RD->getDefinition(); 653f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 654f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FE = RD->field_end(); 655f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI != FE; 656f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI++) { 657f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::FieldDecl *FD = *FI; 658f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 659d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines if (CountRSObjectTypes(C, FT, Loc)) { 660f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Sub-structs should only count once (as should arrays, etc.) 661f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectCount++; 662f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 663f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 664f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 665f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return RSObjectCount; 666f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines} 667f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 668f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic clang::Stmt *ClearStructRSObject( 669f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ASTContext &C, 670f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC, 671f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSStruct, 672cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc, 673f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc) { 674f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *BaseType = RefRSStruct->getType().getTypePtr(); 675f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 676f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(!BaseType->isArrayType()); 677f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 678f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Structs should show up as unknown primitive types 6799be9360d8e02b52ed669afbd69f9becb575c3f0dAlex Sakhartchouk slangAssert(RSExportPrimitiveType::GetRSSpecificType(BaseType) == 6809be9360d8e02b52ed669afbd69f9becb575c3f0dAlex Sakhartchouk RSExportPrimitiveType::DataTypeUnknown); 681f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 682d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines unsigned FieldsToDestroy = CountRSObjectTypes(C, BaseType, Loc); 683b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines slangAssert(FieldsToDestroy != 0); 684f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 685f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines unsigned StmtCount = 0; 686f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Stmt **StmtArray = new clang::Stmt*[FieldsToDestroy]; 6872bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines for (unsigned i = 0; i < FieldsToDestroy; i++) { 6882bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[i] = NULL; 6892bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 690f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 691f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Populate StmtArray by creating a destructor for each RS object field 692f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::RecordDecl *RD = BaseType->getAsStructureType()->getDecl(); 693f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RD = RD->getDefinition(); 694f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 695f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FE = RD->field_end(); 696f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI != FE; 697f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI++) { 698f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // We just look through all field declarations to see if we find a 699f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // declaration for an RS object type (or an array of one). 700f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool IsArrayType = false; 701f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::FieldDecl *FD = *FI; 702f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 703f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *OrigType = FT; 704f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines while (FT && FT->isArrayType()) { 705f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 706f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines IsArrayType = true; 707f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 708f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 709f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (RSExportPrimitiveType::IsRSObjectType(FT)) { 710f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair FoundDecl = 711f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair::make(FD, clang::AS_none); 712f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr *RSObjectMember = 713f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr::Create(C, 714f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSStruct, 715f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines false, 716be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 7170444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 718f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FD, 719f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FoundDecl, 720f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclarationNameInfo(), 721f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines NULL, 722be27482cdeaf08576bc39b72a15d35d13014a636Logan OrigType->getCanonicalTypeInternal(), 723be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 724be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary); 725f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 726f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(StmtCount < FieldsToDestroy); 727f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 728f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (IsArrayType) { 729f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearArrayRSObject(C, 730f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 731f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 732cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, 733f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 734f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 735f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearSingleRSObject(C, 736f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 737f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 738f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 739d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines } else if (FT->isStructureType() && CountRSObjectTypes(C, FT, Loc)) { 740f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // In this case, we have a nested struct. We may not end up filling all 741f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // of the spaces in StmtArray (sub-structs should handle themselves 742f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // with separate compound statements). 743f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair FoundDecl = 744f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair::make(FD, clang::AS_none); 745f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr *RSObjectMember = 746f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr::Create(C, 747f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSStruct, 748f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines false, 749be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 7500444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 751f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FD, 752f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FoundDecl, 753f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclarationNameInfo(), 754f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines NULL, 755be27482cdeaf08576bc39b72a15d35d13014a636Logan OrigType->getCanonicalTypeInternal(), 756be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 757be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary); 758f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 759f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (IsArrayType) { 760f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearArrayRSObject(C, 761f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 762f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 763cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, 764f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 765f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 766f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearStructRSObject(C, 767f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 768f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 769cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, 770f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 771f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 772f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 773f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 774f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 775f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(StmtCount > 0); 776f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::CompoundStmt *CS = 777f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::CompoundStmt(C, StmtArray, StmtCount, Loc, Loc); 778f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 779f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines delete [] StmtArray; 780f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 781f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return CS; 782f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines} 783f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 7842bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesstatic clang::Stmt *CreateSingleRSSetObject(clang::ASTContext &C, 7852bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *DstExpr, 7862bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *SrcExpr, 787cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc, 7882bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SourceLocation Loc) { 7892bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *T = DstExpr->getType().getTypePtr(); 7902bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::FunctionDecl *SetObjectFD = RSObjectRefCount::GetRSSetObjectFD(T); 7916e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((SetObjectFD != NULL) && 7926e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "rsSetObject doesn't cover all RS object types"); 793c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 794c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType SetObjectFDType = SetObjectFD->getType(); 795c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType SetObjectFDArgType[2]; 796c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDArgType[0] = SetObjectFD->getParamDecl(0)->getOriginalType(); 797c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDArgType[1] = SetObjectFD->getParamDecl(1)->getOriginalType(); 798c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 799c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Expr *RefRSSetObjectFD = 800c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::DeclRefExpr::Create(C, 801be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 8020444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 803c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFD, 804e2597ac5a8ba7a45a1d5f342973cd43a3a1932cfShih-wei Liao false, 805c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines Loc, 806be27482cdeaf08576bc39b72a15d35d13014a636Logan SetObjectFDType, 807be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 808be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 809c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 810c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Expr *RSSetObjectFP = 811c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::ImplicitCastExpr::Create(C, 812c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines C.getPointerType(SetObjectFDType), 813c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::CK_FunctionToPointerDecay, 814c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RefRSSetObjectFD, 815c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines NULL, 816c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::VK_RValue); 817c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 8181dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines llvm::SmallVector<clang::Expr*, 2> ArgList; 8191dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines ArgList.push_back(new(C) clang::UnaryOperator(DstExpr, 8201dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines clang::UO_AddrOf, 8211dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines SetObjectFDArgType[0], 8221dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines clang::VK_RValue, 8231dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines clang::OK_Ordinary, 8241dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines Loc)); 8251dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines ArgList.push_back(SrcExpr); 826c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 827c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::CallExpr *RSSetObjectCall = 828c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines new(C) clang::CallExpr(C, 829c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RSSetObjectFP, 830c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines ArgList, 831c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFD->getCallResultType(), 832be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 833c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines Loc); 834c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 8352bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return RSSetObjectCall; 8362bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines} 8372bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8382bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesstatic clang::Stmt *CreateStructRSSetObject(clang::ASTContext &C, 8392bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *LHS, 8402bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *RHS, 841cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc, 8422bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SourceLocation Loc); 8432bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 844246fa17206bf78c59a64b2f7d98a6716d5345b81Al Sutton/*static clang::Stmt *CreateArrayRSSetObject(clang::ASTContext &C, 8452bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *DstArr, 8462bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *SrcArr, 847cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc, 8482bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SourceLocation Loc) { 8492bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclContext *DC = NULL; 8502bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *BaseType = DstArr->getType().getTypePtr(); 8512bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(BaseType->isArrayType()); 8522bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8532bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines int NumArrayElements = ArrayDim(BaseType); 8542bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Actually extract out the base RS object type for use later 8552bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines BaseType = BaseType->getArrayElementTypeNoTypeQual(); 8562bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8572bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Stmt *StmtArray[2] = {NULL}; 8582bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines int StmtCtr = 0; 8592bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8602bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (NumArrayElements <= 0) { 8612bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return NULL; 8622bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 8632bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8642bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Create helper variable for iterating through elements 8652bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::IdentifierInfo& II = C.Idents.get("rsIntIter"); 8662bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VarDecl *IIVD = 8672bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VarDecl::Create(C, 8682bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines DC, 869cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, 8702bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 8712bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines &II, 8722bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 8732bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.getTrivialTypeSourceInfo(C.IntTy), 8742bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SC_None, 8752bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SC_None); 8762bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Decl *IID = (clang::Decl *)IIVD; 8772bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8782bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclGroupRef DGR = clang::DeclGroupRef::Create(C, &IID, 1); 8792bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCtr++] = new(C) clang::DeclStmt(DGR, Loc, Loc); 8802bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8812bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Form the actual loop 8822bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // for (Init; Cond; Inc) 8832bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // RSSetObjectCall; 8842bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8852bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Init -> "rsIntIter = 0" 8862bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclRefExpr *RefrsIntIter = 8872bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclRefExpr::Create(C, 888be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 8892bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines IIVD, 8902bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 891be27482cdeaf08576bc39b72a15d35d13014a636Logan C.IntTy, 892be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 893be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 8942bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8952bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, 8962bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), 0), C.IntTy, Loc); 8972bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 8982bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BinaryOperator *Init = 8992bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 9002bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Int0, 9012bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BO_Assign, 9022bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 903be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 904be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 9052bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 9062bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9072bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Cond -> "rsIntIter < NumArrayElements" 9082bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *NumArrayElementsExpr = clang::IntegerLiteral::Create(C, 9092bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), NumArrayElements), C.IntTy, Loc); 9102bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9112bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BinaryOperator *Cond = 9122bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 9132bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NumArrayElementsExpr, 9142bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BO_LT, 9152bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 916be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 917be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 9182bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 9192bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9202bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Inc -> "rsIntIter++" 9212bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::UnaryOperator *Inc = 9222bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::UnaryOperator(RefrsIntIter, 9232bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::UO_PostInc, 9242bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.IntTy, 925be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 926be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 9272bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 9282bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9292bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Body -> "rsSetObject(&Dst[rsIntIter], Src[rsIntIter]);" 9302bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Loop operates on individual array elements 9312bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9322bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *DstArrPtr = 9332bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ImplicitCastExpr::Create(C, 9342bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.getPointerType(BaseType->getCanonicalTypeInternal()), 9352bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::CK_ArrayToPointerDecay, 9362bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines DstArr, 9372bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NULL, 9382bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VK_RValue); 9392bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9402bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *DstArrPtrSubscript = 9412bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::ArraySubscriptExpr(DstArrPtr, 9422bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RefrsIntIter, 9432bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines BaseType->getCanonicalTypeInternal(), 944be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 945be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 9462bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 9472bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9482bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *SrcArrPtr = 9492bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ImplicitCastExpr::Create(C, 9502bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines C.getPointerType(BaseType->getCanonicalTypeInternal()), 9512bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::CK_ArrayToPointerDecay, 9522bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines SrcArr, 9532bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NULL, 9542bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::VK_RValue); 9552bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9562bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *SrcArrPtrSubscript = 9572bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::ArraySubscriptExpr(SrcArrPtr, 9582bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RefrsIntIter, 9592bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines BaseType->getCanonicalTypeInternal(), 960be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 961be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary, 9622bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 9632bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9642bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSExportPrimitiveType::DataType DT = 9652bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSExportPrimitiveType::GetRSSpecificType(BaseType); 9662bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9672bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Stmt *RSSetObjectCall = NULL; 9682bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (BaseType->isArrayType()) { 969d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines RSSetObjectCall = CreateArrayRSSetObject(C, DstArrPtrSubscript, 970cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao SrcArrPtrSubscript, 971cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, Loc); 9722bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else if (DT == RSExportPrimitiveType::DataTypeUnknown) { 973d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines RSSetObjectCall = CreateStructRSSetObject(C, DstArrPtrSubscript, 974cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao SrcArrPtrSubscript, 975cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, Loc); 9762bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else { 977d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines RSSetObjectCall = CreateSingleRSSetObject(C, DstArrPtrSubscript, 978cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao SrcArrPtrSubscript, 979cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao StartLoc, Loc); 9802bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 9812bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9822bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ForStmt *DestructorLoop = 9832bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::ForStmt(C, 9842bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Init, 9852bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Cond, 9862bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NULL, // no condVar 9872bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Inc, 9882bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSSetObjectCall, 9892bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 9902bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc, 9912bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines Loc); 9922bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9932bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCtr++] = DestructorLoop; 9942bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(StmtCtr == 2); 9952bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9962bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::CompoundStmt *CS = 9972bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::CompoundStmt(C, StmtArray, StmtCtr, Loc, Loc); 9982bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 9992bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return CS; 1000246fa17206bf78c59a64b2f7d98a6716d5345b81Al Sutton} */ 10012bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10022bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesstatic clang::Stmt *CreateStructRSSetObject(clang::ASTContext &C, 10032bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *LHS, 10042bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Expr *RHS, 1005cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc, 10062bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::SourceLocation Loc) { 10072bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::QualType QT = LHS->getType(); 10082bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *T = QT.getTypePtr(); 10092bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(T->isStructureType()); 10102bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(!RSExportPrimitiveType::IsRSObjectType(T)); 10112bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10122bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Keep an extra slot for the original copy (memcpy) 1013d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines unsigned FieldsToSet = CountRSObjectTypes(C, T, Loc) + 1; 10142bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10152bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines unsigned StmtCount = 0; 10162bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Stmt **StmtArray = new clang::Stmt*[FieldsToSet]; 10172bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines for (unsigned i = 0; i < FieldsToSet; i++) { 10182bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[i] = NULL; 10192bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 10202bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10212bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::RecordDecl *RD = T->getAsStructureType()->getDecl(); 10222bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RD = RD->getDefinition(); 10232bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 10242bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FE = RD->field_end(); 10252bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FI != FE; 10262bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FI++) { 10272bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines bool IsArrayType = false; 10282bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::FieldDecl *FD = *FI; 10292bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 10302bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines const clang::Type *OrigType = FT; 10312bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 1032d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines if (!CountRSObjectTypes(C, FT, Loc)) { 10332bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // Skip to next if we don't have any viable RS object types 10342bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines continue; 10352bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 10362bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10372bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclAccessPair FoundDecl = 10382bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclAccessPair::make(FD, clang::AS_none); 10392bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr *DstMember = 10402bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr::Create(C, 10412bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines LHS, 10422bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines false, 1043be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 10440444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 10452bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FD, 10462bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FoundDecl, 10472bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclarationNameInfo(), 10482bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NULL, 1049be27482cdeaf08576bc39b72a15d35d13014a636Logan OrigType->getCanonicalTypeInternal(), 1050be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1051be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary); 10522bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10532bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr *SrcMember = 10542bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::MemberExpr::Create(C, 10552bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RHS, 10562bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines false, 1057be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 10580444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 10592bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FD, 10602bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FoundDecl, 10612bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::DeclarationNameInfo(), 10622bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines NULL, 1063be27482cdeaf08576bc39b72a15d35d13014a636Logan OrigType->getCanonicalTypeInternal(), 1064be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1065be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::OK_Ordinary); 10662bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10672bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (FT->isArrayType()) { 10682bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 10692bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines IsArrayType = true; 10702bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 10712bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10722bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSExportPrimitiveType::DataType DT = 10732bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSExportPrimitiveType::GetRSSpecificType(FT); 10742bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10752bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (IsArrayType) { 10769207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine &DiagEngine = C.getDiagnostics(); 10779207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine.Report( 10789207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::FullSourceLoc(Loc, C.getSourceManager()), 10799207a2e495c8363606861e4f034504ec5c153dabLogan Chien DiagEngine.getCustomDiagID( 10809207a2e495c8363606861e4f034504ec5c153dabLogan Chien clang::DiagnosticsEngine::Error, 10819207a2e495c8363606861e4f034504ec5c153dabLogan Chien "Arrays of RS object types within structures cannot be copied")); 10822bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // TODO(srhines): Support setting arrays of RS objects 10832bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // StmtArray[StmtCount++] = 1084d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines // CreateArrayRSSetObject(C, DstMember, SrcMember, StartLoc, Loc); 10852bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else if (DT == RSExportPrimitiveType::DataTypeUnknown) { 10862bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCount++] = 1087d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines CreateStructRSSetObject(C, DstMember, SrcMember, StartLoc, Loc); 10882bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else if (RSExportPrimitiveType::IsRSObjectType(DT)) { 10892bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCount++] = 1090d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines CreateSingleRSSetObject(C, DstMember, SrcMember, StartLoc, Loc); 10912bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else { 10922bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines slangAssert(false); 10932bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 10942bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 10952bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 1096b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines slangAssert(StmtCount < FieldsToSet); 10972bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 10982bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // We still need to actually do the overall struct copy. For simplicity, 10992bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // we just do a straight-up assignment (which will still preserve all 11002bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // the proper RS object reference counts). 11012bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::BinaryOperator *CopyStruct = 1102be27482cdeaf08576bc39b72a15d35d13014a636Logan new(C) clang::BinaryOperator(LHS, RHS, clang::BO_Assign, QT, 1103be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, clang::OK_Ordinary, Loc); 11042bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines StmtArray[StmtCount++] = CopyStruct; 11052bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 11062bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::CompoundStmt *CS = 11072bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines new(C) clang::CompoundStmt(C, StmtArray, StmtCount, Loc, Loc); 11082bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 11092bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines delete [] StmtArray; 11102bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 11112bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines return CS; 11122bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines} 11132bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 11142bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines} // namespace 11152bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 11162bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hinesvoid RSObjectRefCount::Scope::ReplaceRSObjectAssignment( 1117d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines clang::BinaryOperator *AS) { 11182bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 11192bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::QualType QT = AS->getType(); 11202bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 11212bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::ASTContext &C = RSObjectRefCount::GetRSSetObjectFD( 11222bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines RSExportPrimitiveType::DataTypeRSFont)->getASTContext(); 11232bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 1124832429f6bf4592cfc2ce58f2462f1e8ecdbaaf52Stephen Hines clang::SourceLocation Loc = AS->getExprLoc(); 11259f1d0aa55669b75a718ad2e962fc8c3d8df1a5f4Stephen Hines clang::SourceLocation StartLoc = AS->getLHS()->getExprLoc(); 11262bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines clang::Stmt *UpdatedStmt = NULL; 11272bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines 11282bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines if (!RSExportPrimitiveType::IsRSObjectType(QT.getTypePtr())) { 11292bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines // By definition, this is a struct assignment if we get here 11302bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines UpdatedStmt = 1131d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines CreateStructRSSetObject(C, AS->getLHS(), AS->getRHS(), StartLoc, Loc); 11322bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } else { 11332bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines UpdatedStmt = 1134d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines CreateSingleRSSetObject(C, AS->getLHS(), AS->getRHS(), StartLoc, Loc); 11352bb67db8364162b30e6920baddf6c2e890b3ce79Stephen Hines } 1136e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1137292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines RSASTReplace R(C); 1138292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines R.ReplaceStmt(mCS, AS, UpdatedStmt); 1139e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return; 1140e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines} 1141e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1142e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hinesvoid RSObjectRefCount::Scope::AppendRSObjectInit( 1143e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::VarDecl *VD, 1144e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclStmt *DS, 1145e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataType DT, 1146e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *InitExpr) { 11476e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(VD); 1148e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1149e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (!InitExpr) { 1150e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return; 1151e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 1152e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1153a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::ASTContext &C = RSObjectRefCount::GetRSSetObjectFD( 1154a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines RSExportPrimitiveType::DataTypeRSFont)->getASTContext(); 1155a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::SourceLocation Loc = RSObjectRefCount::GetRSSetObjectFD( 1156a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines RSExportPrimitiveType::DataTypeRSFont)->getLocation(); 1157cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc = RSObjectRefCount::GetRSSetObjectFD( 1158cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao RSExportPrimitiveType::DataTypeRSFont)->getInnerLocStart(); 1159a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines 1160f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (DT == RSExportPrimitiveType::DataTypeIsStruct) { 1161a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 1162a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::DeclRefExpr *RefRSVar = 1163a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::DeclRefExpr::Create(C, 1164be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 11650444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 1166a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines VD, 1167e2597ac5a8ba7a45a1d5f342973cd43a3a1932cfShih-wei Liao false, 1168a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines Loc, 1169be27482cdeaf08576bc39b72a15d35d13014a636Logan T->getCanonicalTypeInternal(), 1170be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1171be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 1172a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines 1173a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines clang::Stmt *RSSetObjectOps = 1174d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines CreateStructRSSetObject(C, RefRSVar, InitExpr, StartLoc, Loc); 1175a0611e66bec148b176404cf6afe4c9ec9b960414Stephen Hines 1176292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*> StmtList; 1177292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines StmtList.push_back(RSSetObjectOps); 1178292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines AppendAfterStmt(C, mCS, DS, StmtList); 1179f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return; 1180f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 1181f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 1182f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::FunctionDecl *SetObjectFD = RSObjectRefCount::GetRSSetObjectFD(DT); 11836e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((SetObjectFD != NULL) && 11846e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "rsSetObject doesn't cover all RS object types"); 1185e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1186e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::QualType SetObjectFDType = SetObjectFD->getType(); 1187e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::QualType SetObjectFDArgType[2]; 1188e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDArgType[0] = SetObjectFD->getParamDecl(0)->getOriginalType(); 1189e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDArgType[1] = SetObjectFD->getParamDecl(1)->getOriginalType(); 1190e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1191e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *RefRSSetObjectFD = 1192e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr::Create(C, 1193be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 11940444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 1195e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFD, 1196e2597ac5a8ba7a45a1d5f342973cd43a3a1932cfShih-wei Liao false, 1197e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc, 1198be27482cdeaf08576bc39b72a15d35d13014a636Logan SetObjectFDType, 1199be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1200be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 1201e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1202e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *RSSetObjectFP = 1203e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::ImplicitCastExpr::Create(C, 1204e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines C.getPointerType(SetObjectFDType), 1205e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CK_FunctionToPointerDecay, 1206e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RefRSSetObjectFD, 1207e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines NULL, 1208e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::VK_RValue); 1209e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1210e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 1211e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr *RefRSVar = 1212e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr::Create(C, 1213be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 12140444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 1215e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD, 1216e2597ac5a8ba7a45a1d5f342973cd43a3a1932cfShih-wei Liao false, 1217e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc, 1218be27482cdeaf08576bc39b72a15d35d13014a636Logan T->getCanonicalTypeInternal(), 1219be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1220be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 1221e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 12221dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines llvm::SmallVector<clang::Expr*, 2> ArgList; 12231dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines ArgList.push_back(new(C) clang::UnaryOperator(RefRSVar, 12241dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines clang::UO_AddrOf, 12251dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines SetObjectFDArgType[0], 12261dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines clang::VK_RValue, 12271dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines clang::OK_Ordinary, 12281dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines Loc)); 12291dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines ArgList.push_back(InitExpr); 1230e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1231e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CallExpr *RSSetObjectCall = 1232e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines new(C) clang::CallExpr(C, 1233e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSSetObjectFP, 1234e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ArgList, 1235e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFD->getCallResultType(), 1236be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1237e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc); 1238e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1239292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines std::list<clang::Stmt*> StmtList; 1240292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines StmtList.push_back(RSSetObjectCall); 1241292e00a0259ac28cac1055cb6077cf6fc7c6743cStephen Hines AppendAfterStmt(C, mCS, DS, StmtList); 1242c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 1243c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines return; 1244c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines} 1245c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 12461bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hinesvoid RSObjectRefCount::Scope::InsertLocalVarDestructors() { 12471bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines for (std::list<clang::VarDecl*>::const_iterator I = mRSO.begin(), 12481bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines E = mRSO.end(); 12491bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines I != E; 12501bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines I++) { 1251a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines clang::VarDecl *VD = *I; 12523f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines clang::Stmt *RSClearObjectCall = ClearRSObject(VD, VD->getDeclContext()); 1253a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines if (RSClearObjectCall) { 1254a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines DestructorVisitor DV((*mRSO.begin())->getASTContext(), 1255a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines mCS, 1256a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines RSClearObjectCall, 1257a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines VD->getSourceRange().getBegin()); 1258a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines DV.Visit(mCS); 1259a883ce325281796dc7cc8fcf973a7ccd47a9a17eStephen Hines DV.InsertDestructors(); 12601bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 12611bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 12621bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines return; 12631bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 12641bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 12653f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hinesclang::Stmt *RSObjectRefCount::Scope::ClearRSObject( 12663f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines clang::VarDecl *VD, 12673f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines clang::DeclContext *DC) { 1268f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(VD); 12691bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::ASTContext &C = VD->getASTContext(); 12701bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::SourceLocation Loc = VD->getLocation(); 1271cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao clang::SourceLocation StartLoc = VD->getInnerLocStart(); 12721bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 127303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 12741bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Reference expr to target RS object variable 12751bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::DeclRefExpr *RefRSVar = 12761bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::DeclRefExpr::Create(C, 1277be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::NestedNameSpecifierLoc(), 12780444de0c0e7cfc8d8f8fed6f64cd97812bdd6a41Stephen Hines clang::SourceLocation(), 12791bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines VD, 1280e2597ac5a8ba7a45a1d5f342973cd43a3a1932cfShih-wei Liao false, 12811bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines Loc, 1282be27482cdeaf08576bc39b72a15d35d13014a636Logan T->getCanonicalTypeInternal(), 1283be27482cdeaf08576bc39b72a15d35d13014a636Logan clang::VK_RValue, 1284be27482cdeaf08576bc39b72a15d35d13014a636Logan NULL); 12851bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1286f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (T->isArrayType()) { 1287cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao return ClearArrayRSObject(C, DC, RefRSVar, StartLoc, Loc); 1288f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 12891bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1290f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::DataType DT = 1291f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::GetRSSpecificType(T); 12921bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1293f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (DT == RSExportPrimitiveType::DataTypeUnknown || 1294f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DT == RSExportPrimitiveType::DataTypeIsStruct) { 1295cc887ba8fe42cca706caae636932ae6a61a30ed2Shih-wei Liao return ClearStructRSObject(C, DC, RefRSVar, StartLoc, Loc); 1296f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 12971bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1298f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert((RSExportPrimitiveType::IsRSObjectType(DT)) && 1299f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "Should be RS object"); 13001bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1301f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return ClearSingleRSObject(C, RefRSVar, Loc); 13021bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 13031bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1304e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hinesbool RSObjectRefCount::InitializeRSObject(clang::VarDecl *VD, 1305e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataType *DT, 1306e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr **InitExpr) { 13076e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(VD && DT && InitExpr); 13084b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 13092d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines 13102d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines // Loop through array types to get to base type 13112d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines while (T && T->isArrayType()) { 13122d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines T = T->getArrayElementTypeNoTypeQual(); 13132d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines } 13142d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines 1315f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool DataTypeIsStructWithRSObject = false; 1316e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines *DT = RSExportPrimitiveType::GetRSSpecificType(T); 13174b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1318e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (*DT == RSExportPrimitiveType::DataTypeUnknown) { 1319feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (RSExportPrimitiveType::IsStructureTypeWithRSObject(T)) { 1320feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines *DT = RSExportPrimitiveType::DataTypeIsStruct; 1321f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DataTypeIsStructWithRSObject = true; 1322feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } else { 1323feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines return false; 1324feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 13252d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines } 13264b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1327f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool DataTypeIsRSObject = false; 1328f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (DataTypeIsStructWithRSObject) { 1329f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DataTypeIsRSObject = true; 1330f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 1331f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DataTypeIsRSObject = RSExportPrimitiveType::IsRSObjectType(*DT); 1332f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 1333e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines *InitExpr = VD->getInit(); 1334e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1335e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (!DataTypeIsRSObject && *InitExpr) { 1336e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines // If we already have an initializer for a matrix type, we are done. 1337e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return DataTypeIsRSObject; 13384b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 13394b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1340e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *ZeroInitializer = 1341e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines CreateZeroInitializerForRSSpecificType(*DT, 1342e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->getASTContext(), 1343e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->getLocation()); 1344e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1345e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (ZeroInitializer) { 1346e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ZeroInitializer->setType(T->getCanonicalTypeInternal()); 1347e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->setInit(ZeroInitializer); 1348e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 1349e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 1350e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return DataTypeIsRSObject; 13514b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 13524b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 13534b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesclang::Expr *RSObjectRefCount::CreateZeroInitializerForRSSpecificType( 13544b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines RSExportPrimitiveType::DataType DT, 13554b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ASTContext &C, 13564b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines const clang::SourceLocation &Loc) { 13574b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *Res = NULL; 13584b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines switch (DT) { 1359feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines case RSExportPrimitiveType::DataTypeIsStruct: 13604b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSElement: 13614b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSType: 13624b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSAllocation: 13634b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSSampler: 13644b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSScript: 13654b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMesh: 1366db6dfdfcb7e8183f1c796475e5098ee4be80b5b8Jason Sams case RSExportPrimitiveType::DataTypeRSPath: 13674b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramFragment: 13684b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramVertex: 13694b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramRaster: 13704b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramStore: 13714b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSFont: { 13724b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (ImplicitCastExpr 'nullptr_t' 13734b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (IntegerLiteral 0))) 13744b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APInt Zero(C.getTypeSize(C.IntTy), 0); 13754b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, Zero, C.IntTy, Loc); 13764b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *CastToNull = 13774b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ImplicitCastExpr::Create(C, 13784b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines C.NullPtrTy, 13794b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::CK_IntegralToPointer, 13804b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Int0, 13814b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines NULL, 13824b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::VK_RValue); 13834b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 13841dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines llvm::SmallVector<clang::Expr*, 1>InitList; 13851dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines InitList.push_back(CastToNull); 13861dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines 13871dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines Res = new(C) clang::InitListExpr(C, Loc, InitList, Loc); 13884b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines break; 13894b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 13904b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMatrix2x2: 13914b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMatrix3x3: 13924b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMatrix4x4: { 13934b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // RS matrix is not completely an RS object. They hold data by themselves. 13944b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (InitListExpr rs_matrix2x2 13954b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (InitListExpr float[4] 13964b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 13974b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 13984b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 13994b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0))) 14004b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::QualType FloatTy = C.FloatTy; 14014b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Constructor sets value to 0.0f by default 14024b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APFloat Val(C.getFloatTypeSemantics(FloatTy)); 14034b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::FloatingLiteral *Float0Val = 14044b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::FloatingLiteral::Create(C, 14054b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Val, 14064b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines /* isExact = */true, 14074b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines FloatTy, 14084b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Loc); 14094b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 14104b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines unsigned N = 0; 14114b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (DT == RSExportPrimitiveType::DataTypeRSMatrix2x2) 14124b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 2; 14134b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines else if (DT == RSExportPrimitiveType::DataTypeRSMatrix3x3) 14144b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 3; 14154b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines else if (DT == RSExportPrimitiveType::DataTypeRSMatrix4x4) 14164b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 4; 14171dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines unsigned N_2 = N * N; 14184b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 14191dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines // Assume we are going to be allocating 16 elements, since 4x4 is max. 14201dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines llvm::SmallVector<clang::Expr*, 16> InitVals; 14211dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines for (unsigned i = 0; i < N_2; i++) 14221dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines InitVals.push_back(Float0Val); 14234b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *InitExpr = 14241dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines new(C) clang::InitListExpr(C, Loc, InitVals, Loc); 14254b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines InitExpr->setType(C.getConstantArrayType(FloatTy, 14261dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines llvm::APInt(32, N_2), 14274b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ArrayType::Normal, 14284b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines /* EltTypeQuals = */0)); 14291dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines llvm::SmallVector<clang::Expr*, 1> InitExprVec; 14301dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines InitExprVec.push_back(InitExpr); 14314b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 14321dfc415431ddd360354fecfcd9b12dcaf686355aStephen Hines Res = new(C) clang::InitListExpr(C, Loc, InitExprVec, Loc); 14334b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines break; 14344b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 14354b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnknown: 14364b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeFloat16: 14374b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeFloat32: 14384b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeFloat64: 14394b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned8: 14404b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned16: 14414b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned32: 14424b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned64: 14434b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned8: 14444b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned16: 14454b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned32: 14464b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned64: 14474b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeBoolean: 14484b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned565: 14494b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned5551: 14504b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned4444: 14514b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeMax: { 14526e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Not RS object type!"); 14534b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 14544b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // No default case will enable compiler detecting the missing cases 14554b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 14564b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 14574b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return Res; 14584b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 14594b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 14604b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitDeclStmt(clang::DeclStmt *DS) { 14614b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (clang::DeclStmt::decl_iterator I = DS->decl_begin(), E = DS->decl_end(); 14624b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I != E; 14634b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I++) { 14644b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Decl *D = *I; 14654b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (D->getKind() == clang::Decl::Var) { 14664b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::VarDecl *VD = static_cast<clang::VarDecl*>(D); 1467e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataType DT = 1468e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataTypeUnknown; 1469e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *InitExpr = NULL; 1470e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (InitializeRSObject(VD, &DT, &InitExpr)) { 1471b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines // We need to zero-init all RS object types (including matrices), ... 1472d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines getCurrentScope()->AppendRSObjectInit(VD, DS, DT, InitExpr); 1473b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines // ... but, only add to the list of RS objects if we have some 1474b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines // non-matrix RS object fields. 1475b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines if (CountRSObjectTypes(mCtx, VD->getType().getTypePtr(), 1476b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines VD->getLocation())) { 1477b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines getCurrentScope()->addRSObject(VD); 1478b0fabe574945bfa85e688e77e9dcb5341fe08840Stephen Hines } 1479e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 14804b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 14814b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 14824b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 14834b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 14844b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 14854b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitCompoundStmt(clang::CompoundStmt *CS) { 14864b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (!CS->body_empty()) { 14874b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Push a new scope 14884b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Scope *S = new Scope(CS); 14894b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines mScopeStack.push(S); 14904b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 14914b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines VisitStmt(CS); 14924b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 14934b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Destroy the scope 14946e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((getCurrentScope() == S) && "Corrupted scope stack!"); 14951bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines S->InsertLocalVarDestructors(); 14964b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines mScopeStack.pop(); 14974b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines delete S; 14984b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 14994b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 15004b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 15014b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 15024b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitBinAssign(clang::BinaryOperator *AS) { 1503c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType QT = AS->getType(); 1504c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 1505d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines if (CountRSObjectTypes(mCtx, QT.getTypePtr(), AS->getExprLoc())) { 1506d0b5edd02be5f09c1d8d211f4a06b031a7b66510Stephen Hines getCurrentScope()->ReplaceRSObjectAssignment(AS); 1507c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 1508c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 15094b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 15104b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 15114b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 15124b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitStmt(clang::Stmt *S) { 15134b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end(); 15144b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I != E; 15154b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I++) { 15164b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (clang::Stmt *Child = *I) { 15174b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Visit(Child); 15184b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 15194b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 15204b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 15214b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 15224b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1523688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines// This function walks the list of global variables and (potentially) creates 1524688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines// a single global static destructor function that properly decrements 1525688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines// reference counts on the contained RS object types. 1526688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hinesclang::FunctionDecl *RSObjectRefCount::CreateStaticGlobalDtor() { 1527688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines Init(); 1528688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 1529688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines clang::DeclContext *DC = mCtx.getTranslationUnitDecl(); 1530688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines clang::SourceLocation loc; 1531688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 15323f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines llvm::StringRef SR(".rs.dtor"); 15333f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines clang::IdentifierInfo &II = mCtx.Idents.get(SR); 15343f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines clang::DeclarationName N(&II); 15353f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines clang::FunctionProtoType::ExtProtoInfo EPI; 15363f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines clang::QualType T = mCtx.getFunctionType(mCtx.VoidTy, NULL, 0, EPI); 15373f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines clang::FunctionDecl *FD = NULL; 15383f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines 1539688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines // Generate rsClearObject() call chains for every global variable 1540688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines // (whether static or extern). 1541688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines std::list<clang::Stmt *> StmtList; 1542688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines for (clang::DeclContext::decl_iterator I = DC->decls_begin(), 1543688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines E = DC->decls_end(); I != E; I++) { 1544688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines clang::VarDecl *VD = llvm::dyn_cast<clang::VarDecl>(*I); 1545688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines if (VD) { 1546688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines if (CountRSObjectTypes(mCtx, VD->getType().getTypePtr(), loc)) { 15473f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines if (!FD) { 15483f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines // Only create FD if we are going to use it. 15493f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines FD = clang::FunctionDecl::Create(mCtx, DC, loc, loc, N, T, NULL); 15503f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines } 15513f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines // Make sure to create any helpers within the function's DeclContext, 15523f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines // not the one associated with the global translation unit. 15533f175af8a0644fb5fc53aa90e01c24f75855c5f7Stephen Hines clang::Stmt *RSClearObjectCall = Scope::ClearRSObject(VD, FD); 1554688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines StmtList.push_back(RSClearObjectCall); 1555688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines } 1556688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines } 1557688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines } 1558688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 1559688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines // Nothing needs to be destroyed, so don't emit a dtor. 1560688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines if (StmtList.empty()) { 1561688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines return NULL; 1562688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines } 1563688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 1564688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines clang::CompoundStmt *CS = BuildCompoundStmt(mCtx, StmtList, loc); 1565688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 1566688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines FD->setBody(CS); 1567688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 1568688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines return FD; 1569688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines} 1570688e64b2d56e4218c680b9d6523c5de672f55757Stephen Hines 1571e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 1572