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 ¤t_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