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.
GetCapturedThisValueObject(StackFrame * frame)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
ClangExpressionDeclMap(bool keep_result_in_memory,Materializer::PersistentVariableDelegate * result_delegate,const lldb::TargetSP & target,const std::shared_ptr<ClangASTImporter> & importer,ValueObject * ctx_obj)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
~ClangExpressionDeclMap()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
WillParse(ExecutionContext & exe_ctx,Materializer * materializer)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
InstallCodeGenerator(clang::ASTConsumer * code_gen)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
InstallDiagnosticManager(DiagnosticManager & diag_manager)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
DidParse()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
GetTargetInfo()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
DeportType(TypeSystemClang & target,TypeSystemClang & source,TypeFromParser parser_type)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
AddPersistentVariable(const NamedDecl * decl,ConstString name,TypeFromParser parser_type,bool is_result,bool is_lvalue)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(
231e8d8bef9SDimitry Andric msg, DiagnosticSeverity::eDiagnosticSeverityError,
232e8d8bef9SDimitry Andric DiagnosticOrigin::eDiagnosticOriginLLDB);
233e8d8bef9SDimitry Andric return false;
234e8d8bef9SDimitry Andric }
235e8d8bef9SDimitry Andric
2360b57cec5SDimitry Andric if (m_parser_vars->m_materializer && is_result) {
2370b57cec5SDimitry Andric Status err;
2380b57cec5SDimitry Andric
2390b57cec5SDimitry Andric ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
2400b57cec5SDimitry Andric Target *target = exe_ctx.GetTargetPtr();
2410b57cec5SDimitry Andric if (target == nullptr)
2420b57cec5SDimitry Andric return false;
2430b57cec5SDimitry Andric
244bdd1243dSDimitry Andric auto clang_ast_context = GetScratchContext(*target);
245480093f4SDimitry Andric if (!clang_ast_context)
246480093f4SDimitry Andric return false;
247480093f4SDimitry Andric
248480093f4SDimitry Andric TypeFromUser user_type = DeportType(*clang_ast_context, *ast, parser_type);
2490b57cec5SDimitry Andric
2500b57cec5SDimitry Andric uint32_t offset = m_parser_vars->m_materializer->AddResultVariable(
2510b57cec5SDimitry Andric user_type, is_lvalue, m_keep_result_in_memory, m_result_delegate, err);
2520b57cec5SDimitry Andric
2530b57cec5SDimitry Andric ClangExpressionVariable *var = new ClangExpressionVariable(
2540b57cec5SDimitry Andric exe_ctx.GetBestExecutionContextScope(), name, user_type,
2550b57cec5SDimitry Andric m_parser_vars->m_target_info.byte_order,
2560b57cec5SDimitry Andric m_parser_vars->m_target_info.address_byte_size);
2570b57cec5SDimitry Andric
2580b57cec5SDimitry Andric m_found_entities.AddNewlyConstructedVariable(var);
2590b57cec5SDimitry Andric
2600b57cec5SDimitry Andric var->EnableParserVars(GetParserID());
2610b57cec5SDimitry Andric
2620b57cec5SDimitry Andric ClangExpressionVariable::ParserVars *parser_vars =
2630b57cec5SDimitry Andric var->GetParserVars(GetParserID());
2640b57cec5SDimitry Andric
2650b57cec5SDimitry Andric parser_vars->m_named_decl = decl;
2660b57cec5SDimitry Andric
2670b57cec5SDimitry Andric var->EnableJITVars(GetParserID());
2680b57cec5SDimitry Andric
2690b57cec5SDimitry Andric ClangExpressionVariable::JITVars *jit_vars = var->GetJITVars(GetParserID());
2700b57cec5SDimitry Andric
2710b57cec5SDimitry Andric jit_vars->m_offset = offset;
2720b57cec5SDimitry Andric
2730b57cec5SDimitry Andric return true;
2740b57cec5SDimitry Andric }
2750b57cec5SDimitry Andric
27681ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions);
2770b57cec5SDimitry Andric ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
2780b57cec5SDimitry Andric Target *target = exe_ctx.GetTargetPtr();
2790b57cec5SDimitry Andric if (target == nullptr)
2800b57cec5SDimitry Andric return false;
2810b57cec5SDimitry Andric
282bdd1243dSDimitry Andric auto context = GetScratchContext(*target);
283480093f4SDimitry Andric if (!context)
284480093f4SDimitry Andric return false;
2850b57cec5SDimitry Andric
2860b57cec5SDimitry Andric TypeFromUser user_type = DeportType(*context, *ast, parser_type);
2870b57cec5SDimitry Andric
2880b57cec5SDimitry Andric if (!user_type.GetOpaqueQualType()) {
2895ffd83dbSDimitry Andric LLDB_LOG(log, "Persistent variable's type wasn't copied successfully");
2900b57cec5SDimitry Andric return false;
2910b57cec5SDimitry Andric }
2920b57cec5SDimitry Andric
2930b57cec5SDimitry Andric if (!m_parser_vars->m_target_info.IsValid())
2940b57cec5SDimitry Andric return false;
2950b57cec5SDimitry Andric
296480093f4SDimitry Andric if (!m_parser_vars->m_persistent_vars)
297480093f4SDimitry Andric return false;
298480093f4SDimitry Andric
2990b57cec5SDimitry Andric ClangExpressionVariable *var = llvm::cast<ClangExpressionVariable>(
3000b57cec5SDimitry Andric m_parser_vars->m_persistent_vars
3010b57cec5SDimitry Andric ->CreatePersistentVariable(
3020b57cec5SDimitry Andric exe_ctx.GetBestExecutionContextScope(), name, user_type,
3030b57cec5SDimitry Andric m_parser_vars->m_target_info.byte_order,
3040b57cec5SDimitry Andric m_parser_vars->m_target_info.address_byte_size)
3050b57cec5SDimitry Andric .get());
3060b57cec5SDimitry Andric
3070b57cec5SDimitry Andric if (!var)
3080b57cec5SDimitry Andric return false;
3090b57cec5SDimitry Andric
3100b57cec5SDimitry Andric var->m_frozen_sp->SetHasCompleteType();
3110b57cec5SDimitry Andric
3120b57cec5SDimitry Andric if (is_result)
3130b57cec5SDimitry Andric var->m_flags |= ClangExpressionVariable::EVNeedsFreezeDry;
3140b57cec5SDimitry Andric else
3150b57cec5SDimitry Andric var->m_flags |=
3160b57cec5SDimitry Andric ClangExpressionVariable::EVKeepInTarget; // explicitly-declared
3170b57cec5SDimitry Andric // persistent variables should
3180b57cec5SDimitry Andric // persist
3190b57cec5SDimitry Andric
3200b57cec5SDimitry Andric if (is_lvalue) {
3210b57cec5SDimitry Andric var->m_flags |= ClangExpressionVariable::EVIsProgramReference;
3220b57cec5SDimitry Andric } else {
3230b57cec5SDimitry Andric var->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated;
3240b57cec5SDimitry Andric var->m_flags |= ClangExpressionVariable::EVNeedsAllocation;
3250b57cec5SDimitry Andric }
3260b57cec5SDimitry Andric
3270b57cec5SDimitry Andric if (m_keep_result_in_memory) {
3280b57cec5SDimitry Andric var->m_flags |= ClangExpressionVariable::EVKeepInTarget;
3290b57cec5SDimitry Andric }
3300b57cec5SDimitry Andric
3315ffd83dbSDimitry Andric LLDB_LOG(log, "Created persistent variable with flags {0:x}", var->m_flags);
3320b57cec5SDimitry Andric
3330b57cec5SDimitry Andric var->EnableParserVars(GetParserID());
3340b57cec5SDimitry Andric
3350b57cec5SDimitry Andric ClangExpressionVariable::ParserVars *parser_vars =
3360b57cec5SDimitry Andric var->GetParserVars(GetParserID());
3370b57cec5SDimitry Andric
3380b57cec5SDimitry Andric parser_vars->m_named_decl = decl;
3390b57cec5SDimitry Andric
3400b57cec5SDimitry Andric return true;
3410b57cec5SDimitry Andric }
3420b57cec5SDimitry Andric
AddValueToStruct(const NamedDecl * decl,ConstString name,llvm::Value * value,size_t size,lldb::offset_t alignment)3430b57cec5SDimitry Andric bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl,
3440b57cec5SDimitry Andric ConstString name,
3450b57cec5SDimitry Andric llvm::Value *value, size_t size,
3460b57cec5SDimitry Andric lldb::offset_t alignment) {
3470b57cec5SDimitry Andric assert(m_struct_vars.get());
3480b57cec5SDimitry Andric assert(m_parser_vars.get());
3490b57cec5SDimitry Andric
3500b57cec5SDimitry Andric bool is_persistent_variable = false;
3510b57cec5SDimitry Andric
35281ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions);
3530b57cec5SDimitry Andric
3540b57cec5SDimitry Andric m_struct_vars->m_struct_laid_out = false;
3550b57cec5SDimitry Andric
3560b57cec5SDimitry Andric if (ClangExpressionVariable::FindVariableInList(m_struct_members, decl,
3570b57cec5SDimitry Andric GetParserID()))
3580b57cec5SDimitry Andric return true;
3590b57cec5SDimitry Andric
3600b57cec5SDimitry Andric ClangExpressionVariable *var(ClangExpressionVariable::FindVariableInList(
3610b57cec5SDimitry Andric m_found_entities, decl, GetParserID()));
3620b57cec5SDimitry Andric
363480093f4SDimitry Andric if (!var && m_parser_vars->m_persistent_vars) {
3640b57cec5SDimitry Andric var = ClangExpressionVariable::FindVariableInList(
3650b57cec5SDimitry Andric *m_parser_vars->m_persistent_vars, decl, GetParserID());
3660b57cec5SDimitry Andric is_persistent_variable = true;
3670b57cec5SDimitry Andric }
3680b57cec5SDimitry Andric
3690b57cec5SDimitry Andric if (!var)
3700b57cec5SDimitry Andric return false;
3710b57cec5SDimitry Andric
372fe6060f1SDimitry Andric LLDB_LOG(log, "Adding value for (NamedDecl*){0} [{1} - {2}] to the structure",
3735ffd83dbSDimitry Andric decl, name, var->GetName());
3740b57cec5SDimitry Andric
3750b57cec5SDimitry Andric // We know entity->m_parser_vars is valid because we used a parser variable
3760b57cec5SDimitry Andric // to find it
3770b57cec5SDimitry Andric
3780b57cec5SDimitry Andric ClangExpressionVariable::ParserVars *parser_vars =
3790b57cec5SDimitry Andric llvm::cast<ClangExpressionVariable>(var)->GetParserVars(GetParserID());
3800b57cec5SDimitry Andric
3810b57cec5SDimitry Andric parser_vars->m_llvm_value = value;
3820b57cec5SDimitry Andric
3830b57cec5SDimitry Andric if (ClangExpressionVariable::JITVars *jit_vars =
3840b57cec5SDimitry Andric llvm::cast<ClangExpressionVariable>(var)->GetJITVars(GetParserID())) {
3850b57cec5SDimitry Andric // We already laid this out; do not touch
3860b57cec5SDimitry Andric
3875ffd83dbSDimitry Andric LLDB_LOG(log, "Already placed at {0:x}", jit_vars->m_offset);
3880b57cec5SDimitry Andric }
3890b57cec5SDimitry Andric
3900b57cec5SDimitry Andric llvm::cast<ClangExpressionVariable>(var)->EnableJITVars(GetParserID());
3910b57cec5SDimitry Andric
3920b57cec5SDimitry Andric ClangExpressionVariable::JITVars *jit_vars =
3930b57cec5SDimitry Andric llvm::cast<ClangExpressionVariable>(var)->GetJITVars(GetParserID());
3940b57cec5SDimitry Andric
3950b57cec5SDimitry Andric jit_vars->m_alignment = alignment;
3960b57cec5SDimitry Andric jit_vars->m_size = size;
3970b57cec5SDimitry Andric
3980b57cec5SDimitry Andric m_struct_members.AddVariable(var->shared_from_this());
3990b57cec5SDimitry Andric
4000b57cec5SDimitry Andric if (m_parser_vars->m_materializer) {
4010b57cec5SDimitry Andric uint32_t offset = 0;
4020b57cec5SDimitry Andric
4030b57cec5SDimitry Andric Status err;
4040b57cec5SDimitry Andric
4050b57cec5SDimitry Andric if (is_persistent_variable) {
4060b57cec5SDimitry Andric ExpressionVariableSP var_sp(var->shared_from_this());
4070b57cec5SDimitry Andric offset = m_parser_vars->m_materializer->AddPersistentVariable(
4080b57cec5SDimitry Andric var_sp, nullptr, err);
4090b57cec5SDimitry Andric } else {
4100b57cec5SDimitry Andric if (const lldb_private::Symbol *sym = parser_vars->m_lldb_sym)
4110b57cec5SDimitry Andric offset = m_parser_vars->m_materializer->AddSymbol(*sym, err);
4120b57cec5SDimitry Andric else if (const RegisterInfo *reg_info = var->GetRegisterInfo())
4130b57cec5SDimitry Andric offset = m_parser_vars->m_materializer->AddRegister(*reg_info, err);
4140b57cec5SDimitry Andric else if (parser_vars->m_lldb_var)
4150b57cec5SDimitry Andric offset = m_parser_vars->m_materializer->AddVariable(
4160b57cec5SDimitry Andric parser_vars->m_lldb_var, err);
417fcaf7f86SDimitry Andric else if (parser_vars->m_lldb_valobj_provider) {
418fcaf7f86SDimitry Andric offset = m_parser_vars->m_materializer->AddValueObject(
419fcaf7f86SDimitry Andric name, parser_vars->m_lldb_valobj_provider, err);
420fcaf7f86SDimitry Andric }
4210b57cec5SDimitry Andric }
4220b57cec5SDimitry Andric
4230b57cec5SDimitry Andric if (!err.Success())
4240b57cec5SDimitry Andric return false;
4250b57cec5SDimitry Andric
4265ffd83dbSDimitry Andric LLDB_LOG(log, "Placed at {0:x}", offset);
4270b57cec5SDimitry Andric
4280b57cec5SDimitry Andric jit_vars->m_offset =
4290b57cec5SDimitry Andric offset; // TODO DoStructLayout() should not change this.
4300b57cec5SDimitry Andric }
4310b57cec5SDimitry Andric
4320b57cec5SDimitry Andric return true;
4330b57cec5SDimitry Andric }
4340b57cec5SDimitry Andric
DoStructLayout()4350b57cec5SDimitry Andric bool ClangExpressionDeclMap::DoStructLayout() {
4360b57cec5SDimitry Andric assert(m_struct_vars.get());
4370b57cec5SDimitry Andric
4380b57cec5SDimitry Andric if (m_struct_vars->m_struct_laid_out)
4390b57cec5SDimitry Andric return true;
4400b57cec5SDimitry Andric
4410b57cec5SDimitry Andric if (!m_parser_vars->m_materializer)
4420b57cec5SDimitry Andric return false;
4430b57cec5SDimitry Andric
4440b57cec5SDimitry Andric m_struct_vars->m_struct_alignment =
4450b57cec5SDimitry Andric m_parser_vars->m_materializer->GetStructAlignment();
4460b57cec5SDimitry Andric m_struct_vars->m_struct_size =
4470b57cec5SDimitry Andric m_parser_vars->m_materializer->GetStructByteSize();
4480b57cec5SDimitry Andric m_struct_vars->m_struct_laid_out = true;
4490b57cec5SDimitry Andric return true;
4500b57cec5SDimitry Andric }
4510b57cec5SDimitry Andric
GetStructInfo(uint32_t & num_elements,size_t & size,lldb::offset_t & alignment)4520b57cec5SDimitry Andric bool ClangExpressionDeclMap::GetStructInfo(uint32_t &num_elements, size_t &size,
4530b57cec5SDimitry Andric lldb::offset_t &alignment) {
4540b57cec5SDimitry Andric assert(m_struct_vars.get());
4550b57cec5SDimitry Andric
4560b57cec5SDimitry Andric if (!m_struct_vars->m_struct_laid_out)
4570b57cec5SDimitry Andric return false;
4580b57cec5SDimitry Andric
4590b57cec5SDimitry Andric num_elements = m_struct_members.GetSize();
4600b57cec5SDimitry Andric size = m_struct_vars->m_struct_size;
4610b57cec5SDimitry Andric alignment = m_struct_vars->m_struct_alignment;
4620b57cec5SDimitry Andric
4630b57cec5SDimitry Andric return true;
4640b57cec5SDimitry Andric }
4650b57cec5SDimitry Andric
GetStructElement(const NamedDecl * & decl,llvm::Value * & value,lldb::offset_t & offset,ConstString & name,uint32_t index)4660b57cec5SDimitry Andric bool ClangExpressionDeclMap::GetStructElement(const NamedDecl *&decl,
4670b57cec5SDimitry Andric llvm::Value *&value,
4680b57cec5SDimitry Andric lldb::offset_t &offset,
4690b57cec5SDimitry Andric ConstString &name,
4700b57cec5SDimitry Andric uint32_t index) {
4710b57cec5SDimitry Andric assert(m_struct_vars.get());
4720b57cec5SDimitry Andric
4730b57cec5SDimitry Andric if (!m_struct_vars->m_struct_laid_out)
4740b57cec5SDimitry Andric return false;
4750b57cec5SDimitry Andric
4760b57cec5SDimitry Andric if (index >= m_struct_members.GetSize())
4770b57cec5SDimitry Andric return false;
4780b57cec5SDimitry Andric
4790b57cec5SDimitry Andric ExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(index));
4800b57cec5SDimitry Andric
4810b57cec5SDimitry Andric if (!member_sp)
4820b57cec5SDimitry Andric return false;
4830b57cec5SDimitry Andric
4840b57cec5SDimitry Andric ClangExpressionVariable::ParserVars *parser_vars =
4850b57cec5SDimitry Andric llvm::cast<ClangExpressionVariable>(member_sp.get())
4860b57cec5SDimitry Andric ->GetParserVars(GetParserID());
4870b57cec5SDimitry Andric ClangExpressionVariable::JITVars *jit_vars =
4880b57cec5SDimitry Andric llvm::cast<ClangExpressionVariable>(member_sp.get())
4890b57cec5SDimitry Andric ->GetJITVars(GetParserID());
4900b57cec5SDimitry Andric
4910b57cec5SDimitry Andric if (!parser_vars || !jit_vars || !member_sp->GetValueObject())
4920b57cec5SDimitry Andric return false;
4930b57cec5SDimitry Andric
4940b57cec5SDimitry Andric decl = parser_vars->m_named_decl;
4950b57cec5SDimitry Andric value = parser_vars->m_llvm_value;
4960b57cec5SDimitry Andric offset = jit_vars->m_offset;
4970b57cec5SDimitry Andric name = member_sp->GetName();
4980b57cec5SDimitry Andric
4990b57cec5SDimitry Andric return true;
5000b57cec5SDimitry Andric }
5010b57cec5SDimitry Andric
GetFunctionInfo(const NamedDecl * decl,uint64_t & ptr)5020b57cec5SDimitry Andric bool ClangExpressionDeclMap::GetFunctionInfo(const NamedDecl *decl,
5030b57cec5SDimitry Andric uint64_t &ptr) {
5040b57cec5SDimitry Andric ClangExpressionVariable *entity(ClangExpressionVariable::FindVariableInList(
5050b57cec5SDimitry Andric m_found_entities, decl, GetParserID()));
5060b57cec5SDimitry Andric
5070b57cec5SDimitry Andric if (!entity)
5080b57cec5SDimitry Andric return false;
5090b57cec5SDimitry Andric
5100b57cec5SDimitry Andric // We know m_parser_vars is valid since we searched for the variable by its
5110b57cec5SDimitry Andric // NamedDecl
5120b57cec5SDimitry Andric
5130b57cec5SDimitry Andric ClangExpressionVariable::ParserVars *parser_vars =
5140b57cec5SDimitry Andric entity->GetParserVars(GetParserID());
5150b57cec5SDimitry Andric
5160b57cec5SDimitry Andric ptr = parser_vars->m_lldb_value.GetScalar().ULongLong();
5170b57cec5SDimitry Andric
5180b57cec5SDimitry Andric return true;
5190b57cec5SDimitry Andric }
5200b57cec5SDimitry Andric
GetSymbolAddress(Target & target,Process * process,ConstString name,lldb::SymbolType symbol_type,lldb_private::Module * module)5210b57cec5SDimitry Andric addr_t ClangExpressionDeclMap::GetSymbolAddress(Target &target,
5220b57cec5SDimitry Andric Process *process,
5230b57cec5SDimitry Andric ConstString name,
5240b57cec5SDimitry Andric lldb::SymbolType symbol_type,
5250b57cec5SDimitry Andric lldb_private::Module *module) {
5260b57cec5SDimitry Andric SymbolContextList sc_list;
5270b57cec5SDimitry Andric
5280b57cec5SDimitry Andric if (module)
5290b57cec5SDimitry Andric module->FindSymbolsWithNameAndType(name, symbol_type, sc_list);
5300b57cec5SDimitry Andric else
5310b57cec5SDimitry Andric target.GetImages().FindSymbolsWithNameAndType(name, symbol_type, sc_list);
5320b57cec5SDimitry Andric
5330b57cec5SDimitry Andric addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
5340b57cec5SDimitry Andric
53506c3fb27SDimitry Andric for (const SymbolContext &sym_ctx : sc_list) {
53606c3fb27SDimitry Andric if (symbol_load_addr != 0 && symbol_load_addr != LLDB_INVALID_ADDRESS)
53706c3fb27SDimitry Andric break;
5380b57cec5SDimitry Andric
5390b57cec5SDimitry Andric const Address sym_address = sym_ctx.symbol->GetAddress();
5400b57cec5SDimitry Andric
5410b57cec5SDimitry Andric if (!sym_address.IsValid())
5420b57cec5SDimitry Andric continue;
5430b57cec5SDimitry Andric
5440b57cec5SDimitry Andric switch (sym_ctx.symbol->GetType()) {
5450b57cec5SDimitry Andric case eSymbolTypeCode:
5460b57cec5SDimitry Andric case eSymbolTypeTrampoline:
5470b57cec5SDimitry Andric symbol_load_addr = sym_address.GetCallableLoadAddress(&target);
5480b57cec5SDimitry Andric break;
5490b57cec5SDimitry Andric
5500b57cec5SDimitry Andric case eSymbolTypeResolver:
5510b57cec5SDimitry Andric symbol_load_addr = sym_address.GetCallableLoadAddress(&target, true);
5520b57cec5SDimitry Andric break;
5530b57cec5SDimitry Andric
5540b57cec5SDimitry Andric case eSymbolTypeReExported: {
5550b57cec5SDimitry Andric ConstString reexport_name = sym_ctx.symbol->GetReExportedSymbolName();
5560b57cec5SDimitry Andric if (reexport_name) {
5570b57cec5SDimitry Andric ModuleSP reexport_module_sp;
5580b57cec5SDimitry Andric ModuleSpec reexport_module_spec;
5590b57cec5SDimitry Andric reexport_module_spec.GetPlatformFileSpec() =
5600b57cec5SDimitry Andric sym_ctx.symbol->GetReExportedSymbolSharedLibrary();
5610b57cec5SDimitry Andric if (reexport_module_spec.GetPlatformFileSpec()) {
5620b57cec5SDimitry Andric reexport_module_sp =
5630b57cec5SDimitry Andric target.GetImages().FindFirstModule(reexport_module_spec);
5640b57cec5SDimitry Andric if (!reexport_module_sp) {
565bdd1243dSDimitry Andric reexport_module_spec.GetPlatformFileSpec().ClearDirectory();
5660b57cec5SDimitry Andric reexport_module_sp =
5670b57cec5SDimitry Andric target.GetImages().FindFirstModule(reexport_module_spec);
5680b57cec5SDimitry Andric }
5690b57cec5SDimitry Andric }
5700b57cec5SDimitry Andric symbol_load_addr = GetSymbolAddress(
5710b57cec5SDimitry Andric target, process, sym_ctx.symbol->GetReExportedSymbolName(),
5720b57cec5SDimitry Andric symbol_type, reexport_module_sp.get());
5730b57cec5SDimitry Andric }
5740b57cec5SDimitry Andric } break;
5750b57cec5SDimitry Andric
5760b57cec5SDimitry Andric case eSymbolTypeData:
5770b57cec5SDimitry Andric case eSymbolTypeRuntime:
5780b57cec5SDimitry Andric case eSymbolTypeVariable:
5790b57cec5SDimitry Andric case eSymbolTypeLocal:
5800b57cec5SDimitry Andric case eSymbolTypeParam:
5810b57cec5SDimitry Andric case eSymbolTypeInvalid:
5820b57cec5SDimitry Andric case eSymbolTypeAbsolute:
5830b57cec5SDimitry Andric case eSymbolTypeException:
5840b57cec5SDimitry Andric case eSymbolTypeSourceFile:
5850b57cec5SDimitry Andric case eSymbolTypeHeaderFile:
5860b57cec5SDimitry Andric case eSymbolTypeObjectFile:
5870b57cec5SDimitry Andric case eSymbolTypeCommonBlock:
5880b57cec5SDimitry Andric case eSymbolTypeBlock:
5890b57cec5SDimitry Andric case eSymbolTypeVariableType:
5900b57cec5SDimitry Andric case eSymbolTypeLineEntry:
5910b57cec5SDimitry Andric case eSymbolTypeLineHeader:
5920b57cec5SDimitry Andric case eSymbolTypeScopeBegin:
5930b57cec5SDimitry Andric case eSymbolTypeScopeEnd:
5940b57cec5SDimitry Andric case eSymbolTypeAdditional:
5950b57cec5SDimitry Andric case eSymbolTypeCompiler:
5960b57cec5SDimitry Andric case eSymbolTypeInstrumentation:
5970b57cec5SDimitry Andric case eSymbolTypeUndefined:
5980b57cec5SDimitry Andric case eSymbolTypeObjCClass:
5990b57cec5SDimitry Andric case eSymbolTypeObjCMetaClass:
6000b57cec5SDimitry Andric case eSymbolTypeObjCIVar:
6010b57cec5SDimitry Andric symbol_load_addr = sym_address.GetLoadAddress(&target);
6020b57cec5SDimitry Andric break;
6030b57cec5SDimitry Andric }
6040b57cec5SDimitry Andric }
6050b57cec5SDimitry Andric
6060b57cec5SDimitry Andric if (symbol_load_addr == LLDB_INVALID_ADDRESS && process) {
6070b57cec5SDimitry Andric ObjCLanguageRuntime *runtime = ObjCLanguageRuntime::Get(*process);
6080b57cec5SDimitry Andric
6090b57cec5SDimitry Andric if (runtime) {
6100b57cec5SDimitry Andric symbol_load_addr = runtime->LookupRuntimeSymbol(name);
6110b57cec5SDimitry Andric }
6120b57cec5SDimitry Andric }
6130b57cec5SDimitry Andric
6140b57cec5SDimitry Andric return symbol_load_addr;
6150b57cec5SDimitry Andric }
6160b57cec5SDimitry Andric
GetSymbolAddress(ConstString name,lldb::SymbolType symbol_type)6170b57cec5SDimitry Andric addr_t ClangExpressionDeclMap::GetSymbolAddress(ConstString name,
6180b57cec5SDimitry Andric lldb::SymbolType symbol_type) {
6190b57cec5SDimitry Andric assert(m_parser_vars.get());
6200b57cec5SDimitry Andric
6210b57cec5SDimitry Andric if (!m_parser_vars->m_exe_ctx.GetTargetPtr())
6220b57cec5SDimitry Andric return false;
6230b57cec5SDimitry Andric
6240b57cec5SDimitry Andric return GetSymbolAddress(m_parser_vars->m_exe_ctx.GetTargetRef(),
6250b57cec5SDimitry Andric m_parser_vars->m_exe_ctx.GetProcessPtr(), name,
6260b57cec5SDimitry Andric symbol_type);
6270b57cec5SDimitry Andric }
6280b57cec5SDimitry Andric
FindGlobalVariable(Target & target,ModuleSP & module,ConstString name,const CompilerDeclContext & namespace_decl)6290b57cec5SDimitry Andric lldb::VariableSP ClangExpressionDeclMap::FindGlobalVariable(
6300b57cec5SDimitry Andric Target &target, ModuleSP &module, ConstString name,
6315ffd83dbSDimitry Andric const CompilerDeclContext &namespace_decl) {
6320b57cec5SDimitry Andric VariableList vars;
6330b57cec5SDimitry Andric
6340b57cec5SDimitry Andric if (module && namespace_decl)
6350b57cec5SDimitry Andric module->FindGlobalVariables(name, namespace_decl, -1, vars);
6360b57cec5SDimitry Andric else
6370b57cec5SDimitry Andric target.GetImages().FindGlobalVariables(name, -1, vars);
6380b57cec5SDimitry Andric
639480093f4SDimitry Andric if (vars.GetSize() == 0)
6400b57cec5SDimitry Andric return VariableSP();
641480093f4SDimitry Andric return vars.GetVariableAtIndex(0);
6420b57cec5SDimitry Andric }
6430b57cec5SDimitry Andric
GetTypeSystemClang()6445ffd83dbSDimitry Andric TypeSystemClang *ClangExpressionDeclMap::GetTypeSystemClang() {
6450b57cec5SDimitry Andric StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
6460b57cec5SDimitry Andric if (frame == nullptr)
6470b57cec5SDimitry Andric return nullptr;
6480b57cec5SDimitry Andric
6490b57cec5SDimitry Andric SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
6500b57cec5SDimitry Andric lldb::eSymbolContextBlock);
6510b57cec5SDimitry Andric if (sym_ctx.block == nullptr)
6520b57cec5SDimitry Andric return nullptr;
6530b57cec5SDimitry Andric
6540b57cec5SDimitry Andric CompilerDeclContext frame_decl_context = sym_ctx.block->GetDeclContext();
6550b57cec5SDimitry Andric if (!frame_decl_context)
6560b57cec5SDimitry Andric return nullptr;
6570b57cec5SDimitry Andric
6585ffd83dbSDimitry Andric return llvm::dyn_cast_or_null<TypeSystemClang>(
6590b57cec5SDimitry Andric frame_decl_context.GetTypeSystem());
6600b57cec5SDimitry Andric }
6610b57cec5SDimitry Andric
6620b57cec5SDimitry Andric // Interface for ClangASTSource
6630b57cec5SDimitry Andric
FindExternalVisibleDecls(NameSearchContext & context)6640b57cec5SDimitry Andric void ClangExpressionDeclMap::FindExternalVisibleDecls(
6650b57cec5SDimitry Andric NameSearchContext &context) {
6660b57cec5SDimitry Andric assert(m_ast_context);
6670b57cec5SDimitry Andric
6680b57cec5SDimitry Andric const ConstString name(context.m_decl_name.getAsString().c_str());
6690b57cec5SDimitry Andric
67081ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions);
6710b57cec5SDimitry Andric
6720b57cec5SDimitry Andric if (log) {
6730b57cec5SDimitry Andric if (!context.m_decl_context)
6745ffd83dbSDimitry Andric LLDB_LOG(log,
6755ffd83dbSDimitry Andric "ClangExpressionDeclMap::FindExternalVisibleDecls for "
6765ffd83dbSDimitry Andric "'{0}' in a NULL DeclContext",
6775ffd83dbSDimitry Andric name);
6780b57cec5SDimitry Andric else if (const NamedDecl *context_named_decl =
6790b57cec5SDimitry Andric dyn_cast<NamedDecl>(context.m_decl_context))
6805ffd83dbSDimitry Andric LLDB_LOG(log,
6815ffd83dbSDimitry Andric "ClangExpressionDeclMap::FindExternalVisibleDecls for "
6825ffd83dbSDimitry Andric "'{0}' in '{1}'",
6835ffd83dbSDimitry Andric name, context_named_decl->getNameAsString());
6840b57cec5SDimitry Andric else
6855ffd83dbSDimitry Andric LLDB_LOG(log,
6865ffd83dbSDimitry Andric "ClangExpressionDeclMap::FindExternalVisibleDecls for "
6875ffd83dbSDimitry Andric "'{0}' in a '{1}'",
6885ffd83dbSDimitry Andric name, context.m_decl_context->getDeclKindName());
6890b57cec5SDimitry Andric }
6900b57cec5SDimitry Andric
6910b57cec5SDimitry Andric if (const NamespaceDecl *namespace_context =
6920b57cec5SDimitry Andric dyn_cast<NamespaceDecl>(context.m_decl_context)) {
6930b57cec5SDimitry Andric if (namespace_context->getName().str() ==
6940b57cec5SDimitry Andric std::string(g_lldb_local_vars_namespace_cstr)) {
695480093f4SDimitry Andric CompilerDeclContext compiler_decl_ctx =
696480093f4SDimitry Andric m_clang_ast_context->CreateDeclContext(
697480093f4SDimitry Andric const_cast<clang::DeclContext *>(context.m_decl_context));
6985ffd83dbSDimitry Andric FindExternalVisibleDecls(context, lldb::ModuleSP(), compiler_decl_ctx);
6990b57cec5SDimitry Andric return;
7000b57cec5SDimitry Andric }
7010b57cec5SDimitry Andric
7020b57cec5SDimitry Andric ClangASTImporter::NamespaceMapSP namespace_map =
7035ffd83dbSDimitry Andric m_ast_importer_sp->GetNamespaceMap(namespace_context);
7040b57cec5SDimitry Andric
7050b57cec5SDimitry Andric if (!namespace_map)
7060b57cec5SDimitry Andric return;
7070b57cec5SDimitry Andric
7085ffd83dbSDimitry Andric LLDB_LOGV(log, " CEDM::FEVD Inspecting (NamespaceMap*){0:x} ({1} entries)",
7095ffd83dbSDimitry Andric namespace_map.get(), namespace_map->size());
7100b57cec5SDimitry Andric
7115ffd83dbSDimitry Andric for (ClangASTImporter::NamespaceMapItem &n : *namespace_map) {
7125ffd83dbSDimitry Andric LLDB_LOG(log, " CEDM::FEVD Searching namespace {0} in module {1}",
7135ffd83dbSDimitry Andric n.second.GetName(), n.first->GetFileSpec().GetFilename());
7140b57cec5SDimitry Andric
7155ffd83dbSDimitry Andric FindExternalVisibleDecls(context, n.first, n.second);
7160b57cec5SDimitry Andric }
7170b57cec5SDimitry Andric } else if (isa<TranslationUnitDecl>(context.m_decl_context)) {
7180b57cec5SDimitry Andric CompilerDeclContext namespace_decl;
7190b57cec5SDimitry Andric
7205ffd83dbSDimitry Andric LLDB_LOG(log, " CEDM::FEVD Searching the root namespace");
7210b57cec5SDimitry Andric
7225ffd83dbSDimitry Andric FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl);
7230b57cec5SDimitry Andric }
7240b57cec5SDimitry Andric
7250b57cec5SDimitry Andric ClangASTSource::FindExternalVisibleDecls(context);
7260b57cec5SDimitry Andric }
7270b57cec5SDimitry Andric
MaybeRegisterFunctionBody(FunctionDecl * copied_function_decl)728480093f4SDimitry Andric void ClangExpressionDeclMap::MaybeRegisterFunctionBody(
729480093f4SDimitry Andric FunctionDecl *copied_function_decl) {
7300b57cec5SDimitry Andric if (copied_function_decl->getBody() && m_parser_vars->m_code_gen) {
731480093f4SDimitry Andric clang::DeclGroupRef decl_group_ref(copied_function_decl);
7320b57cec5SDimitry Andric m_parser_vars->m_code_gen->HandleTopLevelDecl(decl_group_ref);
7330b57cec5SDimitry Andric }
734480093f4SDimitry Andric }
7350b57cec5SDimitry Andric
GetPersistentDecl(ConstString name)736480093f4SDimitry Andric clang::NamedDecl *ClangExpressionDeclMap::GetPersistentDecl(ConstString name) {
737480093f4SDimitry Andric if (!m_parser_vars)
738480093f4SDimitry Andric return nullptr;
739480093f4SDimitry Andric Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
740480093f4SDimitry Andric if (!target)
741480093f4SDimitry Andric return nullptr;
742480093f4SDimitry Andric
743e8d8bef9SDimitry Andric ScratchTypeSystemClang::GetForTarget(*target);
744480093f4SDimitry Andric
745480093f4SDimitry Andric if (!m_parser_vars->m_persistent_vars)
746480093f4SDimitry Andric return nullptr;
747480093f4SDimitry Andric return m_parser_vars->m_persistent_vars->GetPersistentDecl(name);
748480093f4SDimitry Andric }
749480093f4SDimitry Andric
SearchPersistenDecls(NameSearchContext & context,const ConstString name)750480093f4SDimitry Andric void ClangExpressionDeclMap::SearchPersistenDecls(NameSearchContext &context,
7515ffd83dbSDimitry Andric const ConstString name) {
75281ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions);
7530b57cec5SDimitry Andric
754480093f4SDimitry Andric NamedDecl *persistent_decl = GetPersistentDecl(name);
7550b57cec5SDimitry Andric
7560b57cec5SDimitry Andric if (!persistent_decl)
757480093f4SDimitry Andric return;
7580b57cec5SDimitry Andric
7590b57cec5SDimitry Andric Decl *parser_persistent_decl = CopyDecl(persistent_decl);
7600b57cec5SDimitry Andric
7610b57cec5SDimitry Andric if (!parser_persistent_decl)
762480093f4SDimitry Andric return;
7630b57cec5SDimitry Andric
764480093f4SDimitry Andric NamedDecl *parser_named_decl = dyn_cast<NamedDecl>(parser_persistent_decl);
7650b57cec5SDimitry Andric
7660b57cec5SDimitry Andric if (!parser_named_decl)
767480093f4SDimitry Andric return;
7680b57cec5SDimitry Andric
7690b57cec5SDimitry Andric if (clang::FunctionDecl *parser_function_decl =
7700b57cec5SDimitry Andric llvm::dyn_cast<clang::FunctionDecl>(parser_named_decl)) {
7710b57cec5SDimitry Andric MaybeRegisterFunctionBody(parser_function_decl);
7720b57cec5SDimitry Andric }
7730b57cec5SDimitry Andric
774fe6060f1SDimitry Andric LLDB_LOG(log, " CEDM::FEVD Found persistent decl {0}", name);
7750b57cec5SDimitry Andric
7760b57cec5SDimitry Andric context.AddNamedDecl(parser_named_decl);
7770b57cec5SDimitry Andric }
7780b57cec5SDimitry Andric
LookUpLldbClass(NameSearchContext & context)7795ffd83dbSDimitry Andric void ClangExpressionDeclMap::LookUpLldbClass(NameSearchContext &context) {
78081ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions);
7810b57cec5SDimitry Andric
782480093f4SDimitry Andric StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
783480093f4SDimitry Andric SymbolContext sym_ctx;
784480093f4SDimitry Andric if (frame != nullptr)
785480093f4SDimitry Andric sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
786480093f4SDimitry Andric lldb::eSymbolContextBlock);
787480093f4SDimitry Andric
7880b57cec5SDimitry Andric if (m_ctx_obj) {
7890b57cec5SDimitry Andric Status status;
7900b57cec5SDimitry Andric lldb::ValueObjectSP ctx_obj_ptr = m_ctx_obj->AddressOf(status);
7910b57cec5SDimitry Andric if (!ctx_obj_ptr || status.Fail())
7920b57cec5SDimitry Andric return;
7930b57cec5SDimitry Andric
7945ffd83dbSDimitry Andric AddContextClassType(context, TypeFromUser(m_ctx_obj->GetCompilerType()));
7950b57cec5SDimitry Andric return;
7960b57cec5SDimitry Andric }
7970b57cec5SDimitry Andric
7980b57cec5SDimitry Andric // Clang is looking for the type of "this"
7990b57cec5SDimitry Andric
8000b57cec5SDimitry Andric if (frame == nullptr)
8010b57cec5SDimitry Andric return;
8020b57cec5SDimitry Andric
8030b57cec5SDimitry Andric // Find the block that defines the function represented by "sym_ctx"
8040b57cec5SDimitry Andric Block *function_block = sym_ctx.GetFunctionBlock();
8050b57cec5SDimitry Andric
8060b57cec5SDimitry Andric if (!function_block)
8070b57cec5SDimitry Andric return;
8080b57cec5SDimitry Andric
8090b57cec5SDimitry Andric CompilerDeclContext function_decl_ctx = function_block->GetDeclContext();
8100b57cec5SDimitry Andric
8110b57cec5SDimitry Andric if (!function_decl_ctx)
8120b57cec5SDimitry Andric return;
8130b57cec5SDimitry Andric
8140b57cec5SDimitry Andric clang::CXXMethodDecl *method_decl =
8155ffd83dbSDimitry Andric TypeSystemClang::DeclContextGetAsCXXMethodDecl(function_decl_ctx);
8160b57cec5SDimitry Andric
8170b57cec5SDimitry Andric if (method_decl) {
818fcaf7f86SDimitry Andric if (auto capturedThis = GetCapturedThisValueObject(frame)) {
819fcaf7f86SDimitry Andric // We're inside a lambda and we captured a 'this'.
820fcaf7f86SDimitry Andric // Import the outer class's AST instead of the
821fcaf7f86SDimitry Andric // (unnamed) lambda structure AST so unqualified
822fcaf7f86SDimitry Andric // member lookups are understood by the Clang parser.
823fcaf7f86SDimitry Andric //
824fcaf7f86SDimitry Andric // If we're in a lambda which didn't capture 'this',
825fcaf7f86SDimitry Andric // $__lldb_class will correspond to the lambda closure
826fcaf7f86SDimitry Andric // AST and references to captures will resolve like
827fcaf7f86SDimitry Andric // regular member varaiable accesses do.
828fcaf7f86SDimitry Andric TypeFromUser pointee_type =
829fcaf7f86SDimitry Andric capturedThis->GetCompilerType().GetPointeeType();
830fcaf7f86SDimitry Andric
831fcaf7f86SDimitry Andric LLDB_LOG(log,
832fcaf7f86SDimitry Andric " CEDM::FEVD Adding captured type ({0} for"
833fcaf7f86SDimitry Andric " $__lldb_class: {1}",
834fcaf7f86SDimitry Andric capturedThis->GetTypeName(), capturedThis->GetName());
835fcaf7f86SDimitry Andric
836fcaf7f86SDimitry Andric AddContextClassType(context, pointee_type);
837fcaf7f86SDimitry Andric return;
838fcaf7f86SDimitry Andric }
839fcaf7f86SDimitry Andric
8400b57cec5SDimitry Andric clang::CXXRecordDecl *class_decl = method_decl->getParent();
8410b57cec5SDimitry Andric
8420b57cec5SDimitry Andric QualType class_qual_type(class_decl->getTypeForDecl(), 0);
8430b57cec5SDimitry Andric
844bdd1243dSDimitry Andric TypeFromUser class_user_type(
845bdd1243dSDimitry Andric class_qual_type.getAsOpaquePtr(),
846bdd1243dSDimitry Andric function_decl_ctx.GetTypeSystem()->weak_from_this());
8470b57cec5SDimitry Andric
84881ad6265SDimitry Andric LLDB_LOG(log, " CEDM::FEVD Adding type for $__lldb_class: {0}",
8495ffd83dbSDimitry Andric class_qual_type.getAsString());
8500b57cec5SDimitry Andric
8515ffd83dbSDimitry Andric AddContextClassType(context, class_user_type);
852480093f4SDimitry Andric return;
853480093f4SDimitry Andric }
854480093f4SDimitry Andric
8550b57cec5SDimitry Andric // This branch will get hit if we are executing code in the context of
8560b57cec5SDimitry Andric // a function that claims to have an object pointer (through
8570b57cec5SDimitry Andric // DW_AT_object_pointer?) but is not formally a method of the class.
8580b57cec5SDimitry Andric // In that case, just look up the "this" variable in the current scope
8590b57cec5SDimitry Andric // and use its type.
8600b57cec5SDimitry Andric // FIXME: This code is formally correct, but clang doesn't currently
8610b57cec5SDimitry Andric // emit DW_AT_object_pointer
8620b57cec5SDimitry Andric // for C++ so it hasn't actually been tested.
8630b57cec5SDimitry Andric
864bdd1243dSDimitry Andric VariableList *vars = frame->GetVariableList(false, nullptr);
8650b57cec5SDimitry Andric
8660b57cec5SDimitry Andric lldb::VariableSP this_var = vars->FindVariable(ConstString("this"));
8670b57cec5SDimitry Andric
8680b57cec5SDimitry Andric if (this_var && this_var->IsInScope(frame) &&
8690b57cec5SDimitry Andric this_var->LocationIsValidForFrame(frame)) {
8700b57cec5SDimitry Andric Type *this_type = this_var->GetType();
8710b57cec5SDimitry Andric
8720b57cec5SDimitry Andric if (!this_type)
8730b57cec5SDimitry Andric return;
8740b57cec5SDimitry Andric
8750b57cec5SDimitry Andric TypeFromUser pointee_type =
8760b57cec5SDimitry Andric this_type->GetForwardCompilerType().GetPointeeType();
8770b57cec5SDimitry Andric
87881ad6265SDimitry Andric LLDB_LOG(log, " FEVD Adding type for $__lldb_class: {0}",
879480093f4SDimitry Andric ClangUtil::GetQualType(pointee_type).getAsString());
8800b57cec5SDimitry Andric
8815ffd83dbSDimitry Andric AddContextClassType(context, pointee_type);
8820b57cec5SDimitry Andric }
8830b57cec5SDimitry Andric }
8840b57cec5SDimitry Andric
LookUpLldbObjCClass(NameSearchContext & context)8855ffd83dbSDimitry Andric void ClangExpressionDeclMap::LookUpLldbObjCClass(NameSearchContext &context) {
88681ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions);
8870b57cec5SDimitry Andric
888480093f4SDimitry Andric StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
889480093f4SDimitry Andric
8900b57cec5SDimitry Andric if (m_ctx_obj) {
8910b57cec5SDimitry Andric Status status;
8920b57cec5SDimitry Andric lldb::ValueObjectSP ctx_obj_ptr = m_ctx_obj->AddressOf(status);
8930b57cec5SDimitry Andric if (!ctx_obj_ptr || status.Fail())
8940b57cec5SDimitry Andric return;
8950b57cec5SDimitry Andric
8965ffd83dbSDimitry Andric AddOneType(context, TypeFromUser(m_ctx_obj->GetCompilerType()));
8970b57cec5SDimitry Andric return;
8980b57cec5SDimitry Andric }
8990b57cec5SDimitry Andric
9000b57cec5SDimitry Andric // Clang is looking for the type of "*self"
9010b57cec5SDimitry Andric
9020b57cec5SDimitry Andric if (!frame)
9030b57cec5SDimitry Andric return;
9040b57cec5SDimitry Andric
905480093f4SDimitry Andric SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
906480093f4SDimitry Andric lldb::eSymbolContextBlock);
9070b57cec5SDimitry Andric
9080b57cec5SDimitry Andric // Find the block that defines the function represented by "sym_ctx"
9090b57cec5SDimitry Andric Block *function_block = sym_ctx.GetFunctionBlock();
9100b57cec5SDimitry Andric
9110b57cec5SDimitry Andric if (!function_block)
9120b57cec5SDimitry Andric return;
9130b57cec5SDimitry Andric
9140b57cec5SDimitry Andric CompilerDeclContext function_decl_ctx = function_block->GetDeclContext();
9150b57cec5SDimitry Andric
9160b57cec5SDimitry Andric if (!function_decl_ctx)
9170b57cec5SDimitry Andric return;
9180b57cec5SDimitry Andric
9190b57cec5SDimitry Andric clang::ObjCMethodDecl *method_decl =
9205ffd83dbSDimitry Andric TypeSystemClang::DeclContextGetAsObjCMethodDecl(function_decl_ctx);
9210b57cec5SDimitry Andric
9220b57cec5SDimitry Andric if (method_decl) {
9230b57cec5SDimitry Andric ObjCInterfaceDecl *self_interface = method_decl->getClassInterface();
9240b57cec5SDimitry Andric
9250b57cec5SDimitry Andric if (!self_interface)
9260b57cec5SDimitry Andric return;
9270b57cec5SDimitry Andric
9280b57cec5SDimitry Andric const clang::Type *interface_type = self_interface->getTypeForDecl();
9290b57cec5SDimitry Andric
9300b57cec5SDimitry Andric if (!interface_type)
9310b57cec5SDimitry Andric return; // This is unlikely, but we have seen crashes where this
9320b57cec5SDimitry Andric // occurred
9330b57cec5SDimitry Andric
934bdd1243dSDimitry Andric TypeFromUser class_user_type(
935bdd1243dSDimitry Andric QualType(interface_type, 0).getAsOpaquePtr(),
936bdd1243dSDimitry Andric function_decl_ctx.GetTypeSystem()->weak_from_this());
9370b57cec5SDimitry Andric
938480093f4SDimitry Andric LLDB_LOG(log, " FEVD[{0}] Adding type for $__lldb_objc_class: {1}",
9395ffd83dbSDimitry Andric ClangUtil::ToString(interface_type));
9400b57cec5SDimitry Andric
9415ffd83dbSDimitry Andric AddOneType(context, class_user_type);
9420b57cec5SDimitry Andric return;
943480093f4SDimitry Andric }
9440b57cec5SDimitry Andric // This branch will get hit if we are executing code in the context of
9450b57cec5SDimitry Andric // a function that claims to have an object pointer (through
9460b57cec5SDimitry Andric // DW_AT_object_pointer?) but is not formally a method of the class.
9470b57cec5SDimitry Andric // In that case, just look up the "self" variable in the current scope
9480b57cec5SDimitry Andric // and use its type.
9490b57cec5SDimitry Andric
950bdd1243dSDimitry Andric VariableList *vars = frame->GetVariableList(false, nullptr);
9510b57cec5SDimitry Andric
9520b57cec5SDimitry Andric lldb::VariableSP self_var = vars->FindVariable(ConstString("self"));
9530b57cec5SDimitry Andric
954480093f4SDimitry Andric if (!self_var)
955480093f4SDimitry Andric return;
956480093f4SDimitry Andric if (!self_var->IsInScope(frame))
957480093f4SDimitry Andric return;
958480093f4SDimitry Andric if (!self_var->LocationIsValidForFrame(frame))
959480093f4SDimitry Andric return;
960480093f4SDimitry Andric
9610b57cec5SDimitry Andric Type *self_type = self_var->GetType();
9620b57cec5SDimitry Andric
9630b57cec5SDimitry Andric if (!self_type)
9640b57cec5SDimitry Andric return;
9650b57cec5SDimitry Andric
9660b57cec5SDimitry Andric CompilerType self_clang_type = self_type->GetFullCompilerType();
9670b57cec5SDimitry Andric
9685ffd83dbSDimitry Andric if (TypeSystemClang::IsObjCClassType(self_clang_type)) {
9690b57cec5SDimitry Andric return;
970480093f4SDimitry Andric }
9715ffd83dbSDimitry Andric if (!TypeSystemClang::IsObjCObjectPointerType(self_clang_type))
972480093f4SDimitry Andric return;
9730b57cec5SDimitry Andric self_clang_type = self_clang_type.GetPointeeType();
9740b57cec5SDimitry Andric
9750b57cec5SDimitry Andric if (!self_clang_type)
9760b57cec5SDimitry Andric return;
9770b57cec5SDimitry Andric
978480093f4SDimitry Andric LLDB_LOG(log, " FEVD[{0}] Adding type for $__lldb_objc_class: {1}",
9795ffd83dbSDimitry Andric ClangUtil::ToString(self_type->GetFullCompilerType()));
9800b57cec5SDimitry Andric
9810b57cec5SDimitry Andric TypeFromUser class_user_type(self_clang_type);
9820b57cec5SDimitry Andric
9835ffd83dbSDimitry Andric AddOneType(context, class_user_type);
984480093f4SDimitry Andric }
985480093f4SDimitry Andric
LookupLocalVarNamespace(SymbolContext & sym_ctx,NameSearchContext & name_context)986480093f4SDimitry Andric void ClangExpressionDeclMap::LookupLocalVarNamespace(
987480093f4SDimitry Andric SymbolContext &sym_ctx, NameSearchContext &name_context) {
988480093f4SDimitry Andric if (sym_ctx.block == nullptr)
9890b57cec5SDimitry Andric return;
9900b57cec5SDimitry Andric
991480093f4SDimitry Andric CompilerDeclContext frame_decl_context = sym_ctx.block->GetDeclContext();
992480093f4SDimitry Andric if (!frame_decl_context)
9930b57cec5SDimitry Andric return;
9940b57cec5SDimitry Andric
9955ffd83dbSDimitry Andric TypeSystemClang *frame_ast = llvm::dyn_cast_or_null<TypeSystemClang>(
9960b57cec5SDimitry Andric frame_decl_context.GetTypeSystem());
997480093f4SDimitry Andric if (!frame_ast)
998480093f4SDimitry Andric return;
9990b57cec5SDimitry Andric
10000b57cec5SDimitry Andric clang::NamespaceDecl *namespace_decl =
1001480093f4SDimitry Andric m_clang_ast_context->GetUniqueNamespaceDeclaration(
10025ffd83dbSDimitry Andric g_lldb_local_vars_namespace_cstr, nullptr, OptionalClangModuleID());
1003480093f4SDimitry Andric if (!namespace_decl)
1004480093f4SDimitry Andric return;
1005480093f4SDimitry Andric
1006480093f4SDimitry Andric name_context.AddNamedDecl(namespace_decl);
1007480093f4SDimitry Andric clang::DeclContext *ctxt = clang::Decl::castToDeclContext(namespace_decl);
1008480093f4SDimitry Andric ctxt->setHasExternalVisibleStorage(true);
10095ffd83dbSDimitry Andric name_context.m_found_local_vars_nsp = true;
10100b57cec5SDimitry Andric }
10110b57cec5SDimitry Andric
LookupInModulesDeclVendor(NameSearchContext & context,ConstString name)1012480093f4SDimitry Andric void ClangExpressionDeclMap::LookupInModulesDeclVendor(
10135ffd83dbSDimitry Andric NameSearchContext &context, ConstString name) {
101481ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions);
1015480093f4SDimitry Andric
1016480093f4SDimitry Andric if (!m_target)
1017480093f4SDimitry Andric return;
1018480093f4SDimitry Andric
1019fe6060f1SDimitry Andric std::shared_ptr<ClangModulesDeclVendor> modules_decl_vendor =
1020fe6060f1SDimitry Andric GetClangModulesDeclVendor();
1021480093f4SDimitry Andric if (!modules_decl_vendor)
1022480093f4SDimitry Andric return;
1023480093f4SDimitry Andric
1024480093f4SDimitry Andric bool append = false;
1025480093f4SDimitry Andric uint32_t max_matches = 1;
1026480093f4SDimitry Andric std::vector<clang::NamedDecl *> decls;
1027480093f4SDimitry Andric
1028480093f4SDimitry Andric if (!modules_decl_vendor->FindDecls(name, append, max_matches, decls))
1029480093f4SDimitry Andric return;
1030480093f4SDimitry Andric
1031480093f4SDimitry Andric assert(!decls.empty() && "FindDecls returned true but no decls?");
1032480093f4SDimitry Andric clang::NamedDecl *const decl_from_modules = decls[0];
1033480093f4SDimitry Andric
1034480093f4SDimitry Andric LLDB_LOG(log,
10355ffd83dbSDimitry Andric " CAS::FEVD Matching decl found for "
103681ad6265SDimitry Andric "\"{0}\" in the modules",
10375ffd83dbSDimitry Andric name);
1038480093f4SDimitry Andric
1039480093f4SDimitry Andric clang::Decl *copied_decl = CopyDecl(decl_from_modules);
1040480093f4SDimitry Andric if (!copied_decl) {
10415ffd83dbSDimitry Andric LLDB_LOG(log, " CAS::FEVD - Couldn't export a "
10425ffd83dbSDimitry Andric "declaration from the modules");
10430b57cec5SDimitry Andric return;
10440b57cec5SDimitry Andric }
10450b57cec5SDimitry Andric
1046480093f4SDimitry Andric if (auto copied_function = dyn_cast<clang::FunctionDecl>(copied_decl)) {
1047480093f4SDimitry Andric MaybeRegisterFunctionBody(copied_function);
10480b57cec5SDimitry Andric
1049480093f4SDimitry Andric context.AddNamedDecl(copied_function);
10500b57cec5SDimitry Andric
10515ffd83dbSDimitry Andric context.m_found_function_with_type_info = true;
10525ffd83dbSDimitry Andric context.m_found_function = true;
1053480093f4SDimitry Andric } else if (auto copied_var = dyn_cast<clang::VarDecl>(copied_decl)) {
1054480093f4SDimitry Andric context.AddNamedDecl(copied_var);
10555ffd83dbSDimitry Andric context.m_found_variable = true;
10560b57cec5SDimitry Andric }
10570b57cec5SDimitry Andric }
10580b57cec5SDimitry Andric
LookupLocalVariable(NameSearchContext & context,ConstString name,SymbolContext & sym_ctx,const CompilerDeclContext & namespace_decl)1059480093f4SDimitry Andric bool ClangExpressionDeclMap::LookupLocalVariable(
10605ffd83dbSDimitry Andric NameSearchContext &context, ConstString name, SymbolContext &sym_ctx,
10615ffd83dbSDimitry Andric const CompilerDeclContext &namespace_decl) {
1062480093f4SDimitry Andric if (sym_ctx.block == nullptr)
1063480093f4SDimitry Andric return false;
10640b57cec5SDimitry Andric
1065480093f4SDimitry Andric CompilerDeclContext decl_context = sym_ctx.block->GetDeclContext();
1066480093f4SDimitry Andric if (!decl_context)
1067480093f4SDimitry Andric return false;
1068480093f4SDimitry Andric
10690b57cec5SDimitry Andric // Make sure that the variables are parsed so that we have the
10700b57cec5SDimitry Andric // declarations.
1071480093f4SDimitry Andric StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
10720b57cec5SDimitry Andric VariableListSP vars = frame->GetInScopeVariableList(true);
10730b57cec5SDimitry Andric for (size_t i = 0; i < vars->GetSize(); i++)
10740b57cec5SDimitry Andric vars->GetVariableAtIndex(i)->GetDecl();
10750b57cec5SDimitry Andric
10760b57cec5SDimitry Andric // Search for declarations matching the name. Do not include imported
10770b57cec5SDimitry Andric // decls in the search if we are looking for decls in the artificial
10780b57cec5SDimitry Andric // namespace $__lldb_local_vars.
10790b57cec5SDimitry Andric std::vector<CompilerDecl> found_decls =
1080480093f4SDimitry Andric decl_context.FindDeclByName(name, namespace_decl.IsValid());
10810b57cec5SDimitry Andric
1082480093f4SDimitry Andric VariableSP var;
10830b57cec5SDimitry Andric bool variable_found = false;
10840b57cec5SDimitry Andric for (CompilerDecl decl : found_decls) {
10850b57cec5SDimitry Andric for (size_t vi = 0, ve = vars->GetSize(); vi != ve; ++vi) {
10860b57cec5SDimitry Andric VariableSP candidate_var = vars->GetVariableAtIndex(vi);
10870b57cec5SDimitry Andric if (candidate_var->GetDecl() == decl) {
10880b57cec5SDimitry Andric var = candidate_var;
10890b57cec5SDimitry Andric break;
10900b57cec5SDimitry Andric }
10910b57cec5SDimitry Andric }
10920b57cec5SDimitry Andric
10930b57cec5SDimitry Andric if (var && !variable_found) {
10940b57cec5SDimitry Andric variable_found = true;
1095480093f4SDimitry Andric ValueObjectSP valobj = ValueObjectVariable::Create(frame, var);
10965ffd83dbSDimitry Andric AddOneVariable(context, var, valobj);
10975ffd83dbSDimitry Andric context.m_found_variable = true;
10980b57cec5SDimitry Andric }
10990b57cec5SDimitry Andric }
1100fcaf7f86SDimitry Andric
1101fcaf7f86SDimitry Andric // We're in a local_var_lookup but haven't found any local variables
1102fcaf7f86SDimitry Andric // so far. When performing a variable lookup from within the context of
1103fcaf7f86SDimitry Andric // a lambda, we count the lambda captures as local variables. Thus,
1104fcaf7f86SDimitry Andric // see if we captured any variables with the requested 'name'.
1105fcaf7f86SDimitry Andric if (!variable_found) {
1106fcaf7f86SDimitry Andric auto find_capture = [](ConstString varname,
1107fcaf7f86SDimitry Andric StackFrame *frame) -> ValueObjectSP {
1108fcaf7f86SDimitry Andric if (auto lambda = ClangExpressionUtil::GetLambdaValueObject(frame)) {
110906c3fb27SDimitry Andric if (auto capture = lambda->GetChildMemberWithName(varname)) {
1110fcaf7f86SDimitry Andric return capture;
1111fcaf7f86SDimitry Andric }
1112fcaf7f86SDimitry Andric }
1113fcaf7f86SDimitry Andric
1114fcaf7f86SDimitry Andric return nullptr;
1115fcaf7f86SDimitry Andric };
1116fcaf7f86SDimitry Andric
1117fcaf7f86SDimitry Andric if (auto capture = find_capture(name, frame)) {
1118fcaf7f86SDimitry Andric variable_found = true;
1119fcaf7f86SDimitry Andric context.m_found_variable = true;
1120fcaf7f86SDimitry Andric AddOneVariable(context, std::move(capture), std::move(find_capture));
1121fcaf7f86SDimitry Andric }
1122fcaf7f86SDimitry Andric }
1123fcaf7f86SDimitry Andric
1124480093f4SDimitry Andric return variable_found;
11250b57cec5SDimitry Andric }
11260b57cec5SDimitry Andric
1127480093f4SDimitry Andric /// Structure to hold the info needed when comparing function
1128480093f4SDimitry Andric /// declarations.
1129480093f4SDimitry Andric namespace {
1130480093f4SDimitry Andric struct FuncDeclInfo {
1131480093f4SDimitry Andric ConstString m_name;
1132480093f4SDimitry Andric CompilerType m_copied_type;
1133480093f4SDimitry Andric uint32_t m_decl_lvl;
1134480093f4SDimitry Andric SymbolContext m_sym_ctx;
1135480093f4SDimitry Andric };
1136480093f4SDimitry Andric } // namespace
1137480093f4SDimitry Andric
SearchFunctionsInSymbolContexts(const SymbolContextList & sc_list,const CompilerDeclContext & frame_decl_context)1138480093f4SDimitry Andric SymbolContextList ClangExpressionDeclMap::SearchFunctionsInSymbolContexts(
1139480093f4SDimitry Andric const SymbolContextList &sc_list,
1140480093f4SDimitry Andric const CompilerDeclContext &frame_decl_context) {
1141480093f4SDimitry Andric // First, symplify things by looping through the symbol contexts to
1142480093f4SDimitry Andric // remove unwanted functions and separate out the functions we want to
1143480093f4SDimitry Andric // compare and prune into a separate list. Cache the info needed about
1144480093f4SDimitry Andric // the function declarations in a vector for efficiency.
1145480093f4SDimitry Andric SymbolContextList sc_sym_list;
1146480093f4SDimitry Andric std::vector<FuncDeclInfo> decl_infos;
114706c3fb27SDimitry Andric decl_infos.reserve(sc_list.GetSize());
1148480093f4SDimitry Andric clang::DeclContext *frame_decl_ctx =
1149480093f4SDimitry Andric (clang::DeclContext *)frame_decl_context.GetOpaqueDeclContext();
11505ffd83dbSDimitry Andric TypeSystemClang *ast = llvm::dyn_cast_or_null<TypeSystemClang>(
1151480093f4SDimitry Andric frame_decl_context.GetTypeSystem());
1152480093f4SDimitry Andric
115306c3fb27SDimitry Andric for (const SymbolContext &sym_ctx : sc_list) {
1154480093f4SDimitry Andric FuncDeclInfo fdi;
1155480093f4SDimitry Andric
1156480093f4SDimitry Andric // We don't know enough about symbols to compare them, but we should
1157480093f4SDimitry Andric // keep them in the list.
1158480093f4SDimitry Andric Function *function = sym_ctx.function;
1159480093f4SDimitry Andric if (!function) {
1160480093f4SDimitry Andric sc_sym_list.Append(sym_ctx);
1161480093f4SDimitry Andric continue;
1162480093f4SDimitry Andric }
1163480093f4SDimitry Andric // Filter out functions without declaration contexts, as well as
1164480093f4SDimitry Andric // class/instance methods, since they'll be skipped in the code that
1165480093f4SDimitry Andric // follows anyway.
1166480093f4SDimitry Andric CompilerDeclContext func_decl_context = function->GetDeclContext();
116706c3fb27SDimitry Andric if (!func_decl_context || func_decl_context.IsClassMethod())
1168480093f4SDimitry Andric continue;
1169480093f4SDimitry Andric // We can only prune functions for which we can copy the type.
1170480093f4SDimitry Andric CompilerType func_clang_type = function->GetType()->GetFullCompilerType();
1171480093f4SDimitry Andric CompilerType copied_func_type = GuardedCopyType(func_clang_type);
1172480093f4SDimitry Andric if (!copied_func_type) {
1173480093f4SDimitry Andric sc_sym_list.Append(sym_ctx);
1174480093f4SDimitry Andric continue;
1175480093f4SDimitry Andric }
1176480093f4SDimitry Andric
1177480093f4SDimitry Andric fdi.m_sym_ctx = sym_ctx;
1178480093f4SDimitry Andric fdi.m_name = function->GetName();
1179480093f4SDimitry Andric fdi.m_copied_type = copied_func_type;
1180480093f4SDimitry Andric fdi.m_decl_lvl = LLDB_INVALID_DECL_LEVEL;
1181480093f4SDimitry Andric if (fdi.m_copied_type && func_decl_context) {
1182480093f4SDimitry Andric // Call CountDeclLevels to get the number of parent scopes we have
1183480093f4SDimitry Andric // to look through before we find the function declaration. When
1184480093f4SDimitry Andric // comparing functions of the same type, the one with a lower count
1185480093f4SDimitry Andric // will be closer to us in the lookup scope and shadows the other.
1186480093f4SDimitry Andric clang::DeclContext *func_decl_ctx =
1187480093f4SDimitry Andric (clang::DeclContext *)func_decl_context.GetOpaqueDeclContext();
1188480093f4SDimitry Andric fdi.m_decl_lvl = ast->CountDeclLevels(frame_decl_ctx, func_decl_ctx,
1189480093f4SDimitry Andric &fdi.m_name, &fdi.m_copied_type);
1190480093f4SDimitry Andric }
1191480093f4SDimitry Andric decl_infos.emplace_back(fdi);
1192480093f4SDimitry Andric }
1193480093f4SDimitry Andric
1194480093f4SDimitry Andric // Loop through the functions in our cache looking for matching types,
1195480093f4SDimitry Andric // then compare their scope levels to see which is closer.
1196480093f4SDimitry Andric std::multimap<CompilerType, const FuncDeclInfo *> matches;
1197480093f4SDimitry Andric for (const FuncDeclInfo &fdi : decl_infos) {
1198480093f4SDimitry Andric const CompilerType t = fdi.m_copied_type;
1199480093f4SDimitry Andric auto q = matches.find(t);
1200480093f4SDimitry Andric if (q != matches.end()) {
1201480093f4SDimitry Andric if (q->second->m_decl_lvl > fdi.m_decl_lvl)
1202480093f4SDimitry Andric // This function is closer; remove the old set.
1203480093f4SDimitry Andric matches.erase(t);
1204480093f4SDimitry Andric else if (q->second->m_decl_lvl < fdi.m_decl_lvl)
1205480093f4SDimitry Andric // The functions in our set are closer - skip this one.
1206480093f4SDimitry Andric continue;
1207480093f4SDimitry Andric }
1208480093f4SDimitry Andric matches.insert(std::make_pair(t, &fdi));
1209480093f4SDimitry Andric }
1210480093f4SDimitry Andric
1211480093f4SDimitry Andric // Loop through our matches and add their symbol contexts to our list.
1212480093f4SDimitry Andric SymbolContextList sc_func_list;
1213480093f4SDimitry Andric for (const auto &q : matches)
1214480093f4SDimitry Andric sc_func_list.Append(q.second->m_sym_ctx);
1215480093f4SDimitry Andric
1216480093f4SDimitry Andric // Rejoin the lists with the functions in front.
1217480093f4SDimitry Andric sc_func_list.Append(sc_sym_list);
1218480093f4SDimitry Andric return sc_func_list;
1219480093f4SDimitry Andric }
1220480093f4SDimitry Andric
LookupFunction(NameSearchContext & context,lldb::ModuleSP module_sp,ConstString name,const CompilerDeclContext & namespace_decl)12215ffd83dbSDimitry Andric void ClangExpressionDeclMap::LookupFunction(
12225ffd83dbSDimitry Andric NameSearchContext &context, lldb::ModuleSP module_sp, ConstString name,
12235ffd83dbSDimitry Andric const CompilerDeclContext &namespace_decl) {
1224480093f4SDimitry Andric if (!m_parser_vars)
12250b57cec5SDimitry Andric return;
1226480093f4SDimitry Andric
1227480093f4SDimitry Andric Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
12280b57cec5SDimitry Andric
12290b57cec5SDimitry Andric std::vector<clang::NamedDecl *> decls_from_modules;
12300b57cec5SDimitry Andric
12310b57cec5SDimitry Andric if (target) {
1232fe6060f1SDimitry Andric if (std::shared_ptr<ClangModulesDeclVendor> decl_vendor =
1233fe6060f1SDimitry Andric GetClangModulesDeclVendor()) {
12340b57cec5SDimitry Andric decl_vendor->FindDecls(name, false, UINT32_MAX, decls_from_modules);
12350b57cec5SDimitry Andric }
12360b57cec5SDimitry Andric }
12370b57cec5SDimitry Andric
1238480093f4SDimitry Andric SymbolContextList sc_list;
12390b57cec5SDimitry Andric if (namespace_decl && module_sp) {
1240349cc55cSDimitry Andric ModuleFunctionSearchOptions function_options;
1241349cc55cSDimitry Andric function_options.include_inlines = false;
1242349cc55cSDimitry Andric function_options.include_symbols = false;
12430b57cec5SDimitry Andric
12445ffd83dbSDimitry Andric module_sp->FindFunctions(name, namespace_decl, eFunctionNameTypeBase,
1245349cc55cSDimitry Andric function_options, sc_list);
12460b57cec5SDimitry Andric } else if (target && !namespace_decl) {
1247349cc55cSDimitry Andric ModuleFunctionSearchOptions function_options;
1248349cc55cSDimitry Andric function_options.include_inlines = false;
1249349cc55cSDimitry Andric function_options.include_symbols = true;
12500b57cec5SDimitry Andric
12510b57cec5SDimitry Andric // TODO Fix FindFunctions so that it doesn't return
12520b57cec5SDimitry Andric // instance methods for eFunctionNameTypeBase.
12530b57cec5SDimitry Andric
1254480093f4SDimitry Andric target->GetImages().FindFunctions(
1255349cc55cSDimitry Andric name, eFunctionNameTypeFull | eFunctionNameTypeBase, function_options,
1256349cc55cSDimitry Andric sc_list);
12570b57cec5SDimitry Andric }
12580b57cec5SDimitry Andric
12590b57cec5SDimitry Andric // If we found more than one function, see if we can use the frame's decl
12600b57cec5SDimitry Andric // context to remove functions that are shadowed by other functions which
12610b57cec5SDimitry Andric // match in type but are nearer in scope.
12620b57cec5SDimitry Andric //
12630b57cec5SDimitry Andric // AddOneFunction will not add a function whose type has already been
12640b57cec5SDimitry Andric // added, so if there's another function in the list with a matching type,
12650b57cec5SDimitry Andric // check to see if their decl context is a parent of the current frame's or
12660b57cec5SDimitry Andric // was imported via a and using statement, and pick the best match
12670b57cec5SDimitry Andric // according to lookup rules.
12680b57cec5SDimitry Andric if (sc_list.GetSize() > 1) {
12690b57cec5SDimitry Andric // Collect some info about our frame's context.
12700b57cec5SDimitry Andric StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
12710b57cec5SDimitry Andric SymbolContext frame_sym_ctx;
12720b57cec5SDimitry Andric if (frame != nullptr)
12730b57cec5SDimitry Andric frame_sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
12740b57cec5SDimitry Andric lldb::eSymbolContextBlock);
12750b57cec5SDimitry Andric CompilerDeclContext frame_decl_context =
12760b57cec5SDimitry Andric frame_sym_ctx.block != nullptr ? frame_sym_ctx.block->GetDeclContext()
12770b57cec5SDimitry Andric : CompilerDeclContext();
12780b57cec5SDimitry Andric
12790b57cec5SDimitry Andric // We can't do this without a compiler decl context for our frame.
12800b57cec5SDimitry Andric if (frame_decl_context) {
1281480093f4SDimitry Andric sc_list = SearchFunctionsInSymbolContexts(sc_list, frame_decl_context);
12820b57cec5SDimitry Andric }
12830b57cec5SDimitry Andric }
12840b57cec5SDimitry Andric
12850b57cec5SDimitry Andric if (sc_list.GetSize()) {
12860b57cec5SDimitry Andric Symbol *extern_symbol = nullptr;
12870b57cec5SDimitry Andric Symbol *non_extern_symbol = nullptr;
12880b57cec5SDimitry Andric
128906c3fb27SDimitry Andric for (const SymbolContext &sym_ctx : sc_list) {
12900b57cec5SDimitry Andric if (sym_ctx.function) {
12910b57cec5SDimitry Andric CompilerDeclContext decl_ctx = sym_ctx.function->GetDeclContext();
12920b57cec5SDimitry Andric
12930b57cec5SDimitry Andric if (!decl_ctx)
12940b57cec5SDimitry Andric continue;
12950b57cec5SDimitry Andric
12960b57cec5SDimitry Andric // Filter out class/instance methods.
129706c3fb27SDimitry Andric if (decl_ctx.IsClassMethod())
12980b57cec5SDimitry Andric continue;
12990b57cec5SDimitry Andric
13005ffd83dbSDimitry Andric AddOneFunction(context, sym_ctx.function, nullptr);
13015ffd83dbSDimitry Andric context.m_found_function_with_type_info = true;
13025ffd83dbSDimitry Andric context.m_found_function = true;
13030b57cec5SDimitry Andric } else if (sym_ctx.symbol) {
130406c3fb27SDimitry Andric Symbol *symbol = sym_ctx.symbol;
130506c3fb27SDimitry Andric if (target && symbol->GetType() == eSymbolTypeReExported) {
130606c3fb27SDimitry Andric symbol = symbol->ResolveReExportedSymbol(*target);
130706c3fb27SDimitry Andric if (symbol == nullptr)
13080b57cec5SDimitry Andric continue;
13090b57cec5SDimitry Andric }
13100b57cec5SDimitry Andric
131106c3fb27SDimitry Andric if (symbol->IsExternal())
131206c3fb27SDimitry Andric extern_symbol = symbol;
13130b57cec5SDimitry Andric else
131406c3fb27SDimitry Andric non_extern_symbol = symbol;
13150b57cec5SDimitry Andric }
13160b57cec5SDimitry Andric }
13170b57cec5SDimitry Andric
13185ffd83dbSDimitry Andric if (!context.m_found_function_with_type_info) {
13190b57cec5SDimitry Andric for (clang::NamedDecl *decl : decls_from_modules) {
13200b57cec5SDimitry Andric if (llvm::isa<clang::FunctionDecl>(decl)) {
13210b57cec5SDimitry Andric clang::NamedDecl *copied_decl =
13220b57cec5SDimitry Andric llvm::cast_or_null<FunctionDecl>(CopyDecl(decl));
13230b57cec5SDimitry Andric if (copied_decl) {
13240b57cec5SDimitry Andric context.AddNamedDecl(copied_decl);
13255ffd83dbSDimitry Andric context.m_found_function_with_type_info = true;
13260b57cec5SDimitry Andric }
13270b57cec5SDimitry Andric }
13280b57cec5SDimitry Andric }
13290b57cec5SDimitry Andric }
13300b57cec5SDimitry Andric
13315ffd83dbSDimitry Andric if (!context.m_found_function_with_type_info) {
13320b57cec5SDimitry Andric if (extern_symbol) {
13335ffd83dbSDimitry Andric AddOneFunction(context, nullptr, extern_symbol);
13345ffd83dbSDimitry Andric context.m_found_function = true;
13350b57cec5SDimitry Andric } else if (non_extern_symbol) {
13365ffd83dbSDimitry Andric AddOneFunction(context, nullptr, non_extern_symbol);
13375ffd83dbSDimitry Andric context.m_found_function = true;
13380b57cec5SDimitry Andric }
13390b57cec5SDimitry Andric }
13400b57cec5SDimitry Andric }
13410b57cec5SDimitry Andric }
13420b57cec5SDimitry Andric
FindExternalVisibleDecls(NameSearchContext & context,lldb::ModuleSP module_sp,const CompilerDeclContext & namespace_decl)1343480093f4SDimitry Andric void ClangExpressionDeclMap::FindExternalVisibleDecls(
1344480093f4SDimitry Andric NameSearchContext &context, lldb::ModuleSP module_sp,
13455ffd83dbSDimitry Andric const CompilerDeclContext &namespace_decl) {
1346480093f4SDimitry Andric assert(m_ast_context);
13470b57cec5SDimitry Andric
134881ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions);
13490b57cec5SDimitry Andric
1350480093f4SDimitry Andric const ConstString name(context.m_decl_name.getAsString().c_str());
1351480093f4SDimitry Andric if (IgnoreName(name, false))
1352480093f4SDimitry Andric return;
1353480093f4SDimitry Andric
1354480093f4SDimitry Andric // Only look for functions by name out in our symbols if the function doesn't
1355480093f4SDimitry Andric // start with our phony prefix of '$'
1356480093f4SDimitry Andric
1357480093f4SDimitry Andric Target *target = nullptr;
1358480093f4SDimitry Andric StackFrame *frame = nullptr;
1359480093f4SDimitry Andric SymbolContext sym_ctx;
1360480093f4SDimitry Andric if (m_parser_vars) {
1361480093f4SDimitry Andric target = m_parser_vars->m_exe_ctx.GetTargetPtr();
1362480093f4SDimitry Andric frame = m_parser_vars->m_exe_ctx.GetFramePtr();
1363480093f4SDimitry Andric }
1364480093f4SDimitry Andric if (frame != nullptr)
1365480093f4SDimitry Andric sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
1366480093f4SDimitry Andric lldb::eSymbolContextBlock);
1367480093f4SDimitry Andric
1368480093f4SDimitry Andric // Try the persistent decls, which take precedence over all else.
1369480093f4SDimitry Andric if (!namespace_decl)
13705ffd83dbSDimitry Andric SearchPersistenDecls(context, name);
1371480093f4SDimitry Andric
13725f757f3fSDimitry Andric if (name.GetStringRef().starts_with("$") && !namespace_decl) {
1373480093f4SDimitry Andric if (name == "$__lldb_class") {
13745ffd83dbSDimitry Andric LookUpLldbClass(context);
1375480093f4SDimitry Andric return;
13760b57cec5SDimitry Andric }
13770b57cec5SDimitry Andric
1378480093f4SDimitry Andric if (name == "$__lldb_objc_class") {
13795ffd83dbSDimitry Andric LookUpLldbObjCClass(context);
1380480093f4SDimitry Andric return;
1381480093f4SDimitry Andric }
1382480093f4SDimitry Andric if (name == g_lldb_local_vars_namespace_cstr) {
1383480093f4SDimitry Andric LookupLocalVarNamespace(sym_ctx, context);
1384480093f4SDimitry Andric return;
13850b57cec5SDimitry Andric }
13860b57cec5SDimitry Andric
1387480093f4SDimitry Andric // any other $__lldb names should be weeded out now
13885f757f3fSDimitry Andric if (name.GetStringRef().starts_with("$__lldb"))
1389480093f4SDimitry Andric return;
13900b57cec5SDimitry Andric
1391480093f4SDimitry Andric // No ParserVars means we can't do register or variable lookup.
1392480093f4SDimitry Andric if (!m_parser_vars || !m_parser_vars->m_persistent_vars)
1393480093f4SDimitry Andric return;
13940b57cec5SDimitry Andric
1395480093f4SDimitry Andric ExpressionVariableSP pvar_sp(
1396480093f4SDimitry Andric m_parser_vars->m_persistent_vars->GetVariable(name));
1397480093f4SDimitry Andric
1398480093f4SDimitry Andric if (pvar_sp) {
13995ffd83dbSDimitry Andric AddOneVariable(context, pvar_sp);
1400480093f4SDimitry Andric return;
14010b57cec5SDimitry Andric }
14020b57cec5SDimitry Andric
14035f757f3fSDimitry Andric assert(name.GetStringRef().starts_with("$"));
1404480093f4SDimitry Andric llvm::StringRef reg_name = name.GetStringRef().substr(1);
14050b57cec5SDimitry Andric
1406480093f4SDimitry Andric if (m_parser_vars->m_exe_ctx.GetRegisterContext()) {
1407480093f4SDimitry Andric const RegisterInfo *reg_info(
1408480093f4SDimitry Andric m_parser_vars->m_exe_ctx.GetRegisterContext()->GetRegisterInfoByName(
1409480093f4SDimitry Andric reg_name));
1410480093f4SDimitry Andric
1411480093f4SDimitry Andric if (reg_info) {
14125ffd83dbSDimitry Andric LLDB_LOG(log, " CEDM::FEVD Found register {0}", reg_info->name);
1413480093f4SDimitry Andric
14145ffd83dbSDimitry Andric AddOneRegister(context, reg_info);
1415480093f4SDimitry Andric }
1416480093f4SDimitry Andric }
1417480093f4SDimitry Andric return;
1418480093f4SDimitry Andric }
1419480093f4SDimitry Andric
1420480093f4SDimitry Andric bool local_var_lookup = !namespace_decl || (namespace_decl.GetName() ==
1421480093f4SDimitry Andric g_lldb_local_vars_namespace_cstr);
1422480093f4SDimitry Andric if (frame && local_var_lookup)
14235ffd83dbSDimitry Andric if (LookupLocalVariable(context, name, sym_ctx, namespace_decl))
1424480093f4SDimitry Andric return;
1425480093f4SDimitry Andric
1426480093f4SDimitry Andric if (target) {
1427480093f4SDimitry Andric ValueObjectSP valobj;
1428480093f4SDimitry Andric VariableSP var;
14295ffd83dbSDimitry Andric var = FindGlobalVariable(*target, module_sp, name, namespace_decl);
1430480093f4SDimitry Andric
1431480093f4SDimitry Andric if (var) {
1432480093f4SDimitry Andric valobj = ValueObjectVariable::Create(target, var);
14335ffd83dbSDimitry Andric AddOneVariable(context, var, valobj);
14345ffd83dbSDimitry Andric context.m_found_variable = true;
1435480093f4SDimitry Andric return;
14360b57cec5SDimitry Andric }
14370b57cec5SDimitry Andric }
1438480093f4SDimitry Andric
14395ffd83dbSDimitry Andric LookupFunction(context, module_sp, name, namespace_decl);
1440480093f4SDimitry Andric
1441480093f4SDimitry Andric // Try the modules next.
14425ffd83dbSDimitry Andric if (!context.m_found_function_with_type_info)
14435ffd83dbSDimitry Andric LookupInModulesDeclVendor(context, name);
14440b57cec5SDimitry Andric
14455ffd83dbSDimitry Andric if (target && !context.m_found_variable && !namespace_decl) {
14460b57cec5SDimitry Andric // We couldn't find a non-symbol variable for this. Now we'll hunt for a
14470b57cec5SDimitry Andric // generic data symbol, and -- if it is found -- treat it as a variable.
14480b57cec5SDimitry Andric Status error;
14490b57cec5SDimitry Andric
14500b57cec5SDimitry Andric const Symbol *data_symbol =
14510b57cec5SDimitry Andric m_parser_vars->m_sym_ctx.FindBestGlobalDataSymbol(name, error);
14520b57cec5SDimitry Andric
14530b57cec5SDimitry Andric if (!error.Success()) {
14540b57cec5SDimitry Andric const unsigned diag_id =
14550b57cec5SDimitry Andric m_ast_context->getDiagnostics().getCustomDiagID(
14560b57cec5SDimitry Andric clang::DiagnosticsEngine::Level::Error, "%0");
14570b57cec5SDimitry Andric m_ast_context->getDiagnostics().Report(diag_id) << error.AsCString();
14580b57cec5SDimitry Andric }
14590b57cec5SDimitry Andric
14600b57cec5SDimitry Andric if (data_symbol) {
14610b57cec5SDimitry Andric std::string warning("got name from symbols: ");
14620b57cec5SDimitry Andric warning.append(name.AsCString());
14630b57cec5SDimitry Andric const unsigned diag_id =
14640b57cec5SDimitry Andric m_ast_context->getDiagnostics().getCustomDiagID(
14650b57cec5SDimitry Andric clang::DiagnosticsEngine::Level::Warning, "%0");
14660b57cec5SDimitry Andric m_ast_context->getDiagnostics().Report(diag_id) << warning.c_str();
14675ffd83dbSDimitry Andric AddOneGenericVariable(context, *data_symbol);
14685ffd83dbSDimitry Andric context.m_found_variable = true;
14690b57cec5SDimitry Andric }
14700b57cec5SDimitry Andric }
14710b57cec5SDimitry Andric }
14720b57cec5SDimitry Andric
GetVariableValue(VariableSP & var,lldb_private::Value & var_location,TypeFromUser * user_type,TypeFromParser * parser_type)14730b57cec5SDimitry Andric bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var,
14740b57cec5SDimitry Andric lldb_private::Value &var_location,
14750b57cec5SDimitry Andric TypeFromUser *user_type,
14760b57cec5SDimitry Andric TypeFromParser *parser_type) {
147781ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions);
14780b57cec5SDimitry Andric
14790b57cec5SDimitry Andric Type *var_type = var->GetType();
14800b57cec5SDimitry Andric
14810b57cec5SDimitry Andric if (!var_type) {
14825ffd83dbSDimitry Andric LLDB_LOG(log, "Skipped a definition because it has no type");
14830b57cec5SDimitry Andric return false;
14840b57cec5SDimitry Andric }
14850b57cec5SDimitry Andric
14860b57cec5SDimitry Andric CompilerType var_clang_type = var_type->GetFullCompilerType();
14870b57cec5SDimitry Andric
14880b57cec5SDimitry Andric if (!var_clang_type) {
14895ffd83dbSDimitry Andric LLDB_LOG(log, "Skipped a definition because it has no Clang type");
14900b57cec5SDimitry Andric return false;
14910b57cec5SDimitry Andric }
14920b57cec5SDimitry Andric
1493bdd1243dSDimitry Andric auto ts = var_type->GetForwardCompilerType().GetTypeSystem();
1494bdd1243dSDimitry Andric auto clang_ast = ts.dyn_cast_or_null<TypeSystemClang>();
14950b57cec5SDimitry Andric
14960b57cec5SDimitry Andric if (!clang_ast) {
14975ffd83dbSDimitry Andric LLDB_LOG(log, "Skipped a definition because it has no Clang AST");
14980b57cec5SDimitry Andric return false;
14990b57cec5SDimitry Andric }
15000b57cec5SDimitry Andric
1501753f127fSDimitry Andric DWARFExpressionList &var_location_list = var->LocationExpressionList();
15020b57cec5SDimitry Andric
15030b57cec5SDimitry Andric Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
15040b57cec5SDimitry Andric Status err;
15050b57cec5SDimitry Andric
15060b57cec5SDimitry Andric if (var->GetLocationIsConstantValueData()) {
15070b57cec5SDimitry Andric DataExtractor const_value_extractor;
1508753f127fSDimitry Andric if (var_location_list.GetExpressionData(const_value_extractor)) {
15090b57cec5SDimitry Andric var_location = Value(const_value_extractor.GetDataStart(),
15100b57cec5SDimitry Andric const_value_extractor.GetByteSize());
1511fe6060f1SDimitry Andric var_location.SetValueType(Value::ValueType::HostAddress);
15120b57cec5SDimitry Andric } else {
15135ffd83dbSDimitry Andric LLDB_LOG(log, "Error evaluating constant variable: {0}", err.AsCString());
15140b57cec5SDimitry Andric return false;
15150b57cec5SDimitry Andric }
15160b57cec5SDimitry Andric }
15170b57cec5SDimitry Andric
15180b57cec5SDimitry Andric CompilerType type_to_use = GuardedCopyType(var_clang_type);
15190b57cec5SDimitry Andric
15200b57cec5SDimitry Andric if (!type_to_use) {
15215ffd83dbSDimitry Andric LLDB_LOG(log,
15220b57cec5SDimitry Andric "Couldn't copy a variable's type into the parser's AST context");
15230b57cec5SDimitry Andric
15240b57cec5SDimitry Andric return false;
15250b57cec5SDimitry Andric }
15260b57cec5SDimitry Andric
15270b57cec5SDimitry Andric if (parser_type)
15280b57cec5SDimitry Andric *parser_type = TypeFromParser(type_to_use);
15290b57cec5SDimitry Andric
1530fe6060f1SDimitry Andric if (var_location.GetContextType() == Value::ContextType::Invalid)
15310b57cec5SDimitry Andric var_location.SetCompilerType(type_to_use);
15320b57cec5SDimitry Andric
1533fe6060f1SDimitry Andric if (var_location.GetValueType() == Value::ValueType::FileAddress) {
15340b57cec5SDimitry Andric SymbolContext var_sc;
15350b57cec5SDimitry Andric var->CalculateSymbolContext(&var_sc);
15360b57cec5SDimitry Andric
15370b57cec5SDimitry Andric if (!var_sc.module_sp)
15380b57cec5SDimitry Andric return false;
15390b57cec5SDimitry Andric
15400b57cec5SDimitry Andric Address so_addr(var_location.GetScalar().ULongLong(),
15410b57cec5SDimitry Andric var_sc.module_sp->GetSectionList());
15420b57cec5SDimitry Andric
15430b57cec5SDimitry Andric lldb::addr_t load_addr = so_addr.GetLoadAddress(target);
15440b57cec5SDimitry Andric
15450b57cec5SDimitry Andric if (load_addr != LLDB_INVALID_ADDRESS) {
15460b57cec5SDimitry Andric var_location.GetScalar() = load_addr;
1547fe6060f1SDimitry Andric var_location.SetValueType(Value::ValueType::LoadAddress);
15480b57cec5SDimitry Andric }
15490b57cec5SDimitry Andric }
15500b57cec5SDimitry Andric
15510b57cec5SDimitry Andric if (user_type)
15520b57cec5SDimitry Andric *user_type = TypeFromUser(var_clang_type);
15530b57cec5SDimitry Andric
15540b57cec5SDimitry Andric return true;
15550b57cec5SDimitry Andric }
15560b57cec5SDimitry Andric
1557fcaf7f86SDimitry Andric ClangExpressionVariable::ParserVars *
AddExpressionVariable(NameSearchContext & context,TypeFromParser const & pt,ValueObjectSP valobj)1558fcaf7f86SDimitry Andric ClangExpressionDeclMap::AddExpressionVariable(NameSearchContext &context,
1559fcaf7f86SDimitry Andric TypeFromParser const &pt,
15605ffd83dbSDimitry Andric ValueObjectSP valobj) {
15610b57cec5SDimitry Andric clang::QualType parser_opaque_type =
15620b57cec5SDimitry Andric QualType::getFromOpaquePtr(pt.GetOpaqueQualType());
15630b57cec5SDimitry Andric
15640b57cec5SDimitry Andric if (parser_opaque_type.isNull())
1565fcaf7f86SDimitry Andric return nullptr;
15660b57cec5SDimitry Andric
15670b57cec5SDimitry Andric if (const clang::Type *parser_type = parser_opaque_type.getTypePtr()) {
15680b57cec5SDimitry Andric if (const TagType *tag_type = dyn_cast<TagType>(parser_type))
15690b57cec5SDimitry Andric CompleteType(tag_type->getDecl());
15700b57cec5SDimitry Andric if (const ObjCObjectPointerType *objc_object_ptr_type =
15710b57cec5SDimitry Andric dyn_cast<ObjCObjectPointerType>(parser_type))
15720b57cec5SDimitry Andric CompleteType(objc_object_ptr_type->getInterfaceDecl());
15730b57cec5SDimitry Andric }
15740b57cec5SDimitry Andric
15750b57cec5SDimitry Andric bool is_reference = pt.IsReferenceType();
15760b57cec5SDimitry Andric
15770b57cec5SDimitry Andric NamedDecl *var_decl = nullptr;
15780b57cec5SDimitry Andric if (is_reference)
15790b57cec5SDimitry Andric var_decl = context.AddVarDecl(pt);
15800b57cec5SDimitry Andric else
15810b57cec5SDimitry Andric var_decl = context.AddVarDecl(pt.GetLValueReferenceType());
15820b57cec5SDimitry Andric
15830b57cec5SDimitry Andric std::string decl_name(context.m_decl_name.getAsString());
15840b57cec5SDimitry Andric ConstString entity_name(decl_name.c_str());
15850b57cec5SDimitry Andric ClangExpressionVariable *entity(new ClangExpressionVariable(valobj));
15860b57cec5SDimitry Andric m_found_entities.AddNewlyConstructedVariable(entity);
15870b57cec5SDimitry Andric
15880b57cec5SDimitry Andric assert(entity);
15890b57cec5SDimitry Andric entity->EnableParserVars(GetParserID());
15900b57cec5SDimitry Andric ClangExpressionVariable::ParserVars *parser_vars =
15910b57cec5SDimitry Andric entity->GetParserVars(GetParserID());
1592fcaf7f86SDimitry Andric
15930b57cec5SDimitry Andric parser_vars->m_named_decl = var_decl;
15940b57cec5SDimitry Andric
15950b57cec5SDimitry Andric if (is_reference)
15960b57cec5SDimitry Andric entity->m_flags |= ClangExpressionVariable::EVTypeIsReference;
15970b57cec5SDimitry Andric
1598fcaf7f86SDimitry Andric return parser_vars;
1599fcaf7f86SDimitry Andric }
1600fcaf7f86SDimitry Andric
AddOneVariable(NameSearchContext & context,ValueObjectSP valobj,ValueObjectProviderTy valobj_provider)1601fcaf7f86SDimitry Andric void ClangExpressionDeclMap::AddOneVariable(
1602fcaf7f86SDimitry Andric NameSearchContext &context, ValueObjectSP valobj,
1603fcaf7f86SDimitry Andric ValueObjectProviderTy valobj_provider) {
1604fcaf7f86SDimitry Andric assert(m_parser_vars.get());
1605fcaf7f86SDimitry Andric assert(valobj);
1606fcaf7f86SDimitry Andric
1607fcaf7f86SDimitry Andric Log *log = GetLog(LLDBLog::Expressions);
1608fcaf7f86SDimitry Andric
1609fcaf7f86SDimitry Andric Value var_location = valobj->GetValue();
1610fcaf7f86SDimitry Andric
1611fcaf7f86SDimitry Andric TypeFromUser user_type = valobj->GetCompilerType();
1612fcaf7f86SDimitry Andric
1613bdd1243dSDimitry Andric auto clang_ast =
1614bdd1243dSDimitry Andric user_type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>();
1615fcaf7f86SDimitry Andric
1616fcaf7f86SDimitry Andric if (!clang_ast) {
1617fcaf7f86SDimitry Andric LLDB_LOG(log, "Skipped a definition because it has no Clang AST");
1618fcaf7f86SDimitry Andric return;
1619fcaf7f86SDimitry Andric }
1620fcaf7f86SDimitry Andric
1621fcaf7f86SDimitry Andric TypeFromParser parser_type = GuardedCopyType(user_type);
1622fcaf7f86SDimitry Andric
1623fcaf7f86SDimitry Andric if (!parser_type) {
1624fcaf7f86SDimitry Andric LLDB_LOG(log,
1625fcaf7f86SDimitry Andric "Couldn't copy a variable's type into the parser's AST context");
1626fcaf7f86SDimitry Andric
1627fcaf7f86SDimitry Andric return;
1628fcaf7f86SDimitry Andric }
1629fcaf7f86SDimitry Andric
1630fcaf7f86SDimitry Andric if (var_location.GetContextType() == Value::ContextType::Invalid)
1631fcaf7f86SDimitry Andric var_location.SetCompilerType(parser_type);
1632fcaf7f86SDimitry Andric
1633fcaf7f86SDimitry Andric ClangExpressionVariable::ParserVars *parser_vars =
1634fcaf7f86SDimitry Andric AddExpressionVariable(context, parser_type, valobj);
1635fcaf7f86SDimitry Andric
1636fcaf7f86SDimitry Andric if (!parser_vars)
1637fcaf7f86SDimitry Andric return;
1638fcaf7f86SDimitry Andric
163981ad6265SDimitry Andric LLDB_LOG(log, " CEDM::FEVD Found variable {0}, returned\n{1} (original {2})",
1640fcaf7f86SDimitry Andric context.m_decl_name, ClangUtil::DumpDecl(parser_vars->m_named_decl),
1641fcaf7f86SDimitry Andric ClangUtil::ToString(user_type));
1642fcaf7f86SDimitry Andric
1643fcaf7f86SDimitry Andric parser_vars->m_llvm_value = nullptr;
1644fcaf7f86SDimitry Andric parser_vars->m_lldb_value = std::move(var_location);
1645fcaf7f86SDimitry Andric parser_vars->m_lldb_valobj_provider = std::move(valobj_provider);
1646fcaf7f86SDimitry Andric }
1647fcaf7f86SDimitry Andric
AddOneVariable(NameSearchContext & context,VariableSP var,ValueObjectSP valobj)1648fcaf7f86SDimitry Andric void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
1649fcaf7f86SDimitry Andric VariableSP var,
1650fcaf7f86SDimitry Andric ValueObjectSP valobj) {
1651fcaf7f86SDimitry Andric assert(m_parser_vars.get());
1652fcaf7f86SDimitry Andric
1653fcaf7f86SDimitry Andric Log *log = GetLog(LLDBLog::Expressions);
1654fcaf7f86SDimitry Andric
1655fcaf7f86SDimitry Andric TypeFromUser ut;
1656fcaf7f86SDimitry Andric TypeFromParser pt;
1657fcaf7f86SDimitry Andric Value var_location;
1658fcaf7f86SDimitry Andric
1659fcaf7f86SDimitry Andric if (!GetVariableValue(var, var_location, &ut, &pt))
1660fcaf7f86SDimitry Andric return;
1661fcaf7f86SDimitry Andric
1662fcaf7f86SDimitry Andric ClangExpressionVariable::ParserVars *parser_vars =
1663fcaf7f86SDimitry Andric AddExpressionVariable(context, pt, std::move(valobj));
1664fcaf7f86SDimitry Andric
1665fcaf7f86SDimitry Andric if (!parser_vars)
1666fcaf7f86SDimitry Andric return;
1667fcaf7f86SDimitry Andric
1668fcaf7f86SDimitry Andric LLDB_LOG(log, " CEDM::FEVD Found variable {0}, returned\n{1} (original {2})",
1669fcaf7f86SDimitry Andric context.m_decl_name, ClangUtil::DumpDecl(parser_vars->m_named_decl),
1670fcaf7f86SDimitry Andric ClangUtil::ToString(ut));
1671fcaf7f86SDimitry Andric
1672fcaf7f86SDimitry Andric parser_vars->m_llvm_value = nullptr;
1673fcaf7f86SDimitry Andric parser_vars->m_lldb_value = var_location;
1674fcaf7f86SDimitry Andric parser_vars->m_lldb_var = var;
16750b57cec5SDimitry Andric }
16760b57cec5SDimitry Andric
AddOneVariable(NameSearchContext & context,ExpressionVariableSP & pvar_sp)16770b57cec5SDimitry Andric void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
16785ffd83dbSDimitry Andric ExpressionVariableSP &pvar_sp) {
167981ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions);
16800b57cec5SDimitry Andric
16810b57cec5SDimitry Andric TypeFromUser user_type(
16820b57cec5SDimitry Andric llvm::cast<ClangExpressionVariable>(pvar_sp.get())->GetTypeFromUser());
16830b57cec5SDimitry Andric
16840b57cec5SDimitry Andric TypeFromParser parser_type(GuardedCopyType(user_type));
16850b57cec5SDimitry Andric
16860b57cec5SDimitry Andric if (!parser_type.GetOpaqueQualType()) {
16875ffd83dbSDimitry Andric LLDB_LOG(log, " CEDM::FEVD Couldn't import type for pvar {0}",
16885ffd83dbSDimitry Andric pvar_sp->GetName());
16890b57cec5SDimitry Andric return;
16900b57cec5SDimitry Andric }
16910b57cec5SDimitry Andric
16920b57cec5SDimitry Andric NamedDecl *var_decl =
16930b57cec5SDimitry Andric context.AddVarDecl(parser_type.GetLValueReferenceType());
16940b57cec5SDimitry Andric
16950b57cec5SDimitry Andric llvm::cast<ClangExpressionVariable>(pvar_sp.get())
16960b57cec5SDimitry Andric ->EnableParserVars(GetParserID());
16970b57cec5SDimitry Andric ClangExpressionVariable::ParserVars *parser_vars =
16980b57cec5SDimitry Andric llvm::cast<ClangExpressionVariable>(pvar_sp.get())
16990b57cec5SDimitry Andric ->GetParserVars(GetParserID());
17000b57cec5SDimitry Andric parser_vars->m_named_decl = var_decl;
17010b57cec5SDimitry Andric parser_vars->m_llvm_value = nullptr;
17020b57cec5SDimitry Andric parser_vars->m_lldb_value.Clear();
17030b57cec5SDimitry Andric
170481ad6265SDimitry Andric LLDB_LOG(log, " CEDM::FEVD Added pvar {0}, returned\n{1}",
1705480093f4SDimitry Andric pvar_sp->GetName(), ClangUtil::DumpDecl(var_decl));
17060b57cec5SDimitry Andric }
17070b57cec5SDimitry Andric
AddOneGenericVariable(NameSearchContext & context,const Symbol & symbol)17080b57cec5SDimitry Andric void ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context,
17095ffd83dbSDimitry Andric const Symbol &symbol) {
17100b57cec5SDimitry Andric assert(m_parser_vars.get());
17110b57cec5SDimitry Andric
171281ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions);
17130b57cec5SDimitry Andric
17140b57cec5SDimitry Andric Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
17150b57cec5SDimitry Andric
17160b57cec5SDimitry Andric if (target == nullptr)
17170b57cec5SDimitry Andric return;
17180b57cec5SDimitry Andric
1719bdd1243dSDimitry Andric auto scratch_ast_context = GetScratchContext(*target);
1720480093f4SDimitry Andric if (!scratch_ast_context)
1721480093f4SDimitry Andric return;
17220b57cec5SDimitry Andric
1723480093f4SDimitry Andric TypeFromUser user_type(scratch_ast_context->GetBasicType(eBasicTypeVoid)
17240b57cec5SDimitry Andric .GetPointerType()
17250b57cec5SDimitry Andric .GetLValueReferenceType());
1726480093f4SDimitry Andric TypeFromParser parser_type(m_clang_ast_context->GetBasicType(eBasicTypeVoid)
17270b57cec5SDimitry Andric .GetPointerType()
17280b57cec5SDimitry Andric .GetLValueReferenceType());
17290b57cec5SDimitry Andric NamedDecl *var_decl = context.AddVarDecl(parser_type);
17300b57cec5SDimitry Andric
17310b57cec5SDimitry Andric std::string decl_name(context.m_decl_name.getAsString());
17320b57cec5SDimitry Andric ConstString entity_name(decl_name.c_str());
17330b57cec5SDimitry Andric ClangExpressionVariable *entity(new ClangExpressionVariable(
17340b57cec5SDimitry Andric m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), entity_name,
17350b57cec5SDimitry Andric user_type, m_parser_vars->m_target_info.byte_order,
17360b57cec5SDimitry Andric m_parser_vars->m_target_info.address_byte_size));
17370b57cec5SDimitry Andric m_found_entities.AddNewlyConstructedVariable(entity);
17380b57cec5SDimitry Andric
17390b57cec5SDimitry Andric entity->EnableParserVars(GetParserID());
17400b57cec5SDimitry Andric ClangExpressionVariable::ParserVars *parser_vars =
17410b57cec5SDimitry Andric entity->GetParserVars(GetParserID());
17420b57cec5SDimitry Andric
17430b57cec5SDimitry Andric const Address symbol_address = symbol.GetAddress();
17440b57cec5SDimitry Andric lldb::addr_t symbol_load_addr = symbol_address.GetLoadAddress(target);
17450b57cec5SDimitry Andric
1746fe6060f1SDimitry Andric // parser_vars->m_lldb_value.SetContext(Value::ContextType::ClangType,
17470b57cec5SDimitry Andric // user_type.GetOpaqueQualType());
17480b57cec5SDimitry Andric parser_vars->m_lldb_value.SetCompilerType(user_type);
17490b57cec5SDimitry Andric parser_vars->m_lldb_value.GetScalar() = symbol_load_addr;
1750fe6060f1SDimitry Andric parser_vars->m_lldb_value.SetValueType(Value::ValueType::LoadAddress);
17510b57cec5SDimitry Andric
17520b57cec5SDimitry Andric parser_vars->m_named_decl = var_decl;
17530b57cec5SDimitry Andric parser_vars->m_llvm_value = nullptr;
17540b57cec5SDimitry Andric parser_vars->m_lldb_sym = &symbol;
17550b57cec5SDimitry Andric
175681ad6265SDimitry Andric LLDB_LOG(log, " CEDM::FEVD Found variable {0}, returned\n{1}", decl_name,
17575ffd83dbSDimitry Andric ClangUtil::DumpDecl(var_decl));
17580b57cec5SDimitry Andric }
17590b57cec5SDimitry Andric
AddOneRegister(NameSearchContext & context,const RegisterInfo * reg_info)17600b57cec5SDimitry Andric void ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context,
17615ffd83dbSDimitry Andric const RegisterInfo *reg_info) {
176281ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions);
17630b57cec5SDimitry Andric
17640b57cec5SDimitry Andric CompilerType clang_type =
1765480093f4SDimitry Andric m_clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(
1766480093f4SDimitry Andric reg_info->encoding, reg_info->byte_size * 8);
17670b57cec5SDimitry Andric
17680b57cec5SDimitry Andric if (!clang_type) {
17695ffd83dbSDimitry Andric LLDB_LOG(log, " Tried to add a type for {0}, but couldn't get one",
17705ffd83dbSDimitry Andric context.m_decl_name.getAsString());
17710b57cec5SDimitry Andric return;
17720b57cec5SDimitry Andric }
17730b57cec5SDimitry Andric
17740b57cec5SDimitry Andric TypeFromParser parser_clang_type(clang_type);
17750b57cec5SDimitry Andric
17760b57cec5SDimitry Andric NamedDecl *var_decl = context.AddVarDecl(parser_clang_type);
17770b57cec5SDimitry Andric
17780b57cec5SDimitry Andric ClangExpressionVariable *entity(new ClangExpressionVariable(
17790b57cec5SDimitry Andric m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
17800b57cec5SDimitry Andric m_parser_vars->m_target_info.byte_order,
17810b57cec5SDimitry Andric m_parser_vars->m_target_info.address_byte_size));
17820b57cec5SDimitry Andric m_found_entities.AddNewlyConstructedVariable(entity);
17830b57cec5SDimitry Andric
17840b57cec5SDimitry Andric std::string decl_name(context.m_decl_name.getAsString());
17850b57cec5SDimitry Andric entity->SetName(ConstString(decl_name.c_str()));
17860b57cec5SDimitry Andric entity->SetRegisterInfo(reg_info);
17870b57cec5SDimitry Andric entity->EnableParserVars(GetParserID());
17880b57cec5SDimitry Andric ClangExpressionVariable::ParserVars *parser_vars =
17890b57cec5SDimitry Andric entity->GetParserVars(GetParserID());
17900b57cec5SDimitry Andric parser_vars->m_named_decl = var_decl;
17910b57cec5SDimitry Andric parser_vars->m_llvm_value = nullptr;
17920b57cec5SDimitry Andric parser_vars->m_lldb_value.Clear();
17930b57cec5SDimitry Andric entity->m_flags |= ClangExpressionVariable::EVBareRegister;
17940b57cec5SDimitry Andric
179581ad6265SDimitry Andric LLDB_LOG(log, " CEDM::FEVD Added register {0}, returned\n{1}",
17965ffd83dbSDimitry Andric context.m_decl_name.getAsString(), ClangUtil::DumpDecl(var_decl));
17970b57cec5SDimitry Andric }
17980b57cec5SDimitry Andric
AddOneFunction(NameSearchContext & context,Function * function,Symbol * symbol)17990b57cec5SDimitry Andric void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
18005ffd83dbSDimitry Andric Function *function,
18015ffd83dbSDimitry Andric Symbol *symbol) {
18020b57cec5SDimitry Andric assert(m_parser_vars.get());
18030b57cec5SDimitry Andric
180481ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions);
18050b57cec5SDimitry Andric
18060b57cec5SDimitry Andric NamedDecl *function_decl = nullptr;
18070b57cec5SDimitry Andric Address fun_address;
18080b57cec5SDimitry Andric CompilerType function_clang_type;
18090b57cec5SDimitry Andric
18100b57cec5SDimitry Andric bool is_indirect_function = false;
18110b57cec5SDimitry Andric
18120b57cec5SDimitry Andric if (function) {
18130b57cec5SDimitry Andric Type *function_type = function->GetType();
18140b57cec5SDimitry Andric
18150b57cec5SDimitry Andric const auto lang = function->GetCompileUnit()->GetLanguage();
18160b57cec5SDimitry Andric const auto name = function->GetMangled().GetMangledName().AsCString();
18170b57cec5SDimitry Andric const bool extern_c = (Language::LanguageIsC(lang) &&
18180b57cec5SDimitry Andric !CPlusPlusLanguage::IsCPPMangledName(name)) ||
18190b57cec5SDimitry Andric (Language::LanguageIsObjC(lang) &&
18200b57cec5SDimitry Andric !Language::LanguageIsCPlusPlus(lang));
18210b57cec5SDimitry Andric
18220b57cec5SDimitry Andric if (!extern_c) {
18230b57cec5SDimitry Andric TypeSystem *type_system = function->GetDeclContext().GetTypeSystem();
18245ffd83dbSDimitry Andric if (llvm::isa<TypeSystemClang>(type_system)) {
18250b57cec5SDimitry Andric clang::DeclContext *src_decl_context =
18260b57cec5SDimitry Andric (clang::DeclContext *)function->GetDeclContext()
18270b57cec5SDimitry Andric .GetOpaqueDeclContext();
18280b57cec5SDimitry Andric clang::FunctionDecl *src_function_decl =
18290b57cec5SDimitry Andric llvm::dyn_cast_or_null<clang::FunctionDecl>(src_decl_context);
18300b57cec5SDimitry Andric if (src_function_decl &&
18310b57cec5SDimitry Andric src_function_decl->getTemplateSpecializationInfo()) {
18320b57cec5SDimitry Andric clang::FunctionTemplateDecl *function_template =
18330b57cec5SDimitry Andric src_function_decl->getTemplateSpecializationInfo()->getTemplate();
18340b57cec5SDimitry Andric clang::FunctionTemplateDecl *copied_function_template =
18350b57cec5SDimitry Andric llvm::dyn_cast_or_null<clang::FunctionTemplateDecl>(
18360b57cec5SDimitry Andric CopyDecl(function_template));
18370b57cec5SDimitry Andric if (copied_function_template) {
18380b57cec5SDimitry Andric if (log) {
18390b57cec5SDimitry Andric StreamString ss;
18400b57cec5SDimitry Andric
18410b57cec5SDimitry Andric function->DumpSymbolContext(&ss);
18420b57cec5SDimitry Andric
1843480093f4SDimitry Andric LLDB_LOG(log,
18445ffd83dbSDimitry Andric " CEDM::FEVD Imported decl for function template"
184581ad6265SDimitry Andric " {0} (description {1}), returned\n{2}",
18465ffd83dbSDimitry Andric copied_function_template->getNameAsString(),
1847480093f4SDimitry Andric ss.GetData(),
1848480093f4SDimitry Andric ClangUtil::DumpDecl(copied_function_template));
18490b57cec5SDimitry Andric }
18500b57cec5SDimitry Andric
18510b57cec5SDimitry Andric context.AddNamedDecl(copied_function_template);
18520b57cec5SDimitry Andric }
18530b57cec5SDimitry Andric } else if (src_function_decl) {
18540b57cec5SDimitry Andric if (clang::FunctionDecl *copied_function_decl =
18550b57cec5SDimitry Andric llvm::dyn_cast_or_null<clang::FunctionDecl>(
18560b57cec5SDimitry Andric CopyDecl(src_function_decl))) {
18570b57cec5SDimitry Andric if (log) {
18580b57cec5SDimitry Andric StreamString ss;
18590b57cec5SDimitry Andric
18600b57cec5SDimitry Andric function->DumpSymbolContext(&ss);
18610b57cec5SDimitry Andric
1862480093f4SDimitry Andric LLDB_LOG(log,
186381ad6265SDimitry Andric " CEDM::FEVD Imported decl for function {0} "
186481ad6265SDimitry Andric "(description {1}), returned\n{2}",
18655ffd83dbSDimitry Andric copied_function_decl->getNameAsString(), ss.GetData(),
18665ffd83dbSDimitry Andric ClangUtil::DumpDecl(copied_function_decl));
18670b57cec5SDimitry Andric }
18680b57cec5SDimitry Andric
18690b57cec5SDimitry Andric context.AddNamedDecl(copied_function_decl);
18700b57cec5SDimitry Andric return;
18710b57cec5SDimitry Andric } else {
18725ffd83dbSDimitry Andric LLDB_LOG(log, " Failed to import the function decl for '{0}'",
18735ffd83dbSDimitry Andric src_function_decl->getName());
18740b57cec5SDimitry Andric }
18750b57cec5SDimitry Andric }
18760b57cec5SDimitry Andric }
18770b57cec5SDimitry Andric }
18780b57cec5SDimitry Andric
18790b57cec5SDimitry Andric if (!function_type) {
18805ffd83dbSDimitry Andric LLDB_LOG(log, " Skipped a function because it has no type");
18810b57cec5SDimitry Andric return;
18820b57cec5SDimitry Andric }
18830b57cec5SDimitry Andric
18840b57cec5SDimitry Andric function_clang_type = function_type->GetFullCompilerType();
18850b57cec5SDimitry Andric
18860b57cec5SDimitry Andric if (!function_clang_type) {
18875ffd83dbSDimitry Andric LLDB_LOG(log, " Skipped a function because it has no Clang type");
18880b57cec5SDimitry Andric return;
18890b57cec5SDimitry Andric }
18900b57cec5SDimitry Andric
18910b57cec5SDimitry Andric fun_address = function->GetAddressRange().GetBaseAddress();
18920b57cec5SDimitry Andric
18930b57cec5SDimitry Andric CompilerType copied_function_type = GuardedCopyType(function_clang_type);
18940b57cec5SDimitry Andric if (copied_function_type) {
18950b57cec5SDimitry Andric function_decl = context.AddFunDecl(copied_function_type, extern_c);
18960b57cec5SDimitry Andric
18970b57cec5SDimitry Andric if (!function_decl) {
18985ffd83dbSDimitry Andric LLDB_LOG(log, " Failed to create a function decl for '{0}' ({1:x})",
18995ffd83dbSDimitry Andric function_type->GetName(), function_type->GetID());
19000b57cec5SDimitry Andric
19010b57cec5SDimitry Andric return;
19020b57cec5SDimitry Andric }
19030b57cec5SDimitry Andric } else {
19040b57cec5SDimitry Andric // We failed to copy the type we found
19055ffd83dbSDimitry Andric LLDB_LOG(log,
19065ffd83dbSDimitry Andric " Failed to import the function type '{0}' ({1:x})"
1907bdd1243dSDimitry Andric " into the expression parser AST context",
19085ffd83dbSDimitry Andric function_type->GetName(), function_type->GetID());
19090b57cec5SDimitry Andric
19100b57cec5SDimitry Andric return;
19110b57cec5SDimitry Andric }
19120b57cec5SDimitry Andric } else if (symbol) {
19130b57cec5SDimitry Andric fun_address = symbol->GetAddress();
19140b57cec5SDimitry Andric function_decl = context.AddGenericFunDecl();
19150b57cec5SDimitry Andric is_indirect_function = symbol->IsIndirect();
19160b57cec5SDimitry Andric } else {
19175ffd83dbSDimitry Andric LLDB_LOG(log, " AddOneFunction called with no function and no symbol");
19180b57cec5SDimitry Andric return;
19190b57cec5SDimitry Andric }
19200b57cec5SDimitry Andric
19210b57cec5SDimitry Andric Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
19220b57cec5SDimitry Andric
19230b57cec5SDimitry Andric lldb::addr_t load_addr =
19240b57cec5SDimitry Andric fun_address.GetCallableLoadAddress(target, is_indirect_function);
19250b57cec5SDimitry Andric
19260b57cec5SDimitry Andric ClangExpressionVariable *entity(new ClangExpressionVariable(
19270b57cec5SDimitry Andric m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
19280b57cec5SDimitry Andric m_parser_vars->m_target_info.byte_order,
19290b57cec5SDimitry Andric m_parser_vars->m_target_info.address_byte_size));
19300b57cec5SDimitry Andric m_found_entities.AddNewlyConstructedVariable(entity);
19310b57cec5SDimitry Andric
19320b57cec5SDimitry Andric std::string decl_name(context.m_decl_name.getAsString());
19330b57cec5SDimitry Andric entity->SetName(ConstString(decl_name.c_str()));
19340b57cec5SDimitry Andric entity->SetCompilerType(function_clang_type);
19350b57cec5SDimitry Andric entity->EnableParserVars(GetParserID());
19360b57cec5SDimitry Andric
19370b57cec5SDimitry Andric ClangExpressionVariable::ParserVars *parser_vars =
19380b57cec5SDimitry Andric entity->GetParserVars(GetParserID());
19390b57cec5SDimitry Andric
19400b57cec5SDimitry Andric if (load_addr != LLDB_INVALID_ADDRESS) {
1941fe6060f1SDimitry Andric parser_vars->m_lldb_value.SetValueType(Value::ValueType::LoadAddress);
19420b57cec5SDimitry Andric parser_vars->m_lldb_value.GetScalar() = load_addr;
19430b57cec5SDimitry Andric } else {
19440b57cec5SDimitry Andric // We have to try finding a file address.
19450b57cec5SDimitry Andric
19460b57cec5SDimitry Andric lldb::addr_t file_addr = fun_address.GetFileAddress();
19470b57cec5SDimitry Andric
1948fe6060f1SDimitry Andric parser_vars->m_lldb_value.SetValueType(Value::ValueType::FileAddress);
19490b57cec5SDimitry Andric parser_vars->m_lldb_value.GetScalar() = file_addr;
19500b57cec5SDimitry Andric }
19510b57cec5SDimitry Andric
19520b57cec5SDimitry Andric parser_vars->m_named_decl = function_decl;
19530b57cec5SDimitry Andric parser_vars->m_llvm_value = nullptr;
19540b57cec5SDimitry Andric
19550b57cec5SDimitry Andric if (log) {
19560b57cec5SDimitry Andric StreamString ss;
19570b57cec5SDimitry Andric
19580b57cec5SDimitry Andric fun_address.Dump(&ss,
19590b57cec5SDimitry Andric m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
19600b57cec5SDimitry Andric Address::DumpStyleResolvedDescription);
19610b57cec5SDimitry Andric
1962480093f4SDimitry Andric LLDB_LOG(log,
196381ad6265SDimitry Andric " CEDM::FEVD Found {0} function {1} (description {2}), "
196481ad6265SDimitry Andric "returned\n{3}",
19655ffd83dbSDimitry Andric (function ? "specific" : "generic"), decl_name, ss.GetData(),
19665ffd83dbSDimitry Andric ClangUtil::DumpDecl(function_decl));
19670b57cec5SDimitry Andric }
19680b57cec5SDimitry Andric }
19690b57cec5SDimitry Andric
AddContextClassType(NameSearchContext & context,const TypeFromUser & ut)19705ffd83dbSDimitry Andric void ClangExpressionDeclMap::AddContextClassType(NameSearchContext &context,
19715ffd83dbSDimitry Andric const TypeFromUser &ut) {
19720b57cec5SDimitry Andric CompilerType copied_clang_type = GuardedCopyType(ut);
19730b57cec5SDimitry Andric
197481ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions);
19750b57cec5SDimitry Andric
19760b57cec5SDimitry Andric if (!copied_clang_type) {
19775ffd83dbSDimitry Andric LLDB_LOG(log,
19780b57cec5SDimitry Andric "ClangExpressionDeclMap::AddThisType - Couldn't import the type");
19790b57cec5SDimitry Andric
19800b57cec5SDimitry Andric return;
19810b57cec5SDimitry Andric }
19820b57cec5SDimitry Andric
19830b57cec5SDimitry Andric if (copied_clang_type.IsAggregateType() &&
19840b57cec5SDimitry Andric copied_clang_type.GetCompleteType()) {
19850b57cec5SDimitry Andric CompilerType void_clang_type =
1986480093f4SDimitry Andric m_clang_ast_context->GetBasicType(eBasicTypeVoid);
19870b57cec5SDimitry Andric CompilerType void_ptr_clang_type = void_clang_type.GetPointerType();
19880b57cec5SDimitry Andric
1989480093f4SDimitry Andric CompilerType method_type = m_clang_ast_context->CreateFunctionType(
1990480093f4SDimitry Andric void_clang_type, &void_ptr_clang_type, 1, false, 0);
19910b57cec5SDimitry Andric
19920b57cec5SDimitry Andric const bool is_virtual = false;
19930b57cec5SDimitry Andric const bool is_static = false;
19940b57cec5SDimitry Andric const bool is_inline = false;
19950b57cec5SDimitry Andric const bool is_explicit = false;
19960b57cec5SDimitry Andric const bool is_attr_used = true;
19970b57cec5SDimitry Andric const bool is_artificial = false;
19980b57cec5SDimitry Andric
1999480093f4SDimitry Andric CXXMethodDecl *method_decl = m_clang_ast_context->AddMethodToCXXRecordType(
20000b57cec5SDimitry Andric copied_clang_type.GetOpaqueQualType(), "$__lldb_expr", nullptr,
2001480093f4SDimitry Andric method_type, lldb::eAccessPublic, is_virtual, is_static, is_inline,
2002480093f4SDimitry Andric is_explicit, is_attr_used, is_artificial);
20030b57cec5SDimitry Andric
2004480093f4SDimitry Andric LLDB_LOG(log,
20059dba64beSDimitry Andric " CEDM::AddThisType Added function $__lldb_expr "
2006480093f4SDimitry Andric "(description {0}) for this type\n{1}",
2007480093f4SDimitry Andric ClangUtil::ToString(copied_clang_type),
2008480093f4SDimitry Andric ClangUtil::DumpDecl(method_decl));
20090b57cec5SDimitry Andric }
20100b57cec5SDimitry Andric
20110b57cec5SDimitry Andric if (!copied_clang_type.IsValid())
20120b57cec5SDimitry Andric return;
20130b57cec5SDimitry Andric
20140b57cec5SDimitry Andric TypeSourceInfo *type_source_info = m_ast_context->getTrivialTypeSourceInfo(
20150b57cec5SDimitry Andric QualType::getFromOpaquePtr(copied_clang_type.GetOpaqueQualType()));
20160b57cec5SDimitry Andric
20170b57cec5SDimitry Andric if (!type_source_info)
20180b57cec5SDimitry Andric return;
20190b57cec5SDimitry Andric
20200b57cec5SDimitry Andric // Construct a typedef type because if "*this" is a templated type we can't
20210b57cec5SDimitry Andric // just return ClassTemplateSpecializationDecls in response to name queries.
20220b57cec5SDimitry Andric // Using a typedef makes this much more robust.
20230b57cec5SDimitry Andric
20240b57cec5SDimitry Andric TypedefDecl *typedef_decl = TypedefDecl::Create(
20250b57cec5SDimitry Andric *m_ast_context, m_ast_context->getTranslationUnitDecl(), SourceLocation(),
20260b57cec5SDimitry Andric SourceLocation(), context.m_decl_name.getAsIdentifierInfo(),
20270b57cec5SDimitry Andric type_source_info);
20280b57cec5SDimitry Andric
20290b57cec5SDimitry Andric if (!typedef_decl)
20300b57cec5SDimitry Andric return;
20310b57cec5SDimitry Andric
20320b57cec5SDimitry Andric context.AddNamedDecl(typedef_decl);
20330b57cec5SDimitry Andric }
20340b57cec5SDimitry Andric
AddOneType(NameSearchContext & context,const TypeFromUser & ut)20350b57cec5SDimitry Andric void ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
20365ffd83dbSDimitry Andric const TypeFromUser &ut) {
20370b57cec5SDimitry Andric CompilerType copied_clang_type = GuardedCopyType(ut);
20380b57cec5SDimitry Andric
20390b57cec5SDimitry Andric if (!copied_clang_type) {
204081ad6265SDimitry Andric Log *log = GetLog(LLDBLog::Expressions);
20410b57cec5SDimitry Andric
20425ffd83dbSDimitry Andric LLDB_LOG(log,
20435ffd83dbSDimitry Andric "ClangExpressionDeclMap::AddOneType - Couldn't import the type");
20440b57cec5SDimitry Andric
20450b57cec5SDimitry Andric return;
20460b57cec5SDimitry Andric }
20470b57cec5SDimitry Andric
20480b57cec5SDimitry Andric context.AddTypeDecl(copied_clang_type);
20490b57cec5SDimitry Andric }
2050