/*
 * Copyright 2015, 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_reduce.h"

#include <algorithm>
#include <sstream>
#include <string>

#include "clang/AST/ASTContext.h"

#include "slang_assert.h"
#include "slang_rs_context.h"
#include "slang_rs_export_type.h"
#include "slang_rs_object_ref_count.h"
#include "slang_rs_special_kernel_param.h"
#include "slang_version.h"

#include "bcinfo/MetadataExtractor.h"

namespace slang {

const char RSExportReduce::KeyReduce[] = "reduce";
const char RSExportReduce::KeyInitializer[] = "initializer";
const char RSExportReduce::KeyAccumulator[] = "accumulator";
const char RSExportReduce::KeyCombiner[] = "combiner";
const char RSExportReduce::KeyOutConverter[] = "outconverter";
const char RSExportReduce::KeyHalter[] = "halter";

bool RSExportReduce::matchName(const llvm::StringRef &Candidate) const {
  return
      Candidate.equals(mNameInitializer)  ||
      Candidate.equals(mNameAccumulator)  ||
      Candidate.equals(mNameCombiner)     ||
      Candidate.equals(mNameOutConverter) ||
      Candidate.equals(mNameHalter);
}

RSExportReduce *RSExportReduce::Create(RSContext *Context,
                                       const clang::SourceLocation Location,
                                       const llvm::StringRef &NameReduce,
                                       const llvm::StringRef &NameInitializer,
                                       const llvm::StringRef &NameAccumulator,
                                       const llvm::StringRef &NameCombiner,
                                       const llvm::StringRef &NameOutConverter,
                                       const llvm::StringRef &NameHalter) {
  slangAssert(Context);
  RSExportReduce *RNE = new RSExportReduce(Context,
                                           Location,
                                           NameReduce,
                                           NameInitializer,
                                           NameAccumulator,
                                           NameCombiner,
                                           NameOutConverter,
                                           NameHalter);

  return RNE;
}

const char *RSExportReduce::getKey(FnIdent Kind) {
  switch (Kind) {
    default:
      slangAssert(!"Unknown FnIdent");
      // and fall through
    case FN_IDENT_INITIALIZER:
      return KeyInitializer;
    case FN_IDENT_ACCUMULATOR:
      return KeyAccumulator;
    case FN_IDENT_COMBINER:
      return KeyCombiner;
    case FN_IDENT_OUT_CONVERTER:
      return KeyOutConverter;
    case FN_IDENT_HALTER:
      return KeyHalter;
  }
}

// This data is needed during analyzeTranslationUnit() but not afterwards.
// Breaking it out into a struct makes it easy for analyzeTranslationUnit()
// to call a number of helper functions that all need access to this data.
struct RSExportReduce::StateOfAnalyzeTranslationUnit {

  typedef std::function<std::string (const char *Key, const std::string &Name)> DiagnosticDescriptionType;

  StateOfAnalyzeTranslationUnit(
      RSContext &anRSContext,
      clang::Preprocessor &aPP,
      clang::ASTContext &anASTContext,
      const DiagnosticDescriptionType &aDiagnosticDescription) :

      RSC(anRSContext),
      PP(aPP),
      ASTC(anASTContext),
      DiagnosticDescription(aDiagnosticDescription),

      Ok(true),

      FnInitializer(nullptr),
      FnAccumulator(nullptr),
      FnCombiner(nullptr),
      FnOutConverter(nullptr),
      FnHalter(nullptr),

      FnInitializerParam(nullptr),
      FnInitializerParamTy(),

      FnAccumulatorOk(true),
      FnAccumulatorParamFirst(nullptr),
      FnAccumulatorParamFirstTy(),
      FnAccumulatorIndexOfFirstSpecialParameter(0),

      FnOutConverterOk(true),
      FnOutConverterParamFirst(nullptr),
      FnOutConverterParamFirstTy()
  { }

  /*-- Convenience ------------------------------------------*/

  RSContext                       &RSC;
  clang::Preprocessor             &PP;
  clang::ASTContext               &ASTC;
  const DiagnosticDescriptionType  DiagnosticDescription;

  /*-- Actual state -----------------------------------------*/

  bool Ok;

  clang::FunctionDecl *FnInitializer;
  clang::FunctionDecl *FnAccumulator;
  clang::FunctionDecl *FnCombiner;
  clang::FunctionDecl *FnOutConverter;
  clang::FunctionDecl *FnHalter;

  clang::ParmVarDecl  *FnInitializerParam;
  clang::QualType      FnInitializerParamTy;

  bool                 FnAccumulatorOk;
  clang::ParmVarDecl  *FnAccumulatorParamFirst;
  clang::QualType      FnAccumulatorParamFirstTy;
  size_t               FnAccumulatorIndexOfFirstSpecialParameter;

  bool                 FnOutConverterOk;  // also true if no outconverter
  clang::ParmVarDecl  *FnOutConverterParamFirst;
  clang::QualType      FnOutConverterParamFirstTy;
};

