/*
 * Copyright 2010-2012, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "slang_rs_export_var.h"

#include "clang/AST/Type.h"

#include "llvm/ADT/APSInt.h"

#include "slang_rs_context.h"
#include "slang_rs_export_type.h"

namespace slang {

namespace {

static clang::DiagnosticBuilder ReportVarError(RSContext *Context,
                           const clang::SourceLocation Loc,
                           const char *Message) {
  clang::DiagnosticsEngine *DiagEngine = Context->getDiagnostics();
  const clang::SourceManager *SM = Context->getSourceManager();
  return DiagEngine->Report(clang::FullSourceLoc(Loc, *SM),
      DiagEngine->getCustomDiagID(clang::DiagnosticsEngine::Error, Message));
}

}  // namespace

RSExportVar::RSExportVar(RSContext *Context,
                         const clang::VarDecl *VD,
                         const RSExportType *ET)
    : RSExportable(Context, RSExportable::EX_VAR),
      mName(VD->getName().data(), VD->getName().size()),
      mET(ET),
      mIsConst(false),
      mArraySize(0),
      mNumInits(0) {
  // mInit - Evaluate initializer expression
  const clang::Expr *Initializer = VD->getAnyInitializer();
  if (Initializer != NULL) {
    switch (ET->getClass()) {
      case RSExportType::ExportClassPrimitive:
      case RSExportType::ExportClassVector: {
        Initializer->EvaluateAsRValue(mInit, Context->getASTContext());
        break;
      }
      case RSExportType::ExportClassPointer: {
        if (Initializer->isNullPointerConstant(Context->getASTContext(),
                clang::Expr::NPC_ValueDependentIsNotNull)) {
          mInit.Val = clang::APValue(llvm::APSInt(1));
        } else {
          if (!Initializer->EvaluateAsRValue(mInit, Context->getASTContext())) {
            ReportVarError(Context, Initializer->getExprLoc(),
                           "initializer is not an R-value");
          }
        }
        break;
      }
      case RSExportType::ExportClassConstantArray: {
        const clang::InitListExpr *IList =
            static_cast<const clang::InitListExpr*>(Initializer);
        if (!IList) {
          ReportVarError(Context, VD->getLocation(),
                         "Unable to find initializer list");
          break;
        }
        const RSExportConstantArrayType *ECAT =
            static_cast<const RSExportConstantArrayType*>(ET);
        mArraySize = ECAT->getSize();
        mNumInits = IList->getNumInits();
        for (unsigned int i = 0; i < mNumInits; i++) {
          clang::Expr::EvalResult tempInit;
          if (!IList->getInit(i)->EvaluateAsRValue(tempInit,
                                                   Context->getASTContext())) {
            ReportVarError(Context, IList->getInit(i)->getExprLoc(),
                           "initializer is not an R-value");
          }
          mInitArray.push_back(tempInit);
        }
        break;
      }
      case RSExportType::ExportClassMatrix:
      case RSExportType::ExportClassRecord: {
        ReportVarError(Context, VD->getLocation(),
                       "Reflection of initializer to variable '%0' (of type "
                       "'%1') is unsupported currently.")
            << mName
            << ET->getName();
        break;
      }
      default: {
        slangAssert(false && "Unknown class of type");
      }
    }
  }

  // mIsConst - Is it a constant?
  clang::QualType QT = VD->getTypeSourceInfo()->getType();
  if (!QT.isNull()) {
    mIsConst = QT.isConstQualified();
  }

  return;
}

}  // namespace slang
