slang_rs_object_ref_count.cpp revision 4b32ffdfc1ac766f8932e7effbcdf7484e804a8e
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 17#include "slang_rs_object_ref_count.h" 18 19#include "clang/AST/DeclGroup.h" 20#include "clang/AST/Expr.h" 21#include "clang/AST/OperationKinds.h" 22#include "clang/AST/Stmt.h" 23#include "clang/AST/StmtVisitor.h" 24 25#include "slang_rs.h" 26#include "slang_rs_export_type.h" 27 28using namespace slang; 29 30bool RSObjectRefCount::InitializeRSObject(clang::VarDecl *VD) { 31 const clang::Type *T = RSExportType::GetTypeOfDecl(VD); 32 RSExportPrimitiveType::DataType DT = 33 RSExportPrimitiveType::GetRSSpecificType(T); 34 35 if (DT == RSExportPrimitiveType::DataTypeUnknown) 36 return false; 37 38 if (VD->hasInit()) { 39 // TODO: Update the reference count of RS object in initializer. 40 // This can potentially be done as part of the assignment pass. 41 } else { 42 clang::Expr *ZeroInitializer = 43 CreateZeroInitializerForRSSpecificType(DT, 44 VD->getASTContext(), 45 VD->getLocation()); 46 47 if (ZeroInitializer) { 48 ZeroInitializer->setType(T->getCanonicalTypeInternal()); 49 VD->setInit(ZeroInitializer); 50 } 51 } 52 53 return RSExportPrimitiveType::IsRSObjectType(DT); 54} 55 56clang::Expr *RSObjectRefCount::CreateZeroInitializerForRSSpecificType( 57 RSExportPrimitiveType::DataType DT, 58 clang::ASTContext &C, 59 const clang::SourceLocation &Loc) { 60 clang::Expr *Res = NULL; 61 switch (DT) { 62 case RSExportPrimitiveType::DataTypeRSElement: 63 case RSExportPrimitiveType::DataTypeRSType: 64 case RSExportPrimitiveType::DataTypeRSAllocation: 65 case RSExportPrimitiveType::DataTypeRSSampler: 66 case RSExportPrimitiveType::DataTypeRSScript: 67 case RSExportPrimitiveType::DataTypeRSMesh: 68 case RSExportPrimitiveType::DataTypeRSProgramFragment: 69 case RSExportPrimitiveType::DataTypeRSProgramVertex: 70 case RSExportPrimitiveType::DataTypeRSProgramRaster: 71 case RSExportPrimitiveType::DataTypeRSProgramStore: 72 case RSExportPrimitiveType::DataTypeRSFont: { 73 // (ImplicitCastExpr 'nullptr_t' 74 // (IntegerLiteral 0))) 75 llvm::APInt Zero(C.getTypeSize(C.IntTy), 0); 76 clang::Expr *Int0 = clang::IntegerLiteral::Create(C, Zero, C.IntTy, Loc); 77 clang::Expr *CastToNull = 78 clang::ImplicitCastExpr::Create(C, 79 C.NullPtrTy, 80 clang::CK_IntegralToPointer, 81 Int0, 82 NULL, 83 clang::VK_RValue); 84 85 Res = new (C) clang::InitListExpr(C, Loc, &CastToNull, 1, Loc); 86 break; 87 } 88 case RSExportPrimitiveType::DataTypeRSMatrix2x2: 89 case RSExportPrimitiveType::DataTypeRSMatrix3x3: 90 case RSExportPrimitiveType::DataTypeRSMatrix4x4: { 91 // RS matrix is not completely an RS object. They hold data by themselves. 92 // (InitListExpr rs_matrix2x2 93 // (InitListExpr float[4] 94 // (FloatingLiteral 0) 95 // (FloatingLiteral 0) 96 // (FloatingLiteral 0) 97 // (FloatingLiteral 0))) 98 clang::QualType FloatTy = C.FloatTy; 99 // Constructor sets value to 0.0f by default 100 llvm::APFloat Val(C.getFloatTypeSemantics(FloatTy)); 101 clang::FloatingLiteral *Float0Val = 102 clang::FloatingLiteral::Create(C, 103 Val, 104 /* isExact = */true, 105 FloatTy, 106 Loc); 107 108 unsigned N = 0; 109 if (DT == RSExportPrimitiveType::DataTypeRSMatrix2x2) 110 N = 2; 111 else if (DT == RSExportPrimitiveType::DataTypeRSMatrix3x3) 112 N = 3; 113 else if (DT == RSExportPrimitiveType::DataTypeRSMatrix4x4) 114 N = 4; 115 116 // Directly allocate 16 elements instead of dynamically allocate N*N 117 clang::Expr *InitVals[16]; 118 for (unsigned i = 0; i < sizeof(InitVals) / sizeof(InitVals[0]); i++) 119 InitVals[i] = Float0Val; 120 clang::Expr *InitExpr = 121 new (C) clang::InitListExpr(C, Loc, InitVals, N * N, Loc); 122 InitExpr->setType(C.getConstantArrayType(FloatTy, 123 llvm::APInt(32, 4), 124 clang::ArrayType::Normal, 125 /* EltTypeQuals = */0)); 126 127 Res = new (C) clang::InitListExpr(C, Loc, &InitExpr, 1, Loc); 128 break; 129 } 130 case RSExportPrimitiveType::DataTypeUnknown: 131 case RSExportPrimitiveType::DataTypeFloat16: 132 case RSExportPrimitiveType::DataTypeFloat32: 133 case RSExportPrimitiveType::DataTypeFloat64: 134 case RSExportPrimitiveType::DataTypeSigned8: 135 case RSExportPrimitiveType::DataTypeSigned16: 136 case RSExportPrimitiveType::DataTypeSigned32: 137 case RSExportPrimitiveType::DataTypeSigned64: 138 case RSExportPrimitiveType::DataTypeUnsigned8: 139 case RSExportPrimitiveType::DataTypeUnsigned16: 140 case RSExportPrimitiveType::DataTypeUnsigned32: 141 case RSExportPrimitiveType::DataTypeUnsigned64: 142 case RSExportPrimitiveType::DataTypeBoolean: 143 case RSExportPrimitiveType::DataTypeUnsigned565: 144 case RSExportPrimitiveType::DataTypeUnsigned5551: 145 case RSExportPrimitiveType::DataTypeUnsigned4444: 146 case RSExportPrimitiveType::DataTypeMax: { 147 assert(false && "Not RS object type!"); 148 } 149 // No default case will enable compiler detecting the missing cases 150 } 151 152 return Res; 153} 154 155void RSObjectRefCount::VisitDeclStmt(clang::DeclStmt *DS) { 156 for (clang::DeclStmt::decl_iterator I = DS->decl_begin(), E = DS->decl_end(); 157 I != E; 158 I++) { 159 clang::Decl *D = *I; 160 if (D->getKind() == clang::Decl::Var) { 161 clang::VarDecl *VD = static_cast<clang::VarDecl*>(D); 162 if (InitializeRSObject(VD)) 163 getCurrentScope()->addRSObject(VD); 164 } 165 } 166 return; 167} 168 169void RSObjectRefCount::VisitCompoundStmt(clang::CompoundStmt *CS) { 170 if (!CS->body_empty()) { 171 // Push a new scope 172 Scope *S = new Scope(CS); 173 mScopeStack.push(S); 174 175 VisitStmt(CS); 176 177 // Destroy the scope 178 // TODO: Update reference count of the RS object refenced by 179 // getCurrentScope(). 180 assert((getCurrentScope() == S) && "Corrupted scope stack!"); 181 mScopeStack.pop(); 182 delete S; 183 } 184 return; 185} 186 187void RSObjectRefCount::VisitBinAssign(clang::BinaryOperator *AS) { 188 // TODO: Update reference count 189 return; 190} 191 192void RSObjectRefCount::VisitStmt(clang::Stmt *S) { 193 for (clang::Stmt::child_iterator I = S->child_begin(), E = S->child_end(); 194 I != E; 195 I++) { 196 if (clang::Stmt *Child = *I) { 197 Visit(Child); 198 } 199 } 200 return; 201} 202 203