180814287SRaphael Isemann //===-- ClangExpressionDeclMap.cpp ----------------------------------------===//
24dbb271fSSean Callanan //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
64dbb271fSSean Callanan //
74dbb271fSSean Callanan //===----------------------------------------------------------------------===//
84dbb271fSSean Callanan
94dbb271fSSean Callanan #include "ClangExpressionDeclMap.h"
104dbb271fSSean Callanan
114dbb271fSSean Callanan #include "ClangASTSource.h"
128184b252SMichael Buch #include "ClangExpressionUtil.h"
138184b252SMichael Buch #include "ClangExpressionVariable.h"
144dbb271fSSean Callanan #include "ClangModulesDeclVendor.h"
154dbb271fSSean Callanan #include "ClangPersistentVariables.h"
168be30215SAlex Langford #include "ClangUtil.h"
174dbb271fSSean Callanan
188184b252SMichael Buch #include "NameSearchContext.h"
198be30215SAlex Langford #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
204dbb271fSSean Callanan #include "lldb/Core/Address.h"
214dbb271fSSean Callanan #include "lldb/Core/Module.h"
224dbb271fSSean Callanan #include "lldb/Core/ModuleSpec.h"
234dbb271fSSean Callanan #include "lldb/Core/ValueObjectConstResult.h"
244dbb271fSSean Callanan #include "lldb/Core/ValueObjectVariable.h"
25cb81e662SRaphael Isemann #include "lldb/Expression/DiagnosticManager.h"
264dbb271fSSean Callanan #include "lldb/Expression/Materializer.h"
27b9c1b51eSKate Stone #include "lldb/Symbol/CompileUnit.h"
284dbb271fSSean Callanan #include "lldb/Symbol/CompilerDecl.h"
294dbb271fSSean Callanan #include "lldb/Symbol/CompilerDeclContext.h"
304dbb271fSSean Callanan #include "lldb/Symbol/Function.h"
314dbb271fSSean Callanan #include "lldb/Symbol/ObjectFile.h"
324dbb271fSSean Callanan #include "lldb/Symbol/SymbolContext.h"
339293fc41SSiva Chandra #include "lldb/Symbol/SymbolFile.h"
344dbb271fSSean Callanan #include "lldb/Symbol/SymbolVendor.h"
354dbb271fSSean Callanan #include "lldb/Symbol/Type.h"
364dbb271fSSean Callanan #include "lldb/Symbol/TypeList.h"
374dbb271fSSean Callanan #include "lldb/Symbol/Variable.h"
384dbb271fSSean Callanan #include "lldb/Symbol/VariableList.h"
394dbb271fSSean Callanan #include "lldb/Target/ExecutionContext.h"
404dbb271fSSean Callanan #include "lldb/Target/Process.h"
414dbb271fSSean Callanan #include "lldb/Target/RegisterContext.h"
424dbb271fSSean Callanan #include "lldb/Target/StackFrame.h"
434dbb271fSSean Callanan #include "lldb/Target/Target.h"
444dbb271fSSean Callanan #include "lldb/Target/Thread.h"
4501c3243fSZachary Turner #include "lldb/Utility/Endian.h"
46c34698a8SPavel Labath #include "lldb/Utility/LLDBLog.h"
476f9e6901SZachary Turner #include "lldb/Utility/Log.h"
48d821c997SPavel Labath #include "lldb/Utility/RegisterValue.h"
4997206d57SZachary Turner #include "lldb/Utility/Status.h"
508184b252SMichael Buch #include "lldb/lldb-private-types.h"
51b9c1b51eSKate Stone #include "lldb/lldb-private.h"
52b9c1b51eSKate Stone #include "clang/AST/ASTConsumer.h"
53b9c1b51eSKate Stone #include "clang/AST/ASTContext.h"
5468e44239SSean Callanan #include "clang/AST/ASTImporter.h"
55b9c1b51eSKate Stone #include "clang/AST/Decl.h"
56b9c1b51eSKate Stone #include "clang/AST/DeclarationName.h"
5768e44239SSean Callanan #include "clang/AST/RecursiveASTVisitor.h"
584dbb271fSSean Callanan
594dbb271fSSean Callanan #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
60e0678ca5SAlex Langford #include "Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h"
61b5701710SAlex Langford #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
624dbb271fSSean Callanan
634dbb271fSSean Callanan using namespace lldb;
644dbb271fSSean Callanan using namespace lldb_private;
654dbb271fSSean Callanan using namespace clang;
664dbb271fSSean Callanan
6793c1b3caSPavel Labath static const char *g_lldb_local_vars_namespace_cstr = "$__lldb_local_vars";
6803ff5c86SSiva Chandra
698184b252SMichael Buch namespace {
708184b252SMichael Buch /// A lambda is represented by Clang as an artifical class whose
718184b252SMichael Buch /// members are the lambda captures. If we capture a 'this' pointer,
728184b252SMichael Buch /// the artifical class will contain a member variable named 'this'.
738184b252SMichael Buch /// The function returns a ValueObject for the captured 'this' if such
748184b252SMichael Buch /// member exists. If no 'this' was captured, return a nullptr.
GetCapturedThisValueObject(StackFrame * frame)758184b252SMichael Buch lldb::ValueObjectSP GetCapturedThisValueObject(StackFrame *frame) {
768184b252SMichael Buch assert(frame);
778184b252SMichael Buch
788184b252SMichael Buch if (auto thisValSP = frame->FindVariable(ConstString("this")))
798184b252SMichael Buch if (auto thisThisValSP =
808184b252SMichael Buch thisValSP->GetChildMemberWithName(ConstString("this"), true))
818184b252SMichael Buch return thisThisValSP;
828184b252SMichael Buch
838184b252SMichael Buch return nullptr;
848184b252SMichael Buch }
858184b252SMichael Buch } // namespace
868184b252SMichael Buch
ClangExpressionDeclMap(bool keep_result_in_memory,Materializer::PersistentVariableDelegate * result_delegate,const lldb::TargetSP & target,const std::shared_ptr<ClangASTImporter> & importer,ValueObject * ctx_obj)87b9c1b51eSKate Stone ClangExpressionDeclMap::ClangExpressionDeclMap(
88b9c1b51eSKate Stone bool keep_result_in_memory,
899fda9d21SSean Callanan Materializer::PersistentVariableDelegate *result_delegate,
907c9ebdd3SAlex Langford const lldb::TargetSP &target,
917c9ebdd3SAlex Langford const std::shared_ptr<ClangASTImporter> &importer, ValueObject *ctx_obj)
924aee81c4SRaphael Isemann : ClangASTSource(target, importer), m_found_entities(), m_struct_members(),
934aee81c4SRaphael Isemann m_keep_result_in_memory(keep_result_in_memory),
947ffc4681SKrasimir Georgiev m_result_delegate(result_delegate), m_ctx_obj(ctx_obj), m_parser_vars(),
957ffc4681SKrasimir Georgiev m_struct_vars() {
964dbb271fSSean Callanan EnableStructVars();
974dbb271fSSean Callanan }
984dbb271fSSean Callanan
~ClangExpressionDeclMap()99b9c1b51eSKate Stone ClangExpressionDeclMap::~ClangExpressionDeclMap() {
1004dbb271fSSean Callanan // Note: The model is now that the parser's AST context and all associated
1014dbb271fSSean Callanan // data does not vanish until the expression has been executed. This means
1024dbb271fSSean Callanan // that valuable lookup data (like namespaces) doesn't vanish, but
1034dbb271fSSean Callanan
1044dbb271fSSean Callanan DidParse();
1054dbb271fSSean Callanan DisableStructVars();
1064dbb271fSSean Callanan }
1074dbb271fSSean Callanan
WillParse(ExecutionContext & exe_ctx,Materializer * materializer)108b9c1b51eSKate Stone bool ClangExpressionDeclMap::WillParse(ExecutionContext &exe_ctx,
109b9c1b51eSKate Stone Materializer *materializer) {
1104dbb271fSSean Callanan EnableParserVars();
1114dbb271fSSean Callanan m_parser_vars->m_exe_ctx = exe_ctx;
1124dbb271fSSean Callanan
1134dbb271fSSean Callanan Target *target = exe_ctx.GetTargetPtr();
1144dbb271fSSean Callanan if (exe_ctx.GetFramePtr())
115b9c1b51eSKate Stone m_parser_vars->m_sym_ctx =
116b9c1b51eSKate Stone exe_ctx.GetFramePtr()->GetSymbolContext(lldb::eSymbolContextEverything);
117b9c1b51eSKate Stone else if (exe_ctx.GetThreadPtr() &&
118b9c1b51eSKate Stone exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(0))
119b9c1b51eSKate Stone m_parser_vars->m_sym_ctx =
120b9c1b51eSKate Stone exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(0)->GetSymbolContext(
121b9c1b51eSKate Stone lldb::eSymbolContextEverything);
122b9c1b51eSKate Stone else if (exe_ctx.GetProcessPtr()) {
1234dbb271fSSean Callanan m_parser_vars->m_sym_ctx.Clear(true);
1244dbb271fSSean Callanan m_parser_vars->m_sym_ctx.target_sp = exe_ctx.GetTargetSP();
125b9c1b51eSKate Stone } else if (target) {
1264dbb271fSSean Callanan m_parser_vars->m_sym_ctx.Clear(true);
1274dbb271fSSean Callanan m_parser_vars->m_sym_ctx.target_sp = exe_ctx.GetTargetSP();
1284dbb271fSSean Callanan }
1294dbb271fSSean Callanan
130b9c1b51eSKate Stone if (target) {
131b9c1b51eSKate Stone m_parser_vars->m_persistent_vars = llvm::cast<ClangPersistentVariables>(
132b9c1b51eSKate Stone target->GetPersistentExpressionStateForLanguage(eLanguageTypeC));
1334dbb271fSSean Callanan
134594308c7SRaphael Isemann if (!ScratchTypeSystemClang::GetForTarget(*target))
1354dbb271fSSean Callanan return false;
1364dbb271fSSean Callanan }
1374dbb271fSSean Callanan
1384dbb271fSSean Callanan m_parser_vars->m_target_info = GetTargetInfo();
1394dbb271fSSean Callanan m_parser_vars->m_materializer = materializer;
1404dbb271fSSean Callanan
1414dbb271fSSean Callanan return true;
1424dbb271fSSean Callanan }
1434dbb271fSSean Callanan
InstallCodeGenerator(clang::ASTConsumer * code_gen)144b9c1b51eSKate Stone void ClangExpressionDeclMap::InstallCodeGenerator(
145b9c1b51eSKate Stone clang::ASTConsumer *code_gen) {
1464dbb271fSSean Callanan assert(m_parser_vars);
1474dbb271fSSean Callanan m_parser_vars->m_code_gen = code_gen;
1484dbb271fSSean Callanan }
1494dbb271fSSean Callanan
InstallDiagnosticManager(DiagnosticManager & diag_manager)150cb81e662SRaphael Isemann void ClangExpressionDeclMap::InstallDiagnosticManager(
151cb81e662SRaphael Isemann DiagnosticManager &diag_manager) {
152cb81e662SRaphael Isemann assert(m_parser_vars);
153cb81e662SRaphael Isemann m_parser_vars->m_diagnostics = &diag_manager;
154cb81e662SRaphael Isemann }
155cb81e662SRaphael Isemann
DidParse()156b9c1b51eSKate Stone void ClangExpressionDeclMap::DidParse() {
157e9331a56SAdrian Prantl if (m_parser_vars && m_parser_vars->m_persistent_vars) {
1584dbb271fSSean Callanan for (size_t entity_index = 0, num_entities = m_found_entities.GetSize();
159b9c1b51eSKate Stone entity_index < num_entities; ++entity_index) {
160b9c1b51eSKate Stone ExpressionVariableSP var_sp(
161b9c1b51eSKate Stone m_found_entities.GetVariableAtIndex(entity_index));
1624dbb271fSSean Callanan if (var_sp)
163b9c1b51eSKate Stone llvm::cast<ClangExpressionVariable>(var_sp.get())
164b9c1b51eSKate Stone ->DisableParserVars(GetParserID());
1654dbb271fSSean Callanan }
1664dbb271fSSean Callanan
167b9c1b51eSKate Stone for (size_t pvar_index = 0,
168b9c1b51eSKate Stone num_pvars = m_parser_vars->m_persistent_vars->GetSize();
169b9c1b51eSKate Stone pvar_index < num_pvars; ++pvar_index) {
170b9c1b51eSKate Stone ExpressionVariableSP pvar_sp(
171b9c1b51eSKate Stone m_parser_vars->m_persistent_vars->GetVariableAtIndex(pvar_index));
172b9c1b51eSKate Stone if (ClangExpressionVariable *clang_var =
173b9c1b51eSKate Stone llvm::dyn_cast<ClangExpressionVariable>(pvar_sp.get()))
1744dbb271fSSean Callanan clang_var->DisableParserVars(GetParserID());
1754dbb271fSSean Callanan }
1764dbb271fSSean Callanan
1774dbb271fSSean Callanan DisableParserVars();
1784dbb271fSSean Callanan }
1794dbb271fSSean Callanan }
1804dbb271fSSean Callanan
1814dbb271fSSean Callanan // Interface for IRForTarget
1824dbb271fSSean Callanan
GetTargetInfo()183b9c1b51eSKate Stone ClangExpressionDeclMap::TargetInfo ClangExpressionDeclMap::GetTargetInfo() {
1844dbb271fSSean Callanan assert(m_parser_vars.get());
1854dbb271fSSean Callanan
1864dbb271fSSean Callanan TargetInfo ret;
1874dbb271fSSean Callanan
1884dbb271fSSean Callanan ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
1894dbb271fSSean Callanan
1904dbb271fSSean Callanan Process *process = exe_ctx.GetProcessPtr();
191b9c1b51eSKate Stone if (process) {
1924dbb271fSSean Callanan ret.byte_order = process->GetByteOrder();
1934dbb271fSSean Callanan ret.address_byte_size = process->GetAddressByteSize();
194b9c1b51eSKate Stone } else {
1954dbb271fSSean Callanan Target *target = exe_ctx.GetTargetPtr();
196b9c1b51eSKate Stone if (target) {
1974dbb271fSSean Callanan ret.byte_order = target->GetArchitecture().GetByteOrder();
1984dbb271fSSean Callanan ret.address_byte_size = target->GetArchitecture().GetAddressByteSize();
1994dbb271fSSean Callanan }
2004dbb271fSSean Callanan }
2014dbb271fSSean Callanan
2024dbb271fSSean Callanan return ret;
2034dbb271fSSean Callanan }
2044dbb271fSSean Callanan
DeportType(TypeSystemClang & target,TypeSystemClang & source,TypeFromParser parser_type)2056e3b0cc2SRaphael Isemann TypeFromUser ClangExpressionDeclMap::DeportType(TypeSystemClang &target,
2066e3b0cc2SRaphael Isemann TypeSystemClang &source,
20768e44239SSean Callanan TypeFromParser parser_type) {
20847e7ecddSRaphael Isemann assert(&target == GetScratchContext(*m_target));
20968e44239SSean Callanan assert((TypeSystem *)&source == parser_type.GetTypeSystem());
210f9f49d35SRaphael Isemann assert(&source.getASTContext() == m_ast_context);
21168e44239SSean Callanan
21275e8a91cSRaphael Isemann return TypeFromUser(m_ast_importer_sp->DeportType(target, parser_type));
21368e44239SSean Callanan }
21468e44239SSean Callanan
AddPersistentVariable(const NamedDecl * decl,ConstString name,TypeFromParser parser_type,bool is_result,bool is_lvalue)215b9c1b51eSKate Stone bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
2160e4c4821SAdrian Prantl ConstString name,
2174dbb271fSSean Callanan TypeFromParser parser_type,
2184dbb271fSSean Callanan bool is_result,
219b9c1b51eSKate Stone bool is_lvalue) {
2204dbb271fSSean Callanan assert(m_parser_vars.get());
2214dbb271fSSean Callanan
2226e3b0cc2SRaphael Isemann TypeSystemClang *ast =
2236e3b0cc2SRaphael Isemann llvm::dyn_cast_or_null<TypeSystemClang>(parser_type.GetTypeSystem());
2244dbb271fSSean Callanan if (ast == nullptr)
2254dbb271fSSean Callanan return false;
2264dbb271fSSean Callanan
227cb81e662SRaphael Isemann // Check if we already declared a persistent variable with the same name.
228cb81e662SRaphael Isemann if (lldb::ExpressionVariableSP conflicting_var =
229cb81e662SRaphael Isemann m_parser_vars->m_persistent_vars->GetVariable(name)) {
230cb81e662SRaphael Isemann std::string msg = llvm::formatv("redefinition of persistent variable '{0}'",
231cb81e662SRaphael Isemann name).str();
232cb81e662SRaphael Isemann m_parser_vars->m_diagnostics->AddDiagnostic(
233cb81e662SRaphael Isemann msg, DiagnosticSeverity::eDiagnosticSeverityError,
234cb81e662SRaphael Isemann DiagnosticOrigin::eDiagnosticOriginLLDB);
235cb81e662SRaphael Isemann return false;
236cb81e662SRaphael Isemann }
237cb81e662SRaphael Isemann
238b9c1b51eSKate Stone if (m_parser_vars->m_materializer && is_result) {
23997206d57SZachary Turner Status err;
2404dbb271fSSean Callanan
2414dbb271fSSean Callanan ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
2424dbb271fSSean Callanan Target *target = exe_ctx.GetTargetPtr();
2434dbb271fSSean Callanan if (target == nullptr)
2444dbb271fSSean Callanan return false;
2454dbb271fSSean Callanan
24647e7ecddSRaphael Isemann auto *clang_ast_context = GetScratchContext(*target);
2473031818aSAlex Langford if (!clang_ast_context)
2483031818aSAlex Langford return false;
2493031818aSAlex Langford
2503031818aSAlex Langford TypeFromUser user_type = DeportType(*clang_ast_context, *ast, parser_type);
2514dbb271fSSean Callanan
252b9c1b51eSKate Stone uint32_t offset = m_parser_vars->m_materializer->AddResultVariable(
253b9c1b51eSKate Stone user_type, is_lvalue, m_keep_result_in_memory, m_result_delegate, err);
2544dbb271fSSean Callanan
255b9c1b51eSKate Stone ClangExpressionVariable *var = new ClangExpressionVariable(
256b9c1b51eSKate Stone exe_ctx.GetBestExecutionContextScope(), name, user_type,
2574dbb271fSSean Callanan m_parser_vars->m_target_info.byte_order,
2584dbb271fSSean Callanan m_parser_vars->m_target_info.address_byte_size);
2594dbb271fSSean Callanan
2609301ec11SSean Callanan m_found_entities.AddNewlyConstructedVariable(var);
2614dbb271fSSean Callanan
2624dbb271fSSean Callanan var->EnableParserVars(GetParserID());
2634dbb271fSSean Callanan
264b9c1b51eSKate Stone ClangExpressionVariable::ParserVars *parser_vars =
265b9c1b51eSKate Stone var->GetParserVars(GetParserID());
2664dbb271fSSean Callanan
2674dbb271fSSean Callanan parser_vars->m_named_decl = decl;
2684dbb271fSSean Callanan
2694dbb271fSSean Callanan var->EnableJITVars(GetParserID());
2704dbb271fSSean Callanan
2714dbb271fSSean Callanan ClangExpressionVariable::JITVars *jit_vars = var->GetJITVars(GetParserID());
2724dbb271fSSean Callanan
2734dbb271fSSean Callanan jit_vars->m_offset = offset;
2744dbb271fSSean Callanan
2754dbb271fSSean Callanan return true;
2764dbb271fSSean Callanan }
2774dbb271fSSean Callanan
278a007a6d8SPavel Labath Log *log = GetLog(LLDBLog::Expressions);
2794dbb271fSSean Callanan ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
2804dbb271fSSean Callanan Target *target = exe_ctx.GetTargetPtr();
281248a1305SKonrad Kleine if (target == nullptr)
2824dbb271fSSean Callanan return false;
2834dbb271fSSean Callanan
28447e7ecddSRaphael Isemann TypeSystemClang *context = GetScratchContext(*target);
2853031818aSAlex Langford if (!context)
2863031818aSAlex Langford return false;
2874dbb271fSSean Callanan
28868e44239SSean Callanan TypeFromUser user_type = DeportType(*context, *ast, parser_type);
2894dbb271fSSean Callanan
290b9c1b51eSKate Stone if (!user_type.GetOpaqueQualType()) {
291fc0d11c9SRaphael Isemann LLDB_LOG(log, "Persistent variable's type wasn't copied successfully");
2924dbb271fSSean Callanan return false;
2934dbb271fSSean Callanan }
2944dbb271fSSean Callanan
2954dbb271fSSean Callanan if (!m_parser_vars->m_target_info.IsValid())
2964dbb271fSSean Callanan return false;
2974dbb271fSSean Callanan
298e9331a56SAdrian Prantl if (!m_parser_vars->m_persistent_vars)
299e9331a56SAdrian Prantl return false;
300e9331a56SAdrian Prantl
301b9c1b51eSKate Stone ClangExpressionVariable *var = llvm::cast<ClangExpressionVariable>(
302b9c1b51eSKate Stone m_parser_vars->m_persistent_vars
303b9c1b51eSKate Stone ->CreatePersistentVariable(
304b9c1b51eSKate Stone exe_ctx.GetBestExecutionContextScope(), name, user_type,
3054dbb271fSSean Callanan m_parser_vars->m_target_info.byte_order,
306b9c1b51eSKate Stone m_parser_vars->m_target_info.address_byte_size)
307b9c1b51eSKate Stone .get());
3084dbb271fSSean Callanan
3094dbb271fSSean Callanan if (!var)
3104dbb271fSSean Callanan return false;
3114dbb271fSSean Callanan
3124dbb271fSSean Callanan var->m_frozen_sp->SetHasCompleteType();
3134dbb271fSSean Callanan
3144dbb271fSSean Callanan if (is_result)
3154dbb271fSSean Callanan var->m_flags |= ClangExpressionVariable::EVNeedsFreezeDry;
3164dbb271fSSean Callanan else
317b9c1b51eSKate Stone var->m_flags |=
318b9c1b51eSKate Stone ClangExpressionVariable::EVKeepInTarget; // explicitly-declared
319b9c1b51eSKate Stone // persistent variables should
320b9c1b51eSKate Stone // persist
3214dbb271fSSean Callanan
322b9c1b51eSKate Stone if (is_lvalue) {
3234dbb271fSSean Callanan var->m_flags |= ClangExpressionVariable::EVIsProgramReference;
324b9c1b51eSKate Stone } else {
3254dbb271fSSean Callanan var->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated;
3264dbb271fSSean Callanan var->m_flags |= ClangExpressionVariable::EVNeedsAllocation;
3274dbb271fSSean Callanan }
3284dbb271fSSean Callanan
329b9c1b51eSKate Stone if (m_keep_result_in_memory) {
3304dbb271fSSean Callanan var->m_flags |= ClangExpressionVariable::EVKeepInTarget;
3314dbb271fSSean Callanan }
3324dbb271fSSean Callanan
333fc0d11c9SRaphael Isemann LLDB_LOG(log, "Created persistent variable with flags {0:x}", var->m_flags);
3344dbb271fSSean Callanan
3354dbb271fSSean Callanan var->EnableParserVars(GetParserID());
3364dbb271fSSean Callanan
337b9c1b51eSKate Stone ClangExpressionVariable::ParserVars *parser_vars =
338b9c1b51eSKate Stone var->GetParserVars(GetParserID());
3394dbb271fSSean Callanan
3404dbb271fSSean Callanan parser_vars->m_named_decl = decl;
3414dbb271fSSean Callanan
3424dbb271fSSean Callanan return true;
3434dbb271fSSean Callanan }
3444dbb271fSSean Callanan
AddValueToStruct(const NamedDecl * decl,ConstString name,llvm::Value * value,size_t size,lldb::offset_t alignment)345b9c1b51eSKate Stone bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl,
3460e4c4821SAdrian Prantl ConstString name,
347b9c1b51eSKate Stone llvm::Value *value, size_t size,
348b9c1b51eSKate Stone lldb::offset_t alignment) {
3494dbb271fSSean Callanan assert(m_struct_vars.get());
3504dbb271fSSean Callanan assert(m_parser_vars.get());
3514dbb271fSSean Callanan
3524dbb271fSSean Callanan bool is_persistent_variable = false;
3534dbb271fSSean Callanan
354a007a6d8SPavel Labath Log *log = GetLog(LLDBLog::Expressions);
3554dbb271fSSean Callanan
3564dbb271fSSean Callanan m_struct_vars->m_struct_laid_out = false;
3574dbb271fSSean Callanan
358b9c1b51eSKate Stone if (ClangExpressionVariable::FindVariableInList(m_struct_members, decl,
359b9c1b51eSKate Stone GetParserID()))
3604dbb271fSSean Callanan return true;
3614dbb271fSSean Callanan
362b9c1b51eSKate Stone ClangExpressionVariable *var(ClangExpressionVariable::FindVariableInList(
363b9c1b51eSKate Stone m_found_entities, decl, GetParserID()));
3644dbb271fSSean Callanan
365e9331a56SAdrian Prantl if (!var && m_parser_vars->m_persistent_vars) {
366b9c1b51eSKate Stone var = ClangExpressionVariable::FindVariableInList(
367b9c1b51eSKate Stone *m_parser_vars->m_persistent_vars, decl, GetParserID());
3684dbb271fSSean Callanan is_persistent_variable = true;
3694dbb271fSSean Callanan }
3704dbb271fSSean Callanan
3714dbb271fSSean Callanan if (!var)
3724dbb271fSSean Callanan return false;
3734dbb271fSSean Callanan
3749f175998SShafik Yaghmour LLDB_LOG(log, "Adding value for (NamedDecl*){0} [{1} - {2}] to the structure",
375fc0d11c9SRaphael Isemann decl, name, var->GetName());
3764dbb271fSSean Callanan
3774dbb271fSSean Callanan // We know entity->m_parser_vars is valid because we used a parser variable
3784dbb271fSSean Callanan // to find it
3794dbb271fSSean Callanan
380b9c1b51eSKate Stone ClangExpressionVariable::ParserVars *parser_vars =
381b9c1b51eSKate Stone llvm::cast<ClangExpressionVariable>(var)->GetParserVars(GetParserID());
3824dbb271fSSean Callanan
3834dbb271fSSean Callanan parser_vars->m_llvm_value = value;
3844dbb271fSSean Callanan
385b9c1b51eSKate Stone if (ClangExpressionVariable::JITVars *jit_vars =
386b9c1b51eSKate Stone llvm::cast<ClangExpressionVariable>(var)->GetJITVars(GetParserID())) {
3874dbb271fSSean Callanan // We already laid this out; do not touch
3884dbb271fSSean Callanan
389fc0d11c9SRaphael Isemann LLDB_LOG(log, "Already placed at {0:x}", jit_vars->m_offset);
3904dbb271fSSean Callanan }
3914dbb271fSSean Callanan
3924dbb271fSSean Callanan llvm::cast<ClangExpressionVariable>(var)->EnableJITVars(GetParserID());
3934dbb271fSSean Callanan
394b9c1b51eSKate Stone ClangExpressionVariable::JITVars *jit_vars =
395b9c1b51eSKate Stone llvm::cast<ClangExpressionVariable>(var)->GetJITVars(GetParserID());
3964dbb271fSSean Callanan
3974dbb271fSSean Callanan jit_vars->m_alignment = alignment;
3984dbb271fSSean Callanan jit_vars->m_size = size;
3994dbb271fSSean Callanan
4004dbb271fSSean Callanan m_struct_members.AddVariable(var->shared_from_this());
4014dbb271fSSean Callanan
402b9c1b51eSKate Stone if (m_parser_vars->m_materializer) {
4034dbb271fSSean Callanan uint32_t offset = 0;
4044dbb271fSSean Callanan
40597206d57SZachary Turner Status err;
4064dbb271fSSean Callanan
407b9c1b51eSKate Stone if (is_persistent_variable) {
4084dbb271fSSean Callanan ExpressionVariableSP var_sp(var->shared_from_this());
409b9c1b51eSKate Stone offset = m_parser_vars->m_materializer->AddPersistentVariable(
410b9c1b51eSKate Stone var_sp, nullptr, err);
411b9c1b51eSKate Stone } else {
4124dbb271fSSean Callanan if (const lldb_private::Symbol *sym = parser_vars->m_lldb_sym)
4134dbb271fSSean Callanan offset = m_parser_vars->m_materializer->AddSymbol(*sym, err);
4144dbb271fSSean Callanan else if (const RegisterInfo *reg_info = var->GetRegisterInfo())
4154dbb271fSSean Callanan offset = m_parser_vars->m_materializer->AddRegister(*reg_info, err);
4164dbb271fSSean Callanan else if (parser_vars->m_lldb_var)
417b9c1b51eSKate Stone offset = m_parser_vars->m_materializer->AddVariable(
418b9c1b51eSKate Stone parser_vars->m_lldb_var, err);
4198184b252SMichael Buch else if (parser_vars->m_lldb_valobj_provider) {
4208184b252SMichael Buch offset = m_parser_vars->m_materializer->AddValueObject(
4218184b252SMichael Buch name, parser_vars->m_lldb_valobj_provider, err);
4228184b252SMichael Buch }
4234dbb271fSSean Callanan }
4244dbb271fSSean Callanan
4254dbb271fSSean Callanan if (!err.Success())
4264dbb271fSSean Callanan return false;
4274dbb271fSSean Callanan
428fc0d11c9SRaphael Isemann LLDB_LOG(log, "Placed at {0:x}", offset);
4294dbb271fSSean Callanan
430b9c1b51eSKate Stone jit_vars->m_offset =
431b9c1b51eSKate Stone offset; // TODO DoStructLayout() should not change this.
4324dbb271fSSean Callanan }
4334dbb271fSSean Callanan
4344dbb271fSSean Callanan return true;
4354dbb271fSSean Callanan }
4364dbb271fSSean Callanan
DoStructLayout()437b9c1b51eSKate Stone bool ClangExpressionDeclMap::DoStructLayout() {
4384dbb271fSSean Callanan assert(m_struct_vars.get());
4394dbb271fSSean Callanan
4404dbb271fSSean Callanan if (m_struct_vars->m_struct_laid_out)
4414dbb271fSSean Callanan return true;
4424dbb271fSSean Callanan
4434dbb271fSSean Callanan if (!m_parser_vars->m_materializer)
4444dbb271fSSean Callanan return false;
4454dbb271fSSean Callanan
446b9c1b51eSKate Stone m_struct_vars->m_struct_alignment =
447b9c1b51eSKate Stone m_parser_vars->m_materializer->GetStructAlignment();
448b9c1b51eSKate Stone m_struct_vars->m_struct_size =
449b9c1b51eSKate Stone m_parser_vars->m_materializer->GetStructByteSize();
4504dbb271fSSean Callanan m_struct_vars->m_struct_laid_out = true;
4514dbb271fSSean Callanan return true;
4524dbb271fSSean Callanan }
4534dbb271fSSean Callanan
GetStructInfo(uint32_t & num_elements,size_t & size,lldb::offset_t & alignment)454b9c1b51eSKate Stone bool ClangExpressionDeclMap::GetStructInfo(uint32_t &num_elements, size_t &size,
455b9c1b51eSKate Stone lldb::offset_t &alignment) {
4564dbb271fSSean Callanan assert(m_struct_vars.get());
4574dbb271fSSean Callanan
4584dbb271fSSean Callanan if (!m_struct_vars->m_struct_laid_out)
4594dbb271fSSean Callanan return false;
4604dbb271fSSean Callanan
4614dbb271fSSean Callanan num_elements = m_struct_members.GetSize();
4624dbb271fSSean Callanan size = m_struct_vars->m_struct_size;
4634dbb271fSSean Callanan alignment = m_struct_vars->m_struct_alignment;
4644dbb271fSSean Callanan
4654dbb271fSSean Callanan return true;
4664dbb271fSSean Callanan }
4674dbb271fSSean Callanan
GetStructElement(const NamedDecl * & decl,llvm::Value * & value,lldb::offset_t & offset,ConstString & name,uint32_t index)468b9c1b51eSKate Stone bool ClangExpressionDeclMap::GetStructElement(const NamedDecl *&decl,
4694dbb271fSSean Callanan llvm::Value *&value,
4704dbb271fSSean Callanan lldb::offset_t &offset,
4714dbb271fSSean Callanan ConstString &name,
472b9c1b51eSKate Stone uint32_t index) {
4734dbb271fSSean Callanan assert(m_struct_vars.get());
4744dbb271fSSean Callanan
4754dbb271fSSean Callanan if (!m_struct_vars->m_struct_laid_out)
4764dbb271fSSean Callanan return false;
4774dbb271fSSean Callanan
4784dbb271fSSean Callanan if (index >= m_struct_members.GetSize())
4794dbb271fSSean Callanan return false;
4804dbb271fSSean Callanan
4814dbb271fSSean Callanan ExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(index));
4824dbb271fSSean Callanan
4834dbb271fSSean Callanan if (!member_sp)
4844dbb271fSSean Callanan return false;
4854dbb271fSSean Callanan
486b9c1b51eSKate Stone ClangExpressionVariable::ParserVars *parser_vars =
487b9c1b51eSKate Stone llvm::cast<ClangExpressionVariable>(member_sp.get())
488b9c1b51eSKate Stone ->GetParserVars(GetParserID());
489b9c1b51eSKate Stone ClangExpressionVariable::JITVars *jit_vars =
490b9c1b51eSKate Stone llvm::cast<ClangExpressionVariable>(member_sp.get())
491b9c1b51eSKate Stone ->GetJITVars(GetParserID());
4924dbb271fSSean Callanan
493b9c1b51eSKate Stone if (!parser_vars || !jit_vars || !member_sp->GetValueObject())
4944dbb271fSSean Callanan return false;
4954dbb271fSSean Callanan
4964dbb271fSSean Callanan decl = parser_vars->m_named_decl;
4974dbb271fSSean Callanan value = parser_vars->m_llvm_value;
4984dbb271fSSean Callanan offset = jit_vars->m_offset;
4994dbb271fSSean Callanan name = member_sp->GetName();
5004dbb271fSSean Callanan
5014dbb271fSSean Callanan return true;
5024dbb271fSSean Callanan }
5034dbb271fSSean Callanan
GetFunctionInfo(const NamedDecl * decl,uint64_t & ptr)504b9c1b51eSKate Stone bool ClangExpressionDeclMap::GetFunctionInfo(const NamedDecl *decl,
505b9c1b51eSKate Stone uint64_t &ptr) {
506b9c1b51eSKate Stone ClangExpressionVariable *entity(ClangExpressionVariable::FindVariableInList(
507b9c1b51eSKate Stone m_found_entities, decl, GetParserID()));
5084dbb271fSSean Callanan
5094dbb271fSSean Callanan if (!entity)
5104dbb271fSSean Callanan return false;
5114dbb271fSSean Callanan
51205097246SAdrian Prantl // We know m_parser_vars is valid since we searched for the variable by its
51305097246SAdrian Prantl // NamedDecl
5144dbb271fSSean Callanan
515b9c1b51eSKate Stone ClangExpressionVariable::ParserVars *parser_vars =
516b9c1b51eSKate Stone entity->GetParserVars(GetParserID());
5174dbb271fSSean Callanan
5184dbb271fSSean Callanan ptr = parser_vars->m_lldb_value.GetScalar().ULongLong();
5194dbb271fSSean Callanan
5204dbb271fSSean Callanan return true;
5214dbb271fSSean Callanan }
5224dbb271fSSean Callanan
GetSymbolAddress(Target & target,Process * process,ConstString name,lldb::SymbolType symbol_type,lldb_private::Module * module)523b9c1b51eSKate Stone addr_t ClangExpressionDeclMap::GetSymbolAddress(Target &target,
5244dbb271fSSean Callanan Process *process,
5250e4c4821SAdrian Prantl ConstString name,
5264dbb271fSSean Callanan lldb::SymbolType symbol_type,
527b9c1b51eSKate Stone lldb_private::Module *module) {
5284dbb271fSSean Callanan SymbolContextList sc_list;
5294dbb271fSSean Callanan
5304dbb271fSSean Callanan if (module)
5314dbb271fSSean Callanan module->FindSymbolsWithNameAndType(name, symbol_type, sc_list);
5324dbb271fSSean Callanan else
5334dbb271fSSean Callanan target.GetImages().FindSymbolsWithNameAndType(name, symbol_type, sc_list);
5344dbb271fSSean Callanan
5354dbb271fSSean Callanan const uint32_t num_matches = sc_list.GetSize();
5364dbb271fSSean Callanan addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
5374dbb271fSSean Callanan
538b9c1b51eSKate Stone for (uint32_t i = 0;
539b9c1b51eSKate Stone i < num_matches &&
540b9c1b51eSKate Stone (symbol_load_addr == 0 || symbol_load_addr == LLDB_INVALID_ADDRESS);
541b9c1b51eSKate Stone i++) {
5424dbb271fSSean Callanan SymbolContext sym_ctx;
5434dbb271fSSean Callanan sc_list.GetContextAtIndex(i, sym_ctx);
5444dbb271fSSean Callanan
5454dbb271fSSean Callanan const Address sym_address = sym_ctx.symbol->GetAddress();
5464dbb271fSSean Callanan
5474dbb271fSSean Callanan if (!sym_address.IsValid())
5484dbb271fSSean Callanan continue;
5494dbb271fSSean Callanan
550b9c1b51eSKate Stone switch (sym_ctx.symbol->GetType()) {
5514dbb271fSSean Callanan case eSymbolTypeCode:
5524dbb271fSSean Callanan case eSymbolTypeTrampoline:
5534dbb271fSSean Callanan symbol_load_addr = sym_address.GetCallableLoadAddress(&target);
5544dbb271fSSean Callanan break;
5554dbb271fSSean Callanan
5564dbb271fSSean Callanan case eSymbolTypeResolver:
5574dbb271fSSean Callanan symbol_load_addr = sym_address.GetCallableLoadAddress(&target, true);
5584dbb271fSSean Callanan break;
5594dbb271fSSean Callanan
560b9c1b51eSKate Stone case eSymbolTypeReExported: {
5614dbb271fSSean Callanan ConstString reexport_name = sym_ctx.symbol->GetReExportedSymbolName();
562b9c1b51eSKate Stone if (reexport_name) {
5634dbb271fSSean Callanan ModuleSP reexport_module_sp;
5644dbb271fSSean Callanan ModuleSpec reexport_module_spec;
565b9c1b51eSKate Stone reexport_module_spec.GetPlatformFileSpec() =
566b9c1b51eSKate Stone sym_ctx.symbol->GetReExportedSymbolSharedLibrary();
567b9c1b51eSKate Stone if (reexport_module_spec.GetPlatformFileSpec()) {
568b9c1b51eSKate Stone reexport_module_sp =
569b9c1b51eSKate Stone target.GetImages().FindFirstModule(reexport_module_spec);
570b9c1b51eSKate Stone if (!reexport_module_sp) {
571*1b4b12a3SNico Weber reexport_module_spec.GetPlatformFileSpec().GetDirectory().Clear();
572b9c1b51eSKate Stone reexport_module_sp =
573b9c1b51eSKate Stone target.GetImages().FindFirstModule(reexport_module_spec);
5744dbb271fSSean Callanan }
5754dbb271fSSean Callanan }
576b9c1b51eSKate Stone symbol_load_addr = GetSymbolAddress(
577b9c1b51eSKate Stone target, process, sym_ctx.symbol->GetReExportedSymbolName(),
578b9c1b51eSKate Stone symbol_type, reexport_module_sp.get());
5794dbb271fSSean Callanan }
580b9c1b51eSKate Stone } break;
5814dbb271fSSean Callanan
5824dbb271fSSean Callanan case eSymbolTypeData:
5834dbb271fSSean Callanan case eSymbolTypeRuntime:
5844dbb271fSSean Callanan case eSymbolTypeVariable:
5854dbb271fSSean Callanan case eSymbolTypeLocal:
5864dbb271fSSean Callanan case eSymbolTypeParam:
5874dbb271fSSean Callanan case eSymbolTypeInvalid:
5884dbb271fSSean Callanan case eSymbolTypeAbsolute:
5894dbb271fSSean Callanan case eSymbolTypeException:
5904dbb271fSSean Callanan case eSymbolTypeSourceFile:
5914dbb271fSSean Callanan case eSymbolTypeHeaderFile:
5924dbb271fSSean Callanan case eSymbolTypeObjectFile:
5934dbb271fSSean Callanan case eSymbolTypeCommonBlock:
5944dbb271fSSean Callanan case eSymbolTypeBlock:
5954dbb271fSSean Callanan case eSymbolTypeVariableType:
5964dbb271fSSean Callanan case eSymbolTypeLineEntry:
5974dbb271fSSean Callanan case eSymbolTypeLineHeader:
5984dbb271fSSean Callanan case eSymbolTypeScopeBegin:
5994dbb271fSSean Callanan case eSymbolTypeScopeEnd:
6004dbb271fSSean Callanan case eSymbolTypeAdditional:
6014dbb271fSSean Callanan case eSymbolTypeCompiler:
6024dbb271fSSean Callanan case eSymbolTypeInstrumentation:
6034dbb271fSSean Callanan case eSymbolTypeUndefined:
6044dbb271fSSean Callanan case eSymbolTypeObjCClass:
6054dbb271fSSean Callanan case eSymbolTypeObjCMetaClass:
6064dbb271fSSean Callanan case eSymbolTypeObjCIVar:
6074dbb271fSSean Callanan symbol_load_addr = sym_address.GetLoadAddress(&target);
6084dbb271fSSean Callanan break;
6094dbb271fSSean Callanan }
6104dbb271fSSean Callanan }
6114dbb271fSSean Callanan
612b9c1b51eSKate Stone if (symbol_load_addr == LLDB_INVALID_ADDRESS && process) {
613e823bbe8SAlex Langford ObjCLanguageRuntime *runtime = ObjCLanguageRuntime::Get(*process);
6144dbb271fSSean Callanan
615b9c1b51eSKate Stone if (runtime) {
6164dbb271fSSean Callanan symbol_load_addr = runtime->LookupRuntimeSymbol(name);
6174dbb271fSSean Callanan }
6184dbb271fSSean Callanan }
6194dbb271fSSean Callanan
6204dbb271fSSean Callanan return symbol_load_addr;
6214dbb271fSSean Callanan }
6224dbb271fSSean Callanan
GetSymbolAddress(ConstString name,lldb::SymbolType symbol_type)6230e4c4821SAdrian Prantl addr_t ClangExpressionDeclMap::GetSymbolAddress(ConstString name,
624b9c1b51eSKate Stone lldb::SymbolType symbol_type) {
6254dbb271fSSean Callanan assert(m_parser_vars.get());
6264dbb271fSSean Callanan
6274dbb271fSSean Callanan if (!m_parser_vars->m_exe_ctx.GetTargetPtr())
6284dbb271fSSean Callanan return false;
6294dbb271fSSean Callanan
630b9c1b51eSKate Stone return GetSymbolAddress(m_parser_vars->m_exe_ctx.GetTargetRef(),
631b9c1b51eSKate Stone m_parser_vars->m_exe_ctx.GetProcessPtr(), name,
632b9c1b51eSKate Stone symbol_type);
6334dbb271fSSean Callanan }
6344dbb271fSSean Callanan
FindGlobalVariable(Target & target,ModuleSP & module,ConstString name,const CompilerDeclContext & namespace_decl)635b9c1b51eSKate Stone lldb::VariableSP ClangExpressionDeclMap::FindGlobalVariable(
6360e4c4821SAdrian Prantl Target &target, ModuleSP &module, ConstString name,
6373d7b591dSRaphael Isemann const CompilerDeclContext &namespace_decl) {
6384dbb271fSSean Callanan VariableList vars;
6394dbb271fSSean Callanan
6404dbb271fSSean Callanan if (module && namespace_decl)
6413d7b591dSRaphael Isemann module->FindGlobalVariables(name, namespace_decl, -1, vars);
6424dbb271fSSean Callanan else
64334cda14bSPavel Labath target.GetImages().FindGlobalVariables(name, -1, vars);
6444dbb271fSSean Callanan
645b6c29d9dSRaphael Isemann if (vars.GetSize() == 0)
6464dbb271fSSean Callanan return VariableSP();
647b6c29d9dSRaphael Isemann return vars.GetVariableAtIndex(0);
6484dbb271fSSean Callanan }
6494dbb271fSSean Callanan
GetTypeSystemClang()6506e3b0cc2SRaphael Isemann TypeSystemClang *ClangExpressionDeclMap::GetTypeSystemClang() {
65103ff5c86SSiva Chandra StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
65203ff5c86SSiva Chandra if (frame == nullptr)
65303ff5c86SSiva Chandra return nullptr;
65403ff5c86SSiva Chandra
655b9c1b51eSKate Stone SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
656b9c1b51eSKate Stone lldb::eSymbolContextBlock);
65703ff5c86SSiva Chandra if (sym_ctx.block == nullptr)
65803ff5c86SSiva Chandra return nullptr;
65903ff5c86SSiva Chandra
66003ff5c86SSiva Chandra CompilerDeclContext frame_decl_context = sym_ctx.block->GetDeclContext();
66103ff5c86SSiva Chandra if (!frame_decl_context)
66203ff5c86SSiva Chandra return nullptr;
66303ff5c86SSiva Chandra
6646e3b0cc2SRaphael Isemann return llvm::dyn_cast_or_null<TypeSystemClang>(
665b9c1b51eSKate Stone frame_decl_context.GetTypeSystem());
66603ff5c86SSiva Chandra }
66703ff5c86SSiva Chandra
6684dbb271fSSean Callanan // Interface for ClangASTSource
6694dbb271fSSean Callanan
FindExternalVisibleDecls(NameSearchContext & context)670b9c1b51eSKate Stone void ClangExpressionDeclMap::FindExternalVisibleDecls(
671b9c1b51eSKate Stone NameSearchContext &context) {
6724dbb271fSSean Callanan assert(m_ast_context);
6734dbb271fSSean Callanan
6744dbb271fSSean Callanan const ConstString name(context.m_decl_name.getAsString().c_str());
6754dbb271fSSean Callanan
676a007a6d8SPavel Labath Log *log = GetLog(LLDBLog::Expressions);
6774dbb271fSSean Callanan
678b9c1b51eSKate Stone if (log) {
6794dbb271fSSean Callanan if (!context.m_decl_context)
680fc0d11c9SRaphael Isemann LLDB_LOG(log,
681e657a1ebSRaphael Isemann "ClangExpressionDeclMap::FindExternalVisibleDecls for "
682fc0d11c9SRaphael Isemann "'{0}' in a NULL DeclContext",
683fc0d11c9SRaphael Isemann name);
684b9c1b51eSKate Stone else if (const NamedDecl *context_named_decl =
685b9c1b51eSKate Stone dyn_cast<NamedDecl>(context.m_decl_context))
686fc0d11c9SRaphael Isemann LLDB_LOG(log,
687e657a1ebSRaphael Isemann "ClangExpressionDeclMap::FindExternalVisibleDecls for "
688fc0d11c9SRaphael Isemann "'{0}' in '{1}'",
689fc0d11c9SRaphael Isemann name, context_named_decl->getNameAsString());
6904dbb271fSSean Callanan else
691fc0d11c9SRaphael Isemann LLDB_LOG(log,
692e657a1ebSRaphael Isemann "ClangExpressionDeclMap::FindExternalVisibleDecls for "
693fc0d11c9SRaphael Isemann "'{0}' in a '{1}'",
694fc0d11c9SRaphael Isemann name, context.m_decl_context->getDeclKindName());
6954dbb271fSSean Callanan }
6964dbb271fSSean Callanan
697b9c1b51eSKate Stone if (const NamespaceDecl *namespace_context =
698b9c1b51eSKate Stone dyn_cast<NamespaceDecl>(context.m_decl_context)) {
699b9c1b51eSKate Stone if (namespace_context->getName().str() ==
700b9c1b51eSKate Stone std::string(g_lldb_local_vars_namespace_cstr)) {
70173951a11SRaphael Isemann CompilerDeclContext compiler_decl_ctx =
70273951a11SRaphael Isemann m_clang_ast_context->CreateDeclContext(
70373951a11SRaphael Isemann const_cast<clang::DeclContext *>(context.m_decl_context));
704e657a1ebSRaphael Isemann FindExternalVisibleDecls(context, lldb::ModuleSP(), compiler_decl_ctx);
70503ff5c86SSiva Chandra return;
70603ff5c86SSiva Chandra }
70703ff5c86SSiva Chandra
708b9c1b51eSKate Stone ClangASTImporter::NamespaceMapSP namespace_map =
7091ccc7029SRaphael Isemann m_ast_importer_sp->GetNamespaceMap(namespace_context);
71068e44239SSean Callanan
71168e44239SSean Callanan if (!namespace_map)
71268e44239SSean Callanan return;
7134dbb271fSSean Callanan
714fc0d11c9SRaphael Isemann LLDB_LOGV(log, " CEDM::FEVD Inspecting (NamespaceMap*){0:x} ({1} entries)",
715fc0d11c9SRaphael Isemann namespace_map.get(), namespace_map->size());
7164dbb271fSSean Callanan
717aa04ce76SRaphael Isemann for (ClangASTImporter::NamespaceMapItem &n : *namespace_map) {
718fc0d11c9SRaphael Isemann LLDB_LOG(log, " CEDM::FEVD Searching namespace {0} in module {1}",
719aa04ce76SRaphael Isemann n.second.GetName(), n.first->GetFileSpec().GetFilename());
7204dbb271fSSean Callanan
721aa04ce76SRaphael Isemann FindExternalVisibleDecls(context, n.first, n.second);
7224dbb271fSSean Callanan }
723b9c1b51eSKate Stone } else if (isa<TranslationUnitDecl>(context.m_decl_context)) {
7244dbb271fSSean Callanan CompilerDeclContext namespace_decl;
7254dbb271fSSean Callanan
726fc0d11c9SRaphael Isemann LLDB_LOG(log, " CEDM::FEVD Searching the root namespace");
7274dbb271fSSean Callanan
728e657a1ebSRaphael Isemann FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl);
7294dbb271fSSean Callanan }
7304dbb271fSSean Callanan
7314dbb271fSSean Callanan ClangASTSource::FindExternalVisibleDecls(context);
7324dbb271fSSean Callanan }
7334dbb271fSSean Callanan
MaybeRegisterFunctionBody(FunctionDecl * copied_function_decl)734c34478f5SRaphael Isemann void ClangExpressionDeclMap::MaybeRegisterFunctionBody(
735c34478f5SRaphael Isemann FunctionDecl *copied_function_decl) {
736c34478f5SRaphael Isemann if (copied_function_decl->getBody() && m_parser_vars->m_code_gen) {
737c34478f5SRaphael Isemann clang::DeclGroupRef decl_group_ref(copied_function_decl);
738c34478f5SRaphael Isemann m_parser_vars->m_code_gen->HandleTopLevelDecl(decl_group_ref);
739c34478f5SRaphael Isemann }
740c34478f5SRaphael Isemann }
741c34478f5SRaphael Isemann
GetPersistentDecl(ConstString name)742d8a31949SRaphael Isemann clang::NamedDecl *ClangExpressionDeclMap::GetPersistentDecl(ConstString name) {
7434aee81c4SRaphael Isemann if (!m_parser_vars)
744d8a31949SRaphael Isemann return nullptr;
745c34478f5SRaphael Isemann Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
746c34478f5SRaphael Isemann if (!target)
747d8a31949SRaphael Isemann return nullptr;
748c34478f5SRaphael Isemann
749594308c7SRaphael Isemann ScratchTypeSystemClang::GetForTarget(*target);
750c34478f5SRaphael Isemann
751e9331a56SAdrian Prantl if (!m_parser_vars->m_persistent_vars)
752e9331a56SAdrian Prantl return nullptr;
753d8a31949SRaphael Isemann return m_parser_vars->m_persistent_vars->GetPersistentDecl(name);
754d8a31949SRaphael Isemann }
755d8a31949SRaphael Isemann
SearchPersistenDecls(NameSearchContext & context,const ConstString name)756d8a31949SRaphael Isemann void ClangExpressionDeclMap::SearchPersistenDecls(NameSearchContext &context,
757e657a1ebSRaphael Isemann const ConstString name) {
758a007a6d8SPavel Labath Log *log = GetLog(LLDBLog::Expressions);
759d8a31949SRaphael Isemann
760d8a31949SRaphael Isemann NamedDecl *persistent_decl = GetPersistentDecl(name);
761c34478f5SRaphael Isemann
762c34478f5SRaphael Isemann if (!persistent_decl)
763c34478f5SRaphael Isemann return;
764c34478f5SRaphael Isemann
765c34478f5SRaphael Isemann Decl *parser_persistent_decl = CopyDecl(persistent_decl);
766c34478f5SRaphael Isemann
767c34478f5SRaphael Isemann if (!parser_persistent_decl)
768c34478f5SRaphael Isemann return;
769c34478f5SRaphael Isemann
770c34478f5SRaphael Isemann NamedDecl *parser_named_decl = dyn_cast<NamedDecl>(parser_persistent_decl);
771c34478f5SRaphael Isemann
772c34478f5SRaphael Isemann if (!parser_named_decl)
773c34478f5SRaphael Isemann return;
774c34478f5SRaphael Isemann
775c34478f5SRaphael Isemann if (clang::FunctionDecl *parser_function_decl =
776c34478f5SRaphael Isemann llvm::dyn_cast<clang::FunctionDecl>(parser_named_decl)) {
777c34478f5SRaphael Isemann MaybeRegisterFunctionBody(parser_function_decl);
778c34478f5SRaphael Isemann }
779c34478f5SRaphael Isemann
7809f175998SShafik Yaghmour LLDB_LOG(log, " CEDM::FEVD Found persistent decl {0}", name);
781c34478f5SRaphael Isemann
782c34478f5SRaphael Isemann context.AddNamedDecl(parser_named_decl);
783c34478f5SRaphael Isemann }
7844dbb271fSSean Callanan
LookUpLldbClass(NameSearchContext & context)785e657a1ebSRaphael Isemann void ClangExpressionDeclMap::LookUpLldbClass(NameSearchContext &context) {
786a007a6d8SPavel Labath Log *log = GetLog(LLDBLog::Expressions);
7874dbb271fSSean Callanan
7884dbb271fSSean Callanan StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
7894dbb271fSSean Callanan SymbolContext sym_ctx;
7904dbb271fSSean Callanan if (frame != nullptr)
791b9c1b51eSKate Stone sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
792b9c1b51eSKate Stone lldb::eSymbolContextBlock);
793b3a36df3SSean Callanan
79440624a08SAleksandr Urakov if (m_ctx_obj) {
79540624a08SAleksandr Urakov Status status;
79640624a08SAleksandr Urakov lldb::ValueObjectSP ctx_obj_ptr = m_ctx_obj->AddressOf(status);
79740624a08SAleksandr Urakov if (!ctx_obj_ptr || status.Fail())
79840624a08SAleksandr Urakov return;
79940624a08SAleksandr Urakov
800834708a6SRaphael Isemann AddContextClassType(context, TypeFromUser(m_ctx_obj->GetCompilerType()));
80140624a08SAleksandr Urakov return;
80240624a08SAleksandr Urakov }
80340624a08SAleksandr Urakov
8044dbb271fSSean Callanan // Clang is looking for the type of "this"
8054dbb271fSSean Callanan
806248a1305SKonrad Kleine if (frame == nullptr)
8074dbb271fSSean Callanan return;
8084dbb271fSSean Callanan
8094dbb271fSSean Callanan // Find the block that defines the function represented by "sym_ctx"
8104dbb271fSSean Callanan Block *function_block = sym_ctx.GetFunctionBlock();
8114dbb271fSSean Callanan
8124dbb271fSSean Callanan if (!function_block)
8134dbb271fSSean Callanan return;
8144dbb271fSSean Callanan
8154dbb271fSSean Callanan CompilerDeclContext function_decl_ctx = function_block->GetDeclContext();
8164dbb271fSSean Callanan
8174dbb271fSSean Callanan if (!function_decl_ctx)
8184dbb271fSSean Callanan return;
8194dbb271fSSean Callanan
820b9c1b51eSKate Stone clang::CXXMethodDecl *method_decl =
8216e3b0cc2SRaphael Isemann TypeSystemClang::DeclContextGetAsCXXMethodDecl(function_decl_ctx);
8224dbb271fSSean Callanan
823b9c1b51eSKate Stone if (method_decl) {
8248184b252SMichael Buch if (auto capturedThis = GetCapturedThisValueObject(frame)) {
8258184b252SMichael Buch // We're inside a lambda and we captured a 'this'.
8268184b252SMichael Buch // Import the outer class's AST instead of the
8278184b252SMichael Buch // (unnamed) lambda structure AST so unqualified
8288184b252SMichael Buch // member lookups are understood by the Clang parser.
8298184b252SMichael Buch //
8308184b252SMichael Buch // If we're in a lambda which didn't capture 'this',
8318184b252SMichael Buch // $__lldb_class will correspond to the lambda closure
8328184b252SMichael Buch // AST and references to captures will resolve like
8338184b252SMichael Buch // regular member varaiable accesses do.
8348184b252SMichael Buch TypeFromUser pointee_type =
8358184b252SMichael Buch capturedThis->GetCompilerType().GetPointeeType();
8368184b252SMichael Buch
8378184b252SMichael Buch LLDB_LOG(log,
8388184b252SMichael Buch " CEDM::FEVD Adding captured type ({0} for"
8398184b252SMichael Buch " $__lldb_class: {1}",
8408184b252SMichael Buch capturedThis->GetTypeName(), capturedThis->GetName());
8418184b252SMichael Buch
8428184b252SMichael Buch AddContextClassType(context, pointee_type);
8438184b252SMichael Buch return;
8448184b252SMichael Buch }
8458184b252SMichael Buch
8464dbb271fSSean Callanan clang::CXXRecordDecl *class_decl = method_decl->getParent();
8474dbb271fSSean Callanan
8484dbb271fSSean Callanan QualType class_qual_type(class_decl->getTypeForDecl(), 0);
8494dbb271fSSean Callanan
850b036f557SRaphael Isemann TypeFromUser class_user_type(class_qual_type.getAsOpaquePtr(),
851b036f557SRaphael Isemann function_decl_ctx.GetTypeSystem());
8524dbb271fSSean Callanan
853f000de87SAdrian Prantl LLDB_LOG(log, " CEDM::FEVD Adding type for $__lldb_class: {0}",
854e657a1ebSRaphael Isemann class_qual_type.getAsString());
8554dbb271fSSean Callanan
8564125b462SRaphael Isemann AddContextClassType(context, class_user_type);
857e7cc833dSRaphael Isemann return;
858e7cc833dSRaphael Isemann }
859e7cc833dSRaphael Isemann
86005097246SAdrian Prantl // This branch will get hit if we are executing code in the context of
86105097246SAdrian Prantl // a function that claims to have an object pointer (through
86205097246SAdrian Prantl // DW_AT_object_pointer?) but is not formally a method of the class.
86305097246SAdrian Prantl // In that case, just look up the "this" variable in the current scope
86405097246SAdrian Prantl // and use its type.
865b9c1b51eSKate Stone // FIXME: This code is formally correct, but clang doesn't currently
866b9c1b51eSKate Stone // emit DW_AT_object_pointer
8674dbb271fSSean Callanan // for C++ so it hasn't actually been tested.
8684dbb271fSSean Callanan
8694dbb271fSSean Callanan VariableList *vars = frame->GetVariableList(false);
8704dbb271fSSean Callanan
8714dbb271fSSean Callanan lldb::VariableSP this_var = vars->FindVariable(ConstString("this"));
8724dbb271fSSean Callanan
873b9c1b51eSKate Stone if (this_var && this_var->IsInScope(frame) &&
874b9c1b51eSKate Stone this_var->LocationIsValidForFrame(frame)) {
8754dbb271fSSean Callanan Type *this_type = this_var->GetType();
8764dbb271fSSean Callanan
8774dbb271fSSean Callanan if (!this_type)
8784dbb271fSSean Callanan return;
8794dbb271fSSean Callanan
880b9c1b51eSKate Stone TypeFromUser pointee_type =
881b9c1b51eSKate Stone this_type->GetForwardCompilerType().GetPointeeType();
8824dbb271fSSean Callanan
883f000de87SAdrian Prantl LLDB_LOG(log, " FEVD Adding type for $__lldb_class: {0}",
8847a6588abSRaphael Isemann ClangUtil::GetQualType(pointee_type).getAsString());
8854dbb271fSSean Callanan
886834708a6SRaphael Isemann AddContextClassType(context, pointee_type);
8874dbb271fSSean Callanan }
8884dbb271fSSean Callanan }
8894dbb271fSSean Callanan
LookUpLldbObjCClass(NameSearchContext & context)890e657a1ebSRaphael Isemann void ClangExpressionDeclMap::LookUpLldbObjCClass(NameSearchContext &context) {
891a007a6d8SPavel Labath Log *log = GetLog(LLDBLog::Expressions);
892e7cc833dSRaphael Isemann
893e7cc833dSRaphael Isemann StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
894e7cc833dSRaphael Isemann
89540624a08SAleksandr Urakov if (m_ctx_obj) {
89640624a08SAleksandr Urakov Status status;
89740624a08SAleksandr Urakov lldb::ValueObjectSP ctx_obj_ptr = m_ctx_obj->AddressOf(status);
89840624a08SAleksandr Urakov if (!ctx_obj_ptr || status.Fail())
89940624a08SAleksandr Urakov return;
90040624a08SAleksandr Urakov
901e657a1ebSRaphael Isemann AddOneType(context, TypeFromUser(m_ctx_obj->GetCompilerType()));
90240624a08SAleksandr Urakov return;
90340624a08SAleksandr Urakov }
90440624a08SAleksandr Urakov
9054dbb271fSSean Callanan // Clang is looking for the type of "*self"
9064dbb271fSSean Callanan
9074dbb271fSSean Callanan if (!frame)
9084dbb271fSSean Callanan return;
9094dbb271fSSean Callanan
91051ad025fSRaphael Isemann SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
91151ad025fSRaphael Isemann lldb::eSymbolContextBlock);
9124dbb271fSSean Callanan
9134dbb271fSSean Callanan // Find the block that defines the function represented by "sym_ctx"
9144dbb271fSSean Callanan Block *function_block = sym_ctx.GetFunctionBlock();
9154dbb271fSSean Callanan
9164dbb271fSSean Callanan if (!function_block)
9174dbb271fSSean Callanan return;
9184dbb271fSSean Callanan
9194dbb271fSSean Callanan CompilerDeclContext function_decl_ctx = function_block->GetDeclContext();
9204dbb271fSSean Callanan
9214dbb271fSSean Callanan if (!function_decl_ctx)
9224dbb271fSSean Callanan return;
9234dbb271fSSean Callanan
924b9c1b51eSKate Stone clang::ObjCMethodDecl *method_decl =
9256e3b0cc2SRaphael Isemann TypeSystemClang::DeclContextGetAsObjCMethodDecl(function_decl_ctx);
9264dbb271fSSean Callanan
927b9c1b51eSKate Stone if (method_decl) {
9284dbb271fSSean Callanan ObjCInterfaceDecl *self_interface = method_decl->getClassInterface();
9294dbb271fSSean Callanan
9304dbb271fSSean Callanan if (!self_interface)
9314dbb271fSSean Callanan return;
9324dbb271fSSean Callanan
9334dbb271fSSean Callanan const clang::Type *interface_type = self_interface->getTypeForDecl();
9344dbb271fSSean Callanan
9354dbb271fSSean Callanan if (!interface_type)
936b9c1b51eSKate Stone return; // This is unlikely, but we have seen crashes where this
937b9c1b51eSKate Stone // occurred
9384dbb271fSSean Callanan
939b036f557SRaphael Isemann TypeFromUser class_user_type(QualType(interface_type, 0).getAsOpaquePtr(),
940b036f557SRaphael Isemann function_decl_ctx.GetTypeSystem());
9414dbb271fSSean Callanan
9427a6588abSRaphael Isemann LLDB_LOG(log, " FEVD[{0}] Adding type for $__lldb_objc_class: {1}",
943e657a1ebSRaphael Isemann ClangUtil::ToString(interface_type));
9444dbb271fSSean Callanan
945e657a1ebSRaphael Isemann AddOneType(context, class_user_type);
9464dbb271fSSean Callanan return;
94751ad025fSRaphael Isemann }
94805097246SAdrian Prantl // This branch will get hit if we are executing code in the context of
94905097246SAdrian Prantl // a function that claims to have an object pointer (through
95005097246SAdrian Prantl // DW_AT_object_pointer?) but is not formally a method of the class.
95105097246SAdrian Prantl // In that case, just look up the "self" variable in the current scope
95205097246SAdrian Prantl // and use its type.
9534dbb271fSSean Callanan
9544dbb271fSSean Callanan VariableList *vars = frame->GetVariableList(false);
9554dbb271fSSean Callanan
9564dbb271fSSean Callanan lldb::VariableSP self_var = vars->FindVariable(ConstString("self"));
9574dbb271fSSean Callanan
9581e0d3954SRaphael Isemann if (!self_var)
9591e0d3954SRaphael Isemann return;
9601e0d3954SRaphael Isemann if (!self_var->IsInScope(frame))
9611e0d3954SRaphael Isemann return;
9621e0d3954SRaphael Isemann if (!self_var->LocationIsValidForFrame(frame))
9631e0d3954SRaphael Isemann return;
9641e0d3954SRaphael Isemann
9654dbb271fSSean Callanan Type *self_type = self_var->GetType();
9664dbb271fSSean Callanan
9674dbb271fSSean Callanan if (!self_type)
9684dbb271fSSean Callanan return;
9694dbb271fSSean Callanan
9704dbb271fSSean Callanan CompilerType self_clang_type = self_type->GetFullCompilerType();
9714dbb271fSSean Callanan
9726e3b0cc2SRaphael Isemann if (TypeSystemClang::IsObjCClassType(self_clang_type)) {
9734dbb271fSSean Callanan return;
9741e0d3954SRaphael Isemann }
9756e3b0cc2SRaphael Isemann if (!TypeSystemClang::IsObjCObjectPointerType(self_clang_type))
9761e0d3954SRaphael Isemann return;
9774dbb271fSSean Callanan self_clang_type = self_clang_type.GetPointeeType();
9784dbb271fSSean Callanan
9794dbb271fSSean Callanan if (!self_clang_type)
9804dbb271fSSean Callanan return;
9814dbb271fSSean Callanan
9827a6588abSRaphael Isemann LLDB_LOG(log, " FEVD[{0}] Adding type for $__lldb_objc_class: {1}",
983e657a1ebSRaphael Isemann ClangUtil::ToString(self_type->GetFullCompilerType()));
9844dbb271fSSean Callanan
9854dbb271fSSean Callanan TypeFromUser class_user_type(self_clang_type);
9864dbb271fSSean Callanan
987e657a1ebSRaphael Isemann AddOneType(context, class_user_type);
9884dbb271fSSean Callanan }
9894dbb271fSSean Callanan
LookupLocalVarNamespace(SymbolContext & sym_ctx,NameSearchContext & name_context)990337151f4SRaphael Isemann void ClangExpressionDeclMap::LookupLocalVarNamespace(
9911e0d3954SRaphael Isemann SymbolContext &sym_ctx, NameSearchContext &name_context) {
9921e0d3954SRaphael Isemann if (sym_ctx.block == nullptr)
9931e0d3954SRaphael Isemann return;
994337151f4SRaphael Isemann
9951e0d3954SRaphael Isemann CompilerDeclContext frame_decl_context = sym_ctx.block->GetDeclContext();
9961e0d3954SRaphael Isemann if (!frame_decl_context)
9971e0d3954SRaphael Isemann return;
9981e0d3954SRaphael Isemann
9996e3b0cc2SRaphael Isemann TypeSystemClang *frame_ast = llvm::dyn_cast_or_null<TypeSystemClang>(
1000337151f4SRaphael Isemann frame_decl_context.GetTypeSystem());
10011e0d3954SRaphael Isemann if (!frame_ast)
10021e0d3954SRaphael Isemann return;
1003337151f4SRaphael Isemann
1004bc7f1df6SRaphael Isemann clang::NamespaceDecl *namespace_decl =
1005bc7f1df6SRaphael Isemann m_clang_ast_context->GetUniqueNamespaceDeclaration(
1006143d507cSAdrian Prantl g_lldb_local_vars_namespace_cstr, nullptr, OptionalClangModuleID());
10071e0d3954SRaphael Isemann if (!namespace_decl)
10081e0d3954SRaphael Isemann return;
10091e0d3954SRaphael Isemann
10101e0d3954SRaphael Isemann name_context.AddNamedDecl(namespace_decl);
10111e0d3954SRaphael Isemann clang::DeclContext *ctxt = clang::Decl::castToDeclContext(namespace_decl);
10121e0d3954SRaphael Isemann ctxt->setHasExternalVisibleStorage(true);
10132ad7b6fbSRaphael Isemann name_context.m_found_local_vars_nsp = true;
1014337151f4SRaphael Isemann }
1015337151f4SRaphael Isemann
LookupInModulesDeclVendor(NameSearchContext & context,ConstString name)1016a0408ab7SRaphael Isemann void ClangExpressionDeclMap::LookupInModulesDeclVendor(
1017e657a1ebSRaphael Isemann NameSearchContext &context, ConstString name) {
1018a007a6d8SPavel Labath Log *log = GetLog(LLDBLog::Expressions);
1019a0408ab7SRaphael Isemann
10204aee81c4SRaphael Isemann if (!m_target)
10214aee81c4SRaphael Isemann return;
10224aee81c4SRaphael Isemann
10234c0b0de9SAlex Langford std::shared_ptr<ClangModulesDeclVendor> modules_decl_vendor =
10244c0b0de9SAlex Langford GetClangModulesDeclVendor();
102546883f46SRaphael Isemann if (!modules_decl_vendor)
102646883f46SRaphael Isemann return;
102746883f46SRaphael Isemann
1028a0408ab7SRaphael Isemann bool append = false;
1029a0408ab7SRaphael Isemann uint32_t max_matches = 1;
1030a0408ab7SRaphael Isemann std::vector<clang::NamedDecl *> decls;
1031a0408ab7SRaphael Isemann
1032a0408ab7SRaphael Isemann if (!modules_decl_vendor->FindDecls(name, append, max_matches, decls))
1033a0408ab7SRaphael Isemann return;
1034a0408ab7SRaphael Isemann
103546883f46SRaphael Isemann assert(!decls.empty() && "FindDecls returned true but no decls?");
1036a0408ab7SRaphael Isemann clang::NamedDecl *const decl_from_modules = decls[0];
1037a0408ab7SRaphael Isemann
103846883f46SRaphael Isemann LLDB_LOG(log,
1039e657a1ebSRaphael Isemann " CAS::FEVD Matching decl found for "
1040f000de87SAdrian Prantl "\"{0}\" in the modules",
1041e657a1ebSRaphael Isemann name);
1042a0408ab7SRaphael Isemann
1043a0408ab7SRaphael Isemann clang::Decl *copied_decl = CopyDecl(decl_from_modules);
104446883f46SRaphael Isemann if (!copied_decl) {
1045e657a1ebSRaphael Isemann LLDB_LOG(log, " CAS::FEVD - Couldn't export a "
1046e657a1ebSRaphael Isemann "declaration from the modules");
1047a0408ab7SRaphael Isemann return;
1048a0408ab7SRaphael Isemann }
1049a0408ab7SRaphael Isemann
105046883f46SRaphael Isemann if (auto copied_function = dyn_cast<clang::FunctionDecl>(copied_decl)) {
105146883f46SRaphael Isemann MaybeRegisterFunctionBody(copied_function);
1052a0408ab7SRaphael Isemann
105346883f46SRaphael Isemann context.AddNamedDecl(copied_function);
1054a0408ab7SRaphael Isemann
10552ad7b6fbSRaphael Isemann context.m_found_function_with_type_info = true;
10562ad7b6fbSRaphael Isemann context.m_found_function = true;
105746883f46SRaphael Isemann } else if (auto copied_var = dyn_cast<clang::VarDecl>(copied_decl)) {
105846883f46SRaphael Isemann context.AddNamedDecl(copied_var);
10592ad7b6fbSRaphael Isemann context.m_found_variable = true;
1060a0408ab7SRaphael Isemann }
1061a0408ab7SRaphael Isemann }
1062a0408ab7SRaphael Isemann
LookupLocalVariable(NameSearchContext & context,ConstString name,SymbolContext & sym_ctx,const CompilerDeclContext & namespace_decl)10637fa976d5SRaphael Isemann bool ClangExpressionDeclMap::LookupLocalVariable(
1064e657a1ebSRaphael Isemann NameSearchContext &context, ConstString name, SymbolContext &sym_ctx,
1065e657a1ebSRaphael Isemann const CompilerDeclContext &namespace_decl) {
10667a0c5484SRaphael Isemann if (sym_ctx.block == nullptr)
10677a0c5484SRaphael Isemann return false;
10687fa976d5SRaphael Isemann
10697a0c5484SRaphael Isemann CompilerDeclContext decl_context = sym_ctx.block->GetDeclContext();
10707a0c5484SRaphael Isemann if (!decl_context)
10717a0c5484SRaphael Isemann return false;
10727fa976d5SRaphael Isemann
10737fa976d5SRaphael Isemann // Make sure that the variables are parsed so that we have the
10747fa976d5SRaphael Isemann // declarations.
10757a0c5484SRaphael Isemann StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
10767fa976d5SRaphael Isemann VariableListSP vars = frame->GetInScopeVariableList(true);
10777fa976d5SRaphael Isemann for (size_t i = 0; i < vars->GetSize(); i++)
10787fa976d5SRaphael Isemann vars->GetVariableAtIndex(i)->GetDecl();
10797fa976d5SRaphael Isemann
10807fa976d5SRaphael Isemann // Search for declarations matching the name. Do not include imported
10817fa976d5SRaphael Isemann // decls in the search if we are looking for decls in the artificial
10827fa976d5SRaphael Isemann // namespace $__lldb_local_vars.
10837fa976d5SRaphael Isemann std::vector<CompilerDecl> found_decls =
10847a0c5484SRaphael Isemann decl_context.FindDeclByName(name, namespace_decl.IsValid());
10857fa976d5SRaphael Isemann
10867a0c5484SRaphael Isemann VariableSP var;
10877fa976d5SRaphael Isemann bool variable_found = false;
10887fa976d5SRaphael Isemann for (CompilerDecl decl : found_decls) {
10897fa976d5SRaphael Isemann for (size_t vi = 0, ve = vars->GetSize(); vi != ve; ++vi) {
10907fa976d5SRaphael Isemann VariableSP candidate_var = vars->GetVariableAtIndex(vi);
10917fa976d5SRaphael Isemann if (candidate_var->GetDecl() == decl) {
10927fa976d5SRaphael Isemann var = candidate_var;
10937fa976d5SRaphael Isemann break;
10947fa976d5SRaphael Isemann }
10957fa976d5SRaphael Isemann }
10967fa976d5SRaphael Isemann
10977fa976d5SRaphael Isemann if (var && !variable_found) {
10987fa976d5SRaphael Isemann variable_found = true;
10997a0c5484SRaphael Isemann ValueObjectSP valobj = ValueObjectVariable::Create(frame, var);
1100e657a1ebSRaphael Isemann AddOneVariable(context, var, valobj);
11012ad7b6fbSRaphael Isemann context.m_found_variable = true;
11027fa976d5SRaphael Isemann }
11037fa976d5SRaphael Isemann }
11048184b252SMichael Buch
11058184b252SMichael Buch // We're in a local_var_lookup but haven't found any local variables
11068184b252SMichael Buch // so far. When performing a variable lookup from within the context of
11078184b252SMichael Buch // a lambda, we count the lambda captures as local variables. Thus,
11088184b252SMichael Buch // see if we captured any variables with the requested 'name'.
11098184b252SMichael Buch if (!variable_found) {
11108184b252SMichael Buch auto find_capture = [](ConstString varname,
11118184b252SMichael Buch StackFrame *frame) -> ValueObjectSP {
11128184b252SMichael Buch if (auto lambda = ClangExpressionUtil::GetLambdaValueObject(frame)) {
11138184b252SMichael Buch if (auto capture = lambda->GetChildMemberWithName(varname, true)) {
11148184b252SMichael Buch return capture;
11158184b252SMichael Buch }
11168184b252SMichael Buch }
11178184b252SMichael Buch
11188184b252SMichael Buch return nullptr;
11198184b252SMichael Buch };
11208184b252SMichael Buch
11218184b252SMichael Buch if (auto capture = find_capture(name, frame)) {
11228184b252SMichael Buch variable_found = true;
11238184b252SMichael Buch context.m_found_variable = true;
11248184b252SMichael Buch AddOneVariable(context, std::move(capture), std::move(find_capture));
11258184b252SMichael Buch }
11268184b252SMichael Buch }
11278184b252SMichael Buch
11287a0c5484SRaphael Isemann return variable_found;
11297fa976d5SRaphael Isemann }
11307fa976d5SRaphael Isemann
113116c0653dSRaphael Isemann /// Structure to hold the info needed when comparing function
113216c0653dSRaphael Isemann /// declarations.
113316c0653dSRaphael Isemann namespace {
113416c0653dSRaphael Isemann struct FuncDeclInfo {
113516c0653dSRaphael Isemann ConstString m_name;
113616c0653dSRaphael Isemann CompilerType m_copied_type;
113716c0653dSRaphael Isemann uint32_t m_decl_lvl;
113816c0653dSRaphael Isemann SymbolContext m_sym_ctx;
113916c0653dSRaphael Isemann };
114016c0653dSRaphael Isemann } // namespace
114116c0653dSRaphael Isemann
SearchFunctionsInSymbolContexts(const SymbolContextList & sc_list,const CompilerDeclContext & frame_decl_context)114216c0653dSRaphael Isemann SymbolContextList ClangExpressionDeclMap::SearchFunctionsInSymbolContexts(
114316c0653dSRaphael Isemann const SymbolContextList &sc_list,
114416c0653dSRaphael Isemann const CompilerDeclContext &frame_decl_context) {
114516c0653dSRaphael Isemann // First, symplify things by looping through the symbol contexts to
114616c0653dSRaphael Isemann // remove unwanted functions and separate out the functions we want to
114716c0653dSRaphael Isemann // compare and prune into a separate list. Cache the info needed about
114816c0653dSRaphael Isemann // the function declarations in a vector for efficiency.
114916c0653dSRaphael Isemann uint32_t num_indices = sc_list.GetSize();
115016c0653dSRaphael Isemann SymbolContextList sc_sym_list;
115116c0653dSRaphael Isemann std::vector<FuncDeclInfo> decl_infos;
115216c0653dSRaphael Isemann decl_infos.reserve(num_indices);
115316c0653dSRaphael Isemann clang::DeclContext *frame_decl_ctx =
115416c0653dSRaphael Isemann (clang::DeclContext *)frame_decl_context.GetOpaqueDeclContext();
11556e3b0cc2SRaphael Isemann TypeSystemClang *ast = llvm::dyn_cast_or_null<TypeSystemClang>(
115616c0653dSRaphael Isemann frame_decl_context.GetTypeSystem());
115716c0653dSRaphael Isemann
115816c0653dSRaphael Isemann for (uint32_t index = 0; index < num_indices; ++index) {
115916c0653dSRaphael Isemann FuncDeclInfo fdi;
116016c0653dSRaphael Isemann SymbolContext sym_ctx;
116116c0653dSRaphael Isemann sc_list.GetContextAtIndex(index, sym_ctx);
116216c0653dSRaphael Isemann
116316c0653dSRaphael Isemann // We don't know enough about symbols to compare them, but we should
116416c0653dSRaphael Isemann // keep them in the list.
116516c0653dSRaphael Isemann Function *function = sym_ctx.function;
116616c0653dSRaphael Isemann if (!function) {
116716c0653dSRaphael Isemann sc_sym_list.Append(sym_ctx);
116816c0653dSRaphael Isemann continue;
116916c0653dSRaphael Isemann }
117016c0653dSRaphael Isemann // Filter out functions without declaration contexts, as well as
117116c0653dSRaphael Isemann // class/instance methods, since they'll be skipped in the code that
117216c0653dSRaphael Isemann // follows anyway.
117316c0653dSRaphael Isemann CompilerDeclContext func_decl_context = function->GetDeclContext();
117416c0653dSRaphael Isemann if (!func_decl_context ||
117516c0653dSRaphael Isemann func_decl_context.IsClassMethod(nullptr, nullptr, nullptr))
117616c0653dSRaphael Isemann continue;
117716c0653dSRaphael Isemann // We can only prune functions for which we can copy the type.
117816c0653dSRaphael Isemann CompilerType func_clang_type = function->GetType()->GetFullCompilerType();
117916c0653dSRaphael Isemann CompilerType copied_func_type = GuardedCopyType(func_clang_type);
118016c0653dSRaphael Isemann if (!copied_func_type) {
118116c0653dSRaphael Isemann sc_sym_list.Append(sym_ctx);
118216c0653dSRaphael Isemann continue;
118316c0653dSRaphael Isemann }
118416c0653dSRaphael Isemann
118516c0653dSRaphael Isemann fdi.m_sym_ctx = sym_ctx;
118616c0653dSRaphael Isemann fdi.m_name = function->GetName();
118716c0653dSRaphael Isemann fdi.m_copied_type = copied_func_type;
118816c0653dSRaphael Isemann fdi.m_decl_lvl = LLDB_INVALID_DECL_LEVEL;
118916c0653dSRaphael Isemann if (fdi.m_copied_type && func_decl_context) {
119016c0653dSRaphael Isemann // Call CountDeclLevels to get the number of parent scopes we have
119116c0653dSRaphael Isemann // to look through before we find the function declaration. When
119216c0653dSRaphael Isemann // comparing functions of the same type, the one with a lower count
119316c0653dSRaphael Isemann // will be closer to us in the lookup scope and shadows the other.
119416c0653dSRaphael Isemann clang::DeclContext *func_decl_ctx =
119516c0653dSRaphael Isemann (clang::DeclContext *)func_decl_context.GetOpaqueDeclContext();
119616c0653dSRaphael Isemann fdi.m_decl_lvl = ast->CountDeclLevels(frame_decl_ctx, func_decl_ctx,
119716c0653dSRaphael Isemann &fdi.m_name, &fdi.m_copied_type);
119816c0653dSRaphael Isemann }
119916c0653dSRaphael Isemann decl_infos.emplace_back(fdi);
120016c0653dSRaphael Isemann }
120116c0653dSRaphael Isemann
120216c0653dSRaphael Isemann // Loop through the functions in our cache looking for matching types,
120316c0653dSRaphael Isemann // then compare their scope levels to see which is closer.
120416c0653dSRaphael Isemann std::multimap<CompilerType, const FuncDeclInfo *> matches;
120516c0653dSRaphael Isemann for (const FuncDeclInfo &fdi : decl_infos) {
120616c0653dSRaphael Isemann const CompilerType t = fdi.m_copied_type;
120716c0653dSRaphael Isemann auto q = matches.find(t);
120816c0653dSRaphael Isemann if (q != matches.end()) {
120916c0653dSRaphael Isemann if (q->second->m_decl_lvl > fdi.m_decl_lvl)
121016c0653dSRaphael Isemann // This function is closer; remove the old set.
121116c0653dSRaphael Isemann matches.erase(t);
121216c0653dSRaphael Isemann else if (q->second->m_decl_lvl < fdi.m_decl_lvl)
121316c0653dSRaphael Isemann // The functions in our set are closer - skip this one.
121416c0653dSRaphael Isemann continue;
121516c0653dSRaphael Isemann }
121616c0653dSRaphael Isemann matches.insert(std::make_pair(t, &fdi));
121716c0653dSRaphael Isemann }
121816c0653dSRaphael Isemann
121916c0653dSRaphael Isemann // Loop through our matches and add their symbol contexts to our list.
122016c0653dSRaphael Isemann SymbolContextList sc_func_list;
122116c0653dSRaphael Isemann for (const auto &q : matches)
122216c0653dSRaphael Isemann sc_func_list.Append(q.second->m_sym_ctx);
122316c0653dSRaphael Isemann
122416c0653dSRaphael Isemann // Rejoin the lists with the functions in front.
122516c0653dSRaphael Isemann sc_func_list.Append(sc_sym_list);
122616c0653dSRaphael Isemann return sc_func_list;
122716c0653dSRaphael Isemann }
122816c0653dSRaphael Isemann
LookupFunction(NameSearchContext & context,lldb::ModuleSP module_sp,ConstString name,const CompilerDeclContext & namespace_decl)12293d7b591dSRaphael Isemann void ClangExpressionDeclMap::LookupFunction(
12303d7b591dSRaphael Isemann NameSearchContext &context, lldb::ModuleSP module_sp, ConstString name,
1231e657a1ebSRaphael Isemann const CompilerDeclContext &namespace_decl) {
12324aee81c4SRaphael Isemann if (!m_parser_vars)
12334aee81c4SRaphael Isemann return;
123451ad025fSRaphael Isemann
123551ad025fSRaphael Isemann Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
12364dbb271fSSean Callanan
12374dbb271fSSean Callanan std::vector<clang::NamedDecl *> decls_from_modules;
12384dbb271fSSean Callanan
1239b9c1b51eSKate Stone if (target) {
12404c0b0de9SAlex Langford if (std::shared_ptr<ClangModulesDeclVendor> decl_vendor =
12414c0b0de9SAlex Langford GetClangModulesDeclVendor()) {
12424dbb271fSSean Callanan decl_vendor->FindDecls(name, false, UINT32_MAX, decls_from_modules);
12434dbb271fSSean Callanan }
12444dbb271fSSean Callanan }
12454dbb271fSSean Callanan
124624e98867SRaphael Isemann SymbolContextList sc_list;
1247b9c1b51eSKate Stone if (namespace_decl && module_sp) {
1248c020be17SJonas Devlieghere ModuleFunctionSearchOptions function_options;
1249c020be17SJonas Devlieghere function_options.include_inlines = false;
1250c020be17SJonas Devlieghere function_options.include_symbols = false;
12514dbb271fSSean Callanan
1252f9568a95SRaphael Isemann module_sp->FindFunctions(name, namespace_decl, eFunctionNameTypeBase,
1253c020be17SJonas Devlieghere function_options, sc_list);
1254b9c1b51eSKate Stone } else if (target && !namespace_decl) {
1255c020be17SJonas Devlieghere ModuleFunctionSearchOptions function_options;
1256c020be17SJonas Devlieghere function_options.include_inlines = false;
1257c020be17SJonas Devlieghere function_options.include_symbols = true;
12584dbb271fSSean Callanan
12594dbb271fSSean Callanan // TODO Fix FindFunctions so that it doesn't return
12604dbb271fSSean Callanan // instance methods for eFunctionNameTypeBase.
12614dbb271fSSean Callanan
1262a705cf1aSLevon Ter-Grigoryan target->GetImages().FindFunctions(
1263c020be17SJonas Devlieghere name, eFunctionNameTypeFull | eFunctionNameTypeBase, function_options,
1264c020be17SJonas Devlieghere sc_list);
12654dbb271fSSean Callanan }
12664dbb271fSSean Callanan
126705097246SAdrian Prantl // If we found more than one function, see if we can use the frame's decl
126805097246SAdrian Prantl // context to remove functions that are shadowed by other functions which
126905097246SAdrian Prantl // match in type but are nearer in scope.
1270b5925784SDawn Perchik //
1271b5925784SDawn Perchik // AddOneFunction will not add a function whose type has already been
127205097246SAdrian Prantl // added, so if there's another function in the list with a matching type,
127305097246SAdrian Prantl // check to see if their decl context is a parent of the current frame's or
127405097246SAdrian Prantl // was imported via a and using statement, and pick the best match
127505097246SAdrian Prantl // according to lookup rules.
1276b9c1b51eSKate Stone if (sc_list.GetSize() > 1) {
1277b5925784SDawn Perchik // Collect some info about our frame's context.
1278b5925784SDawn Perchik StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
1279b5925784SDawn Perchik SymbolContext frame_sym_ctx;
1280b5925784SDawn Perchik if (frame != nullptr)
1281b9c1b51eSKate Stone frame_sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
1282b9c1b51eSKate Stone lldb::eSymbolContextBlock);
1283b9c1b51eSKate Stone CompilerDeclContext frame_decl_context =
1284c02a1c03SSean Callanan frame_sym_ctx.block != nullptr ? frame_sym_ctx.block->GetDeclContext()
1285b9c1b51eSKate Stone : CompilerDeclContext();
1286b5925784SDawn Perchik
1287b5925784SDawn Perchik // We can't do this without a compiler decl context for our frame.
1288b9c1b51eSKate Stone if (frame_decl_context) {
128916c0653dSRaphael Isemann sc_list = SearchFunctionsInSymbolContexts(sc_list, frame_decl_context);
1290b5925784SDawn Perchik }
1291b5925784SDawn Perchik }
1292b5925784SDawn Perchik
1293b9c1b51eSKate Stone if (sc_list.GetSize()) {
1294248a1305SKonrad Kleine Symbol *extern_symbol = nullptr;
1295248a1305SKonrad Kleine Symbol *non_extern_symbol = nullptr;
12964dbb271fSSean Callanan
12974dbb271fSSean Callanan for (uint32_t index = 0, num_indices = sc_list.GetSize();
1298b9c1b51eSKate Stone index < num_indices; ++index) {
12994dbb271fSSean Callanan SymbolContext sym_ctx;
13004dbb271fSSean Callanan sc_list.GetContextAtIndex(index, sym_ctx);
13014dbb271fSSean Callanan
1302b9c1b51eSKate Stone if (sym_ctx.function) {
13034dbb271fSSean Callanan CompilerDeclContext decl_ctx = sym_ctx.function->GetDeclContext();
13044dbb271fSSean Callanan
13054dbb271fSSean Callanan if (!decl_ctx)
13064dbb271fSSean Callanan continue;
13074dbb271fSSean Callanan
13084dbb271fSSean Callanan // Filter out class/instance methods.
13094dbb271fSSean Callanan if (decl_ctx.IsClassMethod(nullptr, nullptr, nullptr))
13104dbb271fSSean Callanan continue;
13114dbb271fSSean Callanan
1312e657a1ebSRaphael Isemann AddOneFunction(context, sym_ctx.function, nullptr);
13132ad7b6fbSRaphael Isemann context.m_found_function_with_type_info = true;
13142ad7b6fbSRaphael Isemann context.m_found_function = true;
1315b9c1b51eSKate Stone } else if (sym_ctx.symbol) {
1316b9c1b51eSKate Stone if (sym_ctx.symbol->GetType() == eSymbolTypeReExported && target) {
13174dbb271fSSean Callanan sym_ctx.symbol = sym_ctx.symbol->ResolveReExportedSymbol(*target);
1318248a1305SKonrad Kleine if (sym_ctx.symbol == nullptr)
13194dbb271fSSean Callanan continue;
13204dbb271fSSean Callanan }
13214dbb271fSSean Callanan
13224dbb271fSSean Callanan if (sym_ctx.symbol->IsExternal())
13234dbb271fSSean Callanan extern_symbol = sym_ctx.symbol;
13244dbb271fSSean Callanan else
13254dbb271fSSean Callanan non_extern_symbol = sym_ctx.symbol;
13264dbb271fSSean Callanan }
13274dbb271fSSean Callanan }
13284dbb271fSSean Callanan
13292ad7b6fbSRaphael Isemann if (!context.m_found_function_with_type_info) {
1330b9c1b51eSKate Stone for (clang::NamedDecl *decl : decls_from_modules) {
1331b9c1b51eSKate Stone if (llvm::isa<clang::FunctionDecl>(decl)) {
1332b9c1b51eSKate Stone clang::NamedDecl *copied_decl =
133368e44239SSean Callanan llvm::cast_or_null<FunctionDecl>(CopyDecl(decl));
1334b9c1b51eSKate Stone if (copied_decl) {
13354dbb271fSSean Callanan context.AddNamedDecl(copied_decl);
13362ad7b6fbSRaphael Isemann context.m_found_function_with_type_info = true;
13374dbb271fSSean Callanan }
13384dbb271fSSean Callanan }
13394dbb271fSSean Callanan }
134037e2664fSSean Callanan }
13414dbb271fSSean Callanan
13422ad7b6fbSRaphael Isemann if (!context.m_found_function_with_type_info) {
1343b9c1b51eSKate Stone if (extern_symbol) {
1344e657a1ebSRaphael Isemann AddOneFunction(context, nullptr, extern_symbol);
13452ad7b6fbSRaphael Isemann context.m_found_function = true;
1346b9c1b51eSKate Stone } else if (non_extern_symbol) {
1347e657a1ebSRaphael Isemann AddOneFunction(context, nullptr, non_extern_symbol);
13482ad7b6fbSRaphael Isemann context.m_found_function = true;
13494dbb271fSSean Callanan }
13504dbb271fSSean Callanan }
13514dbb271fSSean Callanan }
13525fb7dd8aSRaphael Isemann }
13535fb7dd8aSRaphael Isemann
FindExternalVisibleDecls(NameSearchContext & context,lldb::ModuleSP module_sp,const CompilerDeclContext & namespace_decl)13545fb7dd8aSRaphael Isemann void ClangExpressionDeclMap::FindExternalVisibleDecls(
13555fb7dd8aSRaphael Isemann NameSearchContext &context, lldb::ModuleSP module_sp,
1356e657a1ebSRaphael Isemann const CompilerDeclContext &namespace_decl) {
13575fb7dd8aSRaphael Isemann assert(m_ast_context);
13585fb7dd8aSRaphael Isemann
1359a007a6d8SPavel Labath Log *log = GetLog(LLDBLog::Expressions);
13605fb7dd8aSRaphael Isemann
13615fb7dd8aSRaphael Isemann const ConstString name(context.m_decl_name.getAsString().c_str());
13625fb7dd8aSRaphael Isemann if (IgnoreName(name, false))
13635fb7dd8aSRaphael Isemann return;
13645fb7dd8aSRaphael Isemann
13655fb7dd8aSRaphael Isemann // Only look for functions by name out in our symbols if the function doesn't
13665fb7dd8aSRaphael Isemann // start with our phony prefix of '$'
13674aee81c4SRaphael Isemann
13684aee81c4SRaphael Isemann Target *target = nullptr;
13694aee81c4SRaphael Isemann StackFrame *frame = nullptr;
13705fb7dd8aSRaphael Isemann SymbolContext sym_ctx;
13714aee81c4SRaphael Isemann if (m_parser_vars) {
13724aee81c4SRaphael Isemann target = m_parser_vars->m_exe_ctx.GetTargetPtr();
13734aee81c4SRaphael Isemann frame = m_parser_vars->m_exe_ctx.GetFramePtr();
13744aee81c4SRaphael Isemann }
13755fb7dd8aSRaphael Isemann if (frame != nullptr)
13765fb7dd8aSRaphael Isemann sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
13775fb7dd8aSRaphael Isemann lldb::eSymbolContextBlock);
13785fb7dd8aSRaphael Isemann
13795fb7dd8aSRaphael Isemann // Try the persistent decls, which take precedence over all else.
13805fb7dd8aSRaphael Isemann if (!namespace_decl)
1381e657a1ebSRaphael Isemann SearchPersistenDecls(context, name);
13825fb7dd8aSRaphael Isemann
13838cf8ec40SRaphael Isemann if (name.GetStringRef().startswith("$") && !namespace_decl) {
13848cf8ec40SRaphael Isemann if (name == "$__lldb_class") {
1385e657a1ebSRaphael Isemann LookUpLldbClass(context);
13865fb7dd8aSRaphael Isemann return;
13875fb7dd8aSRaphael Isemann }
13885fb7dd8aSRaphael Isemann
13898cf8ec40SRaphael Isemann if (name == "$__lldb_objc_class") {
1390e657a1ebSRaphael Isemann LookUpLldbObjCClass(context);
13915fb7dd8aSRaphael Isemann return;
13925fb7dd8aSRaphael Isemann }
13938cf8ec40SRaphael Isemann if (name == g_lldb_local_vars_namespace_cstr) {
13945fb7dd8aSRaphael Isemann LookupLocalVarNamespace(sym_ctx, context);
13955fb7dd8aSRaphael Isemann return;
13965fb7dd8aSRaphael Isemann }
13975fb7dd8aSRaphael Isemann
13985fb7dd8aSRaphael Isemann // any other $__lldb names should be weeded out now
13995fb7dd8aSRaphael Isemann if (name.GetStringRef().startswith("$__lldb"))
14005fb7dd8aSRaphael Isemann return;
14015fb7dd8aSRaphael Isemann
1402d8a31949SRaphael Isemann // No ParserVars means we can't do register or variable lookup.
1403e9331a56SAdrian Prantl if (!m_parser_vars || !m_parser_vars->m_persistent_vars)
1404d8a31949SRaphael Isemann return;
1405d8a31949SRaphael Isemann
14065fb7dd8aSRaphael Isemann ExpressionVariableSP pvar_sp(
14075fb7dd8aSRaphael Isemann m_parser_vars->m_persistent_vars->GetVariable(name));
14085fb7dd8aSRaphael Isemann
14095fb7dd8aSRaphael Isemann if (pvar_sp) {
1410e657a1ebSRaphael Isemann AddOneVariable(context, pvar_sp);
14115fb7dd8aSRaphael Isemann return;
14125fb7dd8aSRaphael Isemann }
14135fb7dd8aSRaphael Isemann
14148cf8ec40SRaphael Isemann assert(name.GetStringRef().startswith("$"));
14158cf8ec40SRaphael Isemann llvm::StringRef reg_name = name.GetStringRef().substr(1);
14165fb7dd8aSRaphael Isemann
14175fb7dd8aSRaphael Isemann if (m_parser_vars->m_exe_ctx.GetRegisterContext()) {
14185fb7dd8aSRaphael Isemann const RegisterInfo *reg_info(
14195fb7dd8aSRaphael Isemann m_parser_vars->m_exe_ctx.GetRegisterContext()->GetRegisterInfoByName(
14205fb7dd8aSRaphael Isemann reg_name));
14215fb7dd8aSRaphael Isemann
14225fb7dd8aSRaphael Isemann if (reg_info) {
1423fc0d11c9SRaphael Isemann LLDB_LOG(log, " CEDM::FEVD Found register {0}", reg_info->name);
14245fb7dd8aSRaphael Isemann
1425e657a1ebSRaphael Isemann AddOneRegister(context, reg_info);
14265fb7dd8aSRaphael Isemann }
14275fb7dd8aSRaphael Isemann }
14285fb7dd8aSRaphael Isemann return;
14295fb7dd8aSRaphael Isemann }
14305fb7dd8aSRaphael Isemann
14318cf8ec40SRaphael Isemann bool local_var_lookup = !namespace_decl || (namespace_decl.GetName() ==
14328cf8ec40SRaphael Isemann g_lldb_local_vars_namespace_cstr);
14335fb7dd8aSRaphael Isemann if (frame && local_var_lookup)
1434e657a1ebSRaphael Isemann if (LookupLocalVariable(context, name, sym_ctx, namespace_decl))
14355fb7dd8aSRaphael Isemann return;
14365fb7dd8aSRaphael Isemann
14375fb7dd8aSRaphael Isemann if (target) {
14385fb7dd8aSRaphael Isemann ValueObjectSP valobj;
14395fb7dd8aSRaphael Isemann VariableSP var;
14403d7b591dSRaphael Isemann var = FindGlobalVariable(*target, module_sp, name, namespace_decl);
14415fb7dd8aSRaphael Isemann
14425fb7dd8aSRaphael Isemann if (var) {
14435fb7dd8aSRaphael Isemann valobj = ValueObjectVariable::Create(target, var);
1444e657a1ebSRaphael Isemann AddOneVariable(context, var, valobj);
14452ad7b6fbSRaphael Isemann context.m_found_variable = true;
14465fb7dd8aSRaphael Isemann return;
14475fb7dd8aSRaphael Isemann }
14485fb7dd8aSRaphael Isemann }
14495fb7dd8aSRaphael Isemann
1450e657a1ebSRaphael Isemann LookupFunction(context, module_sp, name, namespace_decl);
14514dbb271fSSean Callanan
14524dbb271fSSean Callanan // Try the modules next.
14532ad7b6fbSRaphael Isemann if (!context.m_found_function_with_type_info)
1454e657a1ebSRaphael Isemann LookupInModulesDeclVendor(context, name);
14554dbb271fSSean Callanan
14562ad7b6fbSRaphael Isemann if (target && !context.m_found_variable && !namespace_decl) {
145705097246SAdrian Prantl // We couldn't find a non-symbol variable for this. Now we'll hunt for a
145805097246SAdrian Prantl // generic data symbol, and -- if it is found -- treat it as a variable.
14599c99faa8SSean Callanan Status error;
14604dbb271fSSean Callanan
14619c99faa8SSean Callanan const Symbol *data_symbol =
14629c99faa8SSean Callanan m_parser_vars->m_sym_ctx.FindBestGlobalDataSymbol(name, error);
14639c99faa8SSean Callanan
14649c99faa8SSean Callanan if (!error.Success()) {
14659c99faa8SSean Callanan const unsigned diag_id =
14669c99faa8SSean Callanan m_ast_context->getDiagnostics().getCustomDiagID(
14679c99faa8SSean Callanan clang::DiagnosticsEngine::Level::Error, "%0");
14689c99faa8SSean Callanan m_ast_context->getDiagnostics().Report(diag_id) << error.AsCString();
14699c99faa8SSean Callanan }
14704dbb271fSSean Callanan
1471b9c1b51eSKate Stone if (data_symbol) {
14724dbb271fSSean Callanan std::string warning("got name from symbols: ");
14734dbb271fSSean Callanan warning.append(name.AsCString());
1474b9c1b51eSKate Stone const unsigned diag_id =
1475b9c1b51eSKate Stone m_ast_context->getDiagnostics().getCustomDiagID(
1476b9c1b51eSKate Stone clang::DiagnosticsEngine::Level::Warning, "%0");
14774dbb271fSSean Callanan m_ast_context->getDiagnostics().Report(diag_id) << warning.c_str();
1478e657a1ebSRaphael Isemann AddOneGenericVariable(context, *data_symbol);
14792ad7b6fbSRaphael Isemann context.m_found_variable = true;
14804dbb271fSSean Callanan }
14814dbb271fSSean Callanan }
14824dbb271fSSean Callanan }
14834dbb271fSSean Callanan
GetVariableValue(VariableSP & var,lldb_private::Value & var_location,TypeFromUser * user_type,TypeFromParser * parser_type)1484b9c1b51eSKate Stone bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var,
14854dbb271fSSean Callanan lldb_private::Value &var_location,
14864dbb271fSSean Callanan TypeFromUser *user_type,
1487b9c1b51eSKate Stone TypeFromParser *parser_type) {
1488a007a6d8SPavel Labath Log *log = GetLog(LLDBLog::Expressions);
14894dbb271fSSean Callanan
14904dbb271fSSean Callanan Type *var_type = var->GetType();
14914dbb271fSSean Callanan
1492b9c1b51eSKate Stone if (!var_type) {
1493fc0d11c9SRaphael Isemann LLDB_LOG(log, "Skipped a definition because it has no type");
14944dbb271fSSean Callanan return false;
14954dbb271fSSean Callanan }
14964dbb271fSSean Callanan
14974dbb271fSSean Callanan CompilerType var_clang_type = var_type->GetFullCompilerType();
14984dbb271fSSean Callanan
1499b9c1b51eSKate Stone if (!var_clang_type) {
1500fc0d11c9SRaphael Isemann LLDB_LOG(log, "Skipped a definition because it has no Clang type");
15014dbb271fSSean Callanan return false;
15024dbb271fSSean Callanan }
15034dbb271fSSean Callanan
15046e3b0cc2SRaphael Isemann TypeSystemClang *clang_ast = llvm::dyn_cast_or_null<TypeSystemClang>(
1505b9c1b51eSKate Stone var_type->GetForwardCompilerType().GetTypeSystem());
15064dbb271fSSean Callanan
1507b9c1b51eSKate Stone if (!clang_ast) {
1508fc0d11c9SRaphael Isemann LLDB_LOG(log, "Skipped a definition because it has no Clang AST");
15094dbb271fSSean Callanan return false;
15104dbb271fSSean Callanan }
15114dbb271fSSean Callanan
1512b74a01a8SZequan Wu DWARFExpressionList &var_location_list = var->LocationExpressionList();
15134dbb271fSSean Callanan
15144dbb271fSSean Callanan Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
151597206d57SZachary Turner Status err;
15164dbb271fSSean Callanan
1517b9c1b51eSKate Stone if (var->GetLocationIsConstantValueData()) {
15184dbb271fSSean Callanan DataExtractor const_value_extractor;
1519b74a01a8SZequan Wu if (var_location_list.GetExpressionData(const_value_extractor)) {
1520b9c1b51eSKate Stone var_location = Value(const_value_extractor.GetDataStart(),
1521b9c1b51eSKate Stone const_value_extractor.GetByteSize());
1522057efa99SAdrian Prantl var_location.SetValueType(Value::ValueType::HostAddress);
1523b9c1b51eSKate Stone } else {
1524fc0d11c9SRaphael Isemann LLDB_LOG(log, "Error evaluating constant variable: {0}", err.AsCString());
15254dbb271fSSean Callanan return false;
15264dbb271fSSean Callanan }
15274dbb271fSSean Callanan }
15284dbb271fSSean Callanan
15294dbb271fSSean Callanan CompilerType type_to_use = GuardedCopyType(var_clang_type);
15304dbb271fSSean Callanan
1531b9c1b51eSKate Stone if (!type_to_use) {
1532fc0d11c9SRaphael Isemann LLDB_LOG(log,
1533b9c1b51eSKate Stone "Couldn't copy a variable's type into the parser's AST context");
15344dbb271fSSean Callanan
15354dbb271fSSean Callanan return false;
15364dbb271fSSean Callanan }
15374dbb271fSSean Callanan
15384dbb271fSSean Callanan if (parser_type)
15394dbb271fSSean Callanan *parser_type = TypeFromParser(type_to_use);
15404dbb271fSSean Callanan
1541057efa99SAdrian Prantl if (var_location.GetContextType() == Value::ContextType::Invalid)
15424dbb271fSSean Callanan var_location.SetCompilerType(type_to_use);
15434dbb271fSSean Callanan
1544057efa99SAdrian Prantl if (var_location.GetValueType() == Value::ValueType::FileAddress) {
15454dbb271fSSean Callanan SymbolContext var_sc;
15464dbb271fSSean Callanan var->CalculateSymbolContext(&var_sc);
15474dbb271fSSean Callanan
15484dbb271fSSean Callanan if (!var_sc.module_sp)
15494dbb271fSSean Callanan return false;
15504dbb271fSSean Callanan
1551b9c1b51eSKate Stone Address so_addr(var_location.GetScalar().ULongLong(),
1552b9c1b51eSKate Stone var_sc.module_sp->GetSectionList());
15534dbb271fSSean Callanan
15544dbb271fSSean Callanan lldb::addr_t load_addr = so_addr.GetLoadAddress(target);
15554dbb271fSSean Callanan
1556b9c1b51eSKate Stone if (load_addr != LLDB_INVALID_ADDRESS) {
15574dbb271fSSean Callanan var_location.GetScalar() = load_addr;
1558057efa99SAdrian Prantl var_location.SetValueType(Value::ValueType::LoadAddress);
15594dbb271fSSean Callanan }
15604dbb271fSSean Callanan }
15614dbb271fSSean Callanan
15624dbb271fSSean Callanan if (user_type)
15634dbb271fSSean Callanan *user_type = TypeFromUser(var_clang_type);
15644dbb271fSSean Callanan
15654dbb271fSSean Callanan return true;
15664dbb271fSSean Callanan }
15674dbb271fSSean Callanan
15688184b252SMichael Buch ClangExpressionVariable::ParserVars *
AddExpressionVariable(NameSearchContext & context,TypeFromParser const & pt,ValueObjectSP valobj)15698184b252SMichael Buch ClangExpressionDeclMap::AddExpressionVariable(NameSearchContext &context,
15708184b252SMichael Buch TypeFromParser const &pt,
1571e657a1ebSRaphael Isemann ValueObjectSP valobj) {
1572b9c1b51eSKate Stone clang::QualType parser_opaque_type =
1573b9c1b51eSKate Stone QualType::getFromOpaquePtr(pt.GetOpaqueQualType());
15744dbb271fSSean Callanan
15754dbb271fSSean Callanan if (parser_opaque_type.isNull())
15768184b252SMichael Buch return nullptr;
15774dbb271fSSean Callanan
1578b9c1b51eSKate Stone if (const clang::Type *parser_type = parser_opaque_type.getTypePtr()) {
15794dbb271fSSean Callanan if (const TagType *tag_type = dyn_cast<TagType>(parser_type))
15804dbb271fSSean Callanan CompleteType(tag_type->getDecl());
1581b9c1b51eSKate Stone if (const ObjCObjectPointerType *objc_object_ptr_type =
1582b9c1b51eSKate Stone dyn_cast<ObjCObjectPointerType>(parser_type))
15834dbb271fSSean Callanan CompleteType(objc_object_ptr_type->getInterfaceDecl());
15844dbb271fSSean Callanan }
15854dbb271fSSean Callanan
15864dbb271fSSean Callanan bool is_reference = pt.IsReferenceType();
15874dbb271fSSean Callanan
1588248a1305SKonrad Kleine NamedDecl *var_decl = nullptr;
15894dbb271fSSean Callanan if (is_reference)
15904dbb271fSSean Callanan var_decl = context.AddVarDecl(pt);
15914dbb271fSSean Callanan else
15924dbb271fSSean Callanan var_decl = context.AddVarDecl(pt.GetLValueReferenceType());
15934dbb271fSSean Callanan
15944dbb271fSSean Callanan std::string decl_name(context.m_decl_name.getAsString());
15954dbb271fSSean Callanan ConstString entity_name(decl_name.c_str());
15969301ec11SSean Callanan ClangExpressionVariable *entity(new ClangExpressionVariable(valobj));
15979301ec11SSean Callanan m_found_entities.AddNewlyConstructedVariable(entity);
15984dbb271fSSean Callanan
15994dbb271fSSean Callanan assert(entity);
16004dbb271fSSean Callanan entity->EnableParserVars(GetParserID());
1601b9c1b51eSKate Stone ClangExpressionVariable::ParserVars *parser_vars =
1602b9c1b51eSKate Stone entity->GetParserVars(GetParserID());
16038184b252SMichael Buch
16044dbb271fSSean Callanan parser_vars->m_named_decl = var_decl;
16054dbb271fSSean Callanan
16064dbb271fSSean Callanan if (is_reference)
16074dbb271fSSean Callanan entity->m_flags |= ClangExpressionVariable::EVTypeIsReference;
16084dbb271fSSean Callanan
16098184b252SMichael Buch return parser_vars;
16108184b252SMichael Buch }
16118184b252SMichael Buch
AddOneVariable(NameSearchContext & context,ValueObjectSP valobj,ValueObjectProviderTy valobj_provider)16128184b252SMichael Buch void ClangExpressionDeclMap::AddOneVariable(
16138184b252SMichael Buch NameSearchContext &context, ValueObjectSP valobj,
16148184b252SMichael Buch ValueObjectProviderTy valobj_provider) {
16158184b252SMichael Buch assert(m_parser_vars.get());
16168184b252SMichael Buch assert(valobj);
16178184b252SMichael Buch
16188184b252SMichael Buch Log *log = GetLog(LLDBLog::Expressions);
16198184b252SMichael Buch
16208184b252SMichael Buch Value var_location = valobj->GetValue();
16218184b252SMichael Buch
16228184b252SMichael Buch TypeFromUser user_type = valobj->GetCompilerType();
16238184b252SMichael Buch
16248184b252SMichael Buch TypeSystemClang *clang_ast =
16258184b252SMichael Buch llvm::dyn_cast_or_null<TypeSystemClang>(user_type.GetTypeSystem());
16268184b252SMichael Buch
16278184b252SMichael Buch if (!clang_ast) {
16288184b252SMichael Buch LLDB_LOG(log, "Skipped a definition because it has no Clang AST");
16298184b252SMichael Buch return;
16308184b252SMichael Buch }
16318184b252SMichael Buch
16328184b252SMichael Buch TypeFromParser parser_type = GuardedCopyType(user_type);
16338184b252SMichael Buch
16348184b252SMichael Buch if (!parser_type) {
16358184b252SMichael Buch LLDB_LOG(log,
16368184b252SMichael Buch "Couldn't copy a variable's type into the parser's AST context");
16378184b252SMichael Buch
16388184b252SMichael Buch return;
16398184b252SMichael Buch }
16408184b252SMichael Buch
16418184b252SMichael Buch if (var_location.GetContextType() == Value::ContextType::Invalid)
16428184b252SMichael Buch var_location.SetCompilerType(parser_type);
16438184b252SMichael Buch
16448184b252SMichael Buch ClangExpressionVariable::ParserVars *parser_vars =
16458184b252SMichael Buch AddExpressionVariable(context, parser_type, valobj);
16468184b252SMichael Buch
16478184b252SMichael Buch if (!parser_vars)
16488184b252SMichael Buch return;
16498184b252SMichael Buch
1650f000de87SAdrian Prantl LLDB_LOG(log, " CEDM::FEVD Found variable {0}, returned\n{1} (original {2})",
16518184b252SMichael Buch context.m_decl_name, ClangUtil::DumpDecl(parser_vars->m_named_decl),
16528184b252SMichael Buch ClangUtil::ToString(user_type));
16538184b252SMichael Buch
16548184b252SMichael Buch parser_vars->m_llvm_value = nullptr;
16558184b252SMichael Buch parser_vars->m_lldb_value = std::move(var_location);
16568184b252SMichael Buch parser_vars->m_lldb_valobj_provider = std::move(valobj_provider);
16578184b252SMichael Buch }
16588184b252SMichael Buch
AddOneVariable(NameSearchContext & context,VariableSP var,ValueObjectSP valobj)16598184b252SMichael Buch void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
16608184b252SMichael Buch VariableSP var,
16618184b252SMichael Buch ValueObjectSP valobj) {
16628184b252SMichael Buch assert(m_parser_vars.get());
16638184b252SMichael Buch
16648184b252SMichael Buch Log *log = GetLog(LLDBLog::Expressions);
16658184b252SMichael Buch
16668184b252SMichael Buch TypeFromUser ut;
16678184b252SMichael Buch TypeFromParser pt;
16688184b252SMichael Buch Value var_location;
16698184b252SMichael Buch
16708184b252SMichael Buch if (!GetVariableValue(var, var_location, &ut, &pt))
16718184b252SMichael Buch return;
16728184b252SMichael Buch
16738184b252SMichael Buch ClangExpressionVariable::ParserVars *parser_vars =
16748184b252SMichael Buch AddExpressionVariable(context, pt, std::move(valobj));
16758184b252SMichael Buch
16768184b252SMichael Buch if (!parser_vars)
16778184b252SMichael Buch return;
16788184b252SMichael Buch
16798184b252SMichael Buch LLDB_LOG(log, " CEDM::FEVD Found variable {0}, returned\n{1} (original {2})",
16808184b252SMichael Buch context.m_decl_name, ClangUtil::DumpDecl(parser_vars->m_named_decl),
16818184b252SMichael Buch ClangUtil::ToString(ut));
16828184b252SMichael Buch
16838184b252SMichael Buch parser_vars->m_llvm_value = nullptr;
16848184b252SMichael Buch parser_vars->m_lldb_value = var_location;
16858184b252SMichael Buch parser_vars->m_lldb_var = var;
16864dbb271fSSean Callanan }
16874dbb271fSSean Callanan
AddOneVariable(NameSearchContext & context,ExpressionVariableSP & pvar_sp)1688b9c1b51eSKate Stone void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
1689e657a1ebSRaphael Isemann ExpressionVariableSP &pvar_sp) {
1690a007a6d8SPavel Labath Log *log = GetLog(LLDBLog::Expressions);
16914dbb271fSSean Callanan
1692b9c1b51eSKate Stone TypeFromUser user_type(
1693b9c1b51eSKate Stone llvm::cast<ClangExpressionVariable>(pvar_sp.get())->GetTypeFromUser());
16944dbb271fSSean Callanan
16954dbb271fSSean Callanan TypeFromParser parser_type(GuardedCopyType(user_type));
16964dbb271fSSean Callanan
1697b9c1b51eSKate Stone if (!parser_type.GetOpaqueQualType()) {
1698fc0d11c9SRaphael Isemann LLDB_LOG(log, " CEDM::FEVD Couldn't import type for pvar {0}",
1699fc0d11c9SRaphael Isemann pvar_sp->GetName());
17004dbb271fSSean Callanan return;
17014dbb271fSSean Callanan }
17024dbb271fSSean Callanan
1703b9c1b51eSKate Stone NamedDecl *var_decl =
1704b9c1b51eSKate Stone context.AddVarDecl(parser_type.GetLValueReferenceType());
17054dbb271fSSean Callanan
1706b9c1b51eSKate Stone llvm::cast<ClangExpressionVariable>(pvar_sp.get())
1707b9c1b51eSKate Stone ->EnableParserVars(GetParserID());
1708b9c1b51eSKate Stone ClangExpressionVariable::ParserVars *parser_vars =
1709b9c1b51eSKate Stone llvm::cast<ClangExpressionVariable>(pvar_sp.get())
1710b9c1b51eSKate Stone ->GetParserVars(GetParserID());
17114dbb271fSSean Callanan parser_vars->m_named_decl = var_decl;
1712248a1305SKonrad Kleine parser_vars->m_llvm_value = nullptr;
17134dbb271fSSean Callanan parser_vars->m_lldb_value.Clear();
17144dbb271fSSean Callanan
1715f000de87SAdrian Prantl LLDB_LOG(log, " CEDM::FEVD Added pvar {0}, returned\n{1}",
17167a6588abSRaphael Isemann pvar_sp->GetName(), ClangUtil::DumpDecl(var_decl));
17174dbb271fSSean Callanan }
17184dbb271fSSean Callanan
AddOneGenericVariable(NameSearchContext & context,const Symbol & symbol)1719b9c1b51eSKate Stone void ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context,
1720e657a1ebSRaphael Isemann const Symbol &symbol) {
17214dbb271fSSean Callanan assert(m_parser_vars.get());
17224dbb271fSSean Callanan
1723a007a6d8SPavel Labath Log *log = GetLog(LLDBLog::Expressions);
17244dbb271fSSean Callanan
17254dbb271fSSean Callanan Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
17264dbb271fSSean Callanan
1727248a1305SKonrad Kleine if (target == nullptr)
17284dbb271fSSean Callanan return;
17294dbb271fSSean Callanan
173047e7ecddSRaphael Isemann TypeSystemClang *scratch_ast_context = GetScratchContext(*target);
17313031818aSAlex Langford if (!scratch_ast_context)
17323031818aSAlex Langford return;
17334dbb271fSSean Callanan
1734c502bae5SRaphael Isemann TypeFromUser user_type(scratch_ast_context->GetBasicType(eBasicTypeVoid)
1735b9c1b51eSKate Stone .GetPointerType()
1736b9c1b51eSKate Stone .GetLValueReferenceType());
1737bc7f1df6SRaphael Isemann TypeFromParser parser_type(m_clang_ast_context->GetBasicType(eBasicTypeVoid)
1738b9c1b51eSKate Stone .GetPointerType()
1739b9c1b51eSKate Stone .GetLValueReferenceType());
17404dbb271fSSean Callanan NamedDecl *var_decl = context.AddVarDecl(parser_type);
17414dbb271fSSean Callanan
17424dbb271fSSean Callanan std::string decl_name(context.m_decl_name.getAsString());
17434dbb271fSSean Callanan ConstString entity_name(decl_name.c_str());
1744b9c1b51eSKate Stone ClangExpressionVariable *entity(new ClangExpressionVariable(
1745b9c1b51eSKate Stone m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), entity_name,
1746b9c1b51eSKate Stone user_type, m_parser_vars->m_target_info.byte_order,
17474dbb271fSSean Callanan m_parser_vars->m_target_info.address_byte_size));
17489301ec11SSean Callanan m_found_entities.AddNewlyConstructedVariable(entity);
17494dbb271fSSean Callanan
17504dbb271fSSean Callanan entity->EnableParserVars(GetParserID());
1751b9c1b51eSKate Stone ClangExpressionVariable::ParserVars *parser_vars =
1752b9c1b51eSKate Stone entity->GetParserVars(GetParserID());
17534dbb271fSSean Callanan
17544dbb271fSSean Callanan const Address symbol_address = symbol.GetAddress();
17554dbb271fSSean Callanan lldb::addr_t symbol_load_addr = symbol_address.GetLoadAddress(target);
17564dbb271fSSean Callanan
1757057efa99SAdrian Prantl // parser_vars->m_lldb_value.SetContext(Value::ContextType::ClangType,
1758b9c1b51eSKate Stone // user_type.GetOpaqueQualType());
17594dbb271fSSean Callanan parser_vars->m_lldb_value.SetCompilerType(user_type);
17604dbb271fSSean Callanan parser_vars->m_lldb_value.GetScalar() = symbol_load_addr;
1761057efa99SAdrian Prantl parser_vars->m_lldb_value.SetValueType(Value::ValueType::LoadAddress);
17624dbb271fSSean Callanan
17634dbb271fSSean Callanan parser_vars->m_named_decl = var_decl;
1764248a1305SKonrad Kleine parser_vars->m_llvm_value = nullptr;
17654dbb271fSSean Callanan parser_vars->m_lldb_sym = &symbol;
17664dbb271fSSean Callanan
1767f000de87SAdrian Prantl LLDB_LOG(log, " CEDM::FEVD Found variable {0}, returned\n{1}", decl_name,
1768e657a1ebSRaphael Isemann ClangUtil::DumpDecl(var_decl));
17694dbb271fSSean Callanan }
17704dbb271fSSean Callanan
AddOneRegister(NameSearchContext & context,const RegisterInfo * reg_info)1771b9c1b51eSKate Stone void ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context,
1772e657a1ebSRaphael Isemann const RegisterInfo *reg_info) {
1773a007a6d8SPavel Labath Log *log = GetLog(LLDBLog::Expressions);
17744dbb271fSSean Callanan
1775b9c1b51eSKate Stone CompilerType clang_type =
1776c214c92fSRaphael Isemann m_clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(
1777c214c92fSRaphael Isemann reg_info->encoding, reg_info->byte_size * 8);
17784dbb271fSSean Callanan
1779b9c1b51eSKate Stone if (!clang_type) {
1780fc0d11c9SRaphael Isemann LLDB_LOG(log, " Tried to add a type for {0}, but couldn't get one",
1781fc0d11c9SRaphael Isemann context.m_decl_name.getAsString());
17824dbb271fSSean Callanan return;
17834dbb271fSSean Callanan }
17844dbb271fSSean Callanan
17854dbb271fSSean Callanan TypeFromParser parser_clang_type(clang_type);
17864dbb271fSSean Callanan
17874dbb271fSSean Callanan NamedDecl *var_decl = context.AddVarDecl(parser_clang_type);
17884dbb271fSSean Callanan
1789b9c1b51eSKate Stone ClangExpressionVariable *entity(new ClangExpressionVariable(
1790b9c1b51eSKate Stone m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
17914dbb271fSSean Callanan m_parser_vars->m_target_info.byte_order,
17924dbb271fSSean Callanan m_parser_vars->m_target_info.address_byte_size));
17939301ec11SSean Callanan m_found_entities.AddNewlyConstructedVariable(entity);
17944dbb271fSSean Callanan
17954dbb271fSSean Callanan std::string decl_name(context.m_decl_name.getAsString());
17964dbb271fSSean Callanan entity->SetName(ConstString(decl_name.c_str()));
17974dbb271fSSean Callanan entity->SetRegisterInfo(reg_info);
17984dbb271fSSean Callanan entity->EnableParserVars(GetParserID());
1799b9c1b51eSKate Stone ClangExpressionVariable::ParserVars *parser_vars =
1800b9c1b51eSKate Stone entity->GetParserVars(GetParserID());
18014dbb271fSSean Callanan parser_vars->m_named_decl = var_decl;
1802248a1305SKonrad Kleine parser_vars->m_llvm_value = nullptr;
18034dbb271fSSean Callanan parser_vars->m_lldb_value.Clear();
18044dbb271fSSean Callanan entity->m_flags |= ClangExpressionVariable::EVBareRegister;
18054dbb271fSSean Callanan
1806f000de87SAdrian Prantl LLDB_LOG(log, " CEDM::FEVD Added register {0}, returned\n{1}",
1807e657a1ebSRaphael Isemann context.m_decl_name.getAsString(), ClangUtil::DumpDecl(var_decl));
18084dbb271fSSean Callanan }
18094dbb271fSSean Callanan
AddOneFunction(NameSearchContext & context,Function * function,Symbol * symbol)1810b9c1b51eSKate Stone void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
1811e657a1ebSRaphael Isemann Function *function,
1812e657a1ebSRaphael Isemann Symbol *symbol) {
18134dbb271fSSean Callanan assert(m_parser_vars.get());
18144dbb271fSSean Callanan
1815a007a6d8SPavel Labath Log *log = GetLog(LLDBLog::Expressions);
18164dbb271fSSean Callanan
1817248a1305SKonrad Kleine NamedDecl *function_decl = nullptr;
18184dbb271fSSean Callanan Address fun_address;
18194dbb271fSSean Callanan CompilerType function_clang_type;
18204dbb271fSSean Callanan
18214dbb271fSSean Callanan bool is_indirect_function = false;
18224dbb271fSSean Callanan
1823b9c1b51eSKate Stone if (function) {
18244dbb271fSSean Callanan Type *function_type = function->GetType();
18254dbb271fSSean Callanan
1826f5bb1d6cSLuke Drummond const auto lang = function->GetCompileUnit()->GetLanguage();
1827f5bb1d6cSLuke Drummond const auto name = function->GetMangled().GetMangledName().AsCString();
1828f5bb1d6cSLuke Drummond const bool extern_c = (Language::LanguageIsC(lang) &&
1829f5bb1d6cSLuke Drummond !CPlusPlusLanguage::IsCPPMangledName(name)) ||
1830f5bb1d6cSLuke Drummond (Language::LanguageIsObjC(lang) &&
1831f5bb1d6cSLuke Drummond !Language::LanguageIsCPlusPlus(lang));
18322a8fa2a8SSean Callanan
1833b9c1b51eSKate Stone if (!extern_c) {
18342a8fa2a8SSean Callanan TypeSystem *type_system = function->GetDeclContext().GetTypeSystem();
18356e3b0cc2SRaphael Isemann if (llvm::isa<TypeSystemClang>(type_system)) {
1836b9c1b51eSKate Stone clang::DeclContext *src_decl_context =
1837b9c1b51eSKate Stone (clang::DeclContext *)function->GetDeclContext()
1838b9c1b51eSKate Stone .GetOpaqueDeclContext();
1839b9c1b51eSKate Stone clang::FunctionDecl *src_function_decl =
1840b9c1b51eSKate Stone llvm::dyn_cast_or_null<clang::FunctionDecl>(src_decl_context);
184109e91ac6SSean Callanan if (src_function_decl &&
184209e91ac6SSean Callanan src_function_decl->getTemplateSpecializationInfo()) {
184309e91ac6SSean Callanan clang::FunctionTemplateDecl *function_template =
184409e91ac6SSean Callanan src_function_decl->getTemplateSpecializationInfo()->getTemplate();
184509e91ac6SSean Callanan clang::FunctionTemplateDecl *copied_function_template =
184609e91ac6SSean Callanan llvm::dyn_cast_or_null<clang::FunctionTemplateDecl>(
184768e44239SSean Callanan CopyDecl(function_template));
184809e91ac6SSean Callanan if (copied_function_template) {
184909e91ac6SSean Callanan if (log) {
185009e91ac6SSean Callanan StreamString ss;
185109e91ac6SSean Callanan
185209e91ac6SSean Callanan function->DumpSymbolContext(&ss);
185309e91ac6SSean Callanan
18547a6588abSRaphael Isemann LLDB_LOG(log,
1855e657a1ebSRaphael Isemann " CEDM::FEVD Imported decl for function template"
1856f000de87SAdrian Prantl " {0} (description {1}), returned\n{2}",
1857e657a1ebSRaphael Isemann copied_function_template->getNameAsString(),
18587a6588abSRaphael Isemann ss.GetData(),
18597a6588abSRaphael Isemann ClangUtil::DumpDecl(copied_function_template));
186009e91ac6SSean Callanan }
186109e91ac6SSean Callanan
186209e91ac6SSean Callanan context.AddNamedDecl(copied_function_template);
186309e91ac6SSean Callanan }
186409e91ac6SSean Callanan } else if (src_function_decl) {
1865b9c1b51eSKate Stone if (clang::FunctionDecl *copied_function_decl =
1866b9c1b51eSKate Stone llvm::dyn_cast_or_null<clang::FunctionDecl>(
186768e44239SSean Callanan CopyDecl(src_function_decl))) {
1868b9c1b51eSKate Stone if (log) {
18692a8fa2a8SSean Callanan StreamString ss;
18702a8fa2a8SSean Callanan
18712a8fa2a8SSean Callanan function->DumpSymbolContext(&ss);
18722a8fa2a8SSean Callanan
18737a6588abSRaphael Isemann LLDB_LOG(log,
1874f000de87SAdrian Prantl " CEDM::FEVD Imported decl for function {0} "
1875f000de87SAdrian Prantl "(description {1}), returned\n{2}",
1876e657a1ebSRaphael Isemann copied_function_decl->getNameAsString(), ss.GetData(),
1877e657a1ebSRaphael Isemann ClangUtil::DumpDecl(copied_function_decl));
18782a8fa2a8SSean Callanan }
18792a8fa2a8SSean Callanan
18802a8fa2a8SSean Callanan context.AddNamedDecl(copied_function_decl);
18812a8fa2a8SSean Callanan return;
1882b9c1b51eSKate Stone } else {
1883fc0d11c9SRaphael Isemann LLDB_LOG(log, " Failed to import the function decl for '{0}'",
1884fc0d11c9SRaphael Isemann src_function_decl->getName());
18852a8fa2a8SSean Callanan }
18862a8fa2a8SSean Callanan }
18872a8fa2a8SSean Callanan }
18882a8fa2a8SSean Callanan }
18892a8fa2a8SSean Callanan
1890b9c1b51eSKate Stone if (!function_type) {
1891fc0d11c9SRaphael Isemann LLDB_LOG(log, " Skipped a function because it has no type");
18924dbb271fSSean Callanan return;
18934dbb271fSSean Callanan }
18944dbb271fSSean Callanan
18954dbb271fSSean Callanan function_clang_type = function_type->GetFullCompilerType();
18964dbb271fSSean Callanan
1897b9c1b51eSKate Stone if (!function_clang_type) {
1898fc0d11c9SRaphael Isemann LLDB_LOG(log, " Skipped a function because it has no Clang type");
18994dbb271fSSean Callanan return;
19004dbb271fSSean Callanan }
19014dbb271fSSean Callanan
19024dbb271fSSean Callanan fun_address = function->GetAddressRange().GetBaseAddress();
19034dbb271fSSean Callanan
19044dbb271fSSean Callanan CompilerType copied_function_type = GuardedCopyType(function_clang_type);
1905b9c1b51eSKate Stone if (copied_function_type) {
19062a8fa2a8SSean Callanan function_decl = context.AddFunDecl(copied_function_type, extern_c);
19074dbb271fSSean Callanan
1908b9c1b51eSKate Stone if (!function_decl) {
1909fc0d11c9SRaphael Isemann LLDB_LOG(log, " Failed to create a function decl for '{0}' ({1:x})",
1910fc0d11c9SRaphael Isemann function_type->GetName(), function_type->GetID());
19114dbb271fSSean Callanan
19124dbb271fSSean Callanan return;
19134dbb271fSSean Callanan }
1914b9c1b51eSKate Stone } else {
19154dbb271fSSean Callanan // We failed to copy the type we found
1916fc0d11c9SRaphael Isemann LLDB_LOG(log,
1917fc0d11c9SRaphael Isemann " Failed to import the function type '{0}' ({1:x})"
1918fc0d11c9SRaphael Isemann " into the expression parser AST contenxt",
1919fc0d11c9SRaphael Isemann function_type->GetName(), function_type->GetID());
19204dbb271fSSean Callanan
19214dbb271fSSean Callanan return;
19224dbb271fSSean Callanan }
1923b9c1b51eSKate Stone } else if (symbol) {
19244dbb271fSSean Callanan fun_address = symbol->GetAddress();
19254dbb271fSSean Callanan function_decl = context.AddGenericFunDecl();
19264dbb271fSSean Callanan is_indirect_function = symbol->IsIndirect();
1927b9c1b51eSKate Stone } else {
1928fc0d11c9SRaphael Isemann LLDB_LOG(log, " AddOneFunction called with no function and no symbol");
19294dbb271fSSean Callanan return;
19304dbb271fSSean Callanan }
19314dbb271fSSean Callanan
19324dbb271fSSean Callanan Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
19334dbb271fSSean Callanan
1934b9c1b51eSKate Stone lldb::addr_t load_addr =
1935b9c1b51eSKate Stone fun_address.GetCallableLoadAddress(target, is_indirect_function);
19364dbb271fSSean Callanan
1937b9c1b51eSKate Stone ClangExpressionVariable *entity(new ClangExpressionVariable(
1938b9c1b51eSKate Stone m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
19394dbb271fSSean Callanan m_parser_vars->m_target_info.byte_order,
19404dbb271fSSean Callanan m_parser_vars->m_target_info.address_byte_size));
19419301ec11SSean Callanan m_found_entities.AddNewlyConstructedVariable(entity);
19424dbb271fSSean Callanan
19434dbb271fSSean Callanan std::string decl_name(context.m_decl_name.getAsString());
19444dbb271fSSean Callanan entity->SetName(ConstString(decl_name.c_str()));
19454dbb271fSSean Callanan entity->SetCompilerType(function_clang_type);
19464dbb271fSSean Callanan entity->EnableParserVars(GetParserID());
19474dbb271fSSean Callanan
1948b9c1b51eSKate Stone ClangExpressionVariable::ParserVars *parser_vars =
1949b9c1b51eSKate Stone entity->GetParserVars(GetParserID());
19504dbb271fSSean Callanan
1951b9c1b51eSKate Stone if (load_addr != LLDB_INVALID_ADDRESS) {
1952057efa99SAdrian Prantl parser_vars->m_lldb_value.SetValueType(Value::ValueType::LoadAddress);
19534dbb271fSSean Callanan parser_vars->m_lldb_value.GetScalar() = load_addr;
1954b9c1b51eSKate Stone } else {
19554dbb271fSSean Callanan // We have to try finding a file address.
19564dbb271fSSean Callanan
19574dbb271fSSean Callanan lldb::addr_t file_addr = fun_address.GetFileAddress();
19584dbb271fSSean Callanan
1959057efa99SAdrian Prantl parser_vars->m_lldb_value.SetValueType(Value::ValueType::FileAddress);
19604dbb271fSSean Callanan parser_vars->m_lldb_value.GetScalar() = file_addr;
19614dbb271fSSean Callanan }
19624dbb271fSSean Callanan
19634dbb271fSSean Callanan parser_vars->m_named_decl = function_decl;
1964248a1305SKonrad Kleine parser_vars->m_llvm_value = nullptr;
19654dbb271fSSean Callanan
1966b9c1b51eSKate Stone if (log) {
19674dbb271fSSean Callanan StreamString ss;
19684dbb271fSSean Callanan
1969b9c1b51eSKate Stone fun_address.Dump(&ss,
1970b9c1b51eSKate Stone m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
1971b9c1b51eSKate Stone Address::DumpStyleResolvedDescription);
19724dbb271fSSean Callanan
19737a6588abSRaphael Isemann LLDB_LOG(log,
1974f000de87SAdrian Prantl " CEDM::FEVD Found {0} function {1} (description {2}), "
1975f000de87SAdrian Prantl "returned\n{3}",
1976e657a1ebSRaphael Isemann (function ? "specific" : "generic"), decl_name, ss.GetData(),
1977e657a1ebSRaphael Isemann ClangUtil::DumpDecl(function_decl));
19784dbb271fSSean Callanan }
19794dbb271fSSean Callanan }
19804dbb271fSSean Callanan
AddContextClassType(NameSearchContext & context,const TypeFromUser & ut)19814125b462SRaphael Isemann void ClangExpressionDeclMap::AddContextClassType(NameSearchContext &context,
19824125b462SRaphael Isemann const TypeFromUser &ut) {
19834dbb271fSSean Callanan CompilerType copied_clang_type = GuardedCopyType(ut);
19844dbb271fSSean Callanan
1985a007a6d8SPavel Labath Log *log = GetLog(LLDBLog::Expressions);
198635e9ea38SPavel Labath
1987b9c1b51eSKate Stone if (!copied_clang_type) {
1988fc0d11c9SRaphael Isemann LLDB_LOG(log,
1989b9c1b51eSKate Stone "ClangExpressionDeclMap::AddThisType - Couldn't import the type");
19904dbb271fSSean Callanan
19913b436d23SSean Callanan return;
19924dbb271fSSean Callanan }
19934dbb271fSSean Callanan
1994b9c1b51eSKate Stone if (copied_clang_type.IsAggregateType() &&
1995b9c1b51eSKate Stone copied_clang_type.GetCompleteType()) {
1996bc7f1df6SRaphael Isemann CompilerType void_clang_type =
1997bc7f1df6SRaphael Isemann m_clang_ast_context->GetBasicType(eBasicTypeVoid);
19984dbb271fSSean Callanan CompilerType void_ptr_clang_type = void_clang_type.GetPointerType();
19994dbb271fSSean Callanan
20000007f9daSRaphael Isemann CompilerType method_type = m_clang_ast_context->CreateFunctionType(
20010007f9daSRaphael Isemann void_clang_type, &void_ptr_clang_type, 1, false, 0);
20024dbb271fSSean Callanan
20034dbb271fSSean Callanan const bool is_virtual = false;
20044125b462SRaphael Isemann const bool is_static = false;
20054dbb271fSSean Callanan const bool is_inline = false;
20064dbb271fSSean Callanan const bool is_explicit = false;
20074dbb271fSSean Callanan const bool is_attr_used = true;
20084dbb271fSSean Callanan const bool is_artificial = false;
20094dbb271fSSean Callanan
2010bc7f1df6SRaphael Isemann CXXMethodDecl *method_decl = m_clang_ast_context->AddMethodToCXXRecordType(
2011248a1305SKonrad Kleine copied_clang_type.GetOpaqueQualType(), "$__lldb_expr", nullptr,
2012bc7f1df6SRaphael Isemann method_type, lldb::eAccessPublic, is_virtual, is_static, is_inline,
2013bc7f1df6SRaphael Isemann is_explicit, is_attr_used, is_artificial);
20147736a208SSean Callanan
20157a6588abSRaphael Isemann LLDB_LOG(log,
201663e5fb76SJonas Devlieghere " CEDM::AddThisType Added function $__lldb_expr "
20177a6588abSRaphael Isemann "(description {0}) for this type\n{1}",
20187a6588abSRaphael Isemann ClangUtil::ToString(copied_clang_type),
20197a6588abSRaphael Isemann ClangUtil::DumpDecl(method_decl));
20204dbb271fSSean Callanan }
20214dbb271fSSean Callanan
20223b436d23SSean Callanan if (!copied_clang_type.IsValid())
20233b436d23SSean Callanan return;
20243b436d23SSean Callanan
2025b9c1b51eSKate Stone TypeSourceInfo *type_source_info = m_ast_context->getTrivialTypeSourceInfo(
2026b9c1b51eSKate Stone QualType::getFromOpaquePtr(copied_clang_type.GetOpaqueQualType()));
20273b436d23SSean Callanan
20283b436d23SSean Callanan if (!type_source_info)
20293b436d23SSean Callanan return;
20303b436d23SSean Callanan
2031b9c1b51eSKate Stone // Construct a typedef type because if "*this" is a templated type we can't
2032b9c1b51eSKate Stone // just return ClassTemplateSpecializationDecls in response to name queries.
20333b436d23SSean Callanan // Using a typedef makes this much more robust.
20343b436d23SSean Callanan
2035b9c1b51eSKate Stone TypedefDecl *typedef_decl = TypedefDecl::Create(
2036b9c1b51eSKate Stone *m_ast_context, m_ast_context->getTranslationUnitDecl(), SourceLocation(),
2037b9c1b51eSKate Stone SourceLocation(), context.m_decl_name.getAsIdentifierInfo(),
20383b436d23SSean Callanan type_source_info);
20393b436d23SSean Callanan
20403b436d23SSean Callanan if (!typedef_decl)
20413b436d23SSean Callanan return;
20423b436d23SSean Callanan
20433b436d23SSean Callanan context.AddNamedDecl(typedef_decl);
20444dbb271fSSean Callanan }
20454dbb271fSSean Callanan
AddOneType(NameSearchContext & context,const TypeFromUser & ut)2046b9c1b51eSKate Stone void ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
2047e657a1ebSRaphael Isemann const TypeFromUser &ut) {
20484dbb271fSSean Callanan CompilerType copied_clang_type = GuardedCopyType(ut);
20494dbb271fSSean Callanan
2050b9c1b51eSKate Stone if (!copied_clang_type) {
2051a007a6d8SPavel Labath Log *log = GetLog(LLDBLog::Expressions);
20524dbb271fSSean Callanan
2053fc0d11c9SRaphael Isemann LLDB_LOG(log,
2054fc0d11c9SRaphael Isemann "ClangExpressionDeclMap::AddOneType - Couldn't import the type");
20554dbb271fSSean Callanan
20564dbb271fSSean Callanan return;
20574dbb271fSSean Callanan }
20584dbb271fSSean Callanan
20594dbb271fSSean Callanan context.AddTypeDecl(copied_clang_type);
20604dbb271fSSean Callanan }
2061