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
299ef2f785e0cc490af678dfd685995dec787321ffShih-wei LiaoRSExportVar::RSExportVar(RSContext *Context,
309ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao                         const clang::VarDecl *VD,
316315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr                         const RSExportType *ET)
32a41ce1d98094da84643995d40d71c529905123fcZonr Chang    : RSExportable(Context, RSExportable::EX_VAR),
336315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      mName(VD->getName().data(), VD->getName().size()),
346315f76e3cc6ff2d012d1183a0b030d4ff0dc808zonr      mET(ET),
35d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines      mIsConst(false),
361f6c331d622ac645ab68a016aa4c577998547373Stephen Hines      mIsUnsigned(false),
37d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines      mArraySize(0),
38d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines      mNumInits(0) {
399ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  // mInit - Evaluate initializer expression
409ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  const clang::Expr *Initializer = VD->getAnyInitializer();
419ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  if (Initializer != NULL) {
429ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao    switch (ET->getClass()) {
43324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao      case RSExportType::ExportClassPrimitive:
449ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      case RSExportType::ExportClassVector: {
454c622e0953afe3dca4da0aee364a811f3ccb61d9Stephen Hines        Initializer->EvaluateAsRValue(mInit, Context->getASTContext());
46324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao        break;
479ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
489ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      case RSExportType::ExportClassPointer: {
49d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines        if (Initializer->isNullPointerConstant(Context->getASTContext(),
50d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines                clang::Expr::NPC_ValueDependentIsNotNull)) {
519ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao          mInit.Val = clang::APValue(llvm::APSInt(1));
52d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines        } else {
53d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines          if (!Initializer->EvaluateAsRValue(mInit, Context->getASTContext())) {
54d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet            Context->ReportError(Initializer->getExprLoc(),
55d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet                                 "initializer is not an R-value");
56d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines          }
57d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines        }
58d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines        break;
59d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines      }
60d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines      case RSExportType::ExportClassConstantArray: {
61e67239de8d94975e7e2216ee6860ae2e6cb8b15aStephen Hines        const clang::InitListExpr *IList =
62d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines            static_cast<const clang::InitListExpr*>(Initializer);
63d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines        if (!IList) {
64d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet          Context->ReportError(VD->getLocation(),
65d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet                               "Unable to find initializer list");
66d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines          break;
67d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines        }
68d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines        const RSExportConstantArrayType *ECAT =
69d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines            static_cast<const RSExportConstantArrayType*>(ET);
70d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines        mArraySize = ECAT->getSize();
71d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines        mNumInits = IList->getNumInits();
72d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines        for (unsigned int i = 0; i < mNumInits; i++) {
73d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines          clang::Expr::EvalResult tempInit;
74d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines          if (!IList->getInit(i)->EvaluateAsRValue(tempInit,
75d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines                                                   Context->getASTContext())) {
76d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet            Context->ReportError(IList->getInit(i)->getExprLoc(),
77d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet                                 "initializer is not an R-value");
78d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines          }
79d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines          mInitArray.push_back(tempInit);
80d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines        }
81324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao        break;
829ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
83d369cda199b11ae28a1935e06398c2162cf146f3Stephen Hines      case RSExportType::ExportClassMatrix:
849ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      case RSExportType::ExportClassRecord: {
85d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet        Context->ReportError(
86d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet            VD->getLocation(),
87d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet            "Reflection of initializer to variable '%0' (of type "
88d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet            "'%1') is unsupported currently.")
89d3f7527b105d21f1c69d3473eb88a762f2c3ab5aJean-Luc Brouillet            << mName << ET->getName();
90324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao        break;
919ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
929ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      default: {
936e6578a360497f78a181e63d7783422a9c9bfb15Stephen Hines        slangAssert(false && "Unknown class of type");
949ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao      }
95324c0479ec3edda573de60b2e6476507a99d06f7Shih-wei Liao    }
9681c1b4865e9c8fd655ea4528814f6c53e225ba6dShih-wei Liao  }
9781c1b4865e9c8fd655ea4528814f6c53e225ba6dShih-wei Liao
989ef2f785e0cc490af678dfd685995dec787321ffShih-wei Liao  clang::QualType QT = VD->getTypeSourceInfo()->getType();
9981c1b4865e9c8fd655ea4528814f6c53e225ba6dShih-wei Liao  if (!QT.isNull()) {
10081c1b4865e9c8fd655ea4528814f6c53e225ba6dShih-wei Liao    mIsConst = QT.isConstQualified();
1011f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    mIsUnsigned = QT->hasUnsignedIntegerRepresentation();
1021f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    if (QT == Context->getASTContext().BoolTy) {
1031f6c331d622ac645ab68a016aa4c577998547373Stephen Hines      mIsUnsigned = false;
1041f6c331d622ac645ab68a016aa4c577998547373Stephen Hines    }
10581c1b4865e9c8fd655ea4528814f6c53e225ba6dShih-wei Liao  }
106462aefd62cc646d2ff753c1d003ef3cd7bbea26Shih-wei Liao}
107e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines
108e639eb5caa2c386b4a60659a4929e8a6141a2cbeStephen Hines}  // namespace slang
109