1*ea401ec7SJim Ingham //===-- ClangExpressionSourceCode.cpp ---------------------------*- C++ -*-===// 2*ea401ec7SJim Ingham // 3*ea401ec7SJim Ingham // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*ea401ec7SJim Ingham // See https://llvm.org/LICENSE.txt for license information. 5*ea401ec7SJim Ingham // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*ea401ec7SJim Ingham // 7*ea401ec7SJim Ingham //===----------------------------------------------------------------------===// 8*ea401ec7SJim Ingham 9*ea401ec7SJim Ingham #include "ClangExpressionSourceCode.h" 10*ea401ec7SJim Ingham 11*ea401ec7SJim Ingham #include "Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.h" 12*ea401ec7SJim Ingham #include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h" 13*ea401ec7SJim Ingham #include "lldb/Symbol/Block.h" 14*ea401ec7SJim Ingham #include "lldb/Symbol/CompileUnit.h" 15*ea401ec7SJim Ingham #include "lldb/Symbol/DebugMacros.h" 16*ea401ec7SJim Ingham #include "lldb/Symbol/TypeSystem.h" 17*ea401ec7SJim Ingham #include "lldb/Symbol/VariableList.h" 18*ea401ec7SJim Ingham #include "lldb/Target/ExecutionContext.h" 19*ea401ec7SJim Ingham #include "lldb/Target/Language.h" 20*ea401ec7SJim Ingham #include "lldb/Target/Platform.h" 21*ea401ec7SJim Ingham #include "lldb/Target/StackFrame.h" 22*ea401ec7SJim Ingham #include "lldb/Target/Target.h" 23*ea401ec7SJim Ingham #include "lldb/Utility/StreamString.h" 24*ea401ec7SJim Ingham 25*ea401ec7SJim Ingham using namespace lldb_private; 26*ea401ec7SJim Ingham 27*ea401ec7SJim Ingham const char *ClangExpressionSourceCode::g_expression_prefix = R"( 28*ea401ec7SJim Ingham #ifndef NULL 29*ea401ec7SJim Ingham #define NULL (__null) 30*ea401ec7SJim Ingham #endif 31*ea401ec7SJim Ingham #ifndef Nil 32*ea401ec7SJim Ingham #define Nil (__null) 33*ea401ec7SJim Ingham #endif 34*ea401ec7SJim Ingham #ifndef nil 35*ea401ec7SJim Ingham #define nil (__null) 36*ea401ec7SJim Ingham #endif 37*ea401ec7SJim Ingham #ifndef YES 38*ea401ec7SJim Ingham #define YES ((BOOL)1) 39*ea401ec7SJim Ingham #endif 40*ea401ec7SJim Ingham #ifndef NO 41*ea401ec7SJim Ingham #define NO ((BOOL)0) 42*ea401ec7SJim Ingham #endif 43*ea401ec7SJim Ingham typedef __INT8_TYPE__ int8_t; 44*ea401ec7SJim Ingham typedef __UINT8_TYPE__ uint8_t; 45*ea401ec7SJim Ingham typedef __INT16_TYPE__ int16_t; 46*ea401ec7SJim Ingham typedef __UINT16_TYPE__ uint16_t; 47*ea401ec7SJim Ingham typedef __INT32_TYPE__ int32_t; 48*ea401ec7SJim Ingham typedef __UINT32_TYPE__ uint32_t; 49*ea401ec7SJim Ingham typedef __INT64_TYPE__ int64_t; 50*ea401ec7SJim Ingham typedef __UINT64_TYPE__ uint64_t; 51*ea401ec7SJim Ingham typedef __INTPTR_TYPE__ intptr_t; 52*ea401ec7SJim Ingham typedef __UINTPTR_TYPE__ uintptr_t; 53*ea401ec7SJim Ingham typedef __SIZE_TYPE__ size_t; 54*ea401ec7SJim Ingham typedef __PTRDIFF_TYPE__ ptrdiff_t; 55*ea401ec7SJim Ingham typedef unsigned short unichar; 56*ea401ec7SJim Ingham extern "C" 57*ea401ec7SJim Ingham { 58*ea401ec7SJim Ingham int printf(const char * __restrict, ...); 59*ea401ec7SJim Ingham } 60*ea401ec7SJim Ingham )"; 61*ea401ec7SJim Ingham 62*ea401ec7SJim Ingham static const char *c_start_marker = " /*LLDB_BODY_START*/\n "; 63*ea401ec7SJim Ingham static const char *c_end_marker = ";\n /*LLDB_BODY_END*/\n"; 64*ea401ec7SJim Ingham 65*ea401ec7SJim Ingham namespace { 66*ea401ec7SJim Ingham 67*ea401ec7SJim Ingham class AddMacroState { 68*ea401ec7SJim Ingham enum State { 69*ea401ec7SJim Ingham CURRENT_FILE_NOT_YET_PUSHED, 70*ea401ec7SJim Ingham CURRENT_FILE_PUSHED, 71*ea401ec7SJim Ingham CURRENT_FILE_POPPED 72*ea401ec7SJim Ingham }; 73*ea401ec7SJim Ingham 74*ea401ec7SJim Ingham public: 75*ea401ec7SJim Ingham AddMacroState(const FileSpec ¤t_file, const uint32_t current_file_line) 76*ea401ec7SJim Ingham : m_state(CURRENT_FILE_NOT_YET_PUSHED), m_current_file(current_file), 77*ea401ec7SJim Ingham m_current_file_line(current_file_line) {} 78*ea401ec7SJim Ingham 79*ea401ec7SJim Ingham void StartFile(const FileSpec &file) { 80*ea401ec7SJim Ingham m_file_stack.push_back(file); 81*ea401ec7SJim Ingham if (file == m_current_file) 82*ea401ec7SJim Ingham m_state = CURRENT_FILE_PUSHED; 83*ea401ec7SJim Ingham } 84*ea401ec7SJim Ingham 85*ea401ec7SJim Ingham void EndFile() { 86*ea401ec7SJim Ingham if (m_file_stack.size() == 0) 87*ea401ec7SJim Ingham return; 88*ea401ec7SJim Ingham 89*ea401ec7SJim Ingham FileSpec old_top = m_file_stack.back(); 90*ea401ec7SJim Ingham m_file_stack.pop_back(); 91*ea401ec7SJim Ingham if (old_top == m_current_file) 92*ea401ec7SJim Ingham m_state = CURRENT_FILE_POPPED; 93*ea401ec7SJim Ingham } 94*ea401ec7SJim Ingham 95*ea401ec7SJim Ingham // An entry is valid if it occurs before the current line in the current 96*ea401ec7SJim Ingham // file. 97*ea401ec7SJim Ingham bool IsValidEntry(uint32_t line) { 98*ea401ec7SJim Ingham switch (m_state) { 99*ea401ec7SJim Ingham case CURRENT_FILE_NOT_YET_PUSHED: 100*ea401ec7SJim Ingham return true; 101*ea401ec7SJim Ingham case CURRENT_FILE_PUSHED: 102*ea401ec7SJim Ingham // If we are in file included in the current file, the entry should be 103*ea401ec7SJim Ingham // added. 104*ea401ec7SJim Ingham if (m_file_stack.back() != m_current_file) 105*ea401ec7SJim Ingham return true; 106*ea401ec7SJim Ingham 107*ea401ec7SJim Ingham return line < m_current_file_line; 108*ea401ec7SJim Ingham default: 109*ea401ec7SJim Ingham return false; 110*ea401ec7SJim Ingham } 111*ea401ec7SJim Ingham } 112*ea401ec7SJim Ingham 113*ea401ec7SJim Ingham private: 114*ea401ec7SJim Ingham std::vector<FileSpec> m_file_stack; 115*ea401ec7SJim Ingham State m_state; 116*ea401ec7SJim Ingham FileSpec m_current_file; 117*ea401ec7SJim Ingham uint32_t m_current_file_line; 118*ea401ec7SJim Ingham }; 119*ea401ec7SJim Ingham 120*ea401ec7SJim Ingham } // anonymous namespace 121*ea401ec7SJim Ingham 122*ea401ec7SJim Ingham static void AddMacros(const DebugMacros *dm, CompileUnit *comp_unit, 123*ea401ec7SJim Ingham AddMacroState &state, StreamString &stream) { 124*ea401ec7SJim Ingham if (dm == nullptr) 125*ea401ec7SJim Ingham return; 126*ea401ec7SJim Ingham 127*ea401ec7SJim Ingham for (size_t i = 0; i < dm->GetNumMacroEntries(); i++) { 128*ea401ec7SJim Ingham const DebugMacroEntry &entry = dm->GetMacroEntryAtIndex(i); 129*ea401ec7SJim Ingham uint32_t line; 130*ea401ec7SJim Ingham 131*ea401ec7SJim Ingham switch (entry.GetType()) { 132*ea401ec7SJim Ingham case DebugMacroEntry::DEFINE: 133*ea401ec7SJim Ingham if (state.IsValidEntry(entry.GetLineNumber())) 134*ea401ec7SJim Ingham stream.Printf("#define %s\n", entry.GetMacroString().AsCString()); 135*ea401ec7SJim Ingham else 136*ea401ec7SJim Ingham return; 137*ea401ec7SJim Ingham break; 138*ea401ec7SJim Ingham case DebugMacroEntry::UNDEF: 139*ea401ec7SJim Ingham if (state.IsValidEntry(entry.GetLineNumber())) 140*ea401ec7SJim Ingham stream.Printf("#undef %s\n", entry.GetMacroString().AsCString()); 141*ea401ec7SJim Ingham else 142*ea401ec7SJim Ingham return; 143*ea401ec7SJim Ingham break; 144*ea401ec7SJim Ingham case DebugMacroEntry::START_FILE: 145*ea401ec7SJim Ingham line = entry.GetLineNumber(); 146*ea401ec7SJim Ingham if (state.IsValidEntry(line)) 147*ea401ec7SJim Ingham state.StartFile(entry.GetFileSpec(comp_unit)); 148*ea401ec7SJim Ingham else 149*ea401ec7SJim Ingham return; 150*ea401ec7SJim Ingham break; 151*ea401ec7SJim Ingham case DebugMacroEntry::END_FILE: 152*ea401ec7SJim Ingham state.EndFile(); 153*ea401ec7SJim Ingham break; 154*ea401ec7SJim Ingham case DebugMacroEntry::INDIRECT: 155*ea401ec7SJim Ingham AddMacros(entry.GetIndirectDebugMacros(), comp_unit, state, stream); 156*ea401ec7SJim Ingham break; 157*ea401ec7SJim Ingham default: 158*ea401ec7SJim Ingham // This is an unknown/invalid entry. Ignore. 159*ea401ec7SJim Ingham break; 160*ea401ec7SJim Ingham } 161*ea401ec7SJim Ingham } 162*ea401ec7SJim Ingham } 163*ea401ec7SJim Ingham 164*ea401ec7SJim Ingham static void AddLocalVariableDecls(const lldb::VariableListSP &var_list_sp, 165*ea401ec7SJim Ingham StreamString &stream) { 166*ea401ec7SJim Ingham for (size_t i = 0; i < var_list_sp->GetSize(); i++) { 167*ea401ec7SJim Ingham lldb::VariableSP var_sp = var_list_sp->GetVariableAtIndex(i); 168*ea401ec7SJim Ingham 169*ea401ec7SJim Ingham ConstString var_name = var_sp->GetName(); 170*ea401ec7SJim Ingham if (!var_name || var_name == ConstString("this") || 171*ea401ec7SJim Ingham var_name == ConstString(".block_descriptor")) 172*ea401ec7SJim Ingham continue; 173*ea401ec7SJim Ingham 174*ea401ec7SJim Ingham stream.Printf("using $__lldb_local_vars::%s;\n", var_name.AsCString()); 175*ea401ec7SJim Ingham } 176*ea401ec7SJim Ingham } 177*ea401ec7SJim Ingham 178*ea401ec7SJim Ingham bool ClangExpressionSourceCode::GetText(std::string &text, 179*ea401ec7SJim Ingham lldb::LanguageType wrapping_language, 180*ea401ec7SJim Ingham bool static_method, 181*ea401ec7SJim Ingham ExecutionContext &exe_ctx, 182*ea401ec7SJim Ingham bool add_locals) const { 183*ea401ec7SJim Ingham const char *target_specific_defines = "typedef signed char BOOL;\n"; 184*ea401ec7SJim Ingham std::string module_macros; 185*ea401ec7SJim Ingham 186*ea401ec7SJim Ingham Target *target = exe_ctx.GetTargetPtr(); 187*ea401ec7SJim Ingham if (target) { 188*ea401ec7SJim Ingham if (target->GetArchitecture().GetMachine() == llvm::Triple::aarch64) { 189*ea401ec7SJim Ingham target_specific_defines = "typedef bool BOOL;\n"; 190*ea401ec7SJim Ingham } 191*ea401ec7SJim Ingham if (target->GetArchitecture().GetMachine() == llvm::Triple::x86_64) { 192*ea401ec7SJim Ingham if (lldb::PlatformSP platform_sp = target->GetPlatform()) { 193*ea401ec7SJim Ingham static ConstString g_platform_ios_simulator("ios-simulator"); 194*ea401ec7SJim Ingham if (platform_sp->GetPluginName() == g_platform_ios_simulator) { 195*ea401ec7SJim Ingham target_specific_defines = "typedef bool BOOL;\n"; 196*ea401ec7SJim Ingham } 197*ea401ec7SJim Ingham } 198*ea401ec7SJim Ingham } 199*ea401ec7SJim Ingham 200*ea401ec7SJim Ingham if (ClangModulesDeclVendor *decl_vendor = 201*ea401ec7SJim Ingham target->GetClangModulesDeclVendor()) { 202*ea401ec7SJim Ingham ClangPersistentVariables *persistent_vars = 203*ea401ec7SJim Ingham llvm::cast<ClangPersistentVariables>( 204*ea401ec7SJim Ingham target->GetPersistentExpressionStateForLanguage( 205*ea401ec7SJim Ingham lldb::eLanguageTypeC)); 206*ea401ec7SJim Ingham const ClangModulesDeclVendor::ModuleVector &hand_imported_modules = 207*ea401ec7SJim Ingham persistent_vars->GetHandLoadedClangModules(); 208*ea401ec7SJim Ingham ClangModulesDeclVendor::ModuleVector modules_for_macros; 209*ea401ec7SJim Ingham 210*ea401ec7SJim Ingham for (ClangModulesDeclVendor::ModuleID module : hand_imported_modules) { 211*ea401ec7SJim Ingham modules_for_macros.push_back(module); 212*ea401ec7SJim Ingham } 213*ea401ec7SJim Ingham 214*ea401ec7SJim Ingham if (target->GetEnableAutoImportClangModules()) { 215*ea401ec7SJim Ingham if (StackFrame *frame = exe_ctx.GetFramePtr()) { 216*ea401ec7SJim Ingham if (Block *block = frame->GetFrameBlock()) { 217*ea401ec7SJim Ingham SymbolContext sc; 218*ea401ec7SJim Ingham 219*ea401ec7SJim Ingham block->CalculateSymbolContext(&sc); 220*ea401ec7SJim Ingham 221*ea401ec7SJim Ingham if (sc.comp_unit) { 222*ea401ec7SJim Ingham StreamString error_stream; 223*ea401ec7SJim Ingham 224*ea401ec7SJim Ingham decl_vendor->AddModulesForCompileUnit( 225*ea401ec7SJim Ingham *sc.comp_unit, modules_for_macros, error_stream); 226*ea401ec7SJim Ingham } 227*ea401ec7SJim Ingham } 228*ea401ec7SJim Ingham } 229*ea401ec7SJim Ingham } 230*ea401ec7SJim Ingham 231*ea401ec7SJim Ingham decl_vendor->ForEachMacro( 232*ea401ec7SJim Ingham modules_for_macros, 233*ea401ec7SJim Ingham [&module_macros](const std::string &expansion) -> bool { 234*ea401ec7SJim Ingham module_macros.append(expansion); 235*ea401ec7SJim Ingham module_macros.append("\n"); 236*ea401ec7SJim Ingham return false; 237*ea401ec7SJim Ingham }); 238*ea401ec7SJim Ingham } 239*ea401ec7SJim Ingham } 240*ea401ec7SJim Ingham 241*ea401ec7SJim Ingham StreamString debug_macros_stream; 242*ea401ec7SJim Ingham StreamString lldb_local_var_decls; 243*ea401ec7SJim Ingham if (StackFrame *frame = exe_ctx.GetFramePtr()) { 244*ea401ec7SJim Ingham const SymbolContext &sc = frame->GetSymbolContext( 245*ea401ec7SJim Ingham lldb::eSymbolContextCompUnit | lldb::eSymbolContextLineEntry); 246*ea401ec7SJim Ingham 247*ea401ec7SJim Ingham if (sc.comp_unit && sc.line_entry.IsValid()) { 248*ea401ec7SJim Ingham DebugMacros *dm = sc.comp_unit->GetDebugMacros(); 249*ea401ec7SJim Ingham if (dm) { 250*ea401ec7SJim Ingham AddMacroState state(sc.line_entry.file, sc.line_entry.line); 251*ea401ec7SJim Ingham AddMacros(dm, sc.comp_unit, state, debug_macros_stream); 252*ea401ec7SJim Ingham } 253*ea401ec7SJim Ingham } 254*ea401ec7SJim Ingham 255*ea401ec7SJim Ingham if (add_locals) { 256*ea401ec7SJim Ingham if (Language::LanguageIsCPlusPlus(frame->GetLanguage())) { 257*ea401ec7SJim Ingham if (target->GetInjectLocalVariables(&exe_ctx)) { 258*ea401ec7SJim Ingham lldb::VariableListSP var_list_sp = 259*ea401ec7SJim Ingham frame->GetInScopeVariableList(false, true); 260*ea401ec7SJim Ingham AddLocalVariableDecls(var_list_sp, lldb_local_var_decls); 261*ea401ec7SJim Ingham } 262*ea401ec7SJim Ingham } 263*ea401ec7SJim Ingham } 264*ea401ec7SJim Ingham } 265*ea401ec7SJim Ingham 266*ea401ec7SJim Ingham if (m_wrap) { 267*ea401ec7SJim Ingham switch (wrapping_language) { 268*ea401ec7SJim Ingham default: 269*ea401ec7SJim Ingham return false; 270*ea401ec7SJim Ingham case lldb::eLanguageTypeC: 271*ea401ec7SJim Ingham case lldb::eLanguageTypeC_plus_plus: 272*ea401ec7SJim Ingham case lldb::eLanguageTypeObjC: 273*ea401ec7SJim Ingham break; 274*ea401ec7SJim Ingham } 275*ea401ec7SJim Ingham 276*ea401ec7SJim Ingham StreamString wrap_stream; 277*ea401ec7SJim Ingham 278*ea401ec7SJim Ingham wrap_stream.Printf("%s\n%s\n%s\n%s\n%s\n", module_macros.c_str(), 279*ea401ec7SJim Ingham debug_macros_stream.GetData(), g_expression_prefix, 280*ea401ec7SJim Ingham target_specific_defines, m_prefix.c_str()); 281*ea401ec7SJim Ingham 282*ea401ec7SJim Ingham // First construct a tagged form of the user expression so we can find it 283*ea401ec7SJim Ingham // later: 284*ea401ec7SJim Ingham std::string tagged_body; 285*ea401ec7SJim Ingham switch (wrapping_language) { 286*ea401ec7SJim Ingham default: 287*ea401ec7SJim Ingham tagged_body = m_body; 288*ea401ec7SJim Ingham break; 289*ea401ec7SJim Ingham case lldb::eLanguageTypeC: 290*ea401ec7SJim Ingham case lldb::eLanguageTypeC_plus_plus: 291*ea401ec7SJim Ingham case lldb::eLanguageTypeObjC: 292*ea401ec7SJim Ingham tagged_body.append(c_start_marker); 293*ea401ec7SJim Ingham tagged_body.append(m_body); 294*ea401ec7SJim Ingham tagged_body.append(c_end_marker); 295*ea401ec7SJim Ingham break; 296*ea401ec7SJim Ingham } 297*ea401ec7SJim Ingham switch (wrapping_language) { 298*ea401ec7SJim Ingham default: 299*ea401ec7SJim Ingham break; 300*ea401ec7SJim Ingham case lldb::eLanguageTypeC: 301*ea401ec7SJim Ingham wrap_stream.Printf("void \n" 302*ea401ec7SJim Ingham "%s(void *$__lldb_arg) \n" 303*ea401ec7SJim Ingham "{ \n" 304*ea401ec7SJim Ingham " %s; \n" 305*ea401ec7SJim Ingham "%s" 306*ea401ec7SJim Ingham "} \n", 307*ea401ec7SJim Ingham m_name.c_str(), lldb_local_var_decls.GetData(), 308*ea401ec7SJim Ingham tagged_body.c_str()); 309*ea401ec7SJim Ingham break; 310*ea401ec7SJim Ingham case lldb::eLanguageTypeC_plus_plus: 311*ea401ec7SJim Ingham wrap_stream.Printf("void \n" 312*ea401ec7SJim Ingham "$__lldb_class::%s(void *$__lldb_arg) \n" 313*ea401ec7SJim Ingham "{ \n" 314*ea401ec7SJim Ingham " %s; \n" 315*ea401ec7SJim Ingham "%s" 316*ea401ec7SJim Ingham "} \n", 317*ea401ec7SJim Ingham m_name.c_str(), lldb_local_var_decls.GetData(), 318*ea401ec7SJim Ingham tagged_body.c_str()); 319*ea401ec7SJim Ingham break; 320*ea401ec7SJim Ingham case lldb::eLanguageTypeObjC: 321*ea401ec7SJim Ingham if (static_method) { 322*ea401ec7SJim Ingham wrap_stream.Printf( 323*ea401ec7SJim Ingham "@interface $__lldb_objc_class ($__lldb_category) \n" 324*ea401ec7SJim Ingham "+(void)%s:(void *)$__lldb_arg; \n" 325*ea401ec7SJim Ingham "@end \n" 326*ea401ec7SJim Ingham "@implementation $__lldb_objc_class ($__lldb_category) \n" 327*ea401ec7SJim Ingham "+(void)%s:(void *)$__lldb_arg \n" 328*ea401ec7SJim Ingham "{ \n" 329*ea401ec7SJim Ingham "%s" 330*ea401ec7SJim Ingham "} \n" 331*ea401ec7SJim Ingham "@end \n", 332*ea401ec7SJim Ingham m_name.c_str(), m_name.c_str(), tagged_body.c_str()); 333*ea401ec7SJim Ingham } else { 334*ea401ec7SJim Ingham wrap_stream.Printf( 335*ea401ec7SJim Ingham "@interface $__lldb_objc_class ($__lldb_category) \n" 336*ea401ec7SJim Ingham "-(void)%s:(void *)$__lldb_arg; \n" 337*ea401ec7SJim Ingham "@end \n" 338*ea401ec7SJim Ingham "@implementation $__lldb_objc_class ($__lldb_category) \n" 339*ea401ec7SJim Ingham "-(void)%s:(void *)$__lldb_arg \n" 340*ea401ec7SJim Ingham "{ \n" 341*ea401ec7SJim Ingham "%s" 342*ea401ec7SJim Ingham "} \n" 343*ea401ec7SJim Ingham "@end \n", 344*ea401ec7SJim Ingham m_name.c_str(), m_name.c_str(), tagged_body.c_str()); 345*ea401ec7SJim Ingham } 346*ea401ec7SJim Ingham break; 347*ea401ec7SJim Ingham } 348*ea401ec7SJim Ingham 349*ea401ec7SJim Ingham text = wrap_stream.GetString(); 350*ea401ec7SJim Ingham } else { 351*ea401ec7SJim Ingham text.append(m_body); 352*ea401ec7SJim Ingham } 353*ea401ec7SJim Ingham 354*ea401ec7SJim Ingham return true; 355*ea401ec7SJim Ingham } 356*ea401ec7SJim Ingham 357*ea401ec7SJim Ingham bool ClangExpressionSourceCode::GetOriginalBodyBounds( 358*ea401ec7SJim Ingham std::string transformed_text, lldb::LanguageType wrapping_language, 359*ea401ec7SJim Ingham size_t &start_loc, size_t &end_loc) { 360*ea401ec7SJim Ingham const char *start_marker; 361*ea401ec7SJim Ingham const char *end_marker; 362*ea401ec7SJim Ingham 363*ea401ec7SJim Ingham switch (wrapping_language) { 364*ea401ec7SJim Ingham default: 365*ea401ec7SJim Ingham return false; 366*ea401ec7SJim Ingham case lldb::eLanguageTypeC: 367*ea401ec7SJim Ingham case lldb::eLanguageTypeC_plus_plus: 368*ea401ec7SJim Ingham case lldb::eLanguageTypeObjC: 369*ea401ec7SJim Ingham start_marker = c_start_marker; 370*ea401ec7SJim Ingham end_marker = c_end_marker; 371*ea401ec7SJim Ingham break; 372*ea401ec7SJim Ingham } 373*ea401ec7SJim Ingham 374*ea401ec7SJim Ingham start_loc = transformed_text.find(start_marker); 375*ea401ec7SJim Ingham if (start_loc == std::string::npos) 376*ea401ec7SJim Ingham return false; 377*ea401ec7SJim Ingham start_loc += strlen(start_marker); 378*ea401ec7SJim Ingham end_loc = transformed_text.find(end_marker); 379*ea401ec7SJim Ingham return end_loc != std::string::npos; 380*ea401ec7SJim Ingham } 381