// does update S.Ok
clang::FunctionDecl *RSExportReduce::lookupFunction(StateOfAnalyzeTranslationUnit &S,
                                                    const char *Kind, const llvm::StringRef &Name) {
  if (Name.empty())
    return nullptr;

  clang::TranslationUnitDecl *TUDecl = getRSContext()->getASTContext().getTranslationUnitDecl();
  slangAssert(TUDecl);

  clang::FunctionDecl *Ret = nullptr;
  const clang::IdentifierInfo *II = S.PP.getIdentifierInfo(Name);
  if (II) {
    for (auto Decl : TUDecl->lookup(II)) {
      clang::FunctionDecl *FDecl = Decl->getAsFunction();
      if (!FDecl || !FDecl->isThisDeclarationADefinition())
        continue;
      if (Ret) {
        S.RSC.ReportError(mLocation,
                          "duplicate function definition for '%0(%1)' for '#pragma rs %2(%3)' (%4, %5)")
            << Kind << Name << KeyReduce << mNameReduce
            << Ret->getLocation().printToString(S.PP.getSourceManager())
            << FDecl->getLocation().printToString(S.PP.getSourceManager());
        S.Ok = false;
        return nullptr;
      }
      Ret = FDecl;
    }
  }
  if (!Ret) {
    // Either the identifier lookup failed, or we never found the function definition.
    S.RSC.ReportError(mLocation,
                      "could not find function definition for '%0(%1)' for '#pragma rs %2(%3)'")
        << Kind << Name << KeyReduce << mNameReduce;
    S.Ok = false;
    return nullptr;
  }
  if (Ret) {
    // Must have internal linkage
    if (Ret->getFormalLinkage() != clang::InternalLinkage) {
      S.RSC.ReportError(Ret->getLocation(), "%0 must be static")
          << S.DiagnosticDescription(Kind, Name);
      S.Ok = false;
    }
  }
  if (Ret == nullptr)
    S.Ok = false;
  return Ret;
}

// updates S.Ok; and, depending on Kind, possibly S.FnAccumulatorOk or S.FnOutConverterOk
void RSExportReduce::notOk(StateOfAnalyzeTranslationUnit &S, FnIdent Kind) {
    S.Ok = false;
    if (Kind == FN_IDENT_ACCUMULATOR) {
      S.FnAccumulatorOk = false;
    } else if (Kind == FN_IDENT_OUT_CONVERTER) {
      S.FnOutConverterOk = false;
    }
}

// updates S.Ok; and, depending on Kind, possibly S.FnAccumulatorOk or S.FnOutConverterOk
void RSExportReduce::checkVoidReturn(StateOfAnalyzeTranslationUnit &S,
                                     FnIdent Kind, clang::FunctionDecl *Fn) {
  slangAssert(Fn);
  const clang::QualType ReturnTy = Fn->getReturnType().getCanonicalType();
  if (!ReturnTy->isVoidType()) {
    S.RSC.ReportError(Fn->getLocation(),
                      "%0 must return void not '%1'")
        << S.DiagnosticDescription(getKey(Kind), Fn->getName()) << ReturnTy.getAsString();
    notOk(S, Kind);
  }
}

// updates S.Ok; and, depending on Kind, possibly S.FnAccumulatorOk or S.FnOutConverterOk
void RSExportReduce::checkPointeeConstQualified(StateOfAnalyzeTranslationUnit &S,
                                                FnIdent Kind, const llvm::StringRef &Name,
                                                const clang::ParmVarDecl *Param, bool ExpectedQualification) {
  const clang::QualType ParamQType = Param->getType();
  slangAssert(ParamQType->isPointerType());
  const clang::QualType PointeeQType = ParamQType->getPointeeType();
  if (PointeeQType.isConstQualified() != ExpectedQualification) {
    S.RSC.ReportError(Param->getLocation(),
                      "%0 parameter '%1' (type '%2') must%3 point to const-qualified type")
        << S.DiagnosticDescription(getKey(Kind), Name)
        << Param->getName() << ParamQType.getAsString()
        << (ExpectedQualification ? "" : " not");
    notOk(S, Kind);
  }
}

