//===--- ParseHLSL.cpp - HLSL-specific parsing support --------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the parsing logic for HLSL language features.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/Attr.h"
#include "clang/Basic/AttributeCommonInfo.h"
#include "clang/Basic/DiagnosticParse.h"
#include "clang/Parse/Parser.h"
#include "clang/Parse/RAIIObjectsForParser.h"
#include "clang/Sema/SemaHLSL.h"

using namespace clang;

static bool validateDeclsInsideHLSLBuffer(Parser::DeclGroupPtrTy DG,
                                          SourceLocation BufferLoc,
                                          bool IsCBuffer, Parser &P) {
  // The parse is failed, just return false.
  if (!DG)
    return false;
  DeclGroupRef Decls = DG.get();
  bool IsValid = true;
  // Only allow function, variable, record, and empty decls inside HLSLBuffer.
  for (DeclGroupRef::iterator I = Decls.begin(), E = Decls.end(); I != E; ++I) {
    Decl *D = *I;
    if (isa<CXXRecordDecl, RecordDecl, FunctionDecl, VarDecl, EmptyDecl>(D))
      continue;

    // FIXME: support nested HLSLBuffer and namespace inside HLSLBuffer.
    if (isa<HLSLBufferDecl, NamespaceDecl>(D)) {
      P.Diag(D->getLocation(), diag::err_invalid_declaration_in_hlsl_buffer)
          << IsCBuffer;
      IsValid = false;
      continue;
    }

    IsValid = false;
    P.Diag(D->getLocation(), diag::err_invalid_declaration_in_hlsl_buffer)
        << IsCBuffer;
  }
  return IsValid;
}

Decl *Parser::ParseHLSLBuffer(SourceLocation &DeclEnd) {
  assert((Tok.is(tok::kw_cbuffer) || Tok.is(tok::kw_tbuffer)) &&
         "Not a cbuffer or tbuffer!");
  bool IsCBuffer = Tok.is(tok::kw_cbuffer);
  SourceLocation BufferLoc = ConsumeToken(); // Eat the 'cbuffer' or 'tbuffer'.

  if (!Tok.is(tok::identifier)) {
    Diag(Tok, diag::err_expected) << tok::identifier;
    return nullptr;
  }

  IdentifierInfo *Identifier = Tok.getIdentifierInfo();
  SourceLocation IdentifierLoc = ConsumeToken();

  ParsedAttributes Attrs(AttrFactory);
  MaybeParseHLSLAnnotations(Attrs, nullptr);

  ParseScope BufferScope(this, Scope::DeclScope);
  BalancedDelimiterTracker T(*this, tok::l_brace);
  if (T.consumeOpen()) {
    Diag(Tok, diag::err_expected) << tok::l_brace;
    return nullptr;
  }

  Decl *D = Actions.HLSL().ActOnStartBuffer(getCurScope(), IsCBuffer, BufferLoc,
                                            Identifier, IdentifierLoc,
                                            T.getOpenLocation());
  Actions.ProcessDeclAttributeList(Actions.CurScope, D, Attrs);

  while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
    // FIXME: support attribute on constants inside cbuffer/tbuffer.
    ParsedAttributes DeclAttrs(AttrFactory);
    ParsedAttributes EmptyDeclSpecAttrs(AttrFactory);

    DeclGroupPtrTy Result =
        ParseExternalDeclaration(DeclAttrs, EmptyDeclSpecAttrs);
    if (!validateDeclsInsideHLSLBuffer(Result, IdentifierLoc, IsCBuffer,
                                       *this)) {
      T.skipToEnd();
      DeclEnd = T.getCloseLocation();
      BufferScope.Exit();
      Actions.HLSL().ActOnFinishBuffer(D, DeclEnd);
      return nullptr;
    }
  }

  T.consumeClose();
  DeclEnd = T.getCloseLocation();
  BufferScope.Exit();
  Actions.HLSL().ActOnFinishBuffer(D, DeclEnd);

  return D;
}

