1292932Sdim//===-- IRForTarget.cpp -----------------------------------------*- C++ -*-===//
2292932Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6292932Sdim//
7292932Sdim//===----------------------------------------------------------------------===//
8292932Sdim
9292932Sdim#include "IRForTarget.h"
10292932Sdim
11292932Sdim#include "ClangExpressionDeclMap.h"
12292932Sdim
13292932Sdim#include "llvm/IR/Constants.h"
14292932Sdim#include "llvm/IR/DataLayout.h"
15292932Sdim#include "llvm/IR/InstrTypes.h"
16292932Sdim#include "llvm/IR/Instructions.h"
17292932Sdim#include "llvm/IR/Intrinsics.h"
18292932Sdim#include "llvm/IR/LegacyPassManager.h"
19292932Sdim#include "llvm/IR/Metadata.h"
20314564Sdim#include "llvm/IR/Module.h"
21292932Sdim#include "llvm/IR/ValueSymbolTable.h"
22314564Sdim#include "llvm/Support/raw_ostream.h"
23314564Sdim#include "llvm/Transforms/IPO.h"
24292932Sdim
25292932Sdim#include "clang/AST/ASTContext.h"
26292932Sdim
27309124Sdim#include "lldb/Core/dwarf.h"
28292932Sdim#include "lldb/Expression/IRExecutionUnit.h"
29292932Sdim#include "lldb/Expression/IRInterpreter.h"
30292932Sdim#include "lldb/Symbol/ClangASTContext.h"
31309124Sdim#include "lldb/Symbol/ClangUtil.h"
32292932Sdim#include "lldb/Symbol/CompilerType.h"
33321369Sdim#include "lldb/Utility/ConstString.h"
34321369Sdim#include "lldb/Utility/DataBufferHeap.h"
35321369Sdim#include "lldb/Utility/Endian.h"
36321369Sdim#include "lldb/Utility/Log.h"
37344779Sdim#include "lldb/Utility/Scalar.h"
38321369Sdim#include "lldb/Utility/StreamString.h"
39292932Sdim
40292932Sdim#include <map>
41292932Sdim
42292932Sdimusing namespace llvm;
43292932Sdim
44292932Sdimstatic char ID;
45292932Sdim
46360784Sdimtypedef SmallVector<Instruction *, 2> InstrList;
47360784Sdim
48314564SdimIRForTarget::FunctionValueCache::FunctionValueCache(Maker const &maker)
49314564Sdim    : m_maker(maker), m_values() {}
50292932Sdim
51314564SdimIRForTarget::FunctionValueCache::~FunctionValueCache() {}
52292932Sdim
53292932Sdimllvm::Value *
54314564SdimIRForTarget::FunctionValueCache::GetValue(llvm::Function *function) {
55314564Sdim  if (!m_values.count(function)) {
56314564Sdim    llvm::Value *ret = m_maker(function);
57314564Sdim    m_values[function] = ret;
58314564Sdim    return ret;
59314564Sdim  }
60314564Sdim  return m_values[function];
61292932Sdim}
62292932Sdim
63314564Sdimstatic llvm::Value *FindEntryInstruction(llvm::Function *function) {
64314564Sdim  if (function->empty())
65353358Sdim    return nullptr;
66292932Sdim
67314564Sdim  return function->getEntryBlock().getFirstNonPHIOrDbg();
68292932Sdim}
69292932Sdim
70314564SdimIRForTarget::IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map,
71314564Sdim                         bool resolve_vars,
72314564Sdim                         lldb_private::IRExecutionUnit &execution_unit,
73314564Sdim                         lldb_private::Stream &error_stream,
74314564Sdim                         const char *func_name)
75314564Sdim    : ModulePass(ID), m_resolve_vars(resolve_vars), m_func_name(func_name),
76353358Sdim      m_module(nullptr), m_decl_map(decl_map),
77353358Sdim      m_CFStringCreateWithBytes(nullptr), m_sel_registerName(nullptr),
78353358Sdim      m_objc_getClass(nullptr), m_intptr_ty(nullptr),
79353358Sdim      m_error_stream(error_stream), m_execution_unit(execution_unit),
80353358Sdim      m_result_store(nullptr), m_result_is_pointer(false),
81353358Sdim      m_reloc_placeholder(nullptr),
82314564Sdim      m_entry_instruction_finder(FindEntryInstruction) {}
83292932Sdim
84292932Sdim/* Handy utility functions used at several places in the code */
85292932Sdim
86314564Sdimstatic std::string PrintValue(const Value *value, bool truncate = false) {
87314564Sdim  std::string s;
88314564Sdim  if (value) {
89292932Sdim    raw_string_ostream rso(s);
90314564Sdim    value->print(rso);
91292932Sdim    rso.flush();
92292932Sdim    if (truncate)
93314564Sdim      s.resize(s.length() - 1);
94314564Sdim  }
95314564Sdim  return s;
96292932Sdim}
97292932Sdim
98314564Sdimstatic std::string PrintType(const llvm::Type *type, bool truncate = false) {
99314564Sdim  std::string s;
100314564Sdim  raw_string_ostream rso(s);
101314564Sdim  type->print(rso);
102314564Sdim  rso.flush();
103314564Sdim  if (truncate)
104314564Sdim    s.resize(s.length() - 1);
105314564Sdim  return s;
106292932Sdim}
107292932Sdim
108314564SdimIRForTarget::~IRForTarget() {}
109292932Sdim
110314564Sdimbool IRForTarget::FixFunctionLinkage(llvm::Function &llvm_function) {
111314564Sdim  llvm_function.setLinkage(GlobalValue::ExternalLinkage);
112314564Sdim
113314564Sdim  return true;
114292932Sdim}
115292932Sdim
116314564Sdimclang::NamedDecl *IRForTarget::DeclForGlobal(const GlobalValue *global_val,
117314564Sdim                                             Module *module) {
118314564Sdim  NamedMDNode *named_metadata =
119314564Sdim      module->getNamedMetadata("clang.global.decl.ptrs");
120292932Sdim
121314564Sdim  if (!named_metadata)
122353358Sdim    return nullptr;
123292932Sdim
124314564Sdim  unsigned num_nodes = named_metadata->getNumOperands();
125314564Sdim  unsigned node_index;
126292932Sdim
127314564Sdim  for (node_index = 0; node_index < num_nodes; ++node_index) {
128314564Sdim    llvm::MDNode *metadata_node =
129314564Sdim        dyn_cast<llvm::MDNode>(named_metadata->getOperand(node_index));
130314564Sdim    if (!metadata_node)
131353358Sdim      return nullptr;
132292932Sdim
133314564Sdim    if (metadata_node->getNumOperands() != 2)
134314564Sdim      continue;
135292932Sdim
136314564Sdim    if (mdconst::dyn_extract_or_null<GlobalValue>(
137314564Sdim            metadata_node->getOperand(0)) != global_val)
138314564Sdim      continue;
139292932Sdim
140314564Sdim    ConstantInt *constant_int =
141314564Sdim        mdconst::dyn_extract<ConstantInt>(metadata_node->getOperand(1));
142292932Sdim
143314564Sdim    if (!constant_int)
144353358Sdim      return nullptr;
145292932Sdim
146314564Sdim    uintptr_t ptr = constant_int->getZExtValue();
147292932Sdim
148314564Sdim    return reinterpret_cast<clang::NamedDecl *>(ptr);
149314564Sdim  }
150292932Sdim
151353358Sdim  return nullptr;
152292932Sdim}
153292932Sdim
154314564Sdimclang::NamedDecl *IRForTarget::DeclForGlobal(GlobalValue *global_val) {
155314564Sdim  return DeclForGlobal(global_val, m_module);
156292932Sdim}
157292932Sdim
158360784Sdim/// Returns true iff the mangled symbol is for a static guard variable.
159360784Sdimstatic bool isGuardVariableSymbol(llvm::StringRef mangled_symbol,
160360784Sdim                                  bool check_ms_abi = true) {
161360784Sdim  bool result = mangled_symbol.startswith("_ZGV"); // Itanium ABI guard variable
162360784Sdim  if (check_ms_abi)
163360784Sdim    result |= mangled_symbol.endswith("@4IA"); // Microsoft ABI
164360784Sdim  return result;
165360784Sdim}
166360784Sdim
167314564Sdimbool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
168314564Sdim  lldb_private::Log *log(
169314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
170292932Sdim
171314564Sdim  if (!m_resolve_vars)
172314564Sdim    return true;
173292932Sdim
174314564Sdim  // Find the result variable.  If it doesn't exist, we can give up right here.
175292932Sdim
176314564Sdim  ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable();
177292932Sdim
178360784Sdim  llvm::StringRef result_name;
179360784Sdim  bool found_result = false;
180292932Sdim
181360784Sdim  for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {
182360784Sdim    result_name = value_symbol.first();
183292932Sdim
184360784Sdim    // Check if this is a guard variable. It seems this causes some hiccups
185360784Sdim    // on Windows, so let's only check for Itanium guard variables.
186360784Sdim    bool is_guard_var = isGuardVariableSymbol(result_name, /*MS ABI*/ false);
187360784Sdim
188360784Sdim    if (result_name.contains("$__lldb_expr_result_ptr") && !is_guard_var) {
189360784Sdim      found_result = true;
190314564Sdim      m_result_is_pointer = true;
191314564Sdim      break;
192314564Sdim    }
193292932Sdim
194360784Sdim    if (result_name.contains("$__lldb_expr_result") && !is_guard_var) {
195360784Sdim      found_result = true;
196314564Sdim      m_result_is_pointer = false;
197314564Sdim      break;
198292932Sdim    }
199314564Sdim  }
200292932Sdim
201360784Sdim  if (!found_result) {
202360784Sdim    LLDB_LOG(log, "Couldn't find result variable");
203292932Sdim
204314564Sdim    return true;
205314564Sdim  }
206292932Sdim
207360784Sdim  LLDB_LOG(log, "Result name: \"{0}\"", result_name);
208314564Sdim
209314564Sdim  Value *result_value = m_module->getNamedValue(result_name);
210314564Sdim
211314564Sdim  if (!result_value) {
212360784Sdim    LLDB_LOG(log, "Result variable had no data");
213292932Sdim
214360784Sdim    m_error_stream.Format("Internal error [IRForTarget]: Result variable's "
215360784Sdim                          "name ({0}) exists, but not its definition\n",
216314564Sdim                          result_name);
217292932Sdim
218314564Sdim    return false;
219314564Sdim  }
220292932Sdim
221360784Sdim  LLDB_LOG(log, "Found result in the IR: \"{0}\"",
222360784Sdim           PrintValue(result_value, false));
223292932Sdim
224314564Sdim  GlobalVariable *result_global = dyn_cast<GlobalVariable>(result_value);
225292932Sdim
226314564Sdim  if (!result_global) {
227360784Sdim    LLDB_LOG(log, "Result variable isn't a GlobalVariable");
228292932Sdim
229360784Sdim    m_error_stream.Format("Internal error [IRForTarget]: Result variable ({0}) "
230314564Sdim                          "is defined, but is not a global variable\n",
231314564Sdim                          result_name);
232292932Sdim
233314564Sdim    return false;
234314564Sdim  }
235292932Sdim
236314564Sdim  clang::NamedDecl *result_decl = DeclForGlobal(result_global);
237314564Sdim  if (!result_decl) {
238360784Sdim    LLDB_LOG(log, "Result variable doesn't have a corresponding Decl");
239292932Sdim
240360784Sdim    m_error_stream.Format("Internal error [IRForTarget]: Result variable ({0}) "
241314564Sdim                          "does not have a corresponding Clang entity\n",
242314564Sdim                          result_name);
243292932Sdim
244314564Sdim    return false;
245314564Sdim  }
246292932Sdim
247314564Sdim  if (log) {
248314564Sdim    std::string decl_desc_str;
249314564Sdim    raw_string_ostream decl_desc_stream(decl_desc_str);
250314564Sdim    result_decl->print(decl_desc_stream);
251314564Sdim    decl_desc_stream.flush();
252292932Sdim
253360784Sdim    LLDB_LOG(log, "Found result decl: \"{0}\"", decl_desc_str);
254314564Sdim  }
255292932Sdim
256314564Sdim  clang::VarDecl *result_var = dyn_cast<clang::VarDecl>(result_decl);
257314564Sdim  if (!result_var) {
258360784Sdim    LLDB_LOG(log, "Result variable Decl isn't a VarDecl");
259292932Sdim
260360784Sdim    m_error_stream.Format("Internal error [IRForTarget]: Result variable "
261360784Sdim                          "({0})'s corresponding Clang entity isn't a "
262314564Sdim                          "variable\n",
263314564Sdim                          result_name);
264292932Sdim
265314564Sdim    return false;
266314564Sdim  }
267292932Sdim
268314564Sdim  // Get the next available result name from m_decl_map and create the
269341825Sdim  // persistent variable for it
270292932Sdim
271314564Sdim  // If the result is an Lvalue, it is emitted as a pointer; see
272314564Sdim  // ASTResultSynthesizer::SynthesizeBodyResult.
273314564Sdim  if (m_result_is_pointer) {
274314564Sdim    clang::QualType pointer_qual_type = result_var->getType();
275314564Sdim    const clang::Type *pointer_type = pointer_qual_type.getTypePtr();
276314564Sdim
277314564Sdim    const clang::PointerType *pointer_pointertype =
278314564Sdim        pointer_type->getAs<clang::PointerType>();
279314564Sdim    const clang::ObjCObjectPointerType *pointer_objcobjpointertype =
280314564Sdim        pointer_type->getAs<clang::ObjCObjectPointerType>();
281314564Sdim
282314564Sdim    if (pointer_pointertype) {
283314564Sdim      clang::QualType element_qual_type = pointer_pointertype->getPointeeType();
284314564Sdim
285314564Sdim      m_result_type = lldb_private::TypeFromParser(
286314564Sdim          element_qual_type.getAsOpaquePtr(),
287314564Sdim          lldb_private::ClangASTContext::GetASTContext(
288314564Sdim              &result_decl->getASTContext()));
289314564Sdim    } else if (pointer_objcobjpointertype) {
290314564Sdim      clang::QualType element_qual_type =
291314564Sdim          clang::QualType(pointer_objcobjpointertype->getObjectType(), 0);
292314564Sdim
293314564Sdim      m_result_type = lldb_private::TypeFromParser(
294314564Sdim          element_qual_type.getAsOpaquePtr(),
295314564Sdim          lldb_private::ClangASTContext::GetASTContext(
296314564Sdim              &result_decl->getASTContext()));
297314564Sdim    } else {
298360784Sdim      LLDB_LOG(log, "Expected result to have pointer type, but it did not");
299314564Sdim
300360784Sdim      m_error_stream.Format("Internal error [IRForTarget]: Lvalue result ({0}) "
301314564Sdim                            "is not a pointer variable\n",
302314564Sdim                            result_name);
303314564Sdim
304314564Sdim      return false;
305292932Sdim    }
306314564Sdim  } else {
307314564Sdim    m_result_type = lldb_private::TypeFromParser(
308314564Sdim        result_var->getType().getAsOpaquePtr(),
309314564Sdim        lldb_private::ClangASTContext::GetASTContext(
310314564Sdim            &result_decl->getASTContext()));
311314564Sdim  }
312292932Sdim
313314564Sdim  lldb::TargetSP target_sp(m_execution_unit.GetTarget());
314314564Sdim  lldb_private::ExecutionContext exe_ctx(target_sp, true);
315344779Sdim  llvm::Optional<uint64_t> bit_size =
316344779Sdim      m_result_type.GetBitSize(exe_ctx.GetBestExecutionContextScope());
317344779Sdim  if (!bit_size) {
318314564Sdim    lldb_private::StreamString type_desc_stream;
319314564Sdim    m_result_type.DumpTypeDescription(&type_desc_stream);
320292932Sdim
321360784Sdim    LLDB_LOG(log, "Result type has unknown size");
322292932Sdim
323314564Sdim    m_error_stream.Printf("Error [IRForTarget]: Size of result type '%s' "
324314564Sdim                          "couldn't be determined\n",
325314564Sdim                          type_desc_stream.GetData());
326314564Sdim    return false;
327314564Sdim  }
328292932Sdim
329314564Sdim  if (log) {
330314564Sdim    lldb_private::StreamString type_desc_stream;
331314564Sdim    m_result_type.DumpTypeDescription(&type_desc_stream);
332292932Sdim
333360784Sdim    LLDB_LOG(log, "Result decl type: \"{0}\"", type_desc_stream.GetData());
334314564Sdim  }
335292932Sdim
336314564Sdim  m_result_name = lldb_private::ConstString("$RESULT_NAME");
337292932Sdim
338360784Sdim  LLDB_LOG(log, "Creating a new result global: \"{0}\" with size {1}",
339360784Sdim           m_result_name, m_result_type.GetByteSize(nullptr).getValueOr(0));
340292932Sdim
341314564Sdim  // Construct a new result global and set up its metadata
342292932Sdim
343314564Sdim  GlobalVariable *new_result_global = new GlobalVariable(
344314564Sdim      (*m_module), result_global->getType()->getElementType(),
345353358Sdim      false,                                 /* not constant */
346353358Sdim      GlobalValue::ExternalLinkage, nullptr, /* no initializer */
347314564Sdim      m_result_name.GetCString());
348292932Sdim
349341825Sdim  // It's too late in compilation to create a new VarDecl for this, but we
350341825Sdim  // don't need to.  We point the metadata at the old VarDecl.  This creates an
351341825Sdim  // odd anomaly: a variable with a Value whose name is something like $0 and a
352314564Sdim  // Decl whose name is $__lldb_expr_result.  This condition is handled in
353314564Sdim  // ClangExpressionDeclMap::DoMaterialize, and the name of the variable is
354314564Sdim  // fixed up.
355292932Sdim
356314564Sdim  ConstantInt *new_constant_int =
357314564Sdim      ConstantInt::get(llvm::Type::getInt64Ty(m_module->getContext()),
358360784Sdim                       reinterpret_cast<uintptr_t>(result_decl), false);
359292932Sdim
360314564Sdim  llvm::Metadata *values[2];
361314564Sdim  values[0] = ConstantAsMetadata::get(new_result_global);
362314564Sdim  values[1] = ConstantAsMetadata::get(new_constant_int);
363292932Sdim
364314564Sdim  ArrayRef<Metadata *> value_ref(values, 2);
365292932Sdim
366314564Sdim  MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
367314564Sdim  NamedMDNode *named_metadata =
368314564Sdim      m_module->getNamedMetadata("clang.global.decl.ptrs");
369314564Sdim  named_metadata->addOperand(persistent_global_md);
370314564Sdim
371360784Sdim  LLDB_LOG(log, "Replacing \"{0}\" with \"{1}\"", PrintValue(result_global),
372360784Sdim           PrintValue(new_result_global));
373314564Sdim
374314564Sdim  if (result_global->use_empty()) {
375314564Sdim    // We need to synthesize a store for this variable, because otherwise
376314564Sdim    // there's nothing to put into its equivalent persistent variable.
377314564Sdim
378314564Sdim    BasicBlock &entry_block(llvm_function.getEntryBlock());
379314564Sdim    Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg());
380314564Sdim
381314564Sdim    if (!first_entry_instruction)
382314564Sdim      return false;
383314564Sdim
384314564Sdim    if (!result_global->hasInitializer()) {
385360784Sdim      LLDB_LOG(log, "Couldn't find initializer for unused variable");
386314564Sdim
387360784Sdim      m_error_stream.Format("Internal error [IRForTarget]: Result variable "
388360784Sdim                            "({0}) has no writes and no initializer\n",
389314564Sdim                            result_name);
390314564Sdim
391314564Sdim      return false;
392292932Sdim    }
393292932Sdim
394314564Sdim    Constant *initializer = result_global->getInitializer();
395292932Sdim
396314564Sdim    StoreInst *synthesized_store =
397314564Sdim        new StoreInst(initializer, new_result_global, first_entry_instruction);
398314564Sdim
399360784Sdim    LLDB_LOG(log, "Synthesized result store \"{0}\"\n",
400360784Sdim             PrintValue(synthesized_store));
401314564Sdim  } else {
402314564Sdim    result_global->replaceAllUsesWith(new_result_global);
403314564Sdim  }
404292932Sdim
405314564Sdim  if (!m_decl_map->AddPersistentVariable(
406314564Sdim          result_decl, m_result_name, m_result_type, true, m_result_is_pointer))
407314564Sdim    return false;
408292932Sdim
409314564Sdim  result_global->eraseFromParent();
410292932Sdim
411314564Sdim  return true;
412314564Sdim}
413292932Sdim
414314564Sdimbool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str,
415314564Sdim                                         llvm::GlobalVariable *cstr) {
416314564Sdim  lldb_private::Log *log(
417314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
418292932Sdim
419314564Sdim  Type *ns_str_ty = ns_str->getType();
420292932Sdim
421314564Sdim  Type *i8_ptr_ty = Type::getInt8PtrTy(m_module->getContext());
422314564Sdim  Type *i32_ty = Type::getInt32Ty(m_module->getContext());
423314564Sdim  Type *i8_ty = Type::getInt8Ty(m_module->getContext());
424292932Sdim
425314564Sdim  if (!m_CFStringCreateWithBytes) {
426314564Sdim    lldb::addr_t CFStringCreateWithBytes_addr;
427292932Sdim
428314564Sdim    static lldb_private::ConstString g_CFStringCreateWithBytes_str(
429314564Sdim        "CFStringCreateWithBytes");
430314564Sdim
431353358Sdim    bool missing_weak = false;
432314564Sdim    CFStringCreateWithBytes_addr =
433353358Sdim        m_execution_unit.FindSymbol(g_CFStringCreateWithBytes_str,
434353358Sdim                                    missing_weak);
435353358Sdim    if (CFStringCreateWithBytes_addr == LLDB_INVALID_ADDRESS || missing_weak) {
436314564Sdim        log->PutCString("Couldn't find CFStringCreateWithBytes in the target");
437314564Sdim
438314564Sdim      m_error_stream.Printf("Error [IRForTarget]: Rewriting an Objective-C "
439314564Sdim                            "constant string requires "
440314564Sdim                            "CFStringCreateWithBytes\n");
441314564Sdim
442314564Sdim      return false;
443314564Sdim    }
444314564Sdim
445360784Sdim    LLDB_LOG(log, "Found CFStringCreateWithBytes at {0}",
446360784Sdim             CFStringCreateWithBytes_addr);
447292932Sdim
448314564Sdim    // Build the function type:
449314564Sdim    //
450314564Sdim    // CFStringRef CFStringCreateWithBytes (
451314564Sdim    //   CFAllocatorRef alloc,
452314564Sdim    //   const UInt8 *bytes,
453314564Sdim    //   CFIndex numBytes,
454314564Sdim    //   CFStringEncoding encoding,
455314564Sdim    //   Boolean isExternalRepresentation
456314564Sdim    // );
457314564Sdim    //
458314564Sdim    // We make the following substitutions:
459314564Sdim    //
460314564Sdim    // CFStringRef -> i8*
461314564Sdim    // CFAllocatorRef -> i8*
462314564Sdim    // UInt8 * -> i8*
463314564Sdim    // CFIndex -> long (i32 or i64, as appropriate; we ask the module for its
464341825Sdim    // pointer size for now) CFStringEncoding -> i32 Boolean -> i8
465292932Sdim
466314564Sdim    Type *arg_type_array[5];
467292932Sdim
468314564Sdim    arg_type_array[0] = i8_ptr_ty;
469314564Sdim    arg_type_array[1] = i8_ptr_ty;
470314564Sdim    arg_type_array[2] = m_intptr_ty;
471314564Sdim    arg_type_array[3] = i32_ty;
472314564Sdim    arg_type_array[4] = i8_ty;
473292932Sdim
474314564Sdim    ArrayRef<Type *> CFSCWB_arg_types(arg_type_array, 5);
475292932Sdim
476353358Sdim    llvm::FunctionType *CFSCWB_ty =
477314564Sdim        FunctionType::get(ns_str_ty, CFSCWB_arg_types, false);
478292932Sdim
479314564Sdim    // Build the constant containing the pointer to the function
480314564Sdim    PointerType *CFSCWB_ptr_ty = PointerType::getUnqual(CFSCWB_ty);
481314564Sdim    Constant *CFSCWB_addr_int =
482314564Sdim        ConstantInt::get(m_intptr_ty, CFStringCreateWithBytes_addr, false);
483353358Sdim    m_CFStringCreateWithBytes = {
484353358Sdim        CFSCWB_ty, ConstantExpr::getIntToPtr(CFSCWB_addr_int, CFSCWB_ptr_ty)};
485314564Sdim  }
486292932Sdim
487353358Sdim  ConstantDataSequential *string_array = nullptr;
488292932Sdim
489314564Sdim  if (cstr)
490314564Sdim    string_array = dyn_cast<ConstantDataSequential>(cstr->getInitializer());
491292932Sdim
492314564Sdim  Constant *alloc_arg = Constant::getNullValue(i8_ptr_ty);
493314564Sdim  Constant *bytes_arg = cstr ? ConstantExpr::getBitCast(cstr, i8_ptr_ty)
494314564Sdim                             : Constant::getNullValue(i8_ptr_ty);
495314564Sdim  Constant *numBytes_arg = ConstantInt::get(
496314564Sdim      m_intptr_ty, cstr ? (string_array->getNumElements() - 1) * string_array->getElementByteSize() : 0, false);
497314564Sdim int encoding_flags = 0;
498314564Sdim switch (cstr ? string_array->getElementByteSize() : 1) {
499314564Sdim case 1:
500314564Sdim   encoding_flags = 0x08000100; /* 0x08000100 is kCFStringEncodingUTF8 */
501314564Sdim   break;
502314564Sdim case 2:
503314564Sdim   encoding_flags = 0x0100; /* 0x0100 is kCFStringEncodingUTF16 */
504314564Sdim   break;
505314564Sdim case 4:
506314564Sdim   encoding_flags = 0x0c000100; /* 0x0c000100 is kCFStringEncodingUTF32 */
507314564Sdim   break;
508314564Sdim default:
509314564Sdim   encoding_flags = 0x0600; /* fall back to 0x0600, kCFStringEncodingASCII */
510321369Sdim   LLDB_LOG(log, "Encountered an Objective-C constant string with unusual "
511314564Sdim                 "element size {0}",
512321369Sdim            string_array->getElementByteSize());
513314564Sdim }
514314564Sdim Constant *encoding_arg = ConstantInt::get(i32_ty, encoding_flags, false);
515314564Sdim Constant *isExternal_arg =
516314564Sdim     ConstantInt::get(i8_ty, 0x0, false); /* 0x0 is false */
517314564Sdim
518314564Sdim Value *argument_array[5];
519314564Sdim
520314564Sdim argument_array[0] = alloc_arg;
521314564Sdim argument_array[1] = bytes_arg;
522314564Sdim argument_array[2] = numBytes_arg;
523314564Sdim argument_array[3] = encoding_arg;
524314564Sdim argument_array[4] = isExternal_arg;
525314564Sdim
526314564Sdim ArrayRef<Value *> CFSCWB_arguments(argument_array, 5);
527314564Sdim
528314564Sdim FunctionValueCache CFSCWB_Caller(
529314564Sdim     [this, &CFSCWB_arguments](llvm::Function *function) -> llvm::Value * {
530314564Sdim       return CallInst::Create(
531314564Sdim           m_CFStringCreateWithBytes, CFSCWB_arguments,
532314564Sdim           "CFStringCreateWithBytes",
533314564Sdim           llvm::cast<Instruction>(
534314564Sdim               m_entry_instruction_finder.GetValue(function)));
535314564Sdim     });
536314564Sdim
537314564Sdim if (!UnfoldConstant(ns_str, nullptr, CFSCWB_Caller, m_entry_instruction_finder,
538314564Sdim                     m_error_stream)) {
539360784Sdim   LLDB_LOG(log, "Couldn't replace the NSString with the result of the call");
540314564Sdim
541314564Sdim   m_error_stream.Printf("error [IRForTarget internal]: Couldn't replace an "
542314564Sdim                         "Objective-C constant string with a dynamic "
543314564Sdim                         "string\n");
544314564Sdim
545314564Sdim   return false;
546314564Sdim  }
547314564Sdim
548314564Sdim  ns_str->eraseFromParent();
549314564Sdim
550314564Sdim  return true;
551314564Sdim}
552314564Sdim
553314564Sdimbool IRForTarget::RewriteObjCConstStrings() {
554314564Sdim  lldb_private::Log *log(
555314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
556314564Sdim
557314564Sdim  ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable();
558314564Sdim
559360784Sdim  for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {
560360784Sdim    llvm::StringRef value_name = value_symbol.first();
561314564Sdim
562360784Sdim    if (value_name.contains("_unnamed_cfstring_")) {
563360784Sdim      Value *nsstring_value = value_symbol.second;
564314564Sdim
565314564Sdim      GlobalVariable *nsstring_global =
566314564Sdim          dyn_cast<GlobalVariable>(nsstring_value);
567314564Sdim
568314564Sdim      if (!nsstring_global) {
569360784Sdim        LLDB_LOG(log, "NSString variable is not a GlobalVariable");
570292932Sdim
571314564Sdim        m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
572314564Sdim                              "constant string is not a global variable\n");
573314564Sdim
574292932Sdim        return false;
575314564Sdim      }
576292932Sdim
577314564Sdim      if (!nsstring_global->hasInitializer()) {
578360784Sdim        LLDB_LOG(log, "NSString variable does not have an initializer");
579292932Sdim
580314564Sdim        m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
581314564Sdim                              "constant string does not have an initializer\n");
582292932Sdim
583314564Sdim        return false;
584314564Sdim      }
585292932Sdim
586314564Sdim      ConstantStruct *nsstring_struct =
587314564Sdim          dyn_cast<ConstantStruct>(nsstring_global->getInitializer());
588292932Sdim
589314564Sdim      if (!nsstring_struct) {
590360784Sdim        LLDB_LOG(log,
591360784Sdim                 "NSString variable's initializer is not a ConstantStruct");
592292932Sdim
593314564Sdim        m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
594314564Sdim                              "constant string is not a structure constant\n");
595292932Sdim
596314564Sdim        return false;
597314564Sdim      }
598292932Sdim
599314564Sdim      // We expect the following structure:
600314564Sdim      //
601314564Sdim      // struct {
602314564Sdim      //   int *isa;
603314564Sdim      //   int flags;
604314564Sdim      //   char *str;
605314564Sdim      //   long length;
606314564Sdim      // };
607292932Sdim
608314564Sdim      if (nsstring_struct->getNumOperands() != 4) {
609292932Sdim
610360784Sdim        LLDB_LOG(log,
611360784Sdim                 "NSString variable's initializer structure has an "
612360784Sdim                 "unexpected number of members.  Should be 4, is {0}",
613360784Sdim                 nsstring_struct->getNumOperands());
614360784Sdim
615314564Sdim        m_error_stream.Printf("Internal error [IRForTarget]: The struct for an "
616314564Sdim                              "Objective-C constant string is not as "
617314564Sdim                              "expected\n");
618292932Sdim
619314564Sdim        return false;
620314564Sdim      }
621314564Sdim
622314564Sdim      Constant *nsstring_member = nsstring_struct->getOperand(2);
623314564Sdim
624314564Sdim      if (!nsstring_member) {
625360784Sdim        LLDB_LOG(log, "NSString initializer's str element was empty");
626292932Sdim
627314564Sdim        m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
628314564Sdim                              "constant string does not have a string "
629314564Sdim                              "initializer\n");
630292932Sdim
631314564Sdim        return false;
632314564Sdim      }
633292932Sdim
634314564Sdim      ConstantExpr *nsstring_expr = dyn_cast<ConstantExpr>(nsstring_member);
635292932Sdim
636314564Sdim      if (!nsstring_expr) {
637360784Sdim        LLDB_LOG(log,
638360784Sdim                 "NSString initializer's str element is not a ConstantExpr");
639292932Sdim
640314564Sdim        m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
641314564Sdim                              "constant string's string initializer is not "
642314564Sdim                              "constant\n");
643292932Sdim
644314564Sdim        return false;
645314564Sdim      }
646292932Sdim
647314564Sdim      GlobalVariable *cstr_global = nullptr;
648292932Sdim
649314564Sdim      if (nsstring_expr->getOpcode() == Instruction::GetElementPtr) {
650314564Sdim        Constant *nsstring_cstr = nsstring_expr->getOperand(0);
651314564Sdim        cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr);
652314564Sdim      } else if (nsstring_expr->getOpcode() == Instruction::BitCast) {
653314564Sdim        Constant *nsstring_cstr = nsstring_expr->getOperand(0);
654314564Sdim        cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr);
655314564Sdim      }
656292932Sdim
657314564Sdim      if (!cstr_global) {
658360784Sdim        LLDB_LOG(log,
659360784Sdim                 "NSString initializer's str element is not a GlobalVariable");
660292932Sdim
661314564Sdim        m_error_stream.Printf("Internal error [IRForTarget]: Unhandled"
662314564Sdim                              "constant string initializer\n");
663292932Sdim
664314564Sdim        return false;
665314564Sdim      }
666292932Sdim
667314564Sdim      if (!cstr_global->hasInitializer()) {
668360784Sdim        LLDB_LOG(log, "NSString initializer's str element does not have an "
669360784Sdim                      "initializer");
670292932Sdim
671314564Sdim        m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
672314564Sdim                              "constant string's string initializer doesn't "
673314564Sdim                              "point to initialized data\n");
674292932Sdim
675314564Sdim        return false;
676314564Sdim      }
677314564Sdim
678314564Sdim      /*
679314564Sdim      if (!cstr_array)
680314564Sdim      {
681314564Sdim          if (log)
682314564Sdim              log->PutCString("NSString initializer's str element is not a
683314564Sdim      ConstantArray");
684314564Sdim
685314564Sdim          if (m_error_stream)
686314564Sdim              m_error_stream.Printf("Internal error [IRForTarget]: An
687314564Sdim      Objective-C constant string's string initializer doesn't point to an
688314564Sdim      array\n");
689314564Sdim
690314564Sdim          return false;
691314564Sdim      }
692314564Sdim
693314564Sdim      if (!cstr_array->isCString())
694314564Sdim      {
695314564Sdim          if (log)
696314564Sdim              log->PutCString("NSString initializer's str element is not a C
697314564Sdim      string array");
698314564Sdim
699314564Sdim          if (m_error_stream)
700314564Sdim              m_error_stream.Printf("Internal error [IRForTarget]: An
701314564Sdim      Objective-C constant string's string initializer doesn't point to a C
702314564Sdim      string\n");
703314564Sdim
704314564Sdim          return false;
705314564Sdim      }
706314564Sdim      */
707314564Sdim
708314564Sdim      ConstantDataArray *cstr_array =
709314564Sdim          dyn_cast<ConstantDataArray>(cstr_global->getInitializer());
710314564Sdim
711360784Sdim      if (cstr_array)
712360784Sdim        LLDB_LOG(log, "Found NSString constant {0}, which contains \"{1}\"",
713360784Sdim                 value_name, cstr_array->getAsString());
714360784Sdim      else
715360784Sdim        LLDB_LOG(log, "Found NSString constant {0}, which contains \"\"",
716360784Sdim                 value_name);
717314564Sdim
718314564Sdim      if (!cstr_array)
719353358Sdim        cstr_global = nullptr;
720314564Sdim
721314564Sdim      if (!RewriteObjCConstString(nsstring_global, cstr_global)) {
722360784Sdim        LLDB_LOG(log, "Error rewriting the constant string");
723292932Sdim
724314564Sdim        // We don't print an error message here because RewriteObjCConstString
725314564Sdim        // has done so for us.
726292932Sdim
727292932Sdim        return false;
728314564Sdim      }
729292932Sdim    }
730314564Sdim  }
731292932Sdim
732360784Sdim  for (StringMapEntry<llvm::Value *> &value_symbol : value_symbol_table) {
733360784Sdim    llvm::StringRef value_name = value_symbol.first();
734292932Sdim
735360784Sdim    if (value_name == "__CFConstantStringClassReference") {
736360784Sdim      GlobalVariable *gv = dyn_cast<GlobalVariable>(value_symbol.second);
737292932Sdim
738314564Sdim      if (!gv) {
739360784Sdim        LLDB_LOG(log,
740360784Sdim                 "__CFConstantStringClassReference is not a global variable");
741292932Sdim
742314564Sdim        m_error_stream.Printf("Internal error [IRForTarget]: Found a "
743314564Sdim                              "CFConstantStringClassReference, but it is not a "
744314564Sdim                              "global object\n");
745292932Sdim
746314564Sdim        return false;
747314564Sdim      }
748292932Sdim
749314564Sdim      gv->eraseFromParent();
750292932Sdim
751314564Sdim      break;
752314564Sdim    }
753314564Sdim  }
754292932Sdim
755314564Sdim  return true;
756314564Sdim}
757292932Sdim
758314564Sdimstatic bool IsObjCSelectorRef(Value *value) {
759314564Sdim  GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);
760292932Sdim
761344779Sdim  return !(!global_variable || !global_variable->hasName() ||
762344779Sdim           !global_variable->getName().startswith("OBJC_SELECTOR_REFERENCES_"));
763314564Sdim}
764292932Sdim
765314564Sdim// This function does not report errors; its callers are responsible.
766314564Sdimbool IRForTarget::RewriteObjCSelector(Instruction *selector_load) {
767314564Sdim  lldb_private::Log *log(
768314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
769292932Sdim
770314564Sdim  LoadInst *load = dyn_cast<LoadInst>(selector_load);
771292932Sdim
772314564Sdim  if (!load)
773314564Sdim    return false;
774292932Sdim
775314564Sdim  // Unpack the message name from the selector.  In LLVM IR, an objc_msgSend
776314564Sdim  // gets represented as
777314564Sdim  //
778341825Sdim  // %tmp     = load i8** @"OBJC_SELECTOR_REFERENCES_" ; <i8*> %call    = call
779341825Sdim  // i8* (i8*, i8*, ...)* @objc_msgSend(i8* %obj, i8* %tmp, ...) ; <i8*>
780314564Sdim  //
781314564Sdim  // where %obj is the object pointer and %tmp is the selector.
782314564Sdim  //
783314564Sdim  // @"OBJC_SELECTOR_REFERENCES_" is a pointer to a character array called
784314564Sdim  // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_".
785314564Sdim  // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_" contains the string.
786292932Sdim
787314564Sdim  // Find the pointer's initializer (a ConstantExpr with opcode GetElementPtr)
788314564Sdim  // and get the string from its target
789292932Sdim
790314564Sdim  GlobalVariable *_objc_selector_references_ =
791314564Sdim      dyn_cast<GlobalVariable>(load->getPointerOperand());
792292932Sdim
793314564Sdim  if (!_objc_selector_references_ ||
794314564Sdim      !_objc_selector_references_->hasInitializer())
795314564Sdim    return false;
796292932Sdim
797314564Sdim  Constant *osr_initializer = _objc_selector_references_->getInitializer();
798292932Sdim
799314564Sdim  ConstantExpr *osr_initializer_expr = dyn_cast<ConstantExpr>(osr_initializer);
800292932Sdim
801314564Sdim  if (!osr_initializer_expr ||
802314564Sdim      osr_initializer_expr->getOpcode() != Instruction::GetElementPtr)
803314564Sdim    return false;
804292932Sdim
805314564Sdim  Value *osr_initializer_base = osr_initializer_expr->getOperand(0);
806292932Sdim
807314564Sdim  if (!osr_initializer_base)
808314564Sdim    return false;
809292932Sdim
810314564Sdim  // Find the string's initializer (a ConstantArray) and get the string from it
811292932Sdim
812314564Sdim  GlobalVariable *_objc_meth_var_name_ =
813314564Sdim      dyn_cast<GlobalVariable>(osr_initializer_base);
814292932Sdim
815314564Sdim  if (!_objc_meth_var_name_ || !_objc_meth_var_name_->hasInitializer())
816314564Sdim    return false;
817292932Sdim
818314564Sdim  Constant *omvn_initializer = _objc_meth_var_name_->getInitializer();
819292932Sdim
820314564Sdim  ConstantDataArray *omvn_initializer_array =
821314564Sdim      dyn_cast<ConstantDataArray>(omvn_initializer);
822292932Sdim
823314564Sdim  if (!omvn_initializer_array->isString())
824314564Sdim    return false;
825292932Sdim
826314564Sdim  std::string omvn_initializer_string = omvn_initializer_array->getAsString();
827292932Sdim
828360784Sdim  LLDB_LOG(log, "Found Objective-C selector reference \"{0}\"",
829360784Sdim           omvn_initializer_string);
830292932Sdim
831314564Sdim  // Construct a call to sel_registerName
832292932Sdim
833314564Sdim  if (!m_sel_registerName) {
834314564Sdim    lldb::addr_t sel_registerName_addr;
835292932Sdim
836353358Sdim    bool missing_weak = false;
837314564Sdim    static lldb_private::ConstString g_sel_registerName_str("sel_registerName");
838353358Sdim    sel_registerName_addr = m_execution_unit.FindSymbol(g_sel_registerName_str,
839353358Sdim                                                        missing_weak);
840353358Sdim    if (sel_registerName_addr == LLDB_INVALID_ADDRESS || missing_weak)
841314564Sdim      return false;
842292932Sdim
843360784Sdim    LLDB_LOG(log, "Found sel_registerName at {0}", sel_registerName_addr);
844292932Sdim
845341825Sdim    // Build the function type: struct objc_selector
846341825Sdim    // *sel_registerName(uint8_t*)
847292932Sdim
848314564Sdim    // The below code would be "more correct," but in actuality what's required
849314564Sdim    // is uint8_t*
850314564Sdim    // Type *sel_type = StructType::get(m_module->getContext());
851314564Sdim    // Type *sel_ptr_type = PointerType::getUnqual(sel_type);
852314564Sdim    Type *sel_ptr_type = Type::getInt8PtrTy(m_module->getContext());
853292932Sdim
854314564Sdim    Type *type_array[1];
855292932Sdim
856314564Sdim    type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext());
857292932Sdim
858314564Sdim    ArrayRef<Type *> srN_arg_types(type_array, 1);
859292932Sdim
860353358Sdim    llvm::FunctionType *srN_type =
861314564Sdim        FunctionType::get(sel_ptr_type, srN_arg_types, false);
862292932Sdim
863314564Sdim    // Build the constant containing the pointer to the function
864314564Sdim    PointerType *srN_ptr_ty = PointerType::getUnqual(srN_type);
865314564Sdim    Constant *srN_addr_int =
866314564Sdim        ConstantInt::get(m_intptr_ty, sel_registerName_addr, false);
867353358Sdim    m_sel_registerName = {srN_type,
868353358Sdim                          ConstantExpr::getIntToPtr(srN_addr_int, srN_ptr_ty)};
869314564Sdim  }
870292932Sdim
871314564Sdim  Value *argument_array[1];
872292932Sdim
873314564Sdim  Constant *omvn_pointer = ConstantExpr::getBitCast(
874314564Sdim      _objc_meth_var_name_, Type::getInt8PtrTy(m_module->getContext()));
875292932Sdim
876314564Sdim  argument_array[0] = omvn_pointer;
877292932Sdim
878314564Sdim  ArrayRef<Value *> srN_arguments(argument_array, 1);
879292932Sdim
880314564Sdim  CallInst *srN_call = CallInst::Create(m_sel_registerName, srN_arguments,
881314564Sdim                                        "sel_registerName", selector_load);
882292932Sdim
883314564Sdim  // Replace the load with the call in all users
884292932Sdim
885314564Sdim  selector_load->replaceAllUsesWith(srN_call);
886292932Sdim
887314564Sdim  selector_load->eraseFromParent();
888292932Sdim
889314564Sdim  return true;
890314564Sdim}
891292932Sdim
892314564Sdimbool IRForTarget::RewriteObjCSelectors(BasicBlock &basic_block) {
893314564Sdim  lldb_private::Log *log(
894314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
895292932Sdim
896314564Sdim  InstrList selector_loads;
897292932Sdim
898360784Sdim  for (Instruction &inst : basic_block) {
899314564Sdim    if (LoadInst *load = dyn_cast<LoadInst>(&inst))
900314564Sdim      if (IsObjCSelectorRef(load->getPointerOperand()))
901314564Sdim        selector_loads.push_back(&inst);
902314564Sdim  }
903292932Sdim
904360784Sdim  for (Instruction *inst : selector_loads) {
905360784Sdim    if (!RewriteObjCSelector(inst)) {
906314564Sdim      m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a "
907314564Sdim                            "static reference to an Objective-C selector to a "
908314564Sdim                            "dynamic reference\n");
909314564Sdim
910360784Sdim      LLDB_LOG(log, "Couldn't rewrite a reference to an Objective-C selector");
911314564Sdim
912314564Sdim      return false;
913292932Sdim    }
914314564Sdim  }
915292932Sdim
916314564Sdim  return true;
917292932Sdim}
918292932Sdim
919314564Sdimstatic bool IsObjCClassReference(Value *value) {
920314564Sdim  GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);
921292932Sdim
922344779Sdim  return !(!global_variable || !global_variable->hasName() ||
923344779Sdim           !global_variable->getName().startswith("OBJC_CLASS_REFERENCES_"));
924292932Sdim}
925292932Sdim
926292932Sdim// This function does not report errors; its callers are responsible.
927314564Sdimbool IRForTarget::RewriteObjCClassReference(Instruction *class_load) {
928314564Sdim  lldb_private::Log *log(
929314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
930292932Sdim
931314564Sdim  LoadInst *load = dyn_cast<LoadInst>(class_load);
932292932Sdim
933314564Sdim  if (!load)
934314564Sdim    return false;
935292932Sdim
936314564Sdim  // Unpack the class name from the reference.  In LLVM IR, a reference to an
937314564Sdim  // Objective-C class gets represented as
938314564Sdim  //
939314564Sdim  // %tmp     = load %struct._objc_class*,
940314564Sdim  //            %struct._objc_class** @OBJC_CLASS_REFERENCES_, align 4
941314564Sdim  //
942314564Sdim  // @"OBJC_CLASS_REFERENCES_ is a bitcast of a character array called
943341825Sdim  // @OBJC_CLASS_NAME_. @OBJC_CLASS_NAME contains the string.
944292932Sdim
945341825Sdim  // Find the pointer's initializer (a ConstantExpr with opcode BitCast) and
946341825Sdim  // get the string from its target
947292932Sdim
948314564Sdim  GlobalVariable *_objc_class_references_ =
949314564Sdim      dyn_cast<GlobalVariable>(load->getPointerOperand());
950292932Sdim
951314564Sdim  if (!_objc_class_references_ ||
952314564Sdim      !_objc_class_references_->hasInitializer())
953314564Sdim    return false;
954292932Sdim
955314564Sdim  Constant *ocr_initializer = _objc_class_references_->getInitializer();
956292932Sdim
957314564Sdim  ConstantExpr *ocr_initializer_expr = dyn_cast<ConstantExpr>(ocr_initializer);
958292932Sdim
959314564Sdim  if (!ocr_initializer_expr ||
960314564Sdim      ocr_initializer_expr->getOpcode() != Instruction::BitCast)
961314564Sdim    return false;
962292932Sdim
963314564Sdim  Value *ocr_initializer_base = ocr_initializer_expr->getOperand(0);
964292932Sdim
965314564Sdim  if (!ocr_initializer_base)
966314564Sdim    return false;
967292932Sdim
968314564Sdim  // Find the string's initializer (a ConstantArray) and get the string from it
969292932Sdim
970314564Sdim  GlobalVariable *_objc_class_name_ =
971314564Sdim      dyn_cast<GlobalVariable>(ocr_initializer_base);
972292932Sdim
973314564Sdim  if (!_objc_class_name_ || !_objc_class_name_->hasInitializer())
974314564Sdim    return false;
975292932Sdim
976314564Sdim  Constant *ocn_initializer = _objc_class_name_->getInitializer();
977292932Sdim
978314564Sdim  ConstantDataArray *ocn_initializer_array =
979314564Sdim      dyn_cast<ConstantDataArray>(ocn_initializer);
980292932Sdim
981314564Sdim  if (!ocn_initializer_array->isString())
982314564Sdim    return false;
983292932Sdim
984314564Sdim  std::string ocn_initializer_string = ocn_initializer_array->getAsString();
985292932Sdim
986360784Sdim  LLDB_LOG(log, "Found Objective-C class reference \"{0}\"",
987360784Sdim           ocn_initializer_string);
988292932Sdim
989314564Sdim  // Construct a call to objc_getClass
990292932Sdim
991314564Sdim  if (!m_objc_getClass) {
992314564Sdim    lldb::addr_t objc_getClass_addr;
993292932Sdim
994353358Sdim    bool missing_weak = false;
995314564Sdim    static lldb_private::ConstString g_objc_getClass_str("objc_getClass");
996353358Sdim    objc_getClass_addr = m_execution_unit.FindSymbol(g_objc_getClass_str,
997353358Sdim                                                     missing_weak);
998353358Sdim    if (objc_getClass_addr == LLDB_INVALID_ADDRESS || missing_weak)
999314564Sdim      return false;
1000292932Sdim
1001360784Sdim    LLDB_LOG(log, "Found objc_getClass at {0}", objc_getClass_addr);
1002292932Sdim
1003314564Sdim    // Build the function type: %struct._objc_class *objc_getClass(i8*)
1004292932Sdim
1005314564Sdim    Type *class_type = load->getType();
1006314564Sdim    Type *type_array[1];
1007314564Sdim    type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext());
1008292932Sdim
1009314564Sdim    ArrayRef<Type *> ogC_arg_types(type_array, 1);
1010292932Sdim
1011353358Sdim    llvm::FunctionType *ogC_type =
1012314564Sdim        FunctionType::get(class_type, ogC_arg_types, false);
1013292932Sdim
1014314564Sdim    // Build the constant containing the pointer to the function
1015314564Sdim    PointerType *ogC_ptr_ty = PointerType::getUnqual(ogC_type);
1016314564Sdim    Constant *ogC_addr_int =
1017314564Sdim        ConstantInt::get(m_intptr_ty, objc_getClass_addr, false);
1018353358Sdim    m_objc_getClass = {ogC_type,
1019353358Sdim                       ConstantExpr::getIntToPtr(ogC_addr_int, ogC_ptr_ty)};
1020314564Sdim  }
1021292932Sdim
1022314564Sdim  Value *argument_array[1];
1023292932Sdim
1024314564Sdim  Constant *ocn_pointer = ConstantExpr::getBitCast(
1025314564Sdim      _objc_class_name_, Type::getInt8PtrTy(m_module->getContext()));
1026292932Sdim
1027314564Sdim  argument_array[0] = ocn_pointer;
1028292932Sdim
1029314564Sdim  ArrayRef<Value *> ogC_arguments(argument_array, 1);
1030292932Sdim
1031314564Sdim  CallInst *ogC_call = CallInst::Create(m_objc_getClass, ogC_arguments,
1032314564Sdim                                        "objc_getClass", class_load);
1033292932Sdim
1034314564Sdim  // Replace the load with the call in all users
1035292932Sdim
1036314564Sdim  class_load->replaceAllUsesWith(ogC_call);
1037292932Sdim
1038314564Sdim  class_load->eraseFromParent();
1039292932Sdim
1040314564Sdim  return true;
1041292932Sdim}
1042292932Sdim
1043314564Sdimbool IRForTarget::RewriteObjCClassReferences(BasicBlock &basic_block) {
1044314564Sdim  lldb_private::Log *log(
1045314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1046292932Sdim
1047314564Sdim  InstrList class_loads;
1048292932Sdim
1049360784Sdim  for (Instruction &inst : basic_block) {
1050314564Sdim    if (LoadInst *load = dyn_cast<LoadInst>(&inst))
1051314564Sdim      if (IsObjCClassReference(load->getPointerOperand()))
1052314564Sdim        class_loads.push_back(&inst);
1053314564Sdim  }
1054292932Sdim
1055360784Sdim  for (Instruction *inst : class_loads) {
1056360784Sdim    if (!RewriteObjCClassReference(inst)) {
1057314564Sdim      m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a "
1058314564Sdim                            "static reference to an Objective-C class to a "
1059314564Sdim                            "dynamic reference\n");
1060292932Sdim
1061360784Sdim      LLDB_LOG(log, "Couldn't rewrite a reference to an Objective-C class");
1062292932Sdim
1063314564Sdim      return false;
1064292932Sdim    }
1065314564Sdim  }
1066292932Sdim
1067314564Sdim  return true;
1068292932Sdim}
1069292932Sdim
1070292932Sdim// This function does not report errors; its callers are responsible.
1071314564Sdimbool IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc) {
1072314564Sdim  lldb_private::Log *log(
1073314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1074292932Sdim
1075314564Sdim  AllocaInst *alloc = dyn_cast<AllocaInst>(persistent_alloc);
1076292932Sdim
1077314564Sdim  MDNode *alloc_md = alloc->getMetadata("clang.decl.ptr");
1078292932Sdim
1079314564Sdim  if (!alloc_md || !alloc_md->getNumOperands())
1080314564Sdim    return false;
1081292932Sdim
1082314564Sdim  ConstantInt *constant_int =
1083314564Sdim      mdconst::dyn_extract<ConstantInt>(alloc_md->getOperand(0));
1084292932Sdim
1085314564Sdim  if (!constant_int)
1086314564Sdim    return false;
1087292932Sdim
1088314564Sdim  // We attempt to register this as a new persistent variable with the DeclMap.
1089292932Sdim
1090314564Sdim  uintptr_t ptr = constant_int->getZExtValue();
1091292932Sdim
1092314564Sdim  clang::VarDecl *decl = reinterpret_cast<clang::VarDecl *>(ptr);
1093292932Sdim
1094314564Sdim  lldb_private::TypeFromParser result_decl_type(
1095314564Sdim      decl->getType().getAsOpaquePtr(),
1096314564Sdim      lldb_private::ClangASTContext::GetASTContext(&decl->getASTContext()));
1097292932Sdim
1098314564Sdim  StringRef decl_name(decl->getName());
1099314564Sdim  lldb_private::ConstString persistent_variable_name(decl_name.data(),
1100314564Sdim                                                     decl_name.size());
1101314564Sdim  if (!m_decl_map->AddPersistentVariable(decl, persistent_variable_name,
1102314564Sdim                                         result_decl_type, false, false))
1103314564Sdim    return false;
1104292932Sdim
1105314564Sdim  GlobalVariable *persistent_global = new GlobalVariable(
1106353358Sdim      (*m_module), alloc->getType(), false,  /* not constant */
1107353358Sdim      GlobalValue::ExternalLinkage, nullptr, /* no initializer */
1108314564Sdim      alloc->getName().str());
1109292932Sdim
1110341825Sdim  // What we're going to do here is make believe this was a regular old
1111341825Sdim  // external variable.  That means we need to make the metadata valid.
1112292932Sdim
1113314564Sdim  NamedMDNode *named_metadata =
1114314564Sdim      m_module->getOrInsertNamedMetadata("clang.global.decl.ptrs");
1115292932Sdim
1116314564Sdim  llvm::Metadata *values[2];
1117314564Sdim  values[0] = ConstantAsMetadata::get(persistent_global);
1118314564Sdim  values[1] = ConstantAsMetadata::get(constant_int);
1119292932Sdim
1120314564Sdim  ArrayRef<llvm::Metadata *> value_ref(values, 2);
1121292932Sdim
1122314564Sdim  MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
1123314564Sdim  named_metadata->addOperand(persistent_global_md);
1124292932Sdim
1125314564Sdim  // Now, since the variable is a pointer variable, we will drop in a load of
1126341825Sdim  // that pointer variable.
1127292932Sdim
1128314564Sdim  LoadInst *persistent_load = new LoadInst(persistent_global, "", alloc);
1129292932Sdim
1130360784Sdim  LLDB_LOG(log, "Replacing \"{0}\" with \"{1}\"", PrintValue(alloc),
1131360784Sdim           PrintValue(persistent_load));
1132292932Sdim
1133314564Sdim  alloc->replaceAllUsesWith(persistent_load);
1134314564Sdim  alloc->eraseFromParent();
1135292932Sdim
1136314564Sdim  return true;
1137292932Sdim}
1138292932Sdim
1139314564Sdimbool IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) {
1140314564Sdim  if (!m_resolve_vars)
1141314564Sdim    return true;
1142292932Sdim
1143314564Sdim  lldb_private::Log *log(
1144314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1145292932Sdim
1146314564Sdim  InstrList pvar_allocs;
1147292932Sdim
1148360784Sdim  for (Instruction &inst : basic_block) {
1149292932Sdim
1150314564Sdim    if (AllocaInst *alloc = dyn_cast<AllocaInst>(&inst)) {
1151314564Sdim      llvm::StringRef alloc_name = alloc->getName();
1152292932Sdim
1153314564Sdim      if (alloc_name.startswith("$") && !alloc_name.startswith("$__lldb")) {
1154314564Sdim        if (alloc_name.find_first_of("0123456789") == 1) {
1155360784Sdim          LLDB_LOG(log, "Rejecting a numeric persistent variable.");
1156292932Sdim
1157314564Sdim          m_error_stream.Printf("Error [IRForTarget]: Names starting with $0, "
1158314564Sdim                                "$1, ... are reserved for use as result "
1159314564Sdim                                "names\n");
1160292932Sdim
1161314564Sdim          return false;
1162314564Sdim        }
1163292932Sdim
1164314564Sdim        pvar_allocs.push_back(alloc);
1165314564Sdim      }
1166292932Sdim    }
1167314564Sdim  }
1168292932Sdim
1169360784Sdim  for (Instruction *inst : pvar_allocs) {
1170360784Sdim    if (!RewritePersistentAlloc(inst)) {
1171314564Sdim      m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
1172314564Sdim                            "the creation of a persistent variable\n");
1173292932Sdim
1174360784Sdim      LLDB_LOG(log, "Couldn't rewrite the creation of a persistent variable");
1175292932Sdim
1176314564Sdim      return false;
1177292932Sdim    }
1178314564Sdim  }
1179292932Sdim
1180314564Sdim  return true;
1181292932Sdim}
1182292932Sdim
1183292932Sdim// This function does not report errors; its callers are responsible.
1184314564Sdimbool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) {
1185314564Sdim  lldb_private::Log *log(
1186314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1187292932Sdim
1188360784Sdim  LLDB_LOG(log, "MaybeHandleVariable ({0})", PrintValue(llvm_value_ptr));
1189292932Sdim
1190314564Sdim  if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(llvm_value_ptr)) {
1191314564Sdim    switch (constant_expr->getOpcode()) {
1192314564Sdim    default:
1193314564Sdim      break;
1194314564Sdim    case Instruction::GetElementPtr:
1195314564Sdim    case Instruction::BitCast:
1196314564Sdim      Value *s = constant_expr->getOperand(0);
1197314564Sdim      if (!MaybeHandleVariable(s))
1198314564Sdim        return false;
1199292932Sdim    }
1200314564Sdim  } else if (GlobalVariable *global_variable =
1201314564Sdim                 dyn_cast<GlobalVariable>(llvm_value_ptr)) {
1202314564Sdim    if (!GlobalValue::isExternalLinkage(global_variable->getLinkage()))
1203314564Sdim      return true;
1204292932Sdim
1205314564Sdim    clang::NamedDecl *named_decl = DeclForGlobal(global_variable);
1206292932Sdim
1207314564Sdim    if (!named_decl) {
1208314564Sdim      if (IsObjCSelectorRef(llvm_value_ptr))
1209314564Sdim        return true;
1210292932Sdim
1211314564Sdim      if (!global_variable->hasExternalLinkage())
1212314564Sdim        return true;
1213292932Sdim
1214360784Sdim      LLDB_LOG(log, "Found global variable \"{0}\" without metadata",
1215360784Sdim               global_variable->getName());
1216292932Sdim
1217314564Sdim      return false;
1218314564Sdim    }
1219292932Sdim
1220360784Sdim    llvm::StringRef name(named_decl->getName());
1221292932Sdim
1222314564Sdim    clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl);
1223353358Sdim    if (value_decl == nullptr)
1224314564Sdim      return false;
1225292932Sdim
1226360784Sdim    lldb_private::CompilerType compiler_type(
1227360784Sdim        lldb_private::ClangASTContext::GetASTContext(
1228360784Sdim            &value_decl->getASTContext()),
1229360784Sdim        value_decl->getType().getAsOpaquePtr());
1230292932Sdim
1231353358Sdim    const Type *value_type = nullptr;
1232292932Sdim
1233360784Sdim    if (name.startswith("$")) {
1234314564Sdim      // The $__lldb_expr_result name indicates the return value has allocated
1235341825Sdim      // as a static variable.  Per the comment at
1236341825Sdim      // ASTResultSynthesizer::SynthesizeBodyResult, accesses to this static
1237341825Sdim      // variable need to be redirected to the result of dereferencing a
1238341825Sdim      // pointer that is passed in as one of the arguments.
1239314564Sdim      //
1240314564Sdim      // Consequently, when reporting the size of the type, we report a pointer
1241341825Sdim      // type pointing to the type of $__lldb_expr_result, not the type itself.
1242314564Sdim      //
1243314564Sdim      // We also do this for any user-declared persistent variables.
1244314564Sdim      compiler_type = compiler_type.GetPointerType();
1245314564Sdim      value_type = PointerType::get(global_variable->getType(), 0);
1246314564Sdim    } else {
1247314564Sdim      value_type = global_variable->getType();
1248314564Sdim    }
1249292932Sdim
1250344779Sdim    llvm::Optional<uint64_t> value_size = compiler_type.GetByteSize(nullptr);
1251344779Sdim    if (!value_size)
1252344779Sdim      return false;
1253360784Sdim    llvm::Optional<size_t> opt_alignment = compiler_type.GetTypeBitAlign(nullptr);
1254360784Sdim    if (!opt_alignment)
1255360784Sdim      return false;
1256360784Sdim    lldb::offset_t value_alignment = (*opt_alignment + 7ull) / 8ull;
1257292932Sdim
1258360784Sdim    LLDB_LOG(log,
1259360784Sdim             "Type of \"{0}\" is [clang \"{1}\", llvm \"{2}\"] [size {3}, "
1260360784Sdim             "align {4}]",
1261360784Sdim             name,
1262360784Sdim             lldb_private::ClangUtil::GetQualType(compiler_type).getAsString(),
1263360784Sdim             PrintType(value_type), *value_size, value_alignment);
1264292932Sdim
1265360784Sdim    if (named_decl)
1266360784Sdim      m_decl_map->AddValueToStruct(named_decl, lldb_private::ConstString(name),
1267360784Sdim                                   llvm_value_ptr, *value_size,
1268360784Sdim                                   value_alignment);
1269314564Sdim  } else if (dyn_cast<llvm::Function>(llvm_value_ptr)) {
1270360784Sdim    LLDB_LOG(log, "Function pointers aren't handled right now");
1271292932Sdim
1272314564Sdim    return false;
1273314564Sdim  }
1274314564Sdim
1275314564Sdim  return true;
1276292932Sdim}
1277292932Sdim
1278292932Sdim// This function does not report errors; its callers are responsible.
1279314564Sdimbool IRForTarget::HandleSymbol(Value *symbol) {
1280314564Sdim  lldb_private::Log *log(
1281314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1282292932Sdim
1283314564Sdim  lldb_private::ConstString name(symbol->getName().str().c_str());
1284292932Sdim
1285314564Sdim  lldb::addr_t symbol_addr =
1286314564Sdim      m_decl_map->GetSymbolAddress(name, lldb::eSymbolTypeAny);
1287292932Sdim
1288314564Sdim  if (symbol_addr == LLDB_INVALID_ADDRESS) {
1289360784Sdim    LLDB_LOG(log, "Symbol \"{0}\" had no address", name);
1290292932Sdim
1291314564Sdim    return false;
1292314564Sdim  }
1293292932Sdim
1294360784Sdim  LLDB_LOG(log, "Found \"{0}\" at {1}", name, symbol_addr);
1295292932Sdim
1296314564Sdim  Type *symbol_type = symbol->getType();
1297292932Sdim
1298314564Sdim  Constant *symbol_addr_int = ConstantInt::get(m_intptr_ty, symbol_addr, false);
1299292932Sdim
1300314564Sdim  Value *symbol_addr_ptr =
1301314564Sdim      ConstantExpr::getIntToPtr(symbol_addr_int, symbol_type);
1302292932Sdim
1303360784Sdim  LLDB_LOG(log, "Replacing {0} with {1}", PrintValue(symbol),
1304360784Sdim           PrintValue(symbol_addr_ptr));
1305292932Sdim
1306314564Sdim  symbol->replaceAllUsesWith(symbol_addr_ptr);
1307292932Sdim
1308314564Sdim  return true;
1309292932Sdim}
1310292932Sdim
1311314564Sdimbool IRForTarget::MaybeHandleCallArguments(CallInst *Old) {
1312314564Sdim  lldb_private::Log *log(
1313314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1314292932Sdim
1315360784Sdim  LLDB_LOG(log, "MaybeHandleCallArguments({0})", PrintValue(Old));
1316292932Sdim
1317314564Sdim  for (unsigned op_index = 0, num_ops = Old->getNumArgOperands();
1318314564Sdim       op_index < num_ops; ++op_index)
1319360784Sdim    // conservatively believe that this is a store
1320360784Sdim    if (!MaybeHandleVariable(Old->getArgOperand(op_index))) {
1321314564Sdim      m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
1322314564Sdim                            "one of the arguments of a function call.\n");
1323292932Sdim
1324314564Sdim      return false;
1325314564Sdim    }
1326292932Sdim
1327314564Sdim  return true;
1328292932Sdim}
1329292932Sdim
1330314564Sdimbool IRForTarget::HandleObjCClass(Value *classlist_reference) {
1331314564Sdim  lldb_private::Log *log(
1332314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1333292932Sdim
1334314564Sdim  GlobalVariable *global_variable =
1335314564Sdim      dyn_cast<GlobalVariable>(classlist_reference);
1336292932Sdim
1337314564Sdim  if (!global_variable)
1338314564Sdim    return false;
1339292932Sdim
1340314564Sdim  Constant *initializer = global_variable->getInitializer();
1341292932Sdim
1342314564Sdim  if (!initializer)
1343314564Sdim    return false;
1344292932Sdim
1345314564Sdim  if (!initializer->hasName())
1346314564Sdim    return false;
1347292932Sdim
1348314564Sdim  StringRef name(initializer->getName());
1349314564Sdim  lldb_private::ConstString name_cstr(name.str().c_str());
1350314564Sdim  lldb::addr_t class_ptr =
1351314564Sdim      m_decl_map->GetSymbolAddress(name_cstr, lldb::eSymbolTypeObjCClass);
1352292932Sdim
1353360784Sdim  LLDB_LOG(log, "Found reference to Objective-C class {0} ({1})", name,
1354360784Sdim           (unsigned long long)class_ptr);
1355292932Sdim
1356314564Sdim  if (class_ptr == LLDB_INVALID_ADDRESS)
1357314564Sdim    return false;
1358292932Sdim
1359314564Sdim  if (global_variable->use_empty())
1360314564Sdim    return false;
1361292932Sdim
1362314564Sdim  SmallVector<LoadInst *, 2> load_instructions;
1363292932Sdim
1364314564Sdim  for (llvm::User *u : global_variable->users()) {
1365314564Sdim    if (LoadInst *load_instruction = dyn_cast<LoadInst>(u))
1366314564Sdim      load_instructions.push_back(load_instruction);
1367314564Sdim  }
1368292932Sdim
1369314564Sdim  if (load_instructions.empty())
1370314564Sdim    return false;
1371292932Sdim
1372314564Sdim  Constant *class_addr = ConstantInt::get(m_intptr_ty, (uint64_t)class_ptr);
1373292932Sdim
1374314564Sdim  for (LoadInst *load_instruction : load_instructions) {
1375314564Sdim    Constant *class_bitcast =
1376314564Sdim        ConstantExpr::getIntToPtr(class_addr, load_instruction->getType());
1377292932Sdim
1378314564Sdim    load_instruction->replaceAllUsesWith(class_bitcast);
1379292932Sdim
1380314564Sdim    load_instruction->eraseFromParent();
1381314564Sdim  }
1382292932Sdim
1383314564Sdim  return true;
1384292932Sdim}
1385292932Sdim
1386314564Sdimbool IRForTarget::RemoveCXAAtExit(BasicBlock &basic_block) {
1387314564Sdim  std::vector<CallInst *> calls_to_remove;
1388292932Sdim
1389360784Sdim  for (Instruction &inst : basic_block) {
1390314564Sdim    CallInst *call = dyn_cast<CallInst>(&inst);
1391292932Sdim
1392314564Sdim    // MaybeHandleCallArguments handles error reporting; we are silent here
1393314564Sdim    if (!call)
1394314564Sdim      continue;
1395292932Sdim
1396314564Sdim    bool remove = false;
1397292932Sdim
1398314564Sdim    llvm::Function *func = call->getCalledFunction();
1399292932Sdim
1400314564Sdim    if (func && func->getName() == "__cxa_atexit")
1401314564Sdim      remove = true;
1402292932Sdim
1403314564Sdim    llvm::Value *val = call->getCalledValue();
1404292932Sdim
1405314564Sdim    if (val && val->getName() == "__cxa_atexit")
1406314564Sdim      remove = true;
1407292932Sdim
1408314564Sdim    if (remove)
1409314564Sdim      calls_to_remove.push_back(call);
1410314564Sdim  }
1411292932Sdim
1412360784Sdim  for (CallInst *ci : calls_to_remove)
1413360784Sdim    ci->eraseFromParent();
1414292932Sdim
1415314564Sdim  return true;
1416292932Sdim}
1417292932Sdim
1418314564Sdimbool IRForTarget::ResolveCalls(BasicBlock &basic_block) {
1419314564Sdim  // Prepare the current basic block for execution in the remote process
1420292932Sdim
1421360784Sdim  for (Instruction &inst : basic_block) {
1422314564Sdim    CallInst *call = dyn_cast<CallInst>(&inst);
1423292932Sdim
1424314564Sdim    // MaybeHandleCallArguments handles error reporting; we are silent here
1425314564Sdim    if (call && !MaybeHandleCallArguments(call))
1426314564Sdim      return false;
1427314564Sdim  }
1428292932Sdim
1429314564Sdim  return true;
1430292932Sdim}
1431292932Sdim
1432314564Sdimbool IRForTarget::ResolveExternals(Function &llvm_function) {
1433314564Sdim  lldb_private::Log *log(
1434314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1435292932Sdim
1436314564Sdim  for (GlobalVariable &global_var : m_module->globals()) {
1437360784Sdim    llvm::StringRef global_name = global_var.getName();
1438292932Sdim
1439360784Sdim    LLDB_LOG(log, "Examining {0}, DeclForGlobalValue returns {1}", global_name,
1440360784Sdim             static_cast<void *>(DeclForGlobal(&global_var)));
1441292932Sdim
1442360784Sdim    if (global_name.startswith("OBJC_IVAR")) {
1443314564Sdim      if (!HandleSymbol(&global_var)) {
1444360784Sdim        m_error_stream.Format("Error [IRForTarget]: Couldn't find Objective-C "
1445360784Sdim                              "indirect ivar symbol {0}\n",
1446360784Sdim                              global_name);
1447292932Sdim
1448314564Sdim        return false;
1449314564Sdim      }
1450360784Sdim    } else if (global_name.contains("OBJC_CLASSLIST_REFERENCES_$")) {
1451314564Sdim      if (!HandleObjCClass(&global_var)) {
1452314564Sdim        m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class "
1453314564Sdim                              "for an Objective-C static method call\n");
1454292932Sdim
1455314564Sdim        return false;
1456314564Sdim      }
1457360784Sdim    } else if (global_name.contains("OBJC_CLASSLIST_SUP_REFS_$")) {
1458314564Sdim      if (!HandleObjCClass(&global_var)) {
1459314564Sdim        m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class "
1460314564Sdim                              "for an Objective-C static method call\n");
1461292932Sdim
1462314564Sdim        return false;
1463314564Sdim      }
1464314564Sdim    } else if (DeclForGlobal(&global_var)) {
1465314564Sdim      if (!MaybeHandleVariable(&global_var)) {
1466360784Sdim        m_error_stream.Format("Internal error [IRForTarget]: Couldn't rewrite "
1467360784Sdim                              "external variable {0}\n",
1468360784Sdim                              global_name);
1469292932Sdim
1470314564Sdim        return false;
1471314564Sdim      }
1472292932Sdim    }
1473314564Sdim  }
1474292932Sdim
1475314564Sdim  return true;
1476292932Sdim}
1477292932Sdim
1478314564Sdimstatic bool isGuardVariableRef(Value *V) {
1479360784Sdim  Constant *Old = dyn_cast<Constant>(V);
1480292932Sdim
1481360784Sdim  if (!Old)
1482314564Sdim    return false;
1483292932Sdim
1484360784Sdim  if (auto CE = dyn_cast<ConstantExpr>(V)) {
1485314564Sdim    if (CE->getOpcode() != Instruction::BitCast)
1486314564Sdim      return false;
1487292932Sdim
1488314564Sdim    Old = CE->getOperand(0);
1489314564Sdim  }
1490292932Sdim
1491314564Sdim  GlobalVariable *GV = dyn_cast<GlobalVariable>(Old);
1492292932Sdim
1493360784Sdim  if (!GV || !GV->hasName() || !isGuardVariableSymbol(GV->getName()))
1494314564Sdim    return false;
1495292932Sdim
1496314564Sdim  return true;
1497292932Sdim}
1498292932Sdim
1499314564Sdimvoid IRForTarget::TurnGuardLoadIntoZero(llvm::Instruction *guard_load) {
1500314564Sdim  Constant *zero(Constant::getNullValue(guard_load->getType()));
1501314564Sdim  guard_load->replaceAllUsesWith(zero);
1502314564Sdim  guard_load->eraseFromParent();
1503292932Sdim}
1504292932Sdim
1505314564Sdimstatic void ExciseGuardStore(Instruction *guard_store) {
1506314564Sdim  guard_store->eraseFromParent();
1507292932Sdim}
1508292932Sdim
1509314564Sdimbool IRForTarget::RemoveGuards(BasicBlock &basic_block) {
1510314564Sdim  // Eliminate any reference to guard variables found.
1511292932Sdim
1512314564Sdim  InstrList guard_loads;
1513314564Sdim  InstrList guard_stores;
1514292932Sdim
1515360784Sdim  for (Instruction &inst : basic_block) {
1516292932Sdim
1517314564Sdim    if (LoadInst *load = dyn_cast<LoadInst>(&inst))
1518314564Sdim      if (isGuardVariableRef(load->getPointerOperand()))
1519314564Sdim        guard_loads.push_back(&inst);
1520292932Sdim
1521314564Sdim    if (StoreInst *store = dyn_cast<StoreInst>(&inst))
1522314564Sdim      if (isGuardVariableRef(store->getPointerOperand()))
1523314564Sdim        guard_stores.push_back(&inst);
1524314564Sdim  }
1525292932Sdim
1526360784Sdim  for (Instruction *inst : guard_loads)
1527360784Sdim    TurnGuardLoadIntoZero(inst);
1528292932Sdim
1529360784Sdim  for (Instruction *inst : guard_stores)
1530360784Sdim    ExciseGuardStore(inst);
1531292932Sdim
1532314564Sdim  return true;
1533292932Sdim}
1534292932Sdim
1535292932Sdim// This function does not report errors; its callers are responsible.
1536314564Sdimbool IRForTarget::UnfoldConstant(Constant *old_constant,
1537314564Sdim                                 llvm::Function *llvm_function,
1538314564Sdim                                 FunctionValueCache &value_maker,
1539314564Sdim                                 FunctionValueCache &entry_instruction_finder,
1540314564Sdim                                 lldb_private::Stream &error_stream) {
1541314564Sdim  SmallVector<User *, 16> users;
1542292932Sdim
1543314564Sdim  // We do this because the use list might change, invalidating our iterator.
1544314564Sdim  // Much better to keep a work list ourselves.
1545314564Sdim  for (llvm::User *u : old_constant->users())
1546314564Sdim    users.push_back(u);
1547292932Sdim
1548314564Sdim  for (size_t i = 0; i < users.size(); ++i) {
1549314564Sdim    User *user = users[i];
1550292932Sdim
1551314564Sdim    if (Constant *constant = dyn_cast<Constant>(user)) {
1552314564Sdim      // synthesize a new non-constant equivalent of the constant
1553292932Sdim
1554314564Sdim      if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant)) {
1555314564Sdim        switch (constant_expr->getOpcode()) {
1556314564Sdim        default:
1557314564Sdim          error_stream.Printf("error [IRForTarget internal]: Unhandled "
1558314564Sdim                              "constant expression type: \"%s\"",
1559314564Sdim                              PrintValue(constant_expr).c_str());
1560314564Sdim          return false;
1561314564Sdim        case Instruction::BitCast: {
1562314564Sdim          FunctionValueCache bit_cast_maker(
1563314564Sdim              [&value_maker, &entry_instruction_finder, old_constant,
1564314564Sdim               constant_expr](llvm::Function *function) -> llvm::Value * {
1565314564Sdim                // UnaryExpr
1566314564Sdim                //   OperandList[0] is value
1567292932Sdim
1568314564Sdim                if (constant_expr->getOperand(0) != old_constant)
1569314564Sdim                  return constant_expr;
1570292932Sdim
1571314564Sdim                return new BitCastInst(
1572314564Sdim                    value_maker.GetValue(function), constant_expr->getType(),
1573314564Sdim                    "", llvm::cast<Instruction>(
1574314564Sdim                            entry_instruction_finder.GetValue(function)));
1575314564Sdim              });
1576292932Sdim
1577314564Sdim          if (!UnfoldConstant(constant_expr, llvm_function, bit_cast_maker,
1578314564Sdim                              entry_instruction_finder, error_stream))
1579314564Sdim            return false;
1580314564Sdim        } break;
1581314564Sdim        case Instruction::GetElementPtr: {
1582314564Sdim          // GetElementPtrConstantExpr
1583314564Sdim          //   OperandList[0] is base
1584314564Sdim          //   OperandList[1]... are indices
1585292932Sdim
1586314564Sdim          FunctionValueCache get_element_pointer_maker(
1587314564Sdim              [&value_maker, &entry_instruction_finder, old_constant,
1588314564Sdim               constant_expr](llvm::Function *function) -> llvm::Value * {
1589314564Sdim                Value *ptr = constant_expr->getOperand(0);
1590292932Sdim
1591314564Sdim                if (ptr == old_constant)
1592314564Sdim                  ptr = value_maker.GetValue(function);
1593292932Sdim
1594314564Sdim                std::vector<Value *> index_vector;
1595292932Sdim
1596314564Sdim                unsigned operand_index;
1597314564Sdim                unsigned num_operands = constant_expr->getNumOperands();
1598292932Sdim
1599314564Sdim                for (operand_index = 1; operand_index < num_operands;
1600314564Sdim                     ++operand_index) {
1601314564Sdim                  Value *operand = constant_expr->getOperand(operand_index);
1602292932Sdim
1603314564Sdim                  if (operand == old_constant)
1604314564Sdim                    operand = value_maker.GetValue(function);
1605292932Sdim
1606314564Sdim                  index_vector.push_back(operand);
1607314564Sdim                }
1608292932Sdim
1609314564Sdim                ArrayRef<Value *> indices(index_vector);
1610292932Sdim
1611314564Sdim                return GetElementPtrInst::Create(
1612314564Sdim                    nullptr, ptr, indices, "",
1613314564Sdim                    llvm::cast<Instruction>(
1614314564Sdim                        entry_instruction_finder.GetValue(function)));
1615314564Sdim              });
1616292932Sdim
1617314564Sdim          if (!UnfoldConstant(constant_expr, llvm_function,
1618314564Sdim                              get_element_pointer_maker,
1619314564Sdim                              entry_instruction_finder, error_stream))
1620314564Sdim            return false;
1621314564Sdim        } break;
1622292932Sdim        }
1623314564Sdim      } else {
1624314564Sdim        error_stream.Printf(
1625314564Sdim            "error [IRForTarget internal]: Unhandled constant type: \"%s\"",
1626314564Sdim            PrintValue(constant).c_str());
1627314564Sdim        return false;
1628314564Sdim      }
1629314564Sdim    } else {
1630314564Sdim      if (Instruction *inst = llvm::dyn_cast<Instruction>(user)) {
1631314564Sdim        if (llvm_function && inst->getParent()->getParent() != llvm_function) {
1632314564Sdim          error_stream.PutCString("error: Capturing non-local variables in "
1633314564Sdim                                  "expressions is unsupported.\n");
1634314564Sdim          return false;
1635292932Sdim        }
1636314564Sdim        inst->replaceUsesOfWith(
1637314564Sdim            old_constant, value_maker.GetValue(inst->getParent()->getParent()));
1638314564Sdim      } else {
1639314564Sdim        error_stream.Printf(
1640314564Sdim            "error [IRForTarget internal]: Unhandled non-constant type: \"%s\"",
1641314564Sdim            PrintValue(user).c_str());
1642314564Sdim        return false;
1643314564Sdim      }
1644292932Sdim    }
1645314564Sdim  }
1646292932Sdim
1647314564Sdim  if (!isa<GlobalValue>(old_constant)) {
1648314564Sdim    old_constant->destroyConstant();
1649314564Sdim  }
1650292932Sdim
1651314564Sdim  return true;
1652292932Sdim}
1653292932Sdim
1654314564Sdimbool IRForTarget::ReplaceVariables(Function &llvm_function) {
1655314564Sdim  if (!m_resolve_vars)
1656314564Sdim    return true;
1657292932Sdim
1658314564Sdim  lldb_private::Log *log(
1659314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1660292932Sdim
1661314564Sdim  m_decl_map->DoStructLayout();
1662292932Sdim
1663360784Sdim  LLDB_LOG(log, "Element arrangement:");
1664292932Sdim
1665314564Sdim  uint32_t num_elements;
1666314564Sdim  uint32_t element_index;
1667292932Sdim
1668314564Sdim  size_t size;
1669314564Sdim  lldb::offset_t alignment;
1670292932Sdim
1671314564Sdim  if (!m_decl_map->GetStructInfo(num_elements, size, alignment))
1672314564Sdim    return false;
1673292932Sdim
1674321369Sdim  Function::arg_iterator iter(llvm_function.arg_begin());
1675292932Sdim
1676321369Sdim  if (iter == llvm_function.arg_end()) {
1677314564Sdim    m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes no "
1678314564Sdim                          "arguments (should take at least a struct pointer)");
1679292932Sdim
1680314564Sdim    return false;
1681314564Sdim  }
1682292932Sdim
1683314564Sdim  Argument *argument = &*iter;
1684292932Sdim
1685314564Sdim  if (argument->getName().equals("this")) {
1686314564Sdim    ++iter;
1687292932Sdim
1688321369Sdim    if (iter == llvm_function.arg_end()) {
1689314564Sdim      m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
1690314564Sdim                            "'this' argument (should take a struct pointer "
1691314564Sdim                            "too)");
1692292932Sdim
1693314564Sdim      return false;
1694292932Sdim    }
1695292932Sdim
1696314564Sdim    argument = &*iter;
1697314564Sdim  } else if (argument->getName().equals("self")) {
1698314564Sdim    ++iter;
1699292932Sdim
1700321369Sdim    if (iter == llvm_function.arg_end()) {
1701314564Sdim      m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
1702314564Sdim                            "'self' argument (should take '_cmd' and a struct "
1703314564Sdim                            "pointer too)");
1704292932Sdim
1705314564Sdim      return false;
1706314564Sdim    }
1707292932Sdim
1708314564Sdim    if (!iter->getName().equals("_cmd")) {
1709360784Sdim      m_error_stream.Format("Internal error [IRForTarget]: Wrapper takes '{0}' "
1710314564Sdim                            "after 'self' argument (should take '_cmd')",
1711360784Sdim                            iter->getName());
1712292932Sdim
1713314564Sdim      return false;
1714314564Sdim    }
1715292932Sdim
1716314564Sdim    ++iter;
1717292932Sdim
1718321369Sdim    if (iter == llvm_function.arg_end()) {
1719314564Sdim      m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
1720314564Sdim                            "'self' and '_cmd' arguments (should take a struct "
1721314564Sdim                            "pointer too)");
1722292932Sdim
1723314564Sdim      return false;
1724292932Sdim    }
1725292932Sdim
1726314564Sdim    argument = &*iter;
1727314564Sdim  }
1728292932Sdim
1729314564Sdim  if (!argument->getName().equals("$__lldb_arg")) {
1730360784Sdim    m_error_stream.Format("Internal error [IRForTarget]: Wrapper takes an "
1731360784Sdim                          "argument named '{0}' instead of the struct pointer",
1732360784Sdim                          argument->getName());
1733292932Sdim
1734314564Sdim    return false;
1735314564Sdim  }
1736292932Sdim
1737360784Sdim  LLDB_LOG(log, "Arg: \"{0}\"", PrintValue(argument));
1738292932Sdim
1739314564Sdim  BasicBlock &entry_block(llvm_function.getEntryBlock());
1740314564Sdim  Instruction *FirstEntryInstruction(entry_block.getFirstNonPHIOrDbg());
1741292932Sdim
1742314564Sdim  if (!FirstEntryInstruction) {
1743314564Sdim    m_error_stream.Printf("Internal error [IRForTarget]: Couldn't find the "
1744314564Sdim                          "first instruction in the wrapper for use in "
1745314564Sdim                          "rewriting");
1746292932Sdim
1747314564Sdim    return false;
1748314564Sdim  }
1749292932Sdim
1750314564Sdim  LLVMContext &context(m_module->getContext());
1751314564Sdim  IntegerType *offset_type(Type::getInt32Ty(context));
1752292932Sdim
1753314564Sdim  if (!offset_type) {
1754314564Sdim    m_error_stream.Printf(
1755314564Sdim        "Internal error [IRForTarget]: Couldn't produce an offset type");
1756292932Sdim
1757314564Sdim    return false;
1758314564Sdim  }
1759292932Sdim
1760314564Sdim  for (element_index = 0; element_index < num_elements; ++element_index) {
1761353358Sdim    const clang::NamedDecl *decl = nullptr;
1762353358Sdim    Value *value = nullptr;
1763314564Sdim    lldb::offset_t offset;
1764314564Sdim    lldb_private::ConstString name;
1765292932Sdim
1766314564Sdim    if (!m_decl_map->GetStructElement(decl, value, offset, name,
1767314564Sdim                                      element_index)) {
1768314564Sdim      m_error_stream.Printf(
1769314564Sdim          "Internal error [IRForTarget]: Structure information is incomplete");
1770292932Sdim
1771314564Sdim      return false;
1772314564Sdim    }
1773292932Sdim
1774360784Sdim    LLDB_LOG(log, "  \"{0}\" (\"{1}\") placed at {2}", name,
1775360784Sdim             decl->getNameAsString(), offset);
1776292932Sdim
1777314564Sdim    if (value) {
1778360784Sdim      LLDB_LOG(log, "    Replacing [{0}]", PrintValue(value));
1779292932Sdim
1780314564Sdim      FunctionValueCache body_result_maker(
1781314564Sdim          [this, name, offset_type, offset, argument,
1782314564Sdim           value](llvm::Function *function) -> llvm::Value * {
1783341825Sdim            // Per the comment at ASTResultSynthesizer::SynthesizeBodyResult,
1784341825Sdim            // in cases where the result variable is an rvalue, we have to
1785341825Sdim            // synthesize a dereference of the appropriate structure entry in
1786341825Sdim            // order to produce the static variable that the AST thinks it is
1787341825Sdim            // accessing.
1788292932Sdim
1789314564Sdim            llvm::Instruction *entry_instruction = llvm::cast<Instruction>(
1790314564Sdim                m_entry_instruction_finder.GetValue(function));
1791292932Sdim
1792314564Sdim            ConstantInt *offset_int(
1793314564Sdim                ConstantInt::get(offset_type, offset, true));
1794314564Sdim            GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(
1795314564Sdim                nullptr, argument, offset_int, "", entry_instruction);
1796292932Sdim
1797314564Sdim            if (name == m_result_name && !m_result_is_pointer) {
1798314564Sdim              BitCastInst *bit_cast = new BitCastInst(
1799314564Sdim                  get_element_ptr, value->getType()->getPointerTo(), "",
1800314564Sdim                  entry_instruction);
1801292932Sdim
1802314564Sdim              LoadInst *load = new LoadInst(bit_cast, "", entry_instruction);
1803292932Sdim
1804314564Sdim              return load;
1805314564Sdim            } else {
1806314564Sdim              BitCastInst *bit_cast = new BitCastInst(
1807314564Sdim                  get_element_ptr, value->getType(), "", entry_instruction);
1808292932Sdim
1809314564Sdim              return bit_cast;
1810292932Sdim            }
1811314564Sdim          });
1812292932Sdim
1813314564Sdim      if (Constant *constant = dyn_cast<Constant>(value)) {
1814314564Sdim        if (!UnfoldConstant(constant, &llvm_function, body_result_maker,
1815314564Sdim                            m_entry_instruction_finder, m_error_stream)) {
1816314564Sdim          return false;
1817292932Sdim        }
1818314564Sdim      } else if (Instruction *instruction = dyn_cast<Instruction>(value)) {
1819314564Sdim        if (instruction->getParent()->getParent() != &llvm_function) {
1820314564Sdim          m_error_stream.PutCString("error: Capturing non-local variables in "
1821314564Sdim                                    "expressions is unsupported.\n");
1822314564Sdim          return false;
1823314564Sdim        }
1824314564Sdim        value->replaceAllUsesWith(
1825314564Sdim            body_result_maker.GetValue(instruction->getParent()->getParent()));
1826314564Sdim      } else {
1827360784Sdim        LLDB_LOG(log, "Unhandled non-constant type: \"{0}\"",
1828360784Sdim                 PrintValue(value));
1829314564Sdim        return false;
1830314564Sdim      }
1831314564Sdim
1832314564Sdim      if (GlobalVariable *var = dyn_cast<GlobalVariable>(value))
1833314564Sdim        var->eraseFromParent();
1834292932Sdim    }
1835314564Sdim  }
1836292932Sdim
1837360784Sdim  LLDB_LOG(log, "Total structure [align {0}, size {1}]", (int64_t)alignment,
1838360784Sdim           (uint64_t)size);
1839292932Sdim
1840314564Sdim  return true;
1841292932Sdim}
1842292932Sdim
1843314564Sdimbool IRForTarget::runOnModule(Module &llvm_module) {
1844314564Sdim  lldb_private::Log *log(
1845314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1846292932Sdim
1847314564Sdim  m_module = &llvm_module;
1848314564Sdim  m_target_data.reset(new DataLayout(m_module));
1849314564Sdim  m_intptr_ty = llvm::Type::getIntNTy(m_module->getContext(),
1850314564Sdim                                      m_target_data->getPointerSizeInBits());
1851292932Sdim
1852314564Sdim  if (log) {
1853314564Sdim    std::string s;
1854314564Sdim    raw_string_ostream oss(s);
1855292932Sdim
1856353358Sdim    m_module->print(oss, nullptr);
1857292932Sdim
1858314564Sdim    oss.flush();
1859292932Sdim
1860360784Sdim    LLDB_LOG(log, "Module as passed in to IRForTarget: \n\"{0}\"", s);
1861314564Sdim  }
1862292932Sdim
1863314564Sdim  Function *const main_function =
1864314564Sdim      m_func_name.IsEmpty() ? nullptr
1865314564Sdim                            : m_module->getFunction(m_func_name.GetStringRef());
1866292932Sdim
1867314564Sdim  if (!m_func_name.IsEmpty() && !main_function) {
1868360784Sdim    LLDB_LOG(log, "Couldn't find \"{0}()\" in the module", m_func_name);
1869292932Sdim
1870360784Sdim    m_error_stream.Format("Internal error [IRForTarget]: Couldn't find wrapper "
1871360784Sdim                          "'{0}' in the module",
1872360784Sdim                          m_func_name);
1873292932Sdim
1874314564Sdim    return false;
1875314564Sdim  }
1876292932Sdim
1877314564Sdim  if (main_function) {
1878314564Sdim    if (!FixFunctionLinkage(*main_function)) {
1879360784Sdim      LLDB_LOG(log, "Couldn't fix the linkage for the function");
1880292932Sdim
1881314564Sdim      return false;
1882292932Sdim    }
1883314564Sdim  }
1884292932Sdim
1885314564Sdim  llvm::Type *int8_ty = Type::getInt8Ty(m_module->getContext());
1886292932Sdim
1887314564Sdim  m_reloc_placeholder = new llvm::GlobalVariable(
1888314564Sdim      (*m_module), int8_ty, false /* IsConstant */,
1889314564Sdim      GlobalVariable::InternalLinkage, Constant::getNullValue(int8_ty),
1890353358Sdim      "reloc_placeholder", nullptr /* InsertBefore */,
1891314564Sdim      GlobalVariable::NotThreadLocal /* ThreadLocal */, 0 /* AddressSpace */);
1892292932Sdim
1893314564Sdim  ////////////////////////////////////////////////////////////
1894314564Sdim  // Replace $__lldb_expr_result with a persistent variable
1895314564Sdim  //
1896292932Sdim
1897314564Sdim  if (main_function) {
1898314564Sdim    if (!CreateResultVariable(*main_function)) {
1899360784Sdim      LLDB_LOG(log, "CreateResultVariable() failed");
1900292932Sdim
1901314564Sdim      // CreateResultVariable() reports its own errors, so we don't do so here
1902292932Sdim
1903314564Sdim      return false;
1904292932Sdim    }
1905314564Sdim  }
1906292932Sdim
1907314564Sdim  if (log && log->GetVerbose()) {
1908314564Sdim    std::string s;
1909314564Sdim    raw_string_ostream oss(s);
1910292932Sdim
1911353358Sdim    m_module->print(oss, nullptr);
1912292932Sdim
1913314564Sdim    oss.flush();
1914292932Sdim
1915360784Sdim    LLDB_LOG(log, "Module after creating the result variable: \n\"{0}\"", s);
1916314564Sdim  }
1917292932Sdim
1918360784Sdim  for (llvm::Function &function : *m_module) {
1919360784Sdim    for (BasicBlock &bb : function) {
1920360784Sdim      if (!RemoveGuards(bb)) {
1921360784Sdim        LLDB_LOG(log, "RemoveGuards() failed");
1922292932Sdim
1923314564Sdim        // RemoveGuards() reports its own errors, so we don't do so here
1924292932Sdim
1925314564Sdim        return false;
1926314564Sdim      }
1927292932Sdim
1928360784Sdim      if (!RewritePersistentAllocs(bb)) {
1929360784Sdim        LLDB_LOG(log, "RewritePersistentAllocs() failed");
1930292932Sdim
1931314564Sdim        // RewritePersistentAllocs() reports its own errors, so we don't do so
1932314564Sdim        // here
1933292932Sdim
1934314564Sdim        return false;
1935314564Sdim      }
1936292932Sdim
1937360784Sdim      if (!RemoveCXAAtExit(bb)) {
1938360784Sdim        LLDB_LOG(log, "RemoveCXAAtExit() failed");
1939292932Sdim
1940314564Sdim        // RemoveCXAAtExit() reports its own errors, so we don't do so here
1941292932Sdim
1942314564Sdim        return false;
1943314564Sdim      }
1944292932Sdim    }
1945314564Sdim  }
1946292932Sdim
1947314564Sdim  ///////////////////////////////////////////////////////////////////////////////
1948314564Sdim  // Fix all Objective-C constant strings to use NSStringWithCString:encoding:
1949314564Sdim  //
1950292932Sdim
1951314564Sdim  if (!RewriteObjCConstStrings()) {
1952360784Sdim    LLDB_LOG(log, "RewriteObjCConstStrings() failed");
1953314564Sdim
1954314564Sdim    // RewriteObjCConstStrings() reports its own errors, so we don't do so here
1955314564Sdim
1956314564Sdim    return false;
1957314564Sdim  }
1958314564Sdim
1959360784Sdim  for (llvm::Function &function : *m_module) {
1960360784Sdim    for (llvm::BasicBlock &bb : function) {
1961360784Sdim      if (!RewriteObjCSelectors(bb)) {
1962360784Sdim        LLDB_LOG(log, "RewriteObjCSelectors() failed");
1963314564Sdim
1964341825Sdim        // RewriteObjCSelectors() reports its own errors, so we don't do so
1965341825Sdim        // here
1966292932Sdim
1967292932Sdim        return false;
1968314564Sdim      }
1969292932Sdim
1970360784Sdim      if (!RewriteObjCClassReferences(bb)) {
1971360784Sdim        LLDB_LOG(log, "RewriteObjCClassReferences() failed");
1972292932Sdim
1973314564Sdim        // RewriteObjCClasses() reports its own errors, so we don't do so here
1974292932Sdim
1975314564Sdim        return false;
1976314564Sdim      }
1977292932Sdim    }
1978314564Sdim  }
1979292932Sdim
1980360784Sdim  for (llvm::Function &function : *m_module) {
1981360784Sdim    for (BasicBlock &bb : function) {
1982360784Sdim      if (!ResolveCalls(bb)) {
1983360784Sdim        LLDB_LOG(log, "ResolveCalls() failed");
1984292932Sdim
1985314564Sdim        // ResolveCalls() reports its own errors, so we don't do so here
1986292932Sdim
1987314564Sdim        return false;
1988314564Sdim      }
1989292932Sdim    }
1990314564Sdim  }
1991292932Sdim
1992314564Sdim  ////////////////////////////////////////////////////////////////////////
1993314564Sdim  // Run function-level passes that only make sense on the main function
1994314564Sdim  //
1995292932Sdim
1996314564Sdim  if (main_function) {
1997314564Sdim    if (!ResolveExternals(*main_function)) {
1998360784Sdim      LLDB_LOG(log, "ResolveExternals() failed");
1999292932Sdim
2000314564Sdim      // ResolveExternals() reports its own errors, so we don't do so here
2001292932Sdim
2002314564Sdim      return false;
2003314564Sdim    }
2004292932Sdim
2005314564Sdim    if (!ReplaceVariables(*main_function)) {
2006360784Sdim      LLDB_LOG(log, "ReplaceVariables() failed");
2007292932Sdim
2008314564Sdim      // ReplaceVariables() reports its own errors, so we don't do so here
2009292932Sdim
2010314564Sdim      return false;
2011292932Sdim    }
2012314564Sdim  }
2013292932Sdim
2014314564Sdim  if (log && log->GetVerbose()) {
2015314564Sdim    std::string s;
2016314564Sdim    raw_string_ostream oss(s);
2017292932Sdim
2018353358Sdim    m_module->print(oss, nullptr);
2019292932Sdim
2020314564Sdim    oss.flush();
2021292932Sdim
2022360784Sdim    LLDB_LOG(log, "Module after preparing for execution: \n\"{0}\"", s);
2023314564Sdim  }
2024292932Sdim
2025314564Sdim  return true;
2026292932Sdim}
2027292932Sdim
2028314564Sdimvoid IRForTarget::assignPassManager(PMStack &pass_mgr_stack,
2029314564Sdim                                    PassManagerType pass_mgr_type) {}
2030292932Sdim
2031314564SdimPassManagerType IRForTarget::getPotentialPassManagerType() const {
2032314564Sdim  return PMT_ModulePassManager;
2033292932Sdim}
2034