//===-- CPPLanguageRuntime.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
//
//===----------------------------------------------------------------------===//

#include <string.h>

#include <memory>

#include "CPPLanguageRuntime.h"

#include "llvm/ADT/StringRef.h"

#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/Variable.h"
#include "lldb/Symbol/VariableList.h"

#include "lldb/Core/PluginManager.h"
#include "lldb/Core/UniqueCStringMap.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/SectionLoadList.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/ThreadPlanRunToAddress.h"
#include "lldb/Target/ThreadPlanStepInRange.h"

using namespace lldb;
using namespace lldb_private;

static ConstString g_this = ConstString("this");

char CPPLanguageRuntime::ID = 0;

// Destructor
CPPLanguageRuntime::~CPPLanguageRuntime() {}

CPPLanguageRuntime::CPPLanguageRuntime(Process *process)
    : LanguageRuntime(process) {}

bool CPPLanguageRuntime::IsWhitelistedRuntimeValue(ConstString name) {
  return name == g_this;
}

bool CPPLanguageRuntime::GetObjectDescription(Stream &str,
                                              ValueObject &object) {
  // C++ has no generic way to do this.
  return false;
}

bool CPPLanguageRuntime::GetObjectDescription(
    Stream &str, Value &value, ExecutionContextScope *exe_scope) {
  // C++ has no generic way to do this.
  return false;
}

