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