// Process "void mNameInitializer(compType *accum)"
void RSExportReduce::analyzeInitializer(StateOfAnalyzeTranslationUnit &S) {
  if (!S.FnInitializer) // initializer is always optional
    return;

  // Must return void
  checkVoidReturn(S, FN_IDENT_INITIALIZER, S.FnInitializer);

  // Must have exactly one parameter
  if (S.FnInitializer->getNumParams() != 1) {
    S.RSC.ReportError(S.FnInitializer->getLocation(),
                      "%0 must take exactly 1 parameter (found %1)")
        << S.DiagnosticDescription(KeyInitializer, mNameInitializer)
        << S.FnInitializer->getNumParams();
    S.Ok = false;
    return;
  }

  // Parameter must not be a special parameter
  S.FnInitializerParam = S.FnInitializer->getParamDecl(0);
  if (isSpecialKernelParameter(S.FnInitializerParam->getName())) {
    S.RSC.ReportError(S.FnInitializer->getLocation(),
                      "%0 cannot take special parameter '%1'")
        << S.DiagnosticDescription(KeyInitializer, mNameInitializer)
        << S.FnInitializerParam->getName();
    S.Ok = false;
    return;
  }

  // Parameter must be of pointer type
  S.FnInitializerParamTy = S.FnInitializerParam->getType().getCanonicalType();
  if (!S.FnInitializerParamTy->isPointerType()) {
    S.RSC.ReportError(S.FnInitializer->getLocation(),
                      "%0 parameter '%1' must be of pointer type not '%2'")
        << S.DiagnosticDescription(KeyInitializer, mNameInitializer)
        << S.FnInitializerParam->getName() << S.FnInitializerParamTy.getAsString();
    S.Ok = false;
    return;
  }

  // Parameter must not point to const-qualified
  checkPointeeConstQualified(S, FN_IDENT_INITIALIZER, mNameInitializer, S.FnInitializerParam, false);
}

