//===-- ClangExpressionSourceCode.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 "ClangExpressionSourceCode.h"

#include "ClangExpressionUtil.h"

#include "clang/Basic/CharInfo.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Lexer.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/StringRef.h"

#include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h"
#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/DebugMacros.h"
#include "lldb/Symbol/TypeSystem.h"
#include "lldb/Symbol/VariableList.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Language.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/StreamString.h"
#include "lldb/lldb-forward.h"

using namespace lldb_private;

#define PREFIX_NAME "<lldb wrapper prefix>"
#define SUFFIX_NAME "<lldb wrapper suffix>"

const llvm::StringRef ClangExpressionSourceCode::g_prefix_file_name = PREFIX_NAME;

const char *ClangExpressionSourceCode::g_expression_prefix =
"#line 1 \"" PREFIX_NAME R"("
#ifndef offsetof
#define offsetof(t, d) __builtin_offsetof(t, d)
#endif
#ifndef NULL
#define NULL (__null)
#endif
#ifndef Nil
#define Nil (__null)
#endif
#ifndef nil
#define nil (__null)
#endif
#ifndef YES
#define YES ((BOOL)1)
#endif
#ifndef NO
#define NO ((BOOL)0)
#endif
typedef __INT8_TYPE__ int8_t;
typedef __UINT8_TYPE__ uint8_t;
typedef __INT16_TYPE__ int16_t;
typedef __UINT16_TYPE__ uint16_t;
typedef __INT32_TYPE__ int32_t;
typedef __UINT32_TYPE__ uint32_t;
typedef __INT64_TYPE__ int64_t;
typedef __UINT64_TYPE__ uint64_t;
typedef __INTPTR_TYPE__ intptr_t;
typedef __UINTPTR_TYPE__ uintptr_t;
typedef __SIZE_TYPE__ size_t;
typedef __PTRDIFF_TYPE__ ptrdiff_t;
typedef unsigned short unichar;
extern "C"
{
    int printf(const char * __restrict, ...);
}
)";

const char *ClangExpressionSourceCode::g_expression_suffix =
    "\n;\n#line 1 \"" SUFFIX_NAME "\"\n";

namespace {

class AddMacroState {
  enum State {
    CURRENT_FILE_NOT_YET_PUSHED,
    CURRENT_FILE_PUSHED,
    CURRENT_FILE_POPPED
  };

public:
  AddMacroState(const FileSpec &current_file, const uint32_t current_file_line)
      : m_current_file(current_file), m_current_file_line(current_file_line) {}

  void StartFile(const FileSpec &file) {
    m_file_stack.push_back(file);
    if (file == m_current_file)
      m_state = CURRENT_FILE_PUSHED;
  }

  void EndFile() {
    if (m_file_stack.size() == 0)
      return;

    FileSpec old_top = m_file_stack.back();
    m_file_stack.pop_back();
    if (old_top == m_current_file)
      m_state = CURRENT_FILE_POPPED;
  }

  // An entry is valid if it occurs before the current line in the current
  // file.
  bool IsValidEntry(uint32_t line) {
    switch (m_state) {
    case CURRENT_FILE_NOT_YET_PUSHED:
      return true;
    case CURRENT_FILE_PUSHED:
      // If we are in file included in the current file, the entry should be
      // added.
      if (m_file_stack.back() != m_current_file)
        return true;

      return line < m_current_file_line;
    default:
      return false;
    }
  }

private:
  std::vector<FileSpec> m_file_stack;
  State m_state = CURRENT_FILE_NOT_YET_PUSHED;
  FileSpec m_current_file;
  uint32_t m_current_file_line;
};

} // anonymous namespace

