slang_rs_object_ref_count.cpp revision f2174cfd6a556b51aadf2b8765e50df080e8f18e
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" 234b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "clang/AST/OperationKinds.h" 244b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "clang/AST/Stmt.h" 254b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "clang/AST/StmtVisitor.h" 264b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 276e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines#include "slang_assert.h" 284b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "slang_rs.h" 294b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines#include "slang_rs_export_type.h" 304b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 31e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang { 324b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 33f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesclang::FunctionDecl *RSObjectRefCount:: 341bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSSetObjectFD[RSExportPrimitiveType::LastRSObjectType - 351bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSExportPrimitiveType::FirstRSObjectType + 1]; 36f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesclang::FunctionDecl *RSObjectRefCount:: 371bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSClearObjectFD[RSExportPrimitiveType::LastRSObjectType - 381bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSExportPrimitiveType::FirstRSObjectType + 1]; 391bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 40f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesvoid RSObjectRefCount::GetRSRefCountingFunctions(clang::ASTContext &C) { 411bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines for (unsigned i = 0; 421bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines i < (sizeof(RSClearObjectFD) / sizeof(clang::FunctionDecl*)); 431bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines i++) { 441bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSSetObjectFD[i] = NULL; 451bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSClearObjectFD[i] = NULL; 461bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 471bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 481bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl(); 491bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 501bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(), 511bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines E = TUDecl->decls_end(); I != E; I++) { 521bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if ((I->getKind() >= clang::Decl::firstFunction) && 531bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines (I->getKind() <= clang::Decl::lastFunction)) { 541bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::FunctionDecl *FD = static_cast<clang::FunctionDecl*>(*I); 551bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 561bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // points to RSSetObjectFD or RSClearObjectFD 571bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::FunctionDecl **RSObjectFD; 581bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 591bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if (FD->getName() == "rsSetObject") { 606e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((FD->getNumParams() == 2) && 616e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "Invalid rsSetObject function prototype (# params)"); 621bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSObjectFD = RSSetObjectFD; 631bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } else if (FD->getName() == "rsClearObject") { 646e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((FD->getNumParams() == 1) && 656e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "Invalid rsClearObject function prototype (# params)"); 661bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSObjectFD = RSClearObjectFD; 67e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines } else { 681bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines continue; 691bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 701bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 711bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines const clang::ParmVarDecl *PVD = FD->getParamDecl(0); 721bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::QualType PVT = PVD->getOriginalType(); 731bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // The first parameter must be a pointer like rs_allocation* 746e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(PVT->isPointerType() && 756e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "Invalid rs{Set,Clear}Object function prototype (pointer param)"); 761bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 771bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // The rs object type passed to the FD 781bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::QualType RST = PVT->getPointeeType(); 791bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSExportPrimitiveType::DataType DT = 801bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSExportPrimitiveType::GetRSSpecificType(RST.getTypePtr()); 816e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(RSExportPrimitiveType::IsRSObjectType(DT) 821bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines && "must be RS object type"); 831bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 841bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines RSObjectFD[(DT - RSExportPrimitiveType::FirstRSObjectType)] = FD; 851bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 861bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 871bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 881bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 894464d825c11349068f2917f9ebee86b721423f3cStephen Hinesnamespace { 904464d825c11349068f2917f9ebee86b721423f3cStephen Hines 914464d825c11349068f2917f9ebee86b721423f3cStephen Hinesstatic void AppendToCompoundStatement(clang::ASTContext& C, 924464d825c11349068f2917f9ebee86b721423f3cStephen Hines clang::CompoundStmt *CS, 93d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines std::list<clang::Stmt*> &StmtList, 944464d825c11349068f2917f9ebee86b721423f3cStephen Hines bool InsertAtEndOfBlock) { 951bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Destructor code will be inserted before any return statement. 961bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Any subsequent statements in the compound statement are then placed 971bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // after our new code. 98e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines // TODO(srhines): This should also handle the case of goto/break/continue. 994464d825c11349068f2917f9ebee86b721423f3cStephen Hines 1004464d825c11349068f2917f9ebee86b721423f3cStephen Hines clang::CompoundStmt::body_iterator bI = CS->body_begin(); 1011bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1021bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines unsigned OldStmtCount = 0; 10303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines for (bI = CS->body_begin(); bI != CS->body_end(); bI++) { 1041bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines OldStmtCount++; 1051bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1061bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 107d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines unsigned NewStmtCount = StmtList.size(); 1081bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 109d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines clang::Stmt **UpdatedStmtList; 110d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines UpdatedStmtList = new clang::Stmt*[OldStmtCount+NewStmtCount]; 1111bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1121bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines unsigned UpdatedStmtCount = 0; 1134464d825c11349068f2917f9ebee86b721423f3cStephen Hines bool FoundReturn = false; 11403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines for (bI = CS->body_begin(); bI != CS->body_end(); bI++) { 1151bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if ((*bI)->getStmtClass() == clang::Stmt::ReturnStmtClass) { 1164464d825c11349068f2917f9ebee86b721423f3cStephen Hines FoundReturn = true; 1171bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines break; 1181bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 119d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines UpdatedStmtList[UpdatedStmtCount++] = *bI; 1201bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1211bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1224464d825c11349068f2917f9ebee86b721423f3cStephen Hines // Always insert before a return that we found, or if we are told 1234464d825c11349068f2917f9ebee86b721423f3cStephen Hines // to insert at the end of the block 1244464d825c11349068f2917f9ebee86b721423f3cStephen Hines if (FoundReturn || InsertAtEndOfBlock) { 12503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines std::list<clang::Stmt*>::const_iterator I = StmtList.begin(); 12603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines for (std::list<clang::Stmt*>::const_iterator I = StmtList.begin(); 12703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines I != StmtList.end(); 1284464d825c11349068f2917f9ebee86b721423f3cStephen Hines I++) { 129d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines UpdatedStmtList[UpdatedStmtCount++] = *I; 1304464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 1311bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1321bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1331bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Pick up anything left over after a return statement 13403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines for ( ; bI != CS->body_end(); bI++) { 135d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines UpdatedStmtList[UpdatedStmtCount++] = *bI; 1361bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 1371bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 138d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines CS->setStmts(C, UpdatedStmtList, UpdatedStmtCount); 1391bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 140d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines delete [] UpdatedStmtList; 1411bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 1421bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines return; 1431bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 1441bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 145e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hinesstatic void AppendAfterStmt(clang::ASTContext& C, 146e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CompoundStmt *CS, 147e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Stmt *OldStmt, 148e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Stmt *NewStmt) { 1496e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(CS && OldStmt && NewStmt); 150e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CompoundStmt::body_iterator bI = CS->body_begin(); 151e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines unsigned StmtCount = 1; // Take into account new statement 152e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines for (bI = CS->body_begin(); bI != CS->body_end(); bI++) { 153e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines StmtCount++; 154e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 155e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 156e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Stmt **UpdatedStmtList = new clang::Stmt*[StmtCount]; 157e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 158e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines unsigned UpdatedStmtCount = 0; 159e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines unsigned Once = 0; 160e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines for (bI = CS->body_begin(); bI != CS->body_end(); bI++) { 161e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines UpdatedStmtList[UpdatedStmtCount++] = *bI; 162e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (*bI == OldStmt) { 163e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Once++; 1646e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(Once == 1); 165e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines UpdatedStmtList[UpdatedStmtCount++] = NewStmt; 166e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 167e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 168e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 169e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines CS->setStmts(C, UpdatedStmtList, UpdatedStmtCount); 170e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 171e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines delete [] UpdatedStmtList; 172e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 173e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return; 174e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines} 175e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 176e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hinesstatic void ReplaceInCompoundStmt(clang::ASTContext& C, 177c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::CompoundStmt *CS, 178c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Stmt* OldStmt, 179c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Stmt* NewStmt) { 180c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::CompoundStmt::body_iterator bI = CS->body_begin(); 181c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 182c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines unsigned StmtCount = 0; 183c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines for (bI = CS->body_begin(); bI != CS->body_end(); bI++) { 184c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines StmtCount++; 185c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 186c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 187c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Stmt **UpdatedStmtList = new clang::Stmt*[StmtCount]; 188c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 189c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines unsigned UpdatedStmtCount = 0; 190c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines for (bI = CS->body_begin(); bI != CS->body_end(); bI++) { 191c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines if (*bI == OldStmt) { 192c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines UpdatedStmtList[UpdatedStmtCount++] = NewStmt; 193c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } else { 194c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines UpdatedStmtList[UpdatedStmtCount++] = *bI; 195c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 196c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 197c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 198c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines CS->setStmts(C, UpdatedStmtList, UpdatedStmtCount); 199c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 200c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines delete [] UpdatedStmtList; 201c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 202c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines return; 203c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines} 204c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 205c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 206d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines// This class visits a compound statement and inserts the StmtList containing 2074464d825c11349068f2917f9ebee86b721423f3cStephen Hines// destructors in proper locations. This includes inserting them before any 2084464d825c11349068f2917f9ebee86b721423f3cStephen Hines// return statement in any sub-block, at the end of the logical enclosing 2094464d825c11349068f2917f9ebee86b721423f3cStephen Hines// scope (compound statement), and/or before any break/continue statement that 2104464d825c11349068f2917f9ebee86b721423f3cStephen Hines// would resume outside the declared scope. We will not handle the case for 2114464d825c11349068f2917f9ebee86b721423f3cStephen Hines// goto statements that leave a local scope. 2124464d825c11349068f2917f9ebee86b721423f3cStephen Hines// TODO(srhines): Make this work properly for break/continue. 2134464d825c11349068f2917f9ebee86b721423f3cStephen Hinesclass DestructorVisitor : public clang::StmtVisitor<DestructorVisitor> { 2144464d825c11349068f2917f9ebee86b721423f3cStephen Hines private: 2154464d825c11349068f2917f9ebee86b721423f3cStephen Hines clang::ASTContext &mC; 216d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines std::list<clang::Stmt*> &mStmtList; 2174464d825c11349068f2917f9ebee86b721423f3cStephen Hines bool mTopLevel; 2184464d825c11349068f2917f9ebee86b721423f3cStephen Hines public: 219d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines DestructorVisitor(clang::ASTContext &C, std::list<clang::Stmt*> &StmtList); 2204464d825c11349068f2917f9ebee86b721423f3cStephen Hines void VisitStmt(clang::Stmt *S); 2214464d825c11349068f2917f9ebee86b721423f3cStephen Hines void VisitCompoundStmt(clang::CompoundStmt *CS); 2224464d825c11349068f2917f9ebee86b721423f3cStephen Hines}; 2234464d825c11349068f2917f9ebee86b721423f3cStephen Hines 2244464d825c11349068f2917f9ebee86b721423f3cStephen HinesDestructorVisitor::DestructorVisitor(clang::ASTContext &C, 225d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines std::list<clang::Stmt*> &StmtList) 2264464d825c11349068f2917f9ebee86b721423f3cStephen Hines : mC(C), 227d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines mStmtList(StmtList), 2284464d825c11349068f2917f9ebee86b721423f3cStephen Hines mTopLevel(true) { 2294464d825c11349068f2917f9ebee86b721423f3cStephen Hines return; 2304464d825c11349068f2917f9ebee86b721423f3cStephen Hines} 2314464d825c11349068f2917f9ebee86b721423f3cStephen Hines 2324464d825c11349068f2917f9ebee86b721423f3cStephen Hinesvoid DestructorVisitor::VisitCompoundStmt(clang::CompoundStmt *CS) { 2334464d825c11349068f2917f9ebee86b721423f3cStephen Hines if (!CS->body_empty()) { 234d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines AppendToCompoundStatement(mC, CS, mStmtList, mTopLevel); 2354464d825c11349068f2917f9ebee86b721423f3cStephen Hines mTopLevel = false; 2364464d825c11349068f2917f9ebee86b721423f3cStephen Hines VisitStmt(CS); 2374464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 2384464d825c11349068f2917f9ebee86b721423f3cStephen Hines return; 2394464d825c11349068f2917f9ebee86b721423f3cStephen Hines} 2404464d825c11349068f2917f9ebee86b721423f3cStephen Hines 2414464d825c11349068f2917f9ebee86b721423f3cStephen Hinesvoid DestructorVisitor::VisitStmt(clang::Stmt *S) { 2424464d825c11349068f2917f9ebee86b721423f3cStephen Hines for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end(); 2434464d825c11349068f2917f9ebee86b721423f3cStephen Hines I != E; 2444464d825c11349068f2917f9ebee86b721423f3cStephen Hines I++) { 2454464d825c11349068f2917f9ebee86b721423f3cStephen Hines if (clang::Stmt *Child = *I) { 2464464d825c11349068f2917f9ebee86b721423f3cStephen Hines Visit(Child); 2474464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 2484464d825c11349068f2917f9ebee86b721423f3cStephen Hines } 2494464d825c11349068f2917f9ebee86b721423f3cStephen Hines return; 2504464d825c11349068f2917f9ebee86b721423f3cStephen Hines} 2514464d825c11349068f2917f9ebee86b721423f3cStephen Hines 252f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesclang::Expr *ClearSingleRSObject(clang::ASTContext &C, 253f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSVar, 254f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc) { 255f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(RefRSVar); 256f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *T = RefRSVar->getType().getTypePtr(); 257f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(!T->isArrayType() && 258f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "Should not be destroying arrays with this function"); 259f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 260f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::FunctionDecl *ClearObjectFD = RSObjectRefCount::GetRSClearObjectFD(T); 261f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert((ClearObjectFD != NULL) && 262f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "rsClearObject doesn't cover all RS object types"); 263f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 264f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::QualType ClearObjectFDType = ClearObjectFD->getType(); 265f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::QualType ClearObjectFDArgType = 266f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD->getParamDecl(0)->getOriginalType(); 267f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 268f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Example destructor for "rs_font localFont;" 269f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // 270f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (CallExpr 'void' 271f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (ImplicitCastExpr 'void (*)(rs_font *)' <FunctionToPointerDecay> 272f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (DeclRefExpr 'void (rs_font *)' FunctionDecl='rsClearObject')) 273f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (UnaryOperator 'rs_font *' prefix '&' 274f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // (DeclRefExpr 'rs_font':'rs_font' Var='localFont'))) 275f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 276f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Get address of targeted RS object 277f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *AddrRefRSVar = 278f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::UnaryOperator(RefRSVar, 279f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::UO_AddrOf, 280f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFDArgType, 281f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 282f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 283f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSClearObjectFD = 284f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclRefExpr::Create(C, 285f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines NULL, 286f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD->getQualifierRange(), 287f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD, 288f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD->getLocation(), 289f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFDType); 290f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 291f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RSClearObjectFP = 292f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ImplicitCastExpr::Create(C, 293f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines C.getPointerType(ClearObjectFDType), 294f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::CK_FunctionToPointerDecay, 295f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSClearObjectFD, 296f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines NULL, 297f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::VK_RValue); 29803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 299f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::CallExpr *RSClearObjectCall = 300f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::CallExpr(C, 301f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectFP, 302f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines &AddrRefRSVar, 303f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 1, 304f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearObjectFD->getCallResultType(), 305f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 306f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 307f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return RSClearObjectCall; 308f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines} 309f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 310f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic int ArrayDim(const clang::Type *T) { 31103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (!T || !T->isArrayType()) { 31203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return 0; 31303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 31403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 31503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines const clang::ConstantArrayType *CAT = 31603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines static_cast<const clang::ConstantArrayType *>(T); 3179d2c0fa6490e09b3ff5603796bce42d97788e5c8Stephen Hines return static_cast<int>(CAT->getSize().getSExtValue()); 31803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines} 31903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 320f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic clang::Stmt *ClearStructRSObject( 321f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ASTContext &C, 322f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC, 323f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSStruct, 324f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceRange Range, 325f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc); 326f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 327f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic clang::Stmt *ClearArrayRSObject( 328f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ASTContext &C, 329f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC, 330f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSArr, 331f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceRange Range, 332f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc) { 333f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *BaseType = RefRSArr->getType().getTypePtr(); 334f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(BaseType->isArrayType()); 335f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 336f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines int NumArrayElements = ArrayDim(BaseType); 337f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Actually extract out the base RS object type for use later 338f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines BaseType = BaseType->getArrayElementTypeNoTypeQual(); 33903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 34003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Stmt *StmtArray[2] = {NULL}; 34103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines int StmtCtr = 0; 34203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 34303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines if (NumArrayElements <= 0) { 34403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return NULL; 34503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines } 34603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 34703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Example destructor loop for "rs_font fontArr[10];" 34803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // 34903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (CompoundStmt 35003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclStmt "int rsIntIter") 35103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ForStmt 35203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (BinaryOperator 'int' '=' 35303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter') 35403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (IntegerLiteral 'int' 0)) 35503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (BinaryOperator 'int' '<' 35603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter') 35703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (IntegerLiteral 'int' 10) 35803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // NULL << CondVar >> 35903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (UnaryOperator 'int' postfix '++' 36003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter')) 36103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (CallExpr 'void' 36203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ImplicitCastExpr 'void (*)(rs_font *)' <FunctionToPointerDecay> 36303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'void (rs_font *)' FunctionDecl='rsClearObject')) 36403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (UnaryOperator 'rs_font *' prefix '&' 36503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ArraySubscriptExpr 'rs_font':'rs_font' 36603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (ImplicitCastExpr 'rs_font *' <ArrayToPointerDecay> 36703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'rs_font [10]' Var='fontArr')) 36803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // (DeclRefExpr 'int' Var='rsIntIter'))))))) 36903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 37003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Create helper variable for iterating through elements 37103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::IdentifierInfo& II = C.Idents.get("rsIntIter"); 37203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VarDecl *IIVD = 37303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VarDecl::Create(C, 374f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 37503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 37603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines &II, 37703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 37803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.getTrivialTypeSourceInfo(C.IntTy), 37903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::SC_None, 38003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::SC_None); 38103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Decl *IID = (clang::Decl *)IIVD; 38203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 38303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclGroupRef DGR = clang::DeclGroupRef::Create(C, &IID, 1); 38403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines StmtArray[StmtCtr++] = new(C) clang::DeclStmt(DGR, Loc, Loc); 38503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 38603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Form the actual destructor loop 38703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // for (Init; Cond; Inc) 38803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // RSClearObjectCall; 38903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 39003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Init -> "rsIntIter = 0" 39103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclRefExpr *RefrsIntIter = 39203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::DeclRefExpr::Create(C, 39303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, 39403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Range, 39503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines IIVD, 39603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 39703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy); 39803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 39903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, 40003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), 0), C.IntTy, Loc); 40103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 40203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BinaryOperator *Init = 40303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 40403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Int0, 40503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BO_Assign, 40603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 40703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 40803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 40903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Cond -> "rsIntIter < NumArrayElements" 41003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::Expr *NumArrayElementsExpr = clang::IntegerLiteral::Create(C, 41103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines llvm::APInt(C.getTypeSize(C.IntTy), NumArrayElements), C.IntTy, Loc); 41203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 41303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BinaryOperator *Cond = 41403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::BinaryOperator(RefrsIntIter, 41503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NumArrayElementsExpr, 41603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::BO_LT, 41703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 41803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 41903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 42003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Inc -> "rsIntIter++" 42103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::UnaryOperator *Inc = 42203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::UnaryOperator(RefrsIntIter, 42303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::UO_PostInc, 42403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines C.IntTy, 42503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 42603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 42703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Body -> "rsClearObject(&VD[rsIntIter]);" 42803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines // Destructor loop operates on individual array elements 42903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 430f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSArrPtr = 43103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::ImplicitCastExpr::Create(C, 432f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines C.getPointerType(BaseType->getCanonicalTypeInternal()), 43303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::CK_ArrayToPointerDecay, 434f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSArr, 43503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, 43603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::VK_RValue); 43703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 438f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSArrPtrSubscript = 439f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::ArraySubscriptExpr(RefRSArrPtr, 44003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines RefrsIntIter, 441f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines BaseType->getCanonicalTypeInternal(), 442f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 44303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 444f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::DataType DT = 445f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::GetRSSpecificType(BaseType); 446f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 447f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Stmt *RSClearObjectCall = NULL; 448f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (BaseType->isArrayType()) { 449f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectCall = 450f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearArrayRSObject(C, DC, RefRSArrPtrSubscript, Range, Loc); 451f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else if (DT == RSExportPrimitiveType::DataTypeUnknown) { 452f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectCall = 453f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines ClearStructRSObject(C, DC, RefRSArrPtrSubscript, Range, Loc); 454f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 455f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSClearObjectCall = ClearSingleRSObject(C, RefRSArrPtrSubscript, Loc); 456f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 45703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 45803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::ForStmt *DestructorLoop = 45903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::ForStmt(C, 46003981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Init, 46103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Cond, 46203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines NULL, // no condVar 46303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Inc, 46403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines RSClearObjectCall, 46503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 46603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc, 46703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines Loc); 46803981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 46903981a308201b9123512297c8b9562a0f29bdf31Stephen Hines StmtArray[StmtCtr++] = DestructorLoop; 4706e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(StmtCtr == 2); 47103981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 47203981a308201b9123512297c8b9562a0f29bdf31Stephen Hines clang::CompoundStmt *CS = 47303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines new(C) clang::CompoundStmt(C, StmtArray, StmtCtr, Loc, Loc); 47403981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 47503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines return CS; 47603981a308201b9123512297c8b9562a0f29bdf31Stephen Hines} 47703981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 478f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic unsigned CountRSObjectTypesInStruct(const clang::Type *T) { 479f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(T); 480f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines unsigned RSObjectCount = 0; 481f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 482f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (T->isArrayType()) { 483f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return CountRSObjectTypesInStruct(T->getArrayElementTypeNoTypeQual()); 484f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 485f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 486f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::DataType DT = 487f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::GetRSSpecificType(T); 488f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (DT != RSExportPrimitiveType::DataTypeUnknown) { 489f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return (RSExportPrimitiveType::IsRSObjectType(DT) ? 1 : 0); 490f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 491f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 492f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (!T->isStructureType()) { 493f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return 0; 494f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 495f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 496f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::RecordDecl *RD = T->getAsStructureType()->getDecl(); 497f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RD = RD->getDefinition(); 498f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 499f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FE = RD->field_end(); 500f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI != FE; 501f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI++) { 502f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::FieldDecl *FD = *FI; 503f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 504f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (CountRSObjectTypesInStruct(FT)) { 505f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Sub-structs should only count once (as should arrays, etc.) 506f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectCount++; 507f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 508f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 509f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 510f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return RSObjectCount; 511f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines} 512f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 513f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hinesstatic clang::Stmt *ClearStructRSObject( 514f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::ASTContext &C, 515f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC, 516f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Expr *RefRSStruct, 517f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceRange Range, 518f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceLocation Loc) { 519f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *BaseType = RefRSStruct->getType().getTypePtr(); 520f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 521f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(!BaseType->isArrayType()); 522f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 523f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::DataType DT = 524f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::GetRSSpecificType(BaseType); 525f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 526f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Structs should show up as unknown primitive types 527f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(DT == RSExportPrimitiveType::DataTypeUnknown); 528f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 529f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines unsigned FieldsToDestroy = CountRSObjectTypesInStruct(BaseType); 530f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 531f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines unsigned StmtCount = 0; 532f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::Stmt **StmtArray = new clang::Stmt*[FieldsToDestroy]; 533f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 534f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // Populate StmtArray by creating a destructor for each RS object field 535f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::RecordDecl *RD = BaseType->getAsStructureType()->getDecl(); 536f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RD = RD->getDefinition(); 537f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines for (clang::RecordDecl::field_iterator FI = RD->field_begin(), 538f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FE = RD->field_end(); 539f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI != FE; 540f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FI++) { 541f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // We just look through all field declarations to see if we find a 542f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // declaration for an RS object type (or an array of one). 543f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool IsArrayType = false; 544f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::FieldDecl *FD = *FI; 545f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *FT = RSExportType::GetTypeOfDecl(FD); 546f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines const clang::Type *OrigType = FT; 547f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines while (FT && FT->isArrayType()) { 548f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FT = FT->getArrayElementTypeNoTypeQual(); 549f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines IsArrayType = true; 550f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 551f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 552f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (RSExportPrimitiveType::IsRSObjectType(FT)) { 553f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair FoundDecl = 554f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair::make(FD, clang::AS_none); 555f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr *RSObjectMember = 556f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr::Create(C, 557f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSStruct, 558f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines false, 559f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines NULL, 560f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Range, 561f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FD, 562f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FoundDecl, 563f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclarationNameInfo(), 564f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines NULL, 565f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines OrigType->getCanonicalTypeInternal()); 566f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 567f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(StmtCount < FieldsToDestroy); 568f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 569f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (IsArrayType) { 570f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearArrayRSObject(C, 571f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 572f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 573f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Range, 574f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 575f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 576f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearSingleRSObject(C, 577f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 578f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 579f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 580f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else if (FT->isStructureType() && CountRSObjectTypesInStruct(FT)) { 581f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // In this case, we have a nested struct. We may not end up filling all 582f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // of the spaces in StmtArray (sub-structs should handle themselves 583f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // with separate compound statements). 584f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair FoundDecl = 585f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclAccessPair::make(FD, clang::AS_none); 586f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr *RSObjectMember = 587f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::MemberExpr::Create(C, 588f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RefRSStruct, 589f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines false, 590f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines NULL, 591f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Range, 592f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FD, 593f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines FoundDecl, 594f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclarationNameInfo(), 595f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines NULL, 596f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines OrigType->getCanonicalTypeInternal()); 597f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 598f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (IsArrayType) { 599f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearArrayRSObject(C, 600f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 601f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 602f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Range, 603f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 604f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 605f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines StmtArray[StmtCount++] = ClearStructRSObject(C, 606f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DC, 607f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSObjectMember, 608f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Range, 609f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Loc); 610f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 611f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 612f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 613f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 614f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(StmtCount > 0); 615f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::CompoundStmt *CS = 616f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines new(C) clang::CompoundStmt(C, StmtArray, StmtCount, Loc, Loc); 617f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 618f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines delete [] StmtArray; 619f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 620f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return CS; 621f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines} 622f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 6234464d825c11349068f2917f9ebee86b721423f3cStephen Hines} // namespace 6244464d825c11349068f2917f9ebee86b721423f3cStephen Hines 625c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hinesvoid RSObjectRefCount::Scope::ReplaceRSObjectAssignment( 626c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::BinaryOperator *AS) { 627c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 628c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType QT = AS->getType(); 629c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 630f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::FunctionDecl *SetObjectFD = RSObjectRefCount::GetRSSetObjectFD( 631f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines QT.getTypePtr()); 6326e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((SetObjectFD != NULL) && 6336e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "rsSetObject doesn't cover all RS object types"); 634c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::ASTContext &C = SetObjectFD->getASTContext(); 635c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 636c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType SetObjectFDType = SetObjectFD->getType(); 637c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType SetObjectFDArgType[2]; 638c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDArgType[0] = SetObjectFD->getParamDecl(0)->getOriginalType(); 639c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDArgType[1] = SetObjectFD->getParamDecl(1)->getOriginalType(); 640c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 641c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::SourceLocation Loc = SetObjectFD->getLocation(); 642c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Expr *RefRSSetObjectFD = 643c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::DeclRefExpr::Create(C, 644c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines NULL, 645c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFD->getQualifierRange(), 646c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFD, 647c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines Loc, 648c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDType); 649c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 650c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Expr *RSSetObjectFP = 651c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::ImplicitCastExpr::Create(C, 652c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines C.getPointerType(SetObjectFDType), 653c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::CK_FunctionToPointerDecay, 654c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RefRSSetObjectFD, 655c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines NULL, 656c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::VK_RValue); 657c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 658c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::Expr *ArgList[2]; 659c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines ArgList[0] = new(C) clang::UnaryOperator(AS->getLHS(), 660c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::UO_AddrOf, 661c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFDArgType[0], 662c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines Loc); 663c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines ArgList[1] = AS->getRHS(); 664c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 665c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::CallExpr *RSSetObjectCall = 666c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines new(C) clang::CallExpr(C, 667c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines RSSetObjectFP, 668c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines ArgList, 669c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 2, 670c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines SetObjectFD->getCallResultType(), 671c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines Loc); 672c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 673e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ReplaceInCompoundStmt(C, mCS, AS, RSSetObjectCall); 674e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 675e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return; 676e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines} 677e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 678e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hinesvoid RSObjectRefCount::Scope::AppendRSObjectInit( 679e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::VarDecl *VD, 680e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclStmt *DS, 681e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataType DT, 682e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *InitExpr) { 6836e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(VD); 684e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 685e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (!InitExpr) { 686e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return; 687e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 688e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 689f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (DT == RSExportPrimitiveType::DataTypeIsStruct) { 690f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines // TODO(srhines): Skip struct initialization right now 691f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return; 692f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 693f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines 694f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::FunctionDecl *SetObjectFD = RSObjectRefCount::GetRSSetObjectFD(DT); 6956e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((SetObjectFD != NULL) && 6966e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines "rsSetObject doesn't cover all RS object types"); 697e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::ASTContext &C = SetObjectFD->getASTContext(); 698e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 699e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::QualType SetObjectFDType = SetObjectFD->getType(); 700e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::QualType SetObjectFDArgType[2]; 701e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDArgType[0] = SetObjectFD->getParamDecl(0)->getOriginalType(); 702e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDArgType[1] = SetObjectFD->getParamDecl(1)->getOriginalType(); 703e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 704e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::SourceLocation Loc = SetObjectFD->getLocation(); 705e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *RefRSSetObjectFD = 706e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr::Create(C, 707e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines NULL, 708e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFD->getQualifierRange(), 709e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFD, 710e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc, 711e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDType); 712e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 713e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *RSSetObjectFP = 714e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::ImplicitCastExpr::Create(C, 715e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines C.getPointerType(SetObjectFDType), 716e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CK_FunctionToPointerDecay, 717e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RefRSSetObjectFD, 718e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines NULL, 719e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::VK_RValue); 720e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 721e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 722e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr *RefRSVar = 723e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::DeclRefExpr::Create(C, 724e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines NULL, 725e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->getQualifierRange(), 726e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD, 727e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc, 728e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines T->getCanonicalTypeInternal()); 729e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 730e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *ArgList[2]; 731e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ArgList[0] = new(C) clang::UnaryOperator(RefRSVar, 732e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::UO_AddrOf, 733e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFDArgType[0], 734e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc); 735e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ArgList[1] = InitExpr; 736e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 737e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::CallExpr *RSSetObjectCall = 738e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines new(C) clang::CallExpr(C, 739e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSSetObjectFP, 740e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ArgList, 741e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 2, 742e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines SetObjectFD->getCallResultType(), 743e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines Loc); 744e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 745e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines AppendAfterStmt(C, mCS, DS, RSSetObjectCall); 746c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 747c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines return; 748c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines} 749c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 7501bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hinesvoid RSObjectRefCount::Scope::InsertLocalVarDestructors() { 751d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hines std::list<clang::Stmt*> RSClearObjectCalls; 7521bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines for (std::list<clang::VarDecl*>::const_iterator I = mRSO.begin(), 7531bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines E = mRSO.end(); 7541bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines I != E; 7551bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines I++) { 756a858cb6f3d9223d65bf73e1230c6324ded4095f6Stephen Hines clang::Stmt *S = ClearRSObject(*I); 757a858cb6f3d9223d65bf73e1230c6324ded4095f6Stephen Hines if (S) { 758a858cb6f3d9223d65bf73e1230c6324ded4095f6Stephen Hines RSClearObjectCalls.push_back(S); 7591bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 7601bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 7611bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines if (RSClearObjectCalls.size() > 0) { 7624464d825c11349068f2917f9ebee86b721423f3cStephen Hines DestructorVisitor DV((*mRSO.begin())->getASTContext(), RSClearObjectCalls); 7634464d825c11349068f2917f9ebee86b721423f3cStephen Hines DV.Visit(mCS); 7641bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines } 7651bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines return; 7661bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 7671bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 768d5f9d6c8b6944dfc30d4fea68479c2fcc250a62cStephen Hinesclang::Stmt *RSObjectRefCount::Scope::ClearRSObject(clang::VarDecl *VD) { 769f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert(VD); 7701bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::ASTContext &C = VD->getASTContext(); 771f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::DeclContext *DC = VD->getDeclContext(); 772f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines clang::SourceRange Range = VD->getQualifierRange(); 7731bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::SourceLocation Loc = VD->getLocation(); 7741bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 77503981a308201b9123512297c8b9562a0f29bdf31Stephen Hines 7761bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines // Reference expr to target RS object variable 7771bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::DeclRefExpr *RefRSVar = 7781bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines clang::DeclRefExpr::Create(C, 7791bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines NULL, 780f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines Range, 7811bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines VD, 7821bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines Loc, 78303981a308201b9123512297c8b9562a0f29bdf31Stephen Hines T->getCanonicalTypeInternal()); 7841bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 785f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (T->isArrayType()) { 786f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return ClearArrayRSObject(C, DC, RefRSVar, Range, Loc); 787f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 7881bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 789f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::DataType DT = 790f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines RSExportPrimitiveType::GetRSSpecificType(T); 7911bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 792f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (DT == RSExportPrimitiveType::DataTypeUnknown || 793f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DT == RSExportPrimitiveType::DataTypeIsStruct) { 794f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return ClearStructRSObject(C, DC, RefRSVar, Range, Loc); 795f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 7961bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 797f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines slangAssert((RSExportPrimitiveType::IsRSObjectType(DT)) && 798f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines "Should be RS object"); 7991bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 800f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines return ClearSingleRSObject(C, RefRSVar, Loc); 8011bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines} 8021bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines 803e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hinesbool RSObjectRefCount::InitializeRSObject(clang::VarDecl *VD, 804e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataType *DT, 805e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr **InitExpr) { 8066e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(VD && DT && InitExpr); 8074b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 8082d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines 8092d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines // Loop through array types to get to base type 8102d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines while (T && T->isArrayType()) { 8112d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines T = T->getArrayElementTypeNoTypeQual(); 8122d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines } 8132d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines 814f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool DataTypeIsStructWithRSObject = false; 815e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines *DT = RSExportPrimitiveType::GetRSSpecificType(T); 8164b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 817e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (*DT == RSExportPrimitiveType::DataTypeUnknown) { 818feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines if (RSExportPrimitiveType::IsStructureTypeWithRSObject(T)) { 819feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines *DT = RSExportPrimitiveType::DataTypeIsStruct; 820f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DataTypeIsStructWithRSObject = true; 821feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } else { 822feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines return false; 823feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines } 8242d095046682d9c372e8c4f102cd1b340ec14bebaStephen Hines } 8254b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 826f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines bool DataTypeIsRSObject = false; 827f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (DataTypeIsStructWithRSObject) { 828f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DataTypeIsRSObject = true; 829f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } else { 830f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines DataTypeIsRSObject = RSExportPrimitiveType::IsRSObjectType(*DT); 831f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines } 832e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines *InitExpr = VD->getInit(); 833e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 834e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (!DataTypeIsRSObject && *InitExpr) { 835e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines // If we already have an initializer for a matrix type, we are done. 836e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return DataTypeIsRSObject; 8374b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 8384b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 839e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *ZeroInitializer = 840e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines CreateZeroInitializerForRSSpecificType(*DT, 841e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->getASTContext(), 842e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->getLocation()); 843e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 844e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (ZeroInitializer) { 845e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines ZeroInitializer->setType(T->getCanonicalTypeInternal()); 846e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines VD->setInit(ZeroInitializer); 847e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 848e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines 849e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines return DataTypeIsRSObject; 8504b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 8514b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 8524b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesclang::Expr *RSObjectRefCount::CreateZeroInitializerForRSSpecificType( 8534b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines RSExportPrimitiveType::DataType DT, 8544b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ASTContext &C, 8554b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines const clang::SourceLocation &Loc) { 8564b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *Res = NULL; 8574b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines switch (DT) { 858feaca06fcb0772e9e972a0d61b17259fc5124d50Stephen Hines case RSExportPrimitiveType::DataTypeIsStruct: 8594b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSElement: 8604b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSType: 8614b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSAllocation: 8624b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSSampler: 8634b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSScript: 8644b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMesh: 8654b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramFragment: 8664b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramVertex: 8674b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramRaster: 8684b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSProgramStore: 8694b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSFont: { 8704b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (ImplicitCastExpr 'nullptr_t' 8714b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (IntegerLiteral 0))) 8724b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APInt Zero(C.getTypeSize(C.IntTy), 0); 8734b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *Int0 = clang::IntegerLiteral::Create(C, Zero, C.IntTy, Loc); 8744b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *CastToNull = 8754b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ImplicitCastExpr::Create(C, 8764b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines C.NullPtrTy, 8774b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::CK_IntegralToPointer, 8784b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Int0, 8794b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines NULL, 8804b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::VK_RValue); 8814b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 882e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Res = new(C) clang::InitListExpr(C, Loc, &CastToNull, 1, Loc); 8834b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines break; 8844b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 8854b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMatrix2x2: 8864b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMatrix3x3: 8874b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeRSMatrix4x4: { 8884b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // RS matrix is not completely an RS object. They hold data by themselves. 8894b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (InitListExpr rs_matrix2x2 8904b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (InitListExpr float[4] 8914b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 8924b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 8934b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0) 8944b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // (FloatingLiteral 0))) 8954b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::QualType FloatTy = C.FloatTy; 8964b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Constructor sets value to 0.0f by default 8974b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APFloat Val(C.getFloatTypeSemantics(FloatTy)); 8984b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::FloatingLiteral *Float0Val = 8994b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::FloatingLiteral::Create(C, 9004b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Val, 9014b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines /* isExact = */true, 9024b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines FloatTy, 9034b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Loc); 9044b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 9054b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines unsigned N = 0; 9064b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (DT == RSExportPrimitiveType::DataTypeRSMatrix2x2) 9074b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 2; 9084b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines else if (DT == RSExportPrimitiveType::DataTypeRSMatrix3x3) 9094b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 3; 9104b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines else if (DT == RSExportPrimitiveType::DataTypeRSMatrix4x4) 9114b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines N = 4; 9124b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 9134b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Directly allocate 16 elements instead of dynamically allocate N*N 9144b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *InitVals[16]; 9154b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (unsigned i = 0; i < sizeof(InitVals) / sizeof(InitVals[0]); i++) 9164b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines InitVals[i] = Float0Val; 9174b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Expr *InitExpr = 918e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines new(C) clang::InitListExpr(C, Loc, InitVals, N * N, Loc); 9194b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines InitExpr->setType(C.getConstantArrayType(FloatTy, 9204b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines llvm::APInt(32, 4), 9214b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::ArrayType::Normal, 9224b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines /* EltTypeQuals = */0)); 9234b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 924e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines Res = new(C) clang::InitListExpr(C, Loc, &InitExpr, 1, Loc); 9254b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines break; 9264b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 9274b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnknown: 9284b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeFloat16: 9294b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeFloat32: 9304b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeFloat64: 9314b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned8: 9324b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned16: 9334b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned32: 9344b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeSigned64: 9354b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned8: 9364b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned16: 9374b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned32: 9384b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned64: 9394b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeBoolean: 9404b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned565: 9414b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned5551: 9424b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeUnsigned4444: 9434b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines case RSExportPrimitiveType::DataTypeMax: { 9446e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Not RS object type!"); 9454b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 9464b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // No default case will enable compiler detecting the missing cases 9474b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 9484b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 9494b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return Res; 9504b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 9514b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 9524b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitDeclStmt(clang::DeclStmt *DS) { 9534b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (clang::DeclStmt::decl_iterator I = DS->decl_begin(), E = DS->decl_end(); 9544b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I != E; 9554b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I++) { 9564b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::Decl *D = *I; 9574b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (D->getKind() == clang::Decl::Var) { 9584b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines clang::VarDecl *VD = static_cast<clang::VarDecl*>(D); 959e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataType DT = 960e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines RSExportPrimitiveType::DataTypeUnknown; 961e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines clang::Expr *InitExpr = NULL; 962e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines if (InitializeRSObject(VD, &DT, &InitExpr)) { 9634b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines getCurrentScope()->addRSObject(VD); 964e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines getCurrentScope()->AppendRSObjectInit(VD, DS, DT, InitExpr); 965e79fb5ec220e20bd04cd6f6059cbc9748181ce21Stephen Hines } 9664b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 9674b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 9684b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 9694b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 9704b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 9714b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitCompoundStmt(clang::CompoundStmt *CS) { 9724b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (!CS->body_empty()) { 9734b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Push a new scope 9744b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Scope *S = new Scope(CS); 9754b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines mScopeStack.push(S); 9764b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 9774b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines VisitStmt(CS); 9784b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 9794b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines // Destroy the scope 9806e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert((getCurrentScope() == S) && "Corrupted scope stack!"); 9811bdd4978caabcdc9489bdcb7f1cd6087340699e8Stephen Hines S->InsertLocalVarDestructors(); 9824b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines mScopeStack.pop(); 9834b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines delete S; 9844b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 9854b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 9864b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 9874b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 9884b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitBinAssign(clang::BinaryOperator *AS) { 989c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines clang::QualType QT = AS->getType(); 990c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 991f2174cfd6a556b51aadf2b8765e50df080e8f18eStephen Hines if (RSExportPrimitiveType::IsRSObjectType(QT.getTypePtr())) { 992c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines getCurrentScope()->ReplaceRSObjectAssignment(AS); 993c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines } 994c202d2d64fe0172bcc3999b515a14d3d88532420Stephen Hines 9954b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 9964b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 9974b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 9984b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hinesvoid RSObjectRefCount::VisitStmt(clang::Stmt *S) { 9994b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end(); 10004b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I != E; 10014b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines I++) { 10024b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines if (clang::Stmt *Child = *I) { 10034b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines Visit(Child); 10044b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 10054b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines } 10064b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines return; 10074b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines} 10084b32ffdfc1ac766f8932e7effbcdf7484e804a8eStephen Hines 1009e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 1010