//===- llvm/MC/MCAsmParserExtension.h - Asm Parser Hooks --------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_MC_MCPARSER_MCASMPARSEREXTENSION_H
#define LLVM_MC_MCPARSER_MCASMPARSEREXTENSION_H

#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/Support/SMLoc.h"

namespace llvm {

class Twine;

/// Generic interface for extending the MCAsmParser,
/// which is implemented by target and object file assembly parser
/// implementations.
class MCAsmParserExtension {
  MCAsmParser *Parser;

protected:
  MCAsmParserExtension();

  // Helper template for implementing static dispatch functions.
  template<typename T, bool (T::*Handler)(StringRef, SMLoc)>
  static bool HandleDirective(MCAsmParserExtension *Target,
                              StringRef Directive,
                              SMLoc DirectiveLoc) {
    T *Obj = static_cast<T*>(Target);
    return (Obj->*Handler)(Directive, DirectiveLoc);
  }

  bool BracketExpressionsSupported = false;

public:
  MCAsmParserExtension(const MCAsmParserExtension &) = delete;
  MCAsmParserExtension &operator=(const MCAsmParserExtension &) = delete;
  virtual ~MCAsmParserExtension();

  /// Initialize the extension for parsing using the given \p Parser.
  /// The extension should use the AsmParser interfaces to register its
  /// parsing routines.
  virtual void Initialize(MCAsmParser &Parser);

  /// \name MCAsmParser Proxy Interfaces
  /// @{

  MCContext &getContext() { return getParser().getContext(); }

  MCAsmLexer &getLexer() { return getParser().getLexer(); }
  const MCAsmLexer &getLexer() const {
    return const_cast<MCAsmParserExtension *>(this)->getLexer();
  }

  MCAsmParser &getParser() { return *Parser; }
  const MCAsmParser &getParser() const {
    return const_cast<MCAsmParserExtension*>(this)->getParser();
  }

  SourceMgr &getSourceManager() { return getParser().getSourceManager(); }
  MCStreamer &getStreamer() { return getParser().getStreamer(); }

  bool Warning(SMLoc L, const Twine &Msg) {
    return getParser().Warning(L, Msg);
  }

  bool Error(SMLoc L, const Twine &Msg, SMRange Range = SMRange()) {
    return getParser().Error(L, Msg, Range);
  }

  void Note(SMLoc L, const Twine &Msg) {
    getParser().Note(L, Msg);
  }

  bool TokError(const Twine &Msg) {
    return getParser().TokError(Msg);
  }

  const AsmToken &Lex() { return getParser().Lex(); }
  const AsmToken &getTok() { return getParser().getTok(); }
  bool parseToken(AsmToken::TokenKind T,
                  const Twine &Msg = "unexpected token") {
    return getParser().parseToken(T, Msg);
  }
  bool parseEOL() { return getParser().parseEOL(); }

  bool parseMany(function_ref<bool()> parseOne, bool hasComma = true) {
    return getParser().parseMany(parseOne, hasComma);
  }

  bool parseOptionalToken(AsmToken::TokenKind T) {
    return getParser().parseOptionalToken(T);
  }

  bool ParseDirectiveCGProfile(StringRef, SMLoc);

  bool check(bool P, const Twine &Msg) {
    return getParser().check(P, Msg);
  }

  bool check(bool P, SMLoc Loc, const Twine &Msg) {
    return getParser().check(P, Loc, Msg);
  }

  bool addErrorSuffix(const Twine &Suffix) {
    return getParser().addErrorSuffix(Suffix);
  }

  bool HasBracketExpressions() const { return BracketExpressionsSupported; }

  /// @}
};

} // end namespace llvm

#endif // LLVM_MC_MCPARSER_MCASMPARSEREXTENSION_H
