slang_rs_export_var.cpp revision 1f6c331d622ac645ab68a016aa4c577998547373
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 mIsUnsigned(false), 49 mArraySize(0), 50 mNumInits(0) { 51 // mInit - Evaluate initializer expression 52 const clang::Expr *Initializer = VD->getAnyInitializer(); 53 if (Initializer != NULL) { 54 switch (ET->getClass()) { 55 case RSExportType::ExportClassPrimitive: 56 case RSExportType::ExportClassVector: { 57 Initializer->EvaluateAsRValue(mInit, Context->getASTContext()); 58 break; 59 } 60 case RSExportType::ExportClassPointer: { 61 if (Initializer->isNullPointerConstant(Context->getASTContext(), 62 clang::Expr::NPC_ValueDependentIsNotNull)) { 63 mInit.Val = clang::APValue(llvm::APSInt(1)); 64 } else { 65 if (!Initializer->EvaluateAsRValue(mInit, Context->getASTContext())) { 66 ReportVarError(Context, Initializer->getExprLoc(), 67 "initializer is not an R-value"); 68 } 69 } 70 break; 71 } 72 case RSExportType::ExportClassConstantArray: { 73 const clang::InitListExpr *IList = 74 static_cast<const clang::InitListExpr*>(Initializer); 75 if (!IList) { 76 ReportVarError(Context, VD->getLocation(), 77 "Unable to find initializer list"); 78 break; 79 } 80 const RSExportConstantArrayType *ECAT = 81 static_cast<const RSExportConstantArrayType*>(ET); 82 mArraySize = ECAT->getSize(); 83 mNumInits = IList->getNumInits(); 84 for (unsigned int i = 0; i < mNumInits; i++) { 85 clang::Expr::EvalResult tempInit; 86 if (!IList->getInit(i)->EvaluateAsRValue(tempInit, 87 Context->getASTContext())) { 88 ReportVarError(Context, IList->getInit(i)->getExprLoc(), 89 "initializer is not an R-value"); 90 } 91 mInitArray.push_back(tempInit); 92 } 93 break; 94 } 95 case RSExportType::ExportClassMatrix: 96 case RSExportType::ExportClassRecord: { 97 ReportVarError(Context, VD->getLocation(), 98 "Reflection of initializer to variable '%0' (of type " 99 "'%1') is unsupported currently.") 100 << mName 101 << ET->getName(); 102 break; 103 } 104 default: { 105 slangAssert(false && "Unknown class of type"); 106 } 107 } 108 } 109 110 clang::QualType QT = VD->getTypeSourceInfo()->getType(); 111 if (!QT.isNull()) { 112 mIsConst = QT.isConstQualified(); 113 mIsUnsigned = QT->hasUnsignedIntegerRepresentation(); 114 if (QT == Context->getASTContext().BoolTy) { 115 mIsUnsigned = false; 116 } 117 } 118 119 return; 120} 121 122} // namespace slang 123