// Process "void mNameAccumulator(compType *accum, in1Type in1, …, inNType inN[, specialarguments])"
void RSExportReduce::analyzeAccumulator(StateOfAnalyzeTranslationUnit &S) {
  slangAssert(S.FnAccumulator);

  // Must return void
  checkVoidReturn(S, FN_IDENT_ACCUMULATOR, S.FnAccumulator);

  // Must have initial parameter of same type as initializer parameter
  // (if there is an initializer), followed by at least 1 input

  if (S.FnAccumulator->getNumParams() < 2) {
    S.RSC.ReportError(S.FnAccumulator->getLocation(),
                      "%0 must take at least 2 parameters")
        << S.DiagnosticDescription(KeyAccumulator, mNameAccumulator);
    S.Ok = S.FnAccumulatorOk = false;
    return;
  }

  S.FnAccumulatorParamFirst = S.FnAccumulator->getParamDecl(0);
  S.FnAccumulatorParamFirstTy = S.FnAccumulatorParamFirst->getType().getCanonicalType();

  // First parameter must be of pointer type
  if (!S.FnAccumulatorParamFirstTy->isPointerType()) {
    S.RSC.ReportError(S.FnAccumulator->getLocation(),
                      "%0 parameter '%1' must be of pointer type not '%2'")
        << S.DiagnosticDescription(KeyAccumulator, mNameAccumulator)
        << S.FnAccumulatorParamFirst->getName() << S.FnAccumulatorParamFirstTy.getAsString();
    S.Ok = S.FnAccumulatorOk = false;
    return;
  }

  // If there is an initializer with a pointer-typed parameter (as
  // opposed to an initializer with a bad parameter list), then
  // accumulator first parameter must be of same type as initializer
  // parameter
  if (S.FnInitializer &&
      !S.FnInitializerParamTy.isNull() &&
      S.FnInitializerParamTy->isPointerType() &&
      !S.FnAccumulator->getASTContext().hasSameUnqualifiedType(
          S.FnInitializerParamTy->getPointeeType().getCanonicalType(),
          S.FnAccumulatorParamFirstTy->getPointeeType().getCanonicalType())) {
    // <accumulator> parameter '<baz>' (type '<tbaz>') and initializer <goo>() parameter '<gaz>' (type '<tgaz>')
    //   must be pointers to the same type
    S.RSC.ReportError(S.FnAccumulator->getLocation(),
                      "%0 parameter '%1' (type '%2') and %3 %4() parameter '%5' (type '%6')"
                      " must be pointers to the same type")
        << S.DiagnosticDescription(KeyAccumulator, mNameAccumulator)
        << S.FnAccumulatorParamFirst->getName() << S.FnAccumulatorParamFirstTy.getAsString()
        << KeyInitializer << mNameInitializer
        << S.FnInitializerParam->getName() << S.FnInitializerParamTy.getAsString();
    S.Ok = S.FnAccumulatorOk = false;
  }

  if (S.FnAccumulatorOk && S.FnAccumulatorParamFirstTy->getPointeeType()->isFunctionType()) {
    S.RSC.ReportError(S.FnAccumulator->getLocation(),
                      "%0 parameter '%1' (type '%2') must not be pointer to function type")
        << S.DiagnosticDescription(KeyAccumulator, mNameAccumulator)
        << S.FnAccumulatorParamFirst->getName() << S.FnAccumulatorParamFirstTy.getAsString();
    S.Ok = S.FnAccumulatorOk = false;
  }

  if (S.FnAccumulatorOk && S.FnAccumulatorParamFirstTy->getPointeeType()->isIncompleteType()) {
    S.RSC.ReportError(S.FnAccumulator->getLocation(),
                      "%0 parameter '%1' (type '%2') must not be pointer to incomplete type")
        << S.DiagnosticDescription(KeyAccumulator, mNameAccumulator)
        << S.FnAccumulatorParamFirst->getName() << S.FnAccumulatorParamFirstTy.getAsString();
    S.Ok = S.FnAccumulatorOk = false;
  }

  if (S.FnAccumulatorOk &&
      HasRSObjectType(S.FnAccumulatorParamFirstTy->getPointeeType().getCanonicalType().getTypePtr())) {
    S.RSC.ReportError(S.FnAccumulator->getLocation(),
                      "%0 parameter '%1' (type '%2') must not be pointer to data containing an object type")
        << S.DiagnosticDescription(KeyAccumulator, mNameAccumulator)
        << S.FnAccumulatorParamFirst->getName() << S.FnAccumulatorParamFirstTy.getAsString();
    S.Ok = S.FnAccumulatorOk = false;
  }

  // Parameter must not point to const-qualified
  checkPointeeConstQualified(S, FN_IDENT_ACCUMULATOR, mNameAccumulator, S.FnAccumulatorParamFirst, false);

  // Analyze special parameters
  S.Ok &= (S.FnAccumulatorOk &= processSpecialKernelParameters(
                                  &S.RSC,
                                  std::bind(S.DiagnosticDescription, KeyAccumulator, mNameAccumulator),
                                  S.FnAccumulator,
                                  &S.FnAccumulatorIndexOfFirstSpecialParameter,
                                  &mAccumulatorSignatureMetadata));

  // Must have at least an accumulator and an input.
  // If we get here we know there are at least 2 arguments; so the only problem case is
  // where we have an accumulator followed immediately by a special parameter.
  if (S.FnAccumulatorIndexOfFirstSpecialParameter < 2) {
    slangAssert(S.FnAccumulatorIndexOfFirstSpecialParameter < S.FnAccumulator->getNumParams());
    S.RSC.ReportError(S.FnAccumulator->getLocation(),
                      "%0 must have at least 1 input ('%1' is a special parameter)")
        << S.DiagnosticDescription(KeyAccumulator, mNameAccumulator)
        << S.FnAccumulator->getParamDecl(S.FnAccumulatorIndexOfFirstSpecialParameter)->getName();
    S.Ok = S.FnAccumulatorOk = false;
    return;
  }

  if (S.FnAccumulatorOk) {
    mAccumulatorSignatureMetadata |= bcinfo::MD_SIG_In;
    mAccumulatorTypeSize = S.ASTC.getTypeSizeInChars(S.FnAccumulatorParamFirstTy->getPointeeType()).getQuantity();
    for (size_t ParamIdx = 1; ParamIdx < S.FnAccumulatorIndexOfFirstSpecialParameter; ++ParamIdx) {
      const clang::ParmVarDecl *const Param = S.FnAccumulator->getParamDecl(ParamIdx);
      mAccumulatorIns.push_back(Param);
      const clang::QualType ParamQType = Param->getType().getCanonicalType();
      const clang::Type *ParamType = ParamQType.getTypePtr();

      RSExportType *ParamEType = nullptr;
      if (ParamQType->isPointerType()) {
        S.RSC.ReportError(Param->getLocation(),
                          "%0 parameter '%1' (type '%2') must not be a pointer")
            << S.DiagnosticDescription(KeyAccumulator, mNameAccumulator)
            << Param->getName() << ParamQType.getAsString();
        S.Ok = false;
      } else if (HasRSObjectType(ParamType)) {
        S.RSC.ReportError(Param->getLocation(),
                          "%0 parameter '%1' (type '%2') must not contain an object type")
            << S.DiagnosticDescription(KeyAccumulator, mNameAccumulator)
            << Param->getName() << ParamQType.getAsString();
        S.Ok = false;
      } else if (RSExportType::ValidateType(&S.RSC, S.ASTC, ParamQType, Param, Param->getLocStart(),
                                            S.RSC.getTargetAPI(),
                                            false /* IsFilterscript */,
                                            true /* IsExtern */)) {
        // TODO: Better diagnostics on validation or creation failure?
        ParamEType = RSExportType::Create(&S.RSC, ParamType, NotLegacyKernelArgument);
        S.Ok &= (ParamEType != nullptr);
      } else {
        S.Ok = false;
      }
      mAccumulatorInTypes.push_back(ParamEType); // possibly nullptr
    }
  }
}

