//===-- ClangASTContext.h ---------------------------------------*- 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 liblldb_ClangASTContext_h_
#define liblldb_ClangASTContext_h_

#include <stdint.h>

#include <functional>
#include <initializer_list>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include "clang/AST/ASTContext.h"
#include "clang/AST/ExternalASTMerger.h"
#include "clang/AST/TemplateBase.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/SmallVector.h"

#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Symbol/CompilerType.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Utility/ConstString.h"
#include "lldb/lldb-enumerations.h"

class DWARFASTParserClang;
class PDBASTParser;

namespace lldb_private {

class Declaration;

class ClangASTContext : public TypeSystem {
public:
  typedef void (*CompleteTagDeclCallback)(void *baton, clang::TagDecl *);
  typedef void (*CompleteObjCInterfaceDeclCallback)(void *baton,
                                                    clang::ObjCInterfaceDecl *);

  // llvm casting support
  static bool classof(const TypeSystem *ts) {
    return ts->getKind() == TypeSystem::eKindClang;
  }

  // Constructors and Destructors
  ClangASTContext(const char *triple = nullptr);

  ~ClangASTContext() override;

  void Finalize() override;

  // PluginInterface functions
  ConstString GetPluginName() override;

  uint32_t GetPluginVersion() override;

  static ConstString GetPluginNameStatic();

  static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language,
                                           Module *module, Target *target);

  static void EnumerateSupportedLanguages(
      std::set<lldb::LanguageType> &languages_for_types,
      std::set<lldb::LanguageType> &languages_for_expressions);

  static void Initialize();

  static void Terminate();

  static ClangASTContext *GetASTContext(clang::ASTContext *ast_ctx);

  clang::ASTContext *getASTContext();

  void setASTContext(clang::ASTContext *ast_ctx);

  clang::Builtin::Context *getBuiltinContext();

  clang::IdentifierTable *getIdentifierTable();

  clang::LangOptions *getLanguageOptions();

  clang::SelectorTable *getSelectorTable();

  clang::FileManager *getFileManager();

  clang::SourceManager *getSourceManager();

  clang::DiagnosticsEngine *getDiagnosticsEngine();

  clang::DiagnosticConsumer *getDiagnosticConsumer();

  clang::MangleContext *getMangleContext();

  std::shared_ptr<clang::TargetOptions> &getTargetOptions();

  clang::TargetInfo *getTargetInfo();

  void setSema(clang::Sema *s);
  clang::Sema *getSema() { return m_sema; }

  void Clear();

  const char *GetTargetTriple();

  void SetTargetTriple(const char *target_triple);

  void SetArchitecture(const ArchSpec &arch);

  bool HasExternalSource();

  void SetExternalSource(
      llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> &ast_source_up);

  void RemoveExternalSource();

  bool GetCompleteDecl(clang::Decl *decl) {
    return ClangASTContext::GetCompleteDecl(getASTContext(), decl);
  }

  static void DumpDeclHiearchy(clang::Decl *decl);

  static void DumpDeclContextHiearchy(clang::DeclContext *decl_ctx);

  static bool DeclsAreEquivalent(clang::Decl *lhs_decl, clang::Decl *rhs_decl);

  static bool GetCompleteDecl(clang::ASTContext *ast, clang::Decl *decl);

  void SetMetadataAsUserID(const void *object, lldb::user_id_t user_id);

  void SetMetadata(const void *object, ClangASTMetadata &meta_data) {
    SetMetadata(getASTContext(), object, meta_data);
  }

  static void SetMetadata(clang::ASTContext *ast, const void *object,
                          ClangASTMetadata &meta_data);

  ClangASTMetadata *GetMetadata(const void *object) {
    return GetMetadata(getASTContext(), object);
  }

  static ClangASTMetadata *GetMetadata(clang::ASTContext *ast,
                                       const void *object);