static void AddMacros(const DebugMacros *dm, CompileUnit *comp_unit,
                      AddMacroState &state, StreamString &stream) {
  if (dm == nullptr)
    return;

  // The macros directives below can potentially redefine builtin macros of the
  // Clang instance which parses the user expression. The Clang diagnostics
  // caused by this are not useful for the user as the source code here is
  // generated by LLDB.
  stream << "#pragma clang diagnostic push\n";
  stream << "#pragma clang diagnostic ignored \"-Wmacro-redefined\"\n";
  stream << "#pragma clang diagnostic ignored \"-Wbuiltin-macro-redefined\"\n";
  llvm::scope_exit pop_warning(
      [&stream]() { stream << "#pragma clang diagnostic pop\n"; });

  for (size_t i = 0; i < dm->GetNumMacroEntries(); i++) {
    const DebugMacroEntry &entry = dm->GetMacroEntryAtIndex(i);
    uint32_t line;

    switch (entry.GetType()) {
    case DebugMacroEntry::DEFINE:
      if (state.IsValidEntry(entry.GetLineNumber()))
        stream.Printf("#define %s\n", entry.GetMacroString().AsCString());
      else
        return;
      break;
    case DebugMacroEntry::UNDEF:
      if (state.IsValidEntry(entry.GetLineNumber()))
        stream.Printf("#undef %s\n", entry.GetMacroString().AsCString());
      else
        return;
      break;
    case DebugMacroEntry::START_FILE:
      line = entry.GetLineNumber();
      if (state.IsValidEntry(line))
        state.StartFile(entry.GetFileSpec(comp_unit));
      else
        return;
      break;
    case DebugMacroEntry::END_FILE:
      state.EndFile();
      break;
    case DebugMacroEntry::INDIRECT:
      AddMacros(entry.GetIndirectDebugMacros(), comp_unit, state, stream);
      break;
    default:
      // This is an unknown/invalid entry. Ignore.
      break;
    }
  }
}

lldb_private::ClangExpressionSourceCode::ClangExpressionSourceCode(
    llvm::StringRef filename, llvm::StringRef name, llvm::StringRef prefix,
    llvm::StringRef body, Wrapping wrap, WrapKind wrap_kind)
    : ExpressionSourceCode(name, prefix, body, wrap), m_wrap_kind(wrap_kind) {
  // Use #line markers to pretend that we have a single-line source file
  // containing only the user expression. This will hide our wrapper code
  // from the user when we render diagnostics with Clang.
  m_start_marker = "#line 1 \"" + filename.str() + "\"\n";
  m_end_marker = g_expression_suffix;
}

namespace {
/// Allows checking if a token is contained in a given expression.
class TokenVerifier {
  /// The tokens we found in the expression.
  llvm::StringSet<> m_tokens;

public:
  TokenVerifier(std::string body);
  /// Returns true iff the given expression body contained a token with the
  /// given content.
  bool hasToken(llvm::StringRef token) const {
    return m_tokens.contains(token);
  }
};

// If we're evaluating from inside a lambda that captures a 'this' pointer,
// add a "using" declaration to 'stream' for each capture used in the
// expression (tokenized by 'verifier').
//
// If no 'this' capture exists, generate no using declarations. Instead
// capture lookups will get resolved by the same mechanism as class member
// variable lookup. That's because Clang generates an unnamed structure
// representing the lambda closure whose members are the captured variables.
void AddLambdaCaptureDecls(StreamString &stream, StackFrame *frame,
                           TokenVerifier const &verifier) {
  assert(frame);

  if (auto thisValSP = ClangExpressionUtil::GetLambdaValueObject(frame)) {
    uint32_t numChildren = thisValSP->GetNumChildrenIgnoringErrors();
    for (uint32_t i = 0; i < numChildren; ++i) {
      auto childVal = thisValSP->GetChildAtIndex(i);
      ConstString childName(childVal ? childVal->GetName() : ConstString(""));

      if (!childName.IsEmpty() && verifier.hasToken(childName.GetStringRef()) &&
          childName != "this") {
        stream.Printf("using $__lldb_local_vars::%s;\n",
                      childName.GetCString());
      }
    }
  }
}

} // namespace

TokenVerifier::TokenVerifier(std::string body) {
  using namespace clang;

  // We only care about tokens and not their original source locations. If we
  // move the whole expression to only be in one line we can simplify the
  // following code that extracts the token contents.
  llvm::replace(body, '\n', ' ');
  llvm::replace(body, '\r', ' ');

  FileSystemOptions file_opts;
  FileManager file_mgr(file_opts,
                       FileSystem::Instance().GetVirtualFileSystem());

  // Let's build the actual source code Clang needs and setup some utility
  // objects.
  DiagnosticOptions diags_opts;
  DiagnosticsEngine diags(DiagnosticIDs::create(), diags_opts);
  clang::SourceManager SM(diags, file_mgr);
  auto buf = llvm::MemoryBuffer::getMemBuffer(body);

  FileID FID = SM.createFileID(buf->getMemBufferRef());

  // Let's just enable the latest ObjC and C++ which should get most tokens
  // right.
  LangOptions Opts;
  Opts.ObjC = true;
  Opts.DollarIdents = true;
  Opts.CPlusPlus20 = true;
  Opts.LineComment = true;

  Lexer lex(FID, buf->getMemBufferRef(), SM, Opts);

  Token token;
  bool exit = false;
  while (!exit) {
    // Returns true if this is the last token we get from the lexer.
    exit = lex.LexFromRawLexer(token);

    // Extract the column number which we need to extract the token content.
    // Our expression is just one line, so we don't need to handle any line
    // numbers here.
    bool invalid = false;
    unsigned start = SM.getSpellingColumnNumber(token.getLocation(), &invalid);
    if (invalid)
      continue;
    // Column numbers start at 1, but indexes in our string start at 0.
    --start;

    // Annotations don't have a length, so let's skip them.
    if (token.isAnnotation())
      continue;

    // Extract the token string from our source code and store it.
    std::string token_str = body.substr(start, token.getLength());
    if (token_str.empty())
      continue;
    m_tokens.insert(token_str);
  }
}

