slang_rs_export_var.cpp revision d369cda199b11ae28a1935e06398c2162cf146f3
1/* 2 * Copyright 2010-2012, 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_export_var.h" 18 19#include "clang/AST/Type.h" 20 21#include "llvm/ADT/APSInt.h" 22 23#include "slang_rs_context.h" 24#include "slang_rs_export_type.h" 25 26namespace slang { 27 28namespace { 29 30static clang::DiagnosticBuilder ReportVarError(RSContext *Context, 31 const clang::SourceLocation Loc, 32 const char *Message) { 33 clang::DiagnosticsEngine *DiagEngine = Context->getDiagnostics(); 34 const clang::SourceManager *SM = Context->getSourceManager(); 35 return DiagEngine->Report(clang::FullSourceLoc(Loc, *SM), 36 DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, Message)); 37} 38 39} // namespace 40 41RSExportVar::RSExportVar(RSContext *Context, 42 const clang::VarDecl *VD, 43 const RSExportType *ET) 44 : RSExportable(Context, RSExportable::EX_VAR), 45 mName(VD->getName().data(), VD->getName().size()), 46 mET(ET), 47 mIsConst(false), 48 mArraySize(0), 49 mNumInits(0) { 50 // mInit - Evaluate initializer expression 51 const clang::Expr *Initializer = VD->getAnyInitializer(); 52 if (Initializer != NULL) { 53 switch (ET->getClass()) { 54 case RSExportType::ExportClassPrimitive: 55 case RSExportType::ExportClassVector: { 56 Initializer->EvaluateAsRValue(mInit, Context->getASTContext()); 57 break; 58 } 59 case RSExportType::ExportClassPointer: { 60 if (Initializer->isNullPointerConstant(Context->getASTContext(), 61 clang::Expr::NPC_ValueDependentIsNotNull)) { 62 mInit.Val = clang::APValue(llvm::APSInt(1)); 63 } else { 64 if (!Initializer->EvaluateAsRValue(mInit, Context->getASTContext())) { 65 ReportVarError(Context, Initializer->getExprLoc(), 66 "initializer is not an R-value"); 67 } 68 } 69 break; 70 } 71 case RSExportType::ExportClassConstantArray: { 72 const clang::InitListExpr *IList = 73 static_cast<const clang::InitListExpr*>(Initializer); 74 if (!IList) { 75 ReportVarError(Context, VD->getLocation(), 76 "Unable to find initializer list"); 77 break; 78 } 79 const RSExportConstantArrayType *ECAT = 80 static_cast<const RSExportConstantArrayType*>(ET); 81 mArraySize = ECAT->getSize(); 82 mNumInits = IList->getNumInits(); 83 for (unsigned int i = 0; i < mNumInits; i++) { 84 clang::Expr::EvalResult tempInit; 85 if (!IList->getInit(i)->EvaluateAsRValue(tempInit, 86 Context->getASTContext())) { 87 ReportVarError(Context, IList->getInit(i)->getExprLoc(), 88 "initializer is not an R-value"); 89 } 90 mInitArray.push_back(tempInit); 91 } 92 break; 93 } 94 case RSExportType::ExportClassMatrix: 95 case RSExportType::ExportClassRecord: { 96 ReportVarError(Context, VD->getLocation(), 97 "Reflection of initializer to variable '%0' (of type " 98 "'%1') is unsupported currently.") 99 << mName 100 << ET->getName(); 101 break; 102 } 103 default: { 104 slangAssert(false && "Unknown class of type"); 105 } 106 } 107 } 108 109 // mIsConst - Is it a constant? 110 clang::QualType QT = VD->getTypeSourceInfo()->getType(); 111 if (!QT.isNull()) { 112 mIsConst = QT.isConstQualified(); 113 } 114 115 return; 116} 117 118} // namespace slang 119