  // Basic Types
  CompilerType GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding,
                                                   size_t bit_size) override;

  static CompilerType GetBuiltinTypeForEncodingAndBitSize(
      clang::ASTContext *ast, lldb::Encoding encoding, uint32_t bit_size);

  CompilerType GetBasicType(lldb::BasicType type);

  static CompilerType GetBasicType(clang::ASTContext *ast,
                                   lldb::BasicType type);

  static CompilerType GetBasicType(clang::ASTContext *ast,
                                   ConstString name);

  static lldb::BasicType GetBasicTypeEnumeration(ConstString name);

  CompilerType GetBuiltinTypeForDWARFEncodingAndBitSize(const char *type_name,
                                                        uint32_t dw_ate,
                                                        uint32_t bit_size);

  CompilerType GetCStringType(bool is_const);

  static CompilerType GetUnknownAnyType(clang::ASTContext *ast);

  CompilerType GetUnknownAnyType() {
    return ClangASTContext::GetUnknownAnyType(getASTContext());
  }

  static clang::DeclContext *GetDeclContextForType(clang::QualType type);

  static clang::DeclContext *GetDeclContextForType(const CompilerType &type);

  uint32_t GetPointerByteSize() override;

  static clang::DeclContext *GetTranslationUnitDecl(clang::ASTContext *ast);

  clang::DeclContext *GetTranslationUnitDecl() {
    return GetTranslationUnitDecl(getASTContext());
  }

  static clang::Decl *CopyDecl(clang::ASTContext *dest_context,
                               clang::ASTContext *source_context,
                               clang::Decl *source_decl);

  static bool AreTypesSame(CompilerType type1, CompilerType type2,
                           bool ignore_qualifiers = false);

  static CompilerType GetTypeForDecl(clang::NamedDecl *decl);

  static CompilerType GetTypeForDecl(clang::TagDecl *decl);

  static CompilerType GetTypeForDecl(clang::ObjCInterfaceDecl *objc_decl);

  template <typename RecordDeclType>
  CompilerType
  GetTypeForIdentifier(ConstString type_name,
                       clang::DeclContext *decl_context = nullptr) {
    CompilerType compiler_type;

    if (type_name.GetLength()) {
      clang::ASTContext *ast = getASTContext();
      if (ast) {
        if (!decl_context)
          decl_context = ast->getTranslationUnitDecl();

        clang::IdentifierInfo &myIdent =
            ast->Idents.get(type_name.GetCString());
        clang::DeclarationName myName =
            ast->DeclarationNames.getIdentifier(&myIdent);

        clang::DeclContext::lookup_result result =
            decl_context->lookup(myName);

        if (!result.empty()) {
          clang::NamedDecl *named_decl = result[0];
          if (const RecordDeclType *record_decl =
                  llvm::dyn_cast<RecordDeclType>(named_decl))
            compiler_type.SetCompilerType(
                ast, clang::QualType(record_decl->getTypeForDecl(), 0));
        }
      }
    }

    return compiler_type;
  }

  CompilerType CreateStructForIdentifier(
      ConstString type_name,
      const std::initializer_list<std::pair<const char *, CompilerType>>
          &type_fields,
      bool packed = false);

  CompilerType GetOrCreateStructForIdentifier(
      ConstString type_name,
      const std::initializer_list<std::pair<const char *, CompilerType>>
          &type_fields,
      bool packed = false);

  static bool IsOperator(const char *name,
                         clang::OverloadedOperatorKind &op_kind);

  // Structure, Unions, Classes

  static clang::AccessSpecifier
  ConvertAccessTypeToAccessSpecifier(lldb::AccessType access);

  static clang::AccessSpecifier
  UnifyAccessSpecifiers(clang::AccessSpecifier lhs, clang::AccessSpecifier rhs);

  static uint32_t GetNumBaseClasses(const clang::CXXRecordDecl *cxx_record_decl,
                                    bool omit_empty_base_classes);

  CompilerType CreateRecordType(clang::DeclContext *decl_ctx,
                                lldb::AccessType access_type, const char *name,
                                int kind, lldb::LanguageType language,
                                ClangASTMetadata *metadata = nullptr);

  class TemplateParameterInfos {
  public:
    bool IsValid() const {
      if (args.empty())
        return false;
      return args.size() == names.size() &&
        ((bool)pack_name == (bool)packed_args) &&
        (!packed_args || !packed_args->packed_args);
    }

    llvm::SmallVector<const char *, 2> names;
    llvm::SmallVector<clang::TemplateArgument, 2> args;
    
    const char * pack_name = nullptr;
    std::unique_ptr<TemplateParameterInfos> packed_args;
  };

  clang::FunctionTemplateDecl *
  CreateFunctionTemplateDecl(clang::DeclContext *decl_ctx,
                             clang::FunctionDecl *func_decl, const char *name,
                             const TemplateParameterInfos &infos);

  void CreateFunctionTemplateSpecializationInfo(
      clang::FunctionDecl *func_decl, clang::FunctionTemplateDecl *Template,
      const TemplateParameterInfos &infos);

  clang::ClassTemplateDecl *
  CreateClassTemplateDecl(clang::DeclContext *decl_ctx,
                          lldb::AccessType access_type, const char *class_name,
                          int kind, const TemplateParameterInfos &infos);

  clang::TemplateTemplateParmDecl *
  CreateTemplateTemplateParmDecl(const char *template_name);

  clang::ClassTemplateSpecializationDecl *CreateClassTemplateSpecializationDecl(
      clang::DeclContext *decl_ctx,
      clang::ClassTemplateDecl *class_template_decl, int kind,
      const TemplateParameterInfos &infos);

  CompilerType
  CreateClassTemplateSpecializationType(clang::ClassTemplateSpecializationDecl *
                                            class_template_specialization_decl);

  static clang::DeclContext *
  GetAsDeclContext(clang::CXXMethodDecl *cxx_method_decl);

  static clang::DeclContext *
  GetAsDeclContext(clang::ObjCMethodDecl *objc_method_decl);

  static bool CheckOverloadedOperatorKindParameterCount(
      bool is_method, clang::OverloadedOperatorKind op_kind,
      uint32_t num_params);

  bool FieldIsBitfield(clang::FieldDecl *field, uint32_t &bitfield_bit_size);

  static bool FieldIsBitfield(clang::ASTContext *ast, clang::FieldDecl *field,
                              uint32_t &bitfield_bit_size);

  static bool RecordHasFields(const clang::RecordDecl *record_decl);

  CompilerType CreateObjCClass(const char *name, clang::DeclContext *decl_ctx,
                               bool isForwardDecl, bool isInternal,
                               ClangASTMetadata *metadata = nullptr);

  bool SetTagTypeKind(clang::QualType type, int kind) const;

  bool SetDefaultAccessForRecordFields(clang::RecordDecl *record_decl,
                                       int default_accessibility,
                                       int *assigned_accessibilities,
                                       size_t num_assigned_accessibilities);

  // Returns a mask containing bits from the ClangASTContext::eTypeXXX
  // enumerations

  // Namespace Declarations

  clang::NamespaceDecl *
  GetUniqueNamespaceDeclaration(const char *name, clang::DeclContext *decl_ctx,
                                bool is_inline = false);

  static clang::NamespaceDecl *
  GetUniqueNamespaceDeclaration(clang::ASTContext *ast, const char *name,
                                clang::DeclContext *decl_ctx,
                                bool is_inline = false);

  // Function Types

  clang::FunctionDecl *
  CreateFunctionDeclaration(clang::DeclContext *decl_ctx, const char *name,
                            const CompilerType &function_Type, int storage,
                            bool is_inline);

  static CompilerType CreateFunctionType(clang::ASTContext *ast,
                                         const CompilerType &result_type,
                                         const CompilerType *args,
                                         unsigned num_args, bool is_variadic,
                                         unsigned type_quals,
                                         clang::CallingConv cc);

  static CompilerType CreateFunctionType(clang::ASTContext *ast,
                                         const CompilerType &result_type,
                                         const CompilerType *args,
                                         unsigned num_args, bool is_variadic,
                                         unsigned type_quals) {
    return ClangASTContext::CreateFunctionType(
        ast, result_type, args, num_args, is_variadic, type_quals, clang::CC_C);
  }

  CompilerType CreateFunctionType(const CompilerType &result_type,
                                  const CompilerType *args, unsigned num_args,
                                  bool is_variadic, unsigned type_quals) {
    return ClangASTContext::CreateFunctionType(
        getASTContext(), result_type, args, num_args, is_variadic, type_quals);
  }

  CompilerType CreateFunctionType(const CompilerType &result_type,
                                  const CompilerType *args, unsigned num_args,
                                  bool is_variadic, unsigned type_quals,
                                  clang::CallingConv cc) {
    return ClangASTContext::CreateFunctionType(getASTContext(), result_type,
                                               args, num_args, is_variadic,
                                               type_quals, cc);
  }

  clang::ParmVarDecl *CreateParameterDeclaration(clang::DeclContext *decl_ctx,
                                                 const char *name,
                                                 const CompilerType &param_type,
                                                 int storage);

  void SetFunctionParameters(clang::FunctionDecl *function_decl,
                             clang::ParmVarDecl **params, unsigned num_params);

  CompilerType CreateBlockPointerType(const CompilerType &function_type);

  // Array Types

  CompilerType CreateArrayType(const CompilerType &element_type,
                               size_t element_count, bool is_vector);

  // Enumeration Types
  CompilerType CreateEnumerationType(const char *name,
                                     clang::DeclContext *decl_ctx,
                                     const Declaration &decl,
                                     const CompilerType &integer_qual_type,
                                     bool is_scoped);

  // Integer type functions

  static CompilerType GetIntTypeFromBitSize(clang::ASTContext *ast,
                                            size_t bit_size, bool is_signed);

  CompilerType GetPointerSizedIntType(bool is_signed) {
    return GetPointerSizedIntType(getASTContext(), is_signed);
  }

  static CompilerType GetPointerSizedIntType(clang::ASTContext *ast,
                                             bool is_signed);

  // Floating point functions

  static CompilerType GetFloatTypeFromBitSize(clang::ASTContext *ast,
                                              size_t bit_size);

  // TypeSystem methods
  DWARFASTParser *GetDWARFParser() override;
  PDBASTParser *GetPDBParser() override;

  // ClangASTContext callbacks for external source lookups.
  static void CompleteTagDecl(void *baton, clang::TagDecl *);

  static void CompleteObjCInterfaceDecl(void *baton,
                                        clang::ObjCInterfaceDecl *);

  static bool LayoutRecordType(
      void *baton, const clang::RecordDecl *record_decl, uint64_t &size,
      uint64_t &alignment,
      llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
      llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
          &base_offsets,
      llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
          &vbase_offsets);

  // CompilerDecl override functions
  ConstString DeclGetName(void *opaque_decl) override;

  ConstString DeclGetMangledName(void *opaque_decl) override;

  CompilerDeclContext DeclGetDeclContext(void *opaque_decl) override;

  CompilerType DeclGetFunctionReturnType(void *opaque_decl) override;

  size_t DeclGetFunctionNumArguments(void *opaque_decl) override;

  CompilerType DeclGetFunctionArgumentType(void *opaque_decl,
                                           size_t arg_idx) override;

  // CompilerDeclContext override functions

  std::vector<CompilerDecl>
  DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name,
                            const bool ignore_using_decls) override;

  bool DeclContextIsStructUnionOrClass(void *opaque_decl_ctx) override;

  ConstString DeclContextGetName(void *opaque_decl_ctx) override;

  ConstString DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) override;

  bool DeclContextIsClassMethod(void *opaque_decl_ctx,
                                lldb::LanguageType *language_ptr,
                                bool *is_instance_method_ptr,
                                ConstString *language_object_name_ptr) override;

  bool DeclContextIsContainedInLookup(void *opaque_decl_ctx,
                                      void *other_opaque_decl_ctx) override;

  // Clang specific clang::DeclContext functions

  static clang::DeclContext *
  DeclContextGetAsDeclContext(const CompilerDeclContext &dc);

  static clang::ObjCMethodDecl *
  DeclContextGetAsObjCMethodDecl(const CompilerDeclContext &dc);

  static clang::CXXMethodDecl *
  DeclContextGetAsCXXMethodDecl(const CompilerDeclContext &dc);

  static clang::FunctionDecl *
  DeclContextGetAsFunctionDecl(const CompilerDeclContext &dc);

  static clang::NamespaceDecl *
  DeclContextGetAsNamespaceDecl(const CompilerDeclContext &dc);

  static ClangASTMetadata *DeclContextGetMetaData(const CompilerDeclContext &dc,
                                                  const void *object);

  static clang::ASTContext *
  DeclContextGetClangASTContext(const CompilerDeclContext &dc);

  // Tests

  bool IsArrayType(lldb::opaque_compiler_type_t type,
                   CompilerType *element_type, uint64_t *size,
                   bool *is_incomplete) override;

  bool IsVectorType(lldb::opaque_compiler_type_t type,
                    CompilerType *element_type, uint64_t *size) override;

  bool IsAggregateType(lldb::opaque_compiler_type_t type) override;

  bool IsAnonymousType(lldb::opaque_compiler_type_t type) override;

  bool IsBeingDefined(lldb::opaque_compiler_type_t type) override;

  bool IsCharType(lldb::opaque_compiler_type_t type) override;

  bool IsCompleteType(lldb::opaque_compiler_type_t type) override;

  bool IsConst(lldb::opaque_compiler_type_t type) override;

  bool IsCStringType(lldb::opaque_compiler_type_t type,
                     uint32_t &length) override;

  static bool IsCXXClassType(const CompilerType &type);

  bool IsDefined(lldb::opaque_compiler_type_t type) override;

  bool IsFloatingPointType(lldb::opaque_compiler_type_t type, uint32_t &count,
                           bool &is_complex) override;

  bool IsFunctionType(lldb::opaque_compiler_type_t type,
                      bool *is_variadic_ptr) override;

  uint32_t IsHomogeneousAggregate(lldb::opaque_compiler_type_t type,
                                  CompilerType *base_type_ptr) override;

  size_t
  GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) override;

  CompilerType GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type,
                                          const size_t index) override;

  bool IsFunctionPointerType(lldb::opaque_compiler_type_t type) override;

  bool IsBlockPointerType(lldb::opaque_compiler_type_t type,
                          CompilerType *function_pointer_type_ptr) override;

  bool IsIntegerType(lldb::opaque_compiler_type_t type,
                     bool &is_signed) override;

  bool IsEnumerationType(lldb::opaque_compiler_type_t type,
                         bool &is_signed) override;

  static bool IsObjCClassType(const CompilerType &type);

  static bool IsObjCClassTypeAndHasIVars(const CompilerType &type,
                                         bool check_superclass);

  static bool IsObjCObjectOrInterfaceType(const CompilerType &type);

  static bool IsObjCObjectPointerType(const CompilerType &type,
                                      CompilerType *target_type = nullptr);

  bool IsPolymorphicClass(lldb::opaque_compiler_type_t type) override;

  static bool IsClassType(lldb::opaque_compiler_type_t type);

  static bool IsEnumType(lldb::opaque_compiler_type_t type);

  bool IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
                             CompilerType *target_type, // Can pass nullptr
                             bool check_cplusplus, bool check_objc) override;

  bool IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) override;

  bool IsPointerType(lldb::opaque_compiler_type_t type,
                     CompilerType *pointee_type) override;

  bool IsPointerOrReferenceType(lldb::opaque_compiler_type_t type,
                                CompilerType *pointee_type) override;

  bool IsReferenceType(lldb::opaque_compiler_type_t type,
                       CompilerType *pointee_type, bool *is_rvalue) override;

  bool IsScalarType(lldb::opaque_compiler_type_t type) override;

  bool IsTypedefType(lldb::opaque_compiler_type_t type) override;

  bool IsVoidType(lldb::opaque_compiler_type_t type) override;

  bool CanPassInRegisters(const CompilerType &type) override;

  bool SupportsLanguage(lldb::LanguageType language) override;

  static bool GetCXXClassName(const CompilerType &type,
                              std::string &class_name);

  static bool GetObjCClassName(const CompilerType &type,
                               std::string &class_name);

  // Type Completion

  bool GetCompleteType(lldb::opaque_compiler_type_t type) override;

  // Accessors

  ConstString GetTypeName(lldb::opaque_compiler_type_t type) override;

  uint32_t GetTypeInfo(lldb::opaque_compiler_type_t type,
                       CompilerType *pointee_or_element_compiler_type) override;

  lldb::LanguageType
  GetMinimumLanguage(lldb::opaque_compiler_type_t type) override;

  lldb::TypeClass GetTypeClass(lldb::opaque_compiler_type_t type) override;

  unsigned GetTypeQualifiers(lldb::opaque_compiler_type_t type) override;

  // Creating related types

  // Using the current type, create a new typedef to that type using
  // "typedef_name" as the name and "decl_ctx" as the decl context.
  static CompilerType
  CreateTypedefType(const CompilerType &type, const char *typedef_name,
                    const CompilerDeclContext &compiler_decl_ctx);

  CompilerType GetArrayElementType(lldb::opaque_compiler_type_t type,
                                   uint64_t *stride) override;

  CompilerType GetArrayType(lldb::opaque_compiler_type_t type,
                            uint64_t size) override;

  CompilerType GetCanonicalType(lldb::opaque_compiler_type_t type) override;

  CompilerType
  GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) override;

  // Returns -1 if this isn't a function of if the function doesn't have a
  // prototype Returns a value >= 0 if there is a prototype.
  int GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) override;

  CompilerType GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type,
                                              size_t idx) override;

  CompilerType
  GetFunctionReturnType(lldb::opaque_compiler_type_t type) override;

  size_t GetNumMemberFunctions(lldb::opaque_compiler_type_t type) override;

  TypeMemberFunctionImpl
  GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type,
                           size_t idx) override;

  CompilerType GetNonReferenceType(lldb::opaque_compiler_type_t type) override;

  CompilerType GetPointeeType(lldb::opaque_compiler_type_t type) override;

  CompilerType GetPointerType(lldb::opaque_compiler_type_t type) override;

  CompilerType
  GetLValueReferenceType(lldb::opaque_compiler_type_t type) override;

  CompilerType
  GetRValueReferenceType(lldb::opaque_compiler_type_t type) override;

  CompilerType AddConstModifier(lldb::opaque_compiler_type_t type) override;

  CompilerType AddVolatileModifier(lldb::opaque_compiler_type_t type) override;

  CompilerType AddRestrictModifier(lldb::opaque_compiler_type_t type) override;

  CompilerType CreateTypedef(lldb::opaque_compiler_type_t type,
                             const char *name,
                             const CompilerDeclContext &decl_ctx) override;

  // If the current object represents a typedef type, get the underlying type
  CompilerType GetTypedefedType(lldb::opaque_compiler_type_t type) override;

  // Create related types using the current type's AST
  CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) override;

  // Exploring the type

  llvm::Optional<uint64_t> GetByteSize(lldb::opaque_compiler_type_t type,
                       ExecutionContextScope *exe_scope) {
    if (llvm::Optional<uint64_t> bit_size = GetBitSize(type, exe_scope))
      return (*bit_size + 7) / 8;
    return llvm::None;
  }

  llvm::Optional<uint64_t>
  GetBitSize(lldb::opaque_compiler_type_t type,
             ExecutionContextScope *exe_scope) override;

  lldb::Encoding GetEncoding(lldb::opaque_compiler_type_t type,
                             uint64_t &count) override;

  lldb::Format GetFormat(lldb::opaque_compiler_type_t type) override;

  size_t GetTypeBitAlign(lldb::opaque_compiler_type_t type) override;

  uint32_t GetNumChildren(lldb::opaque_compiler_type_t type,
                          bool omit_empty_base_classes,
                          const ExecutionContext *exe_ctx) override;

  CompilerType GetBuiltinTypeByName(ConstString name) override;

  lldb::BasicType
  GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) override;

  static lldb::BasicType
  GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type,
                          ConstString name);

  void ForEachEnumerator(
      lldb::opaque_compiler_type_t type,
      std::function<bool(const CompilerType &integer_type,
                         ConstString name,
                         const llvm::APSInt &value)> const &callback) override;

  uint32_t GetNumFields(lldb::opaque_compiler_type_t type) override;

  CompilerType GetFieldAtIndex(lldb::opaque_compiler_type_t type, size_t idx,
                               std::string &name, uint64_t *bit_offset_ptr,
                               uint32_t *bitfield_bit_size_ptr,
                               bool *is_bitfield_ptr) override;

  uint32_t GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) override;

  uint32_t GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) override;

  CompilerType GetDirectBaseClassAtIndex(lldb::opaque_compiler_type_t type,
                                         size_t idx,
                                         uint32_t *bit_offset_ptr) override;

  CompilerType GetVirtualBaseClassAtIndex(lldb::opaque_compiler_type_t type,
                                          size_t idx,
                                          uint32_t *bit_offset_ptr) override;

  static uint32_t GetNumPointeeChildren(clang::QualType type);

  CompilerType GetChildCompilerTypeAtIndex(
      lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx,
      bool transparent_pointers, bool omit_empty_base_classes,
      bool ignore_array_bounds, std::string &child_name,
      uint32_t &child_byte_size, int32_t &child_byte_offset,
      uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset,
      bool &child_is_base_class, bool &child_is_deref_of_parent,
      ValueObject *valobj, uint64_t &language_flags) override;

  // Lookup a child given a name. This function will match base class names and
  // member member names in "clang_type" only, not descendants.
  uint32_t GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
                                   const char *name,
                                   bool omit_empty_base_classes) override;

  // Lookup a child member given a name. This function will match member names
  // only and will descend into "clang_type" children in search for the first
  // member in this class, or any base class that matches "name".
  // TODO: Return all matches for a given name by returning a
  // vector<vector<uint32_t>>
  // so we catch all names that match a given child name, not just the first.
  size_t
  GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type,
                                const char *name, bool omit_empty_base_classes,
                                std::vector<uint32_t> &child_indexes) override;

  size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override;

  lldb::TemplateArgumentKind
  GetTemplateArgumentKind(lldb::opaque_compiler_type_t type,
                          size_t idx) override;
  CompilerType GetTypeTemplateArgument(lldb::opaque_compiler_type_t type,
                                       size_t idx) override;
  llvm::Optional<CompilerType::IntegralTemplateArgument>
  GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type,
                              size_t idx) override;

  CompilerType GetTypeForFormatters(void *type) override;

