//===-- DILParser.cpp -----------------------------------------------------===//
//
// 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 implements the recursive descent parser for the Data Inspection
// Language (DIL), and its helper functions, which will eventually underlie the
// 'frame variable' command. The language that this parser recognizes is
// described in lldb/docs/dil-expr-lang.ebnf
//
//===----------------------------------------------------------------------===//

#include "lldb/ValueObject/DILParser.h"
#include "lldb/Host/common/DiagnosticsRendering.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Target/LanguageRuntime.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/ValueObject/DILAST.h"
#include "lldb/ValueObject/DILEval.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/FormatAdapters.h"
#include <cstdlib>
#include <limits.h>
#include <memory>
#include <sstream>
#include <string>

namespace lldb_private::dil {

DILDiagnosticError::DILDiagnosticError(llvm::StringRef expr,
                                       const std::string &message, uint32_t loc,
                                       uint16_t err_len)
    : ErrorInfo(make_error_code(std::errc::invalid_argument)) {
  DiagnosticDetail::SourceLocation sloc = {
      FileSpec{}, /*line=*/1, static_cast<uint16_t>(loc + 1),
      err_len,    false,      /*in_user_input=*/true};
  // If the error is not handled by `RenderDiagnosticDetails`, this creates an
  // error message that can be displayed instead.
  // Example:
  // (lldb) script lldb.frame.GetValueForVariablePath("1 + foo")
  // error: <user expression>:1:5: use of undeclared identifier 'foo'
  //   1 | 1 + foo
  //     |     ^~~
  auto msg = llvm::formatv("<user expression>:1:{0}: {1}\n    1 | {2}\n      |",
                           loc + 1, message, expr);
  std::string rendered_str;
  llvm::raw_string_ostream rendered_os(rendered_str);
  rendered_os << msg.str();
  rendered_os << llvm::indent(loc + 1) << "^";
  if (err_len > 1) {
    // Underline the rest of the erroneous token after the cursor '^'.
    rendered_os << std::string(err_len - 1, '~');
  }
  m_detail.source_location = sloc;
  m_detail.severity = lldb::eSeverityError;
  m_detail.message = message;
  m_detail.rendered = std::move(rendered_str);
}

CompilerType ResolveTypeByName(const std::string &name,
                               ExecutionContext &exe_ctx) {
  // Internally types don't have global scope qualifier in their names and
  // LLDB doesn't support queries with it too.
  llvm::StringRef name_ref(name);

  if (name_ref.starts_with("::"))
    name_ref = name_ref.drop_front(2);

  std::vector<CompilerType> result_type_list;
  lldb::TargetSP target_sp = exe_ctx.GetTargetSP();
  if (!name_ref.empty() && target_sp) {
    ModuleList &images = target_sp->GetImages();
    TypeQuery query{ConstString(name_ref), TypeQueryOptions::e_exact_match |
                                               TypeQueryOptions::e_find_one};
    TypeResults results;
    images.FindTypes(nullptr, query, results);
    const lldb::TypeSP &type_sp = results.GetFirstType();
    if (type_sp)
      result_type_list.push_back(type_sp->GetFullCompilerType());
  }

  if (!result_type_list.empty()) {
    CompilerType type = result_type_list[0];
    if (type.IsValid() && type.GetTypeName().GetStringRef() == name_ref)
      return type;
  }

  return {};
}

llvm::Expected<ASTNodeUP> DILParser::Parse(ExecutionContext &exe_ctx,
                                           llvm::StringRef dil_input_expr,
                                           DILLexer lexer,
                                           lldb::DynamicValueType use_dynamic,
                                           lldb::DILMode mode) {
  llvm::Error error = llvm::Error::success();
  DILParser parser(exe_ctx, dil_input_expr, lexer, use_dynamic, error, mode);

  ASTNodeUP node_up = parser.Run();
  assert(node_up && "ASTNodeUP must not contain a nullptr");

  if (error) {
    LLDB_LOG(GetLog(LLDBLog::Expressions),
             "[DILParser::Parse] DIL parser failed:\n{0}",
             llvm::toStringWithoutConsuming(error));
    return error;
  }

  return node_up;
}

DILParser::DILParser(ExecutionContext &exe_ctx, llvm::StringRef dil_input_expr,
                     DILLexer lexer, lldb::DynamicValueType use_dynamic,
                     llvm::Error &error, lldb::DILMode mode)
    : m_exe_ctx(exe_ctx), m_input_expr(dil_input_expr),
      m_dil_lexer(std::move(lexer)), m_error(error), m_use_dynamic(use_dynamic),
      m_mode(mode) {}

ASTNodeUP DILParser::Run() {
  ASTNodeUP expr = ParseExpression();

  Expect(Token::Kind::eof);

  return expr;
}

// Parse an expression.
//
//  expression:
//    assignment_expression
//
ASTNodeUP DILParser::ParseExpression() { return ParseAssignmentExpression(); }

// Parse an assignment_expression
//
//  assignment_expression
//    conditional_expression
//    logical_or_expression assignment_operator pure_expression
//
//  assignment_operator:
//    "="
//    "+="
//    "-="
//    "*="
//    "/="
//    "%="
//    "&="
//    "^="
//    "|="
//    "<<="
//    ">>="
//
ASTNodeUP DILParser::ParseAssignmentExpression() {
  auto lhs = ParseLogicalOrExpression();
  assert(lhs && "ASTNodeUP must not contain a nullptr");

  // Check if it's an assignment expression.
  if (CurToken().IsOneOf({Token::equal, Token::plusequal, Token::minusequal,
                          Token::starequal, Token::slashequal,
                          Token::percentequal, Token::ampequal,
                          Token::caretequal, Token::pipeequal,
                          Token::lesslessequal, Token::greatergreaterequal})) {
    // That's an assignment!
    Token token = CurToken();
    m_dil_lexer.Advance();
    auto rhs = ParsePureExpression();
    assert(rhs && "ASTNodeUP must not contain a nullptr");
    lhs = std::make_unique<BinaryOpNode>(
        token.GetLocation(), GetBinaryOpKindFromToken(token.GetKind()),
        std::move(lhs), std::move(rhs));
  }

  // Check if it's a ternary operator.
  if (CurToken().Is(Token::question))
    return ParseConditionalBranches(std::move(lhs));

  return lhs;
}

// Parse a pure expression without side effects.
//
//  pure_expression:
//    conditional_expression
//
ASTNodeUP DILParser::ParsePureExpression() {
  return ParseConditionalExpression();
}

// Parse a conditional_expression.
//
//  conditional_expression:
//    logical_or_expression
//    logical_or_expression "?" pure_expression ":" pure_expression
//
ASTNodeUP DILParser::ParseConditionalExpression() {
  auto lhs = ParseLogicalOrExpression();
  assert(lhs && "ASTNodeUP must not contain a nullptr");

  if (CurToken().Is(Token::question))
    return ParseConditionalBranches(std::move(lhs));

  return lhs;
}

ASTNodeUP DILParser::ParseConditionalBranches(ASTNodeUP condition) {
  assert(condition && "ASTNodeUP must not contain a nullptr");

  Token token = CurToken();
  m_dil_lexer.Advance();
  auto true_op = ParsePureExpression();
  assert(true_op && "ASTNodeUP must not contain a nullptr");
  Expect(Token::colon);
  m_dil_lexer.Advance();
  auto false_op = ParsePureExpression();
  assert(false_op && "ASTNodeUP must not contain a nullptr");
  return std::make_unique<ConditionalNode>(
      token.GetLocation(), std::move(condition), std::move(true_op),
      std::move(false_op));
}

// Parse a logical_or_expression.
//
//  logical_or_expression:
//    logical_and_expression {"||" logical_and_expression}
//
ASTNodeUP DILParser::ParseLogicalOrExpression() {
  auto lhs = ParseLogicalAndExpression();
  assert(lhs && "ASTNodeUP must not contain a nullptr");

  while (CurToken().Is(Token::pipepipe)) {
    Token token = CurToken();
    m_dil_lexer.Advance();
    auto rhs = ParseLogicalAndExpression();
    assert(rhs && "ASTNodeUP must not contain a nullptr");
    lhs = std::make_unique<BinaryOpNode>(
        token.GetLocation(), GetBinaryOpKindFromToken(token.GetKind()),
        std::move(lhs), std::move(rhs));
  }

  return lhs;
}

// Parse a logical_and_expression.
//
//  logical_and_expression:
//    inclusive_or_expression {"&&" inclusive_or_expression}
//
ASTNodeUP DILParser::ParseLogicalAndExpression() {
  auto lhs = ParseInclusiveOrExpression();
  assert(lhs && "ASTNodeUP must not contain a nullptr");

  while (CurToken().Is(Token::ampamp)) {
    Token token = CurToken();
    m_dil_lexer.Advance();
    auto rhs = ParseInclusiveOrExpression();
    assert(rhs && "ASTNodeUP must not contain a nullptr");
    lhs = std::make_unique<BinaryOpNode>(
        token.GetLocation(), GetBinaryOpKindFromToken(token.GetKind()),
        std::move(lhs), std::move(rhs));
  }

  return lhs;
}

// Parse an inclusive_or_expression.
//
//  inclusive_or_expression:
//    exclusive_or_expression {"|" exclusive_or_expression}
//
ASTNodeUP DILParser::ParseInclusiveOrExpression() {
  auto lhs = ParseExclusiveOrExpression();
  assert(lhs && "ASTNodeUP must not contain a nullptr");

  while (CurToken().Is(Token::pipe)) {
    Token token = CurToken();
    m_dil_lexer.Advance();
    auto rhs = ParseExclusiveOrExpression();
    assert(rhs && "ASTNodeUP must not contain a nullptr");
    lhs = std::make_unique<BinaryOpNode>(
        token.GetLocation(), GetBinaryOpKindFromToken(token.GetKind()),
        std::move(lhs), std::move(rhs));
  }

  return lhs;
}

// Parse an exclusive_or_expression.
//
//  exclusive_or_expression:
//    and_expression {"^" and_expression}
//
ASTNodeUP DILParser::ParseExclusiveOrExpression() {
  auto lhs = ParseAndExpression();
  assert(lhs && "ASTNodeUP must not contain a nullptr");

  while (CurToken().Is(Token::caret)) {
    Token token = CurToken();
    m_dil_lexer.Advance();
    auto rhs = ParseAndExpression();
    assert(rhs && "ASTNodeUP must not contain a nullptr");
    lhs = std::make_unique<BinaryOpNode>(
        token.GetLocation(), GetBinaryOpKindFromToken(token.GetKind()),
        std::move(lhs), std::move(rhs));
  }

  return lhs;
}

// Parse an and_expression.
//
//  and_expression:
//    equality_expression {"&" equality_expression}
//
ASTNodeUP DILParser::ParseAndExpression() {
  auto lhs = ParseEqualityExpression();
  assert(lhs && "ASTNodeUP must not contain a nullptr");

  while (CurToken().Is(Token::amp)) {
    Token token = CurToken();
    if (token.Is(Token::amp) && m_mode != lldb::eDILModeFull) {
      BailOut("bitwise and (&) is allowed only in DIL full mode",
              token.GetLocation(), token.GetSpelling().length());
      return std::make_unique<ErrorNode>();
    }
    m_dil_lexer.Advance();
    auto rhs = ParseEqualityExpression();
    assert(rhs && "ASTNodeUP must not contain a nullptr");
    lhs = std::make_unique<BinaryOpNode>(
        token.GetLocation(), GetBinaryOpKindFromToken(token.GetKind()),
        std::move(lhs), std::move(rhs));
  }

  return lhs;
}

// Parse an equality_expression.
//
//  equality_expression:
//    relational_expression {"==" relational_expression}
//    relational_expression {"!=" relational_expression}
//
ASTNodeUP DILParser::ParseEqualityExpression() {
  auto lhs = ParseRelationalExpression();
  assert(lhs && "ASTNodeUP must not contain a nullptr");

  while (CurToken().IsOneOf({Token::equalequal, Token::exclaimequal})) {
    Token token = CurToken();
    m_dil_lexer.Advance();
    auto rhs = ParseRelationalExpression();
    assert(rhs && "ASTNodeUP must not contain a nullptr");
    lhs = std::make_unique<BinaryOpNode>(
        token.GetLocation(), GetBinaryOpKindFromToken(token.GetKind()),
        std::move(lhs), std::move(rhs));
  }

  return lhs;
}

// Parse a relational_expression.
//
//  relational_expression:
//    shift_expression {"<" shift_expression}
//    shift_expression {">" shift_expression}
//    shift_expression {"<=" shift_expression}
//    shift_expression {">=" shift_expression}
//
ASTNodeUP DILParser::ParseRelationalExpression() {
  auto lhs = ParseShiftExpression();
  assert(lhs && "ASTNodeUP must not contain a nullptr");

  while (CurToken().IsOneOf(
      {Token::less, Token::greater, Token::lessequal, Token::greaterequal})) {
    Token token = CurToken();
    m_dil_lexer.Advance();
    auto rhs = ParseShiftExpression();
    assert(rhs && "ASTNodeUP must not contain a nullptr");
    lhs = std::make_unique<BinaryOpNode>(
        token.GetLocation(), GetBinaryOpKindFromToken(token.GetKind()),
        std::move(lhs), std::move(rhs));
  }

  return lhs;
}

// Parse a shift_expression.
//
//  shift_expression:
//    additive_expression {"<<" additive_expression}
//    additive_expression {">>" additive_expression}
//
ASTNodeUP DILParser::ParseShiftExpression() {
  auto lhs = ParseAdditiveExpression();
  assert(lhs && "ASTNodeUP must not contain a nullptr");

  while (CurToken().IsOneOf({Token::lessless, Token::greatergreater})) {
    Token token = CurToken();
    m_dil_lexer.Advance();
    auto rhs = ParseAdditiveExpression();
    assert(rhs && "ASTNodeUP must not contain a nullptr");
    lhs = std::make_unique<BinaryOpNode>(
        token.GetLocation(), GetBinaryOpKindFromToken(token.GetKind()),
        std::move(lhs), std::move(rhs));
  }

  return lhs;
}

// Parse an additive_expression.
//
//  additive_expression:
//    multiplicative_expression {"+" multiplicative_expression}
//    multiplicative_expression {"-" multiplicative_expression}
//
ASTNodeUP DILParser::ParseAdditiveExpression() {
  auto lhs = ParseMultiplicativeExpression();
  assert(lhs && "ASTNodeUP must not contain a nullptr");

  while (CurToken().IsOneOf({Token::plus, Token::minus})) {
    Token token = CurToken();
    m_dil_lexer.Advance();
    auto rhs = ParseMultiplicativeExpression();
    assert(rhs && "ASTNodeUP must not contain a nullptr");
    lhs = std::make_unique<BinaryOpNode>(
        token.GetLocation(), GetBinaryOpKindFromToken(token.GetKind()),
        std::move(lhs), std::move(rhs));
  }

  return lhs;
}

// Parse a multiplicative_expression.
//
//  multiplicative_expression:
//    cast_expression {"*" cast_expression}
//    cast_expression {"/" cast_expression}
//    cast_expression {"%" cast_expression}
//
ASTNodeUP DILParser::ParseMultiplicativeExpression() {
  auto lhs = ParseCastExpression();

  while (CurToken().IsOneOf({Token::star, Token::slash, Token::percent})) {
    Token token = CurToken();
    if (token.Is(Token::star) && m_mode != lldb::eDILModeFull) {
      BailOut("binary multiplication (*) is allowed only in DIL full mode",
              token.GetLocation(), token.GetSpelling().length());
      return std::make_unique<ErrorNode>();
    }
    m_dil_lexer.Advance();
    auto rhs = ParseCastExpression();
    assert(rhs && "ASTNodeUP must not contain a nullptr");
    lhs = std::make_unique<BinaryOpNode>(
        token.GetLocation(), GetBinaryOpKindFromToken(token.GetKind()),
        std::move(lhs), std::move(rhs));
  }

  return lhs;
}

// Parse a cast_expression.
//
// cast_expression:
//   unary_expression
//   "(" type_id ")" cast_expression

ASTNodeUP DILParser::ParseCastExpression() {
  if (!CurToken().Is(Token::l_paren))
    return ParseUnaryExpression();

  // This could be a type cast, try parsing the contents as a type declaration.
  Token token = CurToken();
  uint32_t loc = token.GetLocation();

  // Enable lexer backtracking, so that we can rollback in case it's not
  // actually a type declaration.

  // Start tentative parsing (save token location/idx, for possible rollback).
  uint32_t save_token_idx = m_dil_lexer.GetCurrentTokenIdx();

  // Consume the token only after enabling the backtracking.
  m_dil_lexer.Advance();

  // Try parsing the type declaration. If the returned value is not valid,
  // then we should rollback and try parsing the expression.
  auto type_id = ParseTypeId();
  if (type_id) {
    // Successfully parsed the type declaration. Commit the backtracked
    // tokens and parse the cast_expression.

    if (!type_id.value().IsValid())
      return std::make_unique<ErrorNode>();

    Expect(Token::r_paren);
    m_dil_lexer.Advance();
    auto rhs = ParseCastExpression();
    assert(rhs && "ASTNodeUP must not contain a nullptr");
    return std::make_unique<CastNode>(loc, type_id.value(), std::move(rhs),
                                      CastKind::eNone);
  }

  // Failed to parse the contents of the parentheses as a type declaration.
  // Rollback the lexer and try parsing it as unary_expression.
  TentativeParsingRollback(save_token_idx);

  return ParseUnaryExpression();
}

// Parse an unary_expression.
//
//  unary_expression:
//    postfix_expression
//    unary_operator cast_expression
//
//  unary_operator:
//    "&"
//    "*"
//    "+"
//    "-"
//    "~"
//    "!"
//
ASTNodeUP DILParser::ParseUnaryExpression() {
  if (CurToken().IsOneOf({Token::amp, Token::star, Token::minus, Token::plus,
                          Token::tilde, Token::exclaim, Token::minusminus,
                          Token::plusplus})) {
    Token token = CurToken();
    uint32_t loc = token.GetLocation();
    m_dil_lexer.Advance();
    auto rhs = ParseCastExpression();
    assert(rhs && "ASTNodeUP must not contain a nullptr");
    switch (token.GetKind()) {
    case Token::star:
      return std::make_unique<UnaryOpNode>(loc, UnaryOpKind::Deref,
                                           std::move(rhs));
    case Token::amp:
      return std::make_unique<UnaryOpNode>(loc, UnaryOpKind::AddrOf,
                                           std::move(rhs));
    case Token::minus:
      return std::make_unique<UnaryOpNode>(loc, UnaryOpKind::Minus,
                                           std::move(rhs));
    case Token::plus:
      return std::make_unique<UnaryOpNode>(loc, UnaryOpKind::Plus,
                                           std::move(rhs));
    case Token::tilde:
      return std::make_unique<UnaryOpNode>(loc, UnaryOpKind::Not,
                                           std::move(rhs));
    case Token::exclaim:
      return std::make_unique<UnaryOpNode>(loc, UnaryOpKind::LNot,
                                           std::move(rhs));
    case Token::minusminus:
      BailOut("Decrement operator is not supported. Use `-=` instead.",
              CurToken().GetLocation(), CurToken().GetSpelling().length());
      return std::make_unique<ErrorNode>();
    case Token::plusplus:
      BailOut("Increment operator is not supported. Use `+=` instead.",
              CurToken().GetLocation(), CurToken().GetSpelling().length());
      return std::make_unique<ErrorNode>();
    default:
      llvm_unreachable("invalid token kind");
    }
  }
  return ParsePostfixExpression();
}

// Parse a postfix_expression.
//
//  postfix_expression:
//    primary_expression
//    postfix_expression "[" pure_expression "]"
//    postfix_expression "[" pure_expression ":" pure_expression "]"
//    postfix_expression "." id_expression
//    postfix_expression "->" id_expression
//
ASTNodeUP DILParser::ParsePostfixExpression() {
  ASTNodeUP lhs = ParsePrimaryExpression();
  assert(lhs && "ASTNodeUP must not contain a nullptr");
  while (CurToken().IsOneOf({Token::l_square, Token::period, Token::arrow,
                             Token::minusminus, Token::plusplus})) {
    uint32_t loc = CurToken().GetLocation();
    Token token = CurToken();
    switch (token.GetKind()) {
    case Token::l_square: {
      m_dil_lexer.Advance();
      ASTNodeUP index = ParsePureExpression();
      assert(index && "ASTNodeUP must not contain a nullptr");
      if (CurToken().GetKind() == Token::colon) {
        m_dil_lexer.Advance();
        ASTNodeUP last_index = ParsePureExpression();
        assert(last_index && "ASTNodeUP must not contain a nullptr");
        lhs = std::make_unique<BitFieldExtractionNode>(
            loc, std::move(lhs), std::move(index), std::move(last_index));
      } else if (CurToken().GetKind() == Token::minus) {
        BailOut("use of '-' for bitfield range is deprecated; use ':' instead",
                CurToken().GetLocation(), CurToken().GetSpelling().length());
        return std::make_unique<ErrorNode>();
      } else {
        lhs = std::make_unique<ArraySubscriptNode>(loc, std::move(lhs),
                                                   std::move(index));
      }
      Expect(Token::r_square);
      m_dil_lexer.Advance();
      break;
    }
    case Token::period:
    case Token::arrow: {
      m_dil_lexer.Advance();
      Token member_token = CurToken();
      std::string member_id = ParseIdExpression();
      lhs = std::make_unique<MemberOfNode>(
          member_token.GetLocation(), std::move(lhs),
          token.GetKind() == Token::arrow, member_id);
      break;
    }
    case Token::minusminus:
      BailOut("Decrement operator is not supported. Use `-=` instead.",
              CurToken().GetLocation(), CurToken().GetSpelling().length());
      return std::make_unique<ErrorNode>();
    case Token::plusplus:
      BailOut("Increment operator is not supported. Use `+=` instead.",
              CurToken().GetLocation(), CurToken().GetSpelling().length());
      return std::make_unique<ErrorNode>();
    default:
      llvm_unreachable("invalid token");
    }
  }

  return lhs;
}

// Parse a primary_expression.
//
//  primary_expression:
//    numeric_literal
//    boolean_literal
//    id_expression
//    "(" pure_expression ")"
//
ASTNodeUP DILParser::ParsePrimaryExpression() {
  if (CurToken().IsOneOf({Token::integer_constant, Token::float_constant}))
    return ParseNumericLiteral();
  if (CurToken().IsOneOf({Token::kw_true, Token::kw_false}))
    return ParseBooleanLiteral();
  if (CurToken().IsOneOf(
          {Token::coloncolon, Token::identifier, Token::l_paren})) {
    // Save the source location for the diagnostics message.
    uint32_t loc = CurToken().GetLocation();
    std::string identifier = ParseIdExpression();

    if (!identifier.empty()) {
      if (identifier == "sizeof" && CurToken().Is(Token::l_paren)) {
        m_dil_lexer.Advance();
        uint32_t save_token_idx = m_dil_lexer.GetCurrentTokenIdx();
        auto type_id = ParseTypeId();
        if (type_id) {
          Expect(Token::r_paren);
          m_dil_lexer.Advance();
          return std::make_unique<SizeOfNode>(loc, *type_id);
        }
        TentativeParsingRollback(save_token_idx);
        ASTNodeUP expr = ParsePureExpression();
        Expect(Token::r_paren);
        m_dil_lexer.Advance();
        return std::make_unique<SizeOfNode>(loc, std::move(expr));
      }
      return std::make_unique<IdentifierNode>(loc, identifier);
    }
  }

  if (CurToken().Is(Token::l_paren)) {
    m_dil_lexer.Advance();
    auto expr = ParsePureExpression();
    Expect(Token::r_paren);
    m_dil_lexer.Advance();
    return expr;
  }

  BailOut(llvm::formatv("Unexpected token: {0}", CurToken()),
          CurToken().GetLocation(), CurToken().GetSpelling().length());
  return std::make_unique<ErrorNode>();
}

// Parse nested_name_specifier.
//
//  nested_name_specifier:
//    type_name "::"
//    namespace_name "::"
//    nested_name_specifier identifier "::"
//
std::string DILParser::ParseNestedNameSpecifier() {
  // The first token in nested_name_specifier is always an identifier, or
  // '(anonymous namespace)'.
  switch (CurToken().GetKind()) {
  case Token::l_paren: {
    // Anonymous namespaces need to be treated specially: They are
    // represented the the string '(anonymous namespace)', which has a
    // space in it (throwing off normal parsing) and is not actually
    // proper C++> Check to see if we're looking at
    // '(anonymous namespace)::...'

    // Look for all the pieces, in order:
    // l_paren 'anonymous' 'namespace' r_paren coloncolon
    if (m_dil_lexer.LookAhead(1).Is(Token::identifier) &&
        (m_dil_lexer.LookAhead(1).GetSpelling() == "anonymous") &&
        m_dil_lexer.LookAhead(2).Is(Token::identifier) &&
        (m_dil_lexer.LookAhead(2).GetSpelling() == "namespace") &&
        m_dil_lexer.LookAhead(3).Is(Token::r_paren) &&
        m_dil_lexer.LookAhead(4).Is(Token::coloncolon)) {
      m_dil_lexer.Advance(4);

      Expect(Token::coloncolon);
      m_dil_lexer.Advance();
      if (!CurToken().Is(Token::identifier) && !CurToken().Is(Token::l_paren)) {
        BailOut("Expected an identifier or anonymous namespace, but not found.",
                CurToken().GetLocation(), CurToken().GetSpelling().length());
      }
      // Continue parsing the nested_namespace_specifier.
      std::string identifier2 = ParseNestedNameSpecifier();

      return "(anonymous namespace)::" + identifier2;
    }

    return "";
  } // end of special handling for '(anonymous namespace)'
  case Token::identifier: {
    // If the next token is scope ("::"), then this is indeed a
    // nested_name_specifier
    if (m_dil_lexer.LookAhead(1).Is(Token::coloncolon)) {
      // This nested_name_specifier is a single identifier.
      std::string identifier = CurToken().GetSpelling();
      m_dil_lexer.Advance(1);
      Expect(Token::coloncolon);
      m_dil_lexer.Advance();
      // Continue parsing the nested_name_specifier.
      return identifier + "::" + ParseNestedNameSpecifier();
    }

    return "";
  }
  default:
    return "";
  }
}

// Parse a type_id.
//
//  type_id:
//    type_specifier_seq [abstract_declarator]
//
//  type_specifier_seq:
//    type_specifier [type_specifier]
//
//  type_specifier:
//    ["::"] [nested_name_specifier] type_name // not handled for now!
//    builtin_typename
//
std::optional<CompilerType> DILParser::ParseTypeId() {
  CompilerType type;
  auto maybe_builtin_type = ParseBuiltinType();
  if (maybe_builtin_type) {
    type = *maybe_builtin_type;
  } else {
    // Check to see if we have a user-defined type here.
    // First build  up the user-defined type name.
    std::string type_name;
    ParseTypeSpecifierSeq(type_name);

    if (type_name.empty())
      return {};
    type = ResolveTypeByName(type_name, m_exe_ctx);
    if (!type.IsValid())
      return {};

    // Same-name identifiers should be preferred over typenames.
    if (LookupIdentifier(type_name, m_exe_ctx, m_use_dynamic))
      // TODO: Make type accessible with 'class', 'struct' and 'union' keywords.
      return {};

    // Same-name identifiers should be preferred over typenames.
    if (LookupGlobalIdentifier(type_name, m_exe_ctx, m_use_dynamic))
      // TODO: Make type accessible with 'class', 'struct' and 'union' keywords
      return {};
  }

  //
  //  abstract_declarator:
  //    ptr_operator [abstract_declarator]
  //
  std::vector<Token> ptr_operators;
  while (CurToken().IsOneOf({Token::star, Token::amp})) {
    Token tok = CurToken();
    ptr_operators.push_back(std::move(tok));
    m_dil_lexer.Advance();
  }
  type = ResolveTypeDeclarators(type, ptr_operators);

  return type;
}

// Parse a built-in type
//
// builtin_typename:
//   identifer_seq
//
//  identifier_seq
//    identifer [identifier_seq]
//
// A built-in type can be a single identifier or a space-separated
// list of identifiers (e.g. "short" or "long long").
std::optional<CompilerType> DILParser::ParseBuiltinType() {
  std::string type_name = "";
  uint32_t save_token_idx = m_dil_lexer.GetCurrentTokenIdx();
  bool first_word = true;
  while (CurToken().GetKind() == Token::identifier) {
    if (CurToken().GetSpelling() == "const" ||
        CurToken().GetSpelling() == "volatile") {
      m_dil_lexer.Advance();
      continue;
    }
    if (!first_word)
      type_name.push_back(' ');
    else
      first_word = false;
    type_name.append(CurToken().GetSpelling());
    m_dil_lexer.Advance();
  }

  if (type_name.size() > 0) {
    lldb::TargetSP target_sp = m_exe_ctx.GetTargetSP();
    if (!target_sp)
      return {};
    ConstString const_type_name(type_name);
    for (auto type_system_sp : target_sp->GetScratchTypeSystems())
      if (auto compiler_type =
              type_system_sp->GetBuiltinTypeByName(const_type_name))
        return compiler_type;
  }

  TentativeParsingRollback(save_token_idx);
  return {};
}

// Parse a type_specifier_seq.
//
//  type_specifier_seq:
//    type_specifier [type_specifier_seq]
//
void DILParser::ParseTypeSpecifierSeq(std::string &type_name) {
  while (true) {
    std::optional<std::string> err_or_string = ParseTypeSpecifier();
    if (!err_or_string)
      break;
    type_name = *err_or_string;
  }
}

// Parse a type_specifier.
//
//  type_specifier:
//    ["::"] [nested_name_specifier] type_name
//
// Returns TRUE if a type_specifier was successfully parsed at this location.
//
std::optional<std::string> DILParser::ParseTypeSpecifier() {
  // The type_specifier must be a user-defined type. Try parsing a
  // simple_type_specifier.

  // Try parsing optional global scope operator.
  bool global_scope = false;
  if (CurToken().Is(Token::coloncolon)) {
    global_scope = true;
    m_dil_lexer.Advance();
  }

  // Try parsing optional nested_name_specifier.
  auto nested_name_specifier = ParseNestedNameSpecifier();

  // Try parsing required type_name.
  auto type_name_or_err = ParseTypeName();
  if (!type_name_or_err)
    return type_name_or_err;
  std::string type_name = *type_name_or_err;

  // If there is a type_name, then this is indeed a simple_type_specifier.
  // Global and qualified (namespace/class) scopes can be empty, since they're
  // optional. In this case type_name is type we're looking for.
  if (!type_name.empty())
    // User-defined typenames can't be combined with builtin keywords.
    return llvm::formatv("{0}{1}{2}", global_scope ? "::" : "",
                         nested_name_specifier, type_name);

  // No type_specifier was found here.
  return {};
}

// Parse a type_name.
//
//  type_name:
//    class_name
//    enum_name
//    typedef_name
//
//  class_name
//    identifier
//
//  enum_name
//    identifier
//
//  typedef_name
//    identifier
//
std::optional<std::string> DILParser::ParseTypeName() {
  // Typename always starts with an identifier.
  if (CurToken().IsNot(Token::identifier)) {
    return std::nullopt;
  }

  // Otherwise look for a class_name, enum_name or a typedef_name.
  std::string identifier = CurToken().GetSpelling();
  m_dil_lexer.Advance();

  return identifier;
}

// Parse an id_expression.
//
//  id_expression:
//    unqualified_id
//    qualified_id
//
//  qualified_id:
//    ["::"] [nested_name_specifier] unqualified_id
//    ["::"] identifier
//
//  identifier:
//    ? Token::identifier ?
//
std::string DILParser::ParseIdExpression() {
  // Try parsing optional global scope operator.
  bool global_scope = false;
  if (CurToken().Is(Token::coloncolon)) {
    global_scope = true;
    m_dil_lexer.Advance();
  }

  // Try parsing optional nested_name_specifier.
  std::string nested_name_specifier = ParseNestedNameSpecifier();

  // If nested_name_specifier is present, then it's qualified_id production.
  // Follow the first production rule.
  if (!nested_name_specifier.empty()) {
    // Parse unqualified_id and construct a fully qualified id expression.
    auto unqualified_id = ParseUnqualifiedId();

    return llvm::formatv("{0}{1}{2}", global_scope ? "::" : "",
                         nested_name_specifier, unqualified_id);
  }

  if (!CurToken().Is(Token::identifier))
    return "";

  // No nested_name_specifier, but with global scope -- this is also a
  // qualified_id production. Follow the second production rule.
  if (global_scope) {
    Expect(Token::identifier);
    std::string identifier = CurToken().GetSpelling();
    m_dil_lexer.Advance();
    return llvm::formatv("{0}{1}", global_scope ? "::" : "", identifier);
  }

  // This is unqualified_id production.
  return ParseUnqualifiedId();
}

// Parse an unqualified_id.
//
//  unqualified_id:
//    identifier
//
//  identifier:
//    ? Token::identifier ?
//
std::string DILParser::ParseUnqualifiedId() {
  Expect(Token::identifier);
  std::string identifier = CurToken().GetSpelling();
  m_dil_lexer.Advance();
  return identifier;
}

CompilerType
DILParser::ResolveTypeDeclarators(CompilerType type,
                                  const std::vector<Token> &ptr_operators) {
  // Resolve pointers/references.
  for (Token tk : ptr_operators) {
    uint32_t loc = tk.GetLocation();
    if (tk.GetKind() == Token::star) {
      // Pointers to reference types are forbidden.
      if (type.IsReferenceType()) {
        BailOut(llvm::formatv("'type name' declared as a pointer to a "
                              "reference of type {0}",
                              type.TypeDescription()),
                loc, CurToken().GetSpelling().length());
        return {};
      }
      // Get pointer type for the base type: e.g. int* -> int**.
      type = type.GetPointerType();

    } else if (tk.GetKind() == Token::amp) {
      // References to references are forbidden.
      // FIXME: In future we may want to allow rvalue references (i.e. &&).
      if (type.IsReferenceType()) {
        BailOut("type name declared as a reference to a reference", loc,
                CurToken().GetSpelling().length());
        return {};
      }
      // Get reference type for the base type: e.g. int -> int&.
      type = type.GetLValueReferenceType();
    }
  }

  return type;
}

// Parse an boolean_literal.
//
//  boolean_literal:
//    "true"
//    "false"
//
ASTNodeUP DILParser::ParseBooleanLiteral() {
  ExpectOneOf(std::vector<Token::Kind>{Token::kw_true, Token::kw_false});
  uint32_t loc = CurToken().GetLocation();
  bool literal_value = CurToken().Is(Token::kw_true);
  m_dil_lexer.Advance();
  return std::make_unique<BooleanLiteralNode>(loc, literal_value);
}

void DILParser::BailOut(const std::string &error, uint32_t loc,
                        uint16_t err_len) {
  if (m_error)
    // If error is already set, then the parser is in the "bail-out" mode. Don't
    // do anything and keep the original error.
    return;

  m_error =
      llvm::make_error<DILDiagnosticError>(m_input_expr, error, loc, err_len);
  // Advance the lexer token index to the end of the lexed tokens vector.
  m_dil_lexer.ResetTokenIdx(m_dil_lexer.NumLexedTokens() - 1);
}

// Parse a numeric_literal.
//
//  numeric_literal:
//    ? Token::integer_constant ?
//    ? Token::floating_constant ?
//
ASTNodeUP DILParser::ParseNumericLiteral() {
  ASTNodeUP numeric_constant;
  if (CurToken().Is(Token::integer_constant))
    numeric_constant = ParseIntegerLiteral();
  else
    numeric_constant = ParseFloatingPointLiteral();
  if (numeric_constant->GetKind() == NodeKind::eErrorNode) {
    BailOut(llvm::formatv("Failed to parse token as numeric-constant: {0}",
                          CurToken()),
            CurToken().GetLocation(), CurToken().GetSpelling().length());
    return numeric_constant;
  }
  m_dil_lexer.Advance();
  return numeric_constant;
}

ASTNodeUP DILParser::ParseIntegerLiteral() {
  Token token = CurToken();
  auto spelling = token.GetSpelling();
  llvm::StringRef spelling_ref = spelling;

  auto radix = llvm::getAutoSenseRadix(spelling_ref);
  IntegerTypeSuffix type = IntegerTypeSuffix::None;
  bool is_unsigned = false;
  if (spelling_ref.consume_back_insensitive("u"))
    is_unsigned = true;
  if (spelling_ref.consume_back_insensitive("ll"))
    type = IntegerTypeSuffix::LongLong;
  else if (spelling_ref.consume_back_insensitive("l"))
    type = IntegerTypeSuffix::Long;
  // Suffix 'u' can be only specified only once, before or after 'l'
  if (!is_unsigned && spelling_ref.consume_back_insensitive("u"))
    is_unsigned = true;

  llvm::APInt raw_value;
  if (!spelling_ref.getAsInteger(radix, raw_value))
    return std::make_unique<IntegerLiteralNode>(token.GetLocation(), raw_value,
                                                radix, is_unsigned, type);
  return std::make_unique<ErrorNode>();
}

ASTNodeUP DILParser::ParseFloatingPointLiteral() {
  Token token = CurToken();
  auto spelling = token.GetSpelling();
  llvm::StringRef spelling_ref = spelling;

  llvm::APFloat raw_float(llvm::APFloat::IEEEdouble());
  if (spelling_ref.consume_back_insensitive("f"))
    raw_float = llvm::APFloat(llvm::APFloat::IEEEsingle());

  auto StatusOrErr = raw_float.convertFromString(
      spelling_ref, llvm::APFloat::rmNearestTiesToEven);
  if (!errorToBool(StatusOrErr.takeError()))
    return std::make_unique<FloatLiteralNode>(token.GetLocation(), raw_float);
  return std::make_unique<ErrorNode>();
}

void DILParser::Expect(Token::Kind kind) {
  if (CurToken().IsOneOf({Token::equal, Token::plusequal, Token::minusequal})) {
    BailOut("Assignment is allowed only at top level.",
            CurToken().GetLocation(), CurToken().GetSpelling().length());
  }
  if (CurToken().IsNot(kind)) {
    BailOut(llvm::formatv("expected {0}, got: {1}", kind, CurToken()),
            CurToken().GetLocation(), CurToken().GetSpelling().length());
  }
}

void DILParser::ExpectOneOf(std::vector<Token::Kind> kinds_vec) {
  if (!CurToken().IsOneOf(kinds_vec)) {
    BailOut(llvm::formatv("expected any of ({0}), got: {1}",
                          llvm::iterator_range(kinds_vec), CurToken()),
            CurToken().GetLocation(), CurToken().GetSpelling().length());
  }
}

} // namespace lldb_private::dil