static void fixSeparateAttrArgAndNumber(StringRef ArgStr, SourceLocation ArgLoc,
                                        Token Tok, ArgsVector &ArgExprs,
                                        Parser &P, ASTContext &Ctx,
                                        Preprocessor &PP) {
  StringRef Num = StringRef(Tok.getLiteralData(), Tok.getLength());
  SourceLocation EndNumLoc = Tok.getEndLoc();

  P.ConsumeToken(); // consume constant.
  std::string FixedArg = ArgStr.str() + Num.str();
  P.Diag(ArgLoc, diag::err_hlsl_separate_attr_arg_and_number)
      << FixedArg
      << FixItHint::CreateReplacement(SourceRange(ArgLoc, EndNumLoc), FixedArg);
  ArgsUnion &Slot = ArgExprs.back();
  Slot = new (Ctx) IdentifierLoc(ArgLoc, PP.getIdentifierInfo(FixedArg));
}

void Parser::ParseHLSLAnnotations(ParsedAttributes &Attrs,
                                  SourceLocation *EndLoc,
                                  bool CouldBeBitField) {

  assert(Tok.is(tok::colon) && "Not a HLSL Annotation");
  Token OldToken = Tok;
  ConsumeToken();

  IdentifierInfo *II = nullptr;
  if (Tok.is(tok::kw_register))
    II = PP.getIdentifierInfo("register");
  else if (Tok.is(tok::identifier))
    II = Tok.getIdentifierInfo();

  if (!II) {
    if (CouldBeBitField) {
      UnconsumeToken(OldToken);
      return;
    }
    Diag(Tok.getLocation(), diag::err_expected_semantic_identifier);
    return;
  }

  SourceLocation Loc = ConsumeToken();
  if (EndLoc)
    *EndLoc = Tok.getLocation();
  ParsedAttr::Kind AttrKind =
      ParsedAttr::getParsedKind(II, nullptr, ParsedAttr::AS_HLSLAnnotation);

  ArgsVector ArgExprs;
  switch (AttrKind) {
  case ParsedAttr::AT_HLSLResourceBinding: {
    if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after)) {
      SkipUntil(tok::r_paren, StopAtSemi); // skip through )
      return;
    }
    if (!Tok.is(tok::identifier)) {
      Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
      SkipUntil(tok::r_paren, StopAtSemi); // skip through )
      return;
    }
    StringRef SlotStr = Tok.getIdentifierInfo()->getName();
    SourceLocation SlotLoc = Tok.getLocation();
    ArgExprs.push_back(ParseIdentifierLoc());

    if (SlotStr.size() == 1) {
      if (!Tok.is(tok::numeric_constant)) {
        Diag(Tok.getLocation(), diag::err_expected) << tok::numeric_constant;
        SkipUntil(tok::r_paren, StopAtSemi); // skip through )
        return;
      }
      // Add numeric_constant for fix-it.
      fixSeparateAttrArgAndNumber(SlotStr, SlotLoc, Tok, ArgExprs, *this,
                                  Actions.Context, PP);
    }
    if (Tok.is(tok::comma)) {
      ConsumeToken(); // consume comma
      if (!Tok.is(tok::identifier)) {
        Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
        SkipUntil(tok::r_paren, StopAtSemi); // skip through )
        return;
      }
      StringRef SpaceStr = Tok.getIdentifierInfo()->getName();
      SourceLocation SpaceLoc = Tok.getLocation();
      ArgExprs.push_back(ParseIdentifierLoc());

      // Add numeric_constant for fix-it.
      if (SpaceStr == "space" && Tok.is(tok::numeric_constant))
        fixSeparateAttrArgAndNumber(SpaceStr, SpaceLoc, Tok, ArgExprs, *this,
                                    Actions.Context, PP);
    }
    if (ExpectAndConsume(tok::r_paren, diag::err_expected)) {
      SkipUntil(tok::r_paren, StopAtSemi); // skip through )
      return;
    }
  } break;
  case ParsedAttr::AT_HLSLPackOffset: {
    // Parse 'packoffset( c[Subcomponent][.component] )'.
    // Check '('.
    if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after)) {
      SkipUntil(tok::r_paren, StopAtSemi); // skip through )
      return;
    }
    // Check c[Subcomponent] as an identifier.
    if (!Tok.is(tok::identifier)) {
      Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
      SkipUntil(tok::r_paren, StopAtSemi); // skip through )
      return;
    }
    StringRef OffsetStr = Tok.getIdentifierInfo()->getName();
    SourceLocation SubComponentLoc = Tok.getLocation();
    if (OffsetStr[0] != 'c') {
      Diag(Tok.getLocation(), diag::err_hlsl_packoffset_invalid_reg)
          << OffsetStr;
      SkipUntil(tok::r_paren, StopAtSemi); // skip through )
      return;
    }
    OffsetStr = OffsetStr.substr(1);
    unsigned SubComponent = 0;
    if (!OffsetStr.empty()) {
      // Make sure SubComponent is a number.
      if (OffsetStr.getAsInteger(10, SubComponent)) {
        Diag(SubComponentLoc.getLocWithOffset(1),
             diag::err_hlsl_unsupported_register_number);
        SkipUntil(tok::r_paren, StopAtSemi); // skip through )
        return;
      }
    }
    unsigned Component = 0;
    ConsumeToken(); // consume identifier.
    SourceLocation ComponentLoc;
    if (Tok.is(tok::period)) {
      ConsumeToken(); // consume period.
      if (!Tok.is(tok::identifier)) {
        Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;
        SkipUntil(tok::r_paren, StopAtSemi); // skip through )
        return;
      }
      StringRef ComponentStr = Tok.getIdentifierInfo()->getName();
      ComponentLoc = Tok.getLocation();
      ConsumeToken(); // consume identifier.
      // Make sure Component is a single character.
      if (ComponentStr.size() != 1) {
        Diag(ComponentLoc, diag::err_hlsl_unsupported_component)
            << ComponentStr;
        SkipUntil(tok::r_paren, StopAtSemi); // skip through )
        return;
      }
      switch (ComponentStr[0]) {
      case 'x':
      case 'r':
        Component = 0;
        break;
      case 'y':
      case 'g':
        Component = 1;
        break;
      case 'z':
      case 'b':
        Component = 2;
        break;
      case 'w':
      case 'a':
        Component = 3;
        break;
      default:
        Diag(ComponentLoc, diag::err_hlsl_unsupported_component)
            << ComponentStr;
        SkipUntil(tok::r_paren, StopAtSemi); // skip through )
        return;
      }
    }
    ASTContext &Ctx = Actions.getASTContext();
    QualType SizeTy = Ctx.getSizeType();
    uint64_t SizeTySize = Ctx.getTypeSize(SizeTy);
    ArgExprs.push_back(IntegerLiteral::Create(
        Ctx, llvm::APInt(SizeTySize, SubComponent), SizeTy, SubComponentLoc));
    ArgExprs.push_back(IntegerLiteral::Create(
        Ctx, llvm::APInt(SizeTySize, Component), SizeTy, ComponentLoc));
    if (ExpectAndConsume(tok::r_paren, diag::err_expected)) {
      SkipUntil(tok::r_paren, StopAtSemi); // skip through )
      return;
    }
  } break;
  case ParsedAttr::UnknownAttribute:
    Diag(Loc, diag::err_unknown_hlsl_semantic) << II;
    return;
  case ParsedAttr::AT_HLSLSV_GroupThreadID:
  case ParsedAttr::AT_HLSLSV_GroupID:
  case ParsedAttr::AT_HLSLSV_GroupIndex:
  case ParsedAttr::AT_HLSLSV_DispatchThreadID:
    break;
  default:
    llvm_unreachable("invalid HLSL Annotation");
    break;
  }

  Attrs.addNew(II, Loc, nullptr, SourceLocation(), ArgExprs.data(),
               ArgExprs.size(), ParsedAttr::Form::HLSLAnnotation());
}