#define LLDB_INVALID_DECL_LEVEL UINT32_MAX
  // LLDB_INVALID_DECL_LEVEL is returned by CountDeclLevels if child_decl_ctx
  // could not be found in decl_ctx.
  uint32_t CountDeclLevels(clang::DeclContext *frame_decl_ctx,
                           clang::DeclContext *child_decl_ctx,
                           ConstString *child_name = nullptr,
                           CompilerType *child_type = nullptr);

  // Modifying RecordType
  static clang::FieldDecl *AddFieldToRecordType(const CompilerType &type,
                                                llvm::StringRef name,
                                                const CompilerType &field_type,
                                                lldb::AccessType access,
                                                uint32_t bitfield_bit_size);

  static void BuildIndirectFields(const CompilerType &type);

  static void SetIsPacked(const CompilerType &type);

  static clang::VarDecl *AddVariableToRecordType(const CompilerType &type,
                                                 llvm::StringRef name,
                                                 const CompilerType &var_type,
                                                 lldb::AccessType access);

  clang::CXXMethodDecl *
  AddMethodToCXXRecordType(lldb::opaque_compiler_type_t type, const char *name,
                           const char *mangled_name,
                           const CompilerType &method_type,
                           lldb::AccessType access, bool is_virtual,
                           bool is_static, bool is_inline, bool is_explicit,
                           bool is_attr_used, bool is_artificial);

  void AddMethodOverridesForCXXRecordType(lldb::opaque_compiler_type_t type);

  // C++ Base Classes
  std::unique_ptr<clang::CXXBaseSpecifier>
  CreateBaseClassSpecifier(lldb::opaque_compiler_type_t type,
                           lldb::AccessType access, bool is_virtual,
                           bool base_of_class);

  bool TransferBaseClasses(
      lldb::opaque_compiler_type_t type,
      std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases);

  static bool SetObjCSuperClass(const CompilerType &type,
                                const CompilerType &superclass_compiler_type);

  static bool AddObjCClassProperty(const CompilerType &type,
                                   const char *property_name,
                                   const CompilerType &property_compiler_type,
                                   clang::ObjCIvarDecl *ivar_decl,
                                   const char *property_setter_name,
                                   const char *property_getter_name,
                                   uint32_t property_attributes,
                                   ClangASTMetadata *metadata);

  static clang::ObjCMethodDecl *AddMethodToObjCObjectType(
      const CompilerType &type,
      const char *name, // the full symbol name as seen in the symbol table
                        // (lldb::opaque_compiler_type_t type, "-[NString
                        // stringWithCString:]")
      const CompilerType &method_compiler_type, lldb::AccessType access,
      bool is_artificial, bool is_variadic);

  static bool SetHasExternalStorage(lldb::opaque_compiler_type_t type,
                                    bool has_extern);

  static bool GetHasExternalStorage(const CompilerType &type);
  // Tag Declarations
  static bool StartTagDeclarationDefinition(const CompilerType &type);

  static bool CompleteTagDeclarationDefinition(const CompilerType &type);

  // Modifying Enumeration types
  clang::EnumConstantDecl *AddEnumerationValueToEnumerationType(
      const CompilerType &enum_type, const Declaration &decl, const char *name,
      int64_t enum_value, uint32_t enum_value_bit_size);
  clang::EnumConstantDecl *AddEnumerationValueToEnumerationType(
      const CompilerType &enum_type, const Declaration &decl, const char *name,
      const llvm::APSInt &value);

  CompilerType GetEnumerationIntegerType(lldb::opaque_compiler_type_t type);

  // Pointers & References

  // Call this function using the class type when you want to make a member
  // pointer type to pointee_type.
  static CompilerType CreateMemberPointerType(const CompilerType &type,
                                              const CompilerType &pointee_type);

  // Converts "s" to a floating point value and place resulting floating point
  // bytes in the "dst" buffer.
  size_t ConvertStringToFloatValue(lldb::opaque_compiler_type_t type,
                                   const char *s, uint8_t *dst,
                                   size_t dst_size) override;

  // Dumping types