void ClangExpressionSourceCode::AddLocalVariableDecls(StreamString &stream,
                                                      const std::string &expr,
                                                      StackFrame *frame) const {
  assert(frame);
  TokenVerifier tokens(expr);

  lldb::VariableListSP var_list_sp = frame->GetInScopeVariableList(false, true);

  for (size_t i = 0; i < var_list_sp->GetSize(); i++) {
    lldb::VariableSP var_sp = var_list_sp->GetVariableAtIndex(i);

    ConstString var_name = var_sp->GetName();

    if (var_name == "this" && m_wrap_kind == WrapKind::CppMemberFunction) {
      AddLambdaCaptureDecls(stream, frame, tokens);

      continue;
    }

    // We can check for .block_descriptor w/o checking for langauge since this
    // is not a valid identifier in either C or C++.
    if (!var_name || var_name == ".block_descriptor")
      continue;

    if (!expr.empty() && !tokens.hasToken(var_name.GetStringRef()))
      continue;

    const bool is_objc = m_wrap_kind == WrapKind::ObjCInstanceMethod ||
                         m_wrap_kind == WrapKind::ObjCStaticMethod;
    if ((var_name == "self" || var_name == "_cmd") && is_objc)
      continue;

    stream.Printf("using $__lldb_local_vars::%s;\n", var_name.AsCString());
  }
}

