slang_rs_object_ref_count.cpp 63 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793
  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 "clang/AST/DeclGroup.h"
  18. #include "clang/AST/Expr.h"
  19. #include "clang/AST/NestedNameSpecifier.h"
  20. #include "clang/AST/OperationKinds.h"
  21. #include "clang/AST/RecursiveASTVisitor.h"
  22. #include "clang/AST/Stmt.h"
  23. #include "clang/AST/StmtVisitor.h"
  24. #include "slang_assert.h"
  25. #include "slang.h"
  26. #include "slang_rs_ast_replace.h"
  27. #include "slang_rs_export_type.h"
  28. namespace slang {
  29. /* Even though those two arrays are of size DataTypeMax, only entries that
  30. * correspond to object types will be set.
  31. */
  32. clang::FunctionDecl *
  33. RSObjectRefCount::RSSetObjectFD[DataTypeMax];
  34. clang::FunctionDecl *
  35. RSObjectRefCount::RSClearObjectFD[DataTypeMax];
  36. void RSObjectRefCount::GetRSRefCountingFunctions(clang::ASTContext &C) {
  37. for (unsigned i = 0; i < DataTypeMax; i++) {
  38. RSSetObjectFD[i] = nullptr;
  39. RSClearObjectFD[i] = nullptr;
  40. }
  41. clang::TranslationUnitDecl *TUDecl = C.getTranslationUnitDecl();
  42. for (clang::DeclContext::decl_iterator I = TUDecl->decls_begin(),
  43. E = TUDecl->decls_end(); I != E; I++) {
  44. if ((I->getKind() >= clang::Decl::firstFunction) &&
  45. (I->getKind() <= clang::Decl::lastFunction)) {
  46. clang::FunctionDecl *FD = static_cast<clang::FunctionDecl*>(*I);
  47. // points to RSSetObjectFD or RSClearObjectFD
  48. clang::FunctionDecl **RSObjectFD;
  49. if (FD->getName() == "rsSetObject") {
  50. slangAssert((FD->getNumParams() == 2) &&
  51. "Invalid rsSetObject function prototype (# params)");
  52. RSObjectFD = RSSetObjectFD;
  53. } else if (FD->getName() == "rsClearObject") {
  54. slangAssert((FD->getNumParams() == 1) &&
  55. "Invalid rsClearObject function prototype (# params)");
  56. RSObjectFD = RSClearObjectFD;
  57. } else {
  58. continue;
  59. }
  60. const clang::ParmVarDecl *PVD = FD->getParamDecl(0);
  61. clang::QualType PVT = PVD->getOriginalType();
  62. // The first parameter must be a pointer like rs_allocation*
  63. slangAssert(PVT->isPointerType() &&
  64. "Invalid rs{Set,Clear}Object function prototype (pointer param)");
  65. // The rs object type passed to the FD
  66. clang::QualType RST = PVT->getPointeeType();
  67. DataType DT = RSExportPrimitiveType::GetRSSpecificType(RST.getTypePtr());
  68. slangAssert(RSExportPrimitiveType::IsRSObjectType(DT)
  69. && "must be RS object type");
  70. if (DT >= 0 && DT < DataTypeMax) {
  71. RSObjectFD[DT] = FD;
  72. } else {
  73. slangAssert(false && "incorrect type");
  74. }
  75. }
  76. }
  77. }
  78. namespace {
  79. unsigned CountRSObjectTypes(const clang::Type *T);
  80. clang::Stmt *CreateSingleRSSetObject(clang::ASTContext &C,
  81. clang::Expr *DstExpr,
  82. clang::Expr *SrcExpr,
  83. clang::SourceLocation StartLoc,
  84. clang::SourceLocation Loc);
  85. // This function constructs a new CompoundStmt from the input StmtList.
  86. clang::CompoundStmt* BuildCompoundStmt(clang::ASTContext &C,
  87. std::vector<clang::Stmt*> &StmtList, clang::SourceLocation Loc) {
  88. unsigned NewStmtCount = StmtList.size();
  89. unsigned CompoundStmtCount = 0;
  90. clang::Stmt **CompoundStmtList;
  91. CompoundStmtList = new clang::Stmt*[NewStmtCount];
  92. std::vector<clang::Stmt*>::const_iterator I = StmtList.begin();
  93. std::vector<clang::Stmt*>::const_iterator E = StmtList.end();
  94. for ( ; I != E; I++) {
  95. CompoundStmtList[CompoundStmtCount++] = *I;
  96. }
  97. slangAssert(CompoundStmtCount == NewStmtCount);
  98. clang::CompoundStmt *CS = new(C) clang::CompoundStmt(
  99. C, llvm::makeArrayRef(CompoundStmtList, CompoundStmtCount), Loc, Loc);
  100. delete [] CompoundStmtList;
  101. return CS;
  102. }
  103. void AppendAfterStmt(clang::ASTContext &C,
  104. clang::CompoundStmt *CS,
  105. clang::Stmt *S,
  106. std::list<clang::Stmt*> &StmtList) {
  107. slangAssert(CS);
  108. clang::CompoundStmt::body_iterator bI = CS->body_begin();
  109. clang::CompoundStmt::body_iterator bE = CS->body_end();
  110. clang::Stmt **UpdatedStmtList =
  111. new clang::Stmt*[CS->size() + StmtList.size()];
  112. unsigned UpdatedStmtCount = 0;
  113. unsigned Once = 0;
  114. for ( ; bI != bE; bI++) {
  115. if (!S && ((*bI)->getStmtClass() == clang::Stmt::ReturnStmtClass)) {
  116. // If we come across a return here, we don't have anything we can
  117. // reasonably replace. We should have already inserted our destructor
  118. // code in the proper spot, so we just clean up and return.
  119. delete [] UpdatedStmtList;
  120. return;
  121. }
  122. UpdatedStmtList[UpdatedStmtCount++] = *bI;
  123. if ((*bI == S) && !Once) {
  124. Once++;
  125. std::list<clang::Stmt*>::const_iterator I = StmtList.begin();
  126. std::list<clang::Stmt*>::const_iterator E = StmtList.end();
  127. for ( ; I != E; I++) {
  128. UpdatedStmtList[UpdatedStmtCount++] = *I;
  129. }
  130. }
  131. }
  132. slangAssert(Once <= 1);
  133. // When S is nullptr, we are appending to the end of the CompoundStmt.
  134. if (!S) {
  135. slangAssert(Once == 0);
  136. std::list<clang::Stmt*>::const_iterator I = StmtList.begin();
  137. std::list<clang::Stmt*>::const_iterator E = StmtList.end();
  138. for ( ; I != E; I++) {
  139. UpdatedStmtList[UpdatedStmtCount++] = *I;
  140. }
  141. }
  142. CS->setStmts(C, llvm::makeArrayRef(UpdatedStmtList, UpdatedStmtCount));
  143. delete [] UpdatedStmtList;
  144. }
  145. // This class visits a compound statement and collects a list of all the exiting
  146. // statements, such as any return statement in any sub-block, and any
  147. // break/continue statement that would resume outside the current scope.
  148. // We do not handle the case for goto statements that leave a local scope.
  149. class DestructorVisitor : public clang::StmtVisitor<DestructorVisitor> {
  150. private:
  151. // The loop depth of the currently visited node.
  152. int mLoopDepth;
  153. // The switch statement depth of the currently visited node.
  154. // Note that this is tracked separately from the loop depth because
  155. // SwitchStmt-contained ContinueStmt's should have destructors for the
  156. // corresponding loop scope.
  157. int mSwitchDepth;
  158. // Output of the visitor: the statements that should be replaced by compound
  159. // statements, each of which contains rsClearObject() calls followed by the
  160. // original statement.
  161. std::vector<clang::Stmt*> mExitingStmts;
  162. public:
  163. DestructorVisitor() : mLoopDepth(0), mSwitchDepth(0) {}
  164. const std::vector<clang::Stmt*>& getExitingStmts() const {
  165. return mExitingStmts;
  166. }
  167. void VisitStmt(clang::Stmt *S);
  168. void VisitBreakStmt(clang::BreakStmt *BS);
  169. void VisitContinueStmt(clang::ContinueStmt *CS);
  170. void VisitDoStmt(clang::DoStmt *DS);
  171. void VisitForStmt(clang::ForStmt *FS);
  172. void VisitReturnStmt(clang::ReturnStmt *RS);
  173. void VisitSwitchStmt(clang::SwitchStmt *SS);
  174. void VisitWhileStmt(clang::WhileStmt *WS);
  175. };
  176. void DestructorVisitor::VisitStmt(clang::Stmt *S) {
  177. for (clang::Stmt* Child : S->children()) {
  178. if (Child) {
  179. Visit(Child);
  180. }
  181. }
  182. }
  183. void DestructorVisitor::VisitBreakStmt(clang::BreakStmt *BS) {
  184. VisitStmt(BS);
  185. if ((mLoopDepth == 0) && (mSwitchDepth == 0)) {
  186. mExitingStmts.push_back(BS);
  187. }
  188. }
  189. void DestructorVisitor::VisitContinueStmt(clang::ContinueStmt *CS) {
  190. VisitStmt(CS);
  191. if (mLoopDepth == 0) {
  192. // Switch statements can have nested continues.
  193. mExitingStmts.push_back(CS);
  194. }
  195. }
  196. void DestructorVisitor::VisitDoStmt(clang::DoStmt *DS) {
  197. mLoopDepth++;
  198. VisitStmt(DS);
  199. mLoopDepth--;
  200. }
  201. void DestructorVisitor::VisitForStmt(clang::ForStmt *FS) {
  202. mLoopDepth++;
  203. VisitStmt(FS);
  204. mLoopDepth--;
  205. }
  206. void DestructorVisitor::VisitReturnStmt(clang::ReturnStmt *RS) {
  207. mExitingStmts.push_back(RS);
  208. }
  209. void DestructorVisitor::VisitSwitchStmt(clang::SwitchStmt *SS) {
  210. mSwitchDepth++;
  211. VisitStmt(SS);
  212. mSwitchDepth--;
  213. }
  214. void DestructorVisitor::VisitWhileStmt(clang::WhileStmt *WS) {
  215. mLoopDepth++;
  216. VisitStmt(WS);
  217. mLoopDepth--;
  218. }
  219. clang::Expr *ClearSingleRSObject(clang::ASTContext &C,
  220. clang::Expr *RefRSVar,
  221. clang::SourceLocation Loc) {
  222. slangAssert(RefRSVar);
  223. const clang::Type *T = RefRSVar->getType().getTypePtr();
  224. slangAssert(!T->isArrayType() &&
  225. "Should not be destroying arrays with this function");
  226. clang::FunctionDecl *ClearObjectFD = RSObjectRefCount::GetRSClearObjectFD(T);
  227. slangAssert((ClearObjectFD != nullptr) &&
  228. "rsClearObject doesn't cover all RS object types");
  229. clang::QualType ClearObjectFDType = ClearObjectFD->getType();
  230. clang::QualType ClearObjectFDArgType =
  231. ClearObjectFD->getParamDecl(0)->getOriginalType();
  232. // Example destructor for "rs_font localFont;"
  233. //
  234. // (CallExpr 'void'
  235. // (ImplicitCastExpr 'void (*)(rs_font *)' <FunctionToPointerDecay>
  236. // (DeclRefExpr 'void (rs_font *)' FunctionDecl='rsClearObject'))
  237. // (UnaryOperator 'rs_font *' prefix '&'
  238. // (DeclRefExpr 'rs_font':'rs_font' Var='localFont')))
  239. // Get address of targeted RS object
  240. clang::Expr *AddrRefRSVar =
  241. new(C) clang::UnaryOperator(RefRSVar,
  242. clang::UO_AddrOf,
  243. ClearObjectFDArgType,
  244. clang::VK_RValue,
  245. clang::OK_Ordinary,
  246. Loc);
  247. clang::Expr *RefRSClearObjectFD =
  248. clang::DeclRefExpr::Create(C,
  249. clang::NestedNameSpecifierLoc(),
  250. clang::SourceLocation(),
  251. ClearObjectFD,
  252. false,
  253. ClearObjectFD->getLocation(),
  254. ClearObjectFDType,
  255. clang::VK_RValue,
  256. nullptr);
  257. clang::Expr *RSClearObjectFP =
  258. clang::ImplicitCastExpr::Create(C,
  259. C.getPointerType(ClearObjectFDType),
  260. clang::CK_FunctionToPointerDecay,
  261. RefRSClearObjectFD,
  262. nullptr,
  263. clang::VK_RValue);
  264. llvm::SmallVector<clang::Expr*, 1> ArgList;
  265. ArgList.push_back(AddrRefRSVar);
  266. clang::CallExpr *RSClearObjectCall =
  267. new(C) clang::CallExpr(C,
  268. RSClearObjectFP,
  269. ArgList,
  270. ClearObjectFD->getCallResultType(),
  271. clang::VK_RValue,
  272. Loc);
  273. return RSClearObjectCall;
  274. }
  275. static int ArrayDim(const clang::Type *T) {
  276. if (!T || !T->isArrayType()) {
  277. return 0;
  278. }
  279. const clang::ConstantArrayType *CAT =
  280. static_cast<const clang::ConstantArrayType *>(T);
  281. return static_cast<int>(CAT->getSize().getSExtValue());
  282. }
  283. clang::Stmt *ClearStructRSObject(
  284. clang::ASTContext &C,
  285. clang::DeclContext *DC,
  286. clang::Expr *RefRSStruct,
  287. clang::SourceLocation StartLoc,
  288. clang::SourceLocation Loc);
  289. clang::Stmt *ClearArrayRSObject(
  290. clang::ASTContext &C,
  291. clang::DeclContext *DC,
  292. clang::Expr *RefRSArr,
  293. clang::SourceLocation StartLoc,
  294. clang::SourceLocation Loc) {
  295. const clang::Type *BaseType = RefRSArr->getType().getTypePtr();
  296. slangAssert(BaseType->isArrayType());
  297. int NumArrayElements = ArrayDim(BaseType);
  298. // Actually extract out the base RS object type for use later
  299. BaseType = BaseType->getArrayElementTypeNoTypeQual();
  300. if (NumArrayElements <= 0) {
  301. return nullptr;
  302. }
  303. // Example destructor loop for "rs_font fontArr[10];"
  304. //
  305. // (ForStmt
  306. // (DeclStmt
  307. // (VarDecl used rsIntIter 'int' cinit
  308. // (IntegerLiteral 'int' 0)))
  309. // (BinaryOperator 'int' '<'
  310. // (ImplicitCastExpr int LValueToRValue
  311. // (DeclRefExpr 'int' Var='rsIntIter'))
  312. // (IntegerLiteral 'int' 10)
  313. // nullptr << CondVar >>
  314. // (UnaryOperator 'int' postfix '++'
  315. // (DeclRefExpr 'int' Var='rsIntIter'))
  316. // (CallExpr 'void'
  317. // (ImplicitCastExpr 'void (*)(rs_font *)' <FunctionToPointerDecay>
  318. // (DeclRefExpr 'void (rs_font *)' FunctionDecl='rsClearObject'))
  319. // (UnaryOperator 'rs_font *' prefix '&'
  320. // (ArraySubscriptExpr 'rs_font':'rs_font'
  321. // (ImplicitCastExpr 'rs_font *' <ArrayToPointerDecay>
  322. // (DeclRefExpr 'rs_font [10]' Var='fontArr'))
  323. // (DeclRefExpr 'int' Var='rsIntIter'))))))
  324. // Create helper variable for iterating through elements
  325. static unsigned sIterCounter = 0;
  326. std::stringstream UniqueIterName;
  327. UniqueIterName << "rsIntIter" << sIterCounter++;
  328. clang::IdentifierInfo *II = &C.Idents.get(UniqueIterName.str());
  329. clang::VarDecl *IIVD =
  330. clang::VarDecl::Create(C,
  331. DC,
  332. StartLoc,
  333. Loc,
  334. II,
  335. C.IntTy,
  336. C.getTrivialTypeSourceInfo(C.IntTy),
  337. clang::SC_None);
  338. // Mark "rsIntIter" as used
  339. IIVD->markUsed(C);
  340. // Form the actual destructor loop
  341. // for (Init; Cond; Inc)
  342. // RSClearObjectCall;
  343. // Init -> "int rsIntIter = 0"
  344. clang::Expr *Int0 = clang::IntegerLiteral::Create(C,
  345. llvm::APInt(C.getTypeSize(C.IntTy), 0), C.IntTy, Loc);
  346. IIVD->setInit(Int0);
  347. clang::Decl *IID = (clang::Decl *)IIVD;
  348. clang::DeclGroupRef DGR = clang::DeclGroupRef::Create(C, &IID, 1);
  349. clang::Stmt *Init = new(C) clang::DeclStmt(DGR, Loc, Loc);
  350. // Cond -> "rsIntIter < NumArrayElements"
  351. clang::DeclRefExpr *RefrsIntIterLValue =
  352. clang::DeclRefExpr::Create(C,
  353. clang::NestedNameSpecifierLoc(),
  354. clang::SourceLocation(),
  355. IIVD,
  356. false,
  357. Loc,
  358. C.IntTy,
  359. clang::VK_LValue,
  360. nullptr);
  361. clang::Expr *RefrsIntIterRValue =
  362. clang::ImplicitCastExpr::Create(C,
  363. RefrsIntIterLValue->getType(),
  364. clang::CK_LValueToRValue,
  365. RefrsIntIterLValue,
  366. nullptr,
  367. clang::VK_RValue);
  368. clang::Expr *NumArrayElementsExpr = clang::IntegerLiteral::Create(C,
  369. llvm::APInt(C.getTypeSize(C.IntTy), NumArrayElements), C.IntTy, Loc);
  370. clang::BinaryOperator *Cond =
  371. new(C) clang::BinaryOperator(RefrsIntIterRValue,
  372. NumArrayElementsExpr,
  373. clang::BO_LT,
  374. C.IntTy,
  375. clang::VK_RValue,
  376. clang::OK_Ordinary,
  377. Loc,
  378. false);
  379. // Inc -> "rsIntIter++"
  380. clang::UnaryOperator *Inc =
  381. new(C) clang::UnaryOperator(RefrsIntIterLValue,
  382. clang::UO_PostInc,
  383. C.IntTy,
  384. clang::VK_RValue,
  385. clang::OK_Ordinary,
  386. Loc);
  387. // Body -> "rsClearObject(&VD[rsIntIter]);"
  388. // Destructor loop operates on individual array elements
  389. clang::Expr *RefRSArrPtr =
  390. clang::ImplicitCastExpr::Create(C,
  391. C.getPointerType(BaseType->getCanonicalTypeInternal()),
  392. clang::CK_ArrayToPointerDecay,
  393. RefRSArr,
  394. nullptr,
  395. clang::VK_RValue);
  396. clang::Expr *RefRSArrPtrSubscript =
  397. new(C) clang::ArraySubscriptExpr(RefRSArrPtr,
  398. RefrsIntIterRValue,
  399. BaseType->getCanonicalTypeInternal(),
  400. clang::VK_RValue,
  401. clang::OK_Ordinary,
  402. Loc);
  403. DataType DT = RSExportPrimitiveType::GetRSSpecificType(BaseType);
  404. clang::Stmt *RSClearObjectCall = nullptr;
  405. if (BaseType->isArrayType()) {
  406. RSClearObjectCall =
  407. ClearArrayRSObject(C, DC, RefRSArrPtrSubscript, StartLoc, Loc);
  408. } else if (DT == DataTypeUnknown) {
  409. RSClearObjectCall =
  410. ClearStructRSObject(C, DC, RefRSArrPtrSubscript, StartLoc, Loc);
  411. } else {
  412. RSClearObjectCall = ClearSingleRSObject(C, RefRSArrPtrSubscript, Loc);
  413. }
  414. clang::ForStmt *DestructorLoop =
  415. new(C) clang::ForStmt(C,
  416. Init,
  417. Cond,
  418. nullptr, // no condVar
  419. Inc,
  420. RSClearObjectCall,
  421. Loc,
  422. Loc,
  423. Loc);
  424. return DestructorLoop;
  425. }
  426. unsigned CountRSObjectTypes(const clang::Type *T) {
  427. slangAssert(T);
  428. unsigned RSObjectCount = 0;
  429. if (T->isArrayType()) {
  430. return CountRSObjectTypes(T->getArrayElementTypeNoTypeQual());
  431. }
  432. DataType DT = RSExportPrimitiveType::GetRSSpecificType(T);
  433. if (DT != DataTypeUnknown) {
  434. return (RSExportPrimitiveType::IsRSObjectType(DT) ? 1 : 0);
  435. }
  436. if (T->isUnionType()) {
  437. clang::RecordDecl *RD = T->getAsUnionType()->getDecl();
  438. RD = RD->getDefinition();
  439. for (clang::RecordDecl::field_iterator FI = RD->field_begin(),
  440. FE = RD->field_end();
  441. FI != FE;
  442. FI++) {
  443. const clang::FieldDecl *FD = *FI;
  444. const clang::Type *FT = RSExportType::GetTypeOfDecl(FD);
  445. if (CountRSObjectTypes(FT)) {
  446. slangAssert(false && "can't have unions with RS object types!");
  447. return 0;
  448. }
  449. }
  450. }
  451. if (!T->isStructureType()) {
  452. return 0;
  453. }
  454. clang::RecordDecl *RD = T->getAsStructureType()->getDecl();
  455. RD = RD->getDefinition();
  456. for (clang::RecordDecl::field_iterator FI = RD->field_begin(),
  457. FE = RD->field_end();
  458. FI != FE;
  459. FI++) {
  460. const clang::FieldDecl *FD = *FI;
  461. const clang::Type *FT = RSExportType::GetTypeOfDecl(FD);
  462. if (CountRSObjectTypes(FT)) {
  463. // Sub-structs should only count once (as should arrays, etc.)
  464. RSObjectCount++;
  465. }
  466. }
  467. return RSObjectCount;
  468. }
  469. clang::Stmt *ClearStructRSObject(
  470. clang::ASTContext &C,
  471. clang::DeclContext *DC,
  472. clang::Expr *RefRSStruct,
  473. clang::SourceLocation StartLoc,
  474. clang::SourceLocation Loc) {
  475. const clang::Type *BaseType = RefRSStruct->getType().getTypePtr();
  476. slangAssert(!BaseType->isArrayType());
  477. // Structs should show up as unknown primitive types
  478. slangAssert(RSExportPrimitiveType::GetRSSpecificType(BaseType) ==
  479. DataTypeUnknown);
  480. unsigned FieldsToDestroy = CountRSObjectTypes(BaseType);
  481. slangAssert(FieldsToDestroy != 0);
  482. unsigned StmtCount = 0;
  483. clang::Stmt **StmtArray = new clang::Stmt*[FieldsToDestroy];
  484. for (unsigned i = 0; i < FieldsToDestroy; i++) {
  485. StmtArray[i] = nullptr;
  486. }
  487. // Populate StmtArray by creating a destructor for each RS object field
  488. clang::RecordDecl *RD = BaseType->getAsStructureType()->getDecl();
  489. RD = RD->getDefinition();
  490. for (clang::RecordDecl::field_iterator FI = RD->field_begin(),
  491. FE = RD->field_end();
  492. FI != FE;
  493. FI++) {
  494. // We just look through all field declarations to see if we find a
  495. // declaration for an RS object type (or an array of one).
  496. bool IsArrayType = false;
  497. clang::FieldDecl *FD = *FI;
  498. const clang::Type *FT = RSExportType::GetTypeOfDecl(FD);
  499. slangAssert(FT);
  500. const clang::Type *OrigType = FT;
  501. while (FT->isArrayType()) {
  502. FT = FT->getArrayElementTypeNoTypeQual();
  503. slangAssert(FT);
  504. IsArrayType = true;
  505. }
  506. // Pass a DeclarationNameInfo with a valid DeclName, since name equality
  507. // gets asserted during CodeGen.
  508. clang::DeclarationNameInfo FDDeclNameInfo(FD->getDeclName(),
  509. FD->getLocation());
  510. if (RSExportPrimitiveType::IsRSObjectType(FT)) {
  511. clang::DeclAccessPair FoundDecl =
  512. clang::DeclAccessPair::make(FD, clang::AS_none);
  513. clang::MemberExpr *RSObjectMember =
  514. clang::MemberExpr::Create(C,
  515. RefRSStruct,
  516. false,
  517. clang::SourceLocation(),
  518. clang::NestedNameSpecifierLoc(),
  519. clang::SourceLocation(),
  520. FD,
  521. FoundDecl,
  522. FDDeclNameInfo,
  523. nullptr,
  524. OrigType->getCanonicalTypeInternal(),
  525. clang::VK_RValue,
  526. clang::OK_Ordinary);
  527. slangAssert(StmtCount < FieldsToDestroy);
  528. if (IsArrayType) {
  529. StmtArray[StmtCount++] = ClearArrayRSObject(C,
  530. DC,
  531. RSObjectMember,
  532. StartLoc,
  533. Loc);
  534. } else {
  535. StmtArray[StmtCount++] = ClearSingleRSObject(C,
  536. RSObjectMember,
  537. Loc);
  538. }
  539. } else if (FT->isStructureType() && CountRSObjectTypes(FT)) {
  540. // In this case, we have a nested struct. We may not end up filling all
  541. // of the spaces in StmtArray (sub-structs should handle themselves
  542. // with separate compound statements).
  543. clang::DeclAccessPair FoundDecl =
  544. clang::DeclAccessPair::make(FD, clang::AS_none);
  545. clang::MemberExpr *RSObjectMember =
  546. clang::MemberExpr::Create(C,
  547. RefRSStruct,
  548. false,
  549. clang::SourceLocation(),
  550. clang::NestedNameSpecifierLoc(),
  551. clang::SourceLocation(),
  552. FD,
  553. FoundDecl,
  554. clang::DeclarationNameInfo(),
  555. nullptr,
  556. OrigType->getCanonicalTypeInternal(),
  557. clang::VK_RValue,
  558. clang::OK_Ordinary);
  559. if (IsArrayType) {
  560. StmtArray[StmtCount++] = ClearArrayRSObject(C,
  561. DC,
  562. RSObjectMember,
  563. StartLoc,
  564. Loc);
  565. } else {
  566. StmtArray[StmtCount++] = ClearStructRSObject(C,
  567. DC,
  568. RSObjectMember,
  569. StartLoc,
  570. Loc);
  571. }
  572. }
  573. }
  574. slangAssert(StmtCount > 0);
  575. clang::CompoundStmt *CS = new(C) clang::CompoundStmt(
  576. C, llvm::makeArrayRef(StmtArray, StmtCount), Loc, Loc);
  577. delete [] StmtArray;
  578. return CS;
  579. }
  580. clang::Stmt *CreateSingleRSSetObject(clang::ASTContext &C,
  581. clang::Expr *DstExpr,
  582. clang::Expr *SrcExpr,
  583. clang::SourceLocation StartLoc,
  584. clang::SourceLocation Loc) {
  585. const clang::Type *T = DstExpr->getType().getTypePtr();
  586. clang::FunctionDecl *SetObjectFD = RSObjectRefCount::GetRSSetObjectFD(T);
  587. slangAssert((SetObjectFD != nullptr) &&
  588. "rsSetObject doesn't cover all RS object types");
  589. clang::QualType SetObjectFDType = SetObjectFD->getType();
  590. clang::QualType SetObjectFDArgType[2];
  591. SetObjectFDArgType[0] = SetObjectFD->getParamDecl(0)->getOriginalType();
  592. SetObjectFDArgType[1] = SetObjectFD->getParamDecl(1)->getOriginalType();
  593. clang::Expr *RefRSSetObjectFD =
  594. clang::DeclRefExpr::Create(C,
  595. clang::NestedNameSpecifierLoc(),
  596. clang::SourceLocation(),
  597. SetObjectFD,
  598. false,
  599. Loc,
  600. SetObjectFDType,
  601. clang::VK_RValue,
  602. nullptr);
  603. clang::Expr *RSSetObjectFP =
  604. clang::ImplicitCastExpr::Create(C,
  605. C.getPointerType(SetObjectFDType),
  606. clang::CK_FunctionToPointerDecay,
  607. RefRSSetObjectFD,
  608. nullptr,
  609. clang::VK_RValue);
  610. llvm::SmallVector<clang::Expr*, 2> ArgList;
  611. ArgList.push_back(new(C) clang::UnaryOperator(DstExpr,
  612. clang::UO_AddrOf,
  613. SetObjectFDArgType[0],
  614. clang::VK_RValue,
  615. clang::OK_Ordinary,
  616. Loc));
  617. ArgList.push_back(SrcExpr);
  618. clang::CallExpr *RSSetObjectCall =
  619. new(C) clang::CallExpr(C,
  620. RSSetObjectFP,
  621. ArgList,
  622. SetObjectFD->getCallResultType(),
  623. clang::VK_RValue,
  624. Loc);
  625. return RSSetObjectCall;
  626. }
  627. clang::Stmt *CreateStructRSSetObject(clang::ASTContext &C,
  628. clang::Expr *LHS,
  629. clang::Expr *RHS,
  630. clang::SourceLocation StartLoc,
  631. clang::SourceLocation Loc);
  632. /*static clang::Stmt *CreateArrayRSSetObject(clang::ASTContext &C,
  633. clang::Expr *DstArr,
  634. clang::Expr *SrcArr,
  635. clang::SourceLocation StartLoc,
  636. clang::SourceLocation Loc) {
  637. clang::DeclContext *DC = nullptr;
  638. const clang::Type *BaseType = DstArr->getType().getTypePtr();
  639. slangAssert(BaseType->isArrayType());
  640. int NumArrayElements = ArrayDim(BaseType);
  641. // Actually extract out the base RS object type for use later
  642. BaseType = BaseType->getArrayElementTypeNoTypeQual();
  643. clang::Stmt *StmtArray[2] = {nullptr};
  644. int StmtCtr = 0;
  645. if (NumArrayElements <= 0) {
  646. return nullptr;
  647. }
  648. // Create helper variable for iterating through elements
  649. clang::IdentifierInfo& II = C.Idents.get("rsIntIter");
  650. clang::VarDecl *IIVD =
  651. clang::VarDecl::Create(C,
  652. DC,
  653. StartLoc,
  654. Loc,
  655. &II,
  656. C.IntTy,
  657. C.getTrivialTypeSourceInfo(C.IntTy),
  658. clang::SC_None,
  659. clang::SC_None);
  660. clang::Decl *IID = (clang::Decl *)IIVD;
  661. clang::DeclGroupRef DGR = clang::DeclGroupRef::Create(C, &IID, 1);
  662. StmtArray[StmtCtr++] = new(C) clang::DeclStmt(DGR, Loc, Loc);
  663. // Form the actual loop
  664. // for (Init; Cond; Inc)
  665. // RSSetObjectCall;
  666. // Init -> "rsIntIter = 0"
  667. clang::DeclRefExpr *RefrsIntIter =
  668. clang::DeclRefExpr::Create(C,
  669. clang::NestedNameSpecifierLoc(),
  670. IIVD,
  671. Loc,
  672. C.IntTy,
  673. clang::VK_RValue,
  674. nullptr);
  675. clang::Expr *Int0 = clang::IntegerLiteral::Create(C,
  676. llvm::APInt(C.getTypeSize(C.IntTy), 0), C.IntTy, Loc);
  677. clang::BinaryOperator *Init =
  678. new(C) clang::BinaryOperator(RefrsIntIter,
  679. Int0,
  680. clang::BO_Assign,
  681. C.IntTy,
  682. clang::VK_RValue,
  683. clang::OK_Ordinary,
  684. Loc);
  685. // Cond -> "rsIntIter < NumArrayElements"
  686. clang::Expr *NumArrayElementsExpr = clang::IntegerLiteral::Create(C,
  687. llvm::APInt(C.getTypeSize(C.IntTy), NumArrayElements), C.IntTy, Loc);
  688. clang::BinaryOperator *Cond =
  689. new(C) clang::BinaryOperator(RefrsIntIter,
  690. NumArrayElementsExpr,
  691. clang::BO_LT,
  692. C.IntTy,
  693. clang::VK_RValue,
  694. clang::OK_Ordinary,
  695. Loc);
  696. // Inc -> "rsIntIter++"
  697. clang::UnaryOperator *Inc =
  698. new(C) clang::UnaryOperator(RefrsIntIter,
  699. clang::UO_PostInc,
  700. C.IntTy,
  701. clang::VK_RValue,
  702. clang::OK_Ordinary,
  703. Loc);
  704. // Body -> "rsSetObject(&Dst[rsIntIter], Src[rsIntIter]);"
  705. // Loop operates on individual array elements
  706. clang::Expr *DstArrPtr =
  707. clang::ImplicitCastExpr::Create(C,
  708. C.getPointerType(BaseType->getCanonicalTypeInternal()),
  709. clang::CK_ArrayToPointerDecay,
  710. DstArr,
  711. nullptr,
  712. clang::VK_RValue);
  713. clang::Expr *DstArrPtrSubscript =
  714. new(C) clang::ArraySubscriptExpr(DstArrPtr,
  715. RefrsIntIter,
  716. BaseType->getCanonicalTypeInternal(),
  717. clang::VK_RValue,
  718. clang::OK_Ordinary,
  719. Loc);
  720. clang::Expr *SrcArrPtr =
  721. clang::ImplicitCastExpr::Create(C,
  722. C.getPointerType(BaseType->getCanonicalTypeInternal()),
  723. clang::CK_ArrayToPointerDecay,
  724. SrcArr,
  725. nullptr,
  726. clang::VK_RValue);
  727. clang::Expr *SrcArrPtrSubscript =
  728. new(C) clang::ArraySubscriptExpr(SrcArrPtr,
  729. RefrsIntIter,
  730. BaseType->getCanonicalTypeInternal(),
  731. clang::VK_RValue,
  732. clang::OK_Ordinary,
  733. Loc);
  734. DataType DT = RSExportPrimitiveType::GetRSSpecificType(BaseType);
  735. clang::Stmt *RSSetObjectCall = nullptr;
  736. if (BaseType->isArrayType()) {
  737. RSSetObjectCall = CreateArrayRSSetObject(C, DstArrPtrSubscript,
  738. SrcArrPtrSubscript,
  739. StartLoc, Loc);
  740. } else if (DT == DataTypeUnknown) {
  741. RSSetObjectCall = CreateStructRSSetObject(C, DstArrPtrSubscript,
  742. SrcArrPtrSubscript,
  743. StartLoc, Loc);
  744. } else {
  745. RSSetObjectCall = CreateSingleRSSetObject(C, DstArrPtrSubscript,
  746. SrcArrPtrSubscript,
  747. StartLoc, Loc);
  748. }
  749. clang::ForStmt *DestructorLoop =
  750. new(C) clang::ForStmt(C,
  751. Init,
  752. Cond,
  753. nullptr, // no condVar
  754. Inc,
  755. RSSetObjectCall,
  756. Loc,
  757. Loc,
  758. Loc);
  759. StmtArray[StmtCtr++] = DestructorLoop;
  760. slangAssert(StmtCtr == 2);
  761. clang::CompoundStmt *CS =
  762. new(C) clang::CompoundStmt(C, StmtArray, StmtCtr, Loc, Loc);
  763. return CS;
  764. } */
  765. clang::Stmt *CreateStructRSSetObject(clang::ASTContext &C,
  766. clang::Expr *LHS,
  767. clang::Expr *RHS,
  768. clang::SourceLocation StartLoc,
  769. clang::SourceLocation Loc) {
  770. clang::QualType QT = LHS->getType();
  771. const clang::Type *T = QT.getTypePtr();
  772. slangAssert(T->isStructureType());
  773. slangAssert(!RSExportPrimitiveType::IsRSObjectType(T));
  774. // Keep an extra slot for the original copy (memcpy)
  775. unsigned FieldsToSet = CountRSObjectTypes(T) + 1;
  776. unsigned StmtCount = 0;
  777. clang::Stmt **StmtArray = new clang::Stmt*[FieldsToSet];
  778. for (unsigned i = 0; i < FieldsToSet; i++) {
  779. StmtArray[i] = nullptr;
  780. }
  781. clang::RecordDecl *RD = T->getAsStructureType()->getDecl();
  782. RD = RD->getDefinition();
  783. for (clang::RecordDecl::field_iterator FI = RD->field_begin(),
  784. FE = RD->field_end();
  785. FI != FE;
  786. FI++) {
  787. bool IsArrayType = false;
  788. clang::FieldDecl *FD = *FI;
  789. const clang::Type *FT = RSExportType::GetTypeOfDecl(FD);
  790. const clang::Type *OrigType = FT;
  791. if (!CountRSObjectTypes(FT)) {
  792. // Skip to next if we don't have any viable RS object types
  793. continue;
  794. }
  795. clang::DeclAccessPair FoundDecl =
  796. clang::DeclAccessPair::make(FD, clang::AS_none);
  797. clang::MemberExpr *DstMember =
  798. clang::MemberExpr::Create(C,
  799. LHS,
  800. false,
  801. clang::SourceLocation(),
  802. clang::NestedNameSpecifierLoc(),
  803. clang::SourceLocation(),
  804. FD,
  805. FoundDecl,
  806. clang::DeclarationNameInfo(
  807. FD->getDeclName(),
  808. clang::SourceLocation()),
  809. nullptr,
  810. OrigType->getCanonicalTypeInternal(),
  811. clang::VK_RValue,
  812. clang::OK_Ordinary);
  813. clang::MemberExpr *SrcMember =
  814. clang::MemberExpr::Create(C,
  815. RHS,
  816. false,
  817. clang::SourceLocation(),
  818. clang::NestedNameSpecifierLoc(),
  819. clang::SourceLocation(),
  820. FD,
  821. FoundDecl,
  822. clang::DeclarationNameInfo(
  823. FD->getDeclName(),
  824. clang::SourceLocation()),
  825. nullptr,
  826. OrigType->getCanonicalTypeInternal(),
  827. clang::VK_RValue,
  828. clang::OK_Ordinary);
  829. if (FT->isArrayType()) {
  830. FT = FT->getArrayElementTypeNoTypeQual();
  831. IsArrayType = true;
  832. }
  833. DataType DT = RSExportPrimitiveType::GetRSSpecificType(FT);
  834. if (IsArrayType) {
  835. clang::DiagnosticsEngine &DiagEngine = C.getDiagnostics();
  836. DiagEngine.Report(
  837. clang::FullSourceLoc(Loc, C.getSourceManager()),
  838. DiagEngine.getCustomDiagID(
  839. clang::DiagnosticsEngine::Error,
  840. "Arrays of RS object types within structures cannot be copied"));
  841. // TODO(srhines): Support setting arrays of RS objects
  842. // StmtArray[StmtCount++] =
  843. // CreateArrayRSSetObject(C, DstMember, SrcMember, StartLoc, Loc);
  844. } else if (DT == DataTypeUnknown) {
  845. StmtArray[StmtCount++] =
  846. CreateStructRSSetObject(C, DstMember, SrcMember, StartLoc, Loc);
  847. } else if (RSExportPrimitiveType::IsRSObjectType(DT)) {
  848. StmtArray[StmtCount++] =
  849. CreateSingleRSSetObject(C, DstMember, SrcMember, StartLoc, Loc);
  850. } else {
  851. slangAssert(false);
  852. }
  853. }
  854. slangAssert(StmtCount < FieldsToSet);
  855. // We still need to actually do the overall struct copy. For simplicity,
  856. // we just do a straight-up assignment (which will still preserve all
  857. // the proper RS object reference counts).
  858. clang::BinaryOperator *CopyStruct =
  859. new(C) clang::BinaryOperator(LHS, RHS, clang::BO_Assign, QT,
  860. clang::VK_RValue, clang::OK_Ordinary, Loc,
  861. false);
  862. StmtArray[StmtCount++] = CopyStruct;
  863. clang::CompoundStmt *CS = new(C) clang::CompoundStmt(
  864. C, llvm::makeArrayRef(StmtArray, StmtCount), Loc, Loc);
  865. delete [] StmtArray;
  866. return CS;
  867. }
  868. } // namespace
  869. void RSObjectRefCount::Scope::InsertStmt(const clang::ASTContext &C,
  870. clang::Stmt *NewStmt) {
  871. std::vector<clang::Stmt*> newBody;
  872. for (clang::Stmt* S1 : mCS->body()) {
  873. if (S1 == mCurrent) {
  874. newBody.push_back(NewStmt);
  875. }
  876. newBody.push_back(S1);
  877. }
  878. mCS->setStmts(C, newBody);
  879. }
  880. void RSObjectRefCount::Scope::ReplaceStmt(const clang::ASTContext &C,
  881. clang::Stmt *NewStmt) {
  882. std::vector<clang::Stmt*> newBody;
  883. for (clang::Stmt* S1 : mCS->body()) {
  884. if (S1 == mCurrent) {
  885. newBody.push_back(NewStmt);
  886. } else {
  887. newBody.push_back(S1);
  888. }
  889. }
  890. mCS->setStmts(C, newBody);
  891. }
  892. void RSObjectRefCount::Scope::ReplaceExpr(const clang::ASTContext& C,
  893. clang::Expr* OldExpr,
  894. clang::Expr* NewExpr) {
  895. RSASTReplace R(C);
  896. R.ReplaceStmt(mCurrent, OldExpr, NewExpr);
  897. }
  898. void RSObjectRefCount::Scope::ReplaceRSObjectAssignment(
  899. clang::BinaryOperator *AS) {
  900. clang::QualType QT = AS->getType();
  901. clang::ASTContext &C = RSObjectRefCount::GetRSSetObjectFD(
  902. DataTypeRSAllocation)->getASTContext();
  903. clang::SourceLocation Loc = AS->getExprLoc();
  904. clang::SourceLocation StartLoc = AS->getLHS()->getExprLoc();
  905. clang::Stmt *UpdatedStmt = nullptr;
  906. if (!RSExportPrimitiveType::IsRSObjectType(QT.getTypePtr())) {
  907. // By definition, this is a struct assignment if we get here
  908. UpdatedStmt =
  909. CreateStructRSSetObject(C, AS->getLHS(), AS->getRHS(), StartLoc, Loc);
  910. } else {
  911. UpdatedStmt =
  912. CreateSingleRSSetObject(C, AS->getLHS(), AS->getRHS(), StartLoc, Loc);
  913. }
  914. RSASTReplace R(C);
  915. R.ReplaceStmt(mCS, AS, UpdatedStmt);
  916. }
  917. void RSObjectRefCount::Scope::AppendRSObjectInit(
  918. clang::VarDecl *VD,
  919. clang::DeclStmt *DS,
  920. DataType DT,
  921. clang::Expr *InitExpr) {
  922. slangAssert(VD);
  923. if (!InitExpr) {
  924. return;
  925. }
  926. clang::ASTContext &C = RSObjectRefCount::GetRSSetObjectFD(
  927. DataTypeRSAllocation)->getASTContext();
  928. clang::SourceLocation Loc = RSObjectRefCount::GetRSSetObjectFD(
  929. DataTypeRSAllocation)->getLocation();
  930. clang::SourceLocation StartLoc = RSObjectRefCount::GetRSSetObjectFD(
  931. DataTypeRSAllocation)->getInnerLocStart();
  932. if (DT == DataTypeIsStruct) {
  933. const clang::Type *T = RSExportType::GetTypeOfDecl(VD);
  934. clang::DeclRefExpr *RefRSVar =
  935. clang::DeclRefExpr::Create(C,
  936. clang::NestedNameSpecifierLoc(),
  937. clang::SourceLocation(),
  938. VD,
  939. false,
  940. Loc,
  941. T->getCanonicalTypeInternal(),
  942. clang::VK_RValue,
  943. nullptr);
  944. clang::Stmt *RSSetObjectOps =
  945. CreateStructRSSetObject(C, RefRSVar, InitExpr, StartLoc, Loc);
  946. // Fix for b/37363420; consider:
  947. //
  948. // struct foo { rs_matrix m; };
  949. // void bar() {
  950. // struct foo M = {...};
  951. // }
  952. //
  953. // slang modifies that declaration with initialization to a
  954. // declaration plus an assignment of the initialization values.
  955. //
  956. // void bar() {
  957. // struct foo M = {};
  958. // M = {...}; // by CreateStructRSSetObject() above
  959. // }
  960. //
  961. // the slang-generated statement (M = {...}) is a use of M, and we
  962. // need to mark M (clang::VarDecl *VD) as used.
  963. VD->markUsed(C);
  964. std::list<clang::Stmt*> StmtList;
  965. StmtList.push_back(RSSetObjectOps);
  966. AppendAfterStmt(C, mCS, DS, StmtList);
  967. return;
  968. }
  969. clang::FunctionDecl *SetObjectFD = RSObjectRefCount::GetRSSetObjectFD(DT);
  970. slangAssert((SetObjectFD != nullptr) &&
  971. "rsSetObject doesn't cover all RS object types");
  972. clang::QualType SetObjectFDType = SetObjectFD->getType();
  973. clang::QualType SetObjectFDArgType[2];
  974. SetObjectFDArgType[0] = SetObjectFD->getParamDecl(0)->getOriginalType();
  975. SetObjectFDArgType[1] = SetObjectFD->getParamDecl(1)->getOriginalType();
  976. clang::Expr *RefRSSetObjectFD =
  977. clang::DeclRefExpr::Create(C,
  978. clang::NestedNameSpecifierLoc(),
  979. clang::SourceLocation(),
  980. SetObjectFD,
  981. false,
  982. Loc,
  983. SetObjectFDType,
  984. clang::VK_RValue,
  985. nullptr);
  986. clang::Expr *RSSetObjectFP =
  987. clang::ImplicitCastExpr::Create(C,
  988. C.getPointerType(SetObjectFDType),
  989. clang::CK_FunctionToPointerDecay,
  990. RefRSSetObjectFD,
  991. nullptr,
  992. clang::VK_RValue);
  993. const clang::Type *T = RSExportType::GetTypeOfDecl(VD);
  994. clang::DeclRefExpr *RefRSVar =
  995. clang::DeclRefExpr::Create(C,
  996. clang::NestedNameSpecifierLoc(),
  997. clang::SourceLocation(),
  998. VD,
  999. false,
  1000. Loc,
  1001. T->getCanonicalTypeInternal(),
  1002. clang::VK_RValue,
  1003. nullptr);
  1004. llvm::SmallVector<clang::Expr*, 2> ArgList;
  1005. ArgList.push_back(new(C) clang::UnaryOperator(RefRSVar,
  1006. clang::UO_AddrOf,
  1007. SetObjectFDArgType[0],
  1008. clang::VK_RValue,
  1009. clang::OK_Ordinary,
  1010. Loc));
  1011. ArgList.push_back(InitExpr);
  1012. clang::CallExpr *RSSetObjectCall =
  1013. new(C) clang::CallExpr(C,
  1014. RSSetObjectFP,
  1015. ArgList,
  1016. SetObjectFD->getCallResultType(),
  1017. clang::VK_RValue,
  1018. Loc);
  1019. std::list<clang::Stmt*> StmtList;
  1020. StmtList.push_back(RSSetObjectCall);
  1021. AppendAfterStmt(C, mCS, DS, StmtList);
  1022. }
  1023. void RSObjectRefCount::Scope::InsertLocalVarDestructors() {
  1024. if (mRSO.empty()) {
  1025. return;
  1026. }
  1027. clang::DeclContext* DC = mRSO.front()->getDeclContext();
  1028. clang::ASTContext& C = DC->getParentASTContext();
  1029. clang::SourceManager& SM = C.getSourceManager();
  1030. const auto& OccursBefore = [&SM] (clang::SourceLocation L1, clang::SourceLocation L2)->bool {
  1031. return SM.isBeforeInTranslationUnit(L1, L2);
  1032. };
  1033. typedef std::map<clang::SourceLocation, clang::Stmt*, decltype(OccursBefore)> DMap;
  1034. DMap dtors(OccursBefore);
  1035. // Create rsClearObject calls. Note the DMap entries are sorted by the SourceLocation.
  1036. for (clang::VarDecl* VD : mRSO) {
  1037. clang::SourceLocation Loc = VD->getSourceRange().getBegin();
  1038. clang::Stmt* RSClearObjectCall = ClearRSObject(VD, DC);
  1039. dtors.insert(std::make_pair(Loc, RSClearObjectCall));
  1040. }
  1041. DestructorVisitor Visitor;
  1042. Visitor.Visit(mCS);
  1043. // Replace each exiting statement with a block that contains the original statement
  1044. // and added rsClearObject() calls before it.
  1045. for (clang::Stmt* S : Visitor.getExitingStmts()) {
  1046. const clang::SourceLocation currentLoc = S->getLocStart();
  1047. DMap::iterator firstDtorIter = dtors.begin();
  1048. DMap::iterator currentDtorIter = firstDtorIter;
  1049. DMap::iterator lastDtorIter = dtors.end();
  1050. while (currentDtorIter != lastDtorIter &&
  1051. OccursBefore(currentDtorIter->first, currentLoc)) {
  1052. currentDtorIter++;
  1053. }
  1054. if (currentDtorIter == firstDtorIter) {
  1055. continue;
  1056. }
  1057. std::vector<clang::Stmt*> Stmts;
  1058. // Insert rsClearObject() calls for all rsObjects declared before the current statement
  1059. for(DMap::iterator it = firstDtorIter; it != currentDtorIter; it++) {
  1060. Stmts.push_back(it->second);
  1061. }
  1062. Stmts.push_back(S);
  1063. RSASTReplace R(C);
  1064. clang::CompoundStmt* CS = BuildCompoundStmt(C, Stmts, S->getLocEnd());
  1065. R.ReplaceStmt(mCS, S, CS);
  1066. }
  1067. std::list<clang::Stmt*> Stmts;
  1068. for(auto LocCallPair : dtors) {
  1069. Stmts.push_back(LocCallPair.second);
  1070. }
  1071. AppendAfterStmt(C, mCS, nullptr, Stmts);
  1072. }
  1073. clang::Stmt *RSObjectRefCount::Scope::ClearRSObject(
  1074. clang::VarDecl *VD,
  1075. clang::DeclContext *DC) {
  1076. slangAssert(VD);
  1077. clang::ASTContext &C = VD->getASTContext();
  1078. clang::SourceLocation Loc = VD->getLocation();
  1079. clang::SourceLocation StartLoc = VD->getInnerLocStart();
  1080. const clang::Type *T = RSExportType::GetTypeOfDecl(VD);
  1081. // Reference expr to target RS object variable
  1082. clang::DeclRefExpr *RefRSVar =
  1083. clang::DeclRefExpr::Create(C,
  1084. clang::NestedNameSpecifierLoc(),
  1085. clang::SourceLocation(),
  1086. VD,
  1087. false,
  1088. Loc,
  1089. T->getCanonicalTypeInternal(),
  1090. clang::VK_RValue,
  1091. nullptr);
  1092. if (T->isArrayType()) {
  1093. return ClearArrayRSObject(C, DC, RefRSVar, StartLoc, Loc);
  1094. }
  1095. DataType DT = RSExportPrimitiveType::GetRSSpecificType(T);
  1096. if (DT == DataTypeUnknown ||
  1097. DT == DataTypeIsStruct) {
  1098. return ClearStructRSObject(C, DC, RefRSVar, StartLoc, Loc);
  1099. }
  1100. slangAssert((RSExportPrimitiveType::IsRSObjectType(DT)) &&
  1101. "Should be RS object");
  1102. return ClearSingleRSObject(C, RefRSVar, Loc);
  1103. }
  1104. bool RSObjectRefCount::InitializeRSObject(clang::VarDecl *VD,
  1105. DataType *DT,
  1106. clang::Expr **InitExpr) {
  1107. slangAssert(VD && DT && InitExpr);
  1108. const clang::Type *T = RSExportType::GetTypeOfDecl(VD);
  1109. // Loop through array types to get to base type
  1110. slangAssert(T);
  1111. while (T->isArrayType()) {
  1112. T = T->getArrayElementTypeNoTypeQual();
  1113. slangAssert(T);
  1114. }
  1115. bool DataTypeIsStructWithRSObject = false;
  1116. *DT = RSExportPrimitiveType::GetRSSpecificType(T);
  1117. if (*DT == DataTypeUnknown) {
  1118. if (RSExportPrimitiveType::IsStructureTypeWithRSObject(T)) {
  1119. *DT = DataTypeIsStruct;
  1120. DataTypeIsStructWithRSObject = true;
  1121. } else {
  1122. return false;
  1123. }
  1124. }
  1125. bool DataTypeIsRSObject = false;
  1126. if (DataTypeIsStructWithRSObject) {
  1127. DataTypeIsRSObject = true;
  1128. } else {
  1129. DataTypeIsRSObject = RSExportPrimitiveType::IsRSObjectType(*DT);
  1130. }
  1131. *InitExpr = VD->getInit();
  1132. if (!DataTypeIsRSObject && *InitExpr) {
  1133. // If we already have an initializer for a matrix type, we are done.
  1134. return DataTypeIsRSObject;
  1135. }
  1136. clang::Expr *ZeroInitializer =
  1137. CreateEmptyInitListExpr(VD->getASTContext(), VD->getLocation());
  1138. if (ZeroInitializer) {
  1139. ZeroInitializer->setType(T->getCanonicalTypeInternal());
  1140. VD->setInit(ZeroInitializer);
  1141. }
  1142. return DataTypeIsRSObject;
  1143. }
  1144. clang::Expr *RSObjectRefCount::CreateEmptyInitListExpr(
  1145. clang::ASTContext &C,
  1146. const clang::SourceLocation &Loc) {
  1147. // We can cheaply construct a zero initializer by just creating an empty
  1148. // initializer list. Clang supports this extension to C(99), and will create
  1149. // any necessary constructs to zero out the entire variable.
  1150. llvm::SmallVector<clang::Expr*, 1> EmptyInitList;
  1151. return new(C) clang::InitListExpr(C, Loc, EmptyInitList, Loc);
  1152. }
  1153. clang::DeclRefExpr *RSObjectRefCount::CreateGuard(clang::ASTContext &C,
  1154. clang::DeclContext *DC,
  1155. clang::Expr *E,
  1156. const llvm::Twine &VarName,
  1157. std::vector<clang::Stmt*> &NewStmts) {
  1158. clang::SourceLocation Loc = E->getLocStart();
  1159. const clang::QualType Ty = E->getType();
  1160. clang::VarDecl* TmpDecl = clang::VarDecl::Create(
  1161. C, // AST context
  1162. DC, // Decl context
  1163. Loc, // Start location
  1164. Loc, // Id location
  1165. &C.Idents.get(VarName.str()), // Id
  1166. Ty, // Type
  1167. C.getTrivialTypeSourceInfo(Ty), // Type info
  1168. clang::SC_None // Storage class
  1169. );
  1170. const clang::Type *T = Ty.getTypePtr();
  1171. clang::Expr *ZeroInitializer =
  1172. RSObjectRefCount::CreateEmptyInitListExpr(C, Loc);
  1173. ZeroInitializer->setType(T->getCanonicalTypeInternal());
  1174. TmpDecl->setInit(ZeroInitializer);
  1175. TmpDecl->markUsed(C);
  1176. clang::Decl* Decls[] = { TmpDecl };
  1177. const clang::DeclGroupRef DGR = clang::DeclGroupRef::Create(
  1178. C, Decls, sizeof(Decls) / sizeof(*Decls));
  1179. clang::DeclStmt* DS = new (C) clang::DeclStmt(DGR, Loc, Loc);
  1180. NewStmts.push_back(DS);
  1181. clang::DeclRefExpr* DRE = clang::DeclRefExpr::Create(
  1182. C,
  1183. clang::NestedNameSpecifierLoc(), // QualifierLoc
  1184. Loc, // TemplateKWLoc
  1185. TmpDecl,
  1186. false, // RefersToEnclosingVariableOrCapture
  1187. Loc, // NameLoc
  1188. Ty,
  1189. clang::VK_LValue
  1190. );
  1191. clang::Stmt *UpdatedStmt = nullptr;
  1192. if (CountRSObjectTypes(Ty.getTypePtr()) == 0) {
  1193. // The expression E is not an RS object itself. Instead of calling
  1194. // rsSetObject(), create an assignment statement to set the value of the
  1195. // temporary "guard" variable to the expression.
  1196. // This can happen if called from RSObjectRefCount::VisitReturnStmt(),
  1197. // when the return expression is not an RS object but references one.
  1198. UpdatedStmt =
  1199. new(C) clang::BinaryOperator(DRE, E, clang::BO_Assign, Ty,
  1200. clang::VK_RValue, clang::OK_Ordinary, Loc,
  1201. false);
  1202. } else if (!RSExportPrimitiveType::IsRSObjectType(Ty.getTypePtr())) {
  1203. // By definition, this is a struct assignment if we get here
  1204. UpdatedStmt =
  1205. CreateStructRSSetObject(C, DRE, E, Loc, Loc);
  1206. } else {
  1207. UpdatedStmt =
  1208. CreateSingleRSSetObject(C, DRE, E, Loc, Loc);
  1209. }
  1210. NewStmts.push_back(UpdatedStmt);
  1211. return DRE;
  1212. }
  1213. void RSObjectRefCount::CreateParameterGuard(clang::ASTContext &C,
  1214. clang::DeclContext *DC,
  1215. clang::ParmVarDecl *PD,
  1216. std::vector<clang::Stmt*> &NewStmts) {
  1217. clang::SourceLocation Loc = PD->getLocStart();
  1218. clang::DeclRefExpr* ParamDRE = clang::DeclRefExpr::Create(
  1219. C,
  1220. clang::NestedNameSpecifierLoc(), // QualifierLoc
  1221. Loc, // TemplateKWLoc
  1222. PD,
  1223. false, // RefersToEnclosingVariableOrCapture
  1224. Loc, // NameLoc
  1225. PD->getType(),
  1226. clang::VK_RValue
  1227. );
  1228. CreateGuard(C, DC, ParamDRE,
  1229. llvm::Twine(".rs.param.") + llvm::Twine(PD->getName()), NewStmts);
  1230. }
  1231. void RSObjectRefCount::HandleParamsAndLocals(clang::FunctionDecl *FD) {
  1232. std::vector<clang::Stmt*> NewStmts;
  1233. std::list<clang::ParmVarDecl*> ObjParams;
  1234. for (clang::ParmVarDecl *Param : FD->parameters()) {
  1235. clang::QualType QT = Param->getType();
  1236. if (CountRSObjectTypes(QT.getTypePtr())) {
  1237. // Ignore non-object types
  1238. RSObjectRefCount::CreateParameterGuard(mCtx, FD, Param, NewStmts);
  1239. ObjParams.push_back(Param);
  1240. }
  1241. }
  1242. clang::Stmt *OldBody = FD->getBody();
  1243. if (ObjParams.empty()) {
  1244. Visit(OldBody);
  1245. return;
  1246. }
  1247. NewStmts.push_back(OldBody);
  1248. clang::SourceLocation Loc = FD->getLocStart();
  1249. clang::CompoundStmt *NewBody = BuildCompoundStmt(mCtx, NewStmts, Loc);
  1250. Scope S(NewBody);
  1251. for (clang::ParmVarDecl *Param : ObjParams) {
  1252. S.addRSObject(Param);
  1253. }
  1254. mScopeStack.push_back(&S);
  1255. // To avoid adding unnecessary ref counting artifacts to newly added temporary
  1256. // local variables for parameters, visits only the old function body here.
  1257. Visit(OldBody);
  1258. FD->setBody(NewBody);
  1259. S.InsertLocalVarDestructors();
  1260. mScopeStack.pop_back();
  1261. }
  1262. clang::CompoundStmt* RSObjectRefCount::CreateRetStmtWithTempVar(
  1263. clang::ASTContext& C,
  1264. clang::DeclContext* DC,
  1265. clang::ReturnStmt* RS,
  1266. const unsigned id) {
  1267. std::vector<clang::Stmt*> NewStmts;
  1268. // Since we insert rsClearObj() calls before the return statement, we need
  1269. // to make sure none of the cleared RS objects are referenced in the
  1270. // return statement.
  1271. // For that, we create a new local variable named .rs.retval, assign the
  1272. // original return expression to it, make all necessary rsClearObj()
  1273. // calls, then return .rs.retval. Note rsClearObj() is not called on
  1274. // .rs.retval.
  1275. clang::SourceLocation Loc = RS->getLocStart();
  1276. clang::Expr* RetVal = RS->getRetValue();
  1277. const clang::QualType RetTy = RetVal->getType();
  1278. clang::DeclRefExpr *DRE = CreateGuard(C, DC, RetVal,
  1279. llvm::Twine(".rs.retval") + llvm::Twine(id),
  1280. NewStmts);
  1281. // Creates a new return statement
  1282. clang::ReturnStmt* NewRet = new (C) clang::ReturnStmt(Loc);
  1283. clang::Expr* CastExpr = clang::ImplicitCastExpr::Create(
  1284. C,
  1285. RetTy,
  1286. clang::CK_LValueToRValue,
  1287. DRE,
  1288. nullptr,
  1289. clang::VK_RValue
  1290. );
  1291. NewRet->setRetValue(CastExpr);
  1292. NewStmts.push_back(NewRet);
  1293. return BuildCompoundStmt(C, NewStmts, Loc);
  1294. }
  1295. void RSObjectRefCount::VisitDeclStmt(clang::DeclStmt *DS) {
  1296. VisitStmt(DS);
  1297. getCurrentScope()->setCurrentStmt(DS);
  1298. for (clang::DeclStmt::decl_iterator I = DS->decl_begin(), E = DS->decl_end();
  1299. I != E;
  1300. I++) {
  1301. clang::Decl *D = *I;
  1302. if (D->getKind() == clang::Decl::Var) {
  1303. clang::VarDecl *VD = static_cast<clang::VarDecl*>(D);
  1304. DataType DT = DataTypeUnknown;
  1305. clang::Expr *InitExpr = nullptr;
  1306. if (InitializeRSObject(VD, &DT, &InitExpr)) {
  1307. // We need to zero-init all RS object types (including matrices), ...
  1308. getCurrentScope()->AppendRSObjectInit(VD, DS, DT, InitExpr);
  1309. // ... but, only add to the list of RS objects if we have some
  1310. // non-matrix RS object fields.
  1311. if (CountRSObjectTypes(VD->getType().getTypePtr())) {
  1312. getCurrentScope()->addRSObject(VD);
  1313. }
  1314. }
  1315. }
  1316. }
  1317. }
  1318. void RSObjectRefCount::VisitCallExpr(clang::CallExpr* CE) {
  1319. clang::QualType RetTy;
  1320. const clang::FunctionDecl* FD = CE->getDirectCallee();
  1321. if (FD) {
  1322. // Direct calls
  1323. RetTy = FD->getReturnType();
  1324. } else {
  1325. // Indirect calls through function pointers
  1326. const clang::Expr* Callee = CE->getCallee();
  1327. const clang::Type* CalleeType = Callee->getType().getTypePtr();
  1328. const clang::PointerType* PtrType = CalleeType->getAs<clang::PointerType>();
  1329. if (!PtrType) {
  1330. return;
  1331. }
  1332. const clang::Type* PointeeType = PtrType->getPointeeType().getTypePtr();
  1333. const clang::FunctionType* FuncType = PointeeType->getAs<clang::FunctionType>();
  1334. if (!FuncType) {
  1335. return;
  1336. }
  1337. RetTy = FuncType->getReturnType();
  1338. }
  1339. // The RenderScript runtime API maintains the invariant that the sysRef of a new RS object would
  1340. // be 1, with the exception of rsGetAllocation() (deprecated in API 22), which leaves the sysRef
  1341. // 0 for a new allocation. It is the responsibility of the callee of the API to decrement the
  1342. // sysRef when a reference of the RS object goes out of scope. The compiler generates code to do
  1343. // just that, by creating a temporary variable named ".rs.tmpN" with the result of
  1344. // an RS-object-returning API directly assigned to it, and calling rsClearObject() on .rs.tmpN
  1345. // right before it exits the current scope. Such code generation is skipped for rsGetAllocation()
  1346. // to avoid decrementing its sysRef below zero.
  1347. if (CountRSObjectTypes(RetTy.getTypePtr())==0 ||
  1348. (FD && FD->getName() == "rsGetAllocation")) {
  1349. return;
  1350. }
  1351. clang::SourceLocation Loc = CE->getSourceRange().getBegin();
  1352. std::stringstream ss;
  1353. ss << ".rs.tmp" << getNextID();
  1354. clang::IdentifierInfo *II = &mCtx.Idents.get(ss.str());
  1355. clang::VarDecl* TempVarDecl = clang::VarDecl::Create(
  1356. mCtx, // AST context
  1357. GetDeclContext(), // Decl context
  1358. Loc, // Start location
  1359. Loc, // Id location
  1360. II, // Id
  1361. RetTy, // Type
  1362. mCtx.getTrivialTypeSourceInfo(RetTy), // Type info
  1363. clang::SC_None // Storage class
  1364. );
  1365. TempVarDecl->setInit(CE);
  1366. TempVarDecl->markUsed(mCtx);
  1367. clang::Decl* Decls[] = { TempVarDecl };
  1368. const clang::DeclGroupRef DGR = clang::DeclGroupRef::Create(
  1369. mCtx, Decls, sizeof(Decls) / sizeof(*Decls));
  1370. clang::DeclStmt* DS = new (mCtx) clang::DeclStmt(DGR, Loc, Loc);
  1371. getCurrentScope()->InsertStmt(mCtx, DS);
  1372. clang::DeclRefExpr* DRE = clang::DeclRefExpr::Create(
  1373. mCtx, // AST context
  1374. clang::NestedNameSpecifierLoc(), // QualifierLoc
  1375. Loc, // TemplateKWLoc
  1376. TempVarDecl,
  1377. false, // RefersToEnclosingVariableOrCapture
  1378. Loc, // NameLoc
  1379. RetTy,
  1380. clang::VK_LValue
  1381. );
  1382. clang::Expr* CastExpr = clang::ImplicitCastExpr::Create(
  1383. mCtx,
  1384. RetTy,
  1385. clang::CK_LValueToRValue,
  1386. DRE,
  1387. nullptr,
  1388. clang::VK_RValue
  1389. );
  1390. getCurrentScope()->ReplaceExpr(mCtx, CE, CastExpr);
  1391. // Register TempVarDecl for destruction call (rsClearObj).
  1392. getCurrentScope()->addRSObject(TempVarDecl);
  1393. }
  1394. void RSObjectRefCount::VisitCompoundStmt(clang::CompoundStmt *CS) {
  1395. if (!emptyScope()) {
  1396. getCurrentScope()->setCurrentStmt(CS);
  1397. }
  1398. if (!CS->body_empty()) {
  1399. // Push a new scope
  1400. Scope *S = new Scope(CS);
  1401. mScopeStack.push_back(S);
  1402. VisitStmt(CS);
  1403. // Destroy the scope
  1404. slangAssert((getCurrentScope() == S) && "Corrupted scope stack!");
  1405. S->InsertLocalVarDestructors();
  1406. mScopeStack.pop_back();
  1407. delete S;
  1408. }
  1409. }
  1410. void RSObjectRefCount::VisitBinAssign(clang::BinaryOperator *AS) {
  1411. getCurrentScope()->setCurrentStmt(AS);
  1412. clang::QualType QT = AS->getType();
  1413. if (CountRSObjectTypes(QT.getTypePtr())) {
  1414. getCurrentScope()->ReplaceRSObjectAssignment(AS);
  1415. }
  1416. }
  1417. namespace {
  1418. class FindRSObjRefVisitor : public clang::RecursiveASTVisitor<FindRSObjRefVisitor> {
  1419. public:
  1420. explicit FindRSObjRefVisitor() : mRefRSObj(false) {}
  1421. bool VisitExpr(clang::Expr* Expression) {
  1422. if (CountRSObjectTypes(Expression->getType().getTypePtr()) > 0) {
  1423. mRefRSObj = true;
  1424. // Found a reference to an RS object. Stop the AST traversal.
  1425. return false;
  1426. }
  1427. return true;
  1428. }
  1429. bool foundRSObjRef() const { return mRefRSObj; }
  1430. private:
  1431. bool mRefRSObj;
  1432. };
  1433. } // anonymous namespace
  1434. void RSObjectRefCount::VisitReturnStmt(clang::ReturnStmt *RS) {
  1435. getCurrentScope()->setCurrentStmt(RS);
  1436. // If there is no local rsObject declared so far, no need to transform the
  1437. // return statement.
  1438. bool RSObjDeclared = false;
  1439. for (const Scope* S : mScopeStack) {
  1440. if (S->hasRSObject()) {
  1441. RSObjDeclared = true;
  1442. break;
  1443. }
  1444. }
  1445. if (!RSObjDeclared) {
  1446. return;
  1447. }
  1448. FindRSObjRefVisitor visitor;
  1449. visitor.TraverseStmt(RS);
  1450. // If the return statement does not return anything, or if it does not reference
  1451. // a rsObject, no need to transform it.
  1452. if (!visitor.foundRSObjRef()) {
  1453. return;
  1454. }
  1455. // Transform the return statement so that it does not potentially return or
  1456. // reference a rsObject that has been cleared.
  1457. clang::CompoundStmt* NewRS;
  1458. NewRS = CreateRetStmtWithTempVar(mCtx, GetDeclContext(), RS, getNextID());
  1459. getCurrentScope()->ReplaceStmt(mCtx, NewRS);
  1460. }
  1461. void RSObjectRefCount::VisitStmt(clang::Stmt *S) {
  1462. getCurrentScope()->setCurrentStmt(S);
  1463. for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end();
  1464. I != E;
  1465. I++) {
  1466. if (clang::Stmt *Child = *I) {
  1467. Visit(Child);
  1468. }
  1469. }
  1470. }
  1471. // This function walks the list of global variables and (potentially) creates
  1472. // a single global static destructor function that properly decrements
  1473. // reference counts on the contained RS object types.
  1474. clang::FunctionDecl *RSObjectRefCount::CreateStaticGlobalDtor() {
  1475. Init();
  1476. clang::DeclContext *DC = mCtx.getTranslationUnitDecl();
  1477. clang::SourceLocation loc;
  1478. llvm::StringRef SR(".rs.dtor");
  1479. clang::IdentifierInfo &II = mCtx.Idents.get(SR);
  1480. clang::DeclarationName N(&II);
  1481. clang::FunctionProtoType::ExtProtoInfo EPI;
  1482. clang::QualType T = mCtx.getFunctionType(mCtx.VoidTy,
  1483. llvm::ArrayRef<clang::QualType>(), EPI);
  1484. clang::FunctionDecl *FD = nullptr;
  1485. // Generate rsClearObject() call chains for every global variable
  1486. // (whether static or extern).
  1487. std::vector<clang::Stmt *> StmtList;
  1488. for (clang::DeclContext::decl_iterator I = DC->decls_begin(),
  1489. E = DC->decls_end(); I != E; I++) {
  1490. clang::VarDecl *VD = llvm::dyn_cast<clang::VarDecl>(*I);
  1491. if (VD) {
  1492. if (CountRSObjectTypes(VD->getType().getTypePtr())) {
  1493. if (!FD) {
  1494. // Only create FD if we are going to use it.
  1495. FD = clang::FunctionDecl::Create(mCtx, DC, loc, loc, N, T, nullptr,
  1496. clang::SC_None);
  1497. }
  1498. // Mark VD as used. It might be unused, except for the destructor.
  1499. // 'markUsed' has side-effects that are caused only if VD is not already
  1500. // used. Hence no need for an extra check here.
  1501. VD->markUsed(mCtx);
  1502. // Make sure to create any helpers within the function's DeclContext,
  1503. // not the one associated with the global translation unit.
  1504. clang::Stmt *RSClearObjectCall = Scope::ClearRSObject(VD, FD);
  1505. StmtList.push_back(RSClearObjectCall);
  1506. }
  1507. }
  1508. }
  1509. // Nothing needs to be destroyed, so don't emit a dtor.
  1510. if (StmtList.empty()) {
  1511. return nullptr;
  1512. }
  1513. clang::CompoundStmt *CS = BuildCompoundStmt(mCtx, StmtList, loc);
  1514. slangAssert(FD);
  1515. FD->setBody(CS);
  1516. // We need some way to tell if this FD is generated by slang
  1517. FD->setImplicit();
  1518. return FD;
  1519. }
  1520. bool HasRSObjectType(const clang::Type *T) {
  1521. return CountRSObjectTypes(T) != 0;
  1522. }
  1523. } // namespace slang