#ifndef NDEBUG
  /// Convenience LLVM-style dump method for use in the debugger only.
  /// In contrast to the other \p Dump() methods this directly invokes
  /// \p clang::QualType::dump().
  LLVM_DUMP_METHOD void dump(lldb::opaque_compiler_type_t type) const override;
#endif

  void Dump(Stream &s);

  void DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx,
                 Stream *s, lldb::Format format, const DataExtractor &data,
                 lldb::offset_t data_offset, size_t data_byte_size,
                 uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset,
                 bool show_types, bool show_summary, bool verbose,
                 uint32_t depth) override;

  bool DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s,
                     lldb::Format format, const DataExtractor &data,
                     lldb::offset_t data_offset, size_t data_byte_size,
                     uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset,
                     ExecutionContextScope *exe_scope) override;

  void DumpSummary(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx,
                   Stream *s, const DataExtractor &data,
                   lldb::offset_t data_offset, size_t data_byte_size) override;

  void DumpTypeDescription(
      lldb::opaque_compiler_type_t type) override; // Dump to stdout

  void DumpTypeDescription(lldb::opaque_compiler_type_t type,
                           Stream *s) override;

  static void DumpTypeName(const CompilerType &type);

  static clang::EnumDecl *GetAsEnumDecl(const CompilerType &type);

  static clang::RecordDecl *GetAsRecordDecl(const CompilerType &type);

  static clang::TagDecl *GetAsTagDecl(const CompilerType &type);

  static clang::TypedefNameDecl *GetAsTypedefDecl(const CompilerType &type);

  clang::CXXRecordDecl *GetAsCXXRecordDecl(lldb::opaque_compiler_type_t type);

  static clang::ObjCInterfaceDecl *
  GetAsObjCInterfaceDecl(const CompilerType &type);

  clang::ClassTemplateDecl *ParseClassTemplateDecl(
      clang::DeclContext *decl_ctx, lldb::AccessType access_type,
      const char *parent_name, int tag_decl_kind,
      const ClangASTContext::TemplateParameterInfos &template_param_infos);

  clang::BlockDecl *CreateBlockDeclaration(clang::DeclContext *ctx);

  clang::UsingDirectiveDecl *
  CreateUsingDirectiveDeclaration(clang::DeclContext *decl_ctx,
                                  clang::NamespaceDecl *ns_decl);

  clang::UsingDecl *CreateUsingDeclaration(clang::DeclContext *current_decl_ctx,
                                           clang::NamedDecl *target);

  clang::VarDecl *CreateVariableDeclaration(clang::DeclContext *decl_context,
                                            const char *name,
                                            clang::QualType type);

  static lldb::opaque_compiler_type_t
  GetOpaqueCompilerType(clang::ASTContext *ast, lldb::BasicType basic_type);

  static clang::QualType GetQualType(lldb::opaque_compiler_type_t type) {
    if (type)
      return clang::QualType::getFromOpaquePtr(type);
    return clang::QualType();
  }

  static clang::QualType
  GetCanonicalQualType(lldb::opaque_compiler_type_t type) {
    if (type)
      return clang::QualType::getFromOpaquePtr(type).getCanonicalType();
    return clang::QualType();
  }

  clang::DeclarationName
  GetDeclarationName(const char *name, const CompilerType &function_clang_type);
  
  virtual const clang::ExternalASTMerger::OriginMap &GetOriginMap() {
    return m_origins;
  }