CPPLanguageRuntime::LibCppStdFunctionCallableInfo
CPPLanguageRuntime::FindLibCppStdFunctionCallableInfo(
    lldb::ValueObjectSP &valobj_sp) {
  LibCppStdFunctionCallableInfo optional_info;

  if (!valobj_sp)
    return optional_info;

  // Member __f_ has type __base*, the contents of which will hold:
  // 1) a vtable entry which may hold type information needed to discover the
  //    lambda being called
  // 2) possibly hold a pointer to the callable object
  // e.g.
  //
  // (lldb) frame var -R  f_display
  // (std::__1::function<void (int)>) f_display = {
  //  __buf_ = {
  //  …
  // }
  //  __f_ = 0x00007ffeefbffa00
  // }
  // (lldb) memory read -fA 0x00007ffeefbffa00
  // 0x7ffeefbffa00: ... `vtable for std::__1::__function::__func<void (*) ...
  // 0x7ffeefbffa08: ... `print_num(int) at std_function_cppreference_exam ...
  //
  // We will be handling five cases below, std::function is wrapping:
  //
  // 1) a lambda we know at compile time. We will obtain the name of the lambda
  //    from the first template pameter from __func's vtable. We will look up
  //    the lambda's operator()() and obtain the line table entry.
  // 2) a lambda we know at runtime. A pointer to the lambdas __invoke method
  //    will be stored after the vtable. We will obtain the lambdas name from
  //    this entry and lookup operator()() and obtain the line table entry.
  // 3) a callable object via operator()(). We will obtain the name of the
  //    object from the first template parameter from __func's vtable. We will
  //    look up the objectc operator()() and obtain the line table entry.
  // 4) a member function. A pointer to the function will stored after the
  //    we will obtain the name from this pointer.
  // 5) a free function. A pointer to the function will stored after the vtable
  //    we will obtain the name from this pointer.
  ValueObjectSP member__f_(
      valobj_sp->GetChildMemberWithName(ConstString("__f_"), true));

  if (member__f_) {
    ValueObjectSP sub_member__f_(
       member__f_->GetChildMemberWithName(ConstString("__f_"), true));

    if (sub_member__f_)
        member__f_ = sub_member__f_;
  }

  lldb::addr_t member__f_pointer_value = member__f_->GetValueAsUnsigned(0);

  optional_info.member__f_pointer_value = member__f_pointer_value;

  ExecutionContext exe_ctx(valobj_sp->GetExecutionContextRef());
  Process *process = exe_ctx.GetProcessPtr();

  if (process == nullptr)
    return optional_info;

  uint32_t address_size = process->GetAddressByteSize();
  Status status;

  // First item pointed to by __f_ should be the pointer to the vtable for
  // a __base object.
  lldb::addr_t vtable_address =
      process->ReadPointerFromMemory(member__f_pointer_value, status);

  if (status.Fail())
    return optional_info;

  lldb::addr_t address_after_vtable = member__f_pointer_value + address_size;
  // As commened above we may not have a function pointer but if we do we will
  // need it.
  lldb::addr_t possible_function_address =
      process->ReadPointerFromMemory(address_after_vtable, status);

  if (status.Fail())
    return optional_info;

  Target &target = process->GetTarget();

  if (target.GetSectionLoadList().IsEmpty())
    return optional_info;

  Address vtable_addr_resolved;
  SymbolContext sc;
  Symbol *symbol;

  if (!target.GetSectionLoadList().ResolveLoadAddress(vtable_address,
                                                      vtable_addr_resolved))
    return optional_info;

  target.GetImages().ResolveSymbolContextForAddress(
      vtable_addr_resolved, eSymbolContextEverything, sc);
  symbol = sc.symbol;

  if (symbol == nullptr)
    return optional_info;

  llvm::StringRef vtable_name(symbol->GetName().GetCString());
  bool found_expected_start_string =
      vtable_name.startswith("vtable for std::__1::__function::__func<");

  if (!found_expected_start_string)
    return optional_info;

  // Given case 1 or 3 we have a vtable name, we are want to extract the first
  // template parameter
  //
  //  ... __func<main::$_0, std::__1::allocator<main::$_0> ...
  //             ^^^^^^^^^
  //
  // We do this by find the first < and , and extracting in between.
  //
  // This covers the case of the lambda known at compile time.
  size_t first_open_angle_bracket = vtable_name.find('<') + 1;
  size_t first_comma = vtable_name.find(',');

  llvm::StringRef first_template_parameter =
      vtable_name.slice(first_open_angle_bracket, first_comma);

  Address function_address_resolved;

  // Setup for cases 2, 4 and 5 we have a pointer to a function after the
  // vtable. We will use a process of elimination to drop through each case
  // and obtain the data we need.
  if (target.GetSectionLoadList().ResolveLoadAddress(
          possible_function_address, function_address_resolved)) {
    target.GetImages().ResolveSymbolContextForAddress(
        function_address_resolved, eSymbolContextEverything, sc);
    symbol = sc.symbol;
  }

  auto get_name = [&first_template_parameter, &symbol]() {
    // Given case 1:
    //
    //    main::$_0
    //
    // we want to append ::operator()()
    if (first_template_parameter.contains("$_"))
      return llvm::Regex::escape(first_template_parameter.str()) +
             R"(::operator\(\)\(.*\))";

    if (symbol != nullptr &&
        symbol->GetName().GetStringRef().contains("__invoke")) {

      llvm::StringRef symbol_name = symbol->GetName().GetStringRef();
      size_t pos2 = symbol_name.find_last_of(':');

      // Given case 2:
      //
      //    main::$_1::__invoke(...)
      //
      // We want to slice off __invoke(...) and append operator()()
      std::string lambda_operator =
          llvm::Regex::escape(symbol_name.slice(0, pos2 + 1).str()) +
          R"(operator\(\)\(.*\))";

      return lambda_operator;
    }

    // Case 3
    return first_template_parameter.str() + R"(::operator\(\)\(.*\))";
    ;
  };

  std::string func_to_match = get_name();

  SymbolContextList scl;

  target.GetImages().FindSymbolsMatchingRegExAndType(
      RegularExpression{R"(^)" + func_to_match}, eSymbolTypeAny, scl);

  // Case 1,2 or 3
  if (scl.GetSize() >= 1) {
    SymbolContext sc2 = scl[0];

    AddressRange range;
    sc2.GetAddressRange(eSymbolContextEverything, 0, false, range);

    Address address = range.GetBaseAddress();

    Address addr;
    if (target.ResolveLoadAddress(address.GetCallableLoadAddress(&target),
                                  addr)) {
      LineEntry line_entry;
      addr.CalculateSymbolContextLineEntry(line_entry);

      if (first_template_parameter.contains("$_") ||
          (symbol != nullptr &&
           symbol->GetName().GetStringRef().contains("__invoke"))) {
        // Case 1 and 2
        optional_info.callable_case = LibCppStdFunctionCallableCase::Lambda;
      } else {
        // Case 3
        optional_info.callable_case =
            LibCppStdFunctionCallableCase::CallableObject;
      }

      optional_info.callable_symbol = *symbol;
      optional_info.callable_line_entry = line_entry;
      optional_info.callable_address = addr;
      return optional_info;
    }
  }

  // Case 4 or 5
  if (symbol && !symbol->GetName().GetStringRef().startswith("vtable for")) {
    optional_info.callable_case =
        LibCppStdFunctionCallableCase::FreeOrMemberFunction;
    optional_info.callable_address = function_address_resolved;
    optional_info.callable_symbol = *symbol;

    return optional_info;
  }

  return optional_info;
}