// Process "void combinename(compType *accum, const compType *val)"
void RSExportReduce::analyzeCombiner(StateOfAnalyzeTranslationUnit &S) {
  if (S.FnCombiner) {
    // Must return void
    checkVoidReturn(S, FN_IDENT_COMBINER, S.FnCombiner);

    // Must have exactly two parameters, of same type as first accumulator parameter

    if (S.FnCombiner->getNumParams() != 2) {
      S.RSC.ReportError(S.FnCombiner->getLocation(),
                        "%0 must take exactly 2 parameters (found %1)")
          << S.DiagnosticDescription(KeyCombiner, mNameCombiner)
          << S.FnCombiner->getNumParams();
      S.Ok = false;
      return;
    }

    if (S.FnAccumulatorParamFirstTy.isNull() || !S.FnAccumulatorParamFirstTy->isPointerType()) {
      // We're already in an error situation.  We could compare
      // against the initializer parameter type instead of the first
      // accumulator parameter type (we'd have to check for the
      // availability of a parameter type there, too), but it does not
      // seem worth the effort.
      //
      // Likewise, we could compare the two combiner parameter types
      // against each other.
      slangAssert(!S.Ok);
      return;
    }

    for (int ParamIdx = 0; ParamIdx < 2; ++ParamIdx) {
      const clang::ParmVarDecl *const FnCombinerParam = S.FnCombiner->getParamDecl(ParamIdx);
      const clang::QualType FnCombinerParamTy = FnCombinerParam->getType().getCanonicalType();
      if (!FnCombinerParamTy->isPointerType() ||
          !S.FnCombiner->getASTContext().hasSameUnqualifiedType(
              S.FnAccumulatorParamFirstTy->getPointeeType().getCanonicalType(),
              FnCombinerParamTy->getPointeeType().getCanonicalType())) {
        // <combiner> parameter '<baz>' (type '<tbaz>')
        //   and accumulator <goo>() parameter '<gaz>' (type '<tgaz>') must be pointers to the same type
        S.RSC.ReportError(S.FnCombiner->getLocation(),
                          "%0 parameter '%1' (type '%2') and %3 %4() parameter '%5' (type '%6')"
                          " must be pointers to the same type")
            << S.DiagnosticDescription(KeyCombiner, mNameCombiner)
            << FnCombinerParam->getName() << FnCombinerParamTy.getAsString()
            << KeyAccumulator << mNameAccumulator
            << S.FnAccumulatorParamFirst->getName() << S.FnAccumulatorParamFirstTy.getAsString();
        S.Ok = false;
      } else {
        // Check const-qualification
        checkPointeeConstQualified(S, FN_IDENT_COMBINER, mNameCombiner, FnCombinerParam, ParamIdx==1);
      }
    }

    return;
  }

  // Ensure accumulator properties permit omission of combiner.

  if (!S.FnAccumulatorOk) {
    // Couldn't fully analyze accumulator, so cannot see whether it permits omission of combiner.
    return;
  }

  if (mAccumulatorIns.size() != 1 ||
      S.FnAccumulatorIndexOfFirstSpecialParameter != S.FnAccumulator->getNumParams())
  {
    S.RSC.ReportError(S.FnAccumulator->getLocation(),
                      "%0 must have exactly 1 input"
                      " and no special parameters in order for the %1 to be omitted")
        << S.DiagnosticDescription(KeyAccumulator, mNameAccumulator)
        << KeyCombiner;
    S.Ok = false;
    return;
  }

  const clang::ParmVarDecl *const FnAccumulatorParamInput = S.FnAccumulator->getParamDecl(1);
  const clang::QualType FnAccumulatorParamInputTy = FnAccumulatorParamInput->getType().getCanonicalType();
  if (!S.FnAccumulator->getASTContext().hasSameUnqualifiedType(
          S.FnAccumulatorParamFirstTy->getPointeeType().getCanonicalType(),
          FnAccumulatorParamInputTy.getCanonicalType())) {
    S.RSC.ReportError(S.FnAccumulator->getLocation(),
                      "%0 parameter '%1' (type '%2')"
                      " must be pointer to the type of parameter '%3' (type '%4')"
                      " in order for the %5 to be omitted")
        << S.DiagnosticDescription(KeyAccumulator, mNameAccumulator)
        << S.FnAccumulatorParamFirst->getName() << S.FnAccumulatorParamFirstTy.getAsString()
        << FnAccumulatorParamInput->getName() << FnAccumulatorParamInputTy.getAsString()
        << KeyCombiner;
    S.Ok = false;
  }
}

