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

Code before:
  }
  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) {
  if (llvm::any_of(Converted,
                   [](const TemplateArgument &A) { return A.isDependent(); }))
    return QualType();

  ASTContext &Context = SemaRef.getASTContext();

  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->isIntegralType(Context)) {
      SemaRef.Diag(TemplateArgs[1].getLocation(),
                   diag::err_integer_sequence_integral_element_type);
      return QualType();
    }

    TemplateArgument NumArgsArg = Converted[2];

    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());
           I < NumArgs; ++I) {
        TemplateArgument TA(Context, I, OrigType);
        SyntheticTemplateArgs.addArgument(SemaRef.getTrivialTemplateArgumentLoc(
            TA, OrigType, TemplateArgs[2].getLocation()));
      }
    } else {
      // C++14 [inteseq.make]p1:

Review comment (suggestion):
paranoia: add an `assert(!OrigType->isDependentType())` this also makes it more explicit that it is not allowed

Code after:
  }
  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());
           I < NumArgs; ++I) {
        TemplateArgument TA(Context, I, OrigType);
        SyntheticTemplateArgs.addArgument(SemaRef.getTrivialTemplateArgumentLoc(
            TA, OrigType, TemplateArgs[2].getLocation()));
      }
    } else {