//===-- 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";
  auto pop_warning = llvm::make_scope_exit([&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;
}