// Process "void outconvertname(resultType *result, const compType *accum)"
void RSExportReduce::analyzeOutConverter(StateOfAnalyzeTranslationUnit &S) {
  if (!S.FnOutConverter) // outconverter is always optional
    return;

  // Must return void
  checkVoidReturn(S, FN_IDENT_OUT_CONVERTER, S.FnOutConverter);

  // Must have exactly two parameters
  if (S.FnOutConverter->getNumParams() != 2) {
    S.RSC.ReportError(S.FnOutConverter->getLocation(),
                      "%0 must take exactly 2 parameters (found %1)")
        << S.DiagnosticDescription(KeyOutConverter, mNameOutConverter)
        << S.FnOutConverter->getNumParams();
    S.Ok = S.FnOutConverterOk = false;
    return;
  }

  // Parameters must not be special and must be of pointer type;
  // and second parameter must match first accumulator parameter
  for (int ParamIdx = 0; ParamIdx < 2; ++ParamIdx) {
    clang::ParmVarDecl *const FnOutConverterParam = S.FnOutConverter->getParamDecl(ParamIdx);

    if (isSpecialKernelParameter(FnOutConverterParam->getName())) {
      S.RSC.ReportError(S.FnOutConverter->getLocation(),
                        "%0 cannot take special parameter '%1'")
          << S.DiagnosticDescription(KeyOutConverter, mNameOutConverter)
          << FnOutConverterParam->getName();
      S.Ok = S.FnOutConverterOk = false;
      continue;
    }

    const clang::QualType FnOutConverterParamTy = FnOutConverterParam->getType().getCanonicalType();

    if (!FnOutConverterParamTy->isPointerType()) {
      S.RSC.ReportError(S.FnOutConverter->getLocation(),
                        "%0 parameter '%1' must be of pointer type not '%2'")
          << S.DiagnosticDescription(KeyOutConverter, mNameOutConverter)
          << FnOutConverterParam->getName() << FnOutConverterParamTy.getAsString();
      S.Ok = S.FnOutConverterOk = false;
      continue;
    }

    // Check const-qualification
    checkPointeeConstQualified(S, FN_IDENT_OUT_CONVERTER, mNameOutConverter, FnOutConverterParam, ParamIdx==1);

    if (ParamIdx == 0) {
      S.FnOutConverterParamFirst = FnOutConverterParam;
      S.FnOutConverterParamFirstTy = FnOutConverterParamTy;
      continue;
    }

    if (S.FnAccumulatorParamFirstTy.isNull() || !S.FnAccumulatorParamFirstTy->isPointerType()) {
      // We're already in an error situation.  We could compare
      // against the initializer parameter type instead of the first
      // accumulator parameter type (we'd have to check for the
      // availability of a parameter type there, too), but it does not
      // seem worth the effort.
      slangAssert(!S.Ok);
      continue;
    }

    if (!S.FnOutConverter->getASTContext().hasSameUnqualifiedType(
            S.FnAccumulatorParamFirstTy->getPointeeType().getCanonicalType(),
            FnOutConverterParamTy->getPointeeType().getCanonicalType())) {
      // <outconverter> parameter '<baz>' (type '<tbaz>')
      //   and accumulator <goo>() parameter '<gaz>' (type '<tgaz>') must be pointers to the same type
      S.RSC.ReportError(S.FnOutConverter->getLocation(),
                        "%0 parameter '%1' (type '%2') and %3 %4() parameter '%5' (type '%6')"
                        " must be pointers to the same type")
          << S.DiagnosticDescription(KeyOutConverter, mNameOutConverter)
          << FnOutConverterParam->getName() << FnOutConverterParamTy.getAsString()
          << KeyAccumulator << mNameAccumulator
          << S.FnAccumulatorParamFirst->getName() << S.FnAccumulatorParamFirstTy.getAsString();
      S.Ok = S.FnOutConverterOk = false;
    }
  }
}

