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