lldb::ThreadPlanSP
CPPLanguageRuntime::GetStepThroughTrampolinePlan(Thread &thread,
                                                 bool stop_others) {
  ThreadPlanSP ret_plan_sp;

  lldb::addr_t curr_pc = thread.GetRegisterContext()->GetPC();

  TargetSP target_sp(thread.CalculateTarget());

  if (target_sp->GetSectionLoadList().IsEmpty())
    return ret_plan_sp;

  Address pc_addr_resolved;
  SymbolContext sc;
  Symbol *symbol;

  if (!target_sp->GetSectionLoadList().ResolveLoadAddress(curr_pc,
                                                          pc_addr_resolved))
    return ret_plan_sp;

  target_sp->GetImages().ResolveSymbolContextForAddress(
      pc_addr_resolved, eSymbolContextEverything, sc);
  symbol = sc.symbol;

  if (symbol == nullptr)
    return ret_plan_sp;

  llvm::StringRef function_name(symbol->GetName().GetCString());

  // Handling the case where we are attempting to step into std::function.
  // The behavior will be that we will attempt to obtain the wrapped
  // callable via FindLibCppStdFunctionCallableInfo() and if we find it we
  // will return a ThreadPlanRunToAddress to the callable. Therefore we will
  // step into the wrapped callable.
  //
  bool found_expected_start_string =
      function_name.startswith("std::__1::function<");

  if (!found_expected_start_string)
    return ret_plan_sp;

  AddressRange range_of_curr_func;
  sc.GetAddressRange(eSymbolContextEverything, 0, false, range_of_curr_func);

  StackFrameSP frame = thread.GetStackFrameAtIndex(0);

  if (frame) {
    ValueObjectSP value_sp = frame->FindVariable(g_this);

    CPPLanguageRuntime::LibCppStdFunctionCallableInfo callable_info =
        FindLibCppStdFunctionCallableInfo(value_sp);

    if (callable_info.callable_case != LibCppStdFunctionCallableCase::Invalid &&
        value_sp->GetValueIsValid()) {
      // We found the std::function wrapped callable and we have its address.
      // We now create a ThreadPlan to run to the callable.
      ret_plan_sp = std::make_shared<ThreadPlanRunToAddress>(
          thread, callable_info.callable_address, stop_others);
      return ret_plan_sp;
    } else {
      // We are in std::function but we could not obtain the callable.
      // We create a ThreadPlan to keep stepping through using the address range
      // of the current function.
      ret_plan_sp = std::make_shared<ThreadPlanStepInRange>(
          thread, range_of_curr_func, sc, eOnlyThisThread, eLazyBoolYes,
          eLazyBoolYes);
      return ret_plan_sp;
    }
  }

  return ret_plan_sp;
}