// Process "bool haltername(const compType *accum)"
void RSExportReduce::analyzeHalter(StateOfAnalyzeTranslationUnit &S) {
  if (!S.FnHalter) // halter is always optional
    return;

  // Must return bool
  const clang::QualType ReturnTy = S.FnHalter->getReturnType().getCanonicalType();
  if (!ReturnTy->isBooleanType()) {
    S.RSC.ReportError(S.FnHalter->getLocation(),
                    "%0 must return bool not '%1'")
        << S.DiagnosticDescription(KeyHalter, mNameHalter) << ReturnTy.getAsString();
    S.Ok = false;
  }

  // Must have exactly one parameter
  if (S.FnHalter->getNumParams() != 1) {
    S.RSC.ReportError(S.FnHalter->getLocation(),
                      "%0 must take exactly 1 parameter (found %1)")
        << S.DiagnosticDescription(KeyHalter, mNameHalter)
        << S.FnHalter->getNumParams();
    S.Ok = false;
    return;
  }

  // Parameter must not be a special parameter
  const clang::ParmVarDecl *const FnHalterParam = S.FnHalter->getParamDecl(0);
  if (isSpecialKernelParameter(FnHalterParam->getName())) {
    S.RSC.ReportError(S.FnHalter->getLocation(),
                      "%0 cannot take special parameter '%1'")
        << S.DiagnosticDescription(KeyHalter, mNameHalter)
        << FnHalterParam->getName();
    S.Ok = false;
    return;
  }

  // Parameter must be same type as first accumulator parameter

  if (S.FnAccumulatorParamFirstTy.isNull() || !S.FnAccumulatorParamFirstTy->isPointerType()) {
    // We're already in an error situation.  We could compare against
    // the initializer parameter type or the first combiner parameter
    // type instead of the first accumulator parameter type (we'd have
    // to check for the availability of a parameter type there, too),
    // but it does not seem worth the effort.
    slangAssert(!S.Ok);
    return;
  }

  const clang::QualType FnHalterParamTy = FnHalterParam->getType().getCanonicalType();
  if (!FnHalterParamTy->isPointerType() ||
      !S.FnHalter->getASTContext().hasSameUnqualifiedType(
          S.FnAccumulatorParamFirstTy->getPointeeType().getCanonicalType(),
          FnHalterParamTy->getPointeeType().getCanonicalType())) {
    // <halter> parameter '<baz>' (type '<tbaz>')
    //   and accumulator <goo>() parameter '<gaz>' (type '<tgaz>') must be pointers to the same type
    S.RSC.ReportError(S.FnHalter->getLocation(),
                      "%0 parameter '%1' (type '%2') and %3 %4() parameter '%5' (type '%6')"
                      " must be pointers to the same type")
        << S.DiagnosticDescription(KeyHalter, mNameHalter)
        << FnHalterParam->getName() << FnHalterParamTy.getAsString()
        << KeyAccumulator << mNameAccumulator
        << S.FnAccumulatorParamFirst->getName() << S.FnAccumulatorParamFirstTy.getAsString();
    S.Ok = false;
    return;
  }

  // Parameter must point to const-qualified
  checkPointeeConstQualified(S, FN_IDENT_HALTER, mNameHalter, FnHalterParam, true);
}

