PageRenderTime 66ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/frameworks/compile/slang/slang_rs_object_ref_count.cpp

https://gitlab.com/brian0218/rk3066_r-box_android4.2.2_sdk
C++ | 1376 lines | 923 code | 179 blank | 274 comment | 118 complexity | 0f1b9d816975c422656f4b60f2d9825c MD5 | raw file
  1. /*
  2. * Copyright 2010, The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "slang_rs_object_ref_count.h"
  17. #include <list>
  18. #include "clang/AST/DeclGroup.h"
  19. #include "clang/AST/Expr.h"
  20. #include "clang/AST/NestedNameSpecifier.h"
  21. #include "clang/AST/OperationKinds.h"
  22. #include "clang/AST/Stmt.h"
  23. #include "clang/AST/StmtVisitor.h"
  24. #include "slang_assert.h"
  25. #include "slang_rs.h"
  26. #include "slang_rs_ast_replace.h"
  27. #include "slang_rs_export_type.h"
  28. namespace slang {
  29. clang::FunctionDecl *RSObjectRefCount::
  30. RSSetObjectFD[RSExportPrimitiveType::LastRSObjectType -
  31. RSExportPrimitiveType::FirstRSObjectType + 1];
  32. clang::FunctionDecl *RSObjectRefCount::
  33. RSClearObjectFD[RSExportPrimitiveType::LastRSObjectType -
  34. RSExportPrimitiveType::FirstRSObjectType + 1];
  35. void RSObjectRefCount::GetRSRefCountingFunctions(clang::ASTContext &C) {
  36. for (unsigned i = 0;
  37. i < (sizeof(RSClearObjectFD) / sizeof(clang::FunctionDecl*));
  38. i++) {
  39. RSSetObjectFD[i] = NULL;
  40. RSClearObjectFD[i] = NULL;
  41. }
  42. clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
  43. for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(),
  44. E = TUDecl->decls_end(); I != E; I++) {
  45. if ((I->getKind() >= clang::Decl::firstFunction) &&
  46. (I->getKind() <= clang::Decl::lastFunction)) {
  47. clang::FunctionDecl *FD = static_cast<clang::FunctionDecl*>(*I);
  48. // points to RSSetObjectFD or RSClearObjectFD
  49. clang::FunctionDecl **RSObjectFD;
  50. if (FD->getName() == "rsSetObject") {
  51. slangAssert((FD->getNumParams() == 2) &&
  52. "Invalid rsSetObject function prototype (# params)");
  53. RSObjectFD = RSSetObjectFD;
  54. } else if (FD->getName() == "rsClearObject") {
  55. slangAssert((FD->getNumParams() == 1) &&
  56. "Invalid rsClearObject function prototype (# params)");
  57. RSObjectFD = RSClearObjectFD;
  58. } else {
  59. continue;
  60. }
  61. const clang::ParmVarDecl *PVD = FD->getParamDecl(0);
  62. clang::QualType PVT = PVD->getOriginalType();
  63. // The first parameter must be a pointer like rs_allocation*
  64. slangAssert(PVT->isPointerType() &&
  65. "Invalid rs{Set,Clear}Object function prototype (pointer param)");
  66. // The rs object type passed to the FD
  67. clang::QualType RST = PVT->getPointeeType();
  68. RSExportPrimitiveType::DataType DT =
  69. RSExportPrimitiveType::GetRSSpecificType(RST.getTypePtr());
  70. slangAssert(RSExportPrimitiveType::IsRSObjectType(DT)
  71. && "must be RS object type");
  72. RSObjectFD[(DT - RSExportPrimitiveType::FirstRSObjectType)] = FD;
  73. }
  74. }
  75. }
  76. namespace {
  77. // This function constructs a new CompoundStmt from the input StmtList.
  78. static clang::CompoundStmt* BuildCompoundStmt(clang::ASTContext &C,
  79. std::list<clang::Stmt*> &StmtList, clang::SourceLocation Loc) {
  80. unsigned NewStmtCount = StmtList.size();
  81. unsigned CompoundStmtCount = 0;
  82. clang::Stmt **CompoundStmtList;
  83. CompoundStmtList = new clang::Stmt*[NewStmtCount];
  84. std::list<clang::Stmt*>::const_iterator I = StmtList.begin();
  85. std::list<clang::Stmt*>::const_iterator E = StmtList.end();
  86. for ( ; I != E; I++) {
  87. CompoundStmtList[CompoundStmtCount++] = *I;
  88. }
  89. slangAssert(CompoundStmtCount == NewStmtCount);
  90. clang::CompoundStmt *CS = new(C) clang::CompoundStmt(C,
  91. CompoundStmtList,
  92. CompoundStmtCount,
  93. Loc,
  94. Loc);
  95. delete [] CompoundStmtList;
  96. return CS;
  97. }
  98. static void AppendAfterStmt(clang::ASTContext &C,
  99. clang::CompoundStmt *CS,
  100. clang::Stmt *S,
  101. std::list<clang::Stmt*> &StmtList) {
  102. slangAssert(CS);
  103. clang::CompoundStmt::body_iterator bI = CS->body_begin();
  104. clang::CompoundStmt::body_iterator bE = CS->body_end();
  105. clang::Stmt **UpdatedStmtList =
  106. new clang::Stmt*[CS->size() + StmtList.size()];
  107. unsigned UpdatedStmtCount = 0;
  108. unsigned Once = 0;
  109. for ( ; bI != bE; bI++) {
  110. if (!S && ((*bI)->getStmtClass() == clang::Stmt::ReturnStmtClass)) {
  111. // If we come across a return here, we don't have anything we can
  112. // reasonably replace. We should have already inserted our destructor
  113. // code in the proper spot, so we just clean up and return.
  114. delete [] UpdatedStmtList;
  115. return;
  116. }
  117. UpdatedStmtList[UpdatedStmtCount++] = *bI;
  118. if ((*bI == S) && !Once) {
  119. Once++;
  120. std::list<clang::Stmt*>::const_iterator I = StmtList.begin();
  121. std::list<clang::Stmt*>::const_iterator E = StmtList.end();
  122. for ( ; I != E; I++) {
  123. UpdatedStmtList[UpdatedStmtCount++] = *I;
  124. }
  125. }
  126. }
  127. slangAssert(Once <= 1);
  128. // When S is NULL, we are appending to the end of the CompoundStmt.
  129. if (!S) {
  130. slangAssert(Once == 0);
  131. std::list<clang::Stmt*>::const_iterator I = StmtList.begin();
  132. std::list<clang::Stmt*>::const_iterator E = StmtList.end();
  133. for ( ; I != E; I++) {
  134. UpdatedStmtList[UpdatedStmtCount++] = *I;
  135. }
  136. }
  137. CS->setStmts(C, UpdatedStmtList, UpdatedStmtCount);
  138. delete [] UpdatedStmtList;
  139. return;
  140. }
  141. // This class visits a compound statement and inserts DtorStmt
  142. // in proper locations. This includes inserting it before any
  143. // return statement in any sub-block, at the end of the logical enclosing
  144. // scope (compound statement), and/or before any break/continue statement that
  145. // would resume outside the declared scope. We will not handle the case for
  146. // goto statements that leave a local scope.
  147. //
  148. // To accomplish these goals, it collects a list of sub-Stmt's that
  149. // correspond to scope exit points. It then uses an RSASTReplace visitor to
  150. // transform the AST, inserting appropriate destructors before each of those
  151. // sub-Stmt's (and also before the exit of the outermost containing Stmt for
  152. // the scope).
  153. class DestructorVisitor : public clang::StmtVisitor<DestructorVisitor> {
  154. private:
  155. clang::ASTContext &mCtx;
  156. // The loop depth of the currently visited node.
  157. int mLoopDepth;
  158. // The switch statement depth of the currently visited node.
  159. // Note that this is tracked separately from the loop depth because
  160. // SwitchStmt-contained ContinueStmt's should have destructors for the
  161. // corresponding loop scope.
  162. int mSwitchDepth;
  163. // The outermost statement block that we are currently visiting.
  164. // This should always be a CompoundStmt.
  165. clang::Stmt *mOuterStmt;
  166. // The destructor to execute for this scope/variable.
  167. clang::Stmt* mDtorStmt;
  168. // The stack of statements which should be replaced by a compound statement
  169. // containing the new destructor call followed by the original Stmt.
  170. std::stack<clang::Stmt*> mReplaceStmtStack;
  171. // The source location for the variable declaration that we are trying to
  172. // insert destructors for. Note that InsertDestructors() will not generate
  173. // destructor calls for source locations that occur lexically before this
  174. // location.
  175. clang::SourceLocation mVarLoc;
  176. public:
  177. DestructorVisitor(clang::ASTContext &C,
  178. clang::Stmt* OuterStmt,
  179. clang::Stmt* DtorStmt,
  180. clang::SourceLocation VarLoc);
  181. // This code walks the collected list of Stmts to replace and actually does
  182. // the replacement. It also finishes up by appending the destructor to the
  183. // current outermost CompoundStmt.
  184. void InsertDestructors() {
  185. clang::Stmt *S = NULL;
  186. clang::SourceManager &SM = mCtx.getSourceManager();
  187. std::list<clang::Stmt *> StmtList;
  188. StmtList.push_back(mDtorStmt);
  189. while (!mReplaceStmtStack.empty()) {
  190. S = mReplaceStmtStack.top();
  191. mReplaceStmtStack.pop();
  192. // Skip all source locations that occur before the variable's
  193. // declaration, since it won't have been initialized yet.
  194. if (SM.isBeforeInTranslationUnit(S->getLocStart(), mVarLoc)) {
  195. continue;
  196. }
  197. StmtList.push_back(S);
  198. clang::CompoundStmt *CS =
  199. BuildCompoundStmt(mCtx, StmtList, S->getLocEnd());
  200. StmtList.pop_back();
  201. RSASTReplace R(mCtx);
  202. R.ReplaceStmt(mOuterStmt, S, CS);
  203. }
  204. clang::CompoundStmt *CS =
  205. llvm::dyn_cast<clang::CompoundStmt>(mOuterStmt);
  206. slangAssert(CS);
  207. AppendAfterStmt(mCtx, CS, NULL, StmtList);
  208. }
  209. void VisitStmt(clang::Stmt *S);
  210. void VisitCompoundStmt(clang::CompoundStmt *CS);
  211. void VisitBreakStmt(clang::BreakStmt *BS);
  212. void VisitCaseStmt(clang::CaseStmt *CS);
  213. void VisitContinueStmt(clang::ContinueStmt *CS);
  214. void VisitDefaultStmt(clang::DefaultStmt *DS);
  215. void VisitDoStmt(clang::DoStmt *DS);
  216. void VisitForStmt(clang::ForStmt *FS);
  217. void VisitIfStmt(clang::IfStmt *IS);
  218. void VisitReturnStmt(clang::ReturnStmt *RS);
  219. void VisitSwitchCase(clang::SwitchCase *SC);
  220. void VisitSwitchStmt(clang::SwitchStmt *SS);
  221. void VisitWhileStmt(clang::WhileStmt *WS);
  222. };
  223. DestructorVisitor::DestructorVisitor(clang::ASTContext &C,
  224. clang::Stmt *OuterStmt,
  225. clang::Stmt *DtorStmt,
  226. clang::SourceLocation VarLoc)
  227. : mCtx(C),
  228. mLoopDepth(0),
  229. mSwitchDepth(0),
  230. mOuterStmt(OuterStmt),
  231. mDtorStmt(DtorStmt),
  232. mVarLoc(VarLoc) {
  233. return;
  234. }
  235. void DestructorVisitor::VisitStmt(clang::Stmt *S) {
  236. for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end();
  237. I != E;
  238. I++) {
  239. if (clang::Stmt *Child = *I) {
  240. Visit(Child);
  241. }
  242. }
  243. return;
  244. }
  245. void DestructorVisitor::VisitCompoundStmt(clang::CompoundStmt *CS) {
  246. VisitStmt(CS);
  247. return;
  248. }
  249. void DestructorVisitor::VisitBreakStmt(clang::BreakStmt *BS) {
  250. VisitStmt(BS);
  251. if ((mLoopDepth == 0) && (mSwitchDepth == 0)) {
  252. mReplaceStmtStack.push(BS);
  253. }
  254. return;
  255. }
  256. void DestructorVisitor::VisitCaseStmt(clang::CaseStmt *CS) {
  257. VisitStmt(CS);
  258. return;
  259. }
  260. void DestructorVisitor::VisitContinueStmt(clang::ContinueStmt *CS) {
  261. VisitStmt(CS);
  262. if (mLoopDepth == 0) {
  263. // Switch statements can have nested continues.
  264. mReplaceStmtStack.push(CS);
  265. }
  266. return;
  267. }
  268. void DestructorVisitor::VisitDefaultStmt(clang::DefaultStmt *DS) {
  269. VisitStmt(DS);
  270. return;
  271. }
  272. void DestructorVisitor::VisitDoStmt(clang::DoStmt *DS) {
  273. mLoopDepth++;
  274. VisitStmt(DS);
  275. mLoopDepth--;
  276. return;
  277. }
  278. void DestructorVisitor::VisitForStmt(clang::ForStmt *FS) {
  279. mLoopDepth++;
  280. VisitStmt(FS);
  281. mLoopDepth--;
  282. return;
  283. }
  284. void DestructorVisitor::VisitIfStmt(clang::IfStmt *IS) {
  285. VisitStmt(IS);
  286. return;
  287. }
  288. void DestructorVisitor::VisitReturnStmt(clang::ReturnStmt *RS) {
  289. mReplaceStmtStack.push(RS);
  290. return;
  291. }
  292. void DestructorVisitor::VisitSwitchCase(clang::SwitchCase *SC) {
  293. slangAssert(false && "Both case and default have specialized handlers");
  294. VisitStmt(SC);
  295. return;
  296. }
  297. void DestructorVisitor::VisitSwitchStmt(clang::SwitchStmt *SS) {
  298. mSwitchDepth++;
  299. VisitStmt(SS);
  300. mSwitchDepth--;
  301. return;
  302. }
  303. void DestructorVisitor::VisitWhileStmt(clang::WhileStmt *WS) {
  304. mLoopDepth++;
  305. VisitStmt(WS);
  306. mLoopDepth--;
  307. return;
  308. }
  309. clang::Expr *ClearSingleRSObject(clang::ASTContext &C,
  310. clang::Expr *RefRSVar,
  311. clang::SourceLocation Loc) {
  312. slangAssert(RefRSVar);
  313. const clang::Type *T = RefRSVar->getType().getTypePtr();
  314. slangAssert(!T->isArrayType() &&
  315. "Should not be destroying arrays with this function");
  316. clang::FunctionDecl *ClearObjectFD = RSObjectRefCount::GetRSClearObjectFD(T);
  317. slangAssert((ClearObjectFD != NULL) &&
  318. "rsClearObject doesn't cover all RS object types");
  319. clang::QualType ClearObjectFDType = ClearObjectFD->getType();
  320. clang::QualType ClearObjectFDArgType =
  321. ClearObjectFD->getParamDecl(0)->getOriginalType();
  322. // Example destructor for "rs_font localFont;"
  323. //
  324. // (CallExpr 'void'
  325. // (ImplicitCastExpr 'void (*)(rs_font *)' <FunctionToPointerDecay>
  326. // (DeclRefExpr 'void (rs_font *)' FunctionDecl='rsClearObject'))
  327. // (UnaryOperator 'rs_font *' prefix '&'
  328. // (DeclRefExpr 'rs_font':'rs_font' Var='localFont')))
  329. // Get address of targeted RS object
  330. clang::Expr *AddrRefRSVar =
  331. new(C) clang::UnaryOperator(RefRSVar,
  332. clang::UO_AddrOf,
  333. ClearObjectFDArgType,
  334. clang::VK_RValue,
  335. clang::OK_Ordinary,
  336. Loc);
  337. clang::Expr *RefRSClearObjectFD =
  338. clang::DeclRefExpr::Create(C,
  339. clang::NestedNameSpecifierLoc(),
  340. clang::SourceLocation(),
  341. ClearObjectFD,
  342. false,
  343. ClearObjectFD->getLocation(),
  344. ClearObjectFDType,
  345. clang::VK_RValue,
  346. NULL);
  347. clang::Expr *RSClearObjectFP =
  348. clang::ImplicitCastExpr::Create(C,
  349. C.getPointerType(ClearObjectFDType),
  350. clang::CK_FunctionToPointerDecay,
  351. RefRSClearObjectFD,
  352. NULL,
  353. clang::VK_RValue);
  354. llvm::SmallVector<clang::Expr*, 1> ArgList;
  355. ArgList.push_back(AddrRefRSVar);
  356. clang::CallExpr *RSClearObjectCall =
  357. new(C) clang::CallExpr(C,
  358. RSClearObjectFP,
  359. ArgList,
  360. ClearObjectFD->getCallResultType(),
  361. clang::VK_RValue,
  362. Loc);
  363. return RSClearObjectCall;
  364. }
  365. static int ArrayDim(const clang::Type *T) {
  366. if (!T || !T->isArrayType()) {
  367. return 0;
  368. }
  369. const clang::ConstantArrayType *CAT =
  370. static_cast<const clang::ConstantArrayType *>(T);
  371. return static_cast<int>(CAT->getSize().getSExtValue());
  372. }
  373. static clang::Stmt *ClearStructRSObject(
  374. clang::ASTContext &C,
  375. clang::DeclContext *DC,
  376. clang::Expr *RefRSStruct,
  377. clang::SourceLocation StartLoc,
  378. clang::SourceLocation Loc);
  379. static clang::Stmt *ClearArrayRSObject(
  380. clang::ASTContext &C,
  381. clang::DeclContext *DC,
  382. clang::Expr *RefRSArr,
  383. clang::SourceLocation StartLoc,
  384. clang::SourceLocation Loc) {
  385. const clang::Type *BaseType = RefRSArr->getType().getTypePtr();
  386. slangAssert(BaseType->isArrayType());
  387. int NumArrayElements = ArrayDim(BaseType);
  388. // Actually extract out the base RS object type for use later
  389. BaseType = BaseType->getArrayElementTypeNoTypeQual();
  390. clang::Stmt *StmtArray[2] = {NULL};
  391. int StmtCtr = 0;
  392. if (NumArrayElements <= 0) {
  393. return NULL;
  394. }
  395. // Example destructor loop for "rs_font fontArr[10];"
  396. //
  397. // (CompoundStmt
  398. // (DeclStmt "int rsIntIter")
  399. // (ForStmt
  400. // (BinaryOperator 'int' '='
  401. // (DeclRefExpr 'int' Var='rsIntIter')
  402. // (IntegerLiteral 'int' 0))
  403. // (BinaryOperator 'int' '<'
  404. // (DeclRefExpr 'int' Var='rsIntIter')
  405. // (IntegerLiteral 'int' 10)
  406. // NULL << CondVar >>
  407. // (UnaryOperator 'int' postfix '++'
  408. // (DeclRefExpr 'int' Var='rsIntIter'))
  409. // (CallExpr 'void'
  410. // (ImplicitCastExpr 'void (*)(rs_font *)' <FunctionToPointerDecay>
  411. // (DeclRefExpr 'void (rs_font *)' FunctionDecl='rsClearObject'))
  412. // (UnaryOperator 'rs_font *' prefix '&'
  413. // (ArraySubscriptExpr 'rs_font':'rs_font'
  414. // (ImplicitCastExpr 'rs_font *' <ArrayToPointerDecay>
  415. // (DeclRefExpr 'rs_font [10]' Var='fontArr'))
  416. // (DeclRefExpr 'int' Var='rsIntIter')))))))
  417. // Create helper variable for iterating through elements
  418. clang::IdentifierInfo& II = C.Idents.get("rsIntIter");
  419. clang::VarDecl *IIVD =
  420. clang::VarDecl::Create(C,
  421. DC,
  422. StartLoc,
  423. Loc,
  424. &II,
  425. C.IntTy,
  426. C.getTrivialTypeSourceInfo(C.IntTy),
  427. clang::SC_None,
  428. clang::SC_None);
  429. clang::Decl *IID = (clang::Decl *)IIVD;
  430. clang::DeclGroupRef DGR = clang::DeclGroupRef::Create(C, &IID, 1);
  431. StmtArray[StmtCtr++] = new(C) clang::DeclStmt(DGR, Loc, Loc);
  432. // Form the actual destructor loop
  433. // for (Init; Cond; Inc)
  434. // RSClearObjectCall;
  435. // Init -> "rsIntIter = 0"
  436. clang::DeclRefExpr *RefrsIntIter =
  437. clang::DeclRefExpr::Create(C,
  438. clang::NestedNameSpecifierLoc(),
  439. clang::SourceLocation(),
  440. IIVD,
  441. false,
  442. Loc,
  443. C.IntTy,
  444. clang::VK_RValue,
  445. NULL);
  446. clang::Expr *Int0 = clang::IntegerLiteral::Create(C,
  447. llvm::APInt(C.getTypeSize(C.IntTy), 0), C.IntTy, Loc);
  448. clang::BinaryOperator *Init =
  449. new(C) clang::BinaryOperator(RefrsIntIter,
  450. Int0,
  451. clang::BO_Assign,
  452. C.IntTy,
  453. clang::VK_RValue,
  454. clang::OK_Ordinary,
  455. Loc);
  456. // Cond -> "rsIntIter < NumArrayElements"
  457. clang::Expr *NumArrayElementsExpr = clang::IntegerLiteral::Create(C,
  458. llvm::APInt(C.getTypeSize(C.IntTy), NumArrayElements), C.IntTy, Loc);
  459. clang::BinaryOperator *Cond =
  460. new(C) clang::BinaryOperator(RefrsIntIter,
  461. NumArrayElementsExpr,
  462. clang::BO_LT,
  463. C.IntTy,
  464. clang::VK_RValue,
  465. clang::OK_Ordinary,
  466. Loc);
  467. // Inc -> "rsIntIter++"
  468. clang::UnaryOperator *Inc =
  469. new(C) clang::UnaryOperator(RefrsIntIter,
  470. clang::UO_PostInc,
  471. C.IntTy,
  472. clang::VK_RValue,
  473. clang::OK_Ordinary,
  474. Loc);
  475. // Body -> "rsClearObject(&VD[rsIntIter]);"
  476. // Destructor loop operates on individual array elements
  477. clang::Expr *RefRSArrPtr =
  478. clang::ImplicitCastExpr::Create(C,
  479. C.getPointerType(BaseType->getCanonicalTypeInternal()),
  480. clang::CK_ArrayToPointerDecay,
  481. RefRSArr,
  482. NULL,
  483. clang::VK_RValue);
  484. clang::Expr *RefRSArrPtrSubscript =
  485. new(C) clang::ArraySubscriptExpr(RefRSArrPtr,
  486. RefrsIntIter,
  487. BaseType->getCanonicalTypeInternal(),
  488. clang::VK_RValue,
  489. clang::OK_Ordinary,
  490. Loc);
  491. RSExportPrimitiveType::DataType DT =
  492. RSExportPrimitiveType::GetRSSpecificType(BaseType);
  493. clang::Stmt *RSClearObjectCall = NULL;
  494. if (BaseType->isArrayType()) {
  495. RSClearObjectCall =
  496. ClearArrayRSObject(C, DC, RefRSArrPtrSubscript, StartLoc, Loc);
  497. } else if (DT == RSExportPrimitiveType::DataTypeUnknown) {
  498. RSClearObjectCall =
  499. ClearStructRSObject(C, DC, RefRSArrPtrSubscript, StartLoc, Loc);
  500. } else {
  501. RSClearObjectCall = ClearSingleRSObject(C, RefRSArrPtrSubscript, Loc);
  502. }
  503. clang::ForStmt *DestructorLoop =
  504. new(C) clang::ForStmt(C,
  505. Init,
  506. Cond,
  507. NULL, // no condVar
  508. Inc,
  509. RSClearObjectCall,
  510. Loc,
  511. Loc,
  512. Loc);
  513. StmtArray[StmtCtr++] = DestructorLoop;
  514. slangAssert(StmtCtr == 2);
  515. clang::CompoundStmt *CS =
  516. new(C) clang::CompoundStmt(C, StmtArray, StmtCtr, Loc, Loc);
  517. return CS;
  518. }
  519. static unsigned CountRSObjectTypes(clang::ASTContext &C,
  520. const clang::Type *T,
  521. clang::SourceLocation Loc) {
  522. slangAssert(T);
  523. unsigned RSObjectCount = 0;
  524. if (T->isArrayType()) {
  525. return CountRSObjectTypes(C, T->getArrayElementTypeNoTypeQual(), Loc);
  526. }
  527. RSExportPrimitiveType::DataType DT =
  528. RSExportPrimitiveType::GetRSSpecificType(T);
  529. if (DT != RSExportPrimitiveType::DataTypeUnknown) {
  530. return (RSExportPrimitiveType::IsRSObjectType(DT) ? 1 : 0);
  531. }
  532. if (T->isUnionType()) {
  533. clang::RecordDecl *RD = T->getAsUnionType()->getDecl();
  534. RD = RD->getDefinition();
  535. for (clang::RecordDecl::field_iterator FI = RD->field_begin(),
  536. FE = RD->field_end();
  537. FI != FE;
  538. FI++) {
  539. const clang::FieldDecl *FD = *FI;
  540. const clang::Type *FT = RSExportType::GetTypeOfDecl(FD);
  541. if (CountRSObjectTypes(C, FT, Loc)) {
  542. slangAssert(false && "can't have unions with RS object types!");
  543. return 0;
  544. }
  545. }
  546. }
  547. if (!T->isStructureType()) {
  548. return 0;
  549. }
  550. clang::RecordDecl *RD = T->getAsStructureType()->getDecl();
  551. RD = RD->getDefinition();
  552. for (clang::RecordDecl::field_iterator FI = RD->field_begin(),
  553. FE = RD->field_end();
  554. FI != FE;
  555. FI++) {
  556. const clang::FieldDecl *FD = *FI;
  557. const clang::Type *FT = RSExportType::GetTypeOfDecl(FD);
  558. if (CountRSObjectTypes(C, FT, Loc)) {
  559. // Sub-structs should only count once (as should arrays, etc.)
  560. RSObjectCount++;
  561. }
  562. }
  563. return RSObjectCount;
  564. }
  565. static clang::Stmt *ClearStructRSObject(
  566. clang::ASTContext &C,
  567. clang::DeclContext *DC,
  568. clang::Expr *RefRSStruct,
  569. clang::SourceLocation StartLoc,
  570. clang::SourceLocation Loc) {
  571. const clang::Type *BaseType = RefRSStruct->getType().getTypePtr();
  572. slangAssert(!BaseType->isArrayType());
  573. // Structs should show up as unknown primitive types
  574. slangAssert(RSExportPrimitiveType::GetRSSpecificType(BaseType) ==
  575. RSExportPrimitiveType::DataTypeUnknown);
  576. unsigned FieldsToDestroy = CountRSObjectTypes(C, BaseType, Loc);
  577. unsigned StmtCount = 0;
  578. clang::Stmt **StmtArray = new clang::Stmt*[FieldsToDestroy];
  579. for (unsigned i = 0; i < FieldsToDestroy; i++) {
  580. StmtArray[i] = NULL;
  581. }
  582. // Populate StmtArray by creating a destructor for each RS object field
  583. clang::RecordDecl *RD = BaseType->getAsStructureType()->getDecl();
  584. RD = RD->getDefinition();
  585. for (clang::RecordDecl::field_iterator FI = RD->field_begin(),
  586. FE = RD->field_end();
  587. FI != FE;
  588. FI++) {
  589. // We just look through all field declarations to see if we find a
  590. // declaration for an RS object type (or an array of one).
  591. bool IsArrayType = false;
  592. clang::FieldDecl *FD = *FI;
  593. const clang::Type *FT = RSExportType::GetTypeOfDecl(FD);
  594. const clang::Type *OrigType = FT;
  595. while (FT && FT->isArrayType()) {
  596. FT = FT->getArrayElementTypeNoTypeQual();
  597. IsArrayType = true;
  598. }
  599. if (RSExportPrimitiveType::IsRSObjectType(FT)) {
  600. clang::DeclAccessPair FoundDecl =
  601. clang::DeclAccessPair::make(FD, clang::AS_none);
  602. clang::MemberExpr *RSObjectMember =
  603. clang::MemberExpr::Create(C,
  604. RefRSStruct,
  605. false,
  606. clang::NestedNameSpecifierLoc(),
  607. clang::SourceLocation(),
  608. FD,
  609. FoundDecl,
  610. clang::DeclarationNameInfo(),
  611. NULL,
  612. OrigType->getCanonicalTypeInternal(),
  613. clang::VK_RValue,
  614. clang::OK_Ordinary);
  615. slangAssert(StmtCount < FieldsToDestroy);
  616. if (IsArrayType) {
  617. StmtArray[StmtCount++] = ClearArrayRSObject(C,
  618. DC,
  619. RSObjectMember,
  620. StartLoc,
  621. Loc);
  622. } else {
  623. StmtArray[StmtCount++] = ClearSingleRSObject(C,
  624. RSObjectMember,
  625. Loc);
  626. }
  627. } else if (FT->isStructureType() && CountRSObjectTypes(C, FT, Loc)) {
  628. // In this case, we have a nested struct. We may not end up filling all
  629. // of the spaces in StmtArray (sub-structs should handle themselves
  630. // with separate compound statements).
  631. clang::DeclAccessPair FoundDecl =
  632. clang::DeclAccessPair::make(FD, clang::AS_none);
  633. clang::MemberExpr *RSObjectMember =
  634. clang::MemberExpr::Create(C,
  635. RefRSStruct,
  636. false,
  637. clang::NestedNameSpecifierLoc(),
  638. clang::SourceLocation(),
  639. FD,
  640. FoundDecl,
  641. clang::DeclarationNameInfo(),
  642. NULL,
  643. OrigType->getCanonicalTypeInternal(),
  644. clang::VK_RValue,
  645. clang::OK_Ordinary);
  646. if (IsArrayType) {
  647. StmtArray[StmtCount++] = ClearArrayRSObject(C,
  648. DC,
  649. RSObjectMember,
  650. StartLoc,
  651. Loc);
  652. } else {
  653. StmtArray[StmtCount++] = ClearStructRSObject(C,
  654. DC,
  655. RSObjectMember,
  656. StartLoc,
  657. Loc);
  658. }
  659. }
  660. }
  661. slangAssert(StmtCount > 0);
  662. clang::CompoundStmt *CS =
  663. new(C) clang::CompoundStmt(C, StmtArray, StmtCount, Loc, Loc);
  664. delete [] StmtArray;
  665. return CS;
  666. }
  667. static clang::Stmt *CreateSingleRSSetObject(clang::ASTContext &C,
  668. clang::Expr *DstExpr,
  669. clang::Expr *SrcExpr,
  670. clang::SourceLocation StartLoc,
  671. clang::SourceLocation Loc) {
  672. const clang::Type *T = DstExpr->getType().getTypePtr();
  673. clang::FunctionDecl *SetObjectFD = RSObjectRefCount::GetRSSetObjectFD(T);
  674. slangAssert((SetObjectFD != NULL) &&
  675. "rsSetObject doesn't cover all RS object types");
  676. clang::QualType SetObjectFDType = SetObjectFD->getType();
  677. clang::QualType SetObjectFDArgType[2];
  678. SetObjectFDArgType[0] = SetObjectFD->getParamDecl(0)->getOriginalType();
  679. SetObjectFDArgType[1] = SetObjectFD->getParamDecl(1)->getOriginalType();
  680. clang::Expr *RefRSSetObjectFD =
  681. clang::DeclRefExpr::Create(C,
  682. clang::NestedNameSpecifierLoc(),
  683. clang::SourceLocation(),
  684. SetObjectFD,
  685. false,
  686. Loc,
  687. SetObjectFDType,
  688. clang::VK_RValue,
  689. NULL);
  690. clang::Expr *RSSetObjectFP =
  691. clang::ImplicitCastExpr::Create(C,
  692. C.getPointerType(SetObjectFDType),
  693. clang::CK_FunctionToPointerDecay,
  694. RefRSSetObjectFD,
  695. NULL,
  696. clang::VK_RValue);
  697. llvm::SmallVector<clang::Expr*, 2> ArgList;
  698. ArgList.push_back(new(C) clang::UnaryOperator(DstExpr,
  699. clang::UO_AddrOf,
  700. SetObjectFDArgType[0],
  701. clang::VK_RValue,
  702. clang::OK_Ordinary,
  703. Loc));
  704. ArgList.push_back(SrcExpr);
  705. clang::CallExpr *RSSetObjectCall =
  706. new(C) clang::CallExpr(C,
  707. RSSetObjectFP,
  708. ArgList,
  709. SetObjectFD->getCallResultType(),
  710. clang::VK_RValue,
  711. Loc);
  712. return RSSetObjectCall;
  713. }
  714. static clang::Stmt *CreateStructRSSetObject(clang::ASTContext &C,
  715. clang::Expr *LHS,
  716. clang::Expr *RHS,
  717. clang::SourceLocation StartLoc,
  718. clang::SourceLocation Loc);
  719. /*static clang::Stmt *CreateArrayRSSetObject(clang::ASTContext &C,
  720. clang::Expr *DstArr,
  721. clang::Expr *SrcArr,
  722. clang::SourceLocation StartLoc,
  723. clang::SourceLocation Loc) {
  724. clang::DeclContext *DC = NULL;
  725. const clang::Type *BaseType = DstArr->getType().getTypePtr();
  726. slangAssert(BaseType->isArrayType());
  727. int NumArrayElements = ArrayDim(BaseType);
  728. // Actually extract out the base RS object type for use later
  729. BaseType = BaseType->getArrayElementTypeNoTypeQual();
  730. clang::Stmt *StmtArray[2] = {NULL};
  731. int StmtCtr = 0;
  732. if (NumArrayElements <= 0) {
  733. return NULL;
  734. }
  735. // Create helper variable for iterating through elements
  736. clang::IdentifierInfo& II = C.Idents.get("rsIntIter");
  737. clang::VarDecl *IIVD =
  738. clang::VarDecl::Create(C,
  739. DC,
  740. StartLoc,
  741. Loc,
  742. &II,
  743. C.IntTy,
  744. C.getTrivialTypeSourceInfo(C.IntTy),
  745. clang::SC_None,
  746. clang::SC_None);
  747. clang::Decl *IID = (clang::Decl *)IIVD;
  748. clang::DeclGroupRef DGR = clang::DeclGroupRef::Create(C, &IID, 1);
  749. StmtArray[StmtCtr++] = new(C) clang::DeclStmt(DGR, Loc, Loc);
  750. // Form the actual loop
  751. // for (Init; Cond; Inc)
  752. // RSSetObjectCall;
  753. // Init -> "rsIntIter = 0"
  754. clang::DeclRefExpr *RefrsIntIter =
  755. clang::DeclRefExpr::Create(C,
  756. clang::NestedNameSpecifierLoc(),
  757. IIVD,
  758. Loc,
  759. C.IntTy,
  760. clang::VK_RValue,
  761. NULL);
  762. clang::Expr *Int0 = clang::IntegerLiteral::Create(C,
  763. llvm::APInt(C.getTypeSize(C.IntTy), 0), C.IntTy, Loc);
  764. clang::BinaryOperator *Init =
  765. new(C) clang::BinaryOperator(RefrsIntIter,
  766. Int0,
  767. clang::BO_Assign,
  768. C.IntTy,
  769. clang::VK_RValue,
  770. clang::OK_Ordinary,
  771. Loc);
  772. // Cond -> "rsIntIter < NumArrayElements"
  773. clang::Expr *NumArrayElementsExpr = clang::IntegerLiteral::Create(C,
  774. llvm::APInt(C.getTypeSize(C.IntTy), NumArrayElements), C.IntTy, Loc);
  775. clang::BinaryOperator *Cond =
  776. new(C) clang::BinaryOperator(RefrsIntIter,
  777. NumArrayElementsExpr,
  778. clang::BO_LT,
  779. C.IntTy,
  780. clang::VK_RValue,
  781. clang::OK_Ordinary,
  782. Loc);
  783. // Inc -> "rsIntIter++"
  784. clang::UnaryOperator *Inc =
  785. new(C) clang::UnaryOperator(RefrsIntIter,
  786. clang::UO_PostInc,
  787. C.IntTy,
  788. clang::VK_RValue,
  789. clang::OK_Ordinary,
  790. Loc);
  791. // Body -> "rsSetObject(&Dst[rsIntIter], Src[rsIntIter]);"
  792. // Loop operates on individual array elements
  793. clang::Expr *DstArrPtr =
  794. clang::ImplicitCastExpr::Create(C,
  795. C.getPointerType(BaseType->getCanonicalTypeInternal()),
  796. clang::CK_ArrayToPointerDecay,
  797. DstArr,
  798. NULL,
  799. clang::VK_RValue);
  800. clang::Expr *DstArrPtrSubscript =
  801. new(C) clang::ArraySubscriptExpr(DstArrPtr,
  802. RefrsIntIter,
  803. BaseType->getCanonicalTypeInternal(),
  804. clang::VK_RValue,
  805. clang::OK_Ordinary,
  806. Loc);
  807. clang::Expr *SrcArrPtr =
  808. clang::ImplicitCastExpr::Create(C,
  809. C.getPointerType(BaseType->getCanonicalTypeInternal()),
  810. clang::CK_ArrayToPointerDecay,
  811. SrcArr,
  812. NULL,
  813. clang::VK_RValue);
  814. clang::Expr *SrcArrPtrSubscript =
  815. new(C) clang::ArraySubscriptExpr(SrcArrPtr,
  816. RefrsIntIter,
  817. BaseType->getCanonicalTypeInternal(),
  818. clang::VK_RValue,
  819. clang::OK_Ordinary,
  820. Loc);
  821. RSExportPrimitiveType::DataType DT =
  822. RSExportPrimitiveType::GetRSSpecificType(BaseType);
  823. clang::Stmt *RSSetObjectCall = NULL;
  824. if (BaseType->isArrayType()) {
  825. RSSetObjectCall = CreateArrayRSSetObject(C, DstArrPtrSubscript,
  826. SrcArrPtrSubscript,
  827. StartLoc, Loc);
  828. } else if (DT == RSExportPrimitiveType::DataTypeUnknown) {
  829. RSSetObjectCall = CreateStructRSSetObject(C, DstArrPtrSubscript,
  830. SrcArrPtrSubscript,
  831. StartLoc, Loc);
  832. } else {
  833. RSSetObjectCall = CreateSingleRSSetObject(C, DstArrPtrSubscript,
  834. SrcArrPtrSubscript,
  835. StartLoc, Loc);
  836. }
  837. clang::ForStmt *DestructorLoop =
  838. new(C) clang::ForStmt(C,
  839. Init,
  840. Cond,
  841. NULL, // no condVar
  842. Inc,
  843. RSSetObjectCall,
  844. Loc,
  845. Loc,
  846. Loc);
  847. StmtArray[StmtCtr++] = DestructorLoop;
  848. slangAssert(StmtCtr == 2);
  849. clang::CompoundStmt *CS =
  850. new(C) clang::CompoundStmt(C, StmtArray, StmtCtr, Loc, Loc);
  851. return CS;
  852. } */
  853. static clang::Stmt *CreateStructRSSetObject(clang::ASTContext &C,
  854. clang::Expr *LHS,
  855. clang::Expr *RHS,
  856. clang::SourceLocation StartLoc,
  857. clang::SourceLocation Loc) {
  858. clang::QualType QT = LHS->getType();
  859. const clang::Type *T = QT.getTypePtr();
  860. slangAssert(T->isStructureType());
  861. slangAssert(!RSExportPrimitiveType::IsRSObjectType(T));
  862. // Keep an extra slot for the original copy (memcpy)
  863. unsigned FieldsToSet = CountRSObjectTypes(C, T, Loc) + 1;
  864. unsigned StmtCount = 0;
  865. clang::Stmt **StmtArray = new clang::Stmt*[FieldsToSet];
  866. for (unsigned i = 0; i < FieldsToSet; i++) {
  867. StmtArray[i] = NULL;
  868. }
  869. clang::RecordDecl *RD = T->getAsStructureType()->getDecl();
  870. RD = RD->getDefinition();
  871. for (clang::RecordDecl::field_iterator FI = RD->field_begin(),
  872. FE = RD->field_end();
  873. FI != FE;
  874. FI++) {
  875. bool IsArrayType = false;
  876. clang::FieldDecl *FD = *FI;
  877. const clang::Type *FT = RSExportType::GetTypeOfDecl(FD);
  878. const clang::Type *OrigType = FT;
  879. if (!CountRSObjectTypes(C, FT, Loc)) {
  880. // Skip to next if we don't have any viable RS object types
  881. continue;
  882. }
  883. clang::DeclAccessPair FoundDecl =
  884. clang::DeclAccessPair::make(FD, clang::AS_none);
  885. clang::MemberExpr *DstMember =
  886. clang::MemberExpr::Create(C,
  887. LHS,
  888. false,
  889. clang::NestedNameSpecifierLoc(),
  890. clang::SourceLocation(),
  891. FD,
  892. FoundDecl,
  893. clang::DeclarationNameInfo(),
  894. NULL,
  895. OrigType->getCanonicalTypeInternal(),
  896. clang::VK_RValue,
  897. clang::OK_Ordinary);
  898. clang::MemberExpr *SrcMember =
  899. clang::MemberExpr::Create(C,
  900. RHS,
  901. false,
  902. clang::NestedNameSpecifierLoc(),
  903. clang::SourceLocation(),
  904. FD,
  905. FoundDecl,
  906. clang::DeclarationNameInfo(),
  907. NULL,
  908. OrigType->getCanonicalTypeInternal(),
  909. clang::VK_RValue,
  910. clang::OK_Ordinary);
  911. if (FT->isArrayType()) {
  912. FT = FT->getArrayElementTypeNoTypeQual();
  913. IsArrayType = true;
  914. }
  915. RSExportPrimitiveType::DataType DT =
  916. RSExportPrimitiveType::GetRSSpecificType(FT);
  917. if (IsArrayType) {
  918. clang::DiagnosticsEngine &DiagEngine = C.getDiagnostics();
  919. DiagEngine.Report(
  920. clang::FullSourceLoc(Loc, C.getSourceManager()),
  921. DiagEngine.getCustomDiagID(
  922. clang::DiagnosticsEngine::Error,
  923. "Arrays of RS object types within structures cannot be copied"));
  924. // TODO(srhines): Support setting arrays of RS objects
  925. // StmtArray[StmtCount++] =
  926. // CreateArrayRSSetObject(C, DstMember, SrcMember, StartLoc, Loc);
  927. } else if (DT == RSExportPrimitiveType::DataTypeUnknown) {
  928. StmtArray[StmtCount++] =
  929. CreateStructRSSetObject(C, DstMember, SrcMember, StartLoc, Loc);
  930. } else if (RSExportPrimitiveType::IsRSObjectType(DT)) {
  931. StmtArray[StmtCount++] =
  932. CreateSingleRSSetObject(C, DstMember, SrcMember, StartLoc, Loc);
  933. } else {
  934. slangAssert(false);
  935. }
  936. }
  937. slangAssert(StmtCount > 0 && StmtCount < FieldsToSet);
  938. // We still need to actually do the overall struct copy. For simplicity,
  939. // we just do a straight-up assignment (which will still preserve all
  940. // the proper RS object reference counts).
  941. clang::BinaryOperator *CopyStruct =
  942. new(C) clang::BinaryOperator(LHS, RHS, clang::BO_Assign, QT,
  943. clang::VK_RValue, clang::OK_Ordinary, Loc);
  944. StmtArray[StmtCount++] = CopyStruct;
  945. clang::CompoundStmt *CS =
  946. new(C) clang::CompoundStmt(C, StmtArray, StmtCount, Loc, Loc);
  947. delete [] StmtArray;
  948. return CS;
  949. }
  950. } // namespace
  951. void RSObjectRefCount::Scope::ReplaceRSObjectAssignment(
  952. clang::BinaryOperator *AS) {
  953. clang::QualType QT = AS->getType();
  954. clang::ASTContext &C = RSObjectRefCount::GetRSSetObjectFD(
  955. RSExportPrimitiveType::DataTypeRSFont)->getASTContext();
  956. clang::SourceLocation Loc = AS->getExprLoc();
  957. clang::SourceLocation StartLoc = AS->getLHS()->getExprLoc();
  958. clang::Stmt *UpdatedStmt = NULL;
  959. if (!RSExportPrimitiveType::IsRSObjectType(QT.getTypePtr())) {
  960. // By definition, this is a struct assignment if we get here
  961. UpdatedStmt =
  962. CreateStructRSSetObject(C, AS->getLHS(), AS->getRHS(), StartLoc, Loc);
  963. } else {
  964. UpdatedStmt =
  965. CreateSingleRSSetObject(C, AS->getLHS(), AS->getRHS(), StartLoc, Loc);
  966. }
  967. RSASTReplace R(C);
  968. R.ReplaceStmt(mCS, AS, UpdatedStmt);
  969. return;
  970. }
  971. void RSObjectRefCount::Scope::AppendRSObjectInit(
  972. clang::VarDecl *VD,
  973. clang::DeclStmt *DS,
  974. RSExportPrimitiveType::DataType DT,
  975. clang::Expr *InitExpr) {
  976. slangAssert(VD);
  977. if (!InitExpr) {
  978. return;
  979. }
  980. clang::ASTContext &C = RSObjectRefCount::GetRSSetObjectFD(
  981. RSExportPrimitiveType::DataTypeRSFont)->getASTContext();
  982. clang::SourceLocation Loc = RSObjectRefCount::GetRSSetObjectFD(
  983. RSExportPrimitiveType::DataTypeRSFont)->getLocation();
  984. clang::SourceLocation StartLoc = RSObjectRefCount::GetRSSetObjectFD(
  985. RSExportPrimitiveType::DataTypeRSFont)->getInnerLocStart();
  986. if (DT == RSExportPrimitiveType::DataTypeIsStruct) {
  987. const clang::Type *T = RSExportType::GetTypeOfDecl(VD);
  988. clang::DeclRefExpr *RefRSVar =
  989. clang::DeclRefExpr::Create(C,
  990. clang::NestedNameSpecifierLoc(),
  991. clang::SourceLocation(),
  992. VD,
  993. false,
  994. Loc,
  995. T->getCanonicalTypeInternal(),
  996. clang::VK_RValue,
  997. NULL);
  998. clang::Stmt *RSSetObjectOps =
  999. CreateStructRSSetObject(C, RefRSVar, InitExpr, StartLoc, Loc);
  1000. std::list<clang::Stmt*> StmtList;
  1001. StmtList.push_back(RSSetObjectOps);
  1002. AppendAfterStmt(C, mCS, DS, StmtList);
  1003. return;
  1004. }
  1005. clang::FunctionDecl *SetObjectFD = RSObjectRefCount::GetRSSetObjectFD(DT);
  1006. slangAssert((SetObjectFD != NULL) &&
  1007. "rsSetObject doesn't cover all RS object types");
  1008. clang::QualType SetObjectFDType = SetObjectFD->getType();
  1009. clang::QualType SetObjectFDArgType[2];
  1010. SetObjectFDArgType[0] = SetObjectFD->getParamDecl(0)->getOriginalType();
  1011. SetObjectFDArgType[1] = SetObjectFD->getParamDecl(1)->getOriginalType();
  1012. clang::Expr *RefRSSetObjectFD =
  1013. clang::DeclRefExpr::Create(C,
  1014. clang::NestedNameSpecifierLoc(),
  1015. clang::SourceLocation(),
  1016. SetObjectFD,
  1017. false,
  1018. Loc,
  1019. SetObjectFDType,
  1020. clang::VK_RValue,
  1021. NULL);
  1022. clang::Expr *RSSetObjectFP =
  1023. clang::ImplicitCastExpr::Create(C,
  1024. C.getPointerType(SetObjectFDType),
  1025. clang::CK_FunctionToPointerDecay,
  1026. RefRSSetObjectFD,
  1027. NULL,
  1028. clang::VK_RValue);
  1029. const clang::Type *T = RSExportType::GetTypeOfDecl(VD);
  1030. clang::DeclRefExpr *RefRSVar =
  1031. clang::DeclRefExpr::Create(C,
  1032. clang::NestedNameSpecifierLoc(),
  1033. clang::SourceLocation(),
  1034. VD,
  1035. false,
  1036. Loc,
  1037. T->getCanonicalTypeInternal(),
  1038. clang::VK_RValue,
  1039. NULL);
  1040. llvm::SmallVector<clang::Expr*, 2> ArgList;
  1041. ArgList.push_back(new(C) clang::UnaryOperator(RefRSVar,
  1042. clang::UO_AddrOf,
  1043. SetObjectFDArgType[0],
  1044. clang::VK_RValue,
  1045. clang::OK_Ordinary,
  1046. Loc));
  1047. ArgList.push_back(InitExpr);
  1048. clang::CallExpr *RSSetObjectCall =
  1049. new(C) clang::CallExpr(C,
  1050. RSSetObjectFP,
  1051. ArgList,
  1052. SetObjectFD->getCallResultType(),
  1053. clang::VK_RValue,
  1054. Loc);
  1055. std::list<clang::Stmt*> StmtList;
  1056. StmtList.push_back(RSSetObjectCall);
  1057. AppendAfterStmt(C, mCS, DS, StmtList);
  1058. return;
  1059. }
  1060. void RSObjectRefCount::Scope::InsertLocalVarDestructors() {
  1061. for (std::list<clang::VarDecl*>::const_iterator I = mRSO.begin(),
  1062. E = mRSO.end();
  1063. I != E;
  1064. I++) {
  1065. clang::VarDecl *VD = *I;
  1066. clang::Stmt *RSClearObjectCall = ClearRSObject(VD, VD->getDeclContext());
  1067. if (RSClearObjectCall) {
  1068. DestructorVisitor DV((*mRSO.begin())->getASTContext(),
  1069. mCS,
  1070. RSClearObjectCall,
  1071. VD->getSourceRange().getBegin());
  1072. DV.Visit(mCS);
  1073. DV.InsertDestructors();
  1074. }
  1075. }
  1076. return;
  1077. }
  1078. clang::Stmt *RSObjectRefCount::Scope::ClearRSObject(
  1079. clang::VarDecl *VD,
  1080. clang::DeclContext *DC) {
  1081. slangAssert(VD);
  1082. clang::ASTContext &C = VD->getASTContext();
  1083. clang::SourceLocation Loc = VD->getLocation();
  1084. clang::SourceLocation StartLoc = VD->getInnerLocStart();
  1085. const clang::Type *T = RSExportType::GetTypeOfDecl(VD);
  1086. // Reference expr to target RS object variable
  1087. clang::DeclRefExpr *RefRSVar =
  1088. clang::DeclRefExpr::Create(C,
  1089. clang::NestedNameSpecifierLoc(),
  1090. clang::SourceLocation(),
  1091. VD,
  1092. false,
  1093. Loc,
  1094. T->getCanonicalTypeInternal(),
  1095. clang::VK_RValue,
  1096. NULL);
  1097. if (T->isArrayType()) {
  1098. return ClearArrayRSObject(C, DC, RefRSVar, StartLoc, Loc);
  1099. }
  1100. RSExportPrimitiveType::DataType DT =
  1101. RSExportPrimitiveType::GetRSSpecificType(T);
  1102. if (DT == RSExportPrimitiveType::DataTypeUnknown ||
  1103. DT == RSExportPrimitiveType::DataTypeIsStruct) {
  1104. return ClearStructRSObject(C, DC, RefRSVar, StartLoc, Loc);
  1105. }
  1106. slangAssert((RSExportPrimitiveType::IsRSObjectType(DT)) &&
  1107. "Should be RS object");
  1108. return ClearSingleRSObject(C, RefRSVar, Loc);
  1109. }
  1110. bool RSObjectRefCount::InitializeRSObject(clang::VarDecl *VD,
  1111. RSExportPrimitiveType::DataType *DT,
  1112. clang::Expr **InitExpr) {
  1113. slangAssert(VD && DT && InitExpr);
  1114. const clang::Type *T = RSExportType::GetTypeOfDecl(VD);
  1115. // Loop through array types to get to base type
  1116. while (T && T->isArrayType()) {
  1117. T = T->getArrayElementTypeNoTypeQual();
  1118. }
  1119. bool DataTypeIsStructWithRSObject = false;
  1120. *DT = RSExportPrimitiveType::GetRSSpecificType(T);
  1121. if (*DT == RSExportPrimitiveType::DataTypeUnknown) {
  1122. if (RSExportPrimitiveType::IsStructureTypeWithRSObject(T)) {
  1123. *DT = RSExportPrimitiveType::DataTypeIsStruct;
  1124. DataTypeIsStructWithRSObject = true;
  1125. } else {
  1126. return false;
  1127. }
  1128. }
  1129. bool DataTypeIsRSObject = false;
  1130. if (DataTypeIsStructWithRSObject) {
  1131. DataTypeIsRSObject = true;
  1132. } else {
  1133. DataTypeIsRSObject = RSExportPrimitiveType::IsRSObjectType(*DT);
  1134. }
  1135. *InitExpr = VD->getInit();
  1136. if (!DataTypeIsRSObject && *InitExpr) {
  1137. // If we already have an initializer for a matrix type, we are done.
  1138. return DataTypeIsRSObject;
  1139. }
  1140. clang::Expr *ZeroInitializer =
  1141. CreateZeroInitializerForRSSpecificType(*DT,
  1142. VD->getASTContext(),
  1143. VD->getLocation());
  1144. if (ZeroInitializer) {
  1145. ZeroInitializer->setType(T->getCanonicalTypeInternal());
  1146. VD->setInit(ZeroInitializer);
  1147. }
  1148. return DataTypeIsRSObject;
  1149. }
  1150. clang::Expr *RSObjectRefCount::CreateZeroInitializerForRSSpecificType(
  1151. RSExportPrimitiveType::DataType DT,
  1152. clang::ASTContext &C,
  1153. const clang::SourceLocation &Loc) {
  1154. clang::Expr *Res = NULL;
  1155. switch (DT) {
  1156. case RSExportPrimitiveType::DataTypeIsStruct:
  1157. case RSExportPrimitiveType::DataTypeRSElement:
  1158. case RSExportPrimitiveType::DataTypeRSType:
  1159. case RSExportPrimitiveType::DataTypeRSAllocation:
  1160. case RSExportPrimitiveType::DataTypeRSSampler:
  1161. case RSExportPrimitiveType::DataTypeRSScript:
  1162. case RSExportPrimitiveType::DataTypeRSMesh:
  1163. case RSExportPrimitiveType::DataTypeRSPath:
  1164. case RSExportPrimitiveType::DataTypeRSProgramFragment:
  1165. case RSExportPrimitiveType::DataTypeRSProgramVertex:
  1166. case RSExportPrimitiveType::DataTypeRSProgramRaster:
  1167. case RSExportPrimitiveType::DataTypeRSProgramStore:
  1168. case RSExportPrimitiveType::DataTypeRSFont: {
  1169. // (ImplicitCastExpr 'nullptr_t'
  1170. // (IntegerLiteral 0)))
  1171. llvm::APInt Zero(C.getTypeSize(C.IntTy), 0);
  1172. clang::Expr *Int0 = clang::IntegerLiteral::Create(C, Zero, C.IntTy, Loc);
  1173. clang::Expr *CastToNull =
  1174. c