//===-- 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/AST/TypeBase.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.Format("#define {0}\n", entry.GetMacroString());
      else
        return;
      break;
    case DebugMacroEntry::UNDEF:
      if (state.IsValidEntry(entry.GetLineNumber()))
        stream.Format("#undef {0}\n", entry.GetMacroString());
      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;
    }
  }
}

/// Return qualifers of the current C++ method.
static clang::Qualifiers GetFrameCVQualifiers(StackFrame *frame) {
  if (!frame)
    return {};

  auto this_sp = frame->FindVariable(ConstString("this"));
  if (!this_sp)
    return {};

  // Lambdas that capture 'this' have a member variable called 'this'. The class
  // context of __lldb_expr for a lambda is the class type of the 'this' capture
  // (not the anonymous lambda structure). So use the qualifiers of the captured
  // 'this'.
  if (auto this_this_sp = this_sp->GetChildMemberWithName("this"))
    return clang::Qualifiers::fromCVRMask(
        this_this_sp->GetCompilerType().GetPointeeType().GetTypeQualifiers());

  // Not in a lambda. Return 'this' qualifiers.
  return clang::Qualifiers::fromCVRMask(
      this_sp->GetCompilerType().GetPointeeType().GetTypeQualifiers());
}

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 language 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.Format("using $__lldb_local_vars::{0};\n", var_name);
  }
}

bool ClangExpressionSourceCode::GetText(std::string &text,
                                        ExecutionContext &exe_ctx,
                                        bool add_locals,
                                        bool force_add_all_locals,
                                        llvm::ArrayRef<std::string> modules,
                                        bool ignore_context_qualifiers) 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) %s \n"
                         "{                                       \n"
                         "    %s;                                 \n"
                         "%s"
                         "}                                       \n",
                         module_imports.c_str(), m_name.c_str(),
                         ignore_context_qualifiers
                             ? ""
                             : GetFrameCVQualifiers(exe_ctx.GetFramePtr())
                                   .getAsString()
                                   .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;
}