protected:
  const clang::ClassTemplateSpecializationDecl *
  GetAsTemplateSpecialization(lldb::opaque_compiler_type_t type);

  // Classes that inherit from ClangASTContext can see and modify these
  // clang-format off
    std::string                                     m_target_triple;
    std::unique_ptr<clang::ASTContext>              m_ast_up;
    std::unique_ptr<clang::LangOptions>             m_language_options_up;
    std::unique_ptr<clang::FileManager>             m_file_manager_up;
    std::unique_ptr<clang::FileSystemOptions>       m_file_system_options_up;
    std::unique_ptr<clang::SourceManager>           m_source_manager_up;
    std::unique_ptr<clang::DiagnosticsEngine>       m_diagnostics_engine_up;
    std::unique_ptr<clang::DiagnosticConsumer>      m_diagnostic_consumer_up;
    std::shared_ptr<clang::TargetOptions>           m_target_options_rp;
    std::unique_ptr<clang::TargetInfo>              m_target_info_up;
    std::unique_ptr<clang::IdentifierTable>         m_identifier_table_up;
    std::unique_ptr<clang::SelectorTable>           m_selector_table_up;
    std::unique_ptr<clang::Builtin::Context>        m_builtins_up;
    std::unique_ptr<DWARFASTParserClang>            m_dwarf_ast_parser_up;
    std::unique_ptr<PDBASTParser>                   m_pdb_ast_parser_up;
    std::unique_ptr<ClangASTSource>                 m_scratch_ast_source_up;
    std::unique_ptr<clang::MangleContext>           m_mangle_ctx_up;
    CompleteTagDeclCallback                         m_callback_tag_decl;
    CompleteObjCInterfaceDeclCallback               m_callback_objc_decl;
    void *                                          m_callback_baton;
    clang::ExternalASTMerger::OriginMap             m_origins;
    uint32_t                                        m_pointer_byte_size;
    bool                                            m_ast_owned;
    bool                                            m_can_evaluate_expressions;
    /// The sema associated that is currently used to build this ASTContext.
    /// May be null if we are already done parsing this ASTContext or the
    /// ASTContext wasn't created by parsing source code.
    clang::Sema *                                   m_sema = nullptr;
  // clang-format on
