//===-- 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.
  std::replace(body.begin(), body.end(), '\n', ' ');
  std::replace(body.begin(), body.end(), '\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.
  llvm::IntrusiveRefCntPtr<DiagnosticIDs> diag_ids(new DiagnosticIDs());
  llvm::IntrusiveRefCntPtr<DiagnosticOptions> diags_opts(
      new DiagnosticOptions());
  DiagnosticsEngine diags(diag_ids, 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) {
              StreamString error_stream;

              decl_vendor->AddModulesForCompileUnit(
                  *sc.comp_unit, modules_for_macros, error_stream);
            }
          }
        }
      }

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