void RSExportReduce::analyzeResultType(StateOfAnalyzeTranslationUnit &S) {
  if (!(S.FnAccumulatorOk && S.FnOutConverterOk)) {
    // No idea what the result type is
    slangAssert(!S.Ok);
    return;
  }

  struct ResultInfoType {
    const clang::QualType QType;
    clang::VarDecl *const Decl;
    const char *FnKey;
    const std::string &FnName;
    std::function<std::string ()> UnlessOutConverter;
  } ResultInfo =
        S.FnOutConverter
        ? ResultInfoType({ S.FnOutConverterParamFirstTy, S.FnOutConverterParamFirst,
                           KeyOutConverter, mNameOutConverter,
                           []() { return std::string(""); }})
        : ResultInfoType({ S.FnAccumulatorParamFirstTy,  S.FnAccumulatorParamFirst,
                           KeyAccumulator,  mNameAccumulator,
                           []() { return std::string(" unless ") + KeyOutConverter + " is provided"; }});
  const clang::QualType PointeeQType = ResultInfo.QType->getPointeeType();

  if (PointeeQType->isPointerType()) {
    S.RSC.ReportError(ResultInfo.Decl->getLocation(),
                      "%0 parameter '%1' (type '%2') must not point to a pointer%3")
        << S.DiagnosticDescription(ResultInfo.FnKey, ResultInfo.FnName)
        << ResultInfo.Decl->getName() << ResultInfo.QType.getAsString()
        << ResultInfo.UnlessOutConverter();
  } else if (PointeeQType->isIncompleteType()) {
    S.RSC.ReportError(ResultInfo.Decl->getLocation(),
                      "%0 parameter '%1' (type '%2') must not point to an incomplete type%3")
        << S.DiagnosticDescription(ResultInfo.FnKey, ResultInfo.FnName)
        << ResultInfo.Decl->getName() << ResultInfo.QType.getAsString()
        << ResultInfo.UnlessOutConverter();
  } else if (HasRSObjectType(PointeeQType.getTypePtr())) {
    S.RSC.ReportError(ResultInfo.Decl->getLocation(),
                      "%0 parameter '%1' (type '%2') must not point to data containing an object type%3")
        << S.DiagnosticDescription(ResultInfo.FnKey, ResultInfo.FnName)
        << ResultInfo.Decl->getName() << ResultInfo.QType.getAsString()
        << ResultInfo.UnlessOutConverter();
  } else if (RSExportType::ValidateType(&S.RSC, S.ASTC, PointeeQType,
                                        ResultInfo.Decl, ResultInfo.Decl->getLocStart(),
                                        S.RSC.getTargetAPI(),
                                        false /* IsFilterscript */,
                                        true /* IsExtern */)) {
    // TODO: Better diagnostics on validation or creation failure?
    if ((mResultType = RSExportType::Create(&S.RSC, PointeeQType.getTypePtr(),
                                            NotLegacyKernelArgument, ResultInfo.Decl)) != nullptr) {
      const RSExportType *CheckType = mResultType;
      const char *ArrayErrorPhrase = "";
      if (mResultType->getClass() == RSExportType::ExportClassConstantArray) {
        CheckType = static_cast<const RSExportConstantArrayType *>(mResultType)->getElementType();
        ArrayErrorPhrase = "n array of";
      }
      switch (CheckType->getClass()) {
        case RSExportType::ExportClassMatrix:
          // Not supported for now -- what does a matrix result type mean?
          S.RSC.ReportError(ResultInfo.Decl->getLocation(),
                            "%0 parameter '%1' (type '%2') must not point to a%3 matrix type%4")
              << S.DiagnosticDescription(ResultInfo.FnKey, ResultInfo.FnName)
              << ResultInfo.Decl->getName() << ResultInfo.QType.getAsString()
              << ArrayErrorPhrase
              << ResultInfo.UnlessOutConverter();
          mResultType = nullptr;
          break;
        default:
          // All's well
          break;
      }
    }
  }

  if (mResultType)
    S.RSC.insertExportReduceResultType(mResultType);
  else
    S.Ok = false;
}

bool RSExportReduce::analyzeTranslationUnit() {

  RSContext &RSC = *getRSContext();
  clang::Preprocessor &PP = RSC.getPreprocessor();

  StateOfAnalyzeTranslationUnit S(
      RSC, PP, RSC.getASTContext(),
      [&RSC, &PP, this] (const char *Key, const std::string &Name) {
        std::ostringstream Description;
        Description
            << Key << " " << Name << "()"
            << " for '#pragma rs " << KeyReduce << "(" << mNameReduce << ")'"
            << " (" << mLocation.printToString(PP.getSourceManager()) << ")";
        return Description.str();
      });

  S.FnInitializer  = lookupFunction(S, KeyInitializer,  mNameInitializer);
  S.FnAccumulator  = lookupFunction(S, KeyAccumulator,  mNameAccumulator);
  S.FnCombiner     = lookupFunction(S, KeyCombiner,     mNameCombiner);
  S.FnOutConverter = lookupFunction(S, KeyOutConverter, mNameOutConverter);
  S.FnHalter       = lookupFunction(S, KeyHalter,       mNameHalter);

  if (!S.Ok)
    return false;

  analyzeInitializer(S);
  analyzeAccumulator(S);
  analyzeCombiner(S);
  analyzeOutConverter(S);
  analyzeHalter(S);
  analyzeResultType(S);

  return S.Ok;
}

}  // namespace slang