private:
  // For ClangASTContext only
  ClangASTContext(const ClangASTContext &);
  const ClangASTContext &operator=(const ClangASTContext &);
};

class ClangASTContextForExpressions : public ClangASTContext {
public:
  ClangASTContextForExpressions(Target &target);

  ~ClangASTContextForExpressions() override = default;

  UserExpression *
  GetUserExpression(llvm::StringRef expr, llvm::StringRef prefix,
                    lldb::LanguageType language,
                    Expression::ResultType desired_type,
                    const EvaluateExpressionOptions &options,
                    ValueObject *ctx_obj) override;

  FunctionCaller *GetFunctionCaller(const CompilerType &return_type,
                                    const Address &function_address,
                                    const ValueList &arg_value_list,
                                    const char *name) override;

  UtilityFunction *GetUtilityFunction(const char *text,
                                      const char *name) override;

  PersistentExpressionState *GetPersistentExpressionState() override;
  
  clang::ExternalASTMerger &GetMergerUnchecked();
  
  const clang::ExternalASTMerger::OriginMap &GetOriginMap() override {
    return GetMergerUnchecked().GetOrigins();
  }
private:
  lldb::TargetWP m_target_wp;
  lldb::ClangPersistentVariablesUP m_persistent_variables; ///< These are the
                                                           ///persistent
                                                           ///variables
                                                           ///associated with
                                                           ///this process for
                                                           ///the expression
                                                           ///parser.
};

} // namespace lldb_private

#endif // liblldb_ClangASTContext_h_