bool ClangExpressionSourceCode::GetText(
    std::string &text, ExecutionContext &exe_ctx, bool add_locals,
    bool force_add_all_locals, llvm::ArrayRef<std::string> modules) const {
  const char *target_specific_defines = "typedef signed char BOOL;\n";
  std::string module_macros;
  llvm::raw_string_ostream module_macros_stream(module_macros);

  Target *target = exe_ctx.GetTargetPtr();
  if (target) {
    if (target->GetArchitecture().GetMachine() == llvm::Triple::aarch64 ||
        target->GetArchitecture().GetMachine() == llvm::Triple::aarch64_32) {
      target_specific_defines = "typedef bool BOOL;\n";
    }
    if (target->GetArchitecture().GetMachine() == llvm::Triple::x86_64) {
      if (lldb::PlatformSP platform_sp = target->GetPlatform()) {
        if (platform_sp->GetPluginName() == "ios-simulator") {
          target_specific_defines = "typedef bool BOOL;\n";
        }
      }
    }

    auto *persistent_vars = llvm::cast<ClangPersistentVariables>(
        target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC));
    std::shared_ptr<ClangModulesDeclVendor> decl_vendor =
        persistent_vars->GetClangModulesDeclVendor();
    if (decl_vendor) {
      const ClangModulesDeclVendor::ModuleVector &hand_imported_modules =
          persistent_vars->GetHandLoadedClangModules();
      ClangModulesDeclVendor::ModuleVector modules_for_macros;

      for (ClangModulesDeclVendor::ModuleID module : hand_imported_modules) {
        modules_for_macros.push_back(module);
      }

      if (target->GetEnableAutoImportClangModules()) {
        if (StackFrame *frame = exe_ctx.GetFramePtr()) {
          if (Block *block = frame->GetFrameBlock()) {
            SymbolContext sc;

            block->CalculateSymbolContext(&sc);

            if (sc.comp_unit) {
              if (auto err = decl_vendor->AddModulesForCompileUnit(
                      *sc.comp_unit, modules_for_macros))
                LLDB_LOG_ERROR(
                    GetLog(LLDBLog::Expressions), std::move(err),
                    "Error while loading hand-imported modules:\n{0}");
            }
          }
        }
      }

      decl_vendor->ForEachMacro(
          modules_for_macros,
          [&module_macros_stream](llvm::StringRef token,
                                  llvm::StringRef expansion) -> bool {
            // Check if the macro hasn't already been defined in the
            // g_expression_prefix (which defines a few builtin macros).
            module_macros_stream << "#ifndef " << token << "\n";
            module_macros_stream << expansion << "\n";
            module_macros_stream << "#endif\n";
            return false;
          });
    }
  }

  StreamString debug_macros_stream;
  StreamString lldb_local_var_decls;
  if (StackFrame *frame = exe_ctx.GetFramePtr()) {
    const SymbolContext &sc = frame->GetSymbolContext(
        lldb::eSymbolContextCompUnit | lldb::eSymbolContextLineEntry);

    if (sc.comp_unit && sc.line_entry.IsValid()) {
      DebugMacros *dm = sc.comp_unit->GetDebugMacros();
      if (dm) {
        AddMacroState state(sc.line_entry.GetFile(), sc.line_entry.line);
        AddMacros(dm, sc.comp_unit, state, debug_macros_stream);
      }
    }

    if (add_locals)
      if (target->GetInjectLocalVariables(&exe_ctx)) {
        AddLocalVariableDecls(lldb_local_var_decls,
                              force_add_all_locals ? "" : m_body, frame);
      }
  }

  if (m_wrap) {
    // Generate a list of @import statements that will import the specified
    // module into our expression.
    std::string module_imports;
    for (const std::string &module : modules) {
      module_imports.append("@import ");
      module_imports.append(module);
      module_imports.append(";\n");
    }

    StreamString wrap_stream;

    wrap_stream.Printf("%s\n%s\n%s\n%s\n%s\n", g_expression_prefix,
                       module_macros.c_str(), debug_macros_stream.GetData(),
                       target_specific_defines, m_prefix.c_str());

    // First construct a tagged form of the user expression so we can find it
    // later:
    std::string tagged_body;
    tagged_body.append(m_start_marker);
    tagged_body.append(m_body);
    tagged_body.append(m_end_marker);

    switch (m_wrap_kind) {
    case WrapKind::Function:
      wrap_stream.Printf("%s"
                         "void                           \n"
                         "%s(void *$__lldb_arg)          \n"
                         "{                              \n"
                         "    %s;                        \n"
                         "%s"
                         "}                              \n",
                         module_imports.c_str(), m_name.c_str(),
                         lldb_local_var_decls.GetData(), tagged_body.c_str());
      break;
    case WrapKind::CppMemberFunction:
      wrap_stream.Printf("%s"
                         "void                                   \n"
                         "$__lldb_class::%s(void *$__lldb_arg)   \n"
                         "{                                      \n"
                         "    %s;                                \n"
                         "%s"
                         "}                                      \n",
                         module_imports.c_str(), m_name.c_str(),
                         lldb_local_var_decls.GetData(), tagged_body.c_str());
      break;
    case WrapKind::ObjCInstanceMethod:
      wrap_stream.Printf(
          "%s"
          "@interface $__lldb_objc_class ($__lldb_category)       \n"
          "-(void)%s:(void *)$__lldb_arg;                         \n"
          "@end                                                   \n"
          "@implementation $__lldb_objc_class ($__lldb_category)  \n"
          "-(void)%s:(void *)$__lldb_arg                          \n"
          "{                                                      \n"
          "    %s;                                                \n"
          "%s"
          "}                                                      \n"
          "@end                                                   \n",
          module_imports.c_str(), m_name.c_str(), m_name.c_str(),
          lldb_local_var_decls.GetData(), tagged_body.c_str());
      break;

    case WrapKind::ObjCStaticMethod:
      wrap_stream.Printf(
          "%s"
          "@interface $__lldb_objc_class ($__lldb_category)        \n"
          "+(void)%s:(void *)$__lldb_arg;                          \n"
          "@end                                                    \n"
          "@implementation $__lldb_objc_class ($__lldb_category)   \n"
          "+(void)%s:(void *)$__lldb_arg                           \n"
          "{                                                       \n"
          "    %s;                                                 \n"
          "%s"
          "}                                                       \n"
          "@end                                                    \n",
          module_imports.c_str(), m_name.c_str(), m_name.c_str(),
          lldb_local_var_decls.GetData(), tagged_body.c_str());
      break;
    }

    text = std::string(wrap_stream.GetString());
  } else {
    text.append(m_body);
  }

  return true;
}

bool ClangExpressionSourceCode::GetOriginalBodyBounds(
    std::string transformed_text, size_t &start_loc, size_t &end_loc) {
  start_loc = transformed_text.find(m_start_marker);
  if (start_loc == std::string::npos)
    return false;
  start_loc += m_start_marker.size();
  end_loc = transformed_text.find(m_end_marker);
  return end_loc != std::string::npos;
}
