1ac7ddfbfSEd Maste //===-- ExpressionSourceCode.cpp --------------------------------*- C++ -*-===//
2ac7ddfbfSEd Maste //
3ac7ddfbfSEd Maste //                     The LLVM Compiler Infrastructure
4ac7ddfbfSEd Maste //
5ac7ddfbfSEd Maste // This file is distributed under the University of Illinois Open Source
6ac7ddfbfSEd Maste // License. See LICENSE.TXT for details.
7ac7ddfbfSEd Maste //
8ac7ddfbfSEd Maste //===----------------------------------------------------------------------===//
9ac7ddfbfSEd Maste 
10ac7ddfbfSEd Maste #include "lldb/Expression/ExpressionSourceCode.h"
11ac7ddfbfSEd Maste 
12ac7ddfbfSEd Maste #include "lldb/Core/StreamString.h"
139f2f44ceSEd Maste #include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h"
149f2f44ceSEd Maste #include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
159f2f44ceSEd Maste #include "lldb/Symbol/CompileUnit.h"
169f2f44ceSEd Maste #include "lldb/Symbol/DebugMacros.h"
171c3bbb01SEd Maste #include "lldb/Symbol/Block.h"
189f2f44ceSEd Maste #include "lldb/Symbol/TypeSystem.h"
194bb0738eSEd Maste #include "lldb/Symbol/VariableList.h"
200127ef0fSEd Maste #include "lldb/Target/ExecutionContext.h"
214bb0738eSEd Maste #include "lldb/Target/Language.h"
220127ef0fSEd Maste #include "lldb/Target/Platform.h"
231c3bbb01SEd Maste #include "lldb/Target/StackFrame.h"
240127ef0fSEd Maste #include "lldb/Target/Target.h"
25ac7ddfbfSEd Maste 
26ac7ddfbfSEd Maste using namespace lldb_private;
27ac7ddfbfSEd Maste 
28ac7ddfbfSEd Maste const char *
29ac7ddfbfSEd Maste ExpressionSourceCode::g_expression_prefix = R"(
301c3bbb01SEd Maste #ifndef NULL
31ac7ddfbfSEd Maste #define NULL (__null)
321c3bbb01SEd Maste #endif
331c3bbb01SEd Maste #ifndef Nil
34ac7ddfbfSEd Maste #define Nil (__null)
351c3bbb01SEd Maste #endif
361c3bbb01SEd Maste #ifndef nil
37ac7ddfbfSEd Maste #define nil (__null)
381c3bbb01SEd Maste #endif
391c3bbb01SEd Maste #ifndef YES
40ac7ddfbfSEd Maste #define YES ((BOOL)1)
411c3bbb01SEd Maste #endif
421c3bbb01SEd Maste #ifndef NO
43ac7ddfbfSEd Maste #define NO ((BOOL)0)
441c3bbb01SEd Maste #endif
450127ef0fSEd Maste typedef __INT8_TYPE__ int8_t;
460127ef0fSEd Maste typedef __UINT8_TYPE__ uint8_t;
470127ef0fSEd Maste typedef __INT16_TYPE__ int16_t;
480127ef0fSEd Maste typedef __UINT16_TYPE__ uint16_t;
490127ef0fSEd Maste typedef __INT32_TYPE__ int32_t;
500127ef0fSEd Maste typedef __UINT32_TYPE__ uint32_t;
510127ef0fSEd Maste typedef __INT64_TYPE__ int64_t;
520127ef0fSEd Maste typedef __UINT64_TYPE__ uint64_t;
530127ef0fSEd Maste typedef __INTPTR_TYPE__ intptr_t;
540127ef0fSEd Maste typedef __UINTPTR_TYPE__ uintptr_t;
55ac7ddfbfSEd Maste typedef __SIZE_TYPE__ size_t;
56ac7ddfbfSEd Maste typedef __PTRDIFF_TYPE__ ptrdiff_t;
57ac7ddfbfSEd Maste typedef unsigned short unichar;
581c3bbb01SEd Maste extern "C"
591c3bbb01SEd Maste {
601c3bbb01SEd Maste     int printf(const char * __restrict, ...);
611c3bbb01SEd Maste }
62ac7ddfbfSEd Maste )";
63ac7ddfbfSEd Maste 
644bb0738eSEd Maste static const char *c_start_marker = "    /*LLDB_BODY_START*/\n    ";
654bb0738eSEd Maste static const char *c_end_marker   = ";\n    /*LLDB_BODY_END*/\n";
664bb0738eSEd Maste 
679f2f44ceSEd Maste namespace {
689f2f44ceSEd Maste 
699f2f44ceSEd Maste class AddMacroState
709f2f44ceSEd Maste {
719f2f44ceSEd Maste     enum State
729f2f44ceSEd Maste     {
739f2f44ceSEd Maste         CURRENT_FILE_NOT_YET_PUSHED,
749f2f44ceSEd Maste         CURRENT_FILE_PUSHED,
759f2f44ceSEd Maste         CURRENT_FILE_POPPED
769f2f44ceSEd Maste     };
779f2f44ceSEd Maste 
789f2f44ceSEd Maste public:
799f2f44ceSEd Maste     AddMacroState(const FileSpec &current_file, const uint32_t current_file_line)
809f2f44ceSEd Maste         : m_state(CURRENT_FILE_NOT_YET_PUSHED),
819f2f44ceSEd Maste           m_current_file(current_file),
829f2f44ceSEd Maste           m_current_file_line(current_file_line)
839f2f44ceSEd Maste     { }
849f2f44ceSEd Maste 
859f2f44ceSEd Maste     void
869f2f44ceSEd Maste     StartFile(const FileSpec &file)
879f2f44ceSEd Maste     {
889f2f44ceSEd Maste         m_file_stack.push_back(file);
899f2f44ceSEd Maste         if (file == m_current_file)
909f2f44ceSEd Maste             m_state = CURRENT_FILE_PUSHED;
919f2f44ceSEd Maste     }
929f2f44ceSEd Maste 
939f2f44ceSEd Maste     void
949f2f44ceSEd Maste     EndFile()
959f2f44ceSEd Maste     {
969f2f44ceSEd Maste         if (m_file_stack.size() == 0)
979f2f44ceSEd Maste             return;
989f2f44ceSEd Maste 
999f2f44ceSEd Maste         FileSpec old_top = m_file_stack.back();
1009f2f44ceSEd Maste         m_file_stack.pop_back();
1019f2f44ceSEd Maste         if (old_top == m_current_file)
1029f2f44ceSEd Maste             m_state = CURRENT_FILE_POPPED;
1039f2f44ceSEd Maste     }
1049f2f44ceSEd Maste 
1059f2f44ceSEd Maste     // An entry is valid if it occurs before the current line in
1069f2f44ceSEd Maste     // the current file.
1079f2f44ceSEd Maste     bool
1089f2f44ceSEd Maste     IsValidEntry(uint32_t line)
1099f2f44ceSEd Maste     {
1109f2f44ceSEd Maste         switch (m_state)
1119f2f44ceSEd Maste         {
1129f2f44ceSEd Maste             case CURRENT_FILE_NOT_YET_PUSHED:
1139f2f44ceSEd Maste                 return true;
1149f2f44ceSEd Maste             case CURRENT_FILE_PUSHED:
1159f2f44ceSEd Maste                 // If we are in file included in the current file,
1169f2f44ceSEd Maste                 // the entry should be added.
1179f2f44ceSEd Maste                 if (m_file_stack.back() != m_current_file)
1189f2f44ceSEd Maste                     return true;
1199f2f44ceSEd Maste 
1209f2f44ceSEd Maste                 if (line >= m_current_file_line)
1219f2f44ceSEd Maste                     return false;
1229f2f44ceSEd Maste                 else
1239f2f44ceSEd Maste                     return true;
1244bb0738eSEd Maste             default:
1254bb0738eSEd Maste                 return false;
1269f2f44ceSEd Maste         }
1279f2f44ceSEd Maste     }
1289f2f44ceSEd Maste 
1299f2f44ceSEd Maste private:
1309f2f44ceSEd Maste     std::vector<FileSpec> m_file_stack;
1319f2f44ceSEd Maste     State m_state;
1329f2f44ceSEd Maste     FileSpec m_current_file;
1339f2f44ceSEd Maste     uint32_t m_current_file_line;
1349f2f44ceSEd Maste };
1359f2f44ceSEd Maste 
1369f2f44ceSEd Maste } // anonymous namespace
1379f2f44ceSEd Maste 
1389f2f44ceSEd Maste static void
1399f2f44ceSEd Maste AddMacros(const DebugMacros *dm, CompileUnit *comp_unit, AddMacroState &state, StreamString &stream)
1409f2f44ceSEd Maste {
1419f2f44ceSEd Maste     if (dm == nullptr)
1429f2f44ceSEd Maste         return;
1439f2f44ceSEd Maste 
1449f2f44ceSEd Maste     for (size_t i = 0; i < dm->GetNumMacroEntries(); i++)
1459f2f44ceSEd Maste     {
1469f2f44ceSEd Maste         const DebugMacroEntry &entry = dm->GetMacroEntryAtIndex(i);
1479f2f44ceSEd Maste         uint32_t line;
1489f2f44ceSEd Maste 
1499f2f44ceSEd Maste         switch (entry.GetType())
1509f2f44ceSEd Maste         {
1519f2f44ceSEd Maste             case DebugMacroEntry::DEFINE:
1529f2f44ceSEd Maste                 if (state.IsValidEntry(entry.GetLineNumber()))
1539f2f44ceSEd Maste                     stream.Printf("#define %s\n", entry.GetMacroString().AsCString());
1549f2f44ceSEd Maste                 else
1559f2f44ceSEd Maste                     return;
1569f2f44ceSEd Maste                 break;
1579f2f44ceSEd Maste             case DebugMacroEntry::UNDEF:
1589f2f44ceSEd Maste                 if (state.IsValidEntry(entry.GetLineNumber()))
1599f2f44ceSEd Maste                     stream.Printf("#undef %s\n", entry.GetMacroString().AsCString());
1609f2f44ceSEd Maste                 else
1619f2f44ceSEd Maste                     return;
1629f2f44ceSEd Maste                 break;
1639f2f44ceSEd Maste             case DebugMacroEntry::START_FILE:
1649f2f44ceSEd Maste                 line = entry.GetLineNumber();
1659f2f44ceSEd Maste                 if (state.IsValidEntry(line))
1669f2f44ceSEd Maste                     state.StartFile(entry.GetFileSpec(comp_unit));
1679f2f44ceSEd Maste                 else
1689f2f44ceSEd Maste                     return;
1699f2f44ceSEd Maste                 break;
1709f2f44ceSEd Maste             case DebugMacroEntry::END_FILE:
1719f2f44ceSEd Maste                 state.EndFile();
1729f2f44ceSEd Maste                 break;
1739f2f44ceSEd Maste             case DebugMacroEntry::INDIRECT:
1749f2f44ceSEd Maste                 AddMacros(entry.GetIndirectDebugMacros(), comp_unit, state, stream);
1759f2f44ceSEd Maste                 break;
1769f2f44ceSEd Maste             default:
1779f2f44ceSEd Maste                 // This is an unknown/invalid entry. Ignore.
1789f2f44ceSEd Maste                 break;
1799f2f44ceSEd Maste         }
1809f2f44ceSEd Maste     }
1819f2f44ceSEd Maste }
182ac7ddfbfSEd Maste 
1834bb0738eSEd Maste static void
1844bb0738eSEd Maste AddLocalVariableDecls(const lldb::VariableListSP &var_list_sp, StreamString &stream)
1854bb0738eSEd Maste {
1864bb0738eSEd Maste     for (size_t i = 0; i < var_list_sp->GetSize(); i++)
1874bb0738eSEd Maste     {
1884bb0738eSEd Maste         lldb::VariableSP var_sp = var_list_sp->GetVariableAtIndex(i);
1894bb0738eSEd Maste 
1904bb0738eSEd Maste         ConstString var_name = var_sp->GetName();
1914bb0738eSEd Maste         if (!var_name || var_name == ConstString("this") || var_name == ConstString(".block_descriptor"))
1924bb0738eSEd Maste             continue;
1934bb0738eSEd Maste 
1944bb0738eSEd Maste         stream.Printf("using $__lldb_local_vars::%s;\n", var_name.AsCString());
1954bb0738eSEd Maste     }
1964bb0738eSEd Maste }
1974bb0738eSEd Maste 
1984bb0738eSEd Maste bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrapping_language, bool static_method, ExecutionContext &exe_ctx) const
199ac7ddfbfSEd Maste {
2000127ef0fSEd Maste     const char *target_specific_defines = "typedef signed char BOOL;\n";
2011c3bbb01SEd Maste     std::string module_macros;
2020127ef0fSEd Maste 
2034bb0738eSEd Maste     Target *target = exe_ctx.GetTargetPtr();
2044bb0738eSEd Maste     if (target)
2050127ef0fSEd Maste     {
2060127ef0fSEd Maste         if (target->GetArchitecture().GetMachine() == llvm::Triple::aarch64)
2070127ef0fSEd Maste         {
2080127ef0fSEd Maste             target_specific_defines = "typedef bool BOOL;\n";
2090127ef0fSEd Maste         }
2100127ef0fSEd Maste         if (target->GetArchitecture().GetMachine() == llvm::Triple::x86_64)
2110127ef0fSEd Maste         {
2120127ef0fSEd Maste             if (lldb::PlatformSP platform_sp = target->GetPlatform())
2130127ef0fSEd Maste             {
2141c3bbb01SEd Maste                 static ConstString g_platform_ios_simulator ("ios-simulator");
2150127ef0fSEd Maste                 if (platform_sp->GetPluginName() == g_platform_ios_simulator)
2160127ef0fSEd Maste                 {
2170127ef0fSEd Maste                     target_specific_defines = "typedef bool BOOL;\n";
2180127ef0fSEd Maste                 }
2190127ef0fSEd Maste             }
2200127ef0fSEd Maste         }
2211c3bbb01SEd Maste 
2221c3bbb01SEd Maste         if (ClangModulesDeclVendor *decl_vendor = target->GetClangModulesDeclVendor())
2231c3bbb01SEd Maste         {
2249f2f44ceSEd Maste             ClangPersistentVariables *persistent_vars = llvm::cast<ClangPersistentVariables>(target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC));
2259f2f44ceSEd Maste             const ClangModulesDeclVendor::ModuleVector &hand_imported_modules = persistent_vars->GetHandLoadedClangModules();
2261c3bbb01SEd Maste             ClangModulesDeclVendor::ModuleVector modules_for_macros;
2271c3bbb01SEd Maste 
2281c3bbb01SEd Maste             for (ClangModulesDeclVendor::ModuleID module : hand_imported_modules)
2291c3bbb01SEd Maste             {
2301c3bbb01SEd Maste                 modules_for_macros.push_back(module);
2311c3bbb01SEd Maste             }
2321c3bbb01SEd Maste 
2331c3bbb01SEd Maste             if (target->GetEnableAutoImportClangModules())
2341c3bbb01SEd Maste             {
2351c3bbb01SEd Maste                 if (StackFrame *frame = exe_ctx.GetFramePtr())
2361c3bbb01SEd Maste                 {
2371c3bbb01SEd Maste                     if (Block *block = frame->GetFrameBlock())
2381c3bbb01SEd Maste                     {
2391c3bbb01SEd Maste                         SymbolContext sc;
2401c3bbb01SEd Maste 
2411c3bbb01SEd Maste                         block->CalculateSymbolContext(&sc);
2421c3bbb01SEd Maste 
2431c3bbb01SEd Maste                         if (sc.comp_unit)
2441c3bbb01SEd Maste                         {
2451c3bbb01SEd Maste                             StreamString error_stream;
2461c3bbb01SEd Maste 
2471c3bbb01SEd Maste                             decl_vendor->AddModulesForCompileUnit(*sc.comp_unit, modules_for_macros, error_stream);
2481c3bbb01SEd Maste                         }
2491c3bbb01SEd Maste                     }
2501c3bbb01SEd Maste                 }
2511c3bbb01SEd Maste             }
2521c3bbb01SEd Maste 
2531c3bbb01SEd Maste             decl_vendor->ForEachMacro(modules_for_macros, [&module_macros] (const std::string &expansion) -> bool {
2541c3bbb01SEd Maste                 module_macros.append(expansion);
2551c3bbb01SEd Maste                 module_macros.append("\n");
2561c3bbb01SEd Maste                 return false;
2571c3bbb01SEd Maste             });
2581c3bbb01SEd Maste         }
2591c3bbb01SEd Maste 
2600127ef0fSEd Maste     }
2610127ef0fSEd Maste 
2629f2f44ceSEd Maste     StreamString debug_macros_stream;
2634bb0738eSEd Maste     StreamString lldb_local_var_decls;
2649f2f44ceSEd Maste     if (StackFrame *frame = exe_ctx.GetFramePtr())
2659f2f44ceSEd Maste     {
2669f2f44ceSEd Maste         const SymbolContext &sc = frame->GetSymbolContext(
2679f2f44ceSEd Maste            lldb:: eSymbolContextCompUnit | lldb::eSymbolContextLineEntry);
2689f2f44ceSEd Maste 
2699f2f44ceSEd Maste         if (sc.comp_unit && sc.line_entry.IsValid())
2709f2f44ceSEd Maste         {
2719f2f44ceSEd Maste             DebugMacros *dm = sc.comp_unit->GetDebugMacros();
2729f2f44ceSEd Maste             if (dm)
2739f2f44ceSEd Maste             {
2749f2f44ceSEd Maste                 AddMacroState state(sc.line_entry.file, sc.line_entry.line);
2759f2f44ceSEd Maste                 AddMacros(dm, sc.comp_unit, state, debug_macros_stream);
2769f2f44ceSEd Maste             }
2779f2f44ceSEd Maste         }
2784bb0738eSEd Maste 
2794bb0738eSEd Maste         ConstString object_name;
2804bb0738eSEd Maste         if (Language::LanguageIsCPlusPlus(frame->GetLanguage()))
2814bb0738eSEd Maste         {
2824bb0738eSEd Maste             if (target->GetInjectLocalVariables(&exe_ctx))
2834bb0738eSEd Maste             {
2844bb0738eSEd Maste                 lldb::VariableListSP var_list_sp = frame->GetInScopeVariableList(false, true);
2854bb0738eSEd Maste                 AddLocalVariableDecls(var_list_sp, lldb_local_var_decls);
2864bb0738eSEd Maste             }
2874bb0738eSEd Maste         }
2889f2f44ceSEd Maste     }
2899f2f44ceSEd Maste 
290ac7ddfbfSEd Maste     if (m_wrap)
291ac7ddfbfSEd Maste     {
292ac7ddfbfSEd Maste         switch (wrapping_language)
293ac7ddfbfSEd Maste         {
294ac7ddfbfSEd Maste         default:
295ac7ddfbfSEd Maste             return false;
296ac7ddfbfSEd Maste         case lldb::eLanguageTypeC:
297ac7ddfbfSEd Maste         case lldb::eLanguageTypeC_plus_plus:
298ac7ddfbfSEd Maste         case lldb::eLanguageTypeObjC:
299ac7ddfbfSEd Maste             break;
300ac7ddfbfSEd Maste         }
301ac7ddfbfSEd Maste 
302ac7ddfbfSEd Maste         StreamString wrap_stream;
303ac7ddfbfSEd Maste 
3049f2f44ceSEd Maste         wrap_stream.Printf("%s\n%s\n%s\n%s\n%s\n",
3051c3bbb01SEd Maste                            module_macros.c_str(),
3069f2f44ceSEd Maste                            debug_macros_stream.GetData(),
3071c3bbb01SEd Maste                            g_expression_prefix,
3081c3bbb01SEd Maste                            target_specific_defines,
3091c3bbb01SEd Maste                            m_prefix.c_str());
3101c3bbb01SEd Maste 
3114bb0738eSEd Maste         // First construct a tagged form of the user expression so we can find it later:
3124bb0738eSEd Maste         std::string tagged_body;
3134bb0738eSEd Maste         switch (wrapping_language)
3144bb0738eSEd Maste         {
3154bb0738eSEd Maste             default:
3164bb0738eSEd Maste                 tagged_body = m_body;
3174bb0738eSEd Maste                 break;
3184bb0738eSEd Maste             case lldb::eLanguageTypeC:
3194bb0738eSEd Maste             case lldb::eLanguageTypeC_plus_plus:
3204bb0738eSEd Maste             case lldb::eLanguageTypeObjC:
3214bb0738eSEd Maste                 tagged_body.append(c_start_marker);
3224bb0738eSEd Maste                 tagged_body.append(m_body);
3234bb0738eSEd Maste                 tagged_body.append(c_end_marker);
3244bb0738eSEd Maste                 break;
3254bb0738eSEd Maste 
3264bb0738eSEd Maste         }
327ac7ddfbfSEd Maste         switch (wrapping_language)
328ac7ddfbfSEd Maste         {
329ac7ddfbfSEd Maste         default:
330ac7ddfbfSEd Maste             break;
331ac7ddfbfSEd Maste         case lldb::eLanguageTypeC:
3321c3bbb01SEd Maste             wrap_stream.Printf("void                           \n"
333ac7ddfbfSEd Maste                                "%s(void *$__lldb_arg)          \n"
334ac7ddfbfSEd Maste                                "{                              \n"
335ac7ddfbfSEd Maste                                "    %s;                        \n"
3364bb0738eSEd Maste                                "%s"
337ac7ddfbfSEd Maste                                "}                              \n",
338ac7ddfbfSEd Maste                                m_name.c_str(),
3394bb0738eSEd Maste                                lldb_local_var_decls.GetData(),
3404bb0738eSEd Maste                                tagged_body.c_str());
341ac7ddfbfSEd Maste             break;
342ac7ddfbfSEd Maste         case lldb::eLanguageTypeC_plus_plus:
3431c3bbb01SEd Maste             wrap_stream.Printf("void                                   \n"
3444bb0738eSEd Maste                                "$__lldb_class::%s(void *$__lldb_arg)   \n"
345ac7ddfbfSEd Maste                                "{                                      \n"
346ac7ddfbfSEd Maste                                "    %s;                                \n"
3474bb0738eSEd Maste                                "%s"
348ac7ddfbfSEd Maste                                "}                                      \n",
349ac7ddfbfSEd Maste                                m_name.c_str(),
3504bb0738eSEd Maste                                lldb_local_var_decls.GetData(),
3514bb0738eSEd Maste                                tagged_body.c_str());
352ac7ddfbfSEd Maste             break;
353ac7ddfbfSEd Maste         case lldb::eLanguageTypeObjC:
354ac7ddfbfSEd Maste             if (static_method)
355ac7ddfbfSEd Maste             {
3561c3bbb01SEd Maste                 wrap_stream.Printf("@interface $__lldb_objc_class ($__lldb_category)        \n"
357ac7ddfbfSEd Maste                                    "+(void)%s:(void *)$__lldb_arg;                          \n"
358ac7ddfbfSEd Maste                                    "@end                                                    \n"
359ac7ddfbfSEd Maste                                    "@implementation $__lldb_objc_class ($__lldb_category)   \n"
360ac7ddfbfSEd Maste                                    "+(void)%s:(void *)$__lldb_arg                           \n"
361ac7ddfbfSEd Maste                                    "{                                                       \n"
3624bb0738eSEd Maste                                    "%s"
363ac7ddfbfSEd Maste                                    "}                                                       \n"
364ac7ddfbfSEd Maste                                    "@end                                                    \n",
365ac7ddfbfSEd Maste                                    m_name.c_str(),
366ac7ddfbfSEd Maste                                    m_name.c_str(),
3674bb0738eSEd Maste                                    tagged_body.c_str());
368ac7ddfbfSEd Maste             }
369ac7ddfbfSEd Maste             else
370ac7ddfbfSEd Maste             {
3711c3bbb01SEd Maste                 wrap_stream.Printf("@interface $__lldb_objc_class ($__lldb_category)       \n"
372ac7ddfbfSEd Maste                                    "-(void)%s:(void *)$__lldb_arg;                         \n"
373ac7ddfbfSEd Maste                                    "@end                                                   \n"
374ac7ddfbfSEd Maste                                    "@implementation $__lldb_objc_class ($__lldb_category)  \n"
375ac7ddfbfSEd Maste                                    "-(void)%s:(void *)$__lldb_arg                          \n"
376ac7ddfbfSEd Maste                                    "{                                                      \n"
3774bb0738eSEd Maste                                    "%s"
378ac7ddfbfSEd Maste                                    "}                                                      \n"
379ac7ddfbfSEd Maste                                    "@end                                                   \n",
380ac7ddfbfSEd Maste                                    m_name.c_str(),
381ac7ddfbfSEd Maste                                    m_name.c_str(),
3824bb0738eSEd Maste                                    tagged_body.c_str());
383ac7ddfbfSEd Maste             }
384ac7ddfbfSEd Maste             break;
385ac7ddfbfSEd Maste         }
386ac7ddfbfSEd Maste 
387ac7ddfbfSEd Maste         text = wrap_stream.GetString();
388ac7ddfbfSEd Maste     }
389ac7ddfbfSEd Maste     else
390ac7ddfbfSEd Maste     {
391ac7ddfbfSEd Maste         text.append(m_body);
392ac7ddfbfSEd Maste     }
393ac7ddfbfSEd Maste 
394ac7ddfbfSEd Maste     return true;
395ac7ddfbfSEd Maste }
3964bb0738eSEd Maste 
3974bb0738eSEd Maste bool
3984bb0738eSEd Maste ExpressionSourceCode::GetOriginalBodyBounds(std::string transformed_text,
3994bb0738eSEd Maste                                             lldb::LanguageType wrapping_language,
4004bb0738eSEd Maste                                             size_t &start_loc,
4014bb0738eSEd Maste                                             size_t &end_loc)
4024bb0738eSEd Maste {
4034bb0738eSEd Maste     const char *start_marker;
4044bb0738eSEd Maste     const char *end_marker;
4054bb0738eSEd Maste 
4064bb0738eSEd Maste     switch (wrapping_language)
4074bb0738eSEd Maste     {
4084bb0738eSEd Maste     default:
4094bb0738eSEd Maste         return false;
4104bb0738eSEd Maste     case lldb::eLanguageTypeC:
4114bb0738eSEd Maste     case lldb::eLanguageTypeC_plus_plus:
4124bb0738eSEd Maste     case lldb::eLanguageTypeObjC:
4134bb0738eSEd Maste         start_marker = c_start_marker;
4144bb0738eSEd Maste         end_marker = c_end_marker;
4154bb0738eSEd Maste         break;
4164bb0738eSEd Maste     }
4174bb0738eSEd Maste 
4184bb0738eSEd Maste     start_loc = transformed_text.find(start_marker);
4194bb0738eSEd Maste     if (start_loc == std::string::npos)
4204bb0738eSEd Maste         return false;
4214bb0738eSEd Maste     start_loc += strlen(start_marker);
4224bb0738eSEd Maste     end_loc  = transformed_text.find(end_marker);
4234bb0738eSEd Maste     if (end_loc == std::string::npos)
4244bb0738eSEd Maste         return false;
4254bb0738eSEd Maste     return true;
4264bb0738eSEd Maste }
4274bb0738eSEd Maste 
428