IRForTarget.cpp revision 314564
1292932Sdim//===-- IRForTarget.cpp -----------------------------------------*- C++ -*-===//
2292932Sdim//
3292932Sdim//                     The LLVM Compiler Infrastructure
4292932Sdim//
5292932Sdim// This file is distributed under the University of Illinois Open Source
6292932Sdim// License. See LICENSE.TXT for details.
7292932Sdim//
8292932Sdim//===----------------------------------------------------------------------===//
9292932Sdim
10292932Sdim#include "IRForTarget.h"
11292932Sdim
12292932Sdim#include "ClangExpressionDeclMap.h"
13292932Sdim
14292932Sdim#include "llvm/IR/Constants.h"
15292932Sdim#include "llvm/IR/DataLayout.h"
16292932Sdim#include "llvm/IR/InstrTypes.h"
17292932Sdim#include "llvm/IR/Instructions.h"
18292932Sdim#include "llvm/IR/Intrinsics.h"
19292932Sdim#include "llvm/IR/LegacyPassManager.h"
20292932Sdim#include "llvm/IR/Metadata.h"
21314564Sdim#include "llvm/IR/Module.h"
22292932Sdim#include "llvm/IR/ValueSymbolTable.h"
23314564Sdim#include "llvm/Support/raw_ostream.h"
24314564Sdim#include "llvm/Transforms/IPO.h"
25292932Sdim
26292932Sdim#include "clang/AST/ASTContext.h"
27292932Sdim
28292932Sdim#include "lldb/Core/ConstString.h"
29292932Sdim#include "lldb/Core/DataBufferHeap.h"
30292932Sdim#include "lldb/Core/Log.h"
31292932Sdim#include "lldb/Core/Scalar.h"
32292932Sdim#include "lldb/Core/StreamString.h"
33309124Sdim#include "lldb/Core/dwarf.h"
34292932Sdim#include "lldb/Expression/IRExecutionUnit.h"
35292932Sdim#include "lldb/Expression/IRInterpreter.h"
36292932Sdim#include "lldb/Host/Endian.h"
37292932Sdim#include "lldb/Symbol/ClangASTContext.h"
38309124Sdim#include "lldb/Symbol/ClangUtil.h"
39292932Sdim#include "lldb/Symbol/CompilerType.h"
40292932Sdim
41292932Sdim#include <map>
42292932Sdim
43292932Sdimusing namespace llvm;
44292932Sdim
45292932Sdimstatic char ID;
46292932Sdim
47314564SdimIRForTarget::FunctionValueCache::FunctionValueCache(Maker const &maker)
48314564Sdim    : m_maker(maker), m_values() {}
49292932Sdim
50314564SdimIRForTarget::FunctionValueCache::~FunctionValueCache() {}
51292932Sdim
52292932Sdimllvm::Value *
53314564SdimIRForTarget::FunctionValueCache::GetValue(llvm::Function *function) {
54314564Sdim  if (!m_values.count(function)) {
55314564Sdim    llvm::Value *ret = m_maker(function);
56314564Sdim    m_values[function] = ret;
57314564Sdim    return ret;
58314564Sdim  }
59314564Sdim  return m_values[function];
60292932Sdim}
61292932Sdim
62314564Sdimstatic llvm::Value *FindEntryInstruction(llvm::Function *function) {
63314564Sdim  if (function->empty())
64314564Sdim    return NULL;
65292932Sdim
66314564Sdim  return function->getEntryBlock().getFirstNonPHIOrDbg();
67292932Sdim}
68292932Sdim
69314564SdimIRForTarget::IRForTarget(lldb_private::ClangExpressionDeclMap *decl_map,
70314564Sdim                         bool resolve_vars,
71314564Sdim                         lldb_private::IRExecutionUnit &execution_unit,
72314564Sdim                         lldb_private::Stream &error_stream,
73314564Sdim                         const char *func_name)
74314564Sdim    : ModulePass(ID), m_resolve_vars(resolve_vars), m_func_name(func_name),
75314564Sdim      m_module(NULL), m_decl_map(decl_map), m_CFStringCreateWithBytes(NULL),
76314564Sdim      m_sel_registerName(NULL), m_objc_getClass(NULL), m_intptr_ty(NULL),
77314564Sdim      m_error_stream(error_stream),
78314564Sdim      m_execution_unit(execution_unit), m_result_store(NULL),
79314564Sdim      m_result_is_pointer(false), m_reloc_placeholder(NULL),
80314564Sdim      m_entry_instruction_finder(FindEntryInstruction) {}
81292932Sdim
82292932Sdim/* Handy utility functions used at several places in the code */
83292932Sdim
84314564Sdimstatic std::string PrintValue(const Value *value, bool truncate = false) {
85314564Sdim  std::string s;
86314564Sdim  if (value) {
87292932Sdim    raw_string_ostream rso(s);
88314564Sdim    value->print(rso);
89292932Sdim    rso.flush();
90292932Sdim    if (truncate)
91314564Sdim      s.resize(s.length() - 1);
92314564Sdim  }
93314564Sdim  return s;
94292932Sdim}
95292932Sdim
96314564Sdimstatic std::string PrintType(const llvm::Type *type, bool truncate = false) {
97314564Sdim  std::string s;
98314564Sdim  raw_string_ostream rso(s);
99314564Sdim  type->print(rso);
100314564Sdim  rso.flush();
101314564Sdim  if (truncate)
102314564Sdim    s.resize(s.length() - 1);
103314564Sdim  return s;
104292932Sdim}
105292932Sdim
106314564SdimIRForTarget::~IRForTarget() {}
107292932Sdim
108314564Sdimbool IRForTarget::FixFunctionLinkage(llvm::Function &llvm_function) {
109314564Sdim  llvm_function.setLinkage(GlobalValue::ExternalLinkage);
110314564Sdim
111314564Sdim  return true;
112292932Sdim}
113292932Sdim
114314564Sdimclang::NamedDecl *IRForTarget::DeclForGlobal(const GlobalValue *global_val,
115314564Sdim                                             Module *module) {
116314564Sdim  NamedMDNode *named_metadata =
117314564Sdim      module->getNamedMetadata("clang.global.decl.ptrs");
118292932Sdim
119314564Sdim  if (!named_metadata)
120314564Sdim    return NULL;
121292932Sdim
122314564Sdim  unsigned num_nodes = named_metadata->getNumOperands();
123314564Sdim  unsigned node_index;
124292932Sdim
125314564Sdim  for (node_index = 0; node_index < num_nodes; ++node_index) {
126314564Sdim    llvm::MDNode *metadata_node =
127314564Sdim        dyn_cast<llvm::MDNode>(named_metadata->getOperand(node_index));
128314564Sdim    if (!metadata_node)
129314564Sdim      return NULL;
130292932Sdim
131314564Sdim    if (metadata_node->getNumOperands() != 2)
132314564Sdim      continue;
133292932Sdim
134314564Sdim    if (mdconst::dyn_extract_or_null<GlobalValue>(
135314564Sdim            metadata_node->getOperand(0)) != global_val)
136314564Sdim      continue;
137292932Sdim
138314564Sdim    ConstantInt *constant_int =
139314564Sdim        mdconst::dyn_extract<ConstantInt>(metadata_node->getOperand(1));
140292932Sdim
141314564Sdim    if (!constant_int)
142314564Sdim      return NULL;
143292932Sdim
144314564Sdim    uintptr_t ptr = constant_int->getZExtValue();
145292932Sdim
146314564Sdim    return reinterpret_cast<clang::NamedDecl *>(ptr);
147314564Sdim  }
148292932Sdim
149314564Sdim  return NULL;
150292932Sdim}
151292932Sdim
152314564Sdimclang::NamedDecl *IRForTarget::DeclForGlobal(GlobalValue *global_val) {
153314564Sdim  return DeclForGlobal(global_val, m_module);
154292932Sdim}
155292932Sdim
156314564Sdimbool IRForTarget::CreateResultVariable(llvm::Function &llvm_function) {
157314564Sdim  lldb_private::Log *log(
158314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
159292932Sdim
160314564Sdim  if (!m_resolve_vars)
161314564Sdim    return true;
162292932Sdim
163314564Sdim  // Find the result variable.  If it doesn't exist, we can give up right here.
164292932Sdim
165314564Sdim  ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable();
166292932Sdim
167314564Sdim  std::string result_name_str;
168314564Sdim  const char *result_name = NULL;
169292932Sdim
170314564Sdim  for (ValueSymbolTable::iterator vi = value_symbol_table.begin(),
171314564Sdim                                  ve = value_symbol_table.end();
172314564Sdim       vi != ve; ++vi) {
173314564Sdim    result_name_str = vi->first().str();
174314564Sdim    const char *value_name = result_name_str.c_str();
175292932Sdim
176314564Sdim    if (strstr(value_name, "$__lldb_expr_result_ptr") &&
177314564Sdim        strncmp(value_name, "_ZGV", 4)) {
178314564Sdim      result_name = value_name;
179314564Sdim      m_result_is_pointer = true;
180314564Sdim      break;
181314564Sdim    }
182292932Sdim
183314564Sdim    if (strstr(value_name, "$__lldb_expr_result") &&
184314564Sdim        strncmp(value_name, "_ZGV", 4)) {
185314564Sdim      result_name = value_name;
186314564Sdim      m_result_is_pointer = false;
187314564Sdim      break;
188292932Sdim    }
189314564Sdim  }
190292932Sdim
191314564Sdim  if (!result_name) {
192314564Sdim    if (log)
193314564Sdim      log->PutCString("Couldn't find result variable");
194292932Sdim
195314564Sdim    return true;
196314564Sdim  }
197292932Sdim
198314564Sdim  if (log)
199314564Sdim    log->Printf("Result name: \"%s\"", result_name);
200314564Sdim
201314564Sdim  Value *result_value = m_module->getNamedValue(result_name);
202314564Sdim
203314564Sdim  if (!result_value) {
204292932Sdim    if (log)
205314564Sdim      log->PutCString("Result variable had no data");
206292932Sdim
207314564Sdim    m_error_stream.Printf("Internal error [IRForTarget]: Result variable's "
208314564Sdim                          "name (%s) exists, but not its definition\n",
209314564Sdim                          result_name);
210292932Sdim
211314564Sdim    return false;
212314564Sdim  }
213292932Sdim
214314564Sdim  if (log)
215314564Sdim    log->Printf("Found result in the IR: \"%s\"",
216314564Sdim                PrintValue(result_value, false).c_str());
217292932Sdim
218314564Sdim  GlobalVariable *result_global = dyn_cast<GlobalVariable>(result_value);
219292932Sdim
220314564Sdim  if (!result_global) {
221292932Sdim    if (log)
222314564Sdim      log->PutCString("Result variable isn't a GlobalVariable");
223292932Sdim
224314564Sdim    m_error_stream.Printf("Internal error [IRForTarget]: Result variable (%s) "
225314564Sdim                          "is defined, but is not a global variable\n",
226314564Sdim                          result_name);
227292932Sdim
228314564Sdim    return false;
229314564Sdim  }
230292932Sdim
231314564Sdim  clang::NamedDecl *result_decl = DeclForGlobal(result_global);
232314564Sdim  if (!result_decl) {
233314564Sdim    if (log)
234314564Sdim      log->PutCString("Result variable doesn't have a corresponding Decl");
235292932Sdim
236314564Sdim    m_error_stream.Printf("Internal error [IRForTarget]: Result variable (%s) "
237314564Sdim                          "does not have a corresponding Clang entity\n",
238314564Sdim                          result_name);
239292932Sdim
240314564Sdim    return false;
241314564Sdim  }
242292932Sdim
243314564Sdim  if (log) {
244314564Sdim    std::string decl_desc_str;
245314564Sdim    raw_string_ostream decl_desc_stream(decl_desc_str);
246314564Sdim    result_decl->print(decl_desc_stream);
247314564Sdim    decl_desc_stream.flush();
248292932Sdim
249314564Sdim    log->Printf("Found result decl: \"%s\"", decl_desc_str.c_str());
250314564Sdim  }
251292932Sdim
252314564Sdim  clang::VarDecl *result_var = dyn_cast<clang::VarDecl>(result_decl);
253314564Sdim  if (!result_var) {
254292932Sdim    if (log)
255314564Sdim      log->PutCString("Result variable Decl isn't a VarDecl");
256292932Sdim
257314564Sdim    m_error_stream.Printf("Internal error [IRForTarget]: Result variable "
258314564Sdim                          "(%s)'s corresponding Clang entity isn't a "
259314564Sdim                          "variable\n",
260314564Sdim                          result_name);
261292932Sdim
262314564Sdim    return false;
263314564Sdim  }
264292932Sdim
265314564Sdim  // Get the next available result name from m_decl_map and create the
266314564Sdim  // persistent
267314564Sdim  // variable for it
268292932Sdim
269314564Sdim  // If the result is an Lvalue, it is emitted as a pointer; see
270314564Sdim  // ASTResultSynthesizer::SynthesizeBodyResult.
271314564Sdim  if (m_result_is_pointer) {
272314564Sdim    clang::QualType pointer_qual_type = result_var->getType();
273314564Sdim    const clang::Type *pointer_type = pointer_qual_type.getTypePtr();
274314564Sdim
275314564Sdim    const clang::PointerType *pointer_pointertype =
276314564Sdim        pointer_type->getAs<clang::PointerType>();
277314564Sdim    const clang::ObjCObjectPointerType *pointer_objcobjpointertype =
278314564Sdim        pointer_type->getAs<clang::ObjCObjectPointerType>();
279314564Sdim
280314564Sdim    if (pointer_pointertype) {
281314564Sdim      clang::QualType element_qual_type = pointer_pointertype->getPointeeType();
282314564Sdim
283314564Sdim      m_result_type = lldb_private::TypeFromParser(
284314564Sdim          element_qual_type.getAsOpaquePtr(),
285314564Sdim          lldb_private::ClangASTContext::GetASTContext(
286314564Sdim              &result_decl->getASTContext()));
287314564Sdim    } else if (pointer_objcobjpointertype) {
288314564Sdim      clang::QualType element_qual_type =
289314564Sdim          clang::QualType(pointer_objcobjpointertype->getObjectType(), 0);
290314564Sdim
291314564Sdim      m_result_type = lldb_private::TypeFromParser(
292314564Sdim          element_qual_type.getAsOpaquePtr(),
293314564Sdim          lldb_private::ClangASTContext::GetASTContext(
294314564Sdim              &result_decl->getASTContext()));
295314564Sdim    } else {
296314564Sdim      if (log)
297314564Sdim        log->PutCString("Expected result to have pointer type, but it did not");
298314564Sdim
299314564Sdim      m_error_stream.Printf("Internal error [IRForTarget]: Lvalue result (%s) "
300314564Sdim                            "is not a pointer variable\n",
301314564Sdim                            result_name);
302314564Sdim
303314564Sdim      return false;
304292932Sdim    }
305314564Sdim  } else {
306314564Sdim    m_result_type = lldb_private::TypeFromParser(
307314564Sdim        result_var->getType().getAsOpaquePtr(),
308314564Sdim        lldb_private::ClangASTContext::GetASTContext(
309314564Sdim            &result_decl->getASTContext()));
310314564Sdim  }
311292932Sdim
312314564Sdim  lldb::TargetSP target_sp(m_execution_unit.GetTarget());
313314564Sdim  lldb_private::ExecutionContext exe_ctx(target_sp, true);
314314564Sdim  if (m_result_type.GetBitSize(exe_ctx.GetBestExecutionContextScope()) == 0) {
315314564Sdim    lldb_private::StreamString type_desc_stream;
316314564Sdim    m_result_type.DumpTypeDescription(&type_desc_stream);
317292932Sdim
318314564Sdim    if (log)
319314564Sdim      log->Printf("Result type has size 0");
320292932Sdim
321314564Sdim    m_error_stream.Printf("Error [IRForTarget]: Size of result type '%s' "
322314564Sdim                          "couldn't be determined\n",
323314564Sdim                          type_desc_stream.GetData());
324314564Sdim    return false;
325314564Sdim  }
326292932Sdim
327314564Sdim  if (log) {
328314564Sdim    lldb_private::StreamString type_desc_stream;
329314564Sdim    m_result_type.DumpTypeDescription(&type_desc_stream);
330292932Sdim
331314564Sdim    log->Printf("Result decl type: \"%s\"", type_desc_stream.GetData());
332314564Sdim  }
333292932Sdim
334314564Sdim  m_result_name = lldb_private::ConstString("$RESULT_NAME");
335292932Sdim
336314564Sdim  if (log)
337314564Sdim    log->Printf("Creating a new result global: \"%s\" with size 0x%" PRIx64,
338314564Sdim                m_result_name.GetCString(), m_result_type.GetByteSize(nullptr));
339292932Sdim
340314564Sdim  // Construct a new result global and set up its metadata
341292932Sdim
342314564Sdim  GlobalVariable *new_result_global = new GlobalVariable(
343314564Sdim      (*m_module), result_global->getType()->getElementType(),
344314564Sdim      false,                              /* not constant */
345314564Sdim      GlobalValue::ExternalLinkage, NULL, /* no initializer */
346314564Sdim      m_result_name.GetCString());
347292932Sdim
348314564Sdim  // It's too late in compilation to create a new VarDecl for this, but we don't
349314564Sdim  // need to.  We point the metadata at the old VarDecl.  This creates an odd
350314564Sdim  // anomaly: a variable with a Value whose name is something like $0 and a
351314564Sdim  // Decl whose name is $__lldb_expr_result.  This condition is handled in
352314564Sdim  // ClangExpressionDeclMap::DoMaterialize, and the name of the variable is
353314564Sdim  // fixed up.
354292932Sdim
355314564Sdim  ConstantInt *new_constant_int =
356314564Sdim      ConstantInt::get(llvm::Type::getInt64Ty(m_module->getContext()),
357314564Sdim                       reinterpret_cast<uint64_t>(result_decl), false);
358292932Sdim
359314564Sdim  llvm::Metadata *values[2];
360314564Sdim  values[0] = ConstantAsMetadata::get(new_result_global);
361314564Sdim  values[1] = ConstantAsMetadata::get(new_constant_int);
362292932Sdim
363314564Sdim  ArrayRef<Metadata *> value_ref(values, 2);
364292932Sdim
365314564Sdim  MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
366314564Sdim  NamedMDNode *named_metadata =
367314564Sdim      m_module->getNamedMetadata("clang.global.decl.ptrs");
368314564Sdim  named_metadata->addOperand(persistent_global_md);
369314564Sdim
370314564Sdim  if (log)
371314564Sdim    log->Printf("Replacing \"%s\" with \"%s\"",
372314564Sdim                PrintValue(result_global).c_str(),
373314564Sdim                PrintValue(new_result_global).c_str());
374314564Sdim
375314564Sdim  if (result_global->use_empty()) {
376314564Sdim    // We need to synthesize a store for this variable, because otherwise
377314564Sdim    // there's nothing to put into its equivalent persistent variable.
378314564Sdim
379314564Sdim    BasicBlock &entry_block(llvm_function.getEntryBlock());
380314564Sdim    Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg());
381314564Sdim
382314564Sdim    if (!first_entry_instruction)
383314564Sdim      return false;
384314564Sdim
385314564Sdim    if (!result_global->hasInitializer()) {
386314564Sdim      if (log)
387314564Sdim        log->Printf("Couldn't find initializer for unused variable");
388314564Sdim
389314564Sdim      m_error_stream.Printf("Internal error [IRForTarget]: Result variable "
390314564Sdim                            "(%s) has no writes and no initializer\n",
391314564Sdim                            result_name);
392314564Sdim
393314564Sdim      return false;
394292932Sdim    }
395292932Sdim
396314564Sdim    Constant *initializer = result_global->getInitializer();
397292932Sdim
398314564Sdim    StoreInst *synthesized_store =
399314564Sdim        new StoreInst(initializer, new_result_global, first_entry_instruction);
400314564Sdim
401292932Sdim    if (log)
402314564Sdim      log->Printf("Synthesized result store \"%s\"\n",
403314564Sdim                  PrintValue(synthesized_store).c_str());
404314564Sdim  } else {
405314564Sdim    result_global->replaceAllUsesWith(new_result_global);
406314564Sdim  }
407292932Sdim
408314564Sdim  if (!m_decl_map->AddPersistentVariable(
409314564Sdim          result_decl, m_result_name, m_result_type, true, m_result_is_pointer))
410314564Sdim    return false;
411292932Sdim
412314564Sdim  result_global->eraseFromParent();
413292932Sdim
414314564Sdim  return true;
415314564Sdim}
416292932Sdim
417314564Sdimbool IRForTarget::RewriteObjCConstString(llvm::GlobalVariable *ns_str,
418314564Sdim                                         llvm::GlobalVariable *cstr) {
419314564Sdim  lldb_private::Log *log(
420314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
421292932Sdim
422314564Sdim  Type *ns_str_ty = ns_str->getType();
423292932Sdim
424314564Sdim  Type *i8_ptr_ty = Type::getInt8PtrTy(m_module->getContext());
425314564Sdim  Type *i32_ty = Type::getInt32Ty(m_module->getContext());
426314564Sdim  Type *i8_ty = Type::getInt8Ty(m_module->getContext());
427292932Sdim
428314564Sdim  if (!m_CFStringCreateWithBytes) {
429314564Sdim    lldb::addr_t CFStringCreateWithBytes_addr;
430292932Sdim
431314564Sdim    static lldb_private::ConstString g_CFStringCreateWithBytes_str(
432314564Sdim        "CFStringCreateWithBytes");
433314564Sdim
434314564Sdim    CFStringCreateWithBytes_addr =
435314564Sdim        m_execution_unit.FindSymbol(g_CFStringCreateWithBytes_str);
436314564Sdim    if (CFStringCreateWithBytes_addr == LLDB_INVALID_ADDRESS) {
437314564Sdim      if (log)
438314564Sdim        log->PutCString("Couldn't find CFStringCreateWithBytes in the target");
439314564Sdim
440314564Sdim      m_error_stream.Printf("Error [IRForTarget]: Rewriting an Objective-C "
441314564Sdim                            "constant string requires "
442314564Sdim                            "CFStringCreateWithBytes\n");
443314564Sdim
444314564Sdim      return false;
445314564Sdim    }
446314564Sdim
447292932Sdim    if (log)
448314564Sdim      log->Printf("Found CFStringCreateWithBytes at 0x%" PRIx64,
449314564Sdim                  CFStringCreateWithBytes_addr);
450292932Sdim
451314564Sdim    // Build the function type:
452314564Sdim    //
453314564Sdim    // CFStringRef CFStringCreateWithBytes (
454314564Sdim    //   CFAllocatorRef alloc,
455314564Sdim    //   const UInt8 *bytes,
456314564Sdim    //   CFIndex numBytes,
457314564Sdim    //   CFStringEncoding encoding,
458314564Sdim    //   Boolean isExternalRepresentation
459314564Sdim    // );
460314564Sdim    //
461314564Sdim    // We make the following substitutions:
462314564Sdim    //
463314564Sdim    // CFStringRef -> i8*
464314564Sdim    // CFAllocatorRef -> i8*
465314564Sdim    // UInt8 * -> i8*
466314564Sdim    // CFIndex -> long (i32 or i64, as appropriate; we ask the module for its
467314564Sdim    // pointer size for now)
468314564Sdim    // CFStringEncoding -> i32
469314564Sdim    // Boolean -> i8
470292932Sdim
471314564Sdim    Type *arg_type_array[5];
472292932Sdim
473314564Sdim    arg_type_array[0] = i8_ptr_ty;
474314564Sdim    arg_type_array[1] = i8_ptr_ty;
475314564Sdim    arg_type_array[2] = m_intptr_ty;
476314564Sdim    arg_type_array[3] = i32_ty;
477314564Sdim    arg_type_array[4] = i8_ty;
478292932Sdim
479314564Sdim    ArrayRef<Type *> CFSCWB_arg_types(arg_type_array, 5);
480292932Sdim
481314564Sdim    llvm::Type *CFSCWB_ty =
482314564Sdim        FunctionType::get(ns_str_ty, CFSCWB_arg_types, false);
483292932Sdim
484314564Sdim    // Build the constant containing the pointer to the function
485314564Sdim    PointerType *CFSCWB_ptr_ty = PointerType::getUnqual(CFSCWB_ty);
486314564Sdim    Constant *CFSCWB_addr_int =
487314564Sdim        ConstantInt::get(m_intptr_ty, CFStringCreateWithBytes_addr, false);
488314564Sdim    m_CFStringCreateWithBytes =
489314564Sdim        ConstantExpr::getIntToPtr(CFSCWB_addr_int, CFSCWB_ptr_ty);
490314564Sdim  }
491292932Sdim
492314564Sdim  ConstantDataSequential *string_array = NULL;
493292932Sdim
494314564Sdim  if (cstr)
495314564Sdim    string_array = dyn_cast<ConstantDataSequential>(cstr->getInitializer());
496292932Sdim
497314564Sdim  Constant *alloc_arg = Constant::getNullValue(i8_ptr_ty);
498314564Sdim  Constant *bytes_arg = cstr ? ConstantExpr::getBitCast(cstr, i8_ptr_ty)
499314564Sdim                             : Constant::getNullValue(i8_ptr_ty);
500314564Sdim  Constant *numBytes_arg = ConstantInt::get(
501314564Sdim      m_intptr_ty, cstr ? (string_array->getNumElements() - 1) * string_array->getElementByteSize() : 0, false);
502314564Sdim int encoding_flags = 0;
503314564Sdim switch (cstr ? string_array->getElementByteSize() : 1) {
504314564Sdim case 1:
505314564Sdim   encoding_flags = 0x08000100; /* 0x08000100 is kCFStringEncodingUTF8 */
506314564Sdim   break;
507314564Sdim case 2:
508314564Sdim   encoding_flags = 0x0100; /* 0x0100 is kCFStringEncodingUTF16 */
509314564Sdim   break;
510314564Sdim case 4:
511314564Sdim   encoding_flags = 0x0c000100; /* 0x0c000100 is kCFStringEncodingUTF32 */
512314564Sdim   break;
513314564Sdim default:
514314564Sdim   encoding_flags = 0x0600; /* fall back to 0x0600, kCFStringEncodingASCII */
515314564Sdim   if (log) {
516314564Sdim     log->Format("Encountered an Objective-C constant string with unusual "
517314564Sdim                 "element size {0}",
518314564Sdim                 string_array->getElementByteSize());
519314564Sdim   }
520314564Sdim }
521314564Sdim Constant *encoding_arg = ConstantInt::get(i32_ty, encoding_flags, false);
522314564Sdim Constant *isExternal_arg =
523314564Sdim     ConstantInt::get(i8_ty, 0x0, false); /* 0x0 is false */
524314564Sdim
525314564Sdim Value *argument_array[5];
526314564Sdim
527314564Sdim argument_array[0] = alloc_arg;
528314564Sdim argument_array[1] = bytes_arg;
529314564Sdim argument_array[2] = numBytes_arg;
530314564Sdim argument_array[3] = encoding_arg;
531314564Sdim argument_array[4] = isExternal_arg;
532314564Sdim
533314564Sdim ArrayRef<Value *> CFSCWB_arguments(argument_array, 5);
534314564Sdim
535314564Sdim FunctionValueCache CFSCWB_Caller(
536314564Sdim     [this, &CFSCWB_arguments](llvm::Function *function) -> llvm::Value * {
537314564Sdim       return CallInst::Create(
538314564Sdim           m_CFStringCreateWithBytes, CFSCWB_arguments,
539314564Sdim           "CFStringCreateWithBytes",
540314564Sdim           llvm::cast<Instruction>(
541314564Sdim               m_entry_instruction_finder.GetValue(function)));
542314564Sdim     });
543314564Sdim
544314564Sdim if (!UnfoldConstant(ns_str, nullptr, CFSCWB_Caller, m_entry_instruction_finder,
545314564Sdim                     m_error_stream)) {
546314564Sdim   if (log)
547314564Sdim     log->PutCString(
548314564Sdim         "Couldn't replace the NSString with the result of the call");
549314564Sdim
550314564Sdim   m_error_stream.Printf("error [IRForTarget internal]: Couldn't replace an "
551314564Sdim                         "Objective-C constant string with a dynamic "
552314564Sdim                         "string\n");
553314564Sdim
554314564Sdim   return false;
555314564Sdim  }
556314564Sdim
557314564Sdim  ns_str->eraseFromParent();
558314564Sdim
559314564Sdim  return true;
560314564Sdim}
561314564Sdim
562314564Sdimbool IRForTarget::RewriteObjCConstStrings() {
563314564Sdim  lldb_private::Log *log(
564314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
565314564Sdim
566314564Sdim  ValueSymbolTable &value_symbol_table = m_module->getValueSymbolTable();
567314564Sdim
568314564Sdim  for (ValueSymbolTable::iterator vi = value_symbol_table.begin(),
569314564Sdim                                  ve = value_symbol_table.end();
570314564Sdim       vi != ve; ++vi) {
571314564Sdim    std::string value_name = vi->first().str();
572314564Sdim    const char *value_name_cstr = value_name.c_str();
573314564Sdim
574314564Sdim    if (strstr(value_name_cstr, "_unnamed_cfstring_")) {
575314564Sdim      Value *nsstring_value = vi->second;
576314564Sdim
577314564Sdim      GlobalVariable *nsstring_global =
578314564Sdim          dyn_cast<GlobalVariable>(nsstring_value);
579314564Sdim
580314564Sdim      if (!nsstring_global) {
581292932Sdim        if (log)
582314564Sdim          log->PutCString("NSString variable is not a GlobalVariable");
583292932Sdim
584314564Sdim        m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
585314564Sdim                              "constant string is not a global variable\n");
586314564Sdim
587292932Sdim        return false;
588314564Sdim      }
589292932Sdim
590314564Sdim      if (!nsstring_global->hasInitializer()) {
591314564Sdim        if (log)
592314564Sdim          log->PutCString("NSString variable does not have an initializer");
593292932Sdim
594314564Sdim        m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
595314564Sdim                              "constant string does not have an initializer\n");
596292932Sdim
597314564Sdim        return false;
598314564Sdim      }
599292932Sdim
600314564Sdim      ConstantStruct *nsstring_struct =
601314564Sdim          dyn_cast<ConstantStruct>(nsstring_global->getInitializer());
602292932Sdim
603314564Sdim      if (!nsstring_struct) {
604314564Sdim        if (log)
605314564Sdim          log->PutCString(
606314564Sdim              "NSString variable's initializer is not a ConstantStruct");
607292932Sdim
608314564Sdim        m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
609314564Sdim                              "constant string is not a structure constant\n");
610292932Sdim
611314564Sdim        return false;
612314564Sdim      }
613292932Sdim
614314564Sdim      // We expect the following structure:
615314564Sdim      //
616314564Sdim      // struct {
617314564Sdim      //   int *isa;
618314564Sdim      //   int flags;
619314564Sdim      //   char *str;
620314564Sdim      //   long length;
621314564Sdim      // };
622292932Sdim
623314564Sdim      if (nsstring_struct->getNumOperands() != 4) {
624314564Sdim        if (log)
625314564Sdim          log->Printf("NSString variable's initializer structure has an "
626314564Sdim                      "unexpected number of members.  Should be 4, is %d",
627314564Sdim                      nsstring_struct->getNumOperands());
628292932Sdim
629314564Sdim        m_error_stream.Printf("Internal error [IRForTarget]: The struct for an "
630314564Sdim                              "Objective-C constant string is not as "
631314564Sdim                              "expected\n");
632292932Sdim
633314564Sdim        return false;
634314564Sdim      }
635314564Sdim
636314564Sdim      Constant *nsstring_member = nsstring_struct->getOperand(2);
637314564Sdim
638314564Sdim      if (!nsstring_member) {
639292932Sdim        if (log)
640314564Sdim          log->PutCString("NSString initializer's str element was empty");
641292932Sdim
642314564Sdim        m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
643314564Sdim                              "constant string does not have a string "
644314564Sdim                              "initializer\n");
645292932Sdim
646314564Sdim        return false;
647314564Sdim      }
648292932Sdim
649314564Sdim      ConstantExpr *nsstring_expr = dyn_cast<ConstantExpr>(nsstring_member);
650292932Sdim
651314564Sdim      if (!nsstring_expr) {
652314564Sdim        if (log)
653314564Sdim          log->PutCString(
654314564Sdim              "NSString initializer's str element is not a ConstantExpr");
655292932Sdim
656314564Sdim        m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
657314564Sdim                              "constant string's string initializer is not "
658314564Sdim                              "constant\n");
659292932Sdim
660314564Sdim        return false;
661314564Sdim      }
662292932Sdim
663314564Sdim      GlobalVariable *cstr_global = nullptr;
664292932Sdim
665314564Sdim      if (nsstring_expr->getOpcode() == Instruction::GetElementPtr) {
666314564Sdim        Constant *nsstring_cstr = nsstring_expr->getOperand(0);
667314564Sdim        cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr);
668314564Sdim      } else if (nsstring_expr->getOpcode() == Instruction::BitCast) {
669314564Sdim        Constant *nsstring_cstr = nsstring_expr->getOperand(0);
670314564Sdim        cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr);
671314564Sdim      }
672292932Sdim
673314564Sdim      if (!cstr_global) {
674314564Sdim        if (log)
675314564Sdim          log->PutCString(
676314564Sdim              "NSString initializer's str element is not a GlobalVariable");
677292932Sdim
678314564Sdim        m_error_stream.Printf("Internal error [IRForTarget]: Unhandled"
679314564Sdim                              "constant string initializer\n");
680292932Sdim
681314564Sdim        return false;
682314564Sdim      }
683292932Sdim
684314564Sdim      if (!cstr_global->hasInitializer()) {
685314564Sdim        if (log)
686314564Sdim          log->PutCString("NSString initializer's str element does not have an "
687314564Sdim                          "initializer");
688292932Sdim
689314564Sdim        m_error_stream.Printf("Internal error [IRForTarget]: An Objective-C "
690314564Sdim                              "constant string's string initializer doesn't "
691314564Sdim                              "point to initialized data\n");
692292932Sdim
693314564Sdim        return false;
694314564Sdim      }
695314564Sdim
696314564Sdim      /*
697314564Sdim      if (!cstr_array)
698314564Sdim      {
699314564Sdim          if (log)
700314564Sdim              log->PutCString("NSString initializer's str element is not a
701314564Sdim      ConstantArray");
702314564Sdim
703314564Sdim          if (m_error_stream)
704314564Sdim              m_error_stream.Printf("Internal error [IRForTarget]: An
705314564Sdim      Objective-C constant string's string initializer doesn't point to an
706314564Sdim      array\n");
707314564Sdim
708314564Sdim          return false;
709314564Sdim      }
710314564Sdim
711314564Sdim      if (!cstr_array->isCString())
712314564Sdim      {
713314564Sdim          if (log)
714314564Sdim              log->PutCString("NSString initializer's str element is not a C
715314564Sdim      string array");
716314564Sdim
717314564Sdim          if (m_error_stream)
718314564Sdim              m_error_stream.Printf("Internal error [IRForTarget]: An
719314564Sdim      Objective-C constant string's string initializer doesn't point to a C
720314564Sdim      string\n");
721314564Sdim
722314564Sdim          return false;
723314564Sdim      }
724314564Sdim      */
725314564Sdim
726314564Sdim      ConstantDataArray *cstr_array =
727314564Sdim          dyn_cast<ConstantDataArray>(cstr_global->getInitializer());
728314564Sdim
729314564Sdim      if (log) {
730314564Sdim        if (cstr_array)
731314564Sdim          log->Printf("Found NSString constant %s, which contains \"%s\"",
732314564Sdim                      value_name_cstr, cstr_array->getAsString().str().c_str());
733314564Sdim        else
734314564Sdim          log->Printf("Found NSString constant %s, which contains \"\"",
735314564Sdim                      value_name_cstr);
736314564Sdim      }
737314564Sdim
738314564Sdim      if (!cstr_array)
739314564Sdim        cstr_global = NULL;
740314564Sdim
741314564Sdim      if (!RewriteObjCConstString(nsstring_global, cstr_global)) {
742292932Sdim        if (log)
743314564Sdim          log->PutCString("Error rewriting the constant string");
744292932Sdim
745314564Sdim        // We don't print an error message here because RewriteObjCConstString
746314564Sdim        // has done so for us.
747292932Sdim
748292932Sdim        return false;
749314564Sdim      }
750292932Sdim    }
751314564Sdim  }
752292932Sdim
753314564Sdim  for (ValueSymbolTable::iterator vi = value_symbol_table.begin(),
754314564Sdim                                  ve = value_symbol_table.end();
755314564Sdim       vi != ve; ++vi) {
756314564Sdim    std::string value_name = vi->first().str();
757314564Sdim    const char *value_name_cstr = value_name.c_str();
758292932Sdim
759314564Sdim    if (!strcmp(value_name_cstr, "__CFConstantStringClassReference")) {
760314564Sdim      GlobalVariable *gv = dyn_cast<GlobalVariable>(vi->second);
761292932Sdim
762314564Sdim      if (!gv) {
763314564Sdim        if (log)
764314564Sdim          log->PutCString(
765314564Sdim              "__CFConstantStringClassReference is not a global variable");
766292932Sdim
767314564Sdim        m_error_stream.Printf("Internal error [IRForTarget]: Found a "
768314564Sdim                              "CFConstantStringClassReference, but it is not a "
769314564Sdim                              "global object\n");
770292932Sdim
771314564Sdim        return false;
772314564Sdim      }
773292932Sdim
774314564Sdim      gv->eraseFromParent();
775292932Sdim
776314564Sdim      break;
777314564Sdim    }
778314564Sdim  }
779292932Sdim
780314564Sdim  return true;
781314564Sdim}
782292932Sdim
783314564Sdimstatic bool IsObjCSelectorRef(Value *value) {
784314564Sdim  GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);
785292932Sdim
786314564Sdim  if (!global_variable || !global_variable->hasName() ||
787314564Sdim      !global_variable->getName().startswith("OBJC_SELECTOR_REFERENCES_"))
788314564Sdim    return false;
789292932Sdim
790314564Sdim  return true;
791314564Sdim}
792292932Sdim
793314564Sdim// This function does not report errors; its callers are responsible.
794314564Sdimbool IRForTarget::RewriteObjCSelector(Instruction *selector_load) {
795314564Sdim  lldb_private::Log *log(
796314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
797292932Sdim
798314564Sdim  LoadInst *load = dyn_cast<LoadInst>(selector_load);
799292932Sdim
800314564Sdim  if (!load)
801314564Sdim    return false;
802292932Sdim
803314564Sdim  // Unpack the message name from the selector.  In LLVM IR, an objc_msgSend
804314564Sdim  // gets represented as
805314564Sdim  //
806314564Sdim  // %tmp     = load i8** @"OBJC_SELECTOR_REFERENCES_" ; <i8*>
807314564Sdim  // %call    = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %obj, i8* %tmp, ...)
808314564Sdim  // ; <i8*>
809314564Sdim  //
810314564Sdim  // where %obj is the object pointer and %tmp is the selector.
811314564Sdim  //
812314564Sdim  // @"OBJC_SELECTOR_REFERENCES_" is a pointer to a character array called
813314564Sdim  // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_".
814314564Sdim  // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_" contains the string.
815292932Sdim
816314564Sdim  // Find the pointer's initializer (a ConstantExpr with opcode GetElementPtr)
817314564Sdim  // and get the string from its target
818292932Sdim
819314564Sdim  GlobalVariable *_objc_selector_references_ =
820314564Sdim      dyn_cast<GlobalVariable>(load->getPointerOperand());
821292932Sdim
822314564Sdim  if (!_objc_selector_references_ ||
823314564Sdim      !_objc_selector_references_->hasInitializer())
824314564Sdim    return false;
825292932Sdim
826314564Sdim  Constant *osr_initializer = _objc_selector_references_->getInitializer();
827292932Sdim
828314564Sdim  ConstantExpr *osr_initializer_expr = dyn_cast<ConstantExpr>(osr_initializer);
829292932Sdim
830314564Sdim  if (!osr_initializer_expr ||
831314564Sdim      osr_initializer_expr->getOpcode() != Instruction::GetElementPtr)
832314564Sdim    return false;
833292932Sdim
834314564Sdim  Value *osr_initializer_base = osr_initializer_expr->getOperand(0);
835292932Sdim
836314564Sdim  if (!osr_initializer_base)
837314564Sdim    return false;
838292932Sdim
839314564Sdim  // Find the string's initializer (a ConstantArray) and get the string from it
840292932Sdim
841314564Sdim  GlobalVariable *_objc_meth_var_name_ =
842314564Sdim      dyn_cast<GlobalVariable>(osr_initializer_base);
843292932Sdim
844314564Sdim  if (!_objc_meth_var_name_ || !_objc_meth_var_name_->hasInitializer())
845314564Sdim    return false;
846292932Sdim
847314564Sdim  Constant *omvn_initializer = _objc_meth_var_name_->getInitializer();
848292932Sdim
849314564Sdim  ConstantDataArray *omvn_initializer_array =
850314564Sdim      dyn_cast<ConstantDataArray>(omvn_initializer);
851292932Sdim
852314564Sdim  if (!omvn_initializer_array->isString())
853314564Sdim    return false;
854292932Sdim
855314564Sdim  std::string omvn_initializer_string = omvn_initializer_array->getAsString();
856292932Sdim
857314564Sdim  if (log)
858314564Sdim    log->Printf("Found Objective-C selector reference \"%s\"",
859314564Sdim                omvn_initializer_string.c_str());
860292932Sdim
861314564Sdim  // Construct a call to sel_registerName
862292932Sdim
863314564Sdim  if (!m_sel_registerName) {
864314564Sdim    lldb::addr_t sel_registerName_addr;
865292932Sdim
866314564Sdim    static lldb_private::ConstString g_sel_registerName_str("sel_registerName");
867314564Sdim    sel_registerName_addr = m_execution_unit.FindSymbol(g_sel_registerName_str);
868314564Sdim    if (sel_registerName_addr == LLDB_INVALID_ADDRESS)
869314564Sdim      return false;
870292932Sdim
871314564Sdim    if (log)
872314564Sdim      log->Printf("Found sel_registerName at 0x%" PRIx64,
873314564Sdim                  sel_registerName_addr);
874292932Sdim
875314564Sdim    // Build the function type: struct objc_selector *sel_registerName(uint8_t*)
876292932Sdim
877314564Sdim    // The below code would be "more correct," but in actuality what's required
878314564Sdim    // is uint8_t*
879314564Sdim    // Type *sel_type = StructType::get(m_module->getContext());
880314564Sdim    // Type *sel_ptr_type = PointerType::getUnqual(sel_type);
881314564Sdim    Type *sel_ptr_type = Type::getInt8PtrTy(m_module->getContext());
882292932Sdim
883314564Sdim    Type *type_array[1];
884292932Sdim
885314564Sdim    type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext());
886292932Sdim
887314564Sdim    ArrayRef<Type *> srN_arg_types(type_array, 1);
888292932Sdim
889314564Sdim    llvm::Type *srN_type =
890314564Sdim        FunctionType::get(sel_ptr_type, srN_arg_types, false);
891292932Sdim
892314564Sdim    // Build the constant containing the pointer to the function
893314564Sdim    PointerType *srN_ptr_ty = PointerType::getUnqual(srN_type);
894314564Sdim    Constant *srN_addr_int =
895314564Sdim        ConstantInt::get(m_intptr_ty, sel_registerName_addr, false);
896314564Sdim    m_sel_registerName = ConstantExpr::getIntToPtr(srN_addr_int, srN_ptr_ty);
897314564Sdim  }
898292932Sdim
899314564Sdim  Value *argument_array[1];
900292932Sdim
901314564Sdim  Constant *omvn_pointer = ConstantExpr::getBitCast(
902314564Sdim      _objc_meth_var_name_, Type::getInt8PtrTy(m_module->getContext()));
903292932Sdim
904314564Sdim  argument_array[0] = omvn_pointer;
905292932Sdim
906314564Sdim  ArrayRef<Value *> srN_arguments(argument_array, 1);
907292932Sdim
908314564Sdim  CallInst *srN_call = CallInst::Create(m_sel_registerName, srN_arguments,
909314564Sdim                                        "sel_registerName", selector_load);
910292932Sdim
911314564Sdim  // Replace the load with the call in all users
912292932Sdim
913314564Sdim  selector_load->replaceAllUsesWith(srN_call);
914292932Sdim
915314564Sdim  selector_load->eraseFromParent();
916292932Sdim
917314564Sdim  return true;
918314564Sdim}
919292932Sdim
920314564Sdimbool IRForTarget::RewriteObjCSelectors(BasicBlock &basic_block) {
921314564Sdim  lldb_private::Log *log(
922314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
923292932Sdim
924314564Sdim  BasicBlock::iterator ii;
925292932Sdim
926314564Sdim  typedef SmallVector<Instruction *, 2> InstrList;
927314564Sdim  typedef InstrList::iterator InstrIterator;
928292932Sdim
929314564Sdim  InstrList selector_loads;
930292932Sdim
931314564Sdim  for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
932314564Sdim    Instruction &inst = *ii;
933292932Sdim
934314564Sdim    if (LoadInst *load = dyn_cast<LoadInst>(&inst))
935314564Sdim      if (IsObjCSelectorRef(load->getPointerOperand()))
936314564Sdim        selector_loads.push_back(&inst);
937314564Sdim  }
938292932Sdim
939314564Sdim  InstrIterator iter;
940292932Sdim
941314564Sdim  for (iter = selector_loads.begin(); iter != selector_loads.end(); ++iter) {
942314564Sdim    if (!RewriteObjCSelector(*iter)) {
943314564Sdim      m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a "
944314564Sdim                            "static reference to an Objective-C selector to a "
945314564Sdim                            "dynamic reference\n");
946314564Sdim
947314564Sdim      if (log)
948314564Sdim        log->PutCString(
949314564Sdim            "Couldn't rewrite a reference to an Objective-C selector");
950314564Sdim
951314564Sdim      return false;
952292932Sdim    }
953314564Sdim  }
954292932Sdim
955314564Sdim  return true;
956292932Sdim}
957292932Sdim
958314564Sdimstatic bool IsObjCClassReference(Value *value) {
959314564Sdim  GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);
960292932Sdim
961314564Sdim  if (!global_variable || !global_variable->hasName() ||
962314564Sdim      !global_variable->getName().startswith("OBJC_CLASS_REFERENCES_"))
963314564Sdim    return false;
964292932Sdim
965314564Sdim  return true;
966292932Sdim}
967292932Sdim
968292932Sdim// This function does not report errors; its callers are responsible.
969314564Sdimbool IRForTarget::RewriteObjCClassReference(Instruction *class_load) {
970314564Sdim  lldb_private::Log *log(
971314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
972292932Sdim
973314564Sdim  LoadInst *load = dyn_cast<LoadInst>(class_load);
974292932Sdim
975314564Sdim  if (!load)
976314564Sdim    return false;
977292932Sdim
978314564Sdim  // Unpack the class name from the reference.  In LLVM IR, a reference to an
979314564Sdim  // Objective-C class gets represented as
980314564Sdim  //
981314564Sdim  // %tmp     = load %struct._objc_class*,
982314564Sdim  //            %struct._objc_class** @OBJC_CLASS_REFERENCES_, align 4
983314564Sdim  //
984314564Sdim  // @"OBJC_CLASS_REFERENCES_ is a bitcast of a character array called
985314564Sdim  // @OBJC_CLASS_NAME_.
986314564Sdim  // @OBJC_CLASS_NAME contains the string.
987292932Sdim
988314564Sdim  // Find the pointer's initializer (a ConstantExpr with opcode BitCast)
989314564Sdim  // and get the string from its target
990292932Sdim
991314564Sdim  GlobalVariable *_objc_class_references_ =
992314564Sdim      dyn_cast<GlobalVariable>(load->getPointerOperand());
993292932Sdim
994314564Sdim  if (!_objc_class_references_ ||
995314564Sdim      !_objc_class_references_->hasInitializer())
996314564Sdim    return false;
997292932Sdim
998314564Sdim  Constant *ocr_initializer = _objc_class_references_->getInitializer();
999292932Sdim
1000314564Sdim  ConstantExpr *ocr_initializer_expr = dyn_cast<ConstantExpr>(ocr_initializer);
1001292932Sdim
1002314564Sdim  if (!ocr_initializer_expr ||
1003314564Sdim      ocr_initializer_expr->getOpcode() != Instruction::BitCast)
1004314564Sdim    return false;
1005292932Sdim
1006314564Sdim  Value *ocr_initializer_base = ocr_initializer_expr->getOperand(0);
1007292932Sdim
1008314564Sdim  if (!ocr_initializer_base)
1009314564Sdim    return false;
1010292932Sdim
1011314564Sdim  // Find the string's initializer (a ConstantArray) and get the string from it
1012292932Sdim
1013314564Sdim  GlobalVariable *_objc_class_name_ =
1014314564Sdim      dyn_cast<GlobalVariable>(ocr_initializer_base);
1015292932Sdim
1016314564Sdim  if (!_objc_class_name_ || !_objc_class_name_->hasInitializer())
1017314564Sdim    return false;
1018292932Sdim
1019314564Sdim  Constant *ocn_initializer = _objc_class_name_->getInitializer();
1020292932Sdim
1021314564Sdim  ConstantDataArray *ocn_initializer_array =
1022314564Sdim      dyn_cast<ConstantDataArray>(ocn_initializer);
1023292932Sdim
1024314564Sdim  if (!ocn_initializer_array->isString())
1025314564Sdim    return false;
1026292932Sdim
1027314564Sdim  std::string ocn_initializer_string = ocn_initializer_array->getAsString();
1028292932Sdim
1029314564Sdim  if (log)
1030314564Sdim    log->Printf("Found Objective-C class reference \"%s\"",
1031314564Sdim                ocn_initializer_string.c_str());
1032292932Sdim
1033314564Sdim  // Construct a call to objc_getClass
1034292932Sdim
1035314564Sdim  if (!m_objc_getClass) {
1036314564Sdim    lldb::addr_t objc_getClass_addr;
1037292932Sdim
1038314564Sdim    static lldb_private::ConstString g_objc_getClass_str("objc_getClass");
1039314564Sdim    objc_getClass_addr = m_execution_unit.FindSymbol(g_objc_getClass_str);
1040314564Sdim    if (objc_getClass_addr == LLDB_INVALID_ADDRESS)
1041314564Sdim      return false;
1042292932Sdim
1043314564Sdim    if (log)
1044314564Sdim      log->Printf("Found objc_getClass at 0x%" PRIx64,
1045314564Sdim                  objc_getClass_addr);
1046292932Sdim
1047314564Sdim    // Build the function type: %struct._objc_class *objc_getClass(i8*)
1048292932Sdim
1049314564Sdim    Type *class_type = load->getType();
1050314564Sdim    Type *type_array[1];
1051314564Sdim    type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext());
1052292932Sdim
1053314564Sdim    ArrayRef<Type *> ogC_arg_types(type_array, 1);
1054292932Sdim
1055314564Sdim    llvm::Type *ogC_type =
1056314564Sdim        FunctionType::get(class_type, ogC_arg_types, false);
1057292932Sdim
1058314564Sdim    // Build the constant containing the pointer to the function
1059314564Sdim    PointerType *ogC_ptr_ty = PointerType::getUnqual(ogC_type);
1060314564Sdim    Constant *ogC_addr_int =
1061314564Sdim        ConstantInt::get(m_intptr_ty, objc_getClass_addr, false);
1062314564Sdim    m_objc_getClass = ConstantExpr::getIntToPtr(ogC_addr_int, ogC_ptr_ty);
1063314564Sdim  }
1064292932Sdim
1065314564Sdim  Value *argument_array[1];
1066292932Sdim
1067314564Sdim  Constant *ocn_pointer = ConstantExpr::getBitCast(
1068314564Sdim      _objc_class_name_, Type::getInt8PtrTy(m_module->getContext()));
1069292932Sdim
1070314564Sdim  argument_array[0] = ocn_pointer;
1071292932Sdim
1072314564Sdim  ArrayRef<Value *> ogC_arguments(argument_array, 1);
1073292932Sdim
1074314564Sdim  CallInst *ogC_call = CallInst::Create(m_objc_getClass, ogC_arguments,
1075314564Sdim                                        "objc_getClass", class_load);
1076292932Sdim
1077314564Sdim  // Replace the load with the call in all users
1078292932Sdim
1079314564Sdim  class_load->replaceAllUsesWith(ogC_call);
1080292932Sdim
1081314564Sdim  class_load->eraseFromParent();
1082292932Sdim
1083314564Sdim  return true;
1084292932Sdim}
1085292932Sdim
1086314564Sdimbool IRForTarget::RewriteObjCClassReferences(BasicBlock &basic_block) {
1087314564Sdim  lldb_private::Log *log(
1088314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1089292932Sdim
1090314564Sdim  BasicBlock::iterator ii;
1091292932Sdim
1092314564Sdim  typedef SmallVector<Instruction *, 2> InstrList;
1093314564Sdim  typedef InstrList::iterator InstrIterator;
1094292932Sdim
1095314564Sdim  InstrList class_loads;
1096292932Sdim
1097314564Sdim  for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
1098314564Sdim    Instruction &inst = *ii;
1099292932Sdim
1100314564Sdim    if (LoadInst *load = dyn_cast<LoadInst>(&inst))
1101314564Sdim      if (IsObjCClassReference(load->getPointerOperand()))
1102314564Sdim        class_loads.push_back(&inst);
1103314564Sdim  }
1104292932Sdim
1105314564Sdim  InstrIterator iter;
1106292932Sdim
1107314564Sdim  for (iter = class_loads.begin(); iter != class_loads.end(); ++iter) {
1108314564Sdim    if (!RewriteObjCClassReference(*iter)) {
1109314564Sdim      m_error_stream.Printf("Internal error [IRForTarget]: Couldn't change a "
1110314564Sdim                            "static reference to an Objective-C class to a "
1111314564Sdim                            "dynamic reference\n");
1112292932Sdim
1113314564Sdim      if (log)
1114314564Sdim        log->PutCString(
1115314564Sdim            "Couldn't rewrite a reference to an Objective-C class");
1116292932Sdim
1117314564Sdim      return false;
1118292932Sdim    }
1119314564Sdim  }
1120292932Sdim
1121314564Sdim  return true;
1122292932Sdim}
1123292932Sdim
1124292932Sdim// This function does not report errors; its callers are responsible.
1125314564Sdimbool IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc) {
1126314564Sdim  lldb_private::Log *log(
1127314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1128292932Sdim
1129314564Sdim  AllocaInst *alloc = dyn_cast<AllocaInst>(persistent_alloc);
1130292932Sdim
1131314564Sdim  MDNode *alloc_md = alloc->getMetadata("clang.decl.ptr");
1132292932Sdim
1133314564Sdim  if (!alloc_md || !alloc_md->getNumOperands())
1134314564Sdim    return false;
1135292932Sdim
1136314564Sdim  ConstantInt *constant_int =
1137314564Sdim      mdconst::dyn_extract<ConstantInt>(alloc_md->getOperand(0));
1138292932Sdim
1139314564Sdim  if (!constant_int)
1140314564Sdim    return false;
1141292932Sdim
1142314564Sdim  // We attempt to register this as a new persistent variable with the DeclMap.
1143292932Sdim
1144314564Sdim  uintptr_t ptr = constant_int->getZExtValue();
1145292932Sdim
1146314564Sdim  clang::VarDecl *decl = reinterpret_cast<clang::VarDecl *>(ptr);
1147292932Sdim
1148314564Sdim  lldb_private::TypeFromParser result_decl_type(
1149314564Sdim      decl->getType().getAsOpaquePtr(),
1150314564Sdim      lldb_private::ClangASTContext::GetASTContext(&decl->getASTContext()));
1151292932Sdim
1152314564Sdim  StringRef decl_name(decl->getName());
1153314564Sdim  lldb_private::ConstString persistent_variable_name(decl_name.data(),
1154314564Sdim                                                     decl_name.size());
1155314564Sdim  if (!m_decl_map->AddPersistentVariable(decl, persistent_variable_name,
1156314564Sdim                                         result_decl_type, false, false))
1157314564Sdim    return false;
1158292932Sdim
1159314564Sdim  GlobalVariable *persistent_global = new GlobalVariable(
1160314564Sdim      (*m_module), alloc->getType(), false, /* not constant */
1161314564Sdim      GlobalValue::ExternalLinkage, NULL,   /* no initializer */
1162314564Sdim      alloc->getName().str());
1163292932Sdim
1164314564Sdim  // What we're going to do here is make believe this was a regular old external
1165314564Sdim  // variable.  That means we need to make the metadata valid.
1166292932Sdim
1167314564Sdim  NamedMDNode *named_metadata =
1168314564Sdim      m_module->getOrInsertNamedMetadata("clang.global.decl.ptrs");
1169292932Sdim
1170314564Sdim  llvm::Metadata *values[2];
1171314564Sdim  values[0] = ConstantAsMetadata::get(persistent_global);
1172314564Sdim  values[1] = ConstantAsMetadata::get(constant_int);
1173292932Sdim
1174314564Sdim  ArrayRef<llvm::Metadata *> value_ref(values, 2);
1175292932Sdim
1176314564Sdim  MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
1177314564Sdim  named_metadata->addOperand(persistent_global_md);
1178292932Sdim
1179314564Sdim  // Now, since the variable is a pointer variable, we will drop in a load of
1180314564Sdim  // that
1181314564Sdim  // pointer variable.
1182292932Sdim
1183314564Sdim  LoadInst *persistent_load = new LoadInst(persistent_global, "", alloc);
1184292932Sdim
1185314564Sdim  if (log)
1186314564Sdim    log->Printf("Replacing \"%s\" with \"%s\"", PrintValue(alloc).c_str(),
1187314564Sdim                PrintValue(persistent_load).c_str());
1188292932Sdim
1189314564Sdim  alloc->replaceAllUsesWith(persistent_load);
1190314564Sdim  alloc->eraseFromParent();
1191292932Sdim
1192314564Sdim  return true;
1193292932Sdim}
1194292932Sdim
1195314564Sdimbool IRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block) {
1196314564Sdim  if (!m_resolve_vars)
1197314564Sdim    return true;
1198292932Sdim
1199314564Sdim  lldb_private::Log *log(
1200314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1201292932Sdim
1202314564Sdim  BasicBlock::iterator ii;
1203292932Sdim
1204314564Sdim  typedef SmallVector<Instruction *, 2> InstrList;
1205314564Sdim  typedef InstrList::iterator InstrIterator;
1206292932Sdim
1207314564Sdim  InstrList pvar_allocs;
1208292932Sdim
1209314564Sdim  for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
1210314564Sdim    Instruction &inst = *ii;
1211292932Sdim
1212314564Sdim    if (AllocaInst *alloc = dyn_cast<AllocaInst>(&inst)) {
1213314564Sdim      llvm::StringRef alloc_name = alloc->getName();
1214292932Sdim
1215314564Sdim      if (alloc_name.startswith("$") && !alloc_name.startswith("$__lldb")) {
1216314564Sdim        if (alloc_name.find_first_of("0123456789") == 1) {
1217314564Sdim          if (log)
1218314564Sdim            log->Printf("Rejecting a numeric persistent variable.");
1219292932Sdim
1220314564Sdim          m_error_stream.Printf("Error [IRForTarget]: Names starting with $0, "
1221314564Sdim                                "$1, ... are reserved for use as result "
1222314564Sdim                                "names\n");
1223292932Sdim
1224314564Sdim          return false;
1225314564Sdim        }
1226292932Sdim
1227314564Sdim        pvar_allocs.push_back(alloc);
1228314564Sdim      }
1229292932Sdim    }
1230314564Sdim  }
1231292932Sdim
1232314564Sdim  InstrIterator iter;
1233292932Sdim
1234314564Sdim  for (iter = pvar_allocs.begin(); iter != pvar_allocs.end(); ++iter) {
1235314564Sdim    if (!RewritePersistentAlloc(*iter)) {
1236314564Sdim      m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
1237314564Sdim                            "the creation of a persistent variable\n");
1238292932Sdim
1239314564Sdim      if (log)
1240314564Sdim        log->PutCString(
1241314564Sdim            "Couldn't rewrite the creation of a persistent variable");
1242292932Sdim
1243314564Sdim      return false;
1244292932Sdim    }
1245314564Sdim  }
1246292932Sdim
1247314564Sdim  return true;
1248292932Sdim}
1249292932Sdim
1250314564Sdimbool IRForTarget::MaterializeInitializer(uint8_t *data, Constant *initializer) {
1251314564Sdim  if (!initializer)
1252314564Sdim    return true;
1253292932Sdim
1254314564Sdim  lldb_private::Log *log(
1255314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1256292932Sdim
1257314564Sdim  if (log && log->GetVerbose())
1258314564Sdim    log->Printf("  MaterializeInitializer(%p, %s)", (void *)data,
1259314564Sdim                PrintValue(initializer).c_str());
1260292932Sdim
1261314564Sdim  Type *initializer_type = initializer->getType();
1262292932Sdim
1263314564Sdim  if (ConstantInt *int_initializer = dyn_cast<ConstantInt>(initializer)) {
1264314564Sdim    size_t constant_size = m_target_data->getTypeStoreSize(initializer_type);
1265314564Sdim    lldb_private::Scalar scalar = int_initializer->getValue().zextOrTrunc(
1266314564Sdim        llvm::NextPowerOf2(constant_size) * 8);
1267309124Sdim
1268314564Sdim    lldb_private::Error get_data_error;
1269314564Sdim    if (!scalar.GetAsMemoryData(data, constant_size,
1270314564Sdim                                lldb_private::endian::InlHostByteOrder(),
1271314564Sdim                                get_data_error))
1272314564Sdim      return false;
1273309124Sdim
1274314564Sdim    return true;
1275314564Sdim  } else if (ConstantDataArray *array_initializer =
1276314564Sdim                 dyn_cast<ConstantDataArray>(initializer)) {
1277314564Sdim    if (array_initializer->isString()) {
1278314564Sdim      std::string array_initializer_string = array_initializer->getAsString();
1279314564Sdim      memcpy(data, array_initializer_string.c_str(),
1280314564Sdim             m_target_data->getTypeStoreSize(initializer_type));
1281314564Sdim    } else {
1282314564Sdim      ArrayType *array_initializer_type = array_initializer->getType();
1283314564Sdim      Type *array_element_type = array_initializer_type->getElementType();
1284292932Sdim
1285314564Sdim      size_t element_size = m_target_data->getTypeAllocSize(array_element_type);
1286292932Sdim
1287314564Sdim      for (unsigned i = 0; i < array_initializer->getNumOperands(); ++i) {
1288314564Sdim        Value *operand_value = array_initializer->getOperand(i);
1289314564Sdim        Constant *operand_constant = dyn_cast<Constant>(operand_value);
1290292932Sdim
1291314564Sdim        if (!operand_constant)
1292314564Sdim          return false;
1293292932Sdim
1294314564Sdim        if (!MaterializeInitializer(data + (i * element_size),
1295314564Sdim                                    operand_constant))
1296314564Sdim          return false;
1297314564Sdim      }
1298292932Sdim    }
1299314564Sdim    return true;
1300314564Sdim  } else if (ConstantStruct *struct_initializer =
1301314564Sdim                 dyn_cast<ConstantStruct>(initializer)) {
1302314564Sdim    StructType *struct_initializer_type = struct_initializer->getType();
1303314564Sdim    const StructLayout *struct_layout =
1304314564Sdim        m_target_data->getStructLayout(struct_initializer_type);
1305292932Sdim
1306314564Sdim    for (unsigned i = 0; i < struct_initializer->getNumOperands(); ++i) {
1307314564Sdim      if (!MaterializeInitializer(data + struct_layout->getElementOffset(i),
1308314564Sdim                                  struct_initializer->getOperand(i)))
1309314564Sdim        return false;
1310292932Sdim    }
1311314564Sdim    return true;
1312314564Sdim  } else if (isa<ConstantAggregateZero>(initializer)) {
1313314564Sdim    memset(data, 0, m_target_data->getTypeStoreSize(initializer_type));
1314314564Sdim    return true;
1315314564Sdim  }
1316314564Sdim  return false;
1317292932Sdim}
1318292932Sdim
1319292932Sdim// This function does not report errors; its callers are responsible.
1320314564Sdimbool IRForTarget::MaybeHandleVariable(Value *llvm_value_ptr) {
1321314564Sdim  lldb_private::Log *log(
1322314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1323292932Sdim
1324314564Sdim  if (log)
1325314564Sdim    log->Printf("MaybeHandleVariable (%s)", PrintValue(llvm_value_ptr).c_str());
1326292932Sdim
1327314564Sdim  if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(llvm_value_ptr)) {
1328314564Sdim    switch (constant_expr->getOpcode()) {
1329314564Sdim    default:
1330314564Sdim      break;
1331314564Sdim    case Instruction::GetElementPtr:
1332314564Sdim    case Instruction::BitCast:
1333314564Sdim      Value *s = constant_expr->getOperand(0);
1334314564Sdim      if (!MaybeHandleVariable(s))
1335314564Sdim        return false;
1336292932Sdim    }
1337314564Sdim  } else if (GlobalVariable *global_variable =
1338314564Sdim                 dyn_cast<GlobalVariable>(llvm_value_ptr)) {
1339314564Sdim    if (!GlobalValue::isExternalLinkage(global_variable->getLinkage()))
1340314564Sdim      return true;
1341292932Sdim
1342314564Sdim    clang::NamedDecl *named_decl = DeclForGlobal(global_variable);
1343292932Sdim
1344314564Sdim    if (!named_decl) {
1345314564Sdim      if (IsObjCSelectorRef(llvm_value_ptr))
1346314564Sdim        return true;
1347292932Sdim
1348314564Sdim      if (!global_variable->hasExternalLinkage())
1349314564Sdim        return true;
1350292932Sdim
1351314564Sdim      if (log)
1352314564Sdim        log->Printf("Found global variable \"%s\" without metadata",
1353314564Sdim                    global_variable->getName().str().c_str());
1354292932Sdim
1355314564Sdim      return false;
1356314564Sdim    }
1357292932Sdim
1358314564Sdim    std::string name(named_decl->getName().str());
1359292932Sdim
1360314564Sdim    clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl);
1361314564Sdim    if (value_decl == NULL)
1362314564Sdim      return false;
1363292932Sdim
1364314564Sdim    lldb_private::CompilerType compiler_type(&value_decl->getASTContext(),
1365314564Sdim                                             value_decl->getType());
1366292932Sdim
1367314564Sdim    const Type *value_type = NULL;
1368292932Sdim
1369314564Sdim    if (name[0] == '$') {
1370314564Sdim      // The $__lldb_expr_result name indicates the return value has allocated
1371314564Sdim      // as
1372314564Sdim      // a static variable.  Per the comment at
1373314564Sdim      // ASTResultSynthesizer::SynthesizeBodyResult,
1374314564Sdim      // accesses to this static variable need to be redirected to the result of
1375314564Sdim      // dereferencing
1376314564Sdim      // a pointer that is passed in as one of the arguments.
1377314564Sdim      //
1378314564Sdim      // Consequently, when reporting the size of the type, we report a pointer
1379314564Sdim      // type pointing
1380314564Sdim      // to the type of $__lldb_expr_result, not the type itself.
1381314564Sdim      //
1382314564Sdim      // We also do this for any user-declared persistent variables.
1383314564Sdim      compiler_type = compiler_type.GetPointerType();
1384314564Sdim      value_type = PointerType::get(global_variable->getType(), 0);
1385314564Sdim    } else {
1386314564Sdim      value_type = global_variable->getType();
1387314564Sdim    }
1388292932Sdim
1389314564Sdim    const uint64_t value_size = compiler_type.GetByteSize(nullptr);
1390314564Sdim    lldb::offset_t value_alignment =
1391314564Sdim        (compiler_type.GetTypeBitAlign() + 7ull) / 8ull;
1392292932Sdim
1393314564Sdim    if (log) {
1394314564Sdim      log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %" PRIu64
1395314564Sdim                  ", align %" PRIu64 "]",
1396314564Sdim                  name.c_str(),
1397314564Sdim                  lldb_private::ClangUtil::GetQualType(compiler_type)
1398314564Sdim                      .getAsString()
1399314564Sdim                      .c_str(),
1400314564Sdim                  PrintType(value_type).c_str(), value_size, value_alignment);
1401292932Sdim    }
1402292932Sdim
1403314564Sdim    if (named_decl &&
1404314564Sdim        !m_decl_map->AddValueToStruct(
1405314564Sdim            named_decl, lldb_private::ConstString(name.c_str()), llvm_value_ptr,
1406314564Sdim            value_size, value_alignment)) {
1407314564Sdim      if (!global_variable->hasExternalLinkage())
1408314564Sdim        return true;
1409314564Sdim      else
1410314564Sdim        return true;
1411292932Sdim    }
1412314564Sdim  } else if (dyn_cast<llvm::Function>(llvm_value_ptr)) {
1413314564Sdim    if (log)
1414314564Sdim      log->Printf("Function pointers aren't handled right now");
1415292932Sdim
1416314564Sdim    return false;
1417314564Sdim  }
1418314564Sdim
1419314564Sdim  return true;
1420292932Sdim}
1421292932Sdim
1422292932Sdim// This function does not report errors; its callers are responsible.
1423314564Sdimbool IRForTarget::HandleSymbol(Value *symbol) {
1424314564Sdim  lldb_private::Log *log(
1425314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1426292932Sdim
1427314564Sdim  lldb_private::ConstString name(symbol->getName().str().c_str());
1428292932Sdim
1429314564Sdim  lldb::addr_t symbol_addr =
1430314564Sdim      m_decl_map->GetSymbolAddress(name, lldb::eSymbolTypeAny);
1431292932Sdim
1432314564Sdim  if (symbol_addr == LLDB_INVALID_ADDRESS) {
1433314564Sdim    if (log)
1434314564Sdim      log->Printf("Symbol \"%s\" had no address", name.GetCString());
1435292932Sdim
1436314564Sdim    return false;
1437314564Sdim  }
1438292932Sdim
1439314564Sdim  if (log)
1440314564Sdim    log->Printf("Found \"%s\" at 0x%" PRIx64, name.GetCString(), symbol_addr);
1441292932Sdim
1442314564Sdim  Type *symbol_type = symbol->getType();
1443292932Sdim
1444314564Sdim  Constant *symbol_addr_int = ConstantInt::get(m_intptr_ty, symbol_addr, false);
1445292932Sdim
1446314564Sdim  Value *symbol_addr_ptr =
1447314564Sdim      ConstantExpr::getIntToPtr(symbol_addr_int, symbol_type);
1448292932Sdim
1449314564Sdim  if (log)
1450314564Sdim    log->Printf("Replacing %s with %s", PrintValue(symbol).c_str(),
1451314564Sdim                PrintValue(symbol_addr_ptr).c_str());
1452292932Sdim
1453314564Sdim  symbol->replaceAllUsesWith(symbol_addr_ptr);
1454292932Sdim
1455314564Sdim  return true;
1456292932Sdim}
1457292932Sdim
1458314564Sdimbool IRForTarget::MaybeHandleCallArguments(CallInst *Old) {
1459314564Sdim  lldb_private::Log *log(
1460314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1461292932Sdim
1462314564Sdim  if (log)
1463314564Sdim    log->Printf("MaybeHandleCallArguments(%s)", PrintValue(Old).c_str());
1464292932Sdim
1465314564Sdim  for (unsigned op_index = 0, num_ops = Old->getNumArgOperands();
1466314564Sdim       op_index < num_ops; ++op_index)
1467314564Sdim    if (!MaybeHandleVariable(Old->getArgOperand(
1468314564Sdim            op_index))) // conservatively believe that this is a store
1469314564Sdim    {
1470314564Sdim      m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
1471314564Sdim                            "one of the arguments of a function call.\n");
1472292932Sdim
1473314564Sdim      return false;
1474314564Sdim    }
1475292932Sdim
1476314564Sdim  return true;
1477292932Sdim}
1478292932Sdim
1479314564Sdimbool IRForTarget::HandleObjCClass(Value *classlist_reference) {
1480314564Sdim  lldb_private::Log *log(
1481314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1482292932Sdim
1483314564Sdim  GlobalVariable *global_variable =
1484314564Sdim      dyn_cast<GlobalVariable>(classlist_reference);
1485292932Sdim
1486314564Sdim  if (!global_variable)
1487314564Sdim    return false;
1488292932Sdim
1489314564Sdim  Constant *initializer = global_variable->getInitializer();
1490292932Sdim
1491314564Sdim  if (!initializer)
1492314564Sdim    return false;
1493292932Sdim
1494314564Sdim  if (!initializer->hasName())
1495314564Sdim    return false;
1496292932Sdim
1497314564Sdim  StringRef name(initializer->getName());
1498314564Sdim  lldb_private::ConstString name_cstr(name.str().c_str());
1499314564Sdim  lldb::addr_t class_ptr =
1500314564Sdim      m_decl_map->GetSymbolAddress(name_cstr, lldb::eSymbolTypeObjCClass);
1501292932Sdim
1502314564Sdim  if (log)
1503314564Sdim    log->Printf("Found reference to Objective-C class %s (0x%llx)",
1504314564Sdim                name_cstr.AsCString(), (unsigned long long)class_ptr);
1505292932Sdim
1506314564Sdim  if (class_ptr == LLDB_INVALID_ADDRESS)
1507314564Sdim    return false;
1508292932Sdim
1509314564Sdim  if (global_variable->use_empty())
1510314564Sdim    return false;
1511292932Sdim
1512314564Sdim  SmallVector<LoadInst *, 2> load_instructions;
1513292932Sdim
1514314564Sdim  for (llvm::User *u : global_variable->users()) {
1515314564Sdim    if (LoadInst *load_instruction = dyn_cast<LoadInst>(u))
1516314564Sdim      load_instructions.push_back(load_instruction);
1517314564Sdim  }
1518292932Sdim
1519314564Sdim  if (load_instructions.empty())
1520314564Sdim    return false;
1521292932Sdim
1522314564Sdim  Constant *class_addr = ConstantInt::get(m_intptr_ty, (uint64_t)class_ptr);
1523292932Sdim
1524314564Sdim  for (LoadInst *load_instruction : load_instructions) {
1525314564Sdim    Constant *class_bitcast =
1526314564Sdim        ConstantExpr::getIntToPtr(class_addr, load_instruction->getType());
1527292932Sdim
1528314564Sdim    load_instruction->replaceAllUsesWith(class_bitcast);
1529292932Sdim
1530314564Sdim    load_instruction->eraseFromParent();
1531314564Sdim  }
1532292932Sdim
1533314564Sdim  return true;
1534292932Sdim}
1535292932Sdim
1536314564Sdimbool IRForTarget::RemoveCXAAtExit(BasicBlock &basic_block) {
1537314564Sdim  BasicBlock::iterator ii;
1538292932Sdim
1539314564Sdim  std::vector<CallInst *> calls_to_remove;
1540292932Sdim
1541314564Sdim  for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
1542314564Sdim    Instruction &inst = *ii;
1543292932Sdim
1544314564Sdim    CallInst *call = dyn_cast<CallInst>(&inst);
1545292932Sdim
1546314564Sdim    // MaybeHandleCallArguments handles error reporting; we are silent here
1547314564Sdim    if (!call)
1548314564Sdim      continue;
1549292932Sdim
1550314564Sdim    bool remove = false;
1551292932Sdim
1552314564Sdim    llvm::Function *func = call->getCalledFunction();
1553292932Sdim
1554314564Sdim    if (func && func->getName() == "__cxa_atexit")
1555314564Sdim      remove = true;
1556292932Sdim
1557314564Sdim    llvm::Value *val = call->getCalledValue();
1558292932Sdim
1559314564Sdim    if (val && val->getName() == "__cxa_atexit")
1560314564Sdim      remove = true;
1561292932Sdim
1562314564Sdim    if (remove)
1563314564Sdim      calls_to_remove.push_back(call);
1564314564Sdim  }
1565292932Sdim
1566314564Sdim  for (std::vector<CallInst *>::iterator ci = calls_to_remove.begin(),
1567314564Sdim                                         ce = calls_to_remove.end();
1568314564Sdim       ci != ce; ++ci) {
1569314564Sdim    (*ci)->eraseFromParent();
1570314564Sdim  }
1571292932Sdim
1572314564Sdim  return true;
1573292932Sdim}
1574292932Sdim
1575314564Sdimbool IRForTarget::ResolveCalls(BasicBlock &basic_block) {
1576314564Sdim  /////////////////////////////////////////////////////////////////////////
1577314564Sdim  // Prepare the current basic block for execution in the remote process
1578314564Sdim  //
1579292932Sdim
1580314564Sdim  BasicBlock::iterator ii;
1581292932Sdim
1582314564Sdim  for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
1583314564Sdim    Instruction &inst = *ii;
1584292932Sdim
1585314564Sdim    CallInst *call = dyn_cast<CallInst>(&inst);
1586292932Sdim
1587314564Sdim    // MaybeHandleCallArguments handles error reporting; we are silent here
1588314564Sdim    if (call && !MaybeHandleCallArguments(call))
1589314564Sdim      return false;
1590314564Sdim  }
1591292932Sdim
1592314564Sdim  return true;
1593292932Sdim}
1594292932Sdim
1595314564Sdimbool IRForTarget::ResolveExternals(Function &llvm_function) {
1596314564Sdim  lldb_private::Log *log(
1597314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1598292932Sdim
1599314564Sdim  for (GlobalVariable &global_var : m_module->globals()) {
1600314564Sdim    std::string global_name = global_var.getName().str();
1601292932Sdim
1602314564Sdim    if (log)
1603314564Sdim      log->Printf("Examining %s, DeclForGlobalValue returns %p",
1604314564Sdim                  global_name.c_str(),
1605314564Sdim                  static_cast<void *>(DeclForGlobal(&global_var)));
1606292932Sdim
1607314564Sdim    if (global_name.find("OBJC_IVAR") == 0) {
1608314564Sdim      if (!HandleSymbol(&global_var)) {
1609314564Sdim        m_error_stream.Printf("Error [IRForTarget]: Couldn't find Objective-C "
1610314564Sdim                              "indirect ivar symbol %s\n",
1611314564Sdim                              global_name.c_str());
1612292932Sdim
1613314564Sdim        return false;
1614314564Sdim      }
1615314564Sdim    } else if (global_name.find("OBJC_CLASSLIST_REFERENCES_$") !=
1616314564Sdim               global_name.npos) {
1617314564Sdim      if (!HandleObjCClass(&global_var)) {
1618314564Sdim        m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class "
1619314564Sdim                              "for an Objective-C static method call\n");
1620292932Sdim
1621314564Sdim        return false;
1622314564Sdim      }
1623314564Sdim    } else if (global_name.find("OBJC_CLASSLIST_SUP_REFS_$") !=
1624314564Sdim               global_name.npos) {
1625314564Sdim      if (!HandleObjCClass(&global_var)) {
1626314564Sdim        m_error_stream.Printf("Error [IRForTarget]: Couldn't resolve the class "
1627314564Sdim                              "for an Objective-C static method call\n");
1628292932Sdim
1629314564Sdim        return false;
1630314564Sdim      }
1631314564Sdim    } else if (DeclForGlobal(&global_var)) {
1632314564Sdim      if (!MaybeHandleVariable(&global_var)) {
1633314564Sdim        m_error_stream.Printf("Internal error [IRForTarget]: Couldn't rewrite "
1634314564Sdim                              "external variable %s\n",
1635314564Sdim                              global_name.c_str());
1636292932Sdim
1637314564Sdim        return false;
1638314564Sdim      }
1639292932Sdim    }
1640314564Sdim  }
1641292932Sdim
1642314564Sdim  return true;
1643292932Sdim}
1644292932Sdim
1645314564Sdimstatic bool isGuardVariableRef(Value *V) {
1646314564Sdim  Constant *Old = NULL;
1647292932Sdim
1648314564Sdim  if (!(Old = dyn_cast<Constant>(V)))
1649314564Sdim    return false;
1650292932Sdim
1651314564Sdim  ConstantExpr *CE = NULL;
1652292932Sdim
1653314564Sdim  if ((CE = dyn_cast<ConstantExpr>(V))) {
1654314564Sdim    if (CE->getOpcode() != Instruction::BitCast)
1655314564Sdim      return false;
1656292932Sdim
1657314564Sdim    Old = CE->getOperand(0);
1658314564Sdim  }
1659292932Sdim
1660314564Sdim  GlobalVariable *GV = dyn_cast<GlobalVariable>(Old);
1661292932Sdim
1662314564Sdim  if (!GV || !GV->hasName() ||
1663314564Sdim      (!GV->getName().startswith("_ZGV") && // Itanium ABI guard variable
1664314564Sdim       !GV->getName().endswith("@4IA")))    // Microsoft ABI guard variable
1665314564Sdim  {
1666314564Sdim    return false;
1667314564Sdim  }
1668292932Sdim
1669314564Sdim  return true;
1670292932Sdim}
1671292932Sdim
1672314564Sdimvoid IRForTarget::TurnGuardLoadIntoZero(llvm::Instruction *guard_load) {
1673314564Sdim  Constant *zero(Constant::getNullValue(guard_load->getType()));
1674314564Sdim  guard_load->replaceAllUsesWith(zero);
1675314564Sdim  guard_load->eraseFromParent();
1676292932Sdim}
1677292932Sdim
1678314564Sdimstatic void ExciseGuardStore(Instruction *guard_store) {
1679314564Sdim  guard_store->eraseFromParent();
1680292932Sdim}
1681292932Sdim
1682314564Sdimbool IRForTarget::RemoveGuards(BasicBlock &basic_block) {
1683314564Sdim  ///////////////////////////////////////////////////////
1684314564Sdim  // Eliminate any reference to guard variables found.
1685314564Sdim  //
1686292932Sdim
1687314564Sdim  BasicBlock::iterator ii;
1688292932Sdim
1689314564Sdim  typedef SmallVector<Instruction *, 2> InstrList;
1690314564Sdim  typedef InstrList::iterator InstrIterator;
1691292932Sdim
1692314564Sdim  InstrList guard_loads;
1693314564Sdim  InstrList guard_stores;
1694292932Sdim
1695314564Sdim  for (ii = basic_block.begin(); ii != basic_block.end(); ++ii) {
1696314564Sdim    Instruction &inst = *ii;
1697292932Sdim
1698314564Sdim    if (LoadInst *load = dyn_cast<LoadInst>(&inst))
1699314564Sdim      if (isGuardVariableRef(load->getPointerOperand()))
1700314564Sdim        guard_loads.push_back(&inst);
1701292932Sdim
1702314564Sdim    if (StoreInst *store = dyn_cast<StoreInst>(&inst))
1703314564Sdim      if (isGuardVariableRef(store->getPointerOperand()))
1704314564Sdim        guard_stores.push_back(&inst);
1705314564Sdim  }
1706292932Sdim
1707314564Sdim  InstrIterator iter;
1708292932Sdim
1709314564Sdim  for (iter = guard_loads.begin(); iter != guard_loads.end(); ++iter)
1710314564Sdim    TurnGuardLoadIntoZero(*iter);
1711292932Sdim
1712314564Sdim  for (iter = guard_stores.begin(); iter != guard_stores.end(); ++iter)
1713314564Sdim    ExciseGuardStore(*iter);
1714292932Sdim
1715314564Sdim  return true;
1716292932Sdim}
1717292932Sdim
1718292932Sdim// This function does not report errors; its callers are responsible.
1719314564Sdimbool IRForTarget::UnfoldConstant(Constant *old_constant,
1720314564Sdim                                 llvm::Function *llvm_function,
1721314564Sdim                                 FunctionValueCache &value_maker,
1722314564Sdim                                 FunctionValueCache &entry_instruction_finder,
1723314564Sdim                                 lldb_private::Stream &error_stream) {
1724314564Sdim  SmallVector<User *, 16> users;
1725292932Sdim
1726314564Sdim  // We do this because the use list might change, invalidating our iterator.
1727314564Sdim  // Much better to keep a work list ourselves.
1728314564Sdim  for (llvm::User *u : old_constant->users())
1729314564Sdim    users.push_back(u);
1730292932Sdim
1731314564Sdim  for (size_t i = 0; i < users.size(); ++i) {
1732314564Sdim    User *user = users[i];
1733292932Sdim
1734314564Sdim    if (Constant *constant = dyn_cast<Constant>(user)) {
1735314564Sdim      // synthesize a new non-constant equivalent of the constant
1736292932Sdim
1737314564Sdim      if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant)) {
1738314564Sdim        switch (constant_expr->getOpcode()) {
1739314564Sdim        default:
1740314564Sdim          error_stream.Printf("error [IRForTarget internal]: Unhandled "
1741314564Sdim                              "constant expression type: \"%s\"",
1742314564Sdim                              PrintValue(constant_expr).c_str());
1743314564Sdim          return false;
1744314564Sdim        case Instruction::BitCast: {
1745314564Sdim          FunctionValueCache bit_cast_maker(
1746314564Sdim              [&value_maker, &entry_instruction_finder, old_constant,
1747314564Sdim               constant_expr](llvm::Function *function) -> llvm::Value * {
1748314564Sdim                // UnaryExpr
1749314564Sdim                //   OperandList[0] is value
1750292932Sdim
1751314564Sdim                if (constant_expr->getOperand(0) != old_constant)
1752314564Sdim                  return constant_expr;
1753292932Sdim
1754314564Sdim                return new BitCastInst(
1755314564Sdim                    value_maker.GetValue(function), constant_expr->getType(),
1756314564Sdim                    "", llvm::cast<Instruction>(
1757314564Sdim                            entry_instruction_finder.GetValue(function)));
1758314564Sdim              });
1759292932Sdim
1760314564Sdim          if (!UnfoldConstant(constant_expr, llvm_function, bit_cast_maker,
1761314564Sdim                              entry_instruction_finder, error_stream))
1762314564Sdim            return false;
1763314564Sdim        } break;
1764314564Sdim        case Instruction::GetElementPtr: {
1765314564Sdim          // GetElementPtrConstantExpr
1766314564Sdim          //   OperandList[0] is base
1767314564Sdim          //   OperandList[1]... are indices
1768292932Sdim
1769314564Sdim          FunctionValueCache get_element_pointer_maker(
1770314564Sdim              [&value_maker, &entry_instruction_finder, old_constant,
1771314564Sdim               constant_expr](llvm::Function *function) -> llvm::Value * {
1772314564Sdim                Value *ptr = constant_expr->getOperand(0);
1773292932Sdim
1774314564Sdim                if (ptr == old_constant)
1775314564Sdim                  ptr = value_maker.GetValue(function);
1776292932Sdim
1777314564Sdim                std::vector<Value *> index_vector;
1778292932Sdim
1779314564Sdim                unsigned operand_index;
1780314564Sdim                unsigned num_operands = constant_expr->getNumOperands();
1781292932Sdim
1782314564Sdim                for (operand_index = 1; operand_index < num_operands;
1783314564Sdim                     ++operand_index) {
1784314564Sdim                  Value *operand = constant_expr->getOperand(operand_index);
1785292932Sdim
1786314564Sdim                  if (operand == old_constant)
1787314564Sdim                    operand = value_maker.GetValue(function);
1788292932Sdim
1789314564Sdim                  index_vector.push_back(operand);
1790314564Sdim                }
1791292932Sdim
1792314564Sdim                ArrayRef<Value *> indices(index_vector);
1793292932Sdim
1794314564Sdim                return GetElementPtrInst::Create(
1795314564Sdim                    nullptr, ptr, indices, "",
1796314564Sdim                    llvm::cast<Instruction>(
1797314564Sdim                        entry_instruction_finder.GetValue(function)));
1798314564Sdim              });
1799292932Sdim
1800314564Sdim          if (!UnfoldConstant(constant_expr, llvm_function,
1801314564Sdim                              get_element_pointer_maker,
1802314564Sdim                              entry_instruction_finder, error_stream))
1803314564Sdim            return false;
1804314564Sdim        } break;
1805292932Sdim        }
1806314564Sdim      } else {
1807314564Sdim        error_stream.Printf(
1808314564Sdim            "error [IRForTarget internal]: Unhandled constant type: \"%s\"",
1809314564Sdim            PrintValue(constant).c_str());
1810314564Sdim        return false;
1811314564Sdim      }
1812314564Sdim    } else {
1813314564Sdim      if (Instruction *inst = llvm::dyn_cast<Instruction>(user)) {
1814314564Sdim        if (llvm_function && inst->getParent()->getParent() != llvm_function) {
1815314564Sdim          error_stream.PutCString("error: Capturing non-local variables in "
1816314564Sdim                                  "expressions is unsupported.\n");
1817314564Sdim          return false;
1818292932Sdim        }
1819314564Sdim        inst->replaceUsesOfWith(
1820314564Sdim            old_constant, value_maker.GetValue(inst->getParent()->getParent()));
1821314564Sdim      } else {
1822314564Sdim        error_stream.Printf(
1823314564Sdim            "error [IRForTarget internal]: Unhandled non-constant type: \"%s\"",
1824314564Sdim            PrintValue(user).c_str());
1825314564Sdim        return false;
1826314564Sdim      }
1827292932Sdim    }
1828314564Sdim  }
1829292932Sdim
1830314564Sdim  if (!isa<GlobalValue>(old_constant)) {
1831314564Sdim    old_constant->destroyConstant();
1832314564Sdim  }
1833292932Sdim
1834314564Sdim  return true;
1835292932Sdim}
1836292932Sdim
1837314564Sdimbool IRForTarget::ReplaceVariables(Function &llvm_function) {
1838314564Sdim  if (!m_resolve_vars)
1839314564Sdim    return true;
1840292932Sdim
1841314564Sdim  lldb_private::Log *log(
1842314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1843292932Sdim
1844314564Sdim  m_decl_map->DoStructLayout();
1845292932Sdim
1846314564Sdim  if (log)
1847314564Sdim    log->Printf("Element arrangement:");
1848292932Sdim
1849314564Sdim  uint32_t num_elements;
1850314564Sdim  uint32_t element_index;
1851292932Sdim
1852314564Sdim  size_t size;
1853314564Sdim  lldb::offset_t alignment;
1854292932Sdim
1855314564Sdim  if (!m_decl_map->GetStructInfo(num_elements, size, alignment))
1856314564Sdim    return false;
1857292932Sdim
1858314564Sdim  Function::arg_iterator iter(llvm_function.getArgumentList().begin());
1859292932Sdim
1860314564Sdim  if (iter == llvm_function.getArgumentList().end()) {
1861314564Sdim    m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes no "
1862314564Sdim                          "arguments (should take at least a struct pointer)");
1863292932Sdim
1864314564Sdim    return false;
1865314564Sdim  }
1866292932Sdim
1867314564Sdim  Argument *argument = &*iter;
1868292932Sdim
1869314564Sdim  if (argument->getName().equals("this")) {
1870314564Sdim    ++iter;
1871292932Sdim
1872314564Sdim    if (iter == llvm_function.getArgumentList().end()) {
1873314564Sdim      m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
1874314564Sdim                            "'this' argument (should take a struct pointer "
1875314564Sdim                            "too)");
1876292932Sdim
1877314564Sdim      return false;
1878292932Sdim    }
1879292932Sdim
1880314564Sdim    argument = &*iter;
1881314564Sdim  } else if (argument->getName().equals("self")) {
1882314564Sdim    ++iter;
1883292932Sdim
1884314564Sdim    if (iter == llvm_function.getArgumentList().end()) {
1885314564Sdim      m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
1886314564Sdim                            "'self' argument (should take '_cmd' and a struct "
1887314564Sdim                            "pointer too)");
1888292932Sdim
1889314564Sdim      return false;
1890314564Sdim    }
1891292932Sdim
1892314564Sdim    if (!iter->getName().equals("_cmd")) {
1893314564Sdim      m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes '%s' "
1894314564Sdim                            "after 'self' argument (should take '_cmd')",
1895314564Sdim                            iter->getName().str().c_str());
1896292932Sdim
1897314564Sdim      return false;
1898314564Sdim    }
1899292932Sdim
1900314564Sdim    ++iter;
1901292932Sdim
1902314564Sdim    if (iter == llvm_function.getArgumentList().end()) {
1903314564Sdim      m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes only "
1904314564Sdim                            "'self' and '_cmd' arguments (should take a struct "
1905314564Sdim                            "pointer too)");
1906292932Sdim
1907314564Sdim      return false;
1908292932Sdim    }
1909292932Sdim
1910314564Sdim    argument = &*iter;
1911314564Sdim  }
1912292932Sdim
1913314564Sdim  if (!argument->getName().equals("$__lldb_arg")) {
1914314564Sdim    m_error_stream.Printf("Internal error [IRForTarget]: Wrapper takes an "
1915314564Sdim                          "argument named '%s' instead of the struct pointer",
1916314564Sdim                          argument->getName().str().c_str());
1917292932Sdim
1918314564Sdim    return false;
1919314564Sdim  }
1920292932Sdim
1921314564Sdim  if (log)
1922314564Sdim    log->Printf("Arg: \"%s\"", PrintValue(argument).c_str());
1923292932Sdim
1924314564Sdim  BasicBlock &entry_block(llvm_function.getEntryBlock());
1925314564Sdim  Instruction *FirstEntryInstruction(entry_block.getFirstNonPHIOrDbg());
1926292932Sdim
1927314564Sdim  if (!FirstEntryInstruction) {
1928314564Sdim    m_error_stream.Printf("Internal error [IRForTarget]: Couldn't find the "
1929314564Sdim                          "first instruction in the wrapper for use in "
1930314564Sdim                          "rewriting");
1931292932Sdim
1932314564Sdim    return false;
1933314564Sdim  }
1934292932Sdim
1935314564Sdim  LLVMContext &context(m_module->getContext());
1936314564Sdim  IntegerType *offset_type(Type::getInt32Ty(context));
1937292932Sdim
1938314564Sdim  if (!offset_type) {
1939314564Sdim    m_error_stream.Printf(
1940314564Sdim        "Internal error [IRForTarget]: Couldn't produce an offset type");
1941292932Sdim
1942314564Sdim    return false;
1943314564Sdim  }
1944292932Sdim
1945314564Sdim  for (element_index = 0; element_index < num_elements; ++element_index) {
1946314564Sdim    const clang::NamedDecl *decl = NULL;
1947314564Sdim    Value *value = NULL;
1948314564Sdim    lldb::offset_t offset;
1949314564Sdim    lldb_private::ConstString name;
1950292932Sdim
1951314564Sdim    if (!m_decl_map->GetStructElement(decl, value, offset, name,
1952314564Sdim                                      element_index)) {
1953314564Sdim      m_error_stream.Printf(
1954314564Sdim          "Internal error [IRForTarget]: Structure information is incomplete");
1955292932Sdim
1956314564Sdim      return false;
1957314564Sdim    }
1958292932Sdim
1959314564Sdim    if (log)
1960314564Sdim      log->Printf("  \"%s\" (\"%s\") placed at %" PRIu64, name.GetCString(),
1961314564Sdim                  decl->getNameAsString().c_str(), offset);
1962292932Sdim
1963314564Sdim    if (value) {
1964314564Sdim      if (log)
1965314564Sdim        log->Printf("    Replacing [%s]", PrintValue(value).c_str());
1966292932Sdim
1967314564Sdim      FunctionValueCache body_result_maker(
1968314564Sdim          [this, name, offset_type, offset, argument,
1969314564Sdim           value](llvm::Function *function) -> llvm::Value * {
1970314564Sdim            // Per the comment at ASTResultSynthesizer::SynthesizeBodyResult, in
1971314564Sdim            // cases where the result
1972314564Sdim            // variable is an rvalue, we have to synthesize a dereference of the
1973314564Sdim            // appropriate structure
1974314564Sdim            // entry in order to produce the static variable that the AST thinks
1975314564Sdim            // it is accessing.
1976292932Sdim
1977314564Sdim            llvm::Instruction *entry_instruction = llvm::cast<Instruction>(
1978314564Sdim                m_entry_instruction_finder.GetValue(function));
1979292932Sdim
1980314564Sdim            ConstantInt *offset_int(
1981314564Sdim                ConstantInt::get(offset_type, offset, true));
1982314564Sdim            GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(
1983314564Sdim                nullptr, argument, offset_int, "", entry_instruction);
1984292932Sdim
1985314564Sdim            if (name == m_result_name && !m_result_is_pointer) {
1986314564Sdim              BitCastInst *bit_cast = new BitCastInst(
1987314564Sdim                  get_element_ptr, value->getType()->getPointerTo(), "",
1988314564Sdim                  entry_instruction);
1989292932Sdim
1990314564Sdim              LoadInst *load = new LoadInst(bit_cast, "", entry_instruction);
1991292932Sdim
1992314564Sdim              return load;
1993314564Sdim            } else {
1994314564Sdim              BitCastInst *bit_cast = new BitCastInst(
1995314564Sdim                  get_element_ptr, value->getType(), "", entry_instruction);
1996292932Sdim
1997314564Sdim              return bit_cast;
1998292932Sdim            }
1999314564Sdim          });
2000292932Sdim
2001314564Sdim      if (Constant *constant = dyn_cast<Constant>(value)) {
2002314564Sdim        if (!UnfoldConstant(constant, &llvm_function, body_result_maker,
2003314564Sdim                            m_entry_instruction_finder, m_error_stream)) {
2004314564Sdim          return false;
2005292932Sdim        }
2006314564Sdim      } else if (Instruction *instruction = dyn_cast<Instruction>(value)) {
2007314564Sdim        if (instruction->getParent()->getParent() != &llvm_function) {
2008314564Sdim          m_error_stream.PutCString("error: Capturing non-local variables in "
2009314564Sdim                                    "expressions is unsupported.\n");
2010314564Sdim          return false;
2011314564Sdim        }
2012314564Sdim        value->replaceAllUsesWith(
2013314564Sdim            body_result_maker.GetValue(instruction->getParent()->getParent()));
2014314564Sdim      } else {
2015314564Sdim        if (log)
2016314564Sdim          log->Printf("Unhandled non-constant type: \"%s\"",
2017314564Sdim                      PrintValue(value).c_str());
2018314564Sdim        return false;
2019314564Sdim      }
2020314564Sdim
2021314564Sdim      if (GlobalVariable *var = dyn_cast<GlobalVariable>(value))
2022314564Sdim        var->eraseFromParent();
2023292932Sdim    }
2024314564Sdim  }
2025292932Sdim
2026314564Sdim  if (log)
2027314564Sdim    log->Printf("Total structure [align %" PRId64 ", size %" PRIu64 "]",
2028314564Sdim                (int64_t)alignment, (uint64_t)size);
2029292932Sdim
2030314564Sdim  return true;
2031292932Sdim}
2032292932Sdim
2033314564Sdimllvm::Constant *IRForTarget::BuildRelocation(llvm::Type *type,
2034314564Sdim                                             uint64_t offset) {
2035314564Sdim  llvm::Constant *offset_int = ConstantInt::get(m_intptr_ty, offset);
2036292932Sdim
2037314564Sdim  llvm::Constant *offset_array[1];
2038292932Sdim
2039314564Sdim  offset_array[0] = offset_int;
2040292932Sdim
2041314564Sdim  llvm::ArrayRef<llvm::Constant *> offsets(offset_array, 1);
2042314564Sdim  llvm::Type *char_type = llvm::Type::getInt8Ty(m_module->getContext());
2043314564Sdim  llvm::Type *char_pointer_type = char_type->getPointerTo();
2044292932Sdim
2045314564Sdim  llvm::Constant *reloc_placeholder_bitcast =
2046314564Sdim      ConstantExpr::getBitCast(m_reloc_placeholder, char_pointer_type);
2047314564Sdim  llvm::Constant *reloc_getelementptr = ConstantExpr::getGetElementPtr(
2048314564Sdim      char_type, reloc_placeholder_bitcast, offsets);
2049314564Sdim  llvm::Constant *reloc_bitcast =
2050314564Sdim      ConstantExpr::getBitCast(reloc_getelementptr, type);
2051292932Sdim
2052314564Sdim  return reloc_bitcast;
2053292932Sdim}
2054292932Sdim
2055314564Sdimbool IRForTarget::runOnModule(Module &llvm_module) {
2056314564Sdim  lldb_private::Log *log(
2057314564Sdim      lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
2058292932Sdim
2059314564Sdim  m_module = &llvm_module;
2060314564Sdim  m_target_data.reset(new DataLayout(m_module));
2061314564Sdim  m_intptr_ty = llvm::Type::getIntNTy(m_module->getContext(),
2062314564Sdim                                      m_target_data->getPointerSizeInBits());
2063292932Sdim
2064314564Sdim  if (log) {
2065314564Sdim    std::string s;
2066314564Sdim    raw_string_ostream oss(s);
2067292932Sdim
2068314564Sdim    m_module->print(oss, NULL);
2069292932Sdim
2070314564Sdim    oss.flush();
2071292932Sdim
2072314564Sdim    log->Printf("Module as passed in to IRForTarget: \n\"%s\"", s.c_str());
2073314564Sdim  }
2074292932Sdim
2075314564Sdim  Function *const main_function =
2076314564Sdim      m_func_name.IsEmpty() ? nullptr
2077314564Sdim                            : m_module->getFunction(m_func_name.GetStringRef());
2078292932Sdim
2079314564Sdim  if (!m_func_name.IsEmpty() && !main_function) {
2080314564Sdim    if (log)
2081314564Sdim      log->Printf("Couldn't find \"%s()\" in the module",
2082314564Sdim                  m_func_name.AsCString());
2083292932Sdim
2084314564Sdim    m_error_stream.Printf("Internal error [IRForTarget]: Couldn't find wrapper "
2085314564Sdim                          "'%s' in the module",
2086314564Sdim                          m_func_name.AsCString());
2087292932Sdim
2088314564Sdim    return false;
2089314564Sdim  }
2090292932Sdim
2091314564Sdim  if (main_function) {
2092314564Sdim    if (!FixFunctionLinkage(*main_function)) {
2093314564Sdim      if (log)
2094314564Sdim        log->Printf("Couldn't fix the linkage for the function");
2095292932Sdim
2096314564Sdim      return false;
2097292932Sdim    }
2098314564Sdim  }
2099292932Sdim
2100314564Sdim  llvm::Type *int8_ty = Type::getInt8Ty(m_module->getContext());
2101292932Sdim
2102314564Sdim  m_reloc_placeholder = new llvm::GlobalVariable(
2103314564Sdim      (*m_module), int8_ty, false /* IsConstant */,
2104314564Sdim      GlobalVariable::InternalLinkage, Constant::getNullValue(int8_ty),
2105314564Sdim      "reloc_placeholder", NULL /* InsertBefore */,
2106314564Sdim      GlobalVariable::NotThreadLocal /* ThreadLocal */, 0 /* AddressSpace */);
2107292932Sdim
2108314564Sdim  ////////////////////////////////////////////////////////////
2109314564Sdim  // Replace $__lldb_expr_result with a persistent variable
2110314564Sdim  //
2111292932Sdim
2112314564Sdim  if (main_function) {
2113314564Sdim    if (!CreateResultVariable(*main_function)) {
2114314564Sdim      if (log)
2115314564Sdim        log->Printf("CreateResultVariable() failed");
2116292932Sdim
2117314564Sdim      // CreateResultVariable() reports its own errors, so we don't do so here
2118292932Sdim
2119314564Sdim      return false;
2120292932Sdim    }
2121314564Sdim  }
2122292932Sdim
2123314564Sdim  if (log && log->GetVerbose()) {
2124314564Sdim    std::string s;
2125314564Sdim    raw_string_ostream oss(s);
2126292932Sdim
2127314564Sdim    m_module->print(oss, NULL);
2128292932Sdim
2129314564Sdim    oss.flush();
2130292932Sdim
2131314564Sdim    log->Printf("Module after creating the result variable: \n\"%s\"",
2132314564Sdim                s.c_str());
2133314564Sdim  }
2134292932Sdim
2135314564Sdim  for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe;
2136314564Sdim       ++fi) {
2137314564Sdim    llvm::Function *function = &*fi;
2138292932Sdim
2139314564Sdim    if (function->begin() == function->end())
2140314564Sdim      continue;
2141292932Sdim
2142314564Sdim    Function::iterator bbi;
2143292932Sdim
2144314564Sdim    for (bbi = function->begin(); bbi != function->end(); ++bbi) {
2145314564Sdim      if (!RemoveGuards(*bbi)) {
2146314564Sdim        if (log)
2147314564Sdim          log->Printf("RemoveGuards() failed");
2148292932Sdim
2149314564Sdim        // RemoveGuards() reports its own errors, so we don't do so here
2150292932Sdim
2151314564Sdim        return false;
2152314564Sdim      }
2153292932Sdim
2154314564Sdim      if (!RewritePersistentAllocs(*bbi)) {
2155314564Sdim        if (log)
2156314564Sdim          log->Printf("RewritePersistentAllocs() failed");
2157292932Sdim
2158314564Sdim        // RewritePersistentAllocs() reports its own errors, so we don't do so
2159314564Sdim        // here
2160292932Sdim
2161314564Sdim        return false;
2162314564Sdim      }
2163292932Sdim
2164314564Sdim      if (!RemoveCXAAtExit(*bbi)) {
2165314564Sdim        if (log)
2166314564Sdim          log->Printf("RemoveCXAAtExit() failed");
2167292932Sdim
2168314564Sdim        // RemoveCXAAtExit() reports its own errors, so we don't do so here
2169292932Sdim
2170314564Sdim        return false;
2171314564Sdim      }
2172292932Sdim    }
2173314564Sdim  }
2174292932Sdim
2175314564Sdim  ///////////////////////////////////////////////////////////////////////////////
2176314564Sdim  // Fix all Objective-C constant strings to use NSStringWithCString:encoding:
2177314564Sdim  //
2178292932Sdim
2179314564Sdim  if (!RewriteObjCConstStrings()) {
2180314564Sdim    if (log)
2181314564Sdim      log->Printf("RewriteObjCConstStrings() failed");
2182314564Sdim
2183314564Sdim    // RewriteObjCConstStrings() reports its own errors, so we don't do so here
2184314564Sdim
2185314564Sdim    return false;
2186314564Sdim  }
2187314564Sdim
2188314564Sdim  for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe;
2189314564Sdim       ++fi) {
2190314564Sdim    llvm::Function *function = &*fi;
2191314564Sdim
2192314564Sdim    for (llvm::Function::iterator bbi = function->begin(),
2193314564Sdim                                  bbe = function->end();
2194314564Sdim         bbi != bbe; ++bbi) {
2195314564Sdim      if (!RewriteObjCSelectors(*bbi)) {
2196292932Sdim        if (log)
2197314564Sdim          log->Printf("RewriteObjCSelectors() failed");
2198292932Sdim
2199314564Sdim        // RewriteObjCSelectors() reports its own errors, so we don't do so here
2200292932Sdim
2201292932Sdim        return false;
2202314564Sdim      }
2203292932Sdim
2204314564Sdim      if (!RewriteObjCClassReferences(*bbi)) {
2205314564Sdim        if (log)
2206314564Sdim          log->Printf("RewriteObjCClassReferences() failed");
2207292932Sdim
2208314564Sdim        // RewriteObjCClasses() reports its own errors, so we don't do so here
2209292932Sdim
2210314564Sdim        return false;
2211314564Sdim      }
2212292932Sdim    }
2213314564Sdim  }
2214292932Sdim
2215314564Sdim  for (Module::iterator fi = m_module->begin(), fe = m_module->end(); fi != fe;
2216314564Sdim       ++fi) {
2217314564Sdim    llvm::Function *function = &*fi;
2218292932Sdim
2219314564Sdim    for (llvm::Function::iterator bbi = function->begin(),
2220314564Sdim                                  bbe = function->end();
2221314564Sdim         bbi != bbe; ++bbi) {
2222314564Sdim      if (!ResolveCalls(*bbi)) {
2223314564Sdim        if (log)
2224314564Sdim          log->Printf("ResolveCalls() failed");
2225292932Sdim
2226314564Sdim        // ResolveCalls() reports its own errors, so we don't do so here
2227292932Sdim
2228314564Sdim        return false;
2229314564Sdim      }
2230292932Sdim    }
2231314564Sdim  }
2232292932Sdim
2233314564Sdim  ////////////////////////////////////////////////////////////////////////
2234314564Sdim  // Run function-level passes that only make sense on the main function
2235314564Sdim  //
2236292932Sdim
2237314564Sdim  if (main_function) {
2238314564Sdim    if (!ResolveExternals(*main_function)) {
2239314564Sdim      if (log)
2240314564Sdim        log->Printf("ResolveExternals() failed");
2241292932Sdim
2242314564Sdim      // ResolveExternals() reports its own errors, so we don't do so here
2243292932Sdim
2244314564Sdim      return false;
2245314564Sdim    }
2246292932Sdim
2247314564Sdim    if (!ReplaceVariables(*main_function)) {
2248314564Sdim      if (log)
2249314564Sdim        log->Printf("ReplaceVariables() failed");
2250292932Sdim
2251314564Sdim      // ReplaceVariables() reports its own errors, so we don't do so here
2252292932Sdim
2253314564Sdim      return false;
2254292932Sdim    }
2255314564Sdim  }
2256292932Sdim
2257314564Sdim  if (log && log->GetVerbose()) {
2258314564Sdim    std::string s;
2259314564Sdim    raw_string_ostream oss(s);
2260292932Sdim
2261314564Sdim    m_module->print(oss, NULL);
2262292932Sdim
2263314564Sdim    oss.flush();
2264292932Sdim
2265314564Sdim    log->Printf("Module after preparing for execution: \n\"%s\"", s.c_str());
2266314564Sdim  }
2267292932Sdim
2268314564Sdim  return true;
2269292932Sdim}
2270292932Sdim
2271314564Sdimvoid IRForTarget::assignPassManager(PMStack &pass_mgr_stack,
2272314564Sdim                                    PassManagerType pass_mgr_type) {}
2273292932Sdim
2274314564SdimPassManagerType IRForTarget::getPotentialPassManagerType() const {
2275314564Sdim  return PMT_ModulePassManager;
2276292932Sdim}
2277