//===-- 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/CompileUnit.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"
#include "lldb/Utility/Timer.h"

using namespace lldb;
using namespace lldb_private;

static ConstString g_this = ConstString("this");

char CPPLanguageRuntime::ID = 0;

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

bool CPPLanguageRuntime::IsAllowedRuntimeValue(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;
}

bool contains_lambda_identifier(llvm::StringRef &str_ref) {
  return str_ref.contains("$_") || str_ref.contains("'lambda'");
}

CPPLanguageRuntime::LibCppStdFunctionCallableInfo
line_entry_helper(Target &target, const SymbolContext &sc, Symbol *symbol,
                  llvm::StringRef first_template_param_sref,
                  bool has___invoke) {

  CPPLanguageRuntime::LibCppStdFunctionCallableInfo optional_info;

  AddressRange range;
  sc.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 (contains_lambda_identifier(first_template_param_sref) || has___invoke) {
      // Case 1 and 2
      optional_info.callable_case = lldb_private::CPPLanguageRuntime::
          LibCppStdFunctionCallableCase::Lambda;
    } else {
      // Case 3
      optional_info.callable_case = lldb_private::CPPLanguageRuntime::
          LibCppStdFunctionCallableCase::CallableObject;
    }

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

  return optional_info;
}

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

  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 objects 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_;
  }

  if (!member__f_)
    return optional_info;

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

  optional_info.member__f_pointer_value = member__f_pointer_value;

  if (!member__f_pointer_value)
    return optional_info;

  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 vtable_address_first_entry =
      process->ReadPointerFromMemory(vtable_address + address_size, status);

  if (status.Fail())
    return optional_info;

  lldb::addr_t address_after_vtable = member__f_pointer_value + address_size;
  // As commented 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_first_entry_resolved;

  if (!target.GetSectionLoadList().ResolveLoadAddress(
          vtable_address_first_entry, vtable_first_entry_resolved))
    return optional_info;

  Address vtable_addr_resolved;
  SymbolContext sc;
  Symbol *symbol = nullptr;

  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().GetStringRef());
  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 could see names such as:
  //    main::$_0
  //    Bar::add_num2(int)::'lambda'(int)
  //    Bar
  //
  // 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;
  }

  // These conditions are used several times to simplify statements later on.
  bool has___invoke =
      (symbol ? symbol->GetName().GetStringRef().contains("__invoke") : false);
  auto calculate_symbol_context_helper = [](auto &t,
                                            SymbolContextList &sc_list) {
    SymbolContext sc;
    t->CalculateSymbolContext(&sc);
    sc_list.Append(sc);
  };

  // Case 2
  if (has___invoke) {
    SymbolContextList scl;
    calculate_symbol_context_helper(symbol, scl);

    return line_entry_helper(target, scl[0], symbol, first_template_parameter,
                             has___invoke);
  }

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

    return optional_info;
  }

  std::string func_to_match = first_template_parameter.str();

  auto it = CallableLookupCache.find(func_to_match);
  if (it != CallableLookupCache.end())
    return it->second;

  SymbolContextList scl;

  CompileUnit *vtable_cu =
      vtable_first_entry_resolved.CalculateSymbolContextCompileUnit();
  llvm::StringRef name_to_use = func_to_match;

  // Case 3, we have a callable object instead of a lambda
  //
  // TODO
  // We currently don't support this case a callable object may have multiple
  // operator()() varying on const/non-const and number of arguments and we
  // don't have a way to currently distinguish them so we will bail out now.
  if (!contains_lambda_identifier(name_to_use))
    return optional_info;

  if (vtable_cu && !has___invoke) {
    lldb::FunctionSP func_sp =
        vtable_cu->FindFunction([name_to_use](const FunctionSP &f) {
          auto name = f->GetName().GetStringRef();
          if (name.startswith(name_to_use) && name.contains("operator"))
            return true;

          return false;
        });

    if (func_sp) {
      calculate_symbol_context_helper(func_sp, scl);
    }
  }

  // Case 1 or 3
  if (scl.GetSize() >= 1) {
    optional_info = line_entry_helper(target, scl[0], symbol,
                                      first_template_parameter, has___invoke);
  }

  CallableLookupCache[func_to_match] = 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, nullptr, eOnlyThisThread,
          eLazyBoolYes, eLazyBoolYes);
      return ret_plan_sp;
    }
  }

  return ret_plan_sp;
}
