15ffd83dbSDimitry Andric //===-- ClangExpressionDeclMap.cpp ----------------------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "ClangExpressionDeclMap.h" 100b57cec5SDimitry Andric 110b57cec5SDimitry Andric #include "ClangASTSource.h" 12fcaf7f86SDimitry Andric #include "ClangExpressionUtil.h" 13fcaf7f86SDimitry Andric #include "ClangExpressionVariable.h" 140b57cec5SDimitry Andric #include "ClangModulesDeclVendor.h" 150b57cec5SDimitry Andric #include "ClangPersistentVariables.h" 165ffd83dbSDimitry Andric #include "ClangUtil.h" 170b57cec5SDimitry Andric 18fcaf7f86SDimitry Andric #include "NameSearchContext.h" 195ffd83dbSDimitry Andric #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" 200b57cec5SDimitry Andric #include "lldb/Core/Address.h" 210b57cec5SDimitry Andric #include "lldb/Core/Module.h" 220b57cec5SDimitry Andric #include "lldb/Core/ModuleSpec.h" 230b57cec5SDimitry Andric #include "lldb/Core/ValueObjectConstResult.h" 240b57cec5SDimitry Andric #include "lldb/Core/ValueObjectVariable.h" 25e8d8bef9SDimitry Andric #include "lldb/Expression/DiagnosticManager.h" 260b57cec5SDimitry Andric #include "lldb/Expression/Materializer.h" 270b57cec5SDimitry Andric #include "lldb/Symbol/CompileUnit.h" 280b57cec5SDimitry Andric #include "lldb/Symbol/CompilerDecl.h" 290b57cec5SDimitry Andric #include "lldb/Symbol/CompilerDeclContext.h" 300b57cec5SDimitry Andric #include "lldb/Symbol/Function.h" 310b57cec5SDimitry Andric #include "lldb/Symbol/ObjectFile.h" 320b57cec5SDimitry Andric #include "lldb/Symbol/SymbolContext.h" 330b57cec5SDimitry Andric #include "lldb/Symbol/SymbolFile.h" 340b57cec5SDimitry Andric #include "lldb/Symbol/SymbolVendor.h" 350b57cec5SDimitry Andric #include "lldb/Symbol/Type.h" 360b57cec5SDimitry Andric #include "lldb/Symbol/TypeList.h" 370b57cec5SDimitry Andric #include "lldb/Symbol/Variable.h" 380b57cec5SDimitry Andric #include "lldb/Symbol/VariableList.h" 390b57cec5SDimitry Andric #include "lldb/Target/ExecutionContext.h" 400b57cec5SDimitry Andric #include "lldb/Target/Process.h" 410b57cec5SDimitry Andric #include "lldb/Target/RegisterContext.h" 420b57cec5SDimitry Andric #include "lldb/Target/StackFrame.h" 430b57cec5SDimitry Andric #include "lldb/Target/Target.h" 440b57cec5SDimitry Andric #include "lldb/Target/Thread.h" 450b57cec5SDimitry Andric #include "lldb/Utility/Endian.h" 4681ad6265SDimitry Andric #include "lldb/Utility/LLDBLog.h" 470b57cec5SDimitry Andric #include "lldb/Utility/Log.h" 480b57cec5SDimitry Andric #include "lldb/Utility/RegisterValue.h" 490b57cec5SDimitry Andric #include "lldb/Utility/Status.h" 50fcaf7f86SDimitry Andric #include "lldb/lldb-private-types.h" 510b57cec5SDimitry Andric #include "lldb/lldb-private.h" 520b57cec5SDimitry Andric #include "clang/AST/ASTConsumer.h" 530b57cec5SDimitry Andric #include "clang/AST/ASTContext.h" 540b57cec5SDimitry Andric #include "clang/AST/ASTImporter.h" 550b57cec5SDimitry Andric #include "clang/AST/Decl.h" 560b57cec5SDimitry Andric #include "clang/AST/DeclarationName.h" 570b57cec5SDimitry Andric #include "clang/AST/RecursiveASTVisitor.h" 580b57cec5SDimitry Andric 590b57cec5SDimitry Andric #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" 600b57cec5SDimitry Andric #include "Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h" 610b57cec5SDimitry Andric #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h" 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric using namespace lldb; 640b57cec5SDimitry Andric using namespace lldb_private; 650b57cec5SDimitry Andric using namespace clang; 660b57cec5SDimitry Andric 67349cc55cSDimitry Andric static const char *g_lldb_local_vars_namespace_cstr = "$__lldb_local_vars"; 680b57cec5SDimitry Andric 69fcaf7f86SDimitry Andric namespace { 70fcaf7f86SDimitry Andric /// A lambda is represented by Clang as an artifical class whose 71fcaf7f86SDimitry Andric /// members are the lambda captures. If we capture a 'this' pointer, 72fcaf7f86SDimitry Andric /// the artifical class will contain a member variable named 'this'. 73fcaf7f86SDimitry Andric /// The function returns a ValueObject for the captured 'this' if such 74fcaf7f86SDimitry Andric /// member exists. If no 'this' was captured, return a nullptr. 75fcaf7f86SDimitry Andric lldb::ValueObjectSP GetCapturedThisValueObject(StackFrame *frame) { 76fcaf7f86SDimitry Andric assert(frame); 77fcaf7f86SDimitry Andric 78fcaf7f86SDimitry Andric if (auto thisValSP = frame->FindVariable(ConstString("this"))) 7906c3fb27SDimitry Andric if (auto thisThisValSP = thisValSP->GetChildMemberWithName("this")) 80fcaf7f86SDimitry Andric return thisThisValSP; 81fcaf7f86SDimitry Andric 82fcaf7f86SDimitry Andric return nullptr; 83fcaf7f86SDimitry Andric } 84fcaf7f86SDimitry Andric } // namespace 85fcaf7f86SDimitry Andric 860b57cec5SDimitry Andric ClangExpressionDeclMap::ClangExpressionDeclMap( 870b57cec5SDimitry Andric bool keep_result_in_memory, 880b57cec5SDimitry Andric Materializer::PersistentVariableDelegate *result_delegate, 895ffd83dbSDimitry Andric const lldb::TargetSP &target, 905ffd83dbSDimitry Andric const std::shared_ptr<ClangASTImporter> &importer, ValueObject *ctx_obj) 91480093f4SDimitry Andric : ClangASTSource(target, importer), m_found_entities(), m_struct_members(), 92480093f4SDimitry Andric m_keep_result_in_memory(keep_result_in_memory), 930b57cec5SDimitry Andric m_result_delegate(result_delegate), m_ctx_obj(ctx_obj), m_parser_vars(), 940b57cec5SDimitry Andric m_struct_vars() { 950b57cec5SDimitry Andric EnableStructVars(); 960b57cec5SDimitry Andric } 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric ClangExpressionDeclMap::~ClangExpressionDeclMap() { 990b57cec5SDimitry Andric // Note: The model is now that the parser's AST context and all associated 1000b57cec5SDimitry Andric // data does not vanish until the expression has been executed. This means 1010b57cec5SDimitry Andric // that valuable lookup data (like namespaces) doesn't vanish, but 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric DidParse(); 1040b57cec5SDimitry Andric DisableStructVars(); 1050b57cec5SDimitry Andric } 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric bool ClangExpressionDeclMap::WillParse(ExecutionContext &exe_ctx, 1080b57cec5SDimitry Andric Materializer *materializer) { 1090b57cec5SDimitry Andric EnableParserVars(); 1100b57cec5SDimitry Andric m_parser_vars->m_exe_ctx = exe_ctx; 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric Target *target = exe_ctx.GetTargetPtr(); 1130b57cec5SDimitry Andric if (exe_ctx.GetFramePtr()) 1140b57cec5SDimitry Andric m_parser_vars->m_sym_ctx = 1150b57cec5SDimitry Andric exe_ctx.GetFramePtr()->GetSymbolContext(lldb::eSymbolContextEverything); 1160b57cec5SDimitry Andric else if (exe_ctx.GetThreadPtr() && 1170b57cec5SDimitry Andric exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(0)) 1180b57cec5SDimitry Andric m_parser_vars->m_sym_ctx = 1190b57cec5SDimitry Andric exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(0)->GetSymbolContext( 1200b57cec5SDimitry Andric lldb::eSymbolContextEverything); 1210b57cec5SDimitry Andric else if (exe_ctx.GetProcessPtr()) { 1220b57cec5SDimitry Andric m_parser_vars->m_sym_ctx.Clear(true); 1230b57cec5SDimitry Andric m_parser_vars->m_sym_ctx.target_sp = exe_ctx.GetTargetSP(); 1240b57cec5SDimitry Andric } else if (target) { 1250b57cec5SDimitry Andric m_parser_vars->m_sym_ctx.Clear(true); 1260b57cec5SDimitry Andric m_parser_vars->m_sym_ctx.target_sp = exe_ctx.GetTargetSP(); 1270b57cec5SDimitry Andric } 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric if (target) { 1300b57cec5SDimitry Andric m_parser_vars->m_persistent_vars = llvm::cast<ClangPersistentVariables>( 1310b57cec5SDimitry Andric target->GetPersistentExpressionStateForLanguage(eLanguageTypeC)); 1320b57cec5SDimitry Andric 133e8d8bef9SDimitry Andric if (!ScratchTypeSystemClang::GetForTarget(*target)) 1340b57cec5SDimitry Andric return false; 1350b57cec5SDimitry Andric } 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andric m_parser_vars->m_target_info = GetTargetInfo(); 1380b57cec5SDimitry Andric m_parser_vars->m_materializer = materializer; 1390b57cec5SDimitry Andric 1400b57cec5SDimitry Andric return true; 1410b57cec5SDimitry Andric } 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric void ClangExpressionDeclMap::InstallCodeGenerator( 1440b57cec5SDimitry Andric clang::ASTConsumer *code_gen) { 1450b57cec5SDimitry Andric assert(m_parser_vars); 1460b57cec5SDimitry Andric m_parser_vars->m_code_gen = code_gen; 1470b57cec5SDimitry Andric } 1480b57cec5SDimitry Andric 149e8d8bef9SDimitry Andric void ClangExpressionDeclMap::InstallDiagnosticManager( 150e8d8bef9SDimitry Andric DiagnosticManager &diag_manager) { 151e8d8bef9SDimitry Andric assert(m_parser_vars); 152e8d8bef9SDimitry Andric m_parser_vars->m_diagnostics = &diag_manager; 153e8d8bef9SDimitry Andric } 154e8d8bef9SDimitry Andric 1550b57cec5SDimitry Andric void ClangExpressionDeclMap::DidParse() { 156480093f4SDimitry Andric if (m_parser_vars && m_parser_vars->m_persistent_vars) { 1570b57cec5SDimitry Andric for (size_t entity_index = 0, num_entities = m_found_entities.GetSize(); 1580b57cec5SDimitry Andric entity_index < num_entities; ++entity_index) { 1590b57cec5SDimitry Andric ExpressionVariableSP var_sp( 1600b57cec5SDimitry Andric m_found_entities.GetVariableAtIndex(entity_index)); 1610b57cec5SDimitry Andric if (var_sp) 1620b57cec5SDimitry Andric llvm::cast<ClangExpressionVariable>(var_sp.get()) 1630b57cec5SDimitry Andric ->DisableParserVars(GetParserID()); 1640b57cec5SDimitry Andric } 1650b57cec5SDimitry Andric 1660b57cec5SDimitry Andric for (size_t pvar_index = 0, 1670b57cec5SDimitry Andric num_pvars = m_parser_vars->m_persistent_vars->GetSize(); 1680b57cec5SDimitry Andric pvar_index < num_pvars; ++pvar_index) { 1690b57cec5SDimitry Andric ExpressionVariableSP pvar_sp( 1700b57cec5SDimitry Andric m_parser_vars->m_persistent_vars->GetVariableAtIndex(pvar_index)); 1710b57cec5SDimitry Andric if (ClangExpressionVariable *clang_var = 1720b57cec5SDimitry Andric llvm::dyn_cast<ClangExpressionVariable>(pvar_sp.get())) 1730b57cec5SDimitry Andric clang_var->DisableParserVars(GetParserID()); 1740b57cec5SDimitry Andric } 1750b57cec5SDimitry Andric 1760b57cec5SDimitry Andric DisableParserVars(); 1770b57cec5SDimitry Andric } 1780b57cec5SDimitry Andric } 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric // Interface for IRForTarget 1810b57cec5SDimitry Andric 1820b57cec5SDimitry Andric ClangExpressionDeclMap::TargetInfo ClangExpressionDeclMap::GetTargetInfo() { 1830b57cec5SDimitry Andric assert(m_parser_vars.get()); 1840b57cec5SDimitry Andric 1850b57cec5SDimitry Andric TargetInfo ret; 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx; 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric Process *process = exe_ctx.GetProcessPtr(); 1900b57cec5SDimitry Andric if (process) { 1910b57cec5SDimitry Andric ret.byte_order = process->GetByteOrder(); 1920b57cec5SDimitry Andric ret.address_byte_size = process->GetAddressByteSize(); 1930b57cec5SDimitry Andric } else { 1940b57cec5SDimitry Andric Target *target = exe_ctx.GetTargetPtr(); 1950b57cec5SDimitry Andric if (target) { 1960b57cec5SDimitry Andric ret.byte_order = target->GetArchitecture().GetByteOrder(); 1970b57cec5SDimitry Andric ret.address_byte_size = target->GetArchitecture().GetAddressByteSize(); 1980b57cec5SDimitry Andric } 1990b57cec5SDimitry Andric } 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric return ret; 2020b57cec5SDimitry Andric } 2030b57cec5SDimitry Andric 2045ffd83dbSDimitry Andric TypeFromUser ClangExpressionDeclMap::DeportType(TypeSystemClang &target, 2055ffd83dbSDimitry Andric TypeSystemClang &source, 2060b57cec5SDimitry Andric TypeFromParser parser_type) { 207bdd1243dSDimitry Andric assert(&target == GetScratchContext(*m_target).get()); 208bdd1243dSDimitry Andric assert((TypeSystem *)&source == 209bdd1243dSDimitry Andric parser_type.GetTypeSystem().GetSharedPointer().get()); 210480093f4SDimitry Andric assert(&source.getASTContext() == m_ast_context); 2110b57cec5SDimitry Andric 212480093f4SDimitry Andric return TypeFromUser(m_ast_importer_sp->DeportType(target, parser_type)); 2130b57cec5SDimitry Andric } 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl, 2160b57cec5SDimitry Andric ConstString name, 2170b57cec5SDimitry Andric TypeFromParser parser_type, 2180b57cec5SDimitry Andric bool is_result, 2190b57cec5SDimitry Andric bool is_lvalue) { 2200b57cec5SDimitry Andric assert(m_parser_vars.get()); 221bdd1243dSDimitry Andric auto ast = parser_type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>(); 2220b57cec5SDimitry Andric if (ast == nullptr) 2230b57cec5SDimitry Andric return false; 2240b57cec5SDimitry Andric 225e8d8bef9SDimitry Andric // Check if we already declared a persistent variable with the same name. 226e8d8bef9SDimitry Andric if (lldb::ExpressionVariableSP conflicting_var = 227e8d8bef9SDimitry Andric m_parser_vars->m_persistent_vars->GetVariable(name)) { 228e8d8bef9SDimitry Andric std::string msg = llvm::formatv("redefinition of persistent variable '{0}'", 229e8d8bef9SDimitry Andric name).str(); 230e8d8bef9SDimitry Andric m_parser_vars->m_diagnostics->AddDiagnostic( 231*0fca6ea1SDimitry Andric msg, lldb::eSeverityError, DiagnosticOrigin::eDiagnosticOriginLLDB); 232e8d8bef9SDimitry Andric return false; 233e8d8bef9SDimitry Andric } 234e8d8bef9SDimitry Andric 2350b57cec5SDimitry Andric if (m_parser_vars->m_materializer && is_result) { 2360b57cec5SDimitry Andric Status err; 2370b57cec5SDimitry Andric 2380b57cec5SDimitry Andric ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx; 2390b57cec5SDimitry Andric Target *target = exe_ctx.GetTargetPtr(); 2400b57cec5SDimitry Andric if (target == nullptr) 2410b57cec5SDimitry Andric return false; 2420b57cec5SDimitry Andric 243bdd1243dSDimitry Andric auto clang_ast_context = GetScratchContext(*target); 244480093f4SDimitry Andric if (!clang_ast_context) 245480093f4SDimitry Andric return false; 246480093f4SDimitry Andric 247480093f4SDimitry Andric TypeFromUser user_type = DeportType(*clang_ast_context, *ast, parser_type); 2480b57cec5SDimitry Andric 2490b57cec5SDimitry Andric uint32_t offset = m_parser_vars->m_materializer->AddResultVariable( 2500b57cec5SDimitry Andric user_type, is_lvalue, m_keep_result_in_memory, m_result_delegate, err); 2510b57cec5SDimitry Andric 2520b57cec5SDimitry Andric ClangExpressionVariable *var = new ClangExpressionVariable( 2530b57cec5SDimitry Andric exe_ctx.GetBestExecutionContextScope(), name, user_type, 2540b57cec5SDimitry Andric m_parser_vars->m_target_info.byte_order, 2550b57cec5SDimitry Andric m_parser_vars->m_target_info.address_byte_size); 2560b57cec5SDimitry Andric 2570b57cec5SDimitry Andric m_found_entities.AddNewlyConstructedVariable(var); 2580b57cec5SDimitry Andric 2590b57cec5SDimitry Andric var->EnableParserVars(GetParserID()); 2600b57cec5SDimitry Andric 2610b57cec5SDimitry Andric ClangExpressionVariable::ParserVars *parser_vars = 2620b57cec5SDimitry Andric var->GetParserVars(GetParserID()); 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric parser_vars->m_named_decl = decl; 2650b57cec5SDimitry Andric 2660b57cec5SDimitry Andric var->EnableJITVars(GetParserID()); 2670b57cec5SDimitry Andric 2680b57cec5SDimitry Andric ClangExpressionVariable::JITVars *jit_vars = var->GetJITVars(GetParserID()); 2690b57cec5SDimitry Andric 2700b57cec5SDimitry Andric jit_vars->m_offset = offset; 2710b57cec5SDimitry Andric 2720b57cec5SDimitry Andric return true; 2730b57cec5SDimitry Andric } 2740b57cec5SDimitry Andric 27581ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions); 2760b57cec5SDimitry Andric ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx; 2770b57cec5SDimitry Andric Target *target = exe_ctx.GetTargetPtr(); 2780b57cec5SDimitry Andric if (target == nullptr) 2790b57cec5SDimitry Andric return false; 2800b57cec5SDimitry Andric 281bdd1243dSDimitry Andric auto context = GetScratchContext(*target); 282480093f4SDimitry Andric if (!context) 283480093f4SDimitry Andric return false; 2840b57cec5SDimitry Andric 2850b57cec5SDimitry Andric TypeFromUser user_type = DeportType(*context, *ast, parser_type); 2860b57cec5SDimitry Andric 2870b57cec5SDimitry Andric if (!user_type.GetOpaqueQualType()) { 2885ffd83dbSDimitry Andric LLDB_LOG(log, "Persistent variable's type wasn't copied successfully"); 2890b57cec5SDimitry Andric return false; 2900b57cec5SDimitry Andric } 2910b57cec5SDimitry Andric 2920b57cec5SDimitry Andric if (!m_parser_vars->m_target_info.IsValid()) 2930b57cec5SDimitry Andric return false; 2940b57cec5SDimitry Andric 295480093f4SDimitry Andric if (!m_parser_vars->m_persistent_vars) 296480093f4SDimitry Andric return false; 297480093f4SDimitry Andric 2980b57cec5SDimitry Andric ClangExpressionVariable *var = llvm::cast<ClangExpressionVariable>( 2990b57cec5SDimitry Andric m_parser_vars->m_persistent_vars 3000b57cec5SDimitry Andric ->CreatePersistentVariable( 3010b57cec5SDimitry Andric exe_ctx.GetBestExecutionContextScope(), name, user_type, 3020b57cec5SDimitry Andric m_parser_vars->m_target_info.byte_order, 3030b57cec5SDimitry Andric m_parser_vars->m_target_info.address_byte_size) 3040b57cec5SDimitry Andric .get()); 3050b57cec5SDimitry Andric 3060b57cec5SDimitry Andric if (!var) 3070b57cec5SDimitry Andric return false; 3080b57cec5SDimitry Andric 3090b57cec5SDimitry Andric var->m_frozen_sp->SetHasCompleteType(); 3100b57cec5SDimitry Andric 3110b57cec5SDimitry Andric if (is_result) 3120b57cec5SDimitry Andric var->m_flags |= ClangExpressionVariable::EVNeedsFreezeDry; 3130b57cec5SDimitry Andric else 3140b57cec5SDimitry Andric var->m_flags |= 3150b57cec5SDimitry Andric ClangExpressionVariable::EVKeepInTarget; // explicitly-declared 3160b57cec5SDimitry Andric // persistent variables should 3170b57cec5SDimitry Andric // persist 3180b57cec5SDimitry Andric 3190b57cec5SDimitry Andric if (is_lvalue) { 3200b57cec5SDimitry Andric var->m_flags |= ClangExpressionVariable::EVIsProgramReference; 3210b57cec5SDimitry Andric } else { 3220b57cec5SDimitry Andric var->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated; 3230b57cec5SDimitry Andric var->m_flags |= ClangExpressionVariable::EVNeedsAllocation; 3240b57cec5SDimitry Andric } 3250b57cec5SDimitry Andric 3260b57cec5SDimitry Andric if (m_keep_result_in_memory) { 3270b57cec5SDimitry Andric var->m_flags |= ClangExpressionVariable::EVKeepInTarget; 3280b57cec5SDimitry Andric } 3290b57cec5SDimitry Andric 3305ffd83dbSDimitry Andric LLDB_LOG(log, "Created persistent variable with flags {0:x}", var->m_flags); 3310b57cec5SDimitry Andric 3320b57cec5SDimitry Andric var->EnableParserVars(GetParserID()); 3330b57cec5SDimitry Andric 3340b57cec5SDimitry Andric ClangExpressionVariable::ParserVars *parser_vars = 3350b57cec5SDimitry Andric var->GetParserVars(GetParserID()); 3360b57cec5SDimitry Andric 3370b57cec5SDimitry Andric parser_vars->m_named_decl = decl; 3380b57cec5SDimitry Andric 3390b57cec5SDimitry Andric return true; 3400b57cec5SDimitry Andric } 3410b57cec5SDimitry Andric 3420b57cec5SDimitry Andric bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl, 3430b57cec5SDimitry Andric ConstString name, 3440b57cec5SDimitry Andric llvm::Value *value, size_t size, 3450b57cec5SDimitry Andric lldb::offset_t alignment) { 3460b57cec5SDimitry Andric assert(m_struct_vars.get()); 3470b57cec5SDimitry Andric assert(m_parser_vars.get()); 3480b57cec5SDimitry Andric 3490b57cec5SDimitry Andric bool is_persistent_variable = false; 3500b57cec5SDimitry Andric 35181ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions); 3520b57cec5SDimitry Andric 3530b57cec5SDimitry Andric m_struct_vars->m_struct_laid_out = false; 3540b57cec5SDimitry Andric 3550b57cec5SDimitry Andric if (ClangExpressionVariable::FindVariableInList(m_struct_members, decl, 3560b57cec5SDimitry Andric GetParserID())) 3570b57cec5SDimitry Andric return true; 3580b57cec5SDimitry Andric 3590b57cec5SDimitry Andric ClangExpressionVariable *var(ClangExpressionVariable::FindVariableInList( 3600b57cec5SDimitry Andric m_found_entities, decl, GetParserID())); 3610b57cec5SDimitry Andric 362480093f4SDimitry Andric if (!var && m_parser_vars->m_persistent_vars) { 3630b57cec5SDimitry Andric var = ClangExpressionVariable::FindVariableInList( 3640b57cec5SDimitry Andric *m_parser_vars->m_persistent_vars, decl, GetParserID()); 3650b57cec5SDimitry Andric is_persistent_variable = true; 3660b57cec5SDimitry Andric } 3670b57cec5SDimitry Andric 3680b57cec5SDimitry Andric if (!var) 3690b57cec5SDimitry Andric return false; 3700b57cec5SDimitry Andric 371fe6060f1SDimitry Andric LLDB_LOG(log, "Adding value for (NamedDecl*){0} [{1} - {2}] to the structure", 3725ffd83dbSDimitry Andric decl, name, var->GetName()); 3730b57cec5SDimitry Andric 3740b57cec5SDimitry Andric // We know entity->m_parser_vars is valid because we used a parser variable 3750b57cec5SDimitry Andric // to find it 3760b57cec5SDimitry Andric 3770b57cec5SDimitry Andric ClangExpressionVariable::ParserVars *parser_vars = 3780b57cec5SDimitry Andric llvm::cast<ClangExpressionVariable>(var)->GetParserVars(GetParserID()); 3790b57cec5SDimitry Andric 3800b57cec5SDimitry Andric parser_vars->m_llvm_value = value; 3810b57cec5SDimitry Andric 3820b57cec5SDimitry Andric if (ClangExpressionVariable::JITVars *jit_vars = 3830b57cec5SDimitry Andric llvm::cast<ClangExpressionVariable>(var)->GetJITVars(GetParserID())) { 3840b57cec5SDimitry Andric // We already laid this out; do not touch 3850b57cec5SDimitry Andric 3865ffd83dbSDimitry Andric LLDB_LOG(log, "Already placed at {0:x}", jit_vars->m_offset); 3870b57cec5SDimitry Andric } 3880b57cec5SDimitry Andric 3890b57cec5SDimitry Andric llvm::cast<ClangExpressionVariable>(var)->EnableJITVars(GetParserID()); 3900b57cec5SDimitry Andric 3910b57cec5SDimitry Andric ClangExpressionVariable::JITVars *jit_vars = 3920b57cec5SDimitry Andric llvm::cast<ClangExpressionVariable>(var)->GetJITVars(GetParserID()); 3930b57cec5SDimitry Andric 3940b57cec5SDimitry Andric jit_vars->m_alignment = alignment; 3950b57cec5SDimitry Andric jit_vars->m_size = size; 3960b57cec5SDimitry Andric 3970b57cec5SDimitry Andric m_struct_members.AddVariable(var->shared_from_this()); 3980b57cec5SDimitry Andric 3990b57cec5SDimitry Andric if (m_parser_vars->m_materializer) { 4000b57cec5SDimitry Andric uint32_t offset = 0; 4010b57cec5SDimitry Andric 4020b57cec5SDimitry Andric Status err; 4030b57cec5SDimitry Andric 4040b57cec5SDimitry Andric if (is_persistent_variable) { 4050b57cec5SDimitry Andric ExpressionVariableSP var_sp(var->shared_from_this()); 4060b57cec5SDimitry Andric offset = m_parser_vars->m_materializer->AddPersistentVariable( 4070b57cec5SDimitry Andric var_sp, nullptr, err); 4080b57cec5SDimitry Andric } else { 4090b57cec5SDimitry Andric if (const lldb_private::Symbol *sym = parser_vars->m_lldb_sym) 4100b57cec5SDimitry Andric offset = m_parser_vars->m_materializer->AddSymbol(*sym, err); 4110b57cec5SDimitry Andric else if (const RegisterInfo *reg_info = var->GetRegisterInfo()) 4120b57cec5SDimitry Andric offset = m_parser_vars->m_materializer->AddRegister(*reg_info, err); 4130b57cec5SDimitry Andric else if (parser_vars->m_lldb_var) 4140b57cec5SDimitry Andric offset = m_parser_vars->m_materializer->AddVariable( 4150b57cec5SDimitry Andric parser_vars->m_lldb_var, err); 416fcaf7f86SDimitry Andric else if (parser_vars->m_lldb_valobj_provider) { 417fcaf7f86SDimitry Andric offset = m_parser_vars->m_materializer->AddValueObject( 418fcaf7f86SDimitry Andric name, parser_vars->m_lldb_valobj_provider, err); 419fcaf7f86SDimitry Andric } 4200b57cec5SDimitry Andric } 4210b57cec5SDimitry Andric 4220b57cec5SDimitry Andric if (!err.Success()) 4230b57cec5SDimitry Andric return false; 4240b57cec5SDimitry Andric 4255ffd83dbSDimitry Andric LLDB_LOG(log, "Placed at {0:x}", offset); 4260b57cec5SDimitry Andric 4270b57cec5SDimitry Andric jit_vars->m_offset = 4280b57cec5SDimitry Andric offset; // TODO DoStructLayout() should not change this. 4290b57cec5SDimitry Andric } 4300b57cec5SDimitry Andric 4310b57cec5SDimitry Andric return true; 4320b57cec5SDimitry Andric } 4330b57cec5SDimitry Andric 4340b57cec5SDimitry Andric bool ClangExpressionDeclMap::DoStructLayout() { 4350b57cec5SDimitry Andric assert(m_struct_vars.get()); 4360b57cec5SDimitry Andric 4370b57cec5SDimitry Andric if (m_struct_vars->m_struct_laid_out) 4380b57cec5SDimitry Andric return true; 4390b57cec5SDimitry Andric 4400b57cec5SDimitry Andric if (!m_parser_vars->m_materializer) 4410b57cec5SDimitry Andric return false; 4420b57cec5SDimitry Andric 4430b57cec5SDimitry Andric m_struct_vars->m_struct_alignment = 4440b57cec5SDimitry Andric m_parser_vars->m_materializer->GetStructAlignment(); 4450b57cec5SDimitry Andric m_struct_vars->m_struct_size = 4460b57cec5SDimitry Andric m_parser_vars->m_materializer->GetStructByteSize(); 4470b57cec5SDimitry Andric m_struct_vars->m_struct_laid_out = true; 4480b57cec5SDimitry Andric return true; 4490b57cec5SDimitry Andric } 4500b57cec5SDimitry Andric 4510b57cec5SDimitry Andric bool ClangExpressionDeclMap::GetStructInfo(uint32_t &num_elements, size_t &size, 4520b57cec5SDimitry Andric lldb::offset_t &alignment) { 4530b57cec5SDimitry Andric assert(m_struct_vars.get()); 4540b57cec5SDimitry Andric 4550b57cec5SDimitry Andric if (!m_struct_vars->m_struct_laid_out) 4560b57cec5SDimitry Andric return false; 4570b57cec5SDimitry Andric 4580b57cec5SDimitry Andric num_elements = m_struct_members.GetSize(); 4590b57cec5SDimitry Andric size = m_struct_vars->m_struct_size; 4600b57cec5SDimitry Andric alignment = m_struct_vars->m_struct_alignment; 4610b57cec5SDimitry Andric 4620b57cec5SDimitry Andric return true; 4630b57cec5SDimitry Andric } 4640b57cec5SDimitry Andric 4650b57cec5SDimitry Andric bool ClangExpressionDeclMap::GetStructElement(const NamedDecl *&decl, 4660b57cec5SDimitry Andric llvm::Value *&value, 4670b57cec5SDimitry Andric lldb::offset_t &offset, 4680b57cec5SDimitry Andric ConstString &name, 4690b57cec5SDimitry Andric uint32_t index) { 4700b57cec5SDimitry Andric assert(m_struct_vars.get()); 4710b57cec5SDimitry Andric 4720b57cec5SDimitry Andric if (!m_struct_vars->m_struct_laid_out) 4730b57cec5SDimitry Andric return false; 4740b57cec5SDimitry Andric 4750b57cec5SDimitry Andric if (index >= m_struct_members.GetSize()) 4760b57cec5SDimitry Andric return false; 4770b57cec5SDimitry Andric 4780b57cec5SDimitry Andric ExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(index)); 4790b57cec5SDimitry Andric 4800b57cec5SDimitry Andric if (!member_sp) 4810b57cec5SDimitry Andric return false; 4820b57cec5SDimitry Andric 4830b57cec5SDimitry Andric ClangExpressionVariable::ParserVars *parser_vars = 4840b57cec5SDimitry Andric llvm::cast<ClangExpressionVariable>(member_sp.get()) 4850b57cec5SDimitry Andric ->GetParserVars(GetParserID()); 4860b57cec5SDimitry Andric ClangExpressionVariable::JITVars *jit_vars = 4870b57cec5SDimitry Andric llvm::cast<ClangExpressionVariable>(member_sp.get()) 4880b57cec5SDimitry Andric ->GetJITVars(GetParserID()); 4890b57cec5SDimitry Andric 4900b57cec5SDimitry Andric if (!parser_vars || !jit_vars || !member_sp->GetValueObject()) 4910b57cec5SDimitry Andric return false; 4920b57cec5SDimitry Andric 4930b57cec5SDimitry Andric decl = parser_vars->m_named_decl; 4940b57cec5SDimitry Andric value = parser_vars->m_llvm_value; 4950b57cec5SDimitry Andric offset = jit_vars->m_offset; 4960b57cec5SDimitry Andric name = member_sp->GetName(); 4970b57cec5SDimitry Andric 4980b57cec5SDimitry Andric return true; 4990b57cec5SDimitry Andric } 5000b57cec5SDimitry Andric 5010b57cec5SDimitry Andric bool ClangExpressionDeclMap::GetFunctionInfo(const NamedDecl *decl, 5020b57cec5SDimitry Andric uint64_t &ptr) { 5030b57cec5SDimitry Andric ClangExpressionVariable *entity(ClangExpressionVariable::FindVariableInList( 5040b57cec5SDimitry Andric m_found_entities, decl, GetParserID())); 5050b57cec5SDimitry Andric 5060b57cec5SDimitry Andric if (!entity) 5070b57cec5SDimitry Andric return false; 5080b57cec5SDimitry Andric 5090b57cec5SDimitry Andric // We know m_parser_vars is valid since we searched for the variable by its 5100b57cec5SDimitry Andric // NamedDecl 5110b57cec5SDimitry Andric 5120b57cec5SDimitry Andric ClangExpressionVariable::ParserVars *parser_vars = 5130b57cec5SDimitry Andric entity->GetParserVars(GetParserID()); 5140b57cec5SDimitry Andric 5150b57cec5SDimitry Andric ptr = parser_vars->m_lldb_value.GetScalar().ULongLong(); 5160b57cec5SDimitry Andric 5170b57cec5SDimitry Andric return true; 5180b57cec5SDimitry Andric } 5190b57cec5SDimitry Andric 5200b57cec5SDimitry Andric addr_t ClangExpressionDeclMap::GetSymbolAddress(Target &target, 5210b57cec5SDimitry Andric Process *process, 5220b57cec5SDimitry Andric ConstString name, 5230b57cec5SDimitry Andric lldb::SymbolType symbol_type, 5240b57cec5SDimitry Andric lldb_private::Module *module) { 5250b57cec5SDimitry Andric SymbolContextList sc_list; 5260b57cec5SDimitry Andric 5270b57cec5SDimitry Andric if (module) 5280b57cec5SDimitry Andric module->FindSymbolsWithNameAndType(name, symbol_type, sc_list); 5290b57cec5SDimitry Andric else 5300b57cec5SDimitry Andric target.GetImages().FindSymbolsWithNameAndType(name, symbol_type, sc_list); 5310b57cec5SDimitry Andric 5320b57cec5SDimitry Andric addr_t symbol_load_addr = LLDB_INVALID_ADDRESS; 5330b57cec5SDimitry Andric 53406c3fb27SDimitry Andric for (const SymbolContext &sym_ctx : sc_list) { 53506c3fb27SDimitry Andric if (symbol_load_addr != 0 && symbol_load_addr != LLDB_INVALID_ADDRESS) 53606c3fb27SDimitry Andric break; 5370b57cec5SDimitry Andric 5380b57cec5SDimitry Andric const Address sym_address = sym_ctx.symbol->GetAddress(); 5390b57cec5SDimitry Andric 5400b57cec5SDimitry Andric if (!sym_address.IsValid()) 5410b57cec5SDimitry Andric continue; 5420b57cec5SDimitry Andric 5430b57cec5SDimitry Andric switch (sym_ctx.symbol->GetType()) { 5440b57cec5SDimitry Andric case eSymbolTypeCode: 5450b57cec5SDimitry Andric case eSymbolTypeTrampoline: 5460b57cec5SDimitry Andric symbol_load_addr = sym_address.GetCallableLoadAddress(&target); 5470b57cec5SDimitry Andric break; 5480b57cec5SDimitry Andric 5490b57cec5SDimitry Andric case eSymbolTypeResolver: 5500b57cec5SDimitry Andric symbol_load_addr = sym_address.GetCallableLoadAddress(&target, true); 5510b57cec5SDimitry Andric break; 5520b57cec5SDimitry Andric 5530b57cec5SDimitry Andric case eSymbolTypeReExported: { 5540b57cec5SDimitry Andric ConstString reexport_name = sym_ctx.symbol->GetReExportedSymbolName(); 5550b57cec5SDimitry Andric if (reexport_name) { 5560b57cec5SDimitry Andric ModuleSP reexport_module_sp; 5570b57cec5SDimitry Andric ModuleSpec reexport_module_spec; 5580b57cec5SDimitry Andric reexport_module_spec.GetPlatformFileSpec() = 5590b57cec5SDimitry Andric sym_ctx.symbol->GetReExportedSymbolSharedLibrary(); 5600b57cec5SDimitry Andric if (reexport_module_spec.GetPlatformFileSpec()) { 5610b57cec5SDimitry Andric reexport_module_sp = 5620b57cec5SDimitry Andric target.GetImages().FindFirstModule(reexport_module_spec); 5630b57cec5SDimitry Andric if (!reexport_module_sp) { 564bdd1243dSDimitry Andric reexport_module_spec.GetPlatformFileSpec().ClearDirectory(); 5650b57cec5SDimitry Andric reexport_module_sp = 5660b57cec5SDimitry Andric target.GetImages().FindFirstModule(reexport_module_spec); 5670b57cec5SDimitry Andric } 5680b57cec5SDimitry Andric } 5690b57cec5SDimitry Andric symbol_load_addr = GetSymbolAddress( 5700b57cec5SDimitry Andric target, process, sym_ctx.symbol->GetReExportedSymbolName(), 5710b57cec5SDimitry Andric symbol_type, reexport_module_sp.get()); 5720b57cec5SDimitry Andric } 5730b57cec5SDimitry Andric } break; 5740b57cec5SDimitry Andric 5750b57cec5SDimitry Andric case eSymbolTypeData: 5760b57cec5SDimitry Andric case eSymbolTypeRuntime: 5770b57cec5SDimitry Andric case eSymbolTypeVariable: 5780b57cec5SDimitry Andric case eSymbolTypeLocal: 5790b57cec5SDimitry Andric case eSymbolTypeParam: 5800b57cec5SDimitry Andric case eSymbolTypeInvalid: 5810b57cec5SDimitry Andric case eSymbolTypeAbsolute: 5820b57cec5SDimitry Andric case eSymbolTypeException: 5830b57cec5SDimitry Andric case eSymbolTypeSourceFile: 5840b57cec5SDimitry Andric case eSymbolTypeHeaderFile: 5850b57cec5SDimitry Andric case eSymbolTypeObjectFile: 5860b57cec5SDimitry Andric case eSymbolTypeCommonBlock: 5870b57cec5SDimitry Andric case eSymbolTypeBlock: 5880b57cec5SDimitry Andric case eSymbolTypeVariableType: 5890b57cec5SDimitry Andric case eSymbolTypeLineEntry: 5900b57cec5SDimitry Andric case eSymbolTypeLineHeader: 5910b57cec5SDimitry Andric case eSymbolTypeScopeBegin: 5920b57cec5SDimitry Andric case eSymbolTypeScopeEnd: 5930b57cec5SDimitry Andric case eSymbolTypeAdditional: 5940b57cec5SDimitry Andric case eSymbolTypeCompiler: 5950b57cec5SDimitry Andric case eSymbolTypeInstrumentation: 5960b57cec5SDimitry Andric case eSymbolTypeUndefined: 5970b57cec5SDimitry Andric case eSymbolTypeObjCClass: 5980b57cec5SDimitry Andric case eSymbolTypeObjCMetaClass: 5990b57cec5SDimitry Andric case eSymbolTypeObjCIVar: 6000b57cec5SDimitry Andric symbol_load_addr = sym_address.GetLoadAddress(&target); 6010b57cec5SDimitry Andric break; 6020b57cec5SDimitry Andric } 6030b57cec5SDimitry Andric } 6040b57cec5SDimitry Andric 6050b57cec5SDimitry Andric if (symbol_load_addr == LLDB_INVALID_ADDRESS && process) { 6060b57cec5SDimitry Andric ObjCLanguageRuntime *runtime = ObjCLanguageRuntime::Get(*process); 6070b57cec5SDimitry Andric 6080b57cec5SDimitry Andric if (runtime) { 6090b57cec5SDimitry Andric symbol_load_addr = runtime->LookupRuntimeSymbol(name); 6100b57cec5SDimitry Andric } 6110b57cec5SDimitry Andric } 6120b57cec5SDimitry Andric 6130b57cec5SDimitry Andric return symbol_load_addr; 6140b57cec5SDimitry Andric } 6150b57cec5SDimitry Andric 6160b57cec5SDimitry Andric addr_t ClangExpressionDeclMap::GetSymbolAddress(ConstString name, 6170b57cec5SDimitry Andric lldb::SymbolType symbol_type) { 6180b57cec5SDimitry Andric assert(m_parser_vars.get()); 6190b57cec5SDimitry Andric 6200b57cec5SDimitry Andric if (!m_parser_vars->m_exe_ctx.GetTargetPtr()) 6210b57cec5SDimitry Andric return false; 6220b57cec5SDimitry Andric 6230b57cec5SDimitry Andric return GetSymbolAddress(m_parser_vars->m_exe_ctx.GetTargetRef(), 6240b57cec5SDimitry Andric m_parser_vars->m_exe_ctx.GetProcessPtr(), name, 6250b57cec5SDimitry Andric symbol_type); 6260b57cec5SDimitry Andric } 6270b57cec5SDimitry Andric 6280b57cec5SDimitry Andric lldb::VariableSP ClangExpressionDeclMap::FindGlobalVariable( 6290b57cec5SDimitry Andric Target &target, ModuleSP &module, ConstString name, 6305ffd83dbSDimitry Andric const CompilerDeclContext &namespace_decl) { 6310b57cec5SDimitry Andric VariableList vars; 6320b57cec5SDimitry Andric 6330b57cec5SDimitry Andric if (module && namespace_decl) 6340b57cec5SDimitry Andric module->FindGlobalVariables(name, namespace_decl, -1, vars); 6350b57cec5SDimitry Andric else 6360b57cec5SDimitry Andric target.GetImages().FindGlobalVariables(name, -1, vars); 6370b57cec5SDimitry Andric 638480093f4SDimitry Andric if (vars.GetSize() == 0) 6390b57cec5SDimitry Andric return VariableSP(); 640480093f4SDimitry Andric return vars.GetVariableAtIndex(0); 6410b57cec5SDimitry Andric } 6420b57cec5SDimitry Andric 6435ffd83dbSDimitry Andric TypeSystemClang *ClangExpressionDeclMap::GetTypeSystemClang() { 6440b57cec5SDimitry Andric StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr(); 6450b57cec5SDimitry Andric if (frame == nullptr) 6460b57cec5SDimitry Andric return nullptr; 6470b57cec5SDimitry Andric 6480b57cec5SDimitry Andric SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | 6490b57cec5SDimitry Andric lldb::eSymbolContextBlock); 6500b57cec5SDimitry Andric if (sym_ctx.block == nullptr) 6510b57cec5SDimitry Andric return nullptr; 6520b57cec5SDimitry Andric 6530b57cec5SDimitry Andric CompilerDeclContext frame_decl_context = sym_ctx.block->GetDeclContext(); 6540b57cec5SDimitry Andric if (!frame_decl_context) 6550b57cec5SDimitry Andric return nullptr; 6560b57cec5SDimitry Andric 6575ffd83dbSDimitry Andric return llvm::dyn_cast_or_null<TypeSystemClang>( 6580b57cec5SDimitry Andric frame_decl_context.GetTypeSystem()); 6590b57cec5SDimitry Andric } 6600b57cec5SDimitry Andric 6610b57cec5SDimitry Andric // Interface for ClangASTSource 6620b57cec5SDimitry Andric 6630b57cec5SDimitry Andric void ClangExpressionDeclMap::FindExternalVisibleDecls( 6640b57cec5SDimitry Andric NameSearchContext &context) { 6650b57cec5SDimitry Andric assert(m_ast_context); 6660b57cec5SDimitry Andric 6670b57cec5SDimitry Andric const ConstString name(context.m_decl_name.getAsString().c_str()); 6680b57cec5SDimitry Andric 66981ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions); 6700b57cec5SDimitry Andric 6710b57cec5SDimitry Andric if (log) { 6720b57cec5SDimitry Andric if (!context.m_decl_context) 6735ffd83dbSDimitry Andric LLDB_LOG(log, 6745ffd83dbSDimitry Andric "ClangExpressionDeclMap::FindExternalVisibleDecls for " 6755ffd83dbSDimitry Andric "'{0}' in a NULL DeclContext", 6765ffd83dbSDimitry Andric name); 6770b57cec5SDimitry Andric else if (const NamedDecl *context_named_decl = 6780b57cec5SDimitry Andric dyn_cast<NamedDecl>(context.m_decl_context)) 6795ffd83dbSDimitry Andric LLDB_LOG(log, 6805ffd83dbSDimitry Andric "ClangExpressionDeclMap::FindExternalVisibleDecls for " 6815ffd83dbSDimitry Andric "'{0}' in '{1}'", 6825ffd83dbSDimitry Andric name, context_named_decl->getNameAsString()); 6830b57cec5SDimitry Andric else 6845ffd83dbSDimitry Andric LLDB_LOG(log, 6855ffd83dbSDimitry Andric "ClangExpressionDeclMap::FindExternalVisibleDecls for " 6865ffd83dbSDimitry Andric "'{0}' in a '{1}'", 6875ffd83dbSDimitry Andric name, context.m_decl_context->getDeclKindName()); 6880b57cec5SDimitry Andric } 6890b57cec5SDimitry Andric 6900b57cec5SDimitry Andric if (const NamespaceDecl *namespace_context = 6910b57cec5SDimitry Andric dyn_cast<NamespaceDecl>(context.m_decl_context)) { 6920b57cec5SDimitry Andric if (namespace_context->getName().str() == 6930b57cec5SDimitry Andric std::string(g_lldb_local_vars_namespace_cstr)) { 694480093f4SDimitry Andric CompilerDeclContext compiler_decl_ctx = 695480093f4SDimitry Andric m_clang_ast_context->CreateDeclContext( 696480093f4SDimitry Andric const_cast<clang::DeclContext *>(context.m_decl_context)); 6975ffd83dbSDimitry Andric FindExternalVisibleDecls(context, lldb::ModuleSP(), compiler_decl_ctx); 6980b57cec5SDimitry Andric return; 6990b57cec5SDimitry Andric } 7000b57cec5SDimitry Andric 7010b57cec5SDimitry Andric ClangASTImporter::NamespaceMapSP namespace_map = 7025ffd83dbSDimitry Andric m_ast_importer_sp->GetNamespaceMap(namespace_context); 7030b57cec5SDimitry Andric 7040b57cec5SDimitry Andric if (!namespace_map) 7050b57cec5SDimitry Andric return; 7060b57cec5SDimitry Andric 7075ffd83dbSDimitry Andric LLDB_LOGV(log, " CEDM::FEVD Inspecting (NamespaceMap*){0:x} ({1} entries)", 7085ffd83dbSDimitry Andric namespace_map.get(), namespace_map->size()); 7090b57cec5SDimitry Andric 7105ffd83dbSDimitry Andric for (ClangASTImporter::NamespaceMapItem &n : *namespace_map) { 7115ffd83dbSDimitry Andric LLDB_LOG(log, " CEDM::FEVD Searching namespace {0} in module {1}", 7125ffd83dbSDimitry Andric n.second.GetName(), n.first->GetFileSpec().GetFilename()); 7130b57cec5SDimitry Andric 7145ffd83dbSDimitry Andric FindExternalVisibleDecls(context, n.first, n.second); 7150b57cec5SDimitry Andric } 7160b57cec5SDimitry Andric } else if (isa<TranslationUnitDecl>(context.m_decl_context)) { 7170b57cec5SDimitry Andric CompilerDeclContext namespace_decl; 7180b57cec5SDimitry Andric 7195ffd83dbSDimitry Andric LLDB_LOG(log, " CEDM::FEVD Searching the root namespace"); 7200b57cec5SDimitry Andric 7215ffd83dbSDimitry Andric FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl); 7220b57cec5SDimitry Andric } 7230b57cec5SDimitry Andric 7240b57cec5SDimitry Andric ClangASTSource::FindExternalVisibleDecls(context); 7250b57cec5SDimitry Andric } 7260b57cec5SDimitry Andric 727480093f4SDimitry Andric void ClangExpressionDeclMap::MaybeRegisterFunctionBody( 728480093f4SDimitry Andric FunctionDecl *copied_function_decl) { 7290b57cec5SDimitry Andric if (copied_function_decl->getBody() && m_parser_vars->m_code_gen) { 730480093f4SDimitry Andric clang::DeclGroupRef decl_group_ref(copied_function_decl); 7310b57cec5SDimitry Andric m_parser_vars->m_code_gen->HandleTopLevelDecl(decl_group_ref); 7320b57cec5SDimitry Andric } 733480093f4SDimitry Andric } 7340b57cec5SDimitry Andric 735480093f4SDimitry Andric clang::NamedDecl *ClangExpressionDeclMap::GetPersistentDecl(ConstString name) { 736480093f4SDimitry Andric if (!m_parser_vars) 737480093f4SDimitry Andric return nullptr; 738480093f4SDimitry Andric Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr(); 739480093f4SDimitry Andric if (!target) 740480093f4SDimitry Andric return nullptr; 741480093f4SDimitry Andric 742e8d8bef9SDimitry Andric ScratchTypeSystemClang::GetForTarget(*target); 743480093f4SDimitry Andric 744480093f4SDimitry Andric if (!m_parser_vars->m_persistent_vars) 745480093f4SDimitry Andric return nullptr; 746480093f4SDimitry Andric return m_parser_vars->m_persistent_vars->GetPersistentDecl(name); 747480093f4SDimitry Andric } 748480093f4SDimitry Andric 749480093f4SDimitry Andric void ClangExpressionDeclMap::SearchPersistenDecls(NameSearchContext &context, 7505ffd83dbSDimitry Andric const ConstString name) { 75181ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions); 7520b57cec5SDimitry Andric 753480093f4SDimitry Andric NamedDecl *persistent_decl = GetPersistentDecl(name); 7540b57cec5SDimitry Andric 7550b57cec5SDimitry Andric if (!persistent_decl) 756480093f4SDimitry Andric return; 7570b57cec5SDimitry Andric 7580b57cec5SDimitry Andric Decl *parser_persistent_decl = CopyDecl(persistent_decl); 7590b57cec5SDimitry Andric 7600b57cec5SDimitry Andric if (!parser_persistent_decl) 761480093f4SDimitry Andric return; 7620b57cec5SDimitry Andric 763480093f4SDimitry Andric NamedDecl *parser_named_decl = dyn_cast<NamedDecl>(parser_persistent_decl); 7640b57cec5SDimitry Andric 7650b57cec5SDimitry Andric if (!parser_named_decl) 766480093f4SDimitry Andric return; 7670b57cec5SDimitry Andric 7680b57cec5SDimitry Andric if (clang::FunctionDecl *parser_function_decl = 7690b57cec5SDimitry Andric llvm::dyn_cast<clang::FunctionDecl>(parser_named_decl)) { 7700b57cec5SDimitry Andric MaybeRegisterFunctionBody(parser_function_decl); 7710b57cec5SDimitry Andric } 7720b57cec5SDimitry Andric 773fe6060f1SDimitry Andric LLDB_LOG(log, " CEDM::FEVD Found persistent decl {0}", name); 7740b57cec5SDimitry Andric 7750b57cec5SDimitry Andric context.AddNamedDecl(parser_named_decl); 7760b57cec5SDimitry Andric } 7770b57cec5SDimitry Andric 7785ffd83dbSDimitry Andric void ClangExpressionDeclMap::LookUpLldbClass(NameSearchContext &context) { 77981ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions); 7800b57cec5SDimitry Andric 781480093f4SDimitry Andric StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr(); 782480093f4SDimitry Andric SymbolContext sym_ctx; 783480093f4SDimitry Andric if (frame != nullptr) 784480093f4SDimitry Andric sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | 785480093f4SDimitry Andric lldb::eSymbolContextBlock); 786480093f4SDimitry Andric 7870b57cec5SDimitry Andric if (m_ctx_obj) { 7880b57cec5SDimitry Andric Status status; 7890b57cec5SDimitry Andric lldb::ValueObjectSP ctx_obj_ptr = m_ctx_obj->AddressOf(status); 7900b57cec5SDimitry Andric if (!ctx_obj_ptr || status.Fail()) 7910b57cec5SDimitry Andric return; 7920b57cec5SDimitry Andric 7935ffd83dbSDimitry Andric AddContextClassType(context, TypeFromUser(m_ctx_obj->GetCompilerType())); 7940b57cec5SDimitry Andric return; 7950b57cec5SDimitry Andric } 7960b57cec5SDimitry Andric 7970b57cec5SDimitry Andric // Clang is looking for the type of "this" 7980b57cec5SDimitry Andric 7990b57cec5SDimitry Andric if (frame == nullptr) 8000b57cec5SDimitry Andric return; 8010b57cec5SDimitry Andric 8020b57cec5SDimitry Andric // Find the block that defines the function represented by "sym_ctx" 8030b57cec5SDimitry Andric Block *function_block = sym_ctx.GetFunctionBlock(); 8040b57cec5SDimitry Andric 8050b57cec5SDimitry Andric if (!function_block) 8060b57cec5SDimitry Andric return; 8070b57cec5SDimitry Andric 8080b57cec5SDimitry Andric CompilerDeclContext function_decl_ctx = function_block->GetDeclContext(); 8090b57cec5SDimitry Andric 8100b57cec5SDimitry Andric if (!function_decl_ctx) 8110b57cec5SDimitry Andric return; 8120b57cec5SDimitry Andric 8130b57cec5SDimitry Andric clang::CXXMethodDecl *method_decl = 8145ffd83dbSDimitry Andric TypeSystemClang::DeclContextGetAsCXXMethodDecl(function_decl_ctx); 8150b57cec5SDimitry Andric 8160b57cec5SDimitry Andric if (method_decl) { 817fcaf7f86SDimitry Andric if (auto capturedThis = GetCapturedThisValueObject(frame)) { 818fcaf7f86SDimitry Andric // We're inside a lambda and we captured a 'this'. 819fcaf7f86SDimitry Andric // Import the outer class's AST instead of the 820fcaf7f86SDimitry Andric // (unnamed) lambda structure AST so unqualified 821fcaf7f86SDimitry Andric // member lookups are understood by the Clang parser. 822fcaf7f86SDimitry Andric // 823fcaf7f86SDimitry Andric // If we're in a lambda which didn't capture 'this', 824fcaf7f86SDimitry Andric // $__lldb_class will correspond to the lambda closure 825fcaf7f86SDimitry Andric // AST and references to captures will resolve like 826fcaf7f86SDimitry Andric // regular member varaiable accesses do. 827fcaf7f86SDimitry Andric TypeFromUser pointee_type = 828fcaf7f86SDimitry Andric capturedThis->GetCompilerType().GetPointeeType(); 829fcaf7f86SDimitry Andric 830fcaf7f86SDimitry Andric LLDB_LOG(log, 831fcaf7f86SDimitry Andric " CEDM::FEVD Adding captured type ({0} for" 832fcaf7f86SDimitry Andric " $__lldb_class: {1}", 833fcaf7f86SDimitry Andric capturedThis->GetTypeName(), capturedThis->GetName()); 834fcaf7f86SDimitry Andric 835fcaf7f86SDimitry Andric AddContextClassType(context, pointee_type); 836fcaf7f86SDimitry Andric return; 837fcaf7f86SDimitry Andric } 838fcaf7f86SDimitry Andric 8390b57cec5SDimitry Andric clang::CXXRecordDecl *class_decl = method_decl->getParent(); 8400b57cec5SDimitry Andric 8410b57cec5SDimitry Andric QualType class_qual_type(class_decl->getTypeForDecl(), 0); 8420b57cec5SDimitry Andric 843bdd1243dSDimitry Andric TypeFromUser class_user_type( 844bdd1243dSDimitry Andric class_qual_type.getAsOpaquePtr(), 845bdd1243dSDimitry Andric function_decl_ctx.GetTypeSystem()->weak_from_this()); 8460b57cec5SDimitry Andric 84781ad6265SDimitry Andric LLDB_LOG(log, " CEDM::FEVD Adding type for $__lldb_class: {0}", 8485ffd83dbSDimitry Andric class_qual_type.getAsString()); 8490b57cec5SDimitry Andric 8505ffd83dbSDimitry Andric AddContextClassType(context, class_user_type); 851480093f4SDimitry Andric return; 852480093f4SDimitry Andric } 853480093f4SDimitry Andric 8540b57cec5SDimitry Andric // This branch will get hit if we are executing code in the context of 8550b57cec5SDimitry Andric // a function that claims to have an object pointer (through 8560b57cec5SDimitry Andric // DW_AT_object_pointer?) but is not formally a method of the class. 8570b57cec5SDimitry Andric // In that case, just look up the "this" variable in the current scope 8580b57cec5SDimitry Andric // and use its type. 8590b57cec5SDimitry Andric // FIXME: This code is formally correct, but clang doesn't currently 8600b57cec5SDimitry Andric // emit DW_AT_object_pointer 8610b57cec5SDimitry Andric // for C++ so it hasn't actually been tested. 8620b57cec5SDimitry Andric 863bdd1243dSDimitry Andric VariableList *vars = frame->GetVariableList(false, nullptr); 8640b57cec5SDimitry Andric 8650b57cec5SDimitry Andric lldb::VariableSP this_var = vars->FindVariable(ConstString("this")); 8660b57cec5SDimitry Andric 8670b57cec5SDimitry Andric if (this_var && this_var->IsInScope(frame) && 8680b57cec5SDimitry Andric this_var->LocationIsValidForFrame(frame)) { 8690b57cec5SDimitry Andric Type *this_type = this_var->GetType(); 8700b57cec5SDimitry Andric 8710b57cec5SDimitry Andric if (!this_type) 8720b57cec5SDimitry Andric return; 8730b57cec5SDimitry Andric 8740b57cec5SDimitry Andric TypeFromUser pointee_type = 8750b57cec5SDimitry Andric this_type->GetForwardCompilerType().GetPointeeType(); 8760b57cec5SDimitry Andric 87781ad6265SDimitry Andric LLDB_LOG(log, " FEVD Adding type for $__lldb_class: {0}", 878480093f4SDimitry Andric ClangUtil::GetQualType(pointee_type).getAsString()); 8790b57cec5SDimitry Andric 8805ffd83dbSDimitry Andric AddContextClassType(context, pointee_type); 8810b57cec5SDimitry Andric } 8820b57cec5SDimitry Andric } 8830b57cec5SDimitry Andric 8845ffd83dbSDimitry Andric void ClangExpressionDeclMap::LookUpLldbObjCClass(NameSearchContext &context) { 88581ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions); 8860b57cec5SDimitry Andric 887480093f4SDimitry Andric StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr(); 888480093f4SDimitry Andric 8890b57cec5SDimitry Andric if (m_ctx_obj) { 8900b57cec5SDimitry Andric Status status; 8910b57cec5SDimitry Andric lldb::ValueObjectSP ctx_obj_ptr = m_ctx_obj->AddressOf(status); 8920b57cec5SDimitry Andric if (!ctx_obj_ptr || status.Fail()) 8930b57cec5SDimitry Andric return; 8940b57cec5SDimitry Andric 8955ffd83dbSDimitry Andric AddOneType(context, TypeFromUser(m_ctx_obj->GetCompilerType())); 8960b57cec5SDimitry Andric return; 8970b57cec5SDimitry Andric } 8980b57cec5SDimitry Andric 8990b57cec5SDimitry Andric // Clang is looking for the type of "*self" 9000b57cec5SDimitry Andric 9010b57cec5SDimitry Andric if (!frame) 9020b57cec5SDimitry Andric return; 9030b57cec5SDimitry Andric 904480093f4SDimitry Andric SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | 905480093f4SDimitry Andric lldb::eSymbolContextBlock); 9060b57cec5SDimitry Andric 9070b57cec5SDimitry Andric // Find the block that defines the function represented by "sym_ctx" 9080b57cec5SDimitry Andric Block *function_block = sym_ctx.GetFunctionBlock(); 9090b57cec5SDimitry Andric 9100b57cec5SDimitry Andric if (!function_block) 9110b57cec5SDimitry Andric return; 9120b57cec5SDimitry Andric 9130b57cec5SDimitry Andric CompilerDeclContext function_decl_ctx = function_block->GetDeclContext(); 9140b57cec5SDimitry Andric 9150b57cec5SDimitry Andric if (!function_decl_ctx) 9160b57cec5SDimitry Andric return; 9170b57cec5SDimitry Andric 9180b57cec5SDimitry Andric clang::ObjCMethodDecl *method_decl = 9195ffd83dbSDimitry Andric TypeSystemClang::DeclContextGetAsObjCMethodDecl(function_decl_ctx); 9200b57cec5SDimitry Andric 9210b57cec5SDimitry Andric if (method_decl) { 9220b57cec5SDimitry Andric ObjCInterfaceDecl *self_interface = method_decl->getClassInterface(); 9230b57cec5SDimitry Andric 9240b57cec5SDimitry Andric if (!self_interface) 9250b57cec5SDimitry Andric return; 9260b57cec5SDimitry Andric 9270b57cec5SDimitry Andric const clang::Type *interface_type = self_interface->getTypeForDecl(); 9280b57cec5SDimitry Andric 9290b57cec5SDimitry Andric if (!interface_type) 9300b57cec5SDimitry Andric return; // This is unlikely, but we have seen crashes where this 9310b57cec5SDimitry Andric // occurred 9320b57cec5SDimitry Andric 933bdd1243dSDimitry Andric TypeFromUser class_user_type( 934bdd1243dSDimitry Andric QualType(interface_type, 0).getAsOpaquePtr(), 935bdd1243dSDimitry Andric function_decl_ctx.GetTypeSystem()->weak_from_this()); 9360b57cec5SDimitry Andric 937480093f4SDimitry Andric LLDB_LOG(log, " FEVD[{0}] Adding type for $__lldb_objc_class: {1}", 9385ffd83dbSDimitry Andric ClangUtil::ToString(interface_type)); 9390b57cec5SDimitry Andric 9405ffd83dbSDimitry Andric AddOneType(context, class_user_type); 9410b57cec5SDimitry Andric return; 942480093f4SDimitry Andric } 9430b57cec5SDimitry Andric // This branch will get hit if we are executing code in the context of 9440b57cec5SDimitry Andric // a function that claims to have an object pointer (through 9450b57cec5SDimitry Andric // DW_AT_object_pointer?) but is not formally a method of the class. 9460b57cec5SDimitry Andric // In that case, just look up the "self" variable in the current scope 9470b57cec5SDimitry Andric // and use its type. 9480b57cec5SDimitry Andric 949bdd1243dSDimitry Andric VariableList *vars = frame->GetVariableList(false, nullptr); 9500b57cec5SDimitry Andric 9510b57cec5SDimitry Andric lldb::VariableSP self_var = vars->FindVariable(ConstString("self")); 9520b57cec5SDimitry Andric 953480093f4SDimitry Andric if (!self_var) 954480093f4SDimitry Andric return; 955480093f4SDimitry Andric if (!self_var->IsInScope(frame)) 956480093f4SDimitry Andric return; 957480093f4SDimitry Andric if (!self_var->LocationIsValidForFrame(frame)) 958480093f4SDimitry Andric return; 959480093f4SDimitry Andric 9600b57cec5SDimitry Andric Type *self_type = self_var->GetType(); 9610b57cec5SDimitry Andric 9620b57cec5SDimitry Andric if (!self_type) 9630b57cec5SDimitry Andric return; 9640b57cec5SDimitry Andric 9650b57cec5SDimitry Andric CompilerType self_clang_type = self_type->GetFullCompilerType(); 9660b57cec5SDimitry Andric 9675ffd83dbSDimitry Andric if (TypeSystemClang::IsObjCClassType(self_clang_type)) { 9680b57cec5SDimitry Andric return; 969480093f4SDimitry Andric } 9705ffd83dbSDimitry Andric if (!TypeSystemClang::IsObjCObjectPointerType(self_clang_type)) 971480093f4SDimitry Andric return; 9720b57cec5SDimitry Andric self_clang_type = self_clang_type.GetPointeeType(); 9730b57cec5SDimitry Andric 9740b57cec5SDimitry Andric if (!self_clang_type) 9750b57cec5SDimitry Andric return; 9760b57cec5SDimitry Andric 977480093f4SDimitry Andric LLDB_LOG(log, " FEVD[{0}] Adding type for $__lldb_objc_class: {1}", 9785ffd83dbSDimitry Andric ClangUtil::ToString(self_type->GetFullCompilerType())); 9790b57cec5SDimitry Andric 9800b57cec5SDimitry Andric TypeFromUser class_user_type(self_clang_type); 9810b57cec5SDimitry Andric 9825ffd83dbSDimitry Andric AddOneType(context, class_user_type); 983480093f4SDimitry Andric } 984480093f4SDimitry Andric 985480093f4SDimitry Andric void ClangExpressionDeclMap::LookupLocalVarNamespace( 986480093f4SDimitry Andric SymbolContext &sym_ctx, NameSearchContext &name_context) { 987480093f4SDimitry Andric if (sym_ctx.block == nullptr) 9880b57cec5SDimitry Andric return; 9890b57cec5SDimitry Andric 990480093f4SDimitry Andric CompilerDeclContext frame_decl_context = sym_ctx.block->GetDeclContext(); 991480093f4SDimitry Andric if (!frame_decl_context) 9920b57cec5SDimitry Andric return; 9930b57cec5SDimitry Andric 9945ffd83dbSDimitry Andric TypeSystemClang *frame_ast = llvm::dyn_cast_or_null<TypeSystemClang>( 9950b57cec5SDimitry Andric frame_decl_context.GetTypeSystem()); 996480093f4SDimitry Andric if (!frame_ast) 997480093f4SDimitry Andric return; 9980b57cec5SDimitry Andric 9990b57cec5SDimitry Andric clang::NamespaceDecl *namespace_decl = 1000480093f4SDimitry Andric m_clang_ast_context->GetUniqueNamespaceDeclaration( 10015ffd83dbSDimitry Andric g_lldb_local_vars_namespace_cstr, nullptr, OptionalClangModuleID()); 1002480093f4SDimitry Andric if (!namespace_decl) 1003480093f4SDimitry Andric return; 1004480093f4SDimitry Andric 1005480093f4SDimitry Andric name_context.AddNamedDecl(namespace_decl); 1006480093f4SDimitry Andric clang::DeclContext *ctxt = clang::Decl::castToDeclContext(namespace_decl); 1007480093f4SDimitry Andric ctxt->setHasExternalVisibleStorage(true); 10085ffd83dbSDimitry Andric name_context.m_found_local_vars_nsp = true; 10090b57cec5SDimitry Andric } 10100b57cec5SDimitry Andric 1011480093f4SDimitry Andric void ClangExpressionDeclMap::LookupInModulesDeclVendor( 10125ffd83dbSDimitry Andric NameSearchContext &context, ConstString name) { 101381ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions); 1014480093f4SDimitry Andric 1015480093f4SDimitry Andric if (!m_target) 1016480093f4SDimitry Andric return; 1017480093f4SDimitry Andric 1018fe6060f1SDimitry Andric std::shared_ptr<ClangModulesDeclVendor> modules_decl_vendor = 1019fe6060f1SDimitry Andric GetClangModulesDeclVendor(); 1020480093f4SDimitry Andric if (!modules_decl_vendor) 1021480093f4SDimitry Andric return; 1022480093f4SDimitry Andric 1023480093f4SDimitry Andric bool append = false; 1024480093f4SDimitry Andric uint32_t max_matches = 1; 1025480093f4SDimitry Andric std::vector<clang::NamedDecl *> decls; 1026480093f4SDimitry Andric 1027480093f4SDimitry Andric if (!modules_decl_vendor->FindDecls(name, append, max_matches, decls)) 1028480093f4SDimitry Andric return; 1029480093f4SDimitry Andric 1030480093f4SDimitry Andric assert(!decls.empty() && "FindDecls returned true but no decls?"); 1031480093f4SDimitry Andric clang::NamedDecl *const decl_from_modules = decls[0]; 1032480093f4SDimitry Andric 1033480093f4SDimitry Andric LLDB_LOG(log, 10345ffd83dbSDimitry Andric " CAS::FEVD Matching decl found for " 103581ad6265SDimitry Andric "\"{0}\" in the modules", 10365ffd83dbSDimitry Andric name); 1037480093f4SDimitry Andric 1038480093f4SDimitry Andric clang::Decl *copied_decl = CopyDecl(decl_from_modules); 1039480093f4SDimitry Andric if (!copied_decl) { 10405ffd83dbSDimitry Andric LLDB_LOG(log, " CAS::FEVD - Couldn't export a " 10415ffd83dbSDimitry Andric "declaration from the modules"); 10420b57cec5SDimitry Andric return; 10430b57cec5SDimitry Andric } 10440b57cec5SDimitry Andric 1045480093f4SDimitry Andric if (auto copied_function = dyn_cast<clang::FunctionDecl>(copied_decl)) { 1046480093f4SDimitry Andric MaybeRegisterFunctionBody(copied_function); 10470b57cec5SDimitry Andric 1048480093f4SDimitry Andric context.AddNamedDecl(copied_function); 10490b57cec5SDimitry Andric 10505ffd83dbSDimitry Andric context.m_found_function_with_type_info = true; 1051480093f4SDimitry Andric } else if (auto copied_var = dyn_cast<clang::VarDecl>(copied_decl)) { 1052480093f4SDimitry Andric context.AddNamedDecl(copied_var); 10535ffd83dbSDimitry Andric context.m_found_variable = true; 10540b57cec5SDimitry Andric } 10550b57cec5SDimitry Andric } 10560b57cec5SDimitry Andric 1057480093f4SDimitry Andric bool ClangExpressionDeclMap::LookupLocalVariable( 10585ffd83dbSDimitry Andric NameSearchContext &context, ConstString name, SymbolContext &sym_ctx, 10595ffd83dbSDimitry Andric const CompilerDeclContext &namespace_decl) { 1060480093f4SDimitry Andric if (sym_ctx.block == nullptr) 1061480093f4SDimitry Andric return false; 10620b57cec5SDimitry Andric 1063480093f4SDimitry Andric CompilerDeclContext decl_context = sym_ctx.block->GetDeclContext(); 1064480093f4SDimitry Andric if (!decl_context) 1065480093f4SDimitry Andric return false; 1066480093f4SDimitry Andric 10670b57cec5SDimitry Andric // Make sure that the variables are parsed so that we have the 10680b57cec5SDimitry Andric // declarations. 1069480093f4SDimitry Andric StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr(); 10700b57cec5SDimitry Andric VariableListSP vars = frame->GetInScopeVariableList(true); 10710b57cec5SDimitry Andric for (size_t i = 0; i < vars->GetSize(); i++) 10720b57cec5SDimitry Andric vars->GetVariableAtIndex(i)->GetDecl(); 10730b57cec5SDimitry Andric 10740b57cec5SDimitry Andric // Search for declarations matching the name. Do not include imported 10750b57cec5SDimitry Andric // decls in the search if we are looking for decls in the artificial 10760b57cec5SDimitry Andric // namespace $__lldb_local_vars. 10770b57cec5SDimitry Andric std::vector<CompilerDecl> found_decls = 1078480093f4SDimitry Andric decl_context.FindDeclByName(name, namespace_decl.IsValid()); 10790b57cec5SDimitry Andric 1080480093f4SDimitry Andric VariableSP var; 10810b57cec5SDimitry Andric bool variable_found = false; 10820b57cec5SDimitry Andric for (CompilerDecl decl : found_decls) { 10830b57cec5SDimitry Andric for (size_t vi = 0, ve = vars->GetSize(); vi != ve; ++vi) { 10840b57cec5SDimitry Andric VariableSP candidate_var = vars->GetVariableAtIndex(vi); 10850b57cec5SDimitry Andric if (candidate_var->GetDecl() == decl) { 10860b57cec5SDimitry Andric var = candidate_var; 10870b57cec5SDimitry Andric break; 10880b57cec5SDimitry Andric } 10890b57cec5SDimitry Andric } 10900b57cec5SDimitry Andric 10910b57cec5SDimitry Andric if (var && !variable_found) { 10920b57cec5SDimitry Andric variable_found = true; 1093480093f4SDimitry Andric ValueObjectSP valobj = ValueObjectVariable::Create(frame, var); 10945ffd83dbSDimitry Andric AddOneVariable(context, var, valobj); 10955ffd83dbSDimitry Andric context.m_found_variable = true; 10960b57cec5SDimitry Andric } 10970b57cec5SDimitry Andric } 1098fcaf7f86SDimitry Andric 1099fcaf7f86SDimitry Andric // We're in a local_var_lookup but haven't found any local variables 1100fcaf7f86SDimitry Andric // so far. When performing a variable lookup from within the context of 1101fcaf7f86SDimitry Andric // a lambda, we count the lambda captures as local variables. Thus, 1102fcaf7f86SDimitry Andric // see if we captured any variables with the requested 'name'. 1103fcaf7f86SDimitry Andric if (!variable_found) { 1104fcaf7f86SDimitry Andric auto find_capture = [](ConstString varname, 1105fcaf7f86SDimitry Andric StackFrame *frame) -> ValueObjectSP { 1106fcaf7f86SDimitry Andric if (auto lambda = ClangExpressionUtil::GetLambdaValueObject(frame)) { 110706c3fb27SDimitry Andric if (auto capture = lambda->GetChildMemberWithName(varname)) { 1108fcaf7f86SDimitry Andric return capture; 1109fcaf7f86SDimitry Andric } 1110fcaf7f86SDimitry Andric } 1111fcaf7f86SDimitry Andric 1112fcaf7f86SDimitry Andric return nullptr; 1113fcaf7f86SDimitry Andric }; 1114fcaf7f86SDimitry Andric 1115fcaf7f86SDimitry Andric if (auto capture = find_capture(name, frame)) { 1116fcaf7f86SDimitry Andric variable_found = true; 1117fcaf7f86SDimitry Andric context.m_found_variable = true; 1118fcaf7f86SDimitry Andric AddOneVariable(context, std::move(capture), std::move(find_capture)); 1119fcaf7f86SDimitry Andric } 1120fcaf7f86SDimitry Andric } 1121fcaf7f86SDimitry Andric 1122480093f4SDimitry Andric return variable_found; 11230b57cec5SDimitry Andric } 11240b57cec5SDimitry Andric 1125480093f4SDimitry Andric /// Structure to hold the info needed when comparing function 1126480093f4SDimitry Andric /// declarations. 1127480093f4SDimitry Andric namespace { 1128480093f4SDimitry Andric struct FuncDeclInfo { 1129480093f4SDimitry Andric ConstString m_name; 1130480093f4SDimitry Andric CompilerType m_copied_type; 1131480093f4SDimitry Andric uint32_t m_decl_lvl; 1132480093f4SDimitry Andric SymbolContext m_sym_ctx; 1133480093f4SDimitry Andric }; 1134480093f4SDimitry Andric } // namespace 1135480093f4SDimitry Andric 1136480093f4SDimitry Andric SymbolContextList ClangExpressionDeclMap::SearchFunctionsInSymbolContexts( 1137480093f4SDimitry Andric const SymbolContextList &sc_list, 1138480093f4SDimitry Andric const CompilerDeclContext &frame_decl_context) { 1139480093f4SDimitry Andric // First, symplify things by looping through the symbol contexts to 1140480093f4SDimitry Andric // remove unwanted functions and separate out the functions we want to 1141480093f4SDimitry Andric // compare and prune into a separate list. Cache the info needed about 1142480093f4SDimitry Andric // the function declarations in a vector for efficiency. 1143480093f4SDimitry Andric SymbolContextList sc_sym_list; 1144480093f4SDimitry Andric std::vector<FuncDeclInfo> decl_infos; 114506c3fb27SDimitry Andric decl_infos.reserve(sc_list.GetSize()); 1146480093f4SDimitry Andric clang::DeclContext *frame_decl_ctx = 1147480093f4SDimitry Andric (clang::DeclContext *)frame_decl_context.GetOpaqueDeclContext(); 11485ffd83dbSDimitry Andric TypeSystemClang *ast = llvm::dyn_cast_or_null<TypeSystemClang>( 1149480093f4SDimitry Andric frame_decl_context.GetTypeSystem()); 1150480093f4SDimitry Andric 115106c3fb27SDimitry Andric for (const SymbolContext &sym_ctx : sc_list) { 1152480093f4SDimitry Andric FuncDeclInfo fdi; 1153480093f4SDimitry Andric 1154480093f4SDimitry Andric // We don't know enough about symbols to compare them, but we should 1155480093f4SDimitry Andric // keep them in the list. 1156480093f4SDimitry Andric Function *function = sym_ctx.function; 1157480093f4SDimitry Andric if (!function) { 1158480093f4SDimitry Andric sc_sym_list.Append(sym_ctx); 1159480093f4SDimitry Andric continue; 1160480093f4SDimitry Andric } 1161480093f4SDimitry Andric // Filter out functions without declaration contexts, as well as 1162480093f4SDimitry Andric // class/instance methods, since they'll be skipped in the code that 1163480093f4SDimitry Andric // follows anyway. 1164480093f4SDimitry Andric CompilerDeclContext func_decl_context = function->GetDeclContext(); 116506c3fb27SDimitry Andric if (!func_decl_context || func_decl_context.IsClassMethod()) 1166480093f4SDimitry Andric continue; 1167480093f4SDimitry Andric // We can only prune functions for which we can copy the type. 1168480093f4SDimitry Andric CompilerType func_clang_type = function->GetType()->GetFullCompilerType(); 1169480093f4SDimitry Andric CompilerType copied_func_type = GuardedCopyType(func_clang_type); 1170480093f4SDimitry Andric if (!copied_func_type) { 1171480093f4SDimitry Andric sc_sym_list.Append(sym_ctx); 1172480093f4SDimitry Andric continue; 1173480093f4SDimitry Andric } 1174480093f4SDimitry Andric 1175480093f4SDimitry Andric fdi.m_sym_ctx = sym_ctx; 1176480093f4SDimitry Andric fdi.m_name = function->GetName(); 1177480093f4SDimitry Andric fdi.m_copied_type = copied_func_type; 1178480093f4SDimitry Andric fdi.m_decl_lvl = LLDB_INVALID_DECL_LEVEL; 1179480093f4SDimitry Andric if (fdi.m_copied_type && func_decl_context) { 1180480093f4SDimitry Andric // Call CountDeclLevels to get the number of parent scopes we have 1181480093f4SDimitry Andric // to look through before we find the function declaration. When 1182480093f4SDimitry Andric // comparing functions of the same type, the one with a lower count 1183480093f4SDimitry Andric // will be closer to us in the lookup scope and shadows the other. 1184480093f4SDimitry Andric clang::DeclContext *func_decl_ctx = 1185480093f4SDimitry Andric (clang::DeclContext *)func_decl_context.GetOpaqueDeclContext(); 1186480093f4SDimitry Andric fdi.m_decl_lvl = ast->CountDeclLevels(frame_decl_ctx, func_decl_ctx, 1187480093f4SDimitry Andric &fdi.m_name, &fdi.m_copied_type); 1188480093f4SDimitry Andric } 1189480093f4SDimitry Andric decl_infos.emplace_back(fdi); 1190480093f4SDimitry Andric } 1191480093f4SDimitry Andric 1192480093f4SDimitry Andric // Loop through the functions in our cache looking for matching types, 1193480093f4SDimitry Andric // then compare their scope levels to see which is closer. 1194480093f4SDimitry Andric std::multimap<CompilerType, const FuncDeclInfo *> matches; 1195480093f4SDimitry Andric for (const FuncDeclInfo &fdi : decl_infos) { 1196480093f4SDimitry Andric const CompilerType t = fdi.m_copied_type; 1197480093f4SDimitry Andric auto q = matches.find(t); 1198480093f4SDimitry Andric if (q != matches.end()) { 1199480093f4SDimitry Andric if (q->second->m_decl_lvl > fdi.m_decl_lvl) 1200480093f4SDimitry Andric // This function is closer; remove the old set. 1201480093f4SDimitry Andric matches.erase(t); 1202480093f4SDimitry Andric else if (q->second->m_decl_lvl < fdi.m_decl_lvl) 1203480093f4SDimitry Andric // The functions in our set are closer - skip this one. 1204480093f4SDimitry Andric continue; 1205480093f4SDimitry Andric } 1206480093f4SDimitry Andric matches.insert(std::make_pair(t, &fdi)); 1207480093f4SDimitry Andric } 1208480093f4SDimitry Andric 1209480093f4SDimitry Andric // Loop through our matches and add their symbol contexts to our list. 1210480093f4SDimitry Andric SymbolContextList sc_func_list; 1211480093f4SDimitry Andric for (const auto &q : matches) 1212480093f4SDimitry Andric sc_func_list.Append(q.second->m_sym_ctx); 1213480093f4SDimitry Andric 1214480093f4SDimitry Andric // Rejoin the lists with the functions in front. 1215480093f4SDimitry Andric sc_func_list.Append(sc_sym_list); 1216480093f4SDimitry Andric return sc_func_list; 1217480093f4SDimitry Andric } 1218480093f4SDimitry Andric 12195ffd83dbSDimitry Andric void ClangExpressionDeclMap::LookupFunction( 12205ffd83dbSDimitry Andric NameSearchContext &context, lldb::ModuleSP module_sp, ConstString name, 12215ffd83dbSDimitry Andric const CompilerDeclContext &namespace_decl) { 1222480093f4SDimitry Andric if (!m_parser_vars) 12230b57cec5SDimitry Andric return; 1224480093f4SDimitry Andric 1225480093f4SDimitry Andric Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr(); 12260b57cec5SDimitry Andric 12270b57cec5SDimitry Andric std::vector<clang::NamedDecl *> decls_from_modules; 12280b57cec5SDimitry Andric 12290b57cec5SDimitry Andric if (target) { 1230fe6060f1SDimitry Andric if (std::shared_ptr<ClangModulesDeclVendor> decl_vendor = 1231fe6060f1SDimitry Andric GetClangModulesDeclVendor()) { 12320b57cec5SDimitry Andric decl_vendor->FindDecls(name, false, UINT32_MAX, decls_from_modules); 12330b57cec5SDimitry Andric } 12340b57cec5SDimitry Andric } 12350b57cec5SDimitry Andric 1236480093f4SDimitry Andric SymbolContextList sc_list; 12370b57cec5SDimitry Andric if (namespace_decl && module_sp) { 1238349cc55cSDimitry Andric ModuleFunctionSearchOptions function_options; 1239349cc55cSDimitry Andric function_options.include_inlines = false; 1240349cc55cSDimitry Andric function_options.include_symbols = false; 12410b57cec5SDimitry Andric 12425ffd83dbSDimitry Andric module_sp->FindFunctions(name, namespace_decl, eFunctionNameTypeBase, 1243349cc55cSDimitry Andric function_options, sc_list); 12440b57cec5SDimitry Andric } else if (target && !namespace_decl) { 1245349cc55cSDimitry Andric ModuleFunctionSearchOptions function_options; 1246349cc55cSDimitry Andric function_options.include_inlines = false; 1247349cc55cSDimitry Andric function_options.include_symbols = true; 12480b57cec5SDimitry Andric 12490b57cec5SDimitry Andric // TODO Fix FindFunctions so that it doesn't return 12500b57cec5SDimitry Andric // instance methods for eFunctionNameTypeBase. 12510b57cec5SDimitry Andric 1252480093f4SDimitry Andric target->GetImages().FindFunctions( 1253349cc55cSDimitry Andric name, eFunctionNameTypeFull | eFunctionNameTypeBase, function_options, 1254349cc55cSDimitry Andric sc_list); 12550b57cec5SDimitry Andric } 12560b57cec5SDimitry Andric 12570b57cec5SDimitry Andric // If we found more than one function, see if we can use the frame's decl 12580b57cec5SDimitry Andric // context to remove functions that are shadowed by other functions which 12590b57cec5SDimitry Andric // match in type but are nearer in scope. 12600b57cec5SDimitry Andric // 12610b57cec5SDimitry Andric // AddOneFunction will not add a function whose type has already been 12620b57cec5SDimitry Andric // added, so if there's another function in the list with a matching type, 12630b57cec5SDimitry Andric // check to see if their decl context is a parent of the current frame's or 12640b57cec5SDimitry Andric // was imported via a and using statement, and pick the best match 12650b57cec5SDimitry Andric // according to lookup rules. 12660b57cec5SDimitry Andric if (sc_list.GetSize() > 1) { 12670b57cec5SDimitry Andric // Collect some info about our frame's context. 12680b57cec5SDimitry Andric StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr(); 12690b57cec5SDimitry Andric SymbolContext frame_sym_ctx; 12700b57cec5SDimitry Andric if (frame != nullptr) 12710b57cec5SDimitry Andric frame_sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | 12720b57cec5SDimitry Andric lldb::eSymbolContextBlock); 12730b57cec5SDimitry Andric CompilerDeclContext frame_decl_context = 12740b57cec5SDimitry Andric frame_sym_ctx.block != nullptr ? frame_sym_ctx.block->GetDeclContext() 12750b57cec5SDimitry Andric : CompilerDeclContext(); 12760b57cec5SDimitry Andric 12770b57cec5SDimitry Andric // We can't do this without a compiler decl context for our frame. 12780b57cec5SDimitry Andric if (frame_decl_context) { 1279480093f4SDimitry Andric sc_list = SearchFunctionsInSymbolContexts(sc_list, frame_decl_context); 12800b57cec5SDimitry Andric } 12810b57cec5SDimitry Andric } 12820b57cec5SDimitry Andric 12830b57cec5SDimitry Andric if (sc_list.GetSize()) { 12840b57cec5SDimitry Andric Symbol *extern_symbol = nullptr; 12850b57cec5SDimitry Andric Symbol *non_extern_symbol = nullptr; 12860b57cec5SDimitry Andric 128706c3fb27SDimitry Andric for (const SymbolContext &sym_ctx : sc_list) { 12880b57cec5SDimitry Andric if (sym_ctx.function) { 12890b57cec5SDimitry Andric CompilerDeclContext decl_ctx = sym_ctx.function->GetDeclContext(); 12900b57cec5SDimitry Andric 12910b57cec5SDimitry Andric if (!decl_ctx) 12920b57cec5SDimitry Andric continue; 12930b57cec5SDimitry Andric 12940b57cec5SDimitry Andric // Filter out class/instance methods. 129506c3fb27SDimitry Andric if (decl_ctx.IsClassMethod()) 12960b57cec5SDimitry Andric continue; 12970b57cec5SDimitry Andric 12985ffd83dbSDimitry Andric AddOneFunction(context, sym_ctx.function, nullptr); 12995ffd83dbSDimitry Andric context.m_found_function_with_type_info = true; 13000b57cec5SDimitry Andric } else if (sym_ctx.symbol) { 130106c3fb27SDimitry Andric Symbol *symbol = sym_ctx.symbol; 130206c3fb27SDimitry Andric if (target && symbol->GetType() == eSymbolTypeReExported) { 130306c3fb27SDimitry Andric symbol = symbol->ResolveReExportedSymbol(*target); 130406c3fb27SDimitry Andric if (symbol == nullptr) 13050b57cec5SDimitry Andric continue; 13060b57cec5SDimitry Andric } 13070b57cec5SDimitry Andric 130806c3fb27SDimitry Andric if (symbol->IsExternal()) 130906c3fb27SDimitry Andric extern_symbol = symbol; 13100b57cec5SDimitry Andric else 131106c3fb27SDimitry Andric non_extern_symbol = symbol; 13120b57cec5SDimitry Andric } 13130b57cec5SDimitry Andric } 13140b57cec5SDimitry Andric 13155ffd83dbSDimitry Andric if (!context.m_found_function_with_type_info) { 13160b57cec5SDimitry Andric for (clang::NamedDecl *decl : decls_from_modules) { 13170b57cec5SDimitry Andric if (llvm::isa<clang::FunctionDecl>(decl)) { 13180b57cec5SDimitry Andric clang::NamedDecl *copied_decl = 13190b57cec5SDimitry Andric llvm::cast_or_null<FunctionDecl>(CopyDecl(decl)); 13200b57cec5SDimitry Andric if (copied_decl) { 13210b57cec5SDimitry Andric context.AddNamedDecl(copied_decl); 13225ffd83dbSDimitry Andric context.m_found_function_with_type_info = true; 13230b57cec5SDimitry Andric } 13240b57cec5SDimitry Andric } 13250b57cec5SDimitry Andric } 13260b57cec5SDimitry Andric } 13270b57cec5SDimitry Andric 13285ffd83dbSDimitry Andric if (!context.m_found_function_with_type_info) { 13290b57cec5SDimitry Andric if (extern_symbol) { 13305ffd83dbSDimitry Andric AddOneFunction(context, nullptr, extern_symbol); 13310b57cec5SDimitry Andric } else if (non_extern_symbol) { 13325ffd83dbSDimitry Andric AddOneFunction(context, nullptr, non_extern_symbol); 13330b57cec5SDimitry Andric } 13340b57cec5SDimitry Andric } 13350b57cec5SDimitry Andric } 13360b57cec5SDimitry Andric } 13370b57cec5SDimitry Andric 1338480093f4SDimitry Andric void ClangExpressionDeclMap::FindExternalVisibleDecls( 1339480093f4SDimitry Andric NameSearchContext &context, lldb::ModuleSP module_sp, 13405ffd83dbSDimitry Andric const CompilerDeclContext &namespace_decl) { 1341480093f4SDimitry Andric assert(m_ast_context); 13420b57cec5SDimitry Andric 134381ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions); 13440b57cec5SDimitry Andric 1345480093f4SDimitry Andric const ConstString name(context.m_decl_name.getAsString().c_str()); 1346480093f4SDimitry Andric if (IgnoreName(name, false)) 1347480093f4SDimitry Andric return; 1348480093f4SDimitry Andric 1349480093f4SDimitry Andric // Only look for functions by name out in our symbols if the function doesn't 1350480093f4SDimitry Andric // start with our phony prefix of '$' 1351480093f4SDimitry Andric 1352480093f4SDimitry Andric Target *target = nullptr; 1353480093f4SDimitry Andric StackFrame *frame = nullptr; 1354480093f4SDimitry Andric SymbolContext sym_ctx; 1355480093f4SDimitry Andric if (m_parser_vars) { 1356480093f4SDimitry Andric target = m_parser_vars->m_exe_ctx.GetTargetPtr(); 1357480093f4SDimitry Andric frame = m_parser_vars->m_exe_ctx.GetFramePtr(); 1358480093f4SDimitry Andric } 1359480093f4SDimitry Andric if (frame != nullptr) 1360480093f4SDimitry Andric sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction | 1361480093f4SDimitry Andric lldb::eSymbolContextBlock); 1362480093f4SDimitry Andric 1363480093f4SDimitry Andric // Try the persistent decls, which take precedence over all else. 1364480093f4SDimitry Andric if (!namespace_decl) 13655ffd83dbSDimitry Andric SearchPersistenDecls(context, name); 1366480093f4SDimitry Andric 13675f757f3fSDimitry Andric if (name.GetStringRef().starts_with("$") && !namespace_decl) { 1368480093f4SDimitry Andric if (name == "$__lldb_class") { 13695ffd83dbSDimitry Andric LookUpLldbClass(context); 1370480093f4SDimitry Andric return; 13710b57cec5SDimitry Andric } 13720b57cec5SDimitry Andric 1373480093f4SDimitry Andric if (name == "$__lldb_objc_class") { 13745ffd83dbSDimitry Andric LookUpLldbObjCClass(context); 1375480093f4SDimitry Andric return; 1376480093f4SDimitry Andric } 1377480093f4SDimitry Andric if (name == g_lldb_local_vars_namespace_cstr) { 1378480093f4SDimitry Andric LookupLocalVarNamespace(sym_ctx, context); 1379480093f4SDimitry Andric return; 13800b57cec5SDimitry Andric } 13810b57cec5SDimitry Andric 1382480093f4SDimitry Andric // any other $__lldb names should be weeded out now 13835f757f3fSDimitry Andric if (name.GetStringRef().starts_with("$__lldb")) 1384480093f4SDimitry Andric return; 13850b57cec5SDimitry Andric 1386480093f4SDimitry Andric // No ParserVars means we can't do register or variable lookup. 1387480093f4SDimitry Andric if (!m_parser_vars || !m_parser_vars->m_persistent_vars) 1388480093f4SDimitry Andric return; 13890b57cec5SDimitry Andric 1390480093f4SDimitry Andric ExpressionVariableSP pvar_sp( 1391480093f4SDimitry Andric m_parser_vars->m_persistent_vars->GetVariable(name)); 1392480093f4SDimitry Andric 1393480093f4SDimitry Andric if (pvar_sp) { 13945ffd83dbSDimitry Andric AddOneVariable(context, pvar_sp); 1395480093f4SDimitry Andric return; 13960b57cec5SDimitry Andric } 13970b57cec5SDimitry Andric 13985f757f3fSDimitry Andric assert(name.GetStringRef().starts_with("$")); 1399480093f4SDimitry Andric llvm::StringRef reg_name = name.GetStringRef().substr(1); 14000b57cec5SDimitry Andric 1401480093f4SDimitry Andric if (m_parser_vars->m_exe_ctx.GetRegisterContext()) { 1402480093f4SDimitry Andric const RegisterInfo *reg_info( 1403480093f4SDimitry Andric m_parser_vars->m_exe_ctx.GetRegisterContext()->GetRegisterInfoByName( 1404480093f4SDimitry Andric reg_name)); 1405480093f4SDimitry Andric 1406480093f4SDimitry Andric if (reg_info) { 14075ffd83dbSDimitry Andric LLDB_LOG(log, " CEDM::FEVD Found register {0}", reg_info->name); 1408480093f4SDimitry Andric 14095ffd83dbSDimitry Andric AddOneRegister(context, reg_info); 1410480093f4SDimitry Andric } 1411480093f4SDimitry Andric } 1412480093f4SDimitry Andric return; 1413480093f4SDimitry Andric } 1414480093f4SDimitry Andric 1415480093f4SDimitry Andric bool local_var_lookup = !namespace_decl || (namespace_decl.GetName() == 1416480093f4SDimitry Andric g_lldb_local_vars_namespace_cstr); 1417480093f4SDimitry Andric if (frame && local_var_lookup) 14185ffd83dbSDimitry Andric if (LookupLocalVariable(context, name, sym_ctx, namespace_decl)) 1419480093f4SDimitry Andric return; 1420480093f4SDimitry Andric 1421480093f4SDimitry Andric if (target) { 1422480093f4SDimitry Andric ValueObjectSP valobj; 1423480093f4SDimitry Andric VariableSP var; 14245ffd83dbSDimitry Andric var = FindGlobalVariable(*target, module_sp, name, namespace_decl); 1425480093f4SDimitry Andric 1426480093f4SDimitry Andric if (var) { 1427480093f4SDimitry Andric valobj = ValueObjectVariable::Create(target, var); 14285ffd83dbSDimitry Andric AddOneVariable(context, var, valobj); 14295ffd83dbSDimitry Andric context.m_found_variable = true; 1430480093f4SDimitry Andric return; 14310b57cec5SDimitry Andric } 14320b57cec5SDimitry Andric } 1433480093f4SDimitry Andric 14345ffd83dbSDimitry Andric LookupFunction(context, module_sp, name, namespace_decl); 1435480093f4SDimitry Andric 1436480093f4SDimitry Andric // Try the modules next. 14375ffd83dbSDimitry Andric if (!context.m_found_function_with_type_info) 14385ffd83dbSDimitry Andric LookupInModulesDeclVendor(context, name); 14390b57cec5SDimitry Andric 14405ffd83dbSDimitry Andric if (target && !context.m_found_variable && !namespace_decl) { 14410b57cec5SDimitry Andric // We couldn't find a non-symbol variable for this. Now we'll hunt for a 14420b57cec5SDimitry Andric // generic data symbol, and -- if it is found -- treat it as a variable. 14430b57cec5SDimitry Andric Status error; 14440b57cec5SDimitry Andric 14450b57cec5SDimitry Andric const Symbol *data_symbol = 14460b57cec5SDimitry Andric m_parser_vars->m_sym_ctx.FindBestGlobalDataSymbol(name, error); 14470b57cec5SDimitry Andric 14480b57cec5SDimitry Andric if (!error.Success()) { 14490b57cec5SDimitry Andric const unsigned diag_id = 14500b57cec5SDimitry Andric m_ast_context->getDiagnostics().getCustomDiagID( 14510b57cec5SDimitry Andric clang::DiagnosticsEngine::Level::Error, "%0"); 14520b57cec5SDimitry Andric m_ast_context->getDiagnostics().Report(diag_id) << error.AsCString(); 14530b57cec5SDimitry Andric } 14540b57cec5SDimitry Andric 14550b57cec5SDimitry Andric if (data_symbol) { 14560b57cec5SDimitry Andric std::string warning("got name from symbols: "); 14570b57cec5SDimitry Andric warning.append(name.AsCString()); 14580b57cec5SDimitry Andric const unsigned diag_id = 14590b57cec5SDimitry Andric m_ast_context->getDiagnostics().getCustomDiagID( 14600b57cec5SDimitry Andric clang::DiagnosticsEngine::Level::Warning, "%0"); 14610b57cec5SDimitry Andric m_ast_context->getDiagnostics().Report(diag_id) << warning.c_str(); 14625ffd83dbSDimitry Andric AddOneGenericVariable(context, *data_symbol); 14635ffd83dbSDimitry Andric context.m_found_variable = true; 14640b57cec5SDimitry Andric } 14650b57cec5SDimitry Andric } 14660b57cec5SDimitry Andric } 14670b57cec5SDimitry Andric 14680b57cec5SDimitry Andric bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var, 14690b57cec5SDimitry Andric lldb_private::Value &var_location, 14700b57cec5SDimitry Andric TypeFromUser *user_type, 14710b57cec5SDimitry Andric TypeFromParser *parser_type) { 147281ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions); 14730b57cec5SDimitry Andric 14740b57cec5SDimitry Andric Type *var_type = var->GetType(); 14750b57cec5SDimitry Andric 14760b57cec5SDimitry Andric if (!var_type) { 14775ffd83dbSDimitry Andric LLDB_LOG(log, "Skipped a definition because it has no type"); 14780b57cec5SDimitry Andric return false; 14790b57cec5SDimitry Andric } 14800b57cec5SDimitry Andric 14810b57cec5SDimitry Andric CompilerType var_clang_type = var_type->GetFullCompilerType(); 14820b57cec5SDimitry Andric 14830b57cec5SDimitry Andric if (!var_clang_type) { 14845ffd83dbSDimitry Andric LLDB_LOG(log, "Skipped a definition because it has no Clang type"); 14850b57cec5SDimitry Andric return false; 14860b57cec5SDimitry Andric } 14870b57cec5SDimitry Andric 1488bdd1243dSDimitry Andric auto ts = var_type->GetForwardCompilerType().GetTypeSystem(); 1489bdd1243dSDimitry Andric auto clang_ast = ts.dyn_cast_or_null<TypeSystemClang>(); 14900b57cec5SDimitry Andric 14910b57cec5SDimitry Andric if (!clang_ast) { 14925ffd83dbSDimitry Andric LLDB_LOG(log, "Skipped a definition because it has no Clang AST"); 14930b57cec5SDimitry Andric return false; 14940b57cec5SDimitry Andric } 14950b57cec5SDimitry Andric 1496753f127fSDimitry Andric DWARFExpressionList &var_location_list = var->LocationExpressionList(); 14970b57cec5SDimitry Andric 14980b57cec5SDimitry Andric Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr(); 14990b57cec5SDimitry Andric Status err; 15000b57cec5SDimitry Andric 15010b57cec5SDimitry Andric if (var->GetLocationIsConstantValueData()) { 15020b57cec5SDimitry Andric DataExtractor const_value_extractor; 1503753f127fSDimitry Andric if (var_location_list.GetExpressionData(const_value_extractor)) { 15040b57cec5SDimitry Andric var_location = Value(const_value_extractor.GetDataStart(), 15050b57cec5SDimitry Andric const_value_extractor.GetByteSize()); 1506fe6060f1SDimitry Andric var_location.SetValueType(Value::ValueType::HostAddress); 15070b57cec5SDimitry Andric } else { 15085ffd83dbSDimitry Andric LLDB_LOG(log, "Error evaluating constant variable: {0}", err.AsCString()); 15090b57cec5SDimitry Andric return false; 15100b57cec5SDimitry Andric } 15110b57cec5SDimitry Andric } 15120b57cec5SDimitry Andric 15130b57cec5SDimitry Andric CompilerType type_to_use = GuardedCopyType(var_clang_type); 15140b57cec5SDimitry Andric 15150b57cec5SDimitry Andric if (!type_to_use) { 15165ffd83dbSDimitry Andric LLDB_LOG(log, 15170b57cec5SDimitry Andric "Couldn't copy a variable's type into the parser's AST context"); 15180b57cec5SDimitry Andric 15190b57cec5SDimitry Andric return false; 15200b57cec5SDimitry Andric } 15210b57cec5SDimitry Andric 15220b57cec5SDimitry Andric if (parser_type) 15230b57cec5SDimitry Andric *parser_type = TypeFromParser(type_to_use); 15240b57cec5SDimitry Andric 1525fe6060f1SDimitry Andric if (var_location.GetContextType() == Value::ContextType::Invalid) 15260b57cec5SDimitry Andric var_location.SetCompilerType(type_to_use); 15270b57cec5SDimitry Andric 1528fe6060f1SDimitry Andric if (var_location.GetValueType() == Value::ValueType::FileAddress) { 15290b57cec5SDimitry Andric SymbolContext var_sc; 15300b57cec5SDimitry Andric var->CalculateSymbolContext(&var_sc); 15310b57cec5SDimitry Andric 15320b57cec5SDimitry Andric if (!var_sc.module_sp) 15330b57cec5SDimitry Andric return false; 15340b57cec5SDimitry Andric 15350b57cec5SDimitry Andric Address so_addr(var_location.GetScalar().ULongLong(), 15360b57cec5SDimitry Andric var_sc.module_sp->GetSectionList()); 15370b57cec5SDimitry Andric 15380b57cec5SDimitry Andric lldb::addr_t load_addr = so_addr.GetLoadAddress(target); 15390b57cec5SDimitry Andric 15400b57cec5SDimitry Andric if (load_addr != LLDB_INVALID_ADDRESS) { 15410b57cec5SDimitry Andric var_location.GetScalar() = load_addr; 1542fe6060f1SDimitry Andric var_location.SetValueType(Value::ValueType::LoadAddress); 15430b57cec5SDimitry Andric } 15440b57cec5SDimitry Andric } 15450b57cec5SDimitry Andric 15460b57cec5SDimitry Andric if (user_type) 15470b57cec5SDimitry Andric *user_type = TypeFromUser(var_clang_type); 15480b57cec5SDimitry Andric 15490b57cec5SDimitry Andric return true; 15500b57cec5SDimitry Andric } 15510b57cec5SDimitry Andric 1552fcaf7f86SDimitry Andric ClangExpressionVariable::ParserVars * 1553fcaf7f86SDimitry Andric ClangExpressionDeclMap::AddExpressionVariable(NameSearchContext &context, 1554fcaf7f86SDimitry Andric TypeFromParser const &pt, 15555ffd83dbSDimitry Andric ValueObjectSP valobj) { 15560b57cec5SDimitry Andric clang::QualType parser_opaque_type = 15570b57cec5SDimitry Andric QualType::getFromOpaquePtr(pt.GetOpaqueQualType()); 15580b57cec5SDimitry Andric 15590b57cec5SDimitry Andric if (parser_opaque_type.isNull()) 1560fcaf7f86SDimitry Andric return nullptr; 15610b57cec5SDimitry Andric 15620b57cec5SDimitry Andric if (const clang::Type *parser_type = parser_opaque_type.getTypePtr()) { 15630b57cec5SDimitry Andric if (const TagType *tag_type = dyn_cast<TagType>(parser_type)) 15640b57cec5SDimitry Andric CompleteType(tag_type->getDecl()); 15650b57cec5SDimitry Andric if (const ObjCObjectPointerType *objc_object_ptr_type = 15660b57cec5SDimitry Andric dyn_cast<ObjCObjectPointerType>(parser_type)) 15670b57cec5SDimitry Andric CompleteType(objc_object_ptr_type->getInterfaceDecl()); 15680b57cec5SDimitry Andric } 15690b57cec5SDimitry Andric 15700b57cec5SDimitry Andric bool is_reference = pt.IsReferenceType(); 15710b57cec5SDimitry Andric 15720b57cec5SDimitry Andric NamedDecl *var_decl = nullptr; 15730b57cec5SDimitry Andric if (is_reference) 15740b57cec5SDimitry Andric var_decl = context.AddVarDecl(pt); 15750b57cec5SDimitry Andric else 15760b57cec5SDimitry Andric var_decl = context.AddVarDecl(pt.GetLValueReferenceType()); 15770b57cec5SDimitry Andric 15780b57cec5SDimitry Andric std::string decl_name(context.m_decl_name.getAsString()); 15790b57cec5SDimitry Andric ConstString entity_name(decl_name.c_str()); 15800b57cec5SDimitry Andric ClangExpressionVariable *entity(new ClangExpressionVariable(valobj)); 15810b57cec5SDimitry Andric m_found_entities.AddNewlyConstructedVariable(entity); 15820b57cec5SDimitry Andric 15830b57cec5SDimitry Andric assert(entity); 15840b57cec5SDimitry Andric entity->EnableParserVars(GetParserID()); 15850b57cec5SDimitry Andric ClangExpressionVariable::ParserVars *parser_vars = 15860b57cec5SDimitry Andric entity->GetParserVars(GetParserID()); 1587fcaf7f86SDimitry Andric 15880b57cec5SDimitry Andric parser_vars->m_named_decl = var_decl; 15890b57cec5SDimitry Andric 15900b57cec5SDimitry Andric if (is_reference) 15910b57cec5SDimitry Andric entity->m_flags |= ClangExpressionVariable::EVTypeIsReference; 15920b57cec5SDimitry Andric 1593fcaf7f86SDimitry Andric return parser_vars; 1594fcaf7f86SDimitry Andric } 1595fcaf7f86SDimitry Andric 1596fcaf7f86SDimitry Andric void ClangExpressionDeclMap::AddOneVariable( 1597fcaf7f86SDimitry Andric NameSearchContext &context, ValueObjectSP valobj, 1598fcaf7f86SDimitry Andric ValueObjectProviderTy valobj_provider) { 1599fcaf7f86SDimitry Andric assert(m_parser_vars.get()); 1600fcaf7f86SDimitry Andric assert(valobj); 1601fcaf7f86SDimitry Andric 1602fcaf7f86SDimitry Andric Log *log = GetLog(LLDBLog::Expressions); 1603fcaf7f86SDimitry Andric 1604fcaf7f86SDimitry Andric Value var_location = valobj->GetValue(); 1605fcaf7f86SDimitry Andric 1606fcaf7f86SDimitry Andric TypeFromUser user_type = valobj->GetCompilerType(); 1607fcaf7f86SDimitry Andric 1608bdd1243dSDimitry Andric auto clang_ast = 1609bdd1243dSDimitry Andric user_type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>(); 1610fcaf7f86SDimitry Andric 1611fcaf7f86SDimitry Andric if (!clang_ast) { 1612fcaf7f86SDimitry Andric LLDB_LOG(log, "Skipped a definition because it has no Clang AST"); 1613fcaf7f86SDimitry Andric return; 1614fcaf7f86SDimitry Andric } 1615fcaf7f86SDimitry Andric 1616fcaf7f86SDimitry Andric TypeFromParser parser_type = GuardedCopyType(user_type); 1617fcaf7f86SDimitry Andric 1618fcaf7f86SDimitry Andric if (!parser_type) { 1619fcaf7f86SDimitry Andric LLDB_LOG(log, 1620fcaf7f86SDimitry Andric "Couldn't copy a variable's type into the parser's AST context"); 1621fcaf7f86SDimitry Andric 1622fcaf7f86SDimitry Andric return; 1623fcaf7f86SDimitry Andric } 1624fcaf7f86SDimitry Andric 1625fcaf7f86SDimitry Andric if (var_location.GetContextType() == Value::ContextType::Invalid) 1626fcaf7f86SDimitry Andric var_location.SetCompilerType(parser_type); 1627fcaf7f86SDimitry Andric 1628fcaf7f86SDimitry Andric ClangExpressionVariable::ParserVars *parser_vars = 1629fcaf7f86SDimitry Andric AddExpressionVariable(context, parser_type, valobj); 1630fcaf7f86SDimitry Andric 1631fcaf7f86SDimitry Andric if (!parser_vars) 1632fcaf7f86SDimitry Andric return; 1633fcaf7f86SDimitry Andric 163481ad6265SDimitry Andric LLDB_LOG(log, " CEDM::FEVD Found variable {0}, returned\n{1} (original {2})", 1635fcaf7f86SDimitry Andric context.m_decl_name, ClangUtil::DumpDecl(parser_vars->m_named_decl), 1636fcaf7f86SDimitry Andric ClangUtil::ToString(user_type)); 1637fcaf7f86SDimitry Andric 1638fcaf7f86SDimitry Andric parser_vars->m_llvm_value = nullptr; 1639fcaf7f86SDimitry Andric parser_vars->m_lldb_value = std::move(var_location); 1640fcaf7f86SDimitry Andric parser_vars->m_lldb_valobj_provider = std::move(valobj_provider); 1641fcaf7f86SDimitry Andric } 1642fcaf7f86SDimitry Andric 1643fcaf7f86SDimitry Andric void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, 1644fcaf7f86SDimitry Andric VariableSP var, 1645fcaf7f86SDimitry Andric ValueObjectSP valobj) { 1646fcaf7f86SDimitry Andric assert(m_parser_vars.get()); 1647fcaf7f86SDimitry Andric 1648fcaf7f86SDimitry Andric Log *log = GetLog(LLDBLog::Expressions); 1649fcaf7f86SDimitry Andric 1650fcaf7f86SDimitry Andric TypeFromUser ut; 1651fcaf7f86SDimitry Andric TypeFromParser pt; 1652fcaf7f86SDimitry Andric Value var_location; 1653fcaf7f86SDimitry Andric 1654fcaf7f86SDimitry Andric if (!GetVariableValue(var, var_location, &ut, &pt)) 1655fcaf7f86SDimitry Andric return; 1656fcaf7f86SDimitry Andric 1657fcaf7f86SDimitry Andric ClangExpressionVariable::ParserVars *parser_vars = 1658fcaf7f86SDimitry Andric AddExpressionVariable(context, pt, std::move(valobj)); 1659fcaf7f86SDimitry Andric 1660fcaf7f86SDimitry Andric if (!parser_vars) 1661fcaf7f86SDimitry Andric return; 1662fcaf7f86SDimitry Andric 1663fcaf7f86SDimitry Andric LLDB_LOG(log, " CEDM::FEVD Found variable {0}, returned\n{1} (original {2})", 1664fcaf7f86SDimitry Andric context.m_decl_name, ClangUtil::DumpDecl(parser_vars->m_named_decl), 1665fcaf7f86SDimitry Andric ClangUtil::ToString(ut)); 1666fcaf7f86SDimitry Andric 1667fcaf7f86SDimitry Andric parser_vars->m_llvm_value = nullptr; 1668fcaf7f86SDimitry Andric parser_vars->m_lldb_value = var_location; 1669fcaf7f86SDimitry Andric parser_vars->m_lldb_var = var; 16700b57cec5SDimitry Andric } 16710b57cec5SDimitry Andric 16720b57cec5SDimitry Andric void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, 16735ffd83dbSDimitry Andric ExpressionVariableSP &pvar_sp) { 167481ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions); 16750b57cec5SDimitry Andric 16760b57cec5SDimitry Andric TypeFromUser user_type( 16770b57cec5SDimitry Andric llvm::cast<ClangExpressionVariable>(pvar_sp.get())->GetTypeFromUser()); 16780b57cec5SDimitry Andric 16790b57cec5SDimitry Andric TypeFromParser parser_type(GuardedCopyType(user_type)); 16800b57cec5SDimitry Andric 16810b57cec5SDimitry Andric if (!parser_type.GetOpaqueQualType()) { 16825ffd83dbSDimitry Andric LLDB_LOG(log, " CEDM::FEVD Couldn't import type for pvar {0}", 16835ffd83dbSDimitry Andric pvar_sp->GetName()); 16840b57cec5SDimitry Andric return; 16850b57cec5SDimitry Andric } 16860b57cec5SDimitry Andric 16870b57cec5SDimitry Andric NamedDecl *var_decl = 16880b57cec5SDimitry Andric context.AddVarDecl(parser_type.GetLValueReferenceType()); 16890b57cec5SDimitry Andric 16900b57cec5SDimitry Andric llvm::cast<ClangExpressionVariable>(pvar_sp.get()) 16910b57cec5SDimitry Andric ->EnableParserVars(GetParserID()); 16920b57cec5SDimitry Andric ClangExpressionVariable::ParserVars *parser_vars = 16930b57cec5SDimitry Andric llvm::cast<ClangExpressionVariable>(pvar_sp.get()) 16940b57cec5SDimitry Andric ->GetParserVars(GetParserID()); 16950b57cec5SDimitry Andric parser_vars->m_named_decl = var_decl; 16960b57cec5SDimitry Andric parser_vars->m_llvm_value = nullptr; 16970b57cec5SDimitry Andric parser_vars->m_lldb_value.Clear(); 16980b57cec5SDimitry Andric 169981ad6265SDimitry Andric LLDB_LOG(log, " CEDM::FEVD Added pvar {0}, returned\n{1}", 1700480093f4SDimitry Andric pvar_sp->GetName(), ClangUtil::DumpDecl(var_decl)); 17010b57cec5SDimitry Andric } 17020b57cec5SDimitry Andric 17030b57cec5SDimitry Andric void ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context, 17045ffd83dbSDimitry Andric const Symbol &symbol) { 17050b57cec5SDimitry Andric assert(m_parser_vars.get()); 17060b57cec5SDimitry Andric 170781ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions); 17080b57cec5SDimitry Andric 17090b57cec5SDimitry Andric Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr(); 17100b57cec5SDimitry Andric 17110b57cec5SDimitry Andric if (target == nullptr) 17120b57cec5SDimitry Andric return; 17130b57cec5SDimitry Andric 1714bdd1243dSDimitry Andric auto scratch_ast_context = GetScratchContext(*target); 1715480093f4SDimitry Andric if (!scratch_ast_context) 1716480093f4SDimitry Andric return; 17170b57cec5SDimitry Andric 1718480093f4SDimitry Andric TypeFromUser user_type(scratch_ast_context->GetBasicType(eBasicTypeVoid) 17190b57cec5SDimitry Andric .GetPointerType() 17200b57cec5SDimitry Andric .GetLValueReferenceType()); 1721480093f4SDimitry Andric TypeFromParser parser_type(m_clang_ast_context->GetBasicType(eBasicTypeVoid) 17220b57cec5SDimitry Andric .GetPointerType() 17230b57cec5SDimitry Andric .GetLValueReferenceType()); 17240b57cec5SDimitry Andric NamedDecl *var_decl = context.AddVarDecl(parser_type); 17250b57cec5SDimitry Andric 17260b57cec5SDimitry Andric std::string decl_name(context.m_decl_name.getAsString()); 17270b57cec5SDimitry Andric ConstString entity_name(decl_name.c_str()); 17280b57cec5SDimitry Andric ClangExpressionVariable *entity(new ClangExpressionVariable( 17290b57cec5SDimitry Andric m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), entity_name, 17300b57cec5SDimitry Andric user_type, m_parser_vars->m_target_info.byte_order, 17310b57cec5SDimitry Andric m_parser_vars->m_target_info.address_byte_size)); 17320b57cec5SDimitry Andric m_found_entities.AddNewlyConstructedVariable(entity); 17330b57cec5SDimitry Andric 17340b57cec5SDimitry Andric entity->EnableParserVars(GetParserID()); 17350b57cec5SDimitry Andric ClangExpressionVariable::ParserVars *parser_vars = 17360b57cec5SDimitry Andric entity->GetParserVars(GetParserID()); 17370b57cec5SDimitry Andric 17380b57cec5SDimitry Andric const Address symbol_address = symbol.GetAddress(); 17390b57cec5SDimitry Andric lldb::addr_t symbol_load_addr = symbol_address.GetLoadAddress(target); 17400b57cec5SDimitry Andric 1741fe6060f1SDimitry Andric // parser_vars->m_lldb_value.SetContext(Value::ContextType::ClangType, 17420b57cec5SDimitry Andric // user_type.GetOpaqueQualType()); 17430b57cec5SDimitry Andric parser_vars->m_lldb_value.SetCompilerType(user_type); 17440b57cec5SDimitry Andric parser_vars->m_lldb_value.GetScalar() = symbol_load_addr; 1745fe6060f1SDimitry Andric parser_vars->m_lldb_value.SetValueType(Value::ValueType::LoadAddress); 17460b57cec5SDimitry Andric 17470b57cec5SDimitry Andric parser_vars->m_named_decl = var_decl; 17480b57cec5SDimitry Andric parser_vars->m_llvm_value = nullptr; 17490b57cec5SDimitry Andric parser_vars->m_lldb_sym = &symbol; 17500b57cec5SDimitry Andric 175181ad6265SDimitry Andric LLDB_LOG(log, " CEDM::FEVD Found variable {0}, returned\n{1}", decl_name, 17525ffd83dbSDimitry Andric ClangUtil::DumpDecl(var_decl)); 17530b57cec5SDimitry Andric } 17540b57cec5SDimitry Andric 17550b57cec5SDimitry Andric void ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context, 17565ffd83dbSDimitry Andric const RegisterInfo *reg_info) { 175781ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions); 17580b57cec5SDimitry Andric 17590b57cec5SDimitry Andric CompilerType clang_type = 1760480093f4SDimitry Andric m_clang_ast_context->GetBuiltinTypeForEncodingAndBitSize( 1761480093f4SDimitry Andric reg_info->encoding, reg_info->byte_size * 8); 17620b57cec5SDimitry Andric 17630b57cec5SDimitry Andric if (!clang_type) { 17645ffd83dbSDimitry Andric LLDB_LOG(log, " Tried to add a type for {0}, but couldn't get one", 17655ffd83dbSDimitry Andric context.m_decl_name.getAsString()); 17660b57cec5SDimitry Andric return; 17670b57cec5SDimitry Andric } 17680b57cec5SDimitry Andric 17690b57cec5SDimitry Andric TypeFromParser parser_clang_type(clang_type); 17700b57cec5SDimitry Andric 17710b57cec5SDimitry Andric NamedDecl *var_decl = context.AddVarDecl(parser_clang_type); 17720b57cec5SDimitry Andric 17730b57cec5SDimitry Andric ClangExpressionVariable *entity(new ClangExpressionVariable( 17740b57cec5SDimitry Andric m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), 17750b57cec5SDimitry Andric m_parser_vars->m_target_info.byte_order, 17760b57cec5SDimitry Andric m_parser_vars->m_target_info.address_byte_size)); 17770b57cec5SDimitry Andric m_found_entities.AddNewlyConstructedVariable(entity); 17780b57cec5SDimitry Andric 17790b57cec5SDimitry Andric std::string decl_name(context.m_decl_name.getAsString()); 17800b57cec5SDimitry Andric entity->SetName(ConstString(decl_name.c_str())); 17810b57cec5SDimitry Andric entity->SetRegisterInfo(reg_info); 17820b57cec5SDimitry Andric entity->EnableParserVars(GetParserID()); 17830b57cec5SDimitry Andric ClangExpressionVariable::ParserVars *parser_vars = 17840b57cec5SDimitry Andric entity->GetParserVars(GetParserID()); 17850b57cec5SDimitry Andric parser_vars->m_named_decl = var_decl; 17860b57cec5SDimitry Andric parser_vars->m_llvm_value = nullptr; 17870b57cec5SDimitry Andric parser_vars->m_lldb_value.Clear(); 17880b57cec5SDimitry Andric entity->m_flags |= ClangExpressionVariable::EVBareRegister; 17890b57cec5SDimitry Andric 179081ad6265SDimitry Andric LLDB_LOG(log, " CEDM::FEVD Added register {0}, returned\n{1}", 17915ffd83dbSDimitry Andric context.m_decl_name.getAsString(), ClangUtil::DumpDecl(var_decl)); 17920b57cec5SDimitry Andric } 17930b57cec5SDimitry Andric 17940b57cec5SDimitry Andric void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, 17955ffd83dbSDimitry Andric Function *function, 17965ffd83dbSDimitry Andric Symbol *symbol) { 17970b57cec5SDimitry Andric assert(m_parser_vars.get()); 17980b57cec5SDimitry Andric 179981ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions); 18000b57cec5SDimitry Andric 18010b57cec5SDimitry Andric NamedDecl *function_decl = nullptr; 18020b57cec5SDimitry Andric Address fun_address; 18030b57cec5SDimitry Andric CompilerType function_clang_type; 18040b57cec5SDimitry Andric 18050b57cec5SDimitry Andric bool is_indirect_function = false; 18060b57cec5SDimitry Andric 18070b57cec5SDimitry Andric if (function) { 18080b57cec5SDimitry Andric Type *function_type = function->GetType(); 18090b57cec5SDimitry Andric 18100b57cec5SDimitry Andric const auto lang = function->GetCompileUnit()->GetLanguage(); 18110b57cec5SDimitry Andric const auto name = function->GetMangled().GetMangledName().AsCString(); 18120b57cec5SDimitry Andric const bool extern_c = (Language::LanguageIsC(lang) && 18130b57cec5SDimitry Andric !CPlusPlusLanguage::IsCPPMangledName(name)) || 18140b57cec5SDimitry Andric (Language::LanguageIsObjC(lang) && 18150b57cec5SDimitry Andric !Language::LanguageIsCPlusPlus(lang)); 18160b57cec5SDimitry Andric 18170b57cec5SDimitry Andric if (!extern_c) { 18180b57cec5SDimitry Andric TypeSystem *type_system = function->GetDeclContext().GetTypeSystem(); 18195ffd83dbSDimitry Andric if (llvm::isa<TypeSystemClang>(type_system)) { 18200b57cec5SDimitry Andric clang::DeclContext *src_decl_context = 18210b57cec5SDimitry Andric (clang::DeclContext *)function->GetDeclContext() 18220b57cec5SDimitry Andric .GetOpaqueDeclContext(); 18230b57cec5SDimitry Andric clang::FunctionDecl *src_function_decl = 18240b57cec5SDimitry Andric llvm::dyn_cast_or_null<clang::FunctionDecl>(src_decl_context); 18250b57cec5SDimitry Andric if (src_function_decl && 18260b57cec5SDimitry Andric src_function_decl->getTemplateSpecializationInfo()) { 18270b57cec5SDimitry Andric clang::FunctionTemplateDecl *function_template = 18280b57cec5SDimitry Andric src_function_decl->getTemplateSpecializationInfo()->getTemplate(); 18290b57cec5SDimitry Andric clang::FunctionTemplateDecl *copied_function_template = 18300b57cec5SDimitry Andric llvm::dyn_cast_or_null<clang::FunctionTemplateDecl>( 18310b57cec5SDimitry Andric CopyDecl(function_template)); 18320b57cec5SDimitry Andric if (copied_function_template) { 18330b57cec5SDimitry Andric if (log) { 18340b57cec5SDimitry Andric StreamString ss; 18350b57cec5SDimitry Andric 18360b57cec5SDimitry Andric function->DumpSymbolContext(&ss); 18370b57cec5SDimitry Andric 1838480093f4SDimitry Andric LLDB_LOG(log, 18395ffd83dbSDimitry Andric " CEDM::FEVD Imported decl for function template" 184081ad6265SDimitry Andric " {0} (description {1}), returned\n{2}", 18415ffd83dbSDimitry Andric copied_function_template->getNameAsString(), 1842480093f4SDimitry Andric ss.GetData(), 1843480093f4SDimitry Andric ClangUtil::DumpDecl(copied_function_template)); 18440b57cec5SDimitry Andric } 18450b57cec5SDimitry Andric 18460b57cec5SDimitry Andric context.AddNamedDecl(copied_function_template); 18470b57cec5SDimitry Andric } 18480b57cec5SDimitry Andric } else if (src_function_decl) { 18490b57cec5SDimitry Andric if (clang::FunctionDecl *copied_function_decl = 18500b57cec5SDimitry Andric llvm::dyn_cast_or_null<clang::FunctionDecl>( 18510b57cec5SDimitry Andric CopyDecl(src_function_decl))) { 18520b57cec5SDimitry Andric if (log) { 18530b57cec5SDimitry Andric StreamString ss; 18540b57cec5SDimitry Andric 18550b57cec5SDimitry Andric function->DumpSymbolContext(&ss); 18560b57cec5SDimitry Andric 1857480093f4SDimitry Andric LLDB_LOG(log, 185881ad6265SDimitry Andric " CEDM::FEVD Imported decl for function {0} " 185981ad6265SDimitry Andric "(description {1}), returned\n{2}", 18605ffd83dbSDimitry Andric copied_function_decl->getNameAsString(), ss.GetData(), 18615ffd83dbSDimitry Andric ClangUtil::DumpDecl(copied_function_decl)); 18620b57cec5SDimitry Andric } 18630b57cec5SDimitry Andric 18640b57cec5SDimitry Andric context.AddNamedDecl(copied_function_decl); 18650b57cec5SDimitry Andric return; 18660b57cec5SDimitry Andric } else { 18675ffd83dbSDimitry Andric LLDB_LOG(log, " Failed to import the function decl for '{0}'", 18685ffd83dbSDimitry Andric src_function_decl->getName()); 18690b57cec5SDimitry Andric } 18700b57cec5SDimitry Andric } 18710b57cec5SDimitry Andric } 18720b57cec5SDimitry Andric } 18730b57cec5SDimitry Andric 18740b57cec5SDimitry Andric if (!function_type) { 18755ffd83dbSDimitry Andric LLDB_LOG(log, " Skipped a function because it has no type"); 18760b57cec5SDimitry Andric return; 18770b57cec5SDimitry Andric } 18780b57cec5SDimitry Andric 18790b57cec5SDimitry Andric function_clang_type = function_type->GetFullCompilerType(); 18800b57cec5SDimitry Andric 18810b57cec5SDimitry Andric if (!function_clang_type) { 18825ffd83dbSDimitry Andric LLDB_LOG(log, " Skipped a function because it has no Clang type"); 18830b57cec5SDimitry Andric return; 18840b57cec5SDimitry Andric } 18850b57cec5SDimitry Andric 18860b57cec5SDimitry Andric fun_address = function->GetAddressRange().GetBaseAddress(); 18870b57cec5SDimitry Andric 18880b57cec5SDimitry Andric CompilerType copied_function_type = GuardedCopyType(function_clang_type); 18890b57cec5SDimitry Andric if (copied_function_type) { 18900b57cec5SDimitry Andric function_decl = context.AddFunDecl(copied_function_type, extern_c); 18910b57cec5SDimitry Andric 18920b57cec5SDimitry Andric if (!function_decl) { 18935ffd83dbSDimitry Andric LLDB_LOG(log, " Failed to create a function decl for '{0}' ({1:x})", 18945ffd83dbSDimitry Andric function_type->GetName(), function_type->GetID()); 18950b57cec5SDimitry Andric 18960b57cec5SDimitry Andric return; 18970b57cec5SDimitry Andric } 18980b57cec5SDimitry Andric } else { 18990b57cec5SDimitry Andric // We failed to copy the type we found 19005ffd83dbSDimitry Andric LLDB_LOG(log, 19015ffd83dbSDimitry Andric " Failed to import the function type '{0}' ({1:x})" 1902bdd1243dSDimitry Andric " into the expression parser AST context", 19035ffd83dbSDimitry Andric function_type->GetName(), function_type->GetID()); 19040b57cec5SDimitry Andric 19050b57cec5SDimitry Andric return; 19060b57cec5SDimitry Andric } 19070b57cec5SDimitry Andric } else if (symbol) { 19080b57cec5SDimitry Andric fun_address = symbol->GetAddress(); 19090b57cec5SDimitry Andric function_decl = context.AddGenericFunDecl(); 19100b57cec5SDimitry Andric is_indirect_function = symbol->IsIndirect(); 19110b57cec5SDimitry Andric } else { 19125ffd83dbSDimitry Andric LLDB_LOG(log, " AddOneFunction called with no function and no symbol"); 19130b57cec5SDimitry Andric return; 19140b57cec5SDimitry Andric } 19150b57cec5SDimitry Andric 19160b57cec5SDimitry Andric Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr(); 19170b57cec5SDimitry Andric 19180b57cec5SDimitry Andric lldb::addr_t load_addr = 19190b57cec5SDimitry Andric fun_address.GetCallableLoadAddress(target, is_indirect_function); 19200b57cec5SDimitry Andric 19210b57cec5SDimitry Andric ClangExpressionVariable *entity(new ClangExpressionVariable( 19220b57cec5SDimitry Andric m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), 19230b57cec5SDimitry Andric m_parser_vars->m_target_info.byte_order, 19240b57cec5SDimitry Andric m_parser_vars->m_target_info.address_byte_size)); 19250b57cec5SDimitry Andric m_found_entities.AddNewlyConstructedVariable(entity); 19260b57cec5SDimitry Andric 19270b57cec5SDimitry Andric std::string decl_name(context.m_decl_name.getAsString()); 19280b57cec5SDimitry Andric entity->SetName(ConstString(decl_name.c_str())); 19290b57cec5SDimitry Andric entity->SetCompilerType(function_clang_type); 19300b57cec5SDimitry Andric entity->EnableParserVars(GetParserID()); 19310b57cec5SDimitry Andric 19320b57cec5SDimitry Andric ClangExpressionVariable::ParserVars *parser_vars = 19330b57cec5SDimitry Andric entity->GetParserVars(GetParserID()); 19340b57cec5SDimitry Andric 19350b57cec5SDimitry Andric if (load_addr != LLDB_INVALID_ADDRESS) { 1936fe6060f1SDimitry Andric parser_vars->m_lldb_value.SetValueType(Value::ValueType::LoadAddress); 19370b57cec5SDimitry Andric parser_vars->m_lldb_value.GetScalar() = load_addr; 19380b57cec5SDimitry Andric } else { 19390b57cec5SDimitry Andric // We have to try finding a file address. 19400b57cec5SDimitry Andric 19410b57cec5SDimitry Andric lldb::addr_t file_addr = fun_address.GetFileAddress(); 19420b57cec5SDimitry Andric 1943fe6060f1SDimitry Andric parser_vars->m_lldb_value.SetValueType(Value::ValueType::FileAddress); 19440b57cec5SDimitry Andric parser_vars->m_lldb_value.GetScalar() = file_addr; 19450b57cec5SDimitry Andric } 19460b57cec5SDimitry Andric 19470b57cec5SDimitry Andric parser_vars->m_named_decl = function_decl; 19480b57cec5SDimitry Andric parser_vars->m_llvm_value = nullptr; 19490b57cec5SDimitry Andric 19500b57cec5SDimitry Andric if (log) { 19510b57cec5SDimitry Andric StreamString ss; 19520b57cec5SDimitry Andric 19530b57cec5SDimitry Andric fun_address.Dump(&ss, 19540b57cec5SDimitry Andric m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), 19550b57cec5SDimitry Andric Address::DumpStyleResolvedDescription); 19560b57cec5SDimitry Andric 1957480093f4SDimitry Andric LLDB_LOG(log, 195881ad6265SDimitry Andric " CEDM::FEVD Found {0} function {1} (description {2}), " 195981ad6265SDimitry Andric "returned\n{3}", 19605ffd83dbSDimitry Andric (function ? "specific" : "generic"), decl_name, ss.GetData(), 19615ffd83dbSDimitry Andric ClangUtil::DumpDecl(function_decl)); 19620b57cec5SDimitry Andric } 19630b57cec5SDimitry Andric } 19640b57cec5SDimitry Andric 19655ffd83dbSDimitry Andric void ClangExpressionDeclMap::AddContextClassType(NameSearchContext &context, 19665ffd83dbSDimitry Andric const TypeFromUser &ut) { 19670b57cec5SDimitry Andric CompilerType copied_clang_type = GuardedCopyType(ut); 19680b57cec5SDimitry Andric 196981ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions); 19700b57cec5SDimitry Andric 19710b57cec5SDimitry Andric if (!copied_clang_type) { 19725ffd83dbSDimitry Andric LLDB_LOG(log, 19730b57cec5SDimitry Andric "ClangExpressionDeclMap::AddThisType - Couldn't import the type"); 19740b57cec5SDimitry Andric 19750b57cec5SDimitry Andric return; 19760b57cec5SDimitry Andric } 19770b57cec5SDimitry Andric 19780b57cec5SDimitry Andric if (copied_clang_type.IsAggregateType() && 19790b57cec5SDimitry Andric copied_clang_type.GetCompleteType()) { 19800b57cec5SDimitry Andric CompilerType void_clang_type = 1981480093f4SDimitry Andric m_clang_ast_context->GetBasicType(eBasicTypeVoid); 19820b57cec5SDimitry Andric CompilerType void_ptr_clang_type = void_clang_type.GetPointerType(); 19830b57cec5SDimitry Andric 1984480093f4SDimitry Andric CompilerType method_type = m_clang_ast_context->CreateFunctionType( 1985480093f4SDimitry Andric void_clang_type, &void_ptr_clang_type, 1, false, 0); 19860b57cec5SDimitry Andric 19870b57cec5SDimitry Andric const bool is_virtual = false; 19880b57cec5SDimitry Andric const bool is_static = false; 19890b57cec5SDimitry Andric const bool is_inline = false; 19900b57cec5SDimitry Andric const bool is_explicit = false; 19910b57cec5SDimitry Andric const bool is_attr_used = true; 19920b57cec5SDimitry Andric const bool is_artificial = false; 19930b57cec5SDimitry Andric 1994480093f4SDimitry Andric CXXMethodDecl *method_decl = m_clang_ast_context->AddMethodToCXXRecordType( 19950b57cec5SDimitry Andric copied_clang_type.GetOpaqueQualType(), "$__lldb_expr", nullptr, 1996480093f4SDimitry Andric method_type, lldb::eAccessPublic, is_virtual, is_static, is_inline, 1997480093f4SDimitry Andric is_explicit, is_attr_used, is_artificial); 19980b57cec5SDimitry Andric 1999480093f4SDimitry Andric LLDB_LOG(log, 20009dba64beSDimitry Andric " CEDM::AddThisType Added function $__lldb_expr " 2001480093f4SDimitry Andric "(description {0}) for this type\n{1}", 2002480093f4SDimitry Andric ClangUtil::ToString(copied_clang_type), 2003480093f4SDimitry Andric ClangUtil::DumpDecl(method_decl)); 20040b57cec5SDimitry Andric } 20050b57cec5SDimitry Andric 20060b57cec5SDimitry Andric if (!copied_clang_type.IsValid()) 20070b57cec5SDimitry Andric return; 20080b57cec5SDimitry Andric 20090b57cec5SDimitry Andric TypeSourceInfo *type_source_info = m_ast_context->getTrivialTypeSourceInfo( 20100b57cec5SDimitry Andric QualType::getFromOpaquePtr(copied_clang_type.GetOpaqueQualType())); 20110b57cec5SDimitry Andric 20120b57cec5SDimitry Andric if (!type_source_info) 20130b57cec5SDimitry Andric return; 20140b57cec5SDimitry Andric 20150b57cec5SDimitry Andric // Construct a typedef type because if "*this" is a templated type we can't 20160b57cec5SDimitry Andric // just return ClassTemplateSpecializationDecls in response to name queries. 20170b57cec5SDimitry Andric // Using a typedef makes this much more robust. 20180b57cec5SDimitry Andric 20190b57cec5SDimitry Andric TypedefDecl *typedef_decl = TypedefDecl::Create( 20200b57cec5SDimitry Andric *m_ast_context, m_ast_context->getTranslationUnitDecl(), SourceLocation(), 20210b57cec5SDimitry Andric SourceLocation(), context.m_decl_name.getAsIdentifierInfo(), 20220b57cec5SDimitry Andric type_source_info); 20230b57cec5SDimitry Andric 20240b57cec5SDimitry Andric if (!typedef_decl) 20250b57cec5SDimitry Andric return; 20260b57cec5SDimitry Andric 20270b57cec5SDimitry Andric context.AddNamedDecl(typedef_decl); 20280b57cec5SDimitry Andric } 20290b57cec5SDimitry Andric 20300b57cec5SDimitry Andric void ClangExpressionDeclMap::AddOneType(NameSearchContext &context, 20315ffd83dbSDimitry Andric const TypeFromUser &ut) { 20320b57cec5SDimitry Andric CompilerType copied_clang_type = GuardedCopyType(ut); 20330b57cec5SDimitry Andric 20340b57cec5SDimitry Andric if (!copied_clang_type) { 203581ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions); 20360b57cec5SDimitry Andric 20375ffd83dbSDimitry Andric LLDB_LOG(log, 20385ffd83dbSDimitry Andric "ClangExpressionDeclMap::AddOneType - Couldn't import the type"); 20390b57cec5SDimitry Andric 20400b57cec5SDimitry Andric return; 20410b57cec5SDimitry Andric } 20420b57cec5SDimitry Andric 20430b57cec5SDimitry Andric context.AddTypeDecl(copied_clang_type); 20440b57cec5SDimitry Andric } 2045