Repository: llvm/llvm-project
File: clang/lib/Sema/SemaTemplate.cpp (C++)

Code before:
        return SpirvOperand::createLiteral(Value);
      return SpirvOperand::createConstant(ConstantType, Value);
    } else if (Literal) {
      SemaRef.Diag(LiteralLoc, diag::err_hlsl_vk_literal_must_contain_constant);
      return SpirvOperand();
    }
  }
  if (SemaRef.RequireCompleteType(Loc, OperandArg,
                                  diag::err_call_incomplete_argument))
    return SpirvOperand();
  return SpirvOperand::createType(OperandArg);
}

static QualType checkBuiltinTemplateIdType(
    Sema &SemaRef, ElaboratedTypeKeyword Keyword, BuiltinTemplateDecl *BTD,
    ArrayRef<TemplateArgument> Converted, SourceLocation TemplateLoc,
    TemplateArgumentListInfo &TemplateArgs) {
  TemplateParameterList *Params = BTD->getTemplateParameters();
  unsigned RequiredArgs = Params->size();
  if (Params->hasParameterPack()) {
    if (Converted.size() < RequiredArgs)
      return QualType();
  } else {
    if (Converted.size() != RequiredArgs)
      return QualType();
  }

  ASTContext &Context = SemaRef.getASTContext();

  switch (BTD->getBuiltinTemplateKind()) {
  case BTK__make_integer_seq: {
    if (Converted[2].isDependent())
      return QualType();
    // Specializations of __make_integer_seq<S, T, N> are treated like
    // S<T, 0, ..., N-1>.

    QualType OrigType = Converted[1].getAsType();
    if (OrigType->isDependentType())
      return QualType();

    // C++14 [inteseq.intseq]p1:
    //   T shall be an integer type.
    assert(!OrigType->isDependentType());
    if (!OrigType->isIntegralType(Context)) {
      SemaRef.Diag(TemplateArgs[1].getLocation(),
                   diag::err_integer_sequence_integral_element_type);
      return QualType();
    }

    TemplateArgument NumArgsArg = Converted[2];


Review comment (suggestion):
This is not correct check, as Converted can contain packs or pack expansions.

Also, if you would determine the argument list can never match the parameter list, then you should produce a diagnostic earlier, instead of just leaving the template specialization as dependent.

Code after:
        return SpirvOperand::createLiteral(Value);
      return SpirvOperand::createConstant(ConstantType, Value);
    } else if (Literal) {
      SemaRef.Diag(LiteralLoc, diag::err_hlsl_vk_literal_must_contain_constant);
      return SpirvOperand();
    }
  }
  if (SemaRef.RequireCompleteType(Loc, OperandArg,
                                  diag::err_call_incomplete_argument))
    return SpirvOperand();
  return SpirvOperand::createType(OperandArg);
}

static QualType checkBuiltinTemplateIdType(
    Sema &SemaRef, ElaboratedTypeKeyword Keyword, BuiltinTemplateDecl *BTD,
    ArrayRef<TemplateArgument> Converted, SourceLocation TemplateLoc,
    TemplateArgumentListInfo &TemplateArgs) {
  ASTContext &Context = SemaRef.getASTContext();

  assert(Converted.size() == BTD->getTemplateParameters()->size() &&
         "Builtin template arguments do not match its parameters");

  switch (BTD->getBuiltinTemplateKind()) {
  case BTK__make_integer_seq: {
    // Specializations of __make_integer_seq<S, T, N> are treated like
    // S<T, 0, ..., N-1>.

    QualType OrigType = Converted[1].getAsType();
    // C++14 [inteseq.intseq]p1:
    //   T shall be an integer type.
    if (!OrigType->isDependentType() && !OrigType->isIntegralType(Context)) {
      SemaRef.Diag(TemplateArgs[1].getLocation(),
                   diag::err_integer_sequence_integral_element_type);
      return QualType();
    }

    TemplateArgument NumArgsArg = Converted[2];
    if (NumArgsArg.isDependent())
      return QualType();

    TemplateArgumentListInfo SyntheticTemplateArgs;
    // The type argument, wrapped in substitution sugar, gets reused as the
    // first template argument in the synthetic template argument list.
    SyntheticTemplateArgs.addArgument(
        TemplateArgumentLoc(TemplateArgument(OrigType),
                            SemaRef.Context.getTrivialTypeSourceInfo(
                                OrigType, TemplateArgs[1].getLocation())));

    if (llvm::APSInt NumArgs = NumArgsArg.getAsIntegral(); NumArgs >= 0) {
      // Expand N into 0 ... N-1.
      for (llvm::APSInt I(NumArgs.getBitWidth(), NumArgs.isUnsigned());