147dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan//===-- IRForTarget.cpp -----------------------------------------*- C++ -*-===//
25cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan//
35cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan//                     The LLVM Compiler Infrastructure
45cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan//
55cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan// This file is distributed under the University of Illinois Open Source
65cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan// License. See LICENSE.TXT for details.
75cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan//
85cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan//===----------------------------------------------------------------------===//
95cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan
105cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan#include "lldb/Expression/IRForTarget.h"
115cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan
125cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan#include "llvm/Support/raw_ostream.h"
13a80c70c22a3e25d693e1a569a5209820873d44c8Chandler Carruth#include "llvm/IR/Constants.h"
14a80c70c22a3e25d693e1a569a5209820873d44c8Chandler Carruth#include "llvm/IR/DataLayout.h"
15a80c70c22a3e25d693e1a569a5209820873d44c8Chandler Carruth#include "llvm/IR/InstrTypes.h"
16a80c70c22a3e25d693e1a569a5209820873d44c8Chandler Carruth#include "llvm/IR/Instructions.h"
17a80c70c22a3e25d693e1a569a5209820873d44c8Chandler Carruth#include "llvm/IR/Intrinsics.h"
18a80c70c22a3e25d693e1a569a5209820873d44c8Chandler Carruth#include "llvm/IR/Module.h"
1906dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan#include "llvm/PassManager.h"
2006dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan#include "llvm/Transforms/IPO.h"
21a80c70c22a3e25d693e1a569a5209820873d44c8Chandler Carruth#include "llvm/IR/ValueSymbolTable.h"
228bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan
238bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan#include "clang/AST/ASTContext.h"
245cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan
255cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan#include "lldb/Core/dwarf.h"
261cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan#include "lldb/Core/ConstString.h"
271cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan#include "lldb/Core/DataBufferHeap.h"
285cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan#include "lldb/Core/Log.h"
295cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan#include "lldb/Core/Scalar.h"
305cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan#include "lldb/Core/StreamString.h"
315cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan#include "lldb/Expression/ClangExpressionDeclMap.h"
321cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan#include "lldb/Expression/IRExecutionUnit.h"
3347dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan#include "lldb/Expression/IRInterpreter.h"
34c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan#include "lldb/Host/Endian.h"
35696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan#include "lldb/Symbol/ClangASTContext.h"
3652f792329be5db8e38961350589e97e8f2823acdGreg Clayton#include "lldb/Symbol/ClangASTType.h"
375cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan
385cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan#include <map>
395cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan
405cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callananusing namespace llvm;
415cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan
423351dacda090c21c203d2300f38e2f45d8f78f4dSean Callananstatic char ID;
433351dacda090c21c203d2300f38e2f45d8f78f4dSean Callanan
441cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean CallananIRForTarget::StaticDataAllocator::StaticDataAllocator(lldb_private::IRExecutionUnit &execution_unit) :
451cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan    m_execution_unit(execution_unit),
460f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    m_stream_string(lldb_private::Stream::eBinary, execution_unit.GetAddressByteSize(), execution_unit.GetByteOrder()),
471cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan    m_allocation(LLDB_INVALID_ADDRESS)
48c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan{
49c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan}
50c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
514a20587f56a05955ea94f650cb39245a092b0c69Sean CallananIRForTarget::FunctionValueCache::FunctionValueCache(Maker const &maker) :
524a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    m_maker(maker),
534a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    m_values()
544a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan{
554a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan}
564a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
574a20587f56a05955ea94f650cb39245a092b0c69Sean CallananIRForTarget::FunctionValueCache::~FunctionValueCache()
584a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan{
594a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan}
604a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
614a20587f56a05955ea94f650cb39245a092b0c69Sean Callananllvm::Value *IRForTarget::FunctionValueCache::GetValue(llvm::Function *function)
624a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan{
634a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    if (!m_values.count(function))
644a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    {
654a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan        llvm::Value *ret = m_maker(function);
664a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan        m_values[function] = ret;
674a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan        return ret;
684a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    }
694a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    return m_values[function];
704a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan}
714a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
721cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callananlldb::addr_t IRForTarget::StaticDataAllocator::Allocate()
73c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan{
741cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan    lldb_private::Error err;
751cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan
761cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan    if (m_allocation != LLDB_INVALID_ADDRESS)
771cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan    {
781cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan        m_execution_unit.FreeNow(m_allocation);
791cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan        m_allocation = LLDB_INVALID_ADDRESS;
801cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan    }
811cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan
821cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan    m_allocation = m_execution_unit.WriteNow((const uint8_t*)m_stream_string.GetData(), m_stream_string.GetSize(), err);
831cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan
841cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan    return m_allocation;
85c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan}
86c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
874a20587f56a05955ea94f650cb39245a092b0c69Sean Callananstatic llvm::Value *FindEntryInstruction (llvm::Function *function)
884a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan{
894a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    if (function->empty())
904a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan        return NULL;
914a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
924a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    return function->getEntryBlock().getFirstNonPHIOrDbg();
934a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan}
944a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
953c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg ClaytonIRForTarget::IRForTarget (lldb_private::ClangExpressionDeclMap *decl_map,
963c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton                          bool resolve_vars,
971cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan                          lldb_private::IRExecutionUnit &execution_unit,
9897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                          lldb_private::Stream *error_stream,
993c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton                          const char *func_name) :
10047a5c4c01066ece2d41cba56c3a065eeca12d47cSean Callanan    ModulePass(ID),
101dbeb3e1e038a75f00fd565203839020e1d00a7c6Stephen Wilson    m_resolve_vars(resolve_vars),
102dbeb3e1e038a75f00fd565203839020e1d00a7c6Stephen Wilson    m_func_name(func_name),
103c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    m_module(NULL),
1042bc9eb3ba78efc64a273729b480bafc3bbaa433aJohnny Chen    m_decl_map(decl_map),
1051cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan    m_data_allocator(execution_unit),
1066ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan    m_CFStringCreateWithBytes(NULL),
10765dafa8344c8c018e346dd331a7782081a896239Sean Callanan    m_sel_registerName(NULL),
108dbeb3e1e038a75f00fd565203839020e1d00a7c6Stephen Wilson    m_error_stream(error_stream),
109696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan    m_result_store(NULL),
110696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan    m_result_is_pointer(false),
1114a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    m_reloc_placeholder(NULL),
1124a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    m_entry_instruction_finder (FindEntryInstruction)
1135cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan{
1145cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan}
1155cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan
116771131d04344e57abb340699f54dce77a511bc71Sean Callanan/* Handy utility functions used at several places in the code */
117a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan
118a48fe1637ec6a381e500633c087f76662e364c20Sean Callananstatic std::string
1193c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg ClaytonPrintValue(const Value *value, bool truncate = false)
120a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan{
121a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    std::string s;
1226f01c93497df194b6f2194630a81e87d806ce0e0Jim Ingham    if (value)
1236f01c93497df194b6f2194630a81e87d806ce0e0Jim Ingham    {
1246f01c93497df194b6f2194630a81e87d806ce0e0Jim Ingham        raw_string_ostream rso(s);
1256f01c93497df194b6f2194630a81e87d806ce0e0Jim Ingham        value->print(rso);
1266f01c93497df194b6f2194630a81e87d806ce0e0Jim Ingham        rso.flush();
1276f01c93497df194b6f2194630a81e87d806ce0e0Jim Ingham        if (truncate)
1286f01c93497df194b6f2194630a81e87d806ce0e0Jim Ingham            s.resize(s.length() - 1);
1296f01c93497df194b6f2194630a81e87d806ce0e0Jim Ingham    }
130a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    return s;
131a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan}
132a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan
133771131d04344e57abb340699f54dce77a511bc71Sean Callananstatic std::string
13452f792329be5db8e38961350589e97e8f2823acdGreg ClaytonPrintType(const llvm::Type *type, bool truncate = false)
135771131d04344e57abb340699f54dce77a511bc71Sean Callanan{
136771131d04344e57abb340699f54dce77a511bc71Sean Callanan    std::string s;
137771131d04344e57abb340699f54dce77a511bc71Sean Callanan    raw_string_ostream rso(s);
1383c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton    type->print(rso);
139771131d04344e57abb340699f54dce77a511bc71Sean Callanan    rso.flush();
140771131d04344e57abb340699f54dce77a511bc71Sean Callanan    if (truncate)
141771131d04344e57abb340699f54dce77a511bc71Sean Callanan        s.resize(s.length() - 1);
142771131d04344e57abb340699f54dce77a511bc71Sean Callanan    return s;
143771131d04344e57abb340699f54dce77a511bc71Sean Callanan}
144771131d04344e57abb340699f54dce77a511bc71Sean Callanan
1455cf4a1ca412654c3f912e2b3cea931fb814f322fSean CallananIRForTarget::~IRForTarget()
1465cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan{
1475cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan}
1485cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan
149c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callananbool
150c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::FixFunctionLinkage(llvm::Function &llvm_function)
151c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan{
152c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    llvm_function.setLinkage(GlobalValue::ExternalLinkage);
153c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
154fecc09c3709262515add87254cb973ce5175f17bSean Callanan    std::string name = llvm_function.getName().str();
155c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
156c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    return true;
157c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan}
158c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
15982b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callananbool
1605c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean CallananIRForTarget::GetFunctionAddress (llvm::Function *fun,
1615c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan                                 uint64_t &fun_addr,
1625c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan                                 lldb_private::ConstString &name,
1635c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan                                 Constant **&value_ptr)
1645c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan{
165952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1665c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
1675c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    fun_addr = LLDB_INVALID_ADDRESS;
1685c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    name.Clear();
1695c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    value_ptr = NULL;
1705c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
1715c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    if (fun->isIntrinsic())
1725c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    {
1735c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan        Intrinsic::ID intrinsic_id = (Intrinsic::ID)fun->getIntrinsicID();
1745c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
1755c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan        switch (intrinsic_id)
1765c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan        {
1775c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan        default:
1785c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan            if (log)
1795c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan                log->Printf("Unresolved intrinsic \"%s\"", Intrinsic::getName(intrinsic_id).c_str());
1805c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
1815c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan            if (m_error_stream)
1825c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan                m_error_stream->Printf("Internal error [IRForTarget]: Call to unhandled compiler intrinsic '%s'\n", Intrinsic::getName(intrinsic_id).c_str());
1835c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
1845c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan            return false;
1855c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan        case Intrinsic::memcpy:
1865c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan            {
1875c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan                static lldb_private::ConstString g_memcpy_str ("memcpy");
1885c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan                name = g_memcpy_str;
1895c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan            }
1905c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan            break;
1917befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan        case Intrinsic::memset:
1927befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan            {
1937befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan                static lldb_private::ConstString g_memset_str ("memset");
1947befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan                name = g_memset_str;
1957befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan            }
1967befa307d354cad9ef1119429dd51032cacb1ce1Sean Callanan            break;
1975c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan        }
1985c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
1995c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan        if (log && name)
2005c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan            log->Printf("Resolved intrinsic name \"%s\"", name.GetCString());
2015c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    }
2025c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    else
2035c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    {
2045c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan        name.SetCStringWithLength (fun->getName().data(), fun->getName().size());
2055c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    }
2065c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
2075c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    // Find the address of the function.
2085c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
2095c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    clang::NamedDecl *fun_decl = DeclForGlobal (fun);
2105c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
2115c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    if (fun_decl)
2125c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    {
213c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan        if (!m_decl_map->GetFunctionInfo (fun_decl, fun_addr))
2145c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan        {
2159b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton            lldb_private::ConstString altnernate_name;
216f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton            bool found_it = m_decl_map->GetFunctionAddress (name, fun_addr);
217f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton            if (!found_it)
218f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton            {
219f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton                // Check for an alternate mangling for "std::basic_string<char>"
220f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton                // that is part of the itanium C++ name mangling scheme
221f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton                const char *name_cstr = name.GetCString();
2226f01c93497df194b6f2194630a81e87d806ce0e0Jim Ingham                if (name_cstr && strncmp(name_cstr, "_ZNKSbIcE", strlen("_ZNKSbIcE")) == 0)
223f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton                {
224f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton                    std::string alternate_mangling("_ZNKSs");
225f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton                    alternate_mangling.append (name_cstr + strlen("_ZNKSbIcE"));
2269b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton                    altnernate_name.SetCString(alternate_mangling.c_str());
2279b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton                    found_it = m_decl_map->GetFunctionAddress (altnernate_name, fun_addr);
228f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton                }
229f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton            }
2305c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
231f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton            if (!found_it)
2325c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan            {
2339b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton                lldb_private::Mangled mangled_name(name);
2349b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton                lldb_private::Mangled alt_mangled_name(altnernate_name);
2355c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan                if (log)
236f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton                {
2379b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton                    if (alt_mangled_name)
2389b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton                        log->Printf("Function \"%s\" (alternate name \"%s\") has no address",
2399b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton                                    mangled_name.GetName().GetCString(),
2409b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton                                    alt_mangled_name.GetName().GetCString());
241f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton                    else
2429b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton                        log->Printf("Function \"%s\" had no address",
2439b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton                                    mangled_name.GetName().GetCString());
244f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton                }
2455c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
2465c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan                if (m_error_stream)
247f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton                {
2489b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton                    if (alt_mangled_name)
2499b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton                        m_error_stream->Printf("error: call to a function '%s' (alternate name '%s') that is not present in the target\n",
2509b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton                                               mangled_name.GetName().GetCString(),
2519b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton                                               alt_mangled_name.GetName().GetCString());
252d9865518043af19069e10a5c56ed68551c7891adGreg Clayton                    else if (mangled_name.GetMangledName())
253d9865518043af19069e10a5c56ed68551c7891adGreg Clayton                        m_error_stream->Printf("error: call to a function '%s' ('%s') that is not present in the target\n",
254d9865518043af19069e10a5c56ed68551c7891adGreg Clayton                                               mangled_name.GetName().GetCString(),
255d9865518043af19069e10a5c56ed68551c7891adGreg Clayton                                               mangled_name.GetMangledName().GetCString());
256f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton                    else
2579b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton                        m_error_stream->Printf("error: call to a function '%s' that is not present in the target\n",
2589b98ffdf151138af70f184c8b5b0b32c8e5c3e31Greg Clayton                                               mangled_name.GetName().GetCString());
259f6a5bd78aaef0e4d477208289ace03cfa7f60649Greg Clayton                }
2605c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan                return false;
2615c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan            }
2625c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan        }
2635c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    }
2645c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    else
2655c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    {
2665c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan        if (!m_decl_map->GetFunctionAddress (name, fun_addr))
2675c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan        {
2685c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan            if (log)
2695c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan                log->Printf ("Metadataless function \"%s\" had no address", name.GetCString());
2705c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
2715c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan            if (m_error_stream)
2725c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan                m_error_stream->Printf("Error [IRForTarget]: Call to a symbol-only function '%s' that is not present in the target\n", name.GetCString());
2735c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
2745c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan            return false;
2755c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan        }
2765c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    }
2775c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
2785c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    if (log)
2795f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea        log->Printf("Found \"%s\" at 0x%" PRIx64, name.GetCString(), fun_addr);
2805c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
2815c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    return true;
2825c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan}
2835c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
2845c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callananllvm::Constant *
2855c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean CallananIRForTarget::BuildFunctionPointer (llvm::Type *type,
2865c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan                                   uint64_t ptr)
2875c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan{
2885c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(),
2894fbe61ba371bfde827b9424ebe5e14dce3d5fad3Sean Callanan                                             (m_module->getPointerSize() == Module::Pointer64) ? 64 : 32);
2905c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    PointerType *fun_ptr_ty = PointerType::getUnqual(type);
2915c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    Constant *fun_addr_int = ConstantInt::get(intptr_ty, ptr, false);
2925c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    return ConstantExpr::getIntToPtr(fun_addr_int, fun_ptr_ty);
2935c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan}
2945c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
295715f6b0843d0099761464f05e4f899cb69e63320Sean Callananvoid
296715f6b0843d0099761464f05e4f899cb69e63320Sean CallananIRForTarget::RegisterFunctionMetadata(LLVMContext &context,
297715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan                                      llvm::Value *function_ptr,
298715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan                                      const char *name)
299715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan{
300715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan    for (Value::use_iterator i = function_ptr->use_begin(), e = function_ptr->use_end();
301715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan         i != e;
302715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan         ++i)
303715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan    {
304715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan        Value *user = *i;
305715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan
306715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan        if (Instruction *user_inst = dyn_cast<Instruction>(user))
307715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan        {
308804930f1d6f0b79f837acadf76b9d7b75cd412cdDaniel Malea            MDString* md_name = MDString::get(context, StringRef(name));
309804930f1d6f0b79f837acadf76b9d7b75cd412cdDaniel Malea
310804930f1d6f0b79f837acadf76b9d7b75cd412cdDaniel Malea            MDNode *metadata = MDNode::get(context, md_name);
311804930f1d6f0b79f837acadf76b9d7b75cd412cdDaniel Malea
312715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan            user_inst->setMetadata("lldb.call.realName", metadata);
313715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan        }
314715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan        else
315715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan        {
316715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan            RegisterFunctionMetadata (context, user, name);
317715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan        }
318715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan    }
319715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan}
320715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan
3215c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callananbool
3224a20587f56a05955ea94f650cb39245a092b0c69Sean CallananIRForTarget::ResolveFunctionPointers(llvm::Module &llvm_module)
3235c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan{
324952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
3255c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
3265c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    for (llvm::Module::iterator fi = llvm_module.begin();
3275c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan         fi != llvm_module.end();
3285c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan         ++fi)
3295c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    {
3305c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan        Function *fun = fi;
3315c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
3325c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan        bool is_decl = fun->isDeclaration();
3335c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
3345c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan        if (log)
335fecc09c3709262515add87254cb973ce5175f17bSean Callanan            log->Printf("Examining %s function %s", (is_decl ? "declaration" : "non-declaration"), fun->getName().str().c_str());
3365c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
3375c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan        if (!is_decl)
3385c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan            continue;
3395c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
3405c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan        if (fun->hasNUses(0))
3415c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan            continue; // ignore
3425c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
3435c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan        uint64_t addr = LLDB_INVALID_ADDRESS;
3445c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan        lldb_private::ConstString name;
3455c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan        Constant **value_ptr = NULL;
3465c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
3475c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan        if (!GetFunctionAddress(fun,
3485c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan                                addr,
3495c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan                                name,
3505c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan                                value_ptr))
3515c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan            return false; // GetFunctionAddress reports its own errors
3525c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
3535c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan        Constant *value = BuildFunctionPointer(fun->getFunctionType(), addr);
3545c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
355715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan        RegisterFunctionMetadata (llvm_module.getContext(), fun, name.AsCString());
356715f6b0843d0099761464f05e4f899cb69e63320Sean Callanan
3575c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan        if (value_ptr)
3585c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan            *value_ptr = value;
359eebd175a054e833c928462a91d7cb07c65b5e09dStefanus Du Toit
360eebd175a054e833c928462a91d7cb07c65b5e09dStefanus Du Toit        // If we are replacing a function with the nobuiltin attribute, it may
361eebd175a054e833c928462a91d7cb07c65b5e09dStefanus Du Toit        // be called with the builtin attribute on call sites. Remove any such
362eebd175a054e833c928462a91d7cb07c65b5e09dStefanus Du Toit        // attributes since it's illegal to have a builtin call to something
363eebd175a054e833c928462a91d7cb07c65b5e09dStefanus Du Toit        // other than a nobuiltin function.
364eebd175a054e833c928462a91d7cb07c65b5e09dStefanus Du Toit        if (fun->hasFnAttribute(Attribute::NoBuiltin)) {
365eebd175a054e833c928462a91d7cb07c65b5e09dStefanus Du Toit            Attribute builtin = Attribute::get(fun->getContext(), Attribute::Builtin);
366eebd175a054e833c928462a91d7cb07c65b5e09dStefanus Du Toit
367eebd175a054e833c928462a91d7cb07c65b5e09dStefanus Du Toit            for (auto u = fun->use_begin(), e = fun->use_end(); u != e; ++u) {
368eebd175a054e833c928462a91d7cb07c65b5e09dStefanus Du Toit                if (auto call = dyn_cast<CallInst>(*u)) {
369eebd175a054e833c928462a91d7cb07c65b5e09dStefanus Du Toit                    call->removeAttribute(AttributeSet::FunctionIndex, builtin);
370eebd175a054e833c928462a91d7cb07c65b5e09dStefanus Du Toit                }
371eebd175a054e833c928462a91d7cb07c65b5e09dStefanus Du Toit            }
372eebd175a054e833c928462a91d7cb07c65b5e09dStefanus Du Toit        }
3735c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
3745c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan        fun->replaceAllUsesWith(value);
3755c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    }
3765c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
3775c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    return true;
3785c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan}
3795c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
38047dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
381696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callananclang::NamedDecl *
38247dc457387b690c5e4df1c0c7dd8c4337b92e630Sean CallananIRForTarget::DeclForGlobal (const GlobalValue *global_val, Module *module)
383696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan{
38447dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    NamedMDNode *named_metadata = module->getNamedMetadata("clang.global.decl.ptrs");
385696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan
386696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan    if (!named_metadata)
387696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan        return NULL;
388696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan
389696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan    unsigned num_nodes = named_metadata->getNumOperands();
390696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan    unsigned node_index;
391696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan
392696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan    for (node_index = 0;
393696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan         node_index < num_nodes;
394696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan         ++node_index)
395696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan    {
396696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan        MDNode *metadata_node = named_metadata->getOperand(node_index);
397696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan
398696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan        if (!metadata_node)
399696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan            return NULL;
400696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan
401696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan        if (metadata_node->getNumOperands() != 2)
402696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan            continue;
403696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan
404696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan        if (metadata_node->getOperand(0) != global_val)
405696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan            continue;
406696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan
407696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan        ConstantInt *constant_int = dyn_cast<ConstantInt>(metadata_node->getOperand(1));
408696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan
409696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan        if (!constant_int)
410696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan            return NULL;
411696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan
412696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan        uintptr_t ptr = constant_int->getZExtValue();
413696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan
414696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan        return reinterpret_cast<clang::NamedDecl *>(ptr);
415696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan    }
416696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan
417696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan    return NULL;
418696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan}
419696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan
42047dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callananclang::NamedDecl *
42147dc457387b690c5e4df1c0c7dd8c4337b92e630Sean CallananIRForTarget::DeclForGlobal (GlobalValue *global_val)
42247dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan{
42347dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan    return DeclForGlobal(global_val, m_module);
42447dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan}
42547dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
42605a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callananbool
427c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::CreateResultVariable (llvm::Function &llvm_function)
42882b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan{
429952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
43082b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan
431e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan    if (!m_resolve_vars)
432e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan        return true;
433e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan
434e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan    // Find the result variable.  If it doesn't exist, we can give up right here.
43582b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan
436c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    ValueSymbolTable& value_symbol_table = m_module->getValueSymbolTable();
4373c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
4389b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan    std::string result_name_str;
4393c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    const char *result_name = NULL;
4403c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
4413c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    for (ValueSymbolTable::iterator vi = value_symbol_table.begin(), ve = value_symbol_table.end();
4423c9c5eb466869ede185e879d14a47335fb43194dSean Callanan         vi != ve;
4433c9c5eb466869ede185e879d14a47335fb43194dSean Callanan         ++vi)
4443c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    {
4459b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan        result_name_str = vi->first().str();
4469b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan        const char *value_name = result_name_str.c_str();
4479b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan
4489b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan        if (strstr(value_name, "$__lldb_expr_result_ptr") &&
449880b2ca643dd4a03a1a7b8113239cfa6006ed382Sean Callanan            strncmp(value_name, "_ZGV", 4))
4506a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan        {
4519b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan            result_name = value_name;
4526a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan            m_result_is_pointer = true;
4536a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan            break;
4546a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan        }
4556a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan
4569b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan        if (strstr(value_name, "$__lldb_expr_result") &&
457880b2ca643dd4a03a1a7b8113239cfa6006ed382Sean Callanan            strncmp(value_name, "_ZGV", 4))
458c04743d68391ae090e6ebada32b6fb87cdc03d30Sean Callanan        {
4599b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan            result_name = value_name;
4606a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan            m_result_is_pointer = false;
461c04743d68391ae090e6ebada32b6fb87cdc03d30Sean Callanan            break;
462c04743d68391ae090e6ebada32b6fb87cdc03d30Sean Callanan        }
4633c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    }
4643c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
4653c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    if (!result_name)
46682b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    {
46782b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan        if (log)
46882b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan            log->PutCString("Couldn't find result variable");
4693c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
470e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan        return true;
47182b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    }
4723c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
473c04743d68391ae090e6ebada32b6fb87cdc03d30Sean Callanan    if (log)
474b5037af312160b2f396aad579e45619af3126e4aGreg Clayton        log->Printf("Result name: \"%s\"", result_name);
475c04743d68391ae090e6ebada32b6fb87cdc03d30Sean Callanan
476c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    Value *result_value = m_module->getNamedValue(result_name);
4773c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
4783c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    if (!result_value)
4793c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    {
4803c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        if (log)
4813c9c5eb466869ede185e879d14a47335fb43194dSean Callanan            log->PutCString("Result variable had no data");
4826a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan
48397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan        if (m_error_stream)
48497c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan            m_error_stream->Printf("Internal error [IRForTarget]: Result variable's name (%s) exists, but not its definition\n", result_name);
48597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
4863c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        return false;
4873c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    }
488e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan
48982b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    if (log)
490b5037af312160b2f396aad579e45619af3126e4aGreg Clayton        log->Printf("Found result in the IR: \"%s\"", PrintValue(result_value, false).c_str());
49182b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan
49282b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    GlobalVariable *result_global = dyn_cast<GlobalVariable>(result_value);
49382b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan
49482b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    if (!result_global)
49582b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    {
49682b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan        if (log)
49782b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan            log->PutCString("Result variable isn't a GlobalVariable");
49897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
49997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan        if (m_error_stream)
50097c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan            m_error_stream->Printf("Internal error [IRForTarget]: Result variable (%s) is defined, but is not a global variable\n", result_name);
50197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
50282b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan        return false;
50382b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    }
50482b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan
505c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    clang::NamedDecl *result_decl = DeclForGlobal (result_global);
506696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan    if (!result_decl)
50782b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    {
50882b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan        if (log)
509696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan            log->PutCString("Result variable doesn't have a corresponding Decl");
51082b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan
51197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan        if (m_error_stream)
512696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan            m_error_stream->Printf("Internal error [IRForTarget]: Result variable (%s) does not have a corresponding Clang entity\n", result_name);
51397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
51482b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan        return false;
51582b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    }
51682b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan
517696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan    if (log)
51882b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    {
519696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan        std::string decl_desc_str;
520696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan        raw_string_ostream decl_desc_stream(decl_desc_str);
521696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan        result_decl->print(decl_desc_stream);
522696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan        decl_desc_stream.flush();
52382b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan
524696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan        log->Printf("Found result decl: \"%s\"", decl_desc_str.c_str());
52582b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    }
52682b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan
527696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan    clang::VarDecl *result_var = dyn_cast<clang::VarDecl>(result_decl);
528696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan    if (!result_var)
52982b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    {
53082b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan        if (log)
531696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan            log->PutCString("Result variable Decl isn't a VarDecl");
53297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
53397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan        if (m_error_stream)
534696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan            m_error_stream->Printf("Internal error [IRForTarget]: Result variable (%s)'s corresponding Clang entity isn't a variable\n", result_name);
53597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
53682b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan        return false;
53782b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    }
53882b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan
53982b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    // Get the next available result name from m_decl_map and create the persistent
54082b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    // variable for it
54147dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan
542696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan    // If the result is an Lvalue, it is emitted as a pointer; see
543696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan    // ASTResultSynthesizer::SynthesizeBodyResult.
5446a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan    if (m_result_is_pointer)
5456a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan    {
546696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan        clang::QualType pointer_qual_type = result_var->getType();
547d5b3c351ea23e8e36d47056e50b1df773ae9050aSean Callanan        const clang::Type *pointer_type = pointer_qual_type.getTypePtr();
5484fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan
54921f2e192079b6aa9ddd2d25283e19abdb38eeeb5Sean Callanan        const clang::PointerType *pointer_pointertype = pointer_type->getAs<clang::PointerType>();
55021f2e192079b6aa9ddd2d25283e19abdb38eeeb5Sean Callanan        const clang::ObjCObjectPointerType *pointer_objcobjpointertype = pointer_type->getAs<clang::ObjCObjectPointerType>();
5516a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan
5524fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan        if (pointer_pointertype)
5534fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan        {
5544fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan            clang::QualType element_qual_type = pointer_pointertype->getPointeeType();
5554fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan
5564fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan            m_result_type = lldb_private::TypeFromParser(element_qual_type.getAsOpaquePtr(),
5574fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan                                                         &result_decl->getASTContext());
5584fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan        }
5594fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan        else if (pointer_objcobjpointertype)
5604fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan        {
5614fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan            clang::QualType element_qual_type = clang::QualType(pointer_objcobjpointertype->getObjectType(), 0);
5624fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan
5634fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan            m_result_type = lldb_private::TypeFromParser(element_qual_type.getAsOpaquePtr(),
5644fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan                                                         &result_decl->getASTContext());
5654fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan        }
5664fdf795b4e9ea643fcafc7fe117a76ad48e021e4Sean Callanan        else
5676a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan        {
5686a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan            if (log)
5696a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan                log->PutCString("Expected result to have pointer type, but it did not");
57097c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
57197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan            if (m_error_stream)
57297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                m_error_stream->Printf("Internal error [IRForTarget]: Lvalue result (%s) is not a pointer variable\n", result_name);
57397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
5746a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan            return false;
5756a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan        }
5766a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan    }
5776a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan    else
5786a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan    {
57947dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        m_result_type = lldb_private::TypeFromParser(result_var->getType().getAsOpaquePtr(),
5805a55c7a90100e2ed832c35955645bf146e8a66b7Sean Callanan                                                     &result_decl->getASTContext());
5815a55c7a90100e2ed832c35955645bf146e8a66b7Sean Callanan    }
5825a55c7a90100e2ed832c35955645bf146e8a66b7Sean Callanan
58352f792329be5db8e38961350589e97e8f2823acdGreg Clayton    if (m_result_type.GetBitSize() == 0)
5845a55c7a90100e2ed832c35955645bf146e8a66b7Sean Callanan    {
5855a55c7a90100e2ed832c35955645bf146e8a66b7Sean Callanan        lldb_private::StreamString type_desc_stream;
5865a55c7a90100e2ed832c35955645bf146e8a66b7Sean Callanan        m_result_type.DumpTypeDescription(&type_desc_stream);
5875a55c7a90100e2ed832c35955645bf146e8a66b7Sean Callanan
5885a55c7a90100e2ed832c35955645bf146e8a66b7Sean Callanan        if (log)
5895a55c7a90100e2ed832c35955645bf146e8a66b7Sean Callanan            log->Printf("Result type has size 0");
5905a55c7a90100e2ed832c35955645bf146e8a66b7Sean Callanan
5915a55c7a90100e2ed832c35955645bf146e8a66b7Sean Callanan        if (m_error_stream)
592b6f9ee73d2abe30242e37e6e0436b4998c35c888Sean Callanan            m_error_stream->Printf("Error [IRForTarget]: Size of result type '%s' couldn't be determined\n",
5935a55c7a90100e2ed832c35955645bf146e8a66b7Sean Callanan                                   type_desc_stream.GetData());
594b6f9ee73d2abe30242e37e6e0436b4998c35c888Sean Callanan        return false;
5956a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan    }
5966a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan
597696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan    if (log)
598696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan    {
599696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan        lldb_private::StreamString type_desc_stream;
60047dc457387b690c5e4df1c0c7dd8c4337b92e630Sean Callanan        m_result_type.DumpTypeDescription(&type_desc_stream);
601696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan
6025a55c7a90100e2ed832c35955645bf146e8a66b7Sean Callanan        log->Printf("Result decl type: \"%s\"", type_desc_stream.GetData());
603696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan    }
604696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan
6050f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    m_result_name = lldb_private::ConstString("$RESULT_NAME");
60682b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan
60782b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    if (log)
608fe6dc6e241c52822710380cec0931351a1d7b2d3Greg Clayton        log->Printf("Creating a new result global: \"%s\" with size 0x%" PRIx64,
6095a55c7a90100e2ed832c35955645bf146e8a66b7Sean Callanan                    m_result_name.GetCString(),
61052f792329be5db8e38961350589e97e8f2823acdGreg Clayton                    m_result_type.GetByteSize());
61182b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan
61282b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    // Construct a new result global and set up its metadata
61382b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan
614c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    GlobalVariable *new_result_global = new GlobalVariable((*m_module),
61582b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan                                                           result_global->getType()->getElementType(),
61682b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan                                                           false, /* not constant */
61782b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan                                                           GlobalValue::ExternalLinkage,
61882b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan                                                           NULL, /* no initializer */
6196a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan                                                           m_result_name.GetCString ());
62082b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan
62182b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    // It's too late in compilation to create a new VarDecl for this, but we don't
62282b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    // need to.  We point the metadata at the old VarDecl.  This creates an odd
62382b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    // anomaly: a variable with a Value whose name is something like $0 and a
6248de27c761a22187ef63fb60000894be163e7285fGreg Clayton    // Decl whose name is $__lldb_expr_result.  This condition is handled in
62582b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    // ClangExpressionDeclMap::DoMaterialize, and the name of the variable is
62682b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    // fixed up.
62782b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan
628c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    ConstantInt *new_constant_int = ConstantInt::get(llvm::Type::getInt64Ty(m_module->getContext()),
629696cf5f6f2a77b87a4b06cdf0f697749b494665fSean Callanan                                                     reinterpret_cast<uint64_t>(result_decl),
63082b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan                                                     false);
63182b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan
63282b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    llvm::Value* values[2];
63382b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    values[0] = new_result_global;
63482b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    values[1] = new_constant_int;
63582b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan
6360de254aaec7d6766379191e5397ec2294042c5d7Sean Callanan    ArrayRef<Value*> value_ref(values, 2);
6370de254aaec7d6766379191e5397ec2294042c5d7Sean Callanan
638c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
639c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    NamedMDNode *named_metadata = m_module->getNamedMetadata("clang.global.decl.ptrs");
64082b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    named_metadata->addOperand(persistent_global_md);
64182b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan
64282b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    if (log)
643b5037af312160b2f396aad579e45619af3126e4aGreg Clayton        log->Printf("Replacing \"%s\" with \"%s\"",
6442e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan                    PrintValue(result_global).c_str(),
64582b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan                    PrintValue(new_result_global).c_str());
6462e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan
6472e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan    if (result_global->hasNUses(0))
6482e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan    {
6492e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan        // We need to synthesize a store for this variable, because otherwise
6502e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan        // there's nothing to put into its equivalent persistent variable.
6512e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan
6528de27c761a22187ef63fb60000894be163e7285fGreg Clayton        BasicBlock &entry_block(llvm_function.getEntryBlock());
6532e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan        Instruction *first_entry_instruction(entry_block.getFirstNonPHIOrDbg());
6542e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan
6552e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan        if (!first_entry_instruction)
6562e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan            return false;
6572e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan
6582e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan        if (!result_global->hasInitializer())
6592e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan        {
6602e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan            if (log)
6612e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan                log->Printf("Couldn't find initializer for unused variable");
66297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
66397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan            if (m_error_stream)
66497c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                m_error_stream->Printf("Internal error [IRForTarget]: Result variable (%s) has no writes and no initializer\n", result_name);
66597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
6662e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan            return false;
6672e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan        }
6682e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan
6692e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan        Constant *initializer = result_global->getInitializer();
67005a5a1bcbed5c0f31fed29153bb2912d71836e91Sean Callanan
6712c344ca60ed19b1284633f795c4dc52245bd8f67Greg Clayton        StoreInst *synthesized_store = new StoreInst(initializer,
6722c344ca60ed19b1284633f795c4dc52245bd8f67Greg Clayton                                                     new_result_global,
6732c344ca60ed19b1284633f795c4dc52245bd8f67Greg Clayton                                                     first_entry_instruction);
6742e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan
6752e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan        if (log)
676b5037af312160b2f396aad579e45619af3126e4aGreg Clayton            log->Printf("Synthesized result store \"%s\"\n", PrintValue(synthesized_store).c_str());
6772e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan    }
6782e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan    else
6792e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan    {
6802e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan        result_global->replaceAllUsesWith(new_result_global);
6812e2db5334f535faa440eb4c6c700b80abf3f99fbSean Callanan    }
68282b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan
6830f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan    if (!m_decl_map->AddPersistentVariable(result_decl,
6840f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                           m_result_name,
6850f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                           m_result_type,
6860f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                           true,
6870f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan                                           m_result_is_pointer))
6880f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan        return false;
6890f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
69082b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    result_global->eraseFromParent();
69182b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan
69282b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    return true;
69382b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan}
69482b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan
69558021ccb9087a5199bb6af0fbdb9ab429d4f9acaJohnny Chen#if 0
696952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Claytonstatic void DebugUsers(Log *log, Value *value, uint8_t depth)
6976ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan{
6986ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan    if (!depth)
6996ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        return;
7006ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
7016ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan    depth--;
7026ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
70358021ccb9087a5199bb6af0fbdb9ab429d4f9acaJohnny Chen    if (log)
70458021ccb9087a5199bb6af0fbdb9ab429d4f9acaJohnny Chen        log->Printf("  <Begin %d users>", value->getNumUses());
7056ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
7063c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton    for (Value::use_iterator ui = value->use_begin(), ue = value->use_end();
7076ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan         ui != ue;
7086ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan         ++ui)
7096ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan    {
71058021ccb9087a5199bb6af0fbdb9ab429d4f9acaJohnny Chen        if (log)
71158021ccb9087a5199bb6af0fbdb9ab429d4f9acaJohnny Chen            log->Printf("  <Use %p> %s", *ui, PrintValue(*ui).c_str());
7126ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        DebugUsers(log, *ui, depth);
7136ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan    }
7146ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
71558021ccb9087a5199bb6af0fbdb9ab429d4f9acaJohnny Chen    if (log)
71658021ccb9087a5199bb6af0fbdb9ab429d4f9acaJohnny Chen        log->Printf("  <End uses>");
7176ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan}
71858021ccb9087a5199bb6af0fbdb9ab429d4f9acaJohnny Chen#endif
7196ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
7204a20587f56a05955ea94f650cb39245a092b0c69Sean Callananbool
721c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::RewriteObjCConstString (llvm::GlobalVariable *ns_str,
7224a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                                     llvm::GlobalVariable *cstr)
7236ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan{
724952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
7256ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
7269b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan    Type *ns_str_ty = ns_str->getType();
727c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
7289b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan    Type *i8_ptr_ty = Type::getInt8PtrTy(m_module->getContext());
7299b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan    IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(),
7304fbe61ba371bfde827b9424ebe5e14dce3d5fad3Sean Callanan                                                   (m_module->getPointerSize()
731ce6335881f330581f641ef808602cac192664adfMicah Villmow                                                    == Module::Pointer64) ? 64 : 32);
7329b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan    Type *i32_ty = Type::getInt32Ty(m_module->getContext());
7339b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan    Type *i8_ty = Type::getInt8Ty(m_module->getContext());
7346ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
7356ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan    if (!m_CFStringCreateWithBytes)
7366ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan    {
7376ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        lldb::addr_t CFStringCreateWithBytes_addr;
7386ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
7396ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        static lldb_private::ConstString g_CFStringCreateWithBytes_str ("CFStringCreateWithBytes");
7406ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
7416ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        if (!m_decl_map->GetFunctionAddress (g_CFStringCreateWithBytes_str, CFStringCreateWithBytes_addr))
7426ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        {
7436ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            if (log)
7446ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                log->PutCString("Couldn't find CFStringCreateWithBytes in the target");
7456ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
74697c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan            if (m_error_stream)
74797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                m_error_stream->Printf("Error [IRForTarget]: Rewriting an Objective-C constant string requires CFStringCreateWithBytes\n");
74897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
7496ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            return false;
7506ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        }
7516ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
7526ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        if (log)
7535f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea            log->Printf("Found CFStringCreateWithBytes at 0x%" PRIx64, CFStringCreateWithBytes_addr);
7546ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
7556ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        // Build the function type:
7566ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        //
7576ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        // CFStringRef CFStringCreateWithBytes (
7586ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        //   CFAllocatorRef alloc,
7596ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        //   const UInt8 *bytes,
7606ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        //   CFIndex numBytes,
7616ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        //   CFStringEncoding encoding,
7626ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        //   Boolean isExternalRepresentation
7636ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        // );
7646ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        //
7656ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        // We make the following substitutions:
7666ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        //
7676ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        // CFStringRef -> i8*
7686ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        // CFAllocatorRef -> i8*
7696ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        // UInt8 * -> i8*
7706ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        // CFIndex -> long (i32 or i64, as appropriate; we ask the module for its pointer size for now)
7716ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        // CFStringEncoding -> i32
7726ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        // Boolean -> i8
7736ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
7749b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan        Type *arg_type_array[5];
7759b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan
7769b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan        arg_type_array[0] = i8_ptr_ty;
7779b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan        arg_type_array[1] = i8_ptr_ty;
7789b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan        arg_type_array[2] = intptr_ty;
7799b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan        arg_type_array[3] = i32_ty;
7809b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan        arg_type_array[4] = i8_ty;
7819b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan
7829b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan        ArrayRef<Type *> CFSCWB_arg_types(arg_type_array, 5);
7839b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan
784c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        llvm::Type *CFSCWB_ty = FunctionType::get(ns_str_ty, CFSCWB_arg_types, false);
7856ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
7866ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        // Build the constant containing the pointer to the function
7876ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        PointerType *CFSCWB_ptr_ty = PointerType::getUnqual(CFSCWB_ty);
7886ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        Constant *CFSCWB_addr_int = ConstantInt::get(intptr_ty, CFStringCreateWithBytes_addr, false);
7896ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        m_CFStringCreateWithBytes = ConstantExpr::getIntToPtr(CFSCWB_addr_int, CFSCWB_ptr_ty);
7906ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan    }
7916ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
79239a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan    ConstantDataSequential *string_array = NULL;
7930ece52676ccd90f23ad42b72788e4b439a43b31bSean Callanan
7940ece52676ccd90f23ad42b72788e4b439a43b31bSean Callanan    if (cstr)
79539a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan        string_array = dyn_cast<ConstantDataSequential>(cstr->getInitializer());
7969b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan
7976ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan    Constant *alloc_arg         = Constant::getNullValue(i8_ptr_ty);
7980ece52676ccd90f23ad42b72788e4b439a43b31bSean Callanan    Constant *bytes_arg         = cstr ? ConstantExpr::getBitCast(cstr, i8_ptr_ty) : Constant::getNullValue(i8_ptr_ty);
79939a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan    Constant *numBytes_arg      = ConstantInt::get(intptr_ty, cstr ? string_array->getNumElements() - 1 : 0, false);
8006ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan    Constant *encoding_arg      = ConstantInt::get(i32_ty, 0x0600, false); /* 0x0600 is kCFStringEncodingASCII */
8016ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan    Constant *isExternal_arg    = ConstantInt::get(i8_ty, 0x0, false); /* 0x0 is false */
8026ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
8039b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan    Value *argument_array[5];
8049b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan
8059b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan    argument_array[0] = alloc_arg;
8069b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan    argument_array[1] = bytes_arg;
8079b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan    argument_array[2] = numBytes_arg;
8089b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan    argument_array[3] = encoding_arg;
8099b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan    argument_array[4] = isExternal_arg;
8109b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan
8119b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan    ArrayRef <Value *> CFSCWB_arguments(argument_array, 5);
8126ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
8134a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    FunctionValueCache CFSCWB_Caller ([this, &CFSCWB_arguments] (llvm::Function *function)->llvm::Value * {
8144a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan        return CallInst::Create(m_CFStringCreateWithBytes,
8154a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                                CFSCWB_arguments,
8164a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                                "CFStringCreateWithBytes",
8174a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                                llvm::cast<Instruction>(m_entry_instruction_finder.GetValue(function)));
8184a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    });
819ae71e30fe0c0e0d5fd1bf9062274798060df674cSean Callanan
8204a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    if (!UnfoldConstant(ns_str, CFSCWB_Caller, m_entry_instruction_finder))
8216ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan    {
8226ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        if (log)
8236ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            log->PutCString("Couldn't replace the NSString with the result of the call");
8246ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
82597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan        if (m_error_stream)
82697c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan            m_error_stream->Printf("Error [IRForTarget]: Couldn't replace an Objective-C constant string with a dynamic string\n");
82797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
8286ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        return false;
8296ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan    }
8306ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
8313c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton    ns_str->eraseFromParent();
8326ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
8336ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan    return true;
8346ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan}
8356ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
8366ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callananbool
8374a20587f56a05955ea94f650cb39245a092b0c69Sean CallananIRForTarget::RewriteObjCConstStrings()
8386ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan{
839952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
8406ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
841c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    ValueSymbolTable& value_symbol_table = m_module->getValueSymbolTable();
8426ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
8436ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan    for (ValueSymbolTable::iterator vi = value_symbol_table.begin(), ve = value_symbol_table.end();
8446ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan         vi != ve;
8456ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan         ++vi)
8466ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan    {
8479b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan        std::string value_name = vi->first().str();
8489b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan        const char *value_name_cstr = value_name.c_str();
8499b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan
8509b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan        if (strstr(value_name_cstr, "_unnamed_cfstring_"))
8516ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        {
8526ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            Value *nsstring_value = vi->second;
8536ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
8546ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            GlobalVariable *nsstring_global = dyn_cast<GlobalVariable>(nsstring_value);
8556ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
8566ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            if (!nsstring_global)
8576ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            {
8586ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                if (log)
8596ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                    log->PutCString("NSString variable is not a GlobalVariable");
86097c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
86197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                if (m_error_stream)
86297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                    m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string is not a global variable\n");
86397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
8646ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                return false;
8656ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            }
8666ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
8676ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            if (!nsstring_global->hasInitializer())
8686ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            {
8696ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                if (log)
8706ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                    log->PutCString("NSString variable does not have an initializer");
87197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
87297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                if (m_error_stream)
87397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                    m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string does not have an initializer\n");
87497c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
8756ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                return false;
8766ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            }
8776ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
8786ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            ConstantStruct *nsstring_struct = dyn_cast<ConstantStruct>(nsstring_global->getInitializer());
8796ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
8806ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            if (!nsstring_struct)
8816ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            {
8826ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                if (log)
8836ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                    log->PutCString("NSString variable's initializer is not a ConstantStruct");
88497c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
88597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                if (m_error_stream)
88697c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                    m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string is not a structure constant\n");
88797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
8886ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                return false;
8896ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            }
8906ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
8916ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            // We expect the following structure:
8926ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            //
8936ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            // struct {
8946ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            //   int *isa;
8956ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            //   int flags;
8966ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            //   char *str;
8976ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            //   long length;
8986ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            // };
8996ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
9006ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            if (nsstring_struct->getNumOperands() != 4)
9016ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            {
9026ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                if (log)
9036ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                    log->Printf("NSString variable's initializer structure has an unexpected number of members.  Should be 4, is %d", nsstring_struct->getNumOperands());
90497c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
90597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                if (m_error_stream)
90697c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                    m_error_stream->Printf("Internal error [IRForTarget]: The struct for an Objective-C constant string is not as expected\n");
90797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
9086ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                return false;
9096ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            }
9106ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
9116ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            Constant *nsstring_member = nsstring_struct->getOperand(2);
9126ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
9136ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            if (!nsstring_member)
9146ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            {
9156ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                if (log)
9166ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                    log->PutCString("NSString initializer's str element was empty");
91797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
91897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                if (m_error_stream)
91997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                    m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string does not have a string initializer\n");
92097c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
9216ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                return false;
9226ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            }
9236ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
9246ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            ConstantExpr *nsstring_expr = dyn_cast<ConstantExpr>(nsstring_member);
9256ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
9266ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            if (!nsstring_expr)
9276ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            {
9286ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                if (log)
9296ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                    log->PutCString("NSString initializer's str element is not a ConstantExpr");
93097c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
93197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                if (m_error_stream)
93297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                    m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer is not constant\n");
93397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
9346ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                return false;
9356ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            }
9366ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
9376ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            if (nsstring_expr->getOpcode() != Instruction::GetElementPtr)
9386ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            {
9396ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                if (log)
9406ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                    log->Printf("NSString initializer's str element is not a GetElementPtr expression, it's a %s", nsstring_expr->getOpcodeName());
94197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
94297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                if (m_error_stream)
94397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                    m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer is not an array\n");
94497c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
9456ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                return false;
9466ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            }
9476ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
9486ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            Constant *nsstring_cstr = nsstring_expr->getOperand(0);
9496ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
9506ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            GlobalVariable *cstr_global = dyn_cast<GlobalVariable>(nsstring_cstr);
9516ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
9526ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            if (!cstr_global)
9536ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            {
9546ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                if (log)
9556ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                    log->PutCString("NSString initializer's str element is not a GlobalVariable");
95697c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
95797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                if (m_error_stream)
95897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                    m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer doesn't point to a global\n");
95965e2aeef29f572ead90029e21b5bc3fec5c01afeSean Callanan
9606ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                return false;
9616ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            }
9626ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
9636ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            if (!cstr_global->hasInitializer())
9646ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            {
9656ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                if (log)
9666ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                    log->PutCString("NSString initializer's str element does not have an initializer");
96797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
96897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                if (m_error_stream)
96997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                    m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer doesn't point to initialized data\n");
97097c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
9716ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                return false;
9726ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            }
9730ece52676ccd90f23ad42b72788e4b439a43b31bSean Callanan
9740ece52676ccd90f23ad42b72788e4b439a43b31bSean Callanan            /*
9756ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            if (!cstr_array)
9766ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            {
9776ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                if (log)
9786ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                    log->PutCString("NSString initializer's str element is not a ConstantArray");
97997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
98097c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                if (m_error_stream)
98197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                    m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer doesn't point to an array\n");
98297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
9836ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                return false;
9846ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            }
9856ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
9866ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            if (!cstr_array->isCString())
9876ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            {
9886ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                if (log)
9896ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                    log->PutCString("NSString initializer's str element is not a C string array");
99097c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
99197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                if (m_error_stream)
99297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                    m_error_stream->Printf("Internal error [IRForTarget]: An Objective-C constant string's string initializer doesn't point to a C string\n");
99397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
9946ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                return false;
9956ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            }
9960ece52676ccd90f23ad42b72788e4b439a43b31bSean Callanan            */
9970ece52676ccd90f23ad42b72788e4b439a43b31bSean Callanan
99839a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan            ConstantDataArray *cstr_array = dyn_cast<ConstantDataArray>(cstr_global->getInitializer());
9996ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
10006ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            if (log)
10010ece52676ccd90f23ad42b72788e4b439a43b31bSean Callanan            {
10020ece52676ccd90f23ad42b72788e4b439a43b31bSean Callanan                if (cstr_array)
100339a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan                    log->Printf("Found NSString constant %s, which contains \"%s\"", value_name_cstr, cstr_array->getAsString().str().c_str());
10040ece52676ccd90f23ad42b72788e4b439a43b31bSean Callanan                else
10059b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan                    log->Printf("Found NSString constant %s, which contains \"\"", value_name_cstr);
10060ece52676ccd90f23ad42b72788e4b439a43b31bSean Callanan            }
10070ece52676ccd90f23ad42b72788e4b439a43b31bSean Callanan
10080ece52676ccd90f23ad42b72788e4b439a43b31bSean Callanan            if (!cstr_array)
10090ece52676ccd90f23ad42b72788e4b439a43b31bSean Callanan                cstr_global = NULL;
10106ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
10114a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            if (!RewriteObjCConstString(nsstring_global, cstr_global))
101297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan            {
10136ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                if (log)
10146ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                    log->PutCString("Error rewriting the constant string");
101597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
101697c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                // We don't print an error message here because RewriteObjCConstString has done so for us.
101797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
10186ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                return false;
10196ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            }
10206ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        }
10216ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan    }
10226ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
10236ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan    for (ValueSymbolTable::iterator vi = value_symbol_table.begin(), ve = value_symbol_table.end();
10246ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan         vi != ve;
10256ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan         ++vi)
10266ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan    {
10279b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan        std::string value_name = vi->first().str();
10289b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan        const char *value_name_cstr = value_name.c_str();
10299b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan
10309b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan        if (!strcmp(value_name_cstr, "__CFConstantStringClassReference"))
10316ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        {
10326ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            GlobalVariable *gv = dyn_cast<GlobalVariable>(vi->second);
10336ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
10346ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            if (!gv)
10356ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            {
10366ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                if (log)
10376ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                    log->PutCString("__CFConstantStringClassReference is not a global variable");
103897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
103997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                if (m_error_stream)
104097c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                    m_error_stream->Printf("Internal error [IRForTarget]: Found a CFConstantStringClassReference, but it is not a global object\n");
104197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
10426ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                return false;
10436ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            }
10446ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
10456ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            gv->eraseFromParent();
10466ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
10476ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan            break;
10486ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        }
10496ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan    }
10506ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
10516ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan    return true;
10526ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan}
10536ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
10543c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Claytonstatic bool IsObjCSelectorRef (Value *value)
1055f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan{
10563c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton    GlobalVariable *global_variable = dyn_cast<GlobalVariable>(value);
1057f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
10583c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton    if (!global_variable || !global_variable->hasName() || !global_variable->getName().startswith("\01L_OBJC_SELECTOR_REFERENCES_"))
1059f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan        return false;
1060f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1061f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    return true;
1062f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan}
1063f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
106497c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan// This function does not report errors; its callers are responsible.
1065f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callananbool
1066c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::RewriteObjCSelector (Instruction* selector_load)
1067f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan{
1068952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1069f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1070f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    LoadInst *load = dyn_cast<LoadInst>(selector_load);
1071f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1072f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    if (!load)
1073f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan        return false;
1074f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1075f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    // Unpack the message name from the selector.  In LLVM IR, an objc_msgSend gets represented as
1076f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    //
1077f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    // %tmp     = load i8** @"\01L_OBJC_SELECTOR_REFERENCES_" ; <i8*>
1078f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    // %call    = call i8* (i8*, i8*, ...)* @objc_msgSend(i8* %obj, i8* %tmp, ...) ; <i8*>
1079f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    //
1080f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    // where %obj is the object pointer and %tmp is the selector.
1081f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    //
10823c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton    // @"\01L_OBJC_SELECTOR_REFERENCES_" is a pointer to a character array called @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_".
10833c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton    // @"\01L_OBJC_llvm_moduleETH_VAR_NAllvm_moduleE_" contains the string.
1084f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1085f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    // Find the pointer's initializer (a ConstantExpr with opcode GetElementPtr) and get the string from its target
1086f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1087f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    GlobalVariable *_objc_selector_references_ = dyn_cast<GlobalVariable>(load->getPointerOperand());
1088f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1089f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    if (!_objc_selector_references_ || !_objc_selector_references_->hasInitializer())
1090f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan        return false;
1091f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1092f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    Constant *osr_initializer = _objc_selector_references_->getInitializer();
1093f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1094f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    ConstantExpr *osr_initializer_expr = dyn_cast<ConstantExpr>(osr_initializer);
1095f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1096f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    if (!osr_initializer_expr || osr_initializer_expr->getOpcode() != Instruction::GetElementPtr)
1097f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan        return false;
1098f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1099f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    Value *osr_initializer_base = osr_initializer_expr->getOperand(0);
1100f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1101f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    if (!osr_initializer_base)
1102f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan        return false;
1103f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1104f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    // Find the string's initializer (a ConstantArray) and get the string from it
1105f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1106f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    GlobalVariable *_objc_meth_var_name_ = dyn_cast<GlobalVariable>(osr_initializer_base);
1107f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1108f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    if (!_objc_meth_var_name_ || !_objc_meth_var_name_->hasInitializer())
1109f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan        return false;
1110f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1111f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    Constant *omvn_initializer = _objc_meth_var_name_->getInitializer();
1112f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
111339a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan    ConstantDataArray *omvn_initializer_array = dyn_cast<ConstantDataArray>(omvn_initializer);
1114f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1115f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    if (!omvn_initializer_array->isString())
1116f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan        return false;
1117f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1118f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    std::string omvn_initializer_string = omvn_initializer_array->getAsString();
1119f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1120f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    if (log)
1121b5037af312160b2f396aad579e45619af3126e4aGreg Clayton        log->Printf("Found Objective-C selector reference \"%s\"", omvn_initializer_string.c_str());
1122f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1123f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    // Construct a call to sel_registerName
1124f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1125f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    if (!m_sel_registerName)
1126f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    {
1127b5037af312160b2f396aad579e45619af3126e4aGreg Clayton        lldb::addr_t sel_registerName_addr;
1128f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
11298de27c761a22187ef63fb60000894be163e7285fGreg Clayton        static lldb_private::ConstString g_sel_registerName_str ("sel_registerName");
1130b5037af312160b2f396aad579e45619af3126e4aGreg Clayton        if (!m_decl_map->GetFunctionAddress (g_sel_registerName_str, sel_registerName_addr))
1131f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan            return false;
1132f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1133c2c6f7781b6721e73ccf5ed842d00906ae27f191Sean Callanan        if (log)
11345f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea            log->Printf("Found sel_registerName at 0x%" PRIx64, sel_registerName_addr);
1135c2c6f7781b6721e73ccf5ed842d00906ae27f191Sean Callanan
1136f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan        // Build the function type: struct objc_selector *sel_registerName(uint8_t*)
1137f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1138f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan        // The below code would be "more correct," but in actuality what's required is uint8_t*
1139c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        //Type *sel_type = StructType::get(m_module->getContext());
1140f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan        //Type *sel_ptr_type = PointerType::getUnqual(sel_type);
11419b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan        Type *sel_ptr_type = Type::getInt8PtrTy(m_module->getContext());
11429b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan
11439b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan        Type *type_array[1];
11449b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan
11459b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan        type_array[0] = llvm::Type::getInt8PtrTy(m_module->getContext());
11469b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan
11479b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan        ArrayRef<Type *> srN_arg_types(type_array, 1);
1148f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1149f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan        llvm::Type *srN_type = FunctionType::get(sel_ptr_type, srN_arg_types, false);
1150f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1151f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan        // Build the constant containing the pointer to the function
11529b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan        IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(),
11534fbe61ba371bfde827b9424ebe5e14dce3d5fad3Sean Callanan                                                 (m_module->getPointerSize() == Module::Pointer64) ? 64 : 32);
1154f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan        PointerType *srN_ptr_ty = PointerType::getUnqual(srN_type);
1155b5037af312160b2f396aad579e45619af3126e4aGreg Clayton        Constant *srN_addr_int = ConstantInt::get(intptr_ty, sel_registerName_addr, false);
1156f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan        m_sel_registerName = ConstantExpr::getIntToPtr(srN_addr_int, srN_ptr_ty);
1157f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    }
1158f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
11599b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan    Value *argument_array[1];
11609b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan
1161c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    Constant *omvn_pointer = ConstantExpr::getBitCast(_objc_meth_var_name_, Type::getInt8PtrTy(m_module->getContext()));
1162f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
11639b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan    argument_array[0] = omvn_pointer;
1164f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
11659b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan    ArrayRef<Value *> srN_arguments(argument_array, 1);
11669b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan
1167f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    CallInst *srN_call = CallInst::Create(m_sel_registerName,
11689b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan                                          srN_arguments,
11696ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan                                          "sel_registerName",
1170f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan                                          selector_load);
1171f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1172f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    // Replace the load with the call in all users
1173f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1174f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    selector_load->replaceAllUsesWith(srN_call);
1175f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1176f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    selector_load->eraseFromParent();
1177f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1178f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    return true;
1179f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan}
1180f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1181f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callananbool
1182c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::RewriteObjCSelectors (BasicBlock &basic_block)
1183f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan{
1184952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1185f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1186f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    BasicBlock::iterator ii;
1187f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1188f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    typedef SmallVector <Instruction*, 2> InstrList;
1189f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    typedef InstrList::iterator InstrIterator;
1190f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1191f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    InstrList selector_loads;
1192f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
11933c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton    for (ii = basic_block.begin();
11943c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton         ii != basic_block.end();
1195f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan         ++ii)
1196f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    {
1197f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan        Instruction &inst = *ii;
1198f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1199f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan        if (LoadInst *load = dyn_cast<LoadInst>(&inst))
12003c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton            if (IsObjCSelectorRef(load->getPointerOperand()))
1201f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan                selector_loads.push_back(&inst);
1202f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    }
1203f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1204f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    InstrIterator iter;
1205f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1206f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    for (iter = selector_loads.begin();
1207f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan         iter != selector_loads.end();
1208f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan         ++iter)
1209f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    {
1210c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        if (!RewriteObjCSelector(*iter))
1211f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan        {
121297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan            if (m_error_stream)
121397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                m_error_stream->Printf("Internal error [IRForTarget]: Couldn't change a static reference to an Objective-C selector to a dynamic reference\n");
121497c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
12154c3fb4b50a87e6e08987096d7edacc26545f58dcEnrico Granata            if (log)
1216f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan                log->PutCString("Couldn't rewrite a reference to an Objective-C selector");
121797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
1218f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan            return false;
1219f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan        }
1220f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    }
1221f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
1222f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    return true;
1223f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan}
1224f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
122597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan// This function does not report errors; its callers are responsible.
1226a48fe1637ec6a381e500633c087f76662e364c20Sean Callananbool
1227c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::RewritePersistentAlloc (llvm::Instruction *persistent_alloc)
1228a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan{
1229952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
123097678d17ac9bcb66f7092178109271991ab16533Sean Callanan
1231a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    AllocaInst *alloc = dyn_cast<AllocaInst>(persistent_alloc);
1232a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan
1233a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    MDNode *alloc_md = alloc->getMetadata("clang.decl.ptr");
1234a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan
1235a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    if (!alloc_md || !alloc_md->getNumOperands())
1236a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan        return false;
1237a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan
1238a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    ConstantInt *constant_int = dyn_cast<ConstantInt>(alloc_md->getOperand(0));
1239a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan
1240a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    if (!constant_int)
1241a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan        return false;
1242a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan
1243a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    // We attempt to register this as a new persistent variable with the DeclMap.
1244a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan
1245a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    uintptr_t ptr = constant_int->getZExtValue();
1246a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan
124782b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    clang::VarDecl *decl = reinterpret_cast<clang::VarDecl *>(ptr);
1248a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan
124982b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    lldb_private::TypeFromParser result_decl_type (decl->getType().getAsOpaquePtr(),
125082b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan                                                   &decl->getASTContext());
125182b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan
12528de27c761a22187ef63fb60000894be163e7285fGreg Clayton    StringRef decl_name (decl->getName());
12538de27c761a22187ef63fb60000894be163e7285fGreg Clayton    lldb_private::ConstString persistent_variable_name (decl_name.data(), decl_name.size());
12546a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan    if (!m_decl_map->AddPersistentVariable(decl, persistent_variable_name, result_decl_type, false, false))
1255a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan        return false;
1256a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan
1257c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    GlobalVariable *persistent_global = new GlobalVariable((*m_module),
125897678d17ac9bcb66f7092178109271991ab16533Sean Callanan                                                           alloc->getType(),
1259a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan                                                           false, /* not constant */
1260a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan                                                           GlobalValue::ExternalLinkage,
1261a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan                                                           NULL, /* no initializer */
1262a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan                                                           alloc->getName().str().c_str());
1263a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan
1264a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    // What we're going to do here is make believe this was a regular old external
1265a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    // variable.  That means we need to make the metadata valid.
1266a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan
12672b03efefef987b2e4f8710d877b55ececc61ac9cSean Callanan    NamedMDNode *named_metadata = m_module->getOrInsertNamedMetadata("clang.global.decl.ptrs");
1268a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan
1269a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    llvm::Value* values[2];
1270a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    values[0] = persistent_global;
1271a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    values[1] = constant_int;
12720de254aaec7d6766379191e5397ec2294042c5d7Sean Callanan
12730de254aaec7d6766379191e5397ec2294042c5d7Sean Callanan    ArrayRef<llvm::Value*> value_ref(values, 2);
1274a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan
1275c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    MDNode *persistent_global_md = MDNode::get(m_module->getContext(), value_ref);
1276a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    named_metadata->addOperand(persistent_global_md);
1277a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan
127897678d17ac9bcb66f7092178109271991ab16533Sean Callanan    // Now, since the variable is a pointer variable, we will drop in a load of that
127997678d17ac9bcb66f7092178109271991ab16533Sean Callanan    // pointer variable.
128097678d17ac9bcb66f7092178109271991ab16533Sean Callanan
128197678d17ac9bcb66f7092178109271991ab16533Sean Callanan    LoadInst *persistent_load = new LoadInst (persistent_global, "", alloc);
128297678d17ac9bcb66f7092178109271991ab16533Sean Callanan
128397678d17ac9bcb66f7092178109271991ab16533Sean Callanan    if (log)
128497678d17ac9bcb66f7092178109271991ab16533Sean Callanan        log->Printf("Replacing \"%s\" with \"%s\"",
128597678d17ac9bcb66f7092178109271991ab16533Sean Callanan                    PrintValue(alloc).c_str(),
128697678d17ac9bcb66f7092178109271991ab16533Sean Callanan                    PrintValue(persistent_load).c_str());
128797678d17ac9bcb66f7092178109271991ab16533Sean Callanan
128897678d17ac9bcb66f7092178109271991ab16533Sean Callanan    alloc->replaceAllUsesWith(persistent_load);
1289a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    alloc->eraseFromParent();
1290a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan
1291a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    return true;
1292a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan}
1293a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan
1294a48fe1637ec6a381e500633c087f76662e364c20Sean Callananbool
1295c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::RewritePersistentAllocs(llvm::BasicBlock &basic_block)
1296a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan{
1297e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan    if (!m_resolve_vars)
1298e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan        return true;
1299e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan
1300952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1301a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan
1302a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    BasicBlock::iterator ii;
1303a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan
1304a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    typedef SmallVector <Instruction*, 2> InstrList;
1305a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    typedef InstrList::iterator InstrIterator;
1306a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan
1307a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    InstrList pvar_allocs;
1308a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan
13093c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton    for (ii = basic_block.begin();
13103c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton         ii != basic_block.end();
1311a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan         ++ii)
1312a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    {
1313a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan        Instruction &inst = *ii;
1314a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan
1315a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan        if (AllocaInst *alloc = dyn_cast<AllocaInst>(&inst))
1316237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan        {
1317237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan            llvm::StringRef alloc_name = alloc->getName();
1318237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan
1319237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan            if (alloc_name.startswith("$") &&
1320237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan                !alloc_name.startswith("$__lldb"))
1321237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan            {
1322237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan                if (alloc_name.find_first_of("0123456789") == 1)
1323237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan                {
1324237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan                    if (log)
1325237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan                        log->Printf("Rejecting a numeric persistent variable.");
1326237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan
132797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                    if (m_error_stream)
132897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                        m_error_stream->Printf("Error [IRForTarget]: Names starting with $0, $1, ... are reserved for use as result names\n");
132997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
1330237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan                    return false;
1331237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan                }
1332237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan
1333a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan                pvar_allocs.push_back(alloc);
1334237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan            }
1335237e47483b9a864fee7da5e2685aea06bc0748b7Sean Callanan        }
1336a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    }
1337a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan
1338a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    InstrIterator iter;
1339a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan
1340a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    for (iter = pvar_allocs.begin();
1341a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan         iter != pvar_allocs.end();
1342a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan         ++iter)
1343a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    {
1344c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        if (!RewritePersistentAlloc(*iter))
1345a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan        {
134697c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan            if (m_error_stream)
134797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                m_error_stream->Printf("Internal error [IRForTarget]: Couldn't rewrite the creation of a persistent variable\n");
134897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
13494c3fb4b50a87e6e08987096d7edacc26545f58dcEnrico Granata            if (log)
1350a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan                log->PutCString("Couldn't rewrite the creation of a persistent variable");
135197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
1352a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan            return false;
1353a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan        }
1354a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    }
1355a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan
1356a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    return true;
1357a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan}
1358a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan
1359c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callananbool
1360c7ca466fa99aea0e4e81530157bc8927682cae00Sean CallananIRForTarget::MaterializeInitializer (uint8_t *data, Constant *initializer)
1361c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan{
1362c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan    if (!initializer)
1363c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan        return true;
1364c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan
1365952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1366c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan
1367c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan    if (log && log->GetVerbose())
1368c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan        log->Printf("  MaterializeInitializer(%p, %s)", data, PrintValue(initializer).c_str());
1369c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan
1370c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan    Type *initializer_type = initializer->getType();
1371c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan
1372c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan    if (ConstantInt *int_initializer = dyn_cast<ConstantInt>(initializer))
1373c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan    {
1374c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan        memcpy (data, int_initializer->getValue().getRawData(), m_target_data->getTypeStoreSize(initializer_type));
1375c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan        return true;
1376c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan    }
137739a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan    else if (ConstantDataArray *array_initializer = dyn_cast<ConstantDataArray>(initializer))
1378c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan    {
1379c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan        if (array_initializer->isString())
1380c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan        {
1381c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan            std::string array_initializer_string = array_initializer->getAsString();
1382c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan            memcpy (data, array_initializer_string.c_str(), m_target_data->getTypeStoreSize(initializer_type));
1383c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan        }
1384c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan        else
1385c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan        {
1386c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan            ArrayType *array_initializer_type = array_initializer->getType();
1387c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan            Type *array_element_type = array_initializer_type->getElementType();
1388c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan
1389c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan            size_t element_size = m_target_data->getTypeAllocSize(array_element_type);
1390c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan
13913e11c7ec050648ba865f1d451f8cb46fd39072a8Andy Gibbs            for (unsigned i = 0; i < array_initializer->getNumOperands(); ++i)
1392c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan            {
139339a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan                Value *operand_value = array_initializer->getOperand(i);
139439a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan                Constant *operand_constant = dyn_cast<Constant>(operand_value);
139539a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan
139639a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan                if (!operand_constant)
139739a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan                    return false;
139839a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan
139939a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan                if (!MaterializeInitializer(data + (i * element_size), operand_constant))
1400c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan                    return false;
1401c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan            }
1402c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan        }
1403c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan        return true;
1404c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan    }
1405c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan    else if (ConstantStruct *struct_initializer = dyn_cast<ConstantStruct>(initializer))
1406c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan    {
1407c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan        StructType *struct_initializer_type = struct_initializer->getType();
1408c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan        const StructLayout *struct_layout = m_target_data->getStructLayout(struct_initializer_type);
1409c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan
14103e11c7ec050648ba865f1d451f8cb46fd39072a8Andy Gibbs        for (unsigned i = 0;
1411c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan             i < struct_initializer->getNumOperands();
1412c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan             ++i)
1413c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan        {
1414c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan            if (!MaterializeInitializer(data + struct_layout->getElementOffset(i), struct_initializer->getOperand(i)))
1415c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan                return false;
1416c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan        }
1417c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan        return true;
1418c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan    }
1419e2172fd8191f1f6493a4388f7082bd2f2f43d67fSean Callanan    else if (isa<ConstantAggregateZero>(initializer))
1420e2172fd8191f1f6493a4388f7082bd2f2f43d67fSean Callanan    {
1421e2172fd8191f1f6493a4388f7082bd2f2f43d67fSean Callanan        memset(data, 0, m_target_data->getTypeStoreSize(initializer_type));
1422e2172fd8191f1f6493a4388f7082bd2f2f43d67fSean Callanan        return true;
1423e2172fd8191f1f6493a4388f7082bd2f2f43d67fSean Callanan    }
1424c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan    return false;
1425c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan}
1426c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan
1427c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callananbool
1428c7ca466fa99aea0e4e81530157bc8927682cae00Sean CallananIRForTarget::MaterializeInternalVariable (GlobalVariable *global_variable)
1429c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan{
1430c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan    if (GlobalVariable::isExternalLinkage(global_variable->getLinkage()))
1431c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan        return false;
1432c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan
1433c41606fe0aeeac867d5d0b64abfe2444c5d36bf2Sean Callanan    if (global_variable == m_reloc_placeholder)
1434c41606fe0aeeac867d5d0b64abfe2444c5d36bf2Sean Callanan        return true;
1435c41606fe0aeeac867d5d0b64abfe2444c5d36bf2Sean Callanan
14361cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan    uint64_t offset = m_data_allocator.GetStream().GetSize();
1437c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan
1438c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan    llvm::Type *variable_type = global_variable->getType();
1439c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan
1440c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan    Constant *initializer = global_variable->getInitializer();
1441c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan
1442c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan    llvm::Type *initializer_type = initializer->getType();
1443c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan
1444c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan    size_t size = m_target_data->getTypeAllocSize(initializer_type);
14451d970e7a461fe31aca72acc3bbe80d0cc79f2d2bSean Callanan    size_t align = m_target_data->getPrefTypeAlignment(initializer_type);
14461d970e7a461fe31aca72acc3bbe80d0cc79f2d2bSean Callanan
14471d970e7a461fe31aca72acc3bbe80d0cc79f2d2bSean Callanan    const size_t mask = (align - 1);
14481d970e7a461fe31aca72acc3bbe80d0cc79f2d2bSean Callanan    uint64_t aligned_offset = (offset + mask) & ~mask;
14491cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan    m_data_allocator.GetStream().PutNHex8(aligned_offset - offset, 0);
14501d970e7a461fe31aca72acc3bbe80d0cc79f2d2bSean Callanan    offset = aligned_offset;
1451c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan
1452c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan    lldb_private::DataBufferHeap data(size, '\0');
1453c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan
1454c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan    if (initializer)
1455c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan        if (!MaterializeInitializer(data.GetBytes(), initializer))
1456c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan            return false;
1457c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan
14581cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan    m_data_allocator.GetStream().Write(data.GetBytes(), data.GetByteSize());
1459c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan
1460c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan    Constant *new_pointer = BuildRelocation(variable_type, offset);
1461c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan
1462c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan    global_variable->replaceAllUsesWith(new_pointer);
1463c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan
1464c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan    global_variable->eraseFromParent();
1465c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan
1466c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan    return true;
1467c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan}
1468c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan
146997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan// This function does not report errors; its callers are responsible.
14708bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callananbool
1471c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::MaybeHandleVariable (Value *llvm_value_ptr)
14725cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan{
1473952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
14744844365bea9261f6afe24508d413d80ea2400abdSean Callanan
14754844365bea9261f6afe24508d413d80ea2400abdSean Callanan    if (log)
1476b9f09a6188dc2b48bf7f5677bc1eef9a73c3fa25Sean Callanan        log->Printf("MaybeHandleVariable (%s)", PrintValue(llvm_value_ptr).c_str());
14779a8774383dc91717151f85b32f3677aef102a77aSean Callanan
14788de27c761a22187ef63fb60000894be163e7285fGreg Clayton    if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(llvm_value_ptr))
1479bc2928a7a6b973327bf10f153c3c0479bc11e4c5Sean Callanan    {
148093a4b1a8d6ad9a5d1e18a38b5ec55de5b7f6e724Sean Callanan        switch (constant_expr->getOpcode())
1481bc2928a7a6b973327bf10f153c3c0479bc11e4c5Sean Callanan        {
148293a4b1a8d6ad9a5d1e18a38b5ec55de5b7f6e724Sean Callanan        default:
148393a4b1a8d6ad9a5d1e18a38b5ec55de5b7f6e724Sean Callanan            break;
148493a4b1a8d6ad9a5d1e18a38b5ec55de5b7f6e724Sean Callanan        case Instruction::GetElementPtr:
148593a4b1a8d6ad9a5d1e18a38b5ec55de5b7f6e724Sean Callanan        case Instruction::BitCast:
1486bc2928a7a6b973327bf10f153c3c0479bc11e4c5Sean Callanan            Value *s = constant_expr->getOperand(0);
1487c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            if (!MaybeHandleVariable(s))
14884844365bea9261f6afe24508d413d80ea2400abdSean Callanan                return false;
1489bc2928a7a6b973327bf10f153c3c0479bc11e4c5Sean Callanan        }
1490bc2928a7a6b973327bf10f153c3c0479bc11e4c5Sean Callanan    }
1491f921cf530ecb96381c93a34c313e4967a6e79834Sean Callanan    else if (GlobalVariable *global_variable = dyn_cast<GlobalVariable>(llvm_value_ptr))
1492f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan    {
1493c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan        if (!GlobalValue::isExternalLinkage(global_variable->getLinkage()))
1494c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan            return MaterializeInternalVariable(global_variable);
1495c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan
1496c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        clang::NamedDecl *named_decl = DeclForGlobal(global_variable);
14978bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan
1498f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan        if (!named_decl)
1499f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan        {
15003c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton            if (IsObjCSelectorRef(llvm_value_ptr))
1501f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan                return true;
1502f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
15037cd4674d027ed726eb8830b455e95249846b7899Sean Callanan            if (!global_variable->hasExternalLinkage())
15047cd4674d027ed726eb8830b455e95249846b7899Sean Callanan                return true;
15057cd4674d027ed726eb8830b455e95249846b7899Sean Callanan
1506f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan            if (log)
1507b5037af312160b2f396aad579e45619af3126e4aGreg Clayton                log->Printf("Found global variable \"%s\" without metadata", global_variable->getName().str().c_str());
150897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
1509f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan            return false;
1510f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan        }
1511f5857a002d1e0c5fe29b8af9f9e2fe4fac0298d8Sean Callanan
15128de27c761a22187ef63fb60000894be163e7285fGreg Clayton        std::string name (named_decl->getName().str());
1513810f22d18ca8f9d31f49d79bb4b51a9f2fd96deaSean Callanan
151452f792329be5db8e38961350589e97e8f2823acdGreg Clayton        clang::ValueDecl *value_decl = dyn_cast<clang::ValueDecl>(named_decl);
151552f792329be5db8e38961350589e97e8f2823acdGreg Clayton        if (value_decl == NULL)
1516810f22d18ca8f9d31f49d79bb4b51a9f2fd96deaSean Callanan            return false;
151752f792329be5db8e38961350589e97e8f2823acdGreg Clayton
151852f792329be5db8e38961350589e97e8f2823acdGreg Clayton        lldb_private::ClangASTType clang_type(&value_decl->getASTContext(), value_decl->getType());
1519771131d04344e57abb340699f54dce77a511bc71Sean Callanan
152058baaada202ea16e928f0c76e9124d42fd3655cdSean Callanan        const Type *value_type = NULL;
152152f792329be5db8e38961350589e97e8f2823acdGreg Clayton
152297678d17ac9bcb66f7092178109271991ab16533Sean Callanan        if (name[0] == '$')
15236a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan        {
15246a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan            // The $__lldb_expr_result name indicates the the return value has allocated as
15256a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan            // a static variable.  Per the comment at ASTResultSynthesizer::SynthesizeBodyResult,
15266a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan            // accesses to this static variable need to be redirected to the result of dereferencing
15276a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan            // a pointer that is passed in as one of the arguments.
15286a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan            //
15296a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan            // Consequently, when reporting the size of the type, we report a pointer type pointing
15306a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan            // to the type of $__lldb_expr_result, not the type itself.
153197678d17ac9bcb66f7092178109271991ab16533Sean Callanan            //
153297678d17ac9bcb66f7092178109271991ab16533Sean Callanan            // We also do this for any user-declared persistent variables.
153352f792329be5db8e38961350589e97e8f2823acdGreg Clayton            clang_type = clang_type.GetPointerType();
15346a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan            value_type = PointerType::get(global_variable->getType(), 0);
15356a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan        }
15366a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan        else
15376a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan        {
15386a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan            value_type = global_variable->getType();
15396a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan        }
154052f792329be5db8e38961350589e97e8f2823acdGreg Clayton
154152f792329be5db8e38961350589e97e8f2823acdGreg Clayton        const uint64_t value_size = clang_type.GetByteSize();
154252f792329be5db8e38961350589e97e8f2823acdGreg Clayton        off_t value_alignment = (clang_type.GetTypeBitAlign() + 7ull) / 8ull;
15433aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan
1544771131d04344e57abb340699f54dce77a511bc71Sean Callanan        if (log)
154552f792329be5db8e38961350589e97e8f2823acdGreg Clayton        {
1546fe6dc6e241c52822710380cec0931351a1d7b2d3Greg Clayton            log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %" PRIu64 ", align %" PRId64 "]",
1547771131d04344e57abb340699f54dce77a511bc71Sean Callanan                        name.c_str(),
154852f792329be5db8e38961350589e97e8f2823acdGreg Clayton                        clang_type.GetQualType().getAsString().c_str(),
154952f792329be5db8e38961350589e97e8f2823acdGreg Clayton                        PrintType(value_type).c_str(),
1550771131d04344e57abb340699f54dce77a511bc71Sean Callanan                        value_size,
1551771131d04344e57abb340699f54dce77a511bc71Sean Callanan                        value_alignment);
155252f792329be5db8e38961350589e97e8f2823acdGreg Clayton        }
15533aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan
15548bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan
15558c12720c108cd5e7ed792596749218d8400f647eSean Callanan        if (named_decl && !m_decl_map->AddValueToStruct(named_decl,
15568de27c761a22187ef63fb60000894be163e7285fGreg Clayton                                                        lldb_private::ConstString (name.c_str()),
15578de27c761a22187ef63fb60000894be163e7285fGreg Clayton                                                        llvm_value_ptr,
1558ba992c58b25ec0a67ef430024dc3dca154982dc9Sean Callanan                                                        value_size,
1559ba992c58b25ec0a67ef430024dc3dca154982dc9Sean Callanan                                                        value_alignment))
15609a8774383dc91717151f85b32f3677aef102a77aSean Callanan        {
15619a8774383dc91717151f85b32f3677aef102a77aSean Callanan            if (!global_variable->hasExternalLinkage())
15629a8774383dc91717151f85b32f3677aef102a77aSean Callanan                return true;
15632a90dd0ce40c583af74333987a48fc82d7d0adf5Sean Callanan            else if (HandleSymbol (global_variable))
15642a90dd0ce40c583af74333987a48fc82d7d0adf5Sean Callanan                return true;
15659a8774383dc91717151f85b32f3677aef102a77aSean Callanan            else
15669a8774383dc91717151f85b32f3677aef102a77aSean Callanan                return false;
15679a8774383dc91717151f85b32f3677aef102a77aSean Callanan        }
15688bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan    }
1569f3143b7faf3f934282859b62575537366565a0eeSean Callanan    else if (dyn_cast<llvm::Function>(llvm_value_ptr))
15704844365bea9261f6afe24508d413d80ea2400abdSean Callanan    {
15714844365bea9261f6afe24508d413d80ea2400abdSean Callanan        if (log)
15724844365bea9261f6afe24508d413d80ea2400abdSean Callanan            log->Printf("Function pointers aren't handled right now");
15734844365bea9261f6afe24508d413d80ea2400abdSean Callanan
15744844365bea9261f6afe24508d413d80ea2400abdSean Callanan        return false;
15754844365bea9261f6afe24508d413d80ea2400abdSean Callanan    }
15768bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan
15778bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan    return true;
15788bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan}
15798bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan
158097c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan// This function does not report errors; its callers are responsible.
15818bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callananbool
1582c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::HandleSymbol (Value *symbol)
1583819749647b1605f75753f625050cb240292c08b0Sean Callanan{
1584952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1585c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan
1586c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan    lldb_private::ConstString name(symbol->getName().str().c_str());
1587c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan
158821ef5bb658e4582339bedf5befc10c13953bdac0Sean Callanan    lldb::addr_t symbol_addr = m_decl_map->GetSymbolAddress (name, lldb::eSymbolTypeAny);
1589c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan
1590cbc07cfd435fb703d8feb69b97ca8590e6ee2fd8Greg Clayton    if (symbol_addr == LLDB_INVALID_ADDRESS)
1591c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan    {
1592c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan        if (log)
1593c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan            log->Printf ("Symbol \"%s\" had no address", name.GetCString());
1594c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan
1595c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan        return false;
1596c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan    }
1597c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan
1598c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan    if (log)
15995f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea        log->Printf("Found \"%s\" at 0x%" PRIx64, name.GetCString(), symbol_addr);
1600c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan
16019b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan    Type *symbol_type = symbol->getType();
16029b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan    IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(),
16034fbe61ba371bfde827b9424ebe5e14dce3d5fad3Sean Callanan                                             (m_module->getPointerSize() == Module::Pointer64) ? 64 : 32);
1604c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan
1605c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan    Constant *symbol_addr_int = ConstantInt::get(intptr_ty, symbol_addr, false);
1606c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan
1607c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan    Value *symbol_addr_ptr = ConstantExpr::getIntToPtr(symbol_addr_int, symbol_type);
1608c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan
1609c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan    if (log)
1610c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan        log->Printf("Replacing %s with %s", PrintValue(symbol).c_str(), PrintValue(symbol_addr_ptr).c_str());
1611c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan
1612c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan    symbol->replaceAllUsesWith(symbol_addr_ptr);
1613c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan
1614c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan    return true;
1615c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan}
1616c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan
1617c7674af9458fbad6f07fa73609c354abf93af2dcSean Callananbool
1618c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::MaybeHandleCallArguments (CallInst *Old)
1619dc27aba0bdf7c2aa4f59374d4b612bf84bfe70c8Sean Callanan{
1620952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
16214844365bea9261f6afe24508d413d80ea2400abdSean Callanan
16224844365bea9261f6afe24508d413d80ea2400abdSean Callanan    if (log)
16234844365bea9261f6afe24508d413d80ea2400abdSean Callanan        log->Printf("MaybeHandleCallArguments(%s)", PrintValue(Old).c_str());
1624dc27aba0bdf7c2aa4f59374d4b612bf84bfe70c8Sean Callanan
16256ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan    for (unsigned op_index = 0, num_ops = Old->getNumArgOperands();
1626dc27aba0bdf7c2aa4f59374d4b612bf84bfe70c8Sean Callanan         op_index < num_ops;
1627dc27aba0bdf7c2aa4f59374d4b612bf84bfe70c8Sean Callanan         ++op_index)
1628c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        if (!MaybeHandleVariable(Old->getArgOperand(op_index))) // conservatively believe that this is a store
162997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan        {
163097c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan            if (m_error_stream)
163197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                m_error_stream->Printf("Internal error [IRForTarget]: Couldn't rewrite one of the arguments of a function call.\n");
163297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
1633dc27aba0bdf7c2aa4f59374d4b612bf84bfe70c8Sean Callanan            return false;
163497c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan        }
163597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
1636dc27aba0bdf7c2aa4f59374d4b612bf84bfe70c8Sean Callanan    return true;
1637dc27aba0bdf7c2aa4f59374d4b612bf84bfe70c8Sean Callanan}
1638dc27aba0bdf7c2aa4f59374d4b612bf84bfe70c8Sean Callanan
1639dc27aba0bdf7c2aa4f59374d4b612bf84bfe70c8Sean Callananbool
16409911d2fa3380028c9b798110bd1dcdeb44920421Sean CallananIRForTarget::HandleObjCClass(Value *classlist_reference)
16419911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan{
1642952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
16439911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan
16449911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan    GlobalVariable *global_variable = dyn_cast<GlobalVariable>(classlist_reference);
16459911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan
16469911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan    if (!global_variable)
16479911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan        return false;
16489911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan
16499911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan    Constant *initializer = global_variable->getInitializer();
16509911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan
16519911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan    if (!initializer)
16529911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan        return false;
16539911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan
16549911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan    if (!initializer->hasName())
16559911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan        return false;
16569911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan
16579911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan    StringRef name(initializer->getName());
16589911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan    lldb_private::ConstString name_cstr(name.str().c_str());
165916d2187c0c3992f22e9cb011f863dc0fe35e3cdeGreg Clayton    lldb::addr_t class_ptr = m_decl_map->GetSymbolAddress(name_cstr, lldb::eSymbolTypeObjCClass);
16609911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan
16619911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan    if (log)
16629911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan        log->Printf("Found reference to Objective-C class %s (0x%llx)", name_cstr.AsCString(), (unsigned long long)class_ptr);
16639911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan
16649911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan    if (class_ptr == LLDB_INVALID_ADDRESS)
16659911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan        return false;
16669911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan
16679911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan    if (global_variable->use_begin() == global_variable->use_end())
16689911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan        return false;
16699911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan
16705365753c4749cdd98a907bf870fdf0cd681a88beSean Callanan    SmallVector<LoadInst *, 2> load_instructions;
16715365753c4749cdd98a907bf870fdf0cd681a88beSean Callanan
16729911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan    for (Value::use_iterator i = global_variable->use_begin(), e = global_variable->use_end();
16739911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan         i != e;
16749911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan         ++i)
16759911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan    {
16765365753c4749cdd98a907bf870fdf0cd681a88beSean Callanan        if (LoadInst *load_instruction = dyn_cast<LoadInst>(*i))
16775365753c4749cdd98a907bf870fdf0cd681a88beSean Callanan            load_instructions.push_back(load_instruction);
16789911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan    }
16799911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan
16805365753c4749cdd98a907bf870fdf0cd681a88beSean Callanan    if (load_instructions.empty())
16819911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan        return false;
16829911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan
16839911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan    IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(),
16844fbe61ba371bfde827b9424ebe5e14dce3d5fad3Sean Callanan                                             (m_module->getPointerSize()
1685ce6335881f330581f641ef808602cac192664adfMicah Villmow                                              == Module::Pointer64) ? 64 : 32);
16869911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan
16879911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan    Constant *class_addr = ConstantInt::get(intptr_ty, (uint64_t)class_ptr);
16889911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan
16895365753c4749cdd98a907bf870fdf0cd681a88beSean Callanan    for (LoadInst *load_instruction : load_instructions)
16905365753c4749cdd98a907bf870fdf0cd681a88beSean Callanan    {
16915365753c4749cdd98a907bf870fdf0cd681a88beSean Callanan        Constant *class_bitcast = ConstantExpr::getIntToPtr(class_addr, load_instruction->getType());
16925365753c4749cdd98a907bf870fdf0cd681a88beSean Callanan
16935365753c4749cdd98a907bf870fdf0cd681a88beSean Callanan        load_instruction->replaceAllUsesWith(class_bitcast);
16949911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan
16955365753c4749cdd98a907bf870fdf0cd681a88beSean Callanan        load_instruction->eraseFromParent();
16965365753c4749cdd98a907bf870fdf0cd681a88beSean Callanan    }
16979911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan
16989911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan    return true;
16999911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan}
17009911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan
17019911d2fa3380028c9b798110bd1dcdeb44920421Sean Callananbool
17021850f94688f9362c78c27e5472afe022a56c08dfSean CallananIRForTarget::RemoveCXAAtExit (BasicBlock &basic_block)
17031850f94688f9362c78c27e5472afe022a56c08dfSean Callanan{
17041850f94688f9362c78c27e5472afe022a56c08dfSean Callanan    BasicBlock::iterator ii;
17051850f94688f9362c78c27e5472afe022a56c08dfSean Callanan
17061850f94688f9362c78c27e5472afe022a56c08dfSean Callanan    std::vector<CallInst *> calls_to_remove;
17071850f94688f9362c78c27e5472afe022a56c08dfSean Callanan
17081850f94688f9362c78c27e5472afe022a56c08dfSean Callanan    for (ii = basic_block.begin();
17091850f94688f9362c78c27e5472afe022a56c08dfSean Callanan         ii != basic_block.end();
17101850f94688f9362c78c27e5472afe022a56c08dfSean Callanan         ++ii)
17111850f94688f9362c78c27e5472afe022a56c08dfSean Callanan    {
17121850f94688f9362c78c27e5472afe022a56c08dfSean Callanan        Instruction &inst = *ii;
17131850f94688f9362c78c27e5472afe022a56c08dfSean Callanan
17141850f94688f9362c78c27e5472afe022a56c08dfSean Callanan        CallInst *call = dyn_cast<CallInst>(&inst);
17151850f94688f9362c78c27e5472afe022a56c08dfSean Callanan
17161850f94688f9362c78c27e5472afe022a56c08dfSean Callanan        // MaybeHandleCallArguments handles error reporting; we are silent here
17171850f94688f9362c78c27e5472afe022a56c08dfSean Callanan        if (!call)
17181850f94688f9362c78c27e5472afe022a56c08dfSean Callanan            continue;
17191850f94688f9362c78c27e5472afe022a56c08dfSean Callanan
17201850f94688f9362c78c27e5472afe022a56c08dfSean Callanan        bool remove = false;
17211850f94688f9362c78c27e5472afe022a56c08dfSean Callanan
17221850f94688f9362c78c27e5472afe022a56c08dfSean Callanan        llvm::Function *func = call->getCalledFunction();
17231850f94688f9362c78c27e5472afe022a56c08dfSean Callanan
17241850f94688f9362c78c27e5472afe022a56c08dfSean Callanan        if (func && func->getName() == "__cxa_atexit")
17251850f94688f9362c78c27e5472afe022a56c08dfSean Callanan            remove = true;
17261850f94688f9362c78c27e5472afe022a56c08dfSean Callanan
17271850f94688f9362c78c27e5472afe022a56c08dfSean Callanan        llvm::Value *val = call->getCalledValue();
17281850f94688f9362c78c27e5472afe022a56c08dfSean Callanan
17291850f94688f9362c78c27e5472afe022a56c08dfSean Callanan        if (val && val->getName() == "__cxa_atexit")
17301850f94688f9362c78c27e5472afe022a56c08dfSean Callanan            remove = true;
17311850f94688f9362c78c27e5472afe022a56c08dfSean Callanan
17321850f94688f9362c78c27e5472afe022a56c08dfSean Callanan        if (remove)
17331850f94688f9362c78c27e5472afe022a56c08dfSean Callanan            calls_to_remove.push_back(call);
17341850f94688f9362c78c27e5472afe022a56c08dfSean Callanan    }
17351850f94688f9362c78c27e5472afe022a56c08dfSean Callanan
17361850f94688f9362c78c27e5472afe022a56c08dfSean Callanan    for (std::vector<CallInst *>::iterator ci = calls_to_remove.begin(), ce = calls_to_remove.end();
17371850f94688f9362c78c27e5472afe022a56c08dfSean Callanan         ci != ce;
17381850f94688f9362c78c27e5472afe022a56c08dfSean Callanan         ++ci)
17391850f94688f9362c78c27e5472afe022a56c08dfSean Callanan    {
17401850f94688f9362c78c27e5472afe022a56c08dfSean Callanan        (*ci)->eraseFromParent();
17411850f94688f9362c78c27e5472afe022a56c08dfSean Callanan    }
17421850f94688f9362c78c27e5472afe022a56c08dfSean Callanan
17431850f94688f9362c78c27e5472afe022a56c08dfSean Callanan    return true;
17441850f94688f9362c78c27e5472afe022a56c08dfSean Callanan}
17451850f94688f9362c78c27e5472afe022a56c08dfSean Callanan
17461850f94688f9362c78c27e5472afe022a56c08dfSean Callananbool
1747c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::ResolveCalls(BasicBlock &basic_block)
17488bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan{
17495cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan    /////////////////////////////////////////////////////////////////////////
17505cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan    // Prepare the current basic block for execution in the remote process
17515cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan    //
17525cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan
175302fbafa1bf2bb77bf8f25af3403d7d8721a3f8b1Sean Callanan    BasicBlock::iterator ii;
17548bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan
17553c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton    for (ii = basic_block.begin();
17563c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton         ii != basic_block.end();
17578bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan         ++ii)
17588bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan    {
17598bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan        Instruction &inst = *ii;
17608bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan
17611d1b39c93c64294ae1c6e5cfe6de584716c284bcSean Callanan        CallInst *call = dyn_cast<CallInst>(&inst);
1762ba992c58b25ec0a67ef430024dc3dca154982dc9Sean Callanan
176397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan        // MaybeHandleCallArguments handles error reporting; we are silent here
1764c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        if (call && !MaybeHandleCallArguments(call))
17654844365bea9261f6afe24508d413d80ea2400abdSean Callanan            return false;
17668bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan    }
17678bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan
17688bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan    return true;
17698bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan}
17708bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan
17711d1b39c93c64294ae1c6e5cfe6de584716c284bcSean Callananbool
1772c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::ResolveExternals (Function &llvm_function)
17731d1b39c93c64294ae1c6e5cfe6de584716c284bcSean Callanan{
1774952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1775ae71e30fe0c0e0d5fd1bf9062274798060df674cSean Callanan
1776c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    for (Module::global_iterator global = m_module->global_begin(), end = m_module->global_end();
17771d1b39c93c64294ae1c6e5cfe6de584716c284bcSean Callanan         global != end;
17781d1b39c93c64294ae1c6e5cfe6de584716c284bcSean Callanan         ++global)
17791d1b39c93c64294ae1c6e5cfe6de584716c284bcSean Callanan    {
17801c17a7ed48d8d16ffde99ff56264c142634cc4f1Sean Callanan        if (!global)
17811c17a7ed48d8d16ffde99ff56264c142634cc4f1Sean Callanan        {
17821c17a7ed48d8d16ffde99ff56264c142634cc4f1Sean Callanan            if (m_error_stream)
17831c17a7ed48d8d16ffde99ff56264c142634cc4f1Sean Callanan                m_error_stream->Printf("Internal error [IRForTarget]: global variable is NULL");
17841c17a7ed48d8d16ffde99ff56264c142634cc4f1Sean Callanan
17851c17a7ed48d8d16ffde99ff56264c142634cc4f1Sean Callanan            return false;
17861c17a7ed48d8d16ffde99ff56264c142634cc4f1Sean Callanan        }
17871c17a7ed48d8d16ffde99ff56264c142634cc4f1Sean Callanan
17881c17a7ed48d8d16ffde99ff56264c142634cc4f1Sean Callanan        std::string global_name = (*global).getName().str();
17891c17a7ed48d8d16ffde99ff56264c142634cc4f1Sean Callanan
17903c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton        if (log)
17913c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton            log->Printf("Examining %s, DeclForGlobalValue returns %p",
17921c17a7ed48d8d16ffde99ff56264c142634cc4f1Sean Callanan                        global_name.c_str(),
1793c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                        DeclForGlobal(global));
17949911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan
17959911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan        if (global_name.find("OBJC_IVAR") == 0)
1796c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan        {
1797c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            if (!HandleSymbol(global))
179897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan            {
179997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                if (m_error_stream)
18001c17a7ed48d8d16ffde99ff56264c142634cc4f1Sean Callanan                    m_error_stream->Printf("Error [IRForTarget]: Couldn't find Objective-C indirect ivar symbol %s\n", global_name.c_str());
180197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
1802c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan                return false;
180397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan            }
1804c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan        }
18059911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan        else if (global_name.find("OBJC_CLASSLIST_REFERENCES_$") != global_name.npos)
18069911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan        {
18079911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan            if (!HandleObjCClass(global))
18089911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan            {
18099911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan                if (m_error_stream)
18109911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan                    m_error_stream->Printf("Error [IRForTarget]: Couldn't resolve the class for an Objective-C static method call\n");
18119911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan
18129911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan                return false;
18139911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan            }
18149911d2fa3380028c9b798110bd1dcdeb44920421Sean Callanan        }
18152dbfe86c0b186487aac732fcb9748a863d138ad0Sean Callanan        else if (global_name.find("OBJC_CLASSLIST_SUP_REFS_$") != global_name.npos)
18162dbfe86c0b186487aac732fcb9748a863d138ad0Sean Callanan        {
18172dbfe86c0b186487aac732fcb9748a863d138ad0Sean Callanan            if (!HandleObjCClass(global))
18182dbfe86c0b186487aac732fcb9748a863d138ad0Sean Callanan            {
18192dbfe86c0b186487aac732fcb9748a863d138ad0Sean Callanan                if (m_error_stream)
18202dbfe86c0b186487aac732fcb9748a863d138ad0Sean Callanan                    m_error_stream->Printf("Error [IRForTarget]: Couldn't resolve the class for an Objective-C static method call\n");
18212dbfe86c0b186487aac732fcb9748a863d138ad0Sean Callanan
18222dbfe86c0b186487aac732fcb9748a863d138ad0Sean Callanan                return false;
18232dbfe86c0b186487aac732fcb9748a863d138ad0Sean Callanan            }
18242dbfe86c0b186487aac732fcb9748a863d138ad0Sean Callanan        }
1825c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        else if (DeclForGlobal(global))
1826c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan        {
1827c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            if (!MaybeHandleVariable (global))
182897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan            {
182997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                if (m_error_stream)
18301c17a7ed48d8d16ffde99ff56264c142634cc4f1Sean Callanan                    m_error_stream->Printf("Internal error [IRForTarget]: Couldn't rewrite external variable %s\n", global_name.c_str());
183197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
1832c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan                return false;
183397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan            }
1834c7674af9458fbad6f07fa73609c354abf93af2dcSean Callanan        }
18351d1b39c93c64294ae1c6e5cfe6de584716c284bcSean Callanan    }
18361d1b39c93c64294ae1c6e5cfe6de584716c284bcSean Callanan
18371d1b39c93c64294ae1c6e5cfe6de584716c284bcSean Callanan    return true;
18381d1b39c93c64294ae1c6e5cfe6de584716c284bcSean Callanan}
18391d1b39c93c64294ae1c6e5cfe6de584716c284bcSean Callanan
1840c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callananbool
1841c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::ReplaceStrings ()
1842c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan{
1843952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1844c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
1845c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    typedef std::map <GlobalVariable *, size_t> OffsetsTy;
1846c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
1847c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    OffsetsTy offsets;
1848c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
1849c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    for (Module::global_iterator gi = m_module->global_begin(), ge = m_module->global_end();
1850c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan         gi != ge;
1851c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan         ++gi)
1852c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    {
1853c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        GlobalVariable *gv = gi;
1854c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
1855c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        if (!gv->hasInitializer())
1856c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            continue;
1857c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
1858c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        Constant *gc = gv->getInitializer();
1859c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
18601b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan        std::string str;
1861c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
18621b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan        if (gc->isNullValue())
18631b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan        {
18641b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan            Type *gc_type = gc->getType();
18651b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan
18661b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan            ArrayType *gc_array_type = dyn_cast<ArrayType>(gc_type);
18671b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan
18681b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan            if (!gc_array_type)
18691b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan                continue;
18701b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan
18711b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan            Type *gc_element_type = gc_array_type->getElementType();
18721b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan
18731b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan            IntegerType *gc_integer_type = dyn_cast<IntegerType>(gc_element_type);
18741b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan
18751b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan            if (gc_integer_type->getBitWidth() != 8)
18761b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan                continue;
18771b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan
18781b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan            str = "";
18791b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan        }
18801b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan        else
18811b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan        {
188239a30348f0233865e168bb3e9a3c63a446f69f34Sean Callanan            ConstantDataArray *gc_array = dyn_cast<ConstantDataArray>(gc);
18831b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan
18841b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan            if (!gc_array)
18851b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan                continue;
1886c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
18871b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan            if (!gc_array->isCString())
18881b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan                continue;
1889c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
18901b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan            if (log)
18911b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan                log->Printf("Found a GlobalVariable with string initializer %s", PrintValue(gc).c_str());
1892c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
18931b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan            str = gc_array->getAsString();
18941b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan        }
18951b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan
18961cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan        offsets[gv] = m_data_allocator.GetStream().GetSize();
1897c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
18981cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan        m_data_allocator.GetStream().Write(str.c_str(), str.length() + 1);
1899c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    }
1900c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
19019b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan    Type *char_ptr_ty = Type::getInt8PtrTy(m_module->getContext());
1902c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
1903c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    for (OffsetsTy::iterator oi = offsets.begin(), oe = offsets.end();
1904c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan         oi != oe;
1905c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan         ++oi)
1906c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    {
1907c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        GlobalVariable *gv = oi->first;
1908c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        size_t offset = oi->second;
1909c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
1910c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        Constant *new_initializer = BuildRelocation(char_ptr_ty, offset);
1911c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
1912c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        if (log)
1913c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            log->Printf("Replacing GV %s with %s", PrintValue(gv).c_str(), PrintValue(new_initializer).c_str());
1914c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
1915c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        for (GlobalVariable::use_iterator ui = gv->use_begin(), ue = gv->use_end();
1916c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan             ui != ue;
1917c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan             ++ui)
1918c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        {
1919c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            if (log)
1920c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                log->Printf("Found use %s", PrintValue(*ui).c_str());
1921c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
1922c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            ConstantExpr *const_expr = dyn_cast<ConstantExpr>(*ui);
1923c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            StoreInst *store_inst = dyn_cast<StoreInst>(*ui);
1924c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
1925c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            if (const_expr)
1926c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            {
1927c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                if (const_expr->getOpcode() != Instruction::GetElementPtr)
1928c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                {
1929c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                    if (log)
1930c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                        log->Printf("Use (%s) of string variable is not a GetElementPtr constant", PrintValue(const_expr).c_str());
1931c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
1932c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                    return false;
1933c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                }
1934c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
19351b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan                Constant *bit_cast = ConstantExpr::getBitCast(new_initializer, const_expr->getOperand(0)->getType());
19361b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan                Constant *new_gep = const_expr->getWithOperandReplaced(0, bit_cast);
19371b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan
19381b3d1dfa9ab139e1d2ddb34aea11703feb7fd761Sean Callanan                const_expr->replaceAllUsesWith(new_gep);
1939c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            }
1940c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            else if (store_inst)
1941c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            {
1942c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                Constant *bit_cast = ConstantExpr::getBitCast(new_initializer, store_inst->getValueOperand()->getType());
1943c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
1944c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                store_inst->setOperand(0, bit_cast);
1945c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            }
1946c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            else
1947c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            {
1948c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                if (log)
1949c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                    log->Printf("Use (%s) of string variable is neither a constant nor a store", PrintValue(const_expr).c_str());
1950c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
1951c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                return false;
1952c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            }
1953c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        }
1954c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
1955c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        gv->eraseFromParent();
1956c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    }
1957c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
1958c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    return true;
1959c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan}
1960c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
1961c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callananbool
1962c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::ReplaceStaticLiterals (llvm::BasicBlock &basic_block)
1963c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan{
1964952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
1965c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
1966c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    typedef SmallVector <Value*, 2> ConstantList;
1967c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    typedef SmallVector <llvm::Instruction*, 2> UserList;
1968c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    typedef ConstantList::iterator ConstantIterator;
1969c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    typedef UserList::iterator UserIterator;
1970c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
1971c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    ConstantList static_constants;
1972c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    UserList static_users;
1973c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
1974c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    for (BasicBlock::iterator ii = basic_block.begin(), ie = basic_block.end();
1975c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan         ii != ie;
1976c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan         ++ii)
1977c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    {
1978c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        llvm::Instruction &inst = *ii;
1979c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
1980c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        for (Instruction::op_iterator oi = inst.op_begin(), oe = inst.op_end();
1981c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan             oi != oe;
1982c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan             ++oi)
1983c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        {
1984c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            Value *operand_val = oi->get();
1985c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
1986c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            ConstantFP *operand_constant_fp = dyn_cast<ConstantFP>(operand_val);
1987c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
198826c05d93aaca1505b92c7ebee65b4078c82f335aSean Callanan            if (operand_constant_fp/* && operand_constant_fp->getType()->isX86_FP80Ty()*/)
1989c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            {
1990c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                static_constants.push_back(operand_val);
1991c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                static_users.push_back(ii);
1992c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            }
1993c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        }
1994c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    }
1995c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
1996c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    ConstantIterator constant_iter;
1997c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    UserIterator user_iter;
199854b38413f62af3bcaeb8802a978cc621c8e88eb1Greg Clayton
1999c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    for (constant_iter = static_constants.begin(), user_iter = static_users.begin();
2000c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan         constant_iter != static_constants.end();
2001c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan         ++constant_iter, ++user_iter)
2002c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    {
2003c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        Value *operand_val = *constant_iter;
2004c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        llvm::Instruction *inst = *user_iter;
2005c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
2006c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        ConstantFP *operand_constant_fp = dyn_cast<ConstantFP>(operand_val);
2007c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
2008c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        if (operand_constant_fp)
2009c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        {
20100f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            Type *operand_type = operand_constant_fp->getType();
20110f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan
2012c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            APFloat operand_apfloat = operand_constant_fp->getValueAPF();
2013c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            APInt operand_apint = operand_apfloat.bitcastToAPInt();
2014c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
2015c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            const uint8_t* operand_raw_data = (const uint8_t*)operand_apint.getRawData();
2016c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            size_t operand_data_size = operand_apint.getBitWidth() / 8;
2017c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
2018c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            if (log)
2019c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            {
2020c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                std::string s;
2021c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                raw_string_ostream ss(s);
2022c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                for (size_t index = 0;
2023c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                     index < operand_data_size;
2024c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                     ++index)
2025c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                {
2026c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                    ss << (uint32_t)operand_raw_data[index];
2027c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                    ss << " ";
2028c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                }
2029c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                ss.flush();
2030c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
20317e5fa7fc1f8efd24c078e063b2c4b5e13ba5be20Jason Molenda                log->Printf("Found ConstantFP with size %lu and raw data %s", operand_data_size, s.c_str());
2032c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            }
2033c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
2034c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            lldb_private::DataBufferHeap data(operand_data_size, 0);
2035c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
20361cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan            if (lldb::endian::InlHostByteOrder() != m_data_allocator.GetStream().GetByteOrder())
2037c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            {
2038c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                uint8_t *data_bytes = data.GetBytes();
2039c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
2040c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                for (size_t index = 0;
2041c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                     index < operand_data_size;
2042c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                     ++index)
2043c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                {
2044c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                    data_bytes[index] = operand_raw_data[operand_data_size - (1 + index)];
2045c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                }
2046c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            }
2047c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            else
2048c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            {
2049c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                memcpy(data.GetBytes(), operand_raw_data, operand_data_size);
2050c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            }
2051c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
20521cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan            uint64_t offset = m_data_allocator.GetStream().GetSize();
2053c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
20541d970e7a461fe31aca72acc3bbe80d0cc79f2d2bSean Callanan            size_t align = m_target_data->getPrefTypeAlignment(operand_type);
20551d970e7a461fe31aca72acc3bbe80d0cc79f2d2bSean Callanan
20561d970e7a461fe31aca72acc3bbe80d0cc79f2d2bSean Callanan            const size_t mask = (align - 1);
20571d970e7a461fe31aca72acc3bbe80d0cc79f2d2bSean Callanan            uint64_t aligned_offset = (offset + mask) & ~mask;
20581cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan            m_data_allocator.GetStream().PutNHex8(aligned_offset - offset, 0);
20591d970e7a461fe31aca72acc3bbe80d0cc79f2d2bSean Callanan            offset = aligned_offset;
20601d970e7a461fe31aca72acc3bbe80d0cc79f2d2bSean Callanan
20611cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan            m_data_allocator.GetStream().Write(data.GetBytes(), operand_data_size);
2062c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
20639b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan            llvm::Type *fp_ptr_ty = operand_constant_fp->getType()->getPointerTo();
2064c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
20650f0551e67d8ea8d63ace5456f7d42d951827b017Sean Callanan            Constant *new_pointer = BuildRelocation(fp_ptr_ty, aligned_offset);
2066c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
2067c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            llvm::LoadInst *fp_load = new llvm::LoadInst(new_pointer, "fp_load", inst);
2068c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
2069c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            operand_constant_fp->replaceAllUsesWith(fp_load);
2070c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        }
2071c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    }
2072c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
2073c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    return true;
2074c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan}
2075c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
207602fbafa1bf2bb77bf8f25af3403d7d8721a3f8b1Sean Callananstatic bool isGuardVariableRef(Value *V)
207745839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan{
207858baaada202ea16e928f0c76e9124d42fd3655cdSean Callanan    Constant *Old = NULL;
207945839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan
20806ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan    if (!(Old = dyn_cast<Constant>(V)))
208145839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan        return false;
208245839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan
208358baaada202ea16e928f0c76e9124d42fd3655cdSean Callanan    ConstantExpr *CE = NULL;
208447a5c4c01066ece2d41cba56c3a065eeca12d47cSean Callanan
208547a5c4c01066ece2d41cba56c3a065eeca12d47cSean Callanan    if ((CE = dyn_cast<ConstantExpr>(V)))
208647a5c4c01066ece2d41cba56c3a065eeca12d47cSean Callanan    {
208747a5c4c01066ece2d41cba56c3a065eeca12d47cSean Callanan        if (CE->getOpcode() != Instruction::BitCast)
208847a5c4c01066ece2d41cba56c3a065eeca12d47cSean Callanan            return false;
208947a5c4c01066ece2d41cba56c3a065eeca12d47cSean Callanan
20906ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        Old = CE->getOperand(0);
209147a5c4c01066ece2d41cba56c3a065eeca12d47cSean Callanan    }
209247a5c4c01066ece2d41cba56c3a065eeca12d47cSean Callanan
20936ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan    GlobalVariable *GV = dyn_cast<GlobalVariable>(Old);
209445839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan
209545839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan    if (!GV || !GV->hasName() || !GV->getName().startswith("_ZGV"))
209645839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan        return false;
209745839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan
209845839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan    return true;
209945839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan}
210045839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan
2101c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callananvoid
2102c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::TurnGuardLoadIntoZero(llvm::Instruction* guard_load)
210345839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan{
2104c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    Constant* zero(ConstantInt::get(Type::getInt8Ty(m_module->getContext()), 0, true));
210545839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan
210645839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan    Value::use_iterator ui;
210745839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan
210845839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan    for (ui = guard_load->use_begin();
210945839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan         ui != guard_load->use_end();
211045839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan         ++ui)
2111b5b749c1d13458b170a7e0e00e7bf0d7da37defaSean Callanan    {
21126e71340988075f55c85e8bfcbc503ceaceb157c7Greg Clayton        if (isa<Constant>(*ui))
2113b5b749c1d13458b170a7e0e00e7bf0d7da37defaSean Callanan        {
2114b5b749c1d13458b170a7e0e00e7bf0d7da37defaSean Callanan            // do nothing for the moment
2115b5b749c1d13458b170a7e0e00e7bf0d7da37defaSean Callanan        }
2116b5b749c1d13458b170a7e0e00e7bf0d7da37defaSean Callanan        else
2117b5b749c1d13458b170a7e0e00e7bf0d7da37defaSean Callanan        {
2118b5b749c1d13458b170a7e0e00e7bf0d7da37defaSean Callanan            ui->replaceUsesOfWith(guard_load, zero);
2119b5b749c1d13458b170a7e0e00e7bf0d7da37defaSean Callanan        }
2120b5b749c1d13458b170a7e0e00e7bf0d7da37defaSean Callanan    }
212145839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan
212245839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan    guard_load->eraseFromParent();
212345839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan}
212445839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan
212545839276c3de51a55adef98a2a20a98f2ba428a9Sean Callananstatic void ExciseGuardStore(Instruction* guard_store)
212645839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan{
212745839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan    guard_store->eraseFromParent();
212845839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan}
212945839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan
213045839276c3de51a55adef98a2a20a98f2ba428a9Sean Callananbool
2131c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::RemoveGuards(BasicBlock &basic_block)
213245839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan{
213345839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan    ///////////////////////////////////////////////////////
213445839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan    // Eliminate any reference to guard variables found.
213545839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan    //
213645839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan
213702fbafa1bf2bb77bf8f25af3403d7d8721a3f8b1Sean Callanan    BasicBlock::iterator ii;
213845839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan
213902fbafa1bf2bb77bf8f25af3403d7d8721a3f8b1Sean Callanan    typedef SmallVector <Instruction*, 2> InstrList;
214045839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan    typedef InstrList::iterator InstrIterator;
214145839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan
214245839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan    InstrList guard_loads;
214345839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan    InstrList guard_stores;
214445839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan
21453c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton    for (ii = basic_block.begin();
21463c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton         ii != basic_block.end();
214745839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan         ++ii)
214845839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan    {
214945839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan        Instruction &inst = *ii;
215045839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan
215145839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan        if (LoadInst *load = dyn_cast<LoadInst>(&inst))
215245839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan            if (isGuardVariableRef(load->getPointerOperand()))
215345839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan                guard_loads.push_back(&inst);
215445839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan
215545839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan        if (StoreInst *store = dyn_cast<StoreInst>(&inst))
215645839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan            if (isGuardVariableRef(store->getPointerOperand()))
215745839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan                guard_stores.push_back(&inst);
215845839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan    }
215945839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan
216045839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan    InstrIterator iter;
216145839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan
216245839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan    for (iter = guard_loads.begin();
216345839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan         iter != guard_loads.end();
216445839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan         ++iter)
2165c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        TurnGuardLoadIntoZero(*iter);
216645839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan
216745839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan    for (iter = guard_stores.begin();
216845839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan         iter != guard_stores.end();
216945839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan         ++iter)
217045839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan        ExciseGuardStore(*iter);
217145839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan
217245839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan    return true;
217345839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan}
217445839276c3de51a55adef98a2a20a98f2ba428a9Sean Callanan
217597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan// This function does not report errors; its callers are responsible.
21766ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callananbool
21774a20587f56a05955ea94f650cb39245a092b0c69Sean CallananIRForTarget::UnfoldConstant(Constant *old_constant,
21784a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                            FunctionValueCache &value_maker,
21794a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                            FunctionValueCache &entry_instruction_finder)
2180bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan{
2181952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
2182bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan
2183bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan    Value::use_iterator ui;
2184bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan
2185a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    SmallVector<User*, 16> users;
2186a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan
2187a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    // We do this because the use list might change, invalidating our iterator.
2188a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    // Much better to keep a work list ourselves.
21893c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton    for (ui = old_constant->use_begin();
21903c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton         ui != old_constant->use_end();
2191bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan         ++ui)
2192a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan        users.push_back(*ui);
2193bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan
21942bc9eb3ba78efc64a273729b480bafc3bbaa433aJohnny Chen    for (size_t i = 0;
2195a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan         i < users.size();
2196a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan         ++i)
2197a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan    {
2198a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan        User *user = users[i];
2199a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan
2200bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan        if (Constant *constant = dyn_cast<Constant>(user))
2201bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan        {
2202bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan            // synthesize a new non-constant equivalent of the constant
2203bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan
2204bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan            if (ConstantExpr *constant_expr = dyn_cast<ConstantExpr>(constant))
2205bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan            {
2206bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan                switch (constant_expr->getOpcode())
2207bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan                {
2208bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan                default:
2209bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan                    if (log)
2210b5037af312160b2f396aad579e45619af3126e4aGreg Clayton                        log->Printf("Unhandled constant expression type: \"%s\"", PrintValue(constant_expr).c_str());
2211bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan                    return false;
2212bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan                case Instruction::BitCast:
22134a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                    {
22144a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                        FunctionValueCache bit_cast_maker ([&value_maker, &entry_instruction_finder, old_constant, constant_expr] (llvm::Function *function)->llvm::Value* {
22154a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                            // UnaryExpr
22164a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                            //   OperandList[0] is value
22174a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
22184a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                            if (constant_expr->getOperand(0) != old_constant)
22194a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                                return constant_expr;
22204a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
22214a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                            return new BitCastInst(value_maker.GetValue(function),
22224a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                                                   constant_expr->getType(),
22234a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                                                   "",
22244a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                                                   llvm::cast<Instruction>(entry_instruction_finder.GetValue(function)));
22254a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                        });
2226bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan
2227250e7494cc3a99a868880ba9240c70f5b78cf273Sean Callanan                        if (!UnfoldConstant(constant_expr, bit_cast_maker, entry_instruction_finder))
2228250e7494cc3a99a868880ba9240c70f5b78cf273Sean Callanan                            return false;
2229bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan                    }
2230bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan                    break;
2231bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan                case Instruction::GetElementPtr:
2232bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan                    {
2233bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan                        // GetElementPtrConstantExpr
2234bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan                        //   OperandList[0] is base
2235bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan                        //   OperandList[1]... are indices
2236bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan
22374a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                        FunctionValueCache get_element_pointer_maker ([&value_maker, &entry_instruction_finder, old_constant, constant_expr] (llvm::Function *function)->llvm::Value* {
22384a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                            Value *ptr = constant_expr->getOperand(0);
2239bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan
22404a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                            if (ptr == old_constant)
22414a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                                ptr = value_maker.GetValue(function);
2242bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan
22434a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                            std::vector<Value*> index_vector;
22444a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
22454a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                            unsigned operand_index;
22464a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                            unsigned num_operands = constant_expr->getNumOperands();
22474a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
22484a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                            for (operand_index = 1;
22494a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                                 operand_index < num_operands;
22504a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                                 ++operand_index)
22514a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                            {
22524a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                                Value *operand = constant_expr->getOperand(operand_index);
22534a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
22544a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                                if (operand == old_constant)
22554a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                                    operand = value_maker.GetValue(function);
22564a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
22574a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                                index_vector.push_back(operand);
22584a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                            }
22594a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
22604a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                            ArrayRef <Value*> indices(index_vector);
22614a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
22624a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                            return GetElementPtrInst::Create(ptr, indices, "", llvm::cast<Instruction>(entry_instruction_finder.GetValue(function)));
22634a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                        });
2264bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan
2265250e7494cc3a99a868880ba9240c70f5b78cf273Sean Callanan                        if (!UnfoldConstant(constant_expr, get_element_pointer_maker, entry_instruction_finder))
2266250e7494cc3a99a868880ba9240c70f5b78cf273Sean Callanan                            return false;
2267bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan                    }
2268bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan                    break;
2269bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan                }
2270bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan            }
2271bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan            else
2272bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan            {
2273bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan                if (log)
2274b5037af312160b2f396aad579e45619af3126e4aGreg Clayton                    log->Printf("Unhandled constant type: \"%s\"", PrintValue(constant).c_str());
2275bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan                return false;
2276bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan            }
2277bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan        }
2278bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan        else
2279bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan        {
22804a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            if (Instruction *inst = llvm::dyn_cast<Instruction>(user))
22814a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            {
22824a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                inst->replaceUsesOfWith(old_constant, value_maker.GetValue(inst->getParent()->getParent()));
22834a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            }
22844a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            else
22854a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            {
22864a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                if (log)
22874a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                    log->Printf("Unhandled non-constant type: \"%s\"", PrintValue(user).c_str());
22884a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                return false;
22894a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            }
2290bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan        }
2291bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan    }
2292bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan
2293250e7494cc3a99a868880ba9240c70f5b78cf273Sean Callanan    if (!isa<GlobalValue>(old_constant))
2294250e7494cc3a99a868880ba9240c70f5b78cf273Sean Callanan    {
2295250e7494cc3a99a868880ba9240c70f5b78cf273Sean Callanan        old_constant->destroyConstant();
2296250e7494cc3a99a868880ba9240c70f5b78cf273Sean Callanan    }
2297250e7494cc3a99a868880ba9240c70f5b78cf273Sean Callanan
2298bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan    return true;
2299bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan}
2300bafd685bcd5efa19f4f01254db1282fbb7541ac7Sean Callanan
23018bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callananbool
2302c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::ReplaceVariables (Function &llvm_function)
23038bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan{
2304e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan    if (!m_resolve_vars)
2305e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan        return true;
2306e8a59a8ec92e71203e434f28b5bac6606aacaf3cSean Callanan
2307952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
23088bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan
23098bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan    m_decl_map->DoStructLayout();
23108bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan
23118bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan    if (log)
23128bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan        log->Printf("Element arrangement:");
23138bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan
23148bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan    uint32_t num_elements;
23158bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan    uint32_t element_index;
23168bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan
23178bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan    size_t size;
23188bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan    off_t alignment;
23198bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan
23208bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan    if (!m_decl_map->GetStructInfo (num_elements, size, alignment))
23218bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan        return false;
23228bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan
23233c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton    Function::arg_iterator iter(llvm_function.getArgumentList().begin());
23248bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan
23253c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton    if (iter == llvm_function.getArgumentList().end())
232697c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan    {
232797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan        if (m_error_stream)
232897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan            m_error_stream->Printf("Internal error [IRForTarget]: Wrapper takes no arguments (should take at least a struct pointer)");
232997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
23308bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan        return false;
233197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan    }
233297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
233302fbafa1bf2bb77bf8f25af3403d7d8721a3f8b1Sean Callanan    Argument *argument = iter;
23348bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan
23353c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    if (argument->getName().equals("this"))
23363c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    {
23373c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        ++iter;
23383c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
23393c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton        if (iter == llvm_function.getArgumentList().end())
234097c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan        {
234197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan            if (m_error_stream)
234297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                m_error_stream->Printf("Internal error [IRForTarget]: Wrapper takes only 'this' argument (should take a struct pointer too)");
234397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
23443c9c5eb466869ede185e879d14a47335fb43194dSean Callanan            return false;
234597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan        }
23463c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
23473c9c5eb466869ede185e879d14a47335fb43194dSean Callanan        argument = iter;
23483c9c5eb466869ede185e879d14a47335fb43194dSean Callanan    }
23493aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan    else if (argument->getName().equals("self"))
23503aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan    {
23513aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan        ++iter;
23523aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan
23533aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan        if (iter == llvm_function.getArgumentList().end())
235497c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan        {
235597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan            if (m_error_stream)
235697c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                m_error_stream->Printf("Internal error [IRForTarget]: Wrapper takes only 'self' argument (should take '_cmd' and a struct pointer too)");
235797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
23583aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            return false;
235997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan        }
23603aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan
23613aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan        if (!iter->getName().equals("_cmd"))
236297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan        {
236397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan            if (m_error_stream)
236497c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                m_error_stream->Printf("Internal error [IRForTarget]: Wrapper takes '%s' after 'self' argument (should take '_cmd')", iter->getName().str().c_str());
236597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
23663aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            return false;
236797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan        }
23683aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan
23693aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan        ++iter;
23703aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan
23713aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan        if (iter == llvm_function.getArgumentList().end())
237297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan        {
237397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan            if (m_error_stream)
237497c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                m_error_stream->Printf("Internal error [IRForTarget]: Wrapper takes only 'self' and '_cmd' arguments (should take a struct pointer too)");
237597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
23763aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            return false;
237797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan        }
23783aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan
23793aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan        argument = iter;
23803aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan    }
23813c9c5eb466869ede185e879d14a47335fb43194dSean Callanan
23828de27c761a22187ef63fb60000894be163e7285fGreg Clayton    if (!argument->getName().equals("$__lldb_arg"))
238397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan    {
238497c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan        if (m_error_stream)
238597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan            m_error_stream->Printf("Internal error [IRForTarget]: Wrapper takes an argument named '%s' instead of the struct pointer", argument->getName().str().c_str());
238697c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
23878bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan        return false;
238897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan    }
238997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
23905cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan    if (log)
2391b5037af312160b2f396aad579e45619af3126e4aGreg Clayton        log->Printf("Arg: \"%s\"", PrintValue(argument).c_str());
23928bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan
23933c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg Clayton    BasicBlock &entry_block(llvm_function.getEntryBlock());
23946ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan    Instruction *FirstEntryInstruction(entry_block.getFirstNonPHIOrDbg());
23958bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan
23966ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan    if (!FirstEntryInstruction)
239797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan    {
239897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan        if (m_error_stream)
239997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan            m_error_stream->Printf("Internal error [IRForTarget]: Couldn't find the first instruction in the wrapper for use in rewriting");
240097c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
24018bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan        return false;
240297c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan    }
24038bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan
2404c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    LLVMContext &context(m_module->getContext());
24059b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan    IntegerType *offset_type(Type::getInt32Ty(context));
24068bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan
24078bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan    if (!offset_type)
240897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan    {
240997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan        if (m_error_stream)
241097c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan            m_error_stream->Printf("Internal error [IRForTarget]: Couldn't produce an offset type");
241197c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
24128bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan        return false;
241397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan    }
24148bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan
24158bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan    for (element_index = 0; element_index < num_elements; ++element_index)
24165cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan    {
241758baaada202ea16e928f0c76e9124d42fd3655cdSean Callanan        const clang::NamedDecl *decl = NULL;
241858baaada202ea16e928f0c76e9124d42fd3655cdSean Callanan        Value *value = NULL;
24198bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan        off_t offset;
24208de27c761a22187ef63fb60000894be163e7285fGreg Clayton        lldb_private::ConstString name;
24215cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan
242245690fe3b8b4efb101dd31085413381021a69c2fSean Callanan        if (!m_decl_map->GetStructElement (decl, value, offset, name, element_index))
242397c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan        {
242497c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan            if (m_error_stream)
242597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan                m_error_stream->Printf("Internal error [IRForTarget]: Structure information is incomplete");
242697c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
24278bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan            return false;
242897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan        }
242997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
24308bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan        if (log)
24315f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea            log->Printf("  \"%s\" (\"%s\") placed at %" PRId64,
24328de27c761a22187ef63fb60000894be163e7285fGreg Clayton                        name.GetCString(),
2433c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan                        decl->getNameAsString().c_str(),
24348bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan                        offset);
24354a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
2436c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan        if (value)
24376a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan        {
2438c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan            if (log)
2439c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan                log->Printf("    Replacing [%s]", PrintValue(value).c_str());
24406a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan
24414a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            FunctionValueCache body_result_maker ([this, name, offset_type, offset, argument, value] (llvm::Function *function)->llvm::Value * {
24424a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                // Per the comment at ASTResultSynthesizer::SynthesizeBodyResult, in cases where the result
24434a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                // variable is an rvalue, we have to synthesize a dereference of the appropriate structure
24444a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                // entry in order to produce the static variable that the AST thinks it is accessing.
2445c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan
24464a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                llvm::Instruction *entry_instruction = llvm::cast<Instruction>(m_entry_instruction_finder.GetValue(function));
2447c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan
24484a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                ConstantInt *offset_int(ConstantInt::get(offset_type, offset, true));
24494a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                GetElementPtrInst *get_element_ptr = GetElementPtrInst::Create(argument,
24504a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                                                                               offset_int,
24514a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                                                                               "",
24524a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                                                                               entry_instruction);
24534a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
24544a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                if (name == m_result_name && !m_result_is_pointer)
24554a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                {
24564a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                    BitCastInst *bit_cast = new BitCastInst(get_element_ptr,
24574a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                                                            value->getType()->getPointerTo(),
24584a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                                                            "",
24594a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                                                            entry_instruction);
24604a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
24614a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                    LoadInst *load = new LoadInst(bit_cast, "", entry_instruction);
24624a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
24634a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                    return load;
24644a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                }
24654a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                else
24664a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                {
24674a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                    BitCastInst *bit_cast = new BitCastInst(get_element_ptr, value->getType(), "", entry_instruction);
24684a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
24694a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                    return bit_cast;
24704a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                }
24714a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            });
24724a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
24734a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            if (Constant *constant = dyn_cast<Constant>(value))
24744a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            {
24754a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                UnfoldConstant(constant, body_result_maker, m_entry_instruction_finder);
2476c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan            }
24774a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            else if (Instruction *instruction = dyn_cast<Instruction>(value))
2478c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan            {
24794a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                value->replaceAllUsesWith(body_result_maker.GetValue(instruction->getParent()->getParent()));
2480c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan            }
2481c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan            else
24824a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            {
24834a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                if (log)
24844a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                    log->Printf("Unhandled non-constant type: \"%s\"", PrintValue(value).c_str());
24854a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                return false;
24864a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            }
2487c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan
2488c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan            if (GlobalVariable *var = dyn_cast<GlobalVariable>(value))
2489c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan                var->eraseFromParent();
2490c7ca466fa99aea0e4e81530157bc8927682cae00Sean Callanan        }
24915cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan    }
24925cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan
24938bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan    if (log)
24945f35a4be95aed0e5b2cb36f7d785bcbfc67284aeDaniel Malea        log->Printf("Total structure [align %" PRId64 ", size %lu]", alignment, size);
24958bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan
24965cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan    return true;
24975cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan}
24985cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan
2499c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callananllvm::Constant *
2500952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg ClaytonIRForTarget::BuildRelocation(llvm::Type *type, uint64_t offset)
2501c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan{
25029b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan    IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(),
25034fbe61ba371bfde827b9424ebe5e14dce3d5fad3Sean Callanan                                             (m_module->getPointerSize() == Module::Pointer64) ? 64 : 32);
2504c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
2505c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    llvm::Constant *offset_int = ConstantInt::get(intptr_ty, offset);
25069b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan
25079b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan    llvm::Constant *offset_array[1];
25089b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan
25099b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan    offset_array[0] = offset_int;
25109b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan
25119b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan    llvm::ArrayRef<llvm::Constant *> offsets(offset_array, 1);
25129b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan
25139b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan    llvm::Constant *reloc_getelementptr = ConstantExpr::getGetElementPtr(m_reloc_placeholder, offsets);
2514c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    llvm::Constant *reloc_getbitcast = ConstantExpr::getBitCast(reloc_getelementptr, type);
2515c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
2516c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    return reloc_getbitcast;
2517c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan}
2518c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
2519c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callananbool
2520c0492741dc594cd02736521048fe0d8f4c9a0a61Sean CallananIRForTarget::CompleteDataAllocation ()
25211cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan{
2522952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
2523c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
25241cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan    if (!m_data_allocator.GetStream().GetSize())
2525c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        return true;
2526c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
25271cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan    lldb::addr_t allocation = m_data_allocator.Allocate();
2528c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
2529c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    if (log)
2530c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    {
2531c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        if (allocation)
2532c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            log->Printf("Allocated static data at 0x%llx", (unsigned long long)allocation);
2533c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        else
2534c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            log->Printf("Failed to allocate static data");
2535c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    }
2536c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
25371cf3da8b0fb0cabf2431b5fe521842929fca69a3Sean Callanan    if (!allocation || allocation == LLDB_INVALID_ADDRESS)
2538c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        return false;
2539c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
25409b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan    IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(),
25414fbe61ba371bfde827b9424ebe5e14dce3d5fad3Sean Callanan                                             (m_module->getPointerSize() == Module::Pointer64) ? 64 : 32);
2542c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
2543c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    Constant *relocated_addr = ConstantInt::get(intptr_ty, (uint64_t)allocation);
2544c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    Constant *relocated_bitcast = ConstantExpr::getIntToPtr(relocated_addr, llvm::Type::getInt8PtrTy(m_module->getContext()));
2545c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
2546c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    m_reloc_placeholder->replaceAllUsesWith(relocated_bitcast);
2547c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
2548c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    m_reloc_placeholder->eraseFromParent();
2549c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
2550c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    return true;
2551c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan}
2552c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
25535cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callananbool
255406dc17f8eb821d7256fd42e56f85c2779a29f689Sean CallananIRForTarget::StripAllGVs (Module &llvm_module)
255506dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan{
2556952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
255706dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan    std::vector<GlobalVariable *> global_vars;
255806dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan    std::set<GlobalVariable *>erased_vars;
255906dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan
256006dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan    bool erased = true;
256106dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan
256206dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan    while (erased)
256306dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan    {
256406dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan        erased = false;
256506dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan
256606dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan        for (Module::global_iterator gi = llvm_module.global_begin(), ge = llvm_module.global_end();
256706dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan             gi != ge;
256806dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan             ++gi)
256906dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan        {
257006dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan            GlobalVariable *global_var = dyn_cast<GlobalVariable>(gi);
257106dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan
257206dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan            global_var->removeDeadConstantUsers();
257306dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan
257406dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan            if (global_var->use_empty())
257506dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan            {
257606dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan                if (log)
257706dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan                    log->Printf("Did remove %s",
257806dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan                                PrintValue(global_var).c_str());
257906dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan                global_var->eraseFromParent();
258006dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan                erased = true;
258106dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan                break;
258206dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan            }
258306dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan        }
258406dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan    }
258506dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan
258606dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan    for (Module::global_iterator gi = llvm_module.global_begin(), ge = llvm_module.global_end();
258706dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan         gi != ge;
258806dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan         ++gi)
258906dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan    {
259006dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan        GlobalVariable *global_var = dyn_cast<GlobalVariable>(gi);
259106dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan
259206dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan        GlobalValue::use_iterator ui = global_var->use_begin();
259306dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan
25940052123c1f8cd5ad42756f0205e93c9fd11bdcb2Jim Ingham        if (log)
25950052123c1f8cd5ad42756f0205e93c9fd11bdcb2Jim Ingham            log->Printf("Couldn't remove %s because of %s",
25960052123c1f8cd5ad42756f0205e93c9fd11bdcb2Jim Ingham                        PrintValue(global_var).c_str(),
25970052123c1f8cd5ad42756f0205e93c9fd11bdcb2Jim Ingham                        PrintValue(*ui).c_str());
259806dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan    }
259906dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan
260006dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan    return true;
260106dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan}
260206dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan
260306dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callananbool
26043c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg ClaytonIRForTarget::runOnModule (Module &llvm_module)
26055cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan{
2606952e9dc874944fcdbbb224f3ec4fc2c859376f64Greg Clayton    lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
26075cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan
2608c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    m_module = &llvm_module;
26093051ed73a487e92f12f8b6062f8415781453da21Micah Villmow    m_target_data.reset(new DataLayout(m_module));
26104a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
26114a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    if (log)
26124a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    {
26134a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan        std::string s;
26144a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan        raw_string_ostream oss(s);
26154a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
26164a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan        m_module->print(oss, NULL);
26174a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
26184a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan        oss.flush();
26194a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
26204a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan        log->Printf("Module as passed in to IRForTarget: \n\"%s\"", s.c_str());
26214a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    }
2622c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
26234a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    Function* main_function = m_module->getFunction(StringRef(m_func_name.c_str()));
26245cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan
26254a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    if (!main_function)
26265cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan    {
26275cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan        if (log)
2628b5037af312160b2f396aad579e45619af3126e4aGreg Clayton            log->Printf("Couldn't find \"%s()\" in the module", m_func_name.c_str());
262997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
263097c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan        if (m_error_stream)
2631c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            m_error_stream->Printf("Internal error [IRForTarget]: Couldn't find wrapper '%s' in the module", m_func_name.c_str());
26326a92553d2cc2b7a3b853fcb6da101583435c2dc0Sean Callanan
26335cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan        return false;
26345cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan    }
2635c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
26364a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    if (!FixFunctionLinkage (*main_function))
2637c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    {
2638c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        if (log)
2639c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            log->Printf("Couldn't fix the linkage for the function");
2640c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
2641c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        return false;
2642c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    }
2643c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
26449b6898f3ec1dedbe1dfc8bd7cd1d82a5b10e1bb0Sean Callanan    llvm::Type *intptr_ty = Type::getInt8Ty(m_module->getContext());
2645c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
26464a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    m_reloc_placeholder = new llvm::GlobalVariable((*m_module),
2647c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                                                   intptr_ty,
264806dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan                                                   false /* IsConstant */,
2649c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                                                   GlobalVariable::InternalLinkage,
2650c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                                                   Constant::getNullValue(intptr_ty),
2651c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                                                   "reloc_placeholder",
2652c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                                                   NULL /* InsertBefore */,
265306dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan                                                   GlobalVariable::NotThreadLocal /* ThreadLocal */,
2654c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan                                                   0 /* AddressSpace */);
26554a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
265682b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    ////////////////////////////////////////////////////////////
26578de27c761a22187ef63fb60000894be163e7285fGreg Clayton    // Replace $__lldb_expr_result with a persistent variable
265882b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan    //
265982b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan
26604a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    if (!CreateResultVariable(*main_function))
26613aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan    {
26623aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan        if (log)
26633aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            log->Printf("CreateResultVariable() failed");
266497c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
266597c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan        // CreateResultVariable() reports its own errors, so we don't do so here
266697c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
266782b74c85f719be67b78f9284a6a1341d47f7ac9cSean Callanan        return false;
26683aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan    }
26691850f94688f9362c78c27e5472afe022a56c08dfSean Callanan
26707b8eb76b6e96913bd26a6f5ad9d7667a66aabbc3Sean Callanan    if (log && log->GetVerbose())
2671c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    {
2672c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        std::string s;
2673c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        raw_string_ostream oss(s);
2674c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
2675c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        m_module->print(oss, NULL);
2676c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
2677c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        oss.flush();
2678c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
2679c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        log->Printf("Module after creating the result variable: \n\"%s\"", s.c_str());
2680c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    }
2681c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
26824a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    for (Module::iterator fi = m_module->begin(), fe = m_module->end();
26834a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan         fi != fe;
26844a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan         ++fi)
26854a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    {
26864a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan        llvm::Function *function = fi;
26874a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
26884a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan        if (function->begin() == function->end())
26894a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            continue;
26904a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
26914a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan        Function::iterator bbi;
26924a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
26934a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan        for (bbi = function->begin();
26944a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan             bbi != function->end();
26954a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan             ++bbi)
26964a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan        {
26974a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            if (!RemoveGuards(*bbi))
26984a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            {
26994a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                if (log)
27004a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                    log->Printf("RemoveGuards() failed");
27014a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
27024a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                // RemoveGuards() reports its own errors, so we don't do so here
27034a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
27044a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                return false;
27054a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            }
27064a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
27074a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            if (!RewritePersistentAllocs(*bbi))
27084a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            {
27094a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                if (log)
27104a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                    log->Printf("RewritePersistentAllocs() failed");
27114a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
27124a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                // RewritePersistentAllocs() reports its own errors, so we don't do so here
27134a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
27144a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                return false;
27154a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            }
27164a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
27174a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            if (!RemoveCXAAtExit(*bbi))
27184a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            {
27194a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                if (log)
27204a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                    log->Printf("RemoveCXAAtExit() failed");
27214a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
27224a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                // RemoveCXAAtExit() reports its own errors, so we don't do so here
27234a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
27244a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                return false;
27254a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            }
27264a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan        }
27274a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    }
27284a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
27296ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan    ///////////////////////////////////////////////////////////////////////////////
27306ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan    // Fix all Objective-C constant strings to use NSStringWithCString:encoding:
27316ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan    //
27324a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
27334a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    if (!RewriteObjCConstStrings())
27343aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan    {
27353aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan        if (log)
27363aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            log->Printf("RewriteObjCConstStrings() failed");
273797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
273897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan        // RewriteObjCConstStrings() reports its own errors, so we don't do so here
273997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
27406ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan        return false;
27413aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan    }
27426ba533e0b2220b2aac92d10f94d3cecedb199763Sean Callanan
27435c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    ///////////////////////////////
27445c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    // Resolve function pointers
27455c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    //
27465c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
27474a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    if (!ResolveFunctionPointers(llvm_module))
27485c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    {
27495c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan        if (log)
27505c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan            log->Printf("ResolveFunctionPointers() failed");
27515c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
27525c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan        // ResolveFunctionPointers() reports its own errors, so we don't do so here
27535c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
27545c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan        return false;
27555c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan    }
27565c9a3c7cce9da84d9eff1eb48ebadab32b1abe54Sean Callanan
27574a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    for (Module::iterator fi = m_module->begin(), fe = m_module->end();
27584a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan         fi != fe;
27594a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan         ++fi)
27605cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan    {
27614a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan        llvm::Function *function = fi;
27624a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
27634a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan        for (llvm::Function::iterator bbi = function->begin(), bbe = function->end();
27644a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan             bbi != bbe;
27654a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan             ++bbi)
27663aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan        {
27674a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            if (!RewriteObjCSelectors(*bbi))
27684a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            {
27694a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                if (log)
27704a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                    log->Printf("RewriteObjCSelectors() failed");
27714a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
27724a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                // RewriteObjCSelectors() reports its own errors, so we don't do so here
27734a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
27744a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                return false;
27754a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            }
27763aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan        }
2777083b37663cb6d880f989c6887085edf499e4525fSean Callanan    }
2778a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan
27794a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    for (Module::iterator fi = m_module->begin(), fe = m_module->end();
27804a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan         fi != fe;
27814a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan         ++fi)
2782083b37663cb6d880f989c6887085edf499e4525fSean Callanan    {
27834a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan        llvm::Function *function = fi;
2784c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
27854a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan        for (llvm::Function::iterator bbi = function->begin(), bbe = function->end();
27864a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan             bbi != bbe;
27874a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan             ++bbi)
2788c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        {
27894a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            if (!ResolveCalls(*bbi))
27904a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            {
27914a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                if (log)
27924a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                    log->Printf("ResolveCalls() failed");
27934a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
27944a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                // ResolveCalls() reports its own errors, so we don't do so here
27954a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
27964a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                return false;
27974a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            }
2798c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
27994a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            if (!ReplaceStaticLiterals(*bbi))
28004a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            {
28014a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                if (log)
28024a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                    log->Printf("ReplaceStaticLiterals() failed");
28034a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
28044a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan                return false;
28054a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan            }
2806c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        }
28078bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan    }
28084a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
28094a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    ////////////////////////////////////////////////////////////////////////
28104a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    // Run function-level passes that only make sense on the main function
2811771131d04344e57abb340699f54dce77a511bc71Sean Callanan    //
2812771131d04344e57abb340699f54dce77a511bc71Sean Callanan
28134a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    if (!ResolveExternals(*main_function))
28143aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan    {
28153aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan        if (log)
28163aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            log->Printf("ResolveExternals() failed");
281797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
281897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan        // ResolveExternals() reports its own errors, so we don't do so here
281997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
28201d1b39c93c64294ae1c6e5cfe6de584716c284bcSean Callanan        return false;
28213aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan    }
28221d1b39c93c64294ae1c6e5cfe6de584716c284bcSean Callanan
28234a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan    if (!ReplaceVariables(*main_function))
28243aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan    {
28253aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan        if (log)
28263aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan            log->Printf("ReplaceVariables() failed");
282797c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
282897c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan        // ReplaceVariables() reports its own errors, so we don't do so here
282997c924e1ff142ea29a2f7b41cbcdcb0082b76959Sean Callanan
2830771131d04344e57abb340699f54dce77a511bc71Sean Callanan        return false;
28313aa7da5cb3327792415de44405e0896c6bdc305bSean Callanan    }
28324a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
2833c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    if (!ReplaceStrings())
2834c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    {
2835c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        if (log)
2836c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            log->Printf("ReplaceStrings() failed");
2837c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
2838c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        return false;
2839c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    }
2840c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
2841c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    if (!CompleteDataAllocation())
2842c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    {
2843c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        if (log)
2844c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan            log->Printf("CompleteDataAllocation() failed");
2845c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan
2846c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        return false;
2847c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan    }
28484a20587f56a05955ea94f650cb39245a092b0c69Sean Callanan
284906dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan    if (!StripAllGVs(llvm_module))
285006dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan    {
285106dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan        if (log)
285206dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan            log->Printf("StripAllGVs() failed");
285306dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan    }
285406dc17f8eb821d7256fd42e56f85c2779a29f689Sean Callanan
28557b8eb76b6e96913bd26a6f5ad9d7667a66aabbc3Sean Callanan    if (log && log->GetVerbose())
28568bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan    {
2857321fe9e06c68dfeed55839d71603713b1ea3bb70Sean Callanan        std::string s;
2858321fe9e06c68dfeed55839d71603713b1ea3bb70Sean Callanan        raw_string_ostream oss(s);
2859321fe9e06c68dfeed55839d71603713b1ea3bb70Sean Callanan
2860c0492741dc594cd02736521048fe0d8f4c9a0a61Sean Callanan        m_module->print(oss, NULL);
2861321fe9e06c68dfeed55839d71603713b1ea3bb70Sean Callanan
2862321fe9e06c68dfeed55839d71603713b1ea3bb70Sean Callanan        oss.flush();
28638bce665569ea08dd43d9ff21e23f14ebbc191d12Sean Callanan
2864b5037af312160b2f396aad579e45619af3126e4aGreg Clayton        log->Printf("Module after preparing for execution: \n\"%s\"", s.c_str());
28655cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan    }
28665cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan
28675cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan    return true;
28685cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan}
28695cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan
28705cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callananvoid
28713c7feb44971e0adf121c9b72a4eb5eb2896fe66dGreg ClaytonIRForTarget::assignPassManager (PMStack &pass_mgr_stack, PassManagerType pass_mgr_type)
28725cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan{
28735cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan}
28745cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan
28755cf4a1ca412654c3f912e2b3cea931fb814f322fSean CallananPassManagerType
28765cf4a1ca412654c3f912e2b3cea931fb814f322fSean CallananIRForTarget::getPotentialPassManagerType() const
28775cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan{
28785cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan    return PMT_ModulePassManager;
28795cf4a1ca412654c3f912e2b3cea931fb814f322fSean Callanan}
2880