1c383a500aa59423264811be3874461bf8adbfea0Zonr Chang/* 2d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines * Copyright 2010-2012, The Android Open Source Project 3c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 4c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Licensed under the Apache License, Version 2.0 (the "License"); 5c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * you may not use this file except in compliance with the License. 6c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * You may obtain a copy of the License at 7c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 8c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * http://www.apache.org/licenses/LICENSE-2.0 9c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * 10c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * Unless required by applicable law or agreed to in writing, software 11c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * distributed under the License is distributed on an "AS IS" BASIS, 12c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * See the License for the specific language governing permissions and 14c383a500aa59423264811be3874461bf8adbfea0Zonr Chang * limitations under the License. 15c383a500aa59423264811be3874461bf8adbfea0Zonr Chang */ 16c383a500aa59423264811be3874461bf8adbfea0Zonr Chang 176315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_var.h" 18462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 19e37f7d349704bdd8c94afad7c6021561787ec5c9Shih-wei Liao#include "clang/AST/ASTContext.h" 209ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao#include "clang/AST/Type.h" 21462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 22e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines#include "llvm/ADT/APSInt.h" 23e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 246315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_context.h" 256315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr#include "slang_rs_export_type.h" 266315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr 27e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hinesnamespace slang { 28462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao 29d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hinesnamespace { 30d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines 31d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hinesstatic clang::DiagnosticBuilder ReportVarError(RSContext *Context, 32d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines const clang::SourceLocation Loc, 33d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines const char *Message) { 34d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines clang::DiagnosticsEngine *DiagEngine = Context->getDiagnostics(); 35d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines const clang::SourceManager *SM = Context->getSourceManager(); 36d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines return DiagEngine->Report(clang::FullSourceLoc(Loc, *SM), 37d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, Message)); 38d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines} 39d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines 40d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines} // namespace 41d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines 429ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportVar::RSExportVar(RSContext *Context, 439ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::VarDecl *VD, 446315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr const RSExportType *ET) 45a41ce1d98094da84643995d40d71c529905123fcZonr Chang : RSExportable(Context, RSExportable::EX_VAR), 466315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr mName(VD->getName().data(), VD->getName().size()), 476315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr mET(ET), 48d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines mIsConst(false), 491f6c331d622ac645ab68a016aa4c577998547373Stephen Hines mIsUnsigned(false), 50d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines mArraySize(0), 51d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines mNumInits(0) { 529ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao // mInit - Evaluate initializer expression 539ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao const clang::Expr *Initializer = VD->getAnyInitializer(); 549ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao if (Initializer != NULL) { 559ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao switch (ET->getClass()) { 56324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao case RSExportType::ExportClassPrimitive: 579ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case RSExportType::ExportClassVector: { 584c622e0953afe3dca4da0aee364a811f3ccb61d9Stephen Hines Initializer->EvaluateAsRValue(mInit, Context->getASTContext()); 59324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao break; 609ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 619ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case RSExportType::ExportClassPointer: { 62d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines if (Initializer->isNullPointerConstant(Context->getASTContext(), 63d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines clang::Expr::NPC_ValueDependentIsNotNull)) { 649ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao mInit.Val = clang::APValue(llvm::APSInt(1)); 65d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines } else { 66d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines if (!Initializer->EvaluateAsRValue(mInit, Context->getASTContext())) { 67d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines ReportVarError(Context, Initializer->getExprLoc(), 68d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines "initializer is not an R-value"); 69d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines } 70d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines } 71d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines break; 72d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines } 73d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines case RSExportType::ExportClassConstantArray: { 74e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines const clang::InitListExpr *IList = 75d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines static_cast<const clang::InitListExpr*>(Initializer); 76d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines if (!IList) { 77d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines ReportVarError(Context, VD->getLocation(), 78d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines "Unable to find initializer list"); 79d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines break; 80d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines } 81d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines const RSExportConstantArrayType *ECAT = 82d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines static_cast<const RSExportConstantArrayType*>(ET); 83d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines mArraySize = ECAT->getSize(); 84d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines mNumInits = IList->getNumInits(); 85d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines for (unsigned int i = 0; i < mNumInits; i++) { 86d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines clang::Expr::EvalResult tempInit; 87d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines if (!IList->getInit(i)->EvaluateAsRValue(tempInit, 88d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines Context->getASTContext())) { 89d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines ReportVarError(Context, IList->getInit(i)->getExprLoc(), 90d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines "initializer is not an R-value"); 91d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines } 92d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines mInitArray.push_back(tempInit); 93d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines } 94324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao break; 959ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 96d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines case RSExportType::ExportClassMatrix: 979ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao case RSExportType::ExportClassRecord: { 98d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines ReportVarError(Context, VD->getLocation(), 99d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines "Reflection of initializer to variable '%0' (of type " 100d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines "'%1') is unsupported currently.") 101d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines << mName 102d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines << ET->getName(); 103324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao break; 1049ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 1059ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao default: { 1066e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines slangAssert(false && "Unknown class of type"); 1079ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao } 108324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao } 10981c1b4865e9c8fd655ea4528814f6c53e225ba6dShih-wei Liao } 11081c1b4865e9c8fd655ea4528814f6c53e225ba6dShih-wei Liao 1119ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao clang::QualType QT = VD->getTypeSourceInfo()->getType(); 11281c1b4865e9c8fd655ea4528814f6c53e225ba6dShih-wei Liao if (!QT.isNull()) { 11381c1b4865e9c8fd655ea4528814f6c53e225ba6dShih-wei Liao mIsConst = QT.isConstQualified(); 1141f6c331d622ac645ab68a016aa4c577998547373Stephen Hines mIsUnsigned = QT->hasUnsignedIntegerRepresentation(); 1151f6c331d622ac645ab68a016aa4c577998547373Stephen Hines if (QT == Context->getASTContext().BoolTy) { 1161f6c331d622ac645ab68a016aa4c577998547373Stephen Hines mIsUnsigned = false; 1171f6c331d622ac645ab68a016aa4c577998547373Stephen Hines } 11881c1b4865e9c8fd655ea4528814f6c53e225ba6dShih-wei Liao } 1199ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao 120324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao return; 121462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao} 122e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines 123e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines} // namespace slang 124