From c202d2d64fe0172bcc3999b515a14d3d88532420 Mon Sep 17 00:00:00 2001 From: Stephen Hines Date: Wed, 26 Jan 2011 11:57:57 -0800 Subject: Replace RS object assignments with rsSetObject(). Reference counting works now for all scalar/array types. It still needs to be modified slightly to support structs, initializers and break/continue. Change-Id: I6e531df86508f261b784932fca930bc666cb0084 b: 3092382 --- slang_rs_object_ref_count.cpp | 99 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 96 insertions(+), 3 deletions(-) (limited to 'slang_rs_object_ref_count.cpp') diff --git a/slang_rs_object_ref_count.cpp b/slang_rs_object_ref_count.cpp index d2c088c..59ec672 100644 --- a/slang_rs_object_ref_count.cpp +++ b/slang_rs_object_ref_count.cpp @@ -142,6 +142,39 @@ static void AppendToCompoundStatement(clang::ASTContext& C, return; } +static void ReplaceinCompoundStmt(clang::ASTContext& C, + clang::CompoundStmt *CS, + clang::Stmt* OldStmt, + clang::Stmt* NewStmt) { + clang::CompoundStmt::body_iterator bI = CS->body_begin(); + + unsigned StmtCount = 0; + for (bI = CS->body_begin(); bI != CS->body_end(); bI++) { + StmtCount++; + } + + //OldStmt->dump(); + //NewStmt->dump(); + + clang::Stmt **UpdatedStmtList = new clang::Stmt*[StmtCount]; + + unsigned UpdatedStmtCount = 0; + for (bI = CS->body_begin(); bI != CS->body_end(); bI++) { + if (*bI == OldStmt) { + UpdatedStmtList[UpdatedStmtCount++] = NewStmt; + } else { + UpdatedStmtList[UpdatedStmtCount++] = *bI; + } + } + + CS->setStmts(C, UpdatedStmtList, UpdatedStmtCount); + + delete [] UpdatedStmtList; + + return; +} + + // This class visits a compound statement and inserts the StmtList containing // destructors in proper locations. This includes inserting them before any // return statement in any sub-block, at the end of the logical enclosing @@ -376,6 +409,61 @@ static clang::Stmt *ClearArrayRSObject(clang::VarDecl *VD, } // namespace +void RSObjectRefCount::Scope::ReplaceRSObjectAssignment( + clang::BinaryOperator *AS) { + + clang::QualType QT = AS->getType(); + RSExportPrimitiveType::DataType DT = + RSExportPrimitiveType::GetRSSpecificType(QT.getTypePtr()); + + clang::FunctionDecl *SetObjectFD = + RSSetObjectFD[(DT - RSExportPrimitiveType::FirstRSObjectType)]; + assert((SetObjectFD != NULL) && + "rsSetObject doesn't cover all RS object types"); + clang::ASTContext &C = SetObjectFD->getASTContext(); + + clang::QualType SetObjectFDType = SetObjectFD->getType(); + clang::QualType SetObjectFDArgType[2]; + SetObjectFDArgType[0] = SetObjectFD->getParamDecl(0)->getOriginalType(); + SetObjectFDArgType[1] = SetObjectFD->getParamDecl(1)->getOriginalType(); + + clang::SourceLocation Loc = SetObjectFD->getLocation(); + clang::Expr *RefRSSetObjectFD = + clang::DeclRefExpr::Create(C, + NULL, + SetObjectFD->getQualifierRange(), + SetObjectFD, + Loc, + SetObjectFDType); + + clang::Expr *RSSetObjectFP = + clang::ImplicitCastExpr::Create(C, + C.getPointerType(SetObjectFDType), + clang::CK_FunctionToPointerDecay, + RefRSSetObjectFD, + NULL, + clang::VK_RValue); + + clang::Expr *ArgList[2]; + ArgList[0] = new(C) clang::UnaryOperator(AS->getLHS(), + clang::UO_AddrOf, + SetObjectFDArgType[0], + Loc); + ArgList[1] = AS->getRHS(); + + clang::CallExpr *RSSetObjectCall = + new(C) clang::CallExpr(C, + RSSetObjectFP, + ArgList, + 2, + SetObjectFD->getCallResultType(), + Loc); + + ReplaceinCompoundStmt(C, mCS, AS, RSSetObjectCall); + + return; +} + void RSObjectRefCount::Scope::InsertLocalVarDestructors() { std::list RSClearObjectCalls; for (std::list::const_iterator I = mRSO.begin(), @@ -634,8 +722,6 @@ void RSObjectRefCount::VisitCompoundStmt(clang::CompoundStmt *CS) { VisitStmt(CS); // Destroy the scope - // TODO(srhines): Update reference count of the RS object refenced by - // getCurrentScope(). assert((getCurrentScope() == S) && "Corrupted scope stack!"); S->InsertLocalVarDestructors(); mScopeStack.pop(); @@ -645,7 +731,14 @@ void RSObjectRefCount::VisitCompoundStmt(clang::CompoundStmt *CS) { } void RSObjectRefCount::VisitBinAssign(clang::BinaryOperator *AS) { - // TODO(srhines): Update reference count + clang::QualType QT = AS->getType(); + RSExportPrimitiveType::DataType DT = + RSExportPrimitiveType::GetRSSpecificType(QT.getTypePtr()); + + if (RSExportPrimitiveType::IsRSObjectType(DT)) { + getCurrentScope()->ReplaceRSObjectAssignment(AS); + } + return; } -- cgit v1.2.3