1dda28197Spatrick //===-- ClangExpressionDeclMap.cpp ----------------------------------------===//
2061da546Spatrick //
3061da546Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4061da546Spatrick // See https://llvm.org/LICENSE.txt for license information.
5061da546Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6061da546Spatrick //
7061da546Spatrick //===----------------------------------------------------------------------===//
8061da546Spatrick
9061da546Spatrick #include "ClangExpressionDeclMap.h"
10061da546Spatrick
11061da546Spatrick #include "ClangASTSource.h"
12*f6aab3d8Srobert #include "ClangExpressionUtil.h"
13*f6aab3d8Srobert #include "ClangExpressionVariable.h"
14061da546Spatrick #include "ClangModulesDeclVendor.h"
15061da546Spatrick #include "ClangPersistentVariables.h"
16dda28197Spatrick #include "ClangUtil.h"
17061da546Spatrick
18*f6aab3d8Srobert #include "NameSearchContext.h"
19dda28197Spatrick #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
20061da546Spatrick #include "lldb/Core/Address.h"
21061da546Spatrick #include "lldb/Core/Module.h"
22061da546Spatrick #include "lldb/Core/ModuleSpec.h"
23061da546Spatrick #include "lldb/Core/ValueObjectConstResult.h"
24061da546Spatrick #include "lldb/Core/ValueObjectVariable.h"
25be691f3bSpatrick #include "lldb/Expression/DiagnosticManager.h"
26061da546Spatrick #include "lldb/Expression/Materializer.h"
27061da546Spatrick #include "lldb/Symbol/CompileUnit.h"
28061da546Spatrick #include "lldb/Symbol/CompilerDecl.h"
29061da546Spatrick #include "lldb/Symbol/CompilerDeclContext.h"
30061da546Spatrick #include "lldb/Symbol/Function.h"
31061da546Spatrick #include "lldb/Symbol/ObjectFile.h"
32061da546Spatrick #include "lldb/Symbol/SymbolContext.h"
33061da546Spatrick #include "lldb/Symbol/SymbolFile.h"
34061da546Spatrick #include "lldb/Symbol/SymbolVendor.h"
35061da546Spatrick #include "lldb/Symbol/Type.h"
36061da546Spatrick #include "lldb/Symbol/TypeList.h"
37061da546Spatrick #include "lldb/Symbol/Variable.h"
38061da546Spatrick #include "lldb/Symbol/VariableList.h"
39061da546Spatrick #include "lldb/Target/ExecutionContext.h"
40061da546Spatrick #include "lldb/Target/Process.h"
41061da546Spatrick #include "lldb/Target/RegisterContext.h"
42061da546Spatrick #include "lldb/Target/StackFrame.h"
43061da546Spatrick #include "lldb/Target/Target.h"
44061da546Spatrick #include "lldb/Target/Thread.h"
45061da546Spatrick #include "lldb/Utility/Endian.h"
46*f6aab3d8Srobert #include "lldb/Utility/LLDBLog.h"
47061da546Spatrick #include "lldb/Utility/Log.h"
48061da546Spatrick #include "lldb/Utility/RegisterValue.h"
49061da546Spatrick #include "lldb/Utility/Status.h"
50*f6aab3d8Srobert #include "lldb/lldb-private-types.h"
51061da546Spatrick #include "lldb/lldb-private.h"
52061da546Spatrick #include "clang/AST/ASTConsumer.h"
53061da546Spatrick #include "clang/AST/ASTContext.h"
54061da546Spatrick #include "clang/AST/ASTImporter.h"
55061da546Spatrick #include "clang/AST/Decl.h"
56061da546Spatrick #include "clang/AST/DeclarationName.h"
57061da546Spatrick #include "clang/AST/RecursiveASTVisitor.h"
58061da546Spatrick
59061da546Spatrick #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
60061da546Spatrick #include "Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h"
61061da546Spatrick #include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
62061da546Spatrick
63061da546Spatrick using namespace lldb;
64061da546Spatrick using namespace lldb_private;
65061da546Spatrick using namespace clang;
66061da546Spatrick
67*f6aab3d8Srobert static const char *g_lldb_local_vars_namespace_cstr = "$__lldb_local_vars";
68*f6aab3d8Srobert
69061da546Spatrick namespace {
70*f6aab3d8Srobert /// A lambda is represented by Clang as an artifical class whose
71*f6aab3d8Srobert /// members are the lambda captures. If we capture a 'this' pointer,
72*f6aab3d8Srobert /// the artifical class will contain a member variable named 'this'.
73*f6aab3d8Srobert /// The function returns a ValueObject for the captured 'this' if such
74*f6aab3d8Srobert /// member exists. If no 'this' was captured, return a nullptr.
GetCapturedThisValueObject(StackFrame * frame)75*f6aab3d8Srobert lldb::ValueObjectSP GetCapturedThisValueObject(StackFrame *frame) {
76*f6aab3d8Srobert assert(frame);
77*f6aab3d8Srobert
78*f6aab3d8Srobert if (auto thisValSP = frame->FindVariable(ConstString("this")))
79*f6aab3d8Srobert if (auto thisThisValSP =
80*f6aab3d8Srobert thisValSP->GetChildMemberWithName(ConstString("this"), true))
81*f6aab3d8Srobert return thisThisValSP;
82*f6aab3d8Srobert
83*f6aab3d8Srobert return nullptr;
84*f6aab3d8Srobert }
85*f6aab3d8Srobert } // namespace
86061da546Spatrick
ClangExpressionDeclMap(bool keep_result_in_memory,Materializer::PersistentVariableDelegate * result_delegate,const lldb::TargetSP & target,const std::shared_ptr<ClangASTImporter> & importer,ValueObject * ctx_obj)87061da546Spatrick ClangExpressionDeclMap::ClangExpressionDeclMap(
88061da546Spatrick bool keep_result_in_memory,
89061da546Spatrick Materializer::PersistentVariableDelegate *result_delegate,
90dda28197Spatrick const lldb::TargetSP &target,
91dda28197Spatrick const std::shared_ptr<ClangASTImporter> &importer, ValueObject *ctx_obj)
92061da546Spatrick : ClangASTSource(target, importer), m_found_entities(), m_struct_members(),
93061da546Spatrick m_keep_result_in_memory(keep_result_in_memory),
94061da546Spatrick m_result_delegate(result_delegate), m_ctx_obj(ctx_obj), m_parser_vars(),
95061da546Spatrick m_struct_vars() {
96061da546Spatrick EnableStructVars();
97061da546Spatrick }
98061da546Spatrick
~ClangExpressionDeclMap()99061da546Spatrick ClangExpressionDeclMap::~ClangExpressionDeclMap() {
100061da546Spatrick // Note: The model is now that the parser's AST context and all associated
101061da546Spatrick // data does not vanish until the expression has been executed. This means
102061da546Spatrick // that valuable lookup data (like namespaces) doesn't vanish, but
103061da546Spatrick
104061da546Spatrick DidParse();
105061da546Spatrick DisableStructVars();
106061da546Spatrick }
107061da546Spatrick
WillParse(ExecutionContext & exe_ctx,Materializer * materializer)108061da546Spatrick bool ClangExpressionDeclMap::WillParse(ExecutionContext &exe_ctx,
109061da546Spatrick Materializer *materializer) {
110061da546Spatrick EnableParserVars();
111061da546Spatrick m_parser_vars->m_exe_ctx = exe_ctx;
112061da546Spatrick
113061da546Spatrick Target *target = exe_ctx.GetTargetPtr();
114061da546Spatrick if (exe_ctx.GetFramePtr())
115061da546Spatrick m_parser_vars->m_sym_ctx =
116061da546Spatrick exe_ctx.GetFramePtr()->GetSymbolContext(lldb::eSymbolContextEverything);
117061da546Spatrick else if (exe_ctx.GetThreadPtr() &&
118061da546Spatrick exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(0))
119061da546Spatrick m_parser_vars->m_sym_ctx =
120061da546Spatrick exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(0)->GetSymbolContext(
121061da546Spatrick lldb::eSymbolContextEverything);
122061da546Spatrick else if (exe_ctx.GetProcessPtr()) {
123061da546Spatrick m_parser_vars->m_sym_ctx.Clear(true);
124061da546Spatrick m_parser_vars->m_sym_ctx.target_sp = exe_ctx.GetTargetSP();
125061da546Spatrick } else if (target) {
126061da546Spatrick m_parser_vars->m_sym_ctx.Clear(true);
127061da546Spatrick m_parser_vars->m_sym_ctx.target_sp = exe_ctx.GetTargetSP();
128061da546Spatrick }
129061da546Spatrick
130061da546Spatrick if (target) {
131061da546Spatrick m_parser_vars->m_persistent_vars = llvm::cast<ClangPersistentVariables>(
132061da546Spatrick target->GetPersistentExpressionStateForLanguage(eLanguageTypeC));
133061da546Spatrick
134be691f3bSpatrick if (!ScratchTypeSystemClang::GetForTarget(*target))
135061da546Spatrick return false;
136061da546Spatrick }
137061da546Spatrick
138061da546Spatrick m_parser_vars->m_target_info = GetTargetInfo();
139061da546Spatrick m_parser_vars->m_materializer = materializer;
140061da546Spatrick
141061da546Spatrick return true;
142061da546Spatrick }
143061da546Spatrick
InstallCodeGenerator(clang::ASTConsumer * code_gen)144061da546Spatrick void ClangExpressionDeclMap::InstallCodeGenerator(
145061da546Spatrick clang::ASTConsumer *code_gen) {
146061da546Spatrick assert(m_parser_vars);
147061da546Spatrick m_parser_vars->m_code_gen = code_gen;
148061da546Spatrick }
149061da546Spatrick
InstallDiagnosticManager(DiagnosticManager & diag_manager)150be691f3bSpatrick void ClangExpressionDeclMap::InstallDiagnosticManager(
151be691f3bSpatrick DiagnosticManager &diag_manager) {
152be691f3bSpatrick assert(m_parser_vars);
153be691f3bSpatrick m_parser_vars->m_diagnostics = &diag_manager;
154be691f3bSpatrick }
155be691f3bSpatrick
DidParse()156061da546Spatrick void ClangExpressionDeclMap::DidParse() {
157061da546Spatrick if (m_parser_vars && m_parser_vars->m_persistent_vars) {
158061da546Spatrick for (size_t entity_index = 0, num_entities = m_found_entities.GetSize();
159061da546Spatrick entity_index < num_entities; ++entity_index) {
160061da546Spatrick ExpressionVariableSP var_sp(
161061da546Spatrick m_found_entities.GetVariableAtIndex(entity_index));
162061da546Spatrick if (var_sp)
163061da546Spatrick llvm::cast<ClangExpressionVariable>(var_sp.get())
164061da546Spatrick ->DisableParserVars(GetParserID());
165061da546Spatrick }
166061da546Spatrick
167061da546Spatrick for (size_t pvar_index = 0,
168061da546Spatrick num_pvars = m_parser_vars->m_persistent_vars->GetSize();
169061da546Spatrick pvar_index < num_pvars; ++pvar_index) {
170061da546Spatrick ExpressionVariableSP pvar_sp(
171061da546Spatrick m_parser_vars->m_persistent_vars->GetVariableAtIndex(pvar_index));
172061da546Spatrick if (ClangExpressionVariable *clang_var =
173061da546Spatrick llvm::dyn_cast<ClangExpressionVariable>(pvar_sp.get()))
174061da546Spatrick clang_var->DisableParserVars(GetParserID());
175061da546Spatrick }
176061da546Spatrick
177061da546Spatrick DisableParserVars();
178061da546Spatrick }
179061da546Spatrick }
180061da546Spatrick
181061da546Spatrick // Interface for IRForTarget
182061da546Spatrick
GetTargetInfo()183061da546Spatrick ClangExpressionDeclMap::TargetInfo ClangExpressionDeclMap::GetTargetInfo() {
184061da546Spatrick assert(m_parser_vars.get());
185061da546Spatrick
186061da546Spatrick TargetInfo ret;
187061da546Spatrick
188061da546Spatrick ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
189061da546Spatrick
190061da546Spatrick Process *process = exe_ctx.GetProcessPtr();
191061da546Spatrick if (process) {
192061da546Spatrick ret.byte_order = process->GetByteOrder();
193061da546Spatrick ret.address_byte_size = process->GetAddressByteSize();
194061da546Spatrick } else {
195061da546Spatrick Target *target = exe_ctx.GetTargetPtr();
196061da546Spatrick if (target) {
197061da546Spatrick ret.byte_order = target->GetArchitecture().GetByteOrder();
198061da546Spatrick ret.address_byte_size = target->GetArchitecture().GetAddressByteSize();
199061da546Spatrick }
200061da546Spatrick }
201061da546Spatrick
202061da546Spatrick return ret;
203061da546Spatrick }
204061da546Spatrick
DeportType(TypeSystemClang & target,TypeSystemClang & source,TypeFromParser parser_type)205dda28197Spatrick TypeFromUser ClangExpressionDeclMap::DeportType(TypeSystemClang &target,
206dda28197Spatrick TypeSystemClang &source,
207061da546Spatrick TypeFromParser parser_type) {
208*f6aab3d8Srobert assert(&target == GetScratchContext(*m_target).get());
209*f6aab3d8Srobert assert((TypeSystem *)&source ==
210*f6aab3d8Srobert parser_type.GetTypeSystem().GetSharedPointer().get());
211061da546Spatrick assert(&source.getASTContext() == m_ast_context);
212061da546Spatrick
213061da546Spatrick return TypeFromUser(m_ast_importer_sp->DeportType(target, parser_type));
214061da546Spatrick }
215061da546Spatrick
AddPersistentVariable(const NamedDecl * decl,ConstString name,TypeFromParser parser_type,bool is_result,bool is_lvalue)216061da546Spatrick bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
217061da546Spatrick ConstString name,
218061da546Spatrick TypeFromParser parser_type,
219061da546Spatrick bool is_result,
220061da546Spatrick bool is_lvalue) {
221061da546Spatrick assert(m_parser_vars.get());
222*f6aab3d8Srobert auto ast = parser_type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>();
223061da546Spatrick if (ast == nullptr)
224061da546Spatrick return false;
225061da546Spatrick
226be691f3bSpatrick // Check if we already declared a persistent variable with the same name.
227be691f3bSpatrick if (lldb::ExpressionVariableSP conflicting_var =
228be691f3bSpatrick m_parser_vars->m_persistent_vars->GetVariable(name)) {
229be691f3bSpatrick std::string msg = llvm::formatv("redefinition of persistent variable '{0}'",
230be691f3bSpatrick name).str();
231be691f3bSpatrick m_parser_vars->m_diagnostics->AddDiagnostic(
232be691f3bSpatrick msg, DiagnosticSeverity::eDiagnosticSeverityError,
233be691f3bSpatrick DiagnosticOrigin::eDiagnosticOriginLLDB);
234be691f3bSpatrick return false;
235be691f3bSpatrick }
236be691f3bSpatrick
237061da546Spatrick if (m_parser_vars->m_materializer && is_result) {
238061da546Spatrick Status err;
239061da546Spatrick
240061da546Spatrick ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
241061da546Spatrick Target *target = exe_ctx.GetTargetPtr();
242061da546Spatrick if (target == nullptr)
243061da546Spatrick return false;
244061da546Spatrick
245*f6aab3d8Srobert auto clang_ast_context = GetScratchContext(*target);
246061da546Spatrick if (!clang_ast_context)
247061da546Spatrick return false;
248061da546Spatrick
249061da546Spatrick TypeFromUser user_type = DeportType(*clang_ast_context, *ast, parser_type);
250061da546Spatrick
251061da546Spatrick uint32_t offset = m_parser_vars->m_materializer->AddResultVariable(
252061da546Spatrick user_type, is_lvalue, m_keep_result_in_memory, m_result_delegate, err);
253061da546Spatrick
254061da546Spatrick ClangExpressionVariable *var = new ClangExpressionVariable(
255061da546Spatrick exe_ctx.GetBestExecutionContextScope(), name, user_type,
256061da546Spatrick m_parser_vars->m_target_info.byte_order,
257061da546Spatrick m_parser_vars->m_target_info.address_byte_size);
258061da546Spatrick
259061da546Spatrick m_found_entities.AddNewlyConstructedVariable(var);
260061da546Spatrick
261061da546Spatrick var->EnableParserVars(GetParserID());
262061da546Spatrick
263061da546Spatrick ClangExpressionVariable::ParserVars *parser_vars =
264061da546Spatrick var->GetParserVars(GetParserID());
265061da546Spatrick
266061da546Spatrick parser_vars->m_named_decl = decl;
267061da546Spatrick
268061da546Spatrick var->EnableJITVars(GetParserID());
269061da546Spatrick
270061da546Spatrick ClangExpressionVariable::JITVars *jit_vars = var->GetJITVars(GetParserID());
271061da546Spatrick
272061da546Spatrick jit_vars->m_offset = offset;
273061da546Spatrick
274061da546Spatrick return true;
275061da546Spatrick }
276061da546Spatrick
277*f6aab3d8Srobert Log *log = GetLog(LLDBLog::Expressions);
278061da546Spatrick ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
279061da546Spatrick Target *target = exe_ctx.GetTargetPtr();
280061da546Spatrick if (target == nullptr)
281061da546Spatrick return false;
282061da546Spatrick
283*f6aab3d8Srobert auto context = GetScratchContext(*target);
284061da546Spatrick if (!context)
285061da546Spatrick return false;
286061da546Spatrick
287061da546Spatrick TypeFromUser user_type = DeportType(*context, *ast, parser_type);
288061da546Spatrick
289061da546Spatrick if (!user_type.GetOpaqueQualType()) {
290dda28197Spatrick LLDB_LOG(log, "Persistent variable's type wasn't copied successfully");
291061da546Spatrick return false;
292061da546Spatrick }
293061da546Spatrick
294061da546Spatrick if (!m_parser_vars->m_target_info.IsValid())
295061da546Spatrick return false;
296061da546Spatrick
297061da546Spatrick if (!m_parser_vars->m_persistent_vars)
298061da546Spatrick return false;
299061da546Spatrick
300061da546Spatrick ClangExpressionVariable *var = llvm::cast<ClangExpressionVariable>(
301061da546Spatrick m_parser_vars->m_persistent_vars
302061da546Spatrick ->CreatePersistentVariable(
303061da546Spatrick exe_ctx.GetBestExecutionContextScope(), name, user_type,
304061da546Spatrick m_parser_vars->m_target_info.byte_order,
305061da546Spatrick m_parser_vars->m_target_info.address_byte_size)
306061da546Spatrick .get());
307061da546Spatrick
308061da546Spatrick if (!var)
309061da546Spatrick return false;
310061da546Spatrick
311061da546Spatrick var->m_frozen_sp->SetHasCompleteType();
312061da546Spatrick
313061da546Spatrick if (is_result)
314061da546Spatrick var->m_flags |= ClangExpressionVariable::EVNeedsFreezeDry;
315061da546Spatrick else
316061da546Spatrick var->m_flags |=
317061da546Spatrick ClangExpressionVariable::EVKeepInTarget; // explicitly-declared
318061da546Spatrick // persistent variables should
319061da546Spatrick // persist
320061da546Spatrick
321061da546Spatrick if (is_lvalue) {
322061da546Spatrick var->m_flags |= ClangExpressionVariable::EVIsProgramReference;
323061da546Spatrick } else {
324061da546Spatrick var->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated;
325061da546Spatrick var->m_flags |= ClangExpressionVariable::EVNeedsAllocation;
326061da546Spatrick }
327061da546Spatrick
328061da546Spatrick if (m_keep_result_in_memory) {
329061da546Spatrick var->m_flags |= ClangExpressionVariable::EVKeepInTarget;
330061da546Spatrick }
331061da546Spatrick
332dda28197Spatrick LLDB_LOG(log, "Created persistent variable with flags {0:x}", var->m_flags);
333061da546Spatrick
334061da546Spatrick var->EnableParserVars(GetParserID());
335061da546Spatrick
336061da546Spatrick ClangExpressionVariable::ParserVars *parser_vars =
337061da546Spatrick var->GetParserVars(GetParserID());
338061da546Spatrick
339061da546Spatrick parser_vars->m_named_decl = decl;
340061da546Spatrick
341061da546Spatrick return true;
342061da546Spatrick }
343061da546Spatrick
AddValueToStruct(const NamedDecl * decl,ConstString name,llvm::Value * value,size_t size,lldb::offset_t alignment)344061da546Spatrick bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl,
345061da546Spatrick ConstString name,
346061da546Spatrick llvm::Value *value, size_t size,
347061da546Spatrick lldb::offset_t alignment) {
348061da546Spatrick assert(m_struct_vars.get());
349061da546Spatrick assert(m_parser_vars.get());
350061da546Spatrick
351061da546Spatrick bool is_persistent_variable = false;
352061da546Spatrick
353*f6aab3d8Srobert Log *log = GetLog(LLDBLog::Expressions);
354061da546Spatrick
355061da546Spatrick m_struct_vars->m_struct_laid_out = false;
356061da546Spatrick
357061da546Spatrick if (ClangExpressionVariable::FindVariableInList(m_struct_members, decl,
358061da546Spatrick GetParserID()))
359061da546Spatrick return true;
360061da546Spatrick
361061da546Spatrick ClangExpressionVariable *var(ClangExpressionVariable::FindVariableInList(
362061da546Spatrick m_found_entities, decl, GetParserID()));
363061da546Spatrick
364061da546Spatrick if (!var && m_parser_vars->m_persistent_vars) {
365061da546Spatrick var = ClangExpressionVariable::FindVariableInList(
366061da546Spatrick *m_parser_vars->m_persistent_vars, decl, GetParserID());
367061da546Spatrick is_persistent_variable = true;
368061da546Spatrick }
369061da546Spatrick
370061da546Spatrick if (!var)
371061da546Spatrick return false;
372061da546Spatrick
373be691f3bSpatrick LLDB_LOG(log, "Adding value for (NamedDecl*){0} [{1} - {2}] to the structure",
374dda28197Spatrick decl, name, var->GetName());
375061da546Spatrick
376061da546Spatrick // We know entity->m_parser_vars is valid because we used a parser variable
377061da546Spatrick // to find it
378061da546Spatrick
379061da546Spatrick ClangExpressionVariable::ParserVars *parser_vars =
380061da546Spatrick llvm::cast<ClangExpressionVariable>(var)->GetParserVars(GetParserID());
381061da546Spatrick
382061da546Spatrick parser_vars->m_llvm_value = value;
383061da546Spatrick
384061da546Spatrick if (ClangExpressionVariable::JITVars *jit_vars =
385061da546Spatrick llvm::cast<ClangExpressionVariable>(var)->GetJITVars(GetParserID())) {
386061da546Spatrick // We already laid this out; do not touch
387061da546Spatrick
388dda28197Spatrick LLDB_LOG(log, "Already placed at {0:x}", jit_vars->m_offset);
389061da546Spatrick }
390061da546Spatrick
391061da546Spatrick llvm::cast<ClangExpressionVariable>(var)->EnableJITVars(GetParserID());
392061da546Spatrick
393061da546Spatrick ClangExpressionVariable::JITVars *jit_vars =
394061da546Spatrick llvm::cast<ClangExpressionVariable>(var)->GetJITVars(GetParserID());
395061da546Spatrick
396061da546Spatrick jit_vars->m_alignment = alignment;
397061da546Spatrick jit_vars->m_size = size;
398061da546Spatrick
399061da546Spatrick m_struct_members.AddVariable(var->shared_from_this());
400061da546Spatrick
401061da546Spatrick if (m_parser_vars->m_materializer) {
402061da546Spatrick uint32_t offset = 0;
403061da546Spatrick
404061da546Spatrick Status err;
405061da546Spatrick
406061da546Spatrick if (is_persistent_variable) {
407061da546Spatrick ExpressionVariableSP var_sp(var->shared_from_this());
408061da546Spatrick offset = m_parser_vars->m_materializer->AddPersistentVariable(
409061da546Spatrick var_sp, nullptr, err);
410061da546Spatrick } else {
411061da546Spatrick if (const lldb_private::Symbol *sym = parser_vars->m_lldb_sym)
412061da546Spatrick offset = m_parser_vars->m_materializer->AddSymbol(*sym, err);
413061da546Spatrick else if (const RegisterInfo *reg_info = var->GetRegisterInfo())
414061da546Spatrick offset = m_parser_vars->m_materializer->AddRegister(*reg_info, err);
415061da546Spatrick else if (parser_vars->m_lldb_var)
416061da546Spatrick offset = m_parser_vars->m_materializer->AddVariable(
417061da546Spatrick parser_vars->m_lldb_var, err);
418*f6aab3d8Srobert else if (parser_vars->m_lldb_valobj_provider) {
419*f6aab3d8Srobert offset = m_parser_vars->m_materializer->AddValueObject(
420*f6aab3d8Srobert name, parser_vars->m_lldb_valobj_provider, err);
421*f6aab3d8Srobert }
422061da546Spatrick }
423061da546Spatrick
424061da546Spatrick if (!err.Success())
425061da546Spatrick return false;
426061da546Spatrick
427dda28197Spatrick LLDB_LOG(log, "Placed at {0:x}", offset);
428061da546Spatrick
429061da546Spatrick jit_vars->m_offset =
430061da546Spatrick offset; // TODO DoStructLayout() should not change this.
431061da546Spatrick }
432061da546Spatrick
433061da546Spatrick return true;
434061da546Spatrick }
435061da546Spatrick
DoStructLayout()436061da546Spatrick bool ClangExpressionDeclMap::DoStructLayout() {
437061da546Spatrick assert(m_struct_vars.get());
438061da546Spatrick
439061da546Spatrick if (m_struct_vars->m_struct_laid_out)
440061da546Spatrick return true;
441061da546Spatrick
442061da546Spatrick if (!m_parser_vars->m_materializer)
443061da546Spatrick return false;
444061da546Spatrick
445061da546Spatrick m_struct_vars->m_struct_alignment =
446061da546Spatrick m_parser_vars->m_materializer->GetStructAlignment();
447061da546Spatrick m_struct_vars->m_struct_size =
448061da546Spatrick m_parser_vars->m_materializer->GetStructByteSize();
449061da546Spatrick m_struct_vars->m_struct_laid_out = true;
450061da546Spatrick return true;
451061da546Spatrick }
452061da546Spatrick
GetStructInfo(uint32_t & num_elements,size_t & size,lldb::offset_t & alignment)453061da546Spatrick bool ClangExpressionDeclMap::GetStructInfo(uint32_t &num_elements, size_t &size,
454061da546Spatrick lldb::offset_t &alignment) {
455061da546Spatrick assert(m_struct_vars.get());
456061da546Spatrick
457061da546Spatrick if (!m_struct_vars->m_struct_laid_out)
458061da546Spatrick return false;
459061da546Spatrick
460061da546Spatrick num_elements = m_struct_members.GetSize();
461061da546Spatrick size = m_struct_vars->m_struct_size;
462061da546Spatrick alignment = m_struct_vars->m_struct_alignment;
463061da546Spatrick
464061da546Spatrick return true;
465061da546Spatrick }
466061da546Spatrick
GetStructElement(const NamedDecl * & decl,llvm::Value * & value,lldb::offset_t & offset,ConstString & name,uint32_t index)467061da546Spatrick bool ClangExpressionDeclMap::GetStructElement(const NamedDecl *&decl,
468061da546Spatrick llvm::Value *&value,
469061da546Spatrick lldb::offset_t &offset,
470061da546Spatrick ConstString &name,
471061da546Spatrick uint32_t index) {
472061da546Spatrick assert(m_struct_vars.get());
473061da546Spatrick
474061da546Spatrick if (!m_struct_vars->m_struct_laid_out)
475061da546Spatrick return false;
476061da546Spatrick
477061da546Spatrick if (index >= m_struct_members.GetSize())
478061da546Spatrick return false;
479061da546Spatrick
480061da546Spatrick ExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(index));
481061da546Spatrick
482061da546Spatrick if (!member_sp)
483061da546Spatrick return false;
484061da546Spatrick
485061da546Spatrick ClangExpressionVariable::ParserVars *parser_vars =
486061da546Spatrick llvm::cast<ClangExpressionVariable>(member_sp.get())
487061da546Spatrick ->GetParserVars(GetParserID());
488061da546Spatrick ClangExpressionVariable::JITVars *jit_vars =
489061da546Spatrick llvm::cast<ClangExpressionVariable>(member_sp.get())
490061da546Spatrick ->GetJITVars(GetParserID());
491061da546Spatrick
492061da546Spatrick if (!parser_vars || !jit_vars || !member_sp->GetValueObject())
493061da546Spatrick return false;
494061da546Spatrick
495061da546Spatrick decl = parser_vars->m_named_decl;
496061da546Spatrick value = parser_vars->m_llvm_value;
497061da546Spatrick offset = jit_vars->m_offset;
498061da546Spatrick name = member_sp->GetName();
499061da546Spatrick
500061da546Spatrick return true;
501061da546Spatrick }
502061da546Spatrick
GetFunctionInfo(const NamedDecl * decl,uint64_t & ptr)503061da546Spatrick bool ClangExpressionDeclMap::GetFunctionInfo(const NamedDecl *decl,
504061da546Spatrick uint64_t &ptr) {
505061da546Spatrick ClangExpressionVariable *entity(ClangExpressionVariable::FindVariableInList(
506061da546Spatrick m_found_entities, decl, GetParserID()));
507061da546Spatrick
508061da546Spatrick if (!entity)
509061da546Spatrick return false;
510061da546Spatrick
511061da546Spatrick // We know m_parser_vars is valid since we searched for the variable by its
512061da546Spatrick // NamedDecl
513061da546Spatrick
514061da546Spatrick ClangExpressionVariable::ParserVars *parser_vars =
515061da546Spatrick entity->GetParserVars(GetParserID());
516061da546Spatrick
517061da546Spatrick ptr = parser_vars->m_lldb_value.GetScalar().ULongLong();
518061da546Spatrick
519061da546Spatrick return true;
520061da546Spatrick }
521061da546Spatrick
GetSymbolAddress(Target & target,Process * process,ConstString name,lldb::SymbolType symbol_type,lldb_private::Module * module)522061da546Spatrick addr_t ClangExpressionDeclMap::GetSymbolAddress(Target &target,
523061da546Spatrick Process *process,
524061da546Spatrick ConstString name,
525061da546Spatrick lldb::SymbolType symbol_type,
526061da546Spatrick lldb_private::Module *module) {
527061da546Spatrick SymbolContextList sc_list;
528061da546Spatrick
529061da546Spatrick if (module)
530061da546Spatrick module->FindSymbolsWithNameAndType(name, symbol_type, sc_list);
531061da546Spatrick else
532061da546Spatrick target.GetImages().FindSymbolsWithNameAndType(name, symbol_type, sc_list);
533061da546Spatrick
534061da546Spatrick const uint32_t num_matches = sc_list.GetSize();
535061da546Spatrick addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
536061da546Spatrick
537061da546Spatrick for (uint32_t i = 0;
538061da546Spatrick i < num_matches &&
539061da546Spatrick (symbol_load_addr == 0 || symbol_load_addr == LLDB_INVALID_ADDRESS);
540061da546Spatrick i++) {
541061da546Spatrick SymbolContext sym_ctx;
542061da546Spatrick sc_list.GetContextAtIndex(i, sym_ctx);
543061da546Spatrick
544061da546Spatrick const Address sym_address = sym_ctx.symbol->GetAddress();
545061da546Spatrick
546061da546Spatrick if (!sym_address.IsValid())
547061da546Spatrick continue;
548061da546Spatrick
549061da546Spatrick switch (sym_ctx.symbol->GetType()) {
550061da546Spatrick case eSymbolTypeCode:
551061da546Spatrick case eSymbolTypeTrampoline:
552061da546Spatrick symbol_load_addr = sym_address.GetCallableLoadAddress(&target);
553061da546Spatrick break;
554061da546Spatrick
555061da546Spatrick case eSymbolTypeResolver:
556061da546Spatrick symbol_load_addr = sym_address.GetCallableLoadAddress(&target, true);
557061da546Spatrick break;
558061da546Spatrick
559061da546Spatrick case eSymbolTypeReExported: {
560061da546Spatrick ConstString reexport_name = sym_ctx.symbol->GetReExportedSymbolName();
561061da546Spatrick if (reexport_name) {
562061da546Spatrick ModuleSP reexport_module_sp;
563061da546Spatrick ModuleSpec reexport_module_spec;
564061da546Spatrick reexport_module_spec.GetPlatformFileSpec() =
565061da546Spatrick sym_ctx.symbol->GetReExportedSymbolSharedLibrary();
566061da546Spatrick if (reexport_module_spec.GetPlatformFileSpec()) {
567061da546Spatrick reexport_module_sp =
568061da546Spatrick target.GetImages().FindFirstModule(reexport_module_spec);
569061da546Spatrick if (!reexport_module_sp) {
570*f6aab3d8Srobert reexport_module_spec.GetPlatformFileSpec().ClearDirectory();
571061da546Spatrick reexport_module_sp =
572061da546Spatrick target.GetImages().FindFirstModule(reexport_module_spec);
573061da546Spatrick }
574061da546Spatrick }
575061da546Spatrick symbol_load_addr = GetSymbolAddress(
576061da546Spatrick target, process, sym_ctx.symbol->GetReExportedSymbolName(),
577061da546Spatrick symbol_type, reexport_module_sp.get());
578061da546Spatrick }
579061da546Spatrick } break;
580061da546Spatrick
581061da546Spatrick case eSymbolTypeData:
582061da546Spatrick case eSymbolTypeRuntime:
583061da546Spatrick case eSymbolTypeVariable:
584061da546Spatrick case eSymbolTypeLocal:
585061da546Spatrick case eSymbolTypeParam:
586061da546Spatrick case eSymbolTypeInvalid:
587061da546Spatrick case eSymbolTypeAbsolute:
588061da546Spatrick case eSymbolTypeException:
589061da546Spatrick case eSymbolTypeSourceFile:
590061da546Spatrick case eSymbolTypeHeaderFile:
591061da546Spatrick case eSymbolTypeObjectFile:
592061da546Spatrick case eSymbolTypeCommonBlock:
593061da546Spatrick case eSymbolTypeBlock:
594061da546Spatrick case eSymbolTypeVariableType:
595061da546Spatrick case eSymbolTypeLineEntry:
596061da546Spatrick case eSymbolTypeLineHeader:
597061da546Spatrick case eSymbolTypeScopeBegin:
598061da546Spatrick case eSymbolTypeScopeEnd:
599061da546Spatrick case eSymbolTypeAdditional:
600061da546Spatrick case eSymbolTypeCompiler:
601061da546Spatrick case eSymbolTypeInstrumentation:
602061da546Spatrick case eSymbolTypeUndefined:
603061da546Spatrick case eSymbolTypeObjCClass:
604061da546Spatrick case eSymbolTypeObjCMetaClass:
605061da546Spatrick case eSymbolTypeObjCIVar:
606061da546Spatrick symbol_load_addr = sym_address.GetLoadAddress(&target);
607061da546Spatrick break;
608061da546Spatrick }
609061da546Spatrick }
610061da546Spatrick
611061da546Spatrick if (symbol_load_addr == LLDB_INVALID_ADDRESS && process) {
612061da546Spatrick ObjCLanguageRuntime *runtime = ObjCLanguageRuntime::Get(*process);
613061da546Spatrick
614061da546Spatrick if (runtime) {
615061da546Spatrick symbol_load_addr = runtime->LookupRuntimeSymbol(name);
616061da546Spatrick }
617061da546Spatrick }
618061da546Spatrick
619061da546Spatrick return symbol_load_addr;
620061da546Spatrick }
621061da546Spatrick
GetSymbolAddress(ConstString name,lldb::SymbolType symbol_type)622061da546Spatrick addr_t ClangExpressionDeclMap::GetSymbolAddress(ConstString name,
623061da546Spatrick lldb::SymbolType symbol_type) {
624061da546Spatrick assert(m_parser_vars.get());
625061da546Spatrick
626061da546Spatrick if (!m_parser_vars->m_exe_ctx.GetTargetPtr())
627061da546Spatrick return false;
628061da546Spatrick
629061da546Spatrick return GetSymbolAddress(m_parser_vars->m_exe_ctx.GetTargetRef(),
630061da546Spatrick m_parser_vars->m_exe_ctx.GetProcessPtr(), name,
631061da546Spatrick symbol_type);
632061da546Spatrick }
633061da546Spatrick
FindGlobalVariable(Target & target,ModuleSP & module,ConstString name,const CompilerDeclContext & namespace_decl)634061da546Spatrick lldb::VariableSP ClangExpressionDeclMap::FindGlobalVariable(
635061da546Spatrick Target &target, ModuleSP &module, ConstString name,
636dda28197Spatrick const CompilerDeclContext &namespace_decl) {
637061da546Spatrick VariableList vars;
638061da546Spatrick
639061da546Spatrick if (module && namespace_decl)
640061da546Spatrick module->FindGlobalVariables(name, namespace_decl, -1, vars);
641061da546Spatrick else
642061da546Spatrick target.GetImages().FindGlobalVariables(name, -1, vars);
643061da546Spatrick
644061da546Spatrick if (vars.GetSize() == 0)
645061da546Spatrick return VariableSP();
646061da546Spatrick return vars.GetVariableAtIndex(0);
647061da546Spatrick }
648061da546Spatrick
GetTypeSystemClang()649dda28197Spatrick TypeSystemClang *ClangExpressionDeclMap::GetTypeSystemClang() {
650061da546Spatrick StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
651061da546Spatrick if (frame == nullptr)
652061da546Spatrick return nullptr;
653061da546Spatrick
654061da546Spatrick SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
655061da546Spatrick lldb::eSymbolContextBlock);
656061da546Spatrick if (sym_ctx.block == nullptr)
657061da546Spatrick return nullptr;
658061da546Spatrick
659061da546Spatrick CompilerDeclContext frame_decl_context = sym_ctx.block->GetDeclContext();
660061da546Spatrick if (!frame_decl_context)
661061da546Spatrick return nullptr;
662061da546Spatrick
663dda28197Spatrick return llvm::dyn_cast_or_null<TypeSystemClang>(
664061da546Spatrick frame_decl_context.GetTypeSystem());
665061da546Spatrick }
666061da546Spatrick
667061da546Spatrick // Interface for ClangASTSource
668061da546Spatrick
FindExternalVisibleDecls(NameSearchContext & context)669061da546Spatrick void ClangExpressionDeclMap::FindExternalVisibleDecls(
670061da546Spatrick NameSearchContext &context) {
671061da546Spatrick assert(m_ast_context);
672061da546Spatrick
673061da546Spatrick const ConstString name(context.m_decl_name.getAsString().c_str());
674061da546Spatrick
675*f6aab3d8Srobert Log *log = GetLog(LLDBLog::Expressions);
676061da546Spatrick
677061da546Spatrick if (log) {
678061da546Spatrick if (!context.m_decl_context)
679dda28197Spatrick LLDB_LOG(log,
680dda28197Spatrick "ClangExpressionDeclMap::FindExternalVisibleDecls for "
681dda28197Spatrick "'{0}' in a NULL DeclContext",
682dda28197Spatrick name);
683061da546Spatrick else if (const NamedDecl *context_named_decl =
684061da546Spatrick dyn_cast<NamedDecl>(context.m_decl_context))
685dda28197Spatrick LLDB_LOG(log,
686dda28197Spatrick "ClangExpressionDeclMap::FindExternalVisibleDecls for "
687dda28197Spatrick "'{0}' in '{1}'",
688dda28197Spatrick name, context_named_decl->getNameAsString());
689061da546Spatrick else
690dda28197Spatrick LLDB_LOG(log,
691dda28197Spatrick "ClangExpressionDeclMap::FindExternalVisibleDecls for "
692dda28197Spatrick "'{0}' in a '{1}'",
693dda28197Spatrick name, context.m_decl_context->getDeclKindName());
694061da546Spatrick }
695061da546Spatrick
696061da546Spatrick if (const NamespaceDecl *namespace_context =
697061da546Spatrick dyn_cast<NamespaceDecl>(context.m_decl_context)) {
698061da546Spatrick if (namespace_context->getName().str() ==
699061da546Spatrick std::string(g_lldb_local_vars_namespace_cstr)) {
700061da546Spatrick CompilerDeclContext compiler_decl_ctx =
701061da546Spatrick m_clang_ast_context->CreateDeclContext(
702061da546Spatrick const_cast<clang::DeclContext *>(context.m_decl_context));
703dda28197Spatrick FindExternalVisibleDecls(context, lldb::ModuleSP(), compiler_decl_ctx);
704061da546Spatrick return;
705061da546Spatrick }
706061da546Spatrick
707061da546Spatrick ClangASTImporter::NamespaceMapSP namespace_map =
708dda28197Spatrick m_ast_importer_sp->GetNamespaceMap(namespace_context);
709061da546Spatrick
710061da546Spatrick if (!namespace_map)
711061da546Spatrick return;
712061da546Spatrick
713dda28197Spatrick LLDB_LOGV(log, " CEDM::FEVD Inspecting (NamespaceMap*){0:x} ({1} entries)",
714dda28197Spatrick namespace_map.get(), namespace_map->size());
715061da546Spatrick
716dda28197Spatrick for (ClangASTImporter::NamespaceMapItem &n : *namespace_map) {
717dda28197Spatrick LLDB_LOG(log, " CEDM::FEVD Searching namespace {0} in module {1}",
718dda28197Spatrick n.second.GetName(), n.first->GetFileSpec().GetFilename());
719061da546Spatrick
720dda28197Spatrick FindExternalVisibleDecls(context, n.first, n.second);
721061da546Spatrick }
722061da546Spatrick } else if (isa<TranslationUnitDecl>(context.m_decl_context)) {
723061da546Spatrick CompilerDeclContext namespace_decl;
724061da546Spatrick
725dda28197Spatrick LLDB_LOG(log, " CEDM::FEVD Searching the root namespace");
726061da546Spatrick
727dda28197Spatrick FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl);
728061da546Spatrick }
729061da546Spatrick
730061da546Spatrick ClangASTSource::FindExternalVisibleDecls(context);
731061da546Spatrick }
732061da546Spatrick
MaybeRegisterFunctionBody(FunctionDecl * copied_function_decl)733061da546Spatrick void ClangExpressionDeclMap::MaybeRegisterFunctionBody(
734061da546Spatrick FunctionDecl *copied_function_decl) {
735061da546Spatrick if (copied_function_decl->getBody() && m_parser_vars->m_code_gen) {
736061da546Spatrick clang::DeclGroupRef decl_group_ref(copied_function_decl);
737061da546Spatrick m_parser_vars->m_code_gen->HandleTopLevelDecl(decl_group_ref);
738061da546Spatrick }
739061da546Spatrick }
740061da546Spatrick
GetPersistentDecl(ConstString name)741061da546Spatrick clang::NamedDecl *ClangExpressionDeclMap::GetPersistentDecl(ConstString name) {
742061da546Spatrick if (!m_parser_vars)
743061da546Spatrick return nullptr;
744061da546Spatrick Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
745061da546Spatrick if (!target)
746061da546Spatrick return nullptr;
747061da546Spatrick
748be691f3bSpatrick ScratchTypeSystemClang::GetForTarget(*target);
749061da546Spatrick
750061da546Spatrick if (!m_parser_vars->m_persistent_vars)
751061da546Spatrick return nullptr;
752061da546Spatrick return m_parser_vars->m_persistent_vars->GetPersistentDecl(name);
753061da546Spatrick }
754061da546Spatrick
SearchPersistenDecls(NameSearchContext & context,const ConstString name)755061da546Spatrick void ClangExpressionDeclMap::SearchPersistenDecls(NameSearchContext &context,
756dda28197Spatrick const ConstString name) {
757*f6aab3d8Srobert Log *log = GetLog(LLDBLog::Expressions);
758061da546Spatrick
759061da546Spatrick NamedDecl *persistent_decl = GetPersistentDecl(name);
760061da546Spatrick
761061da546Spatrick if (!persistent_decl)
762061da546Spatrick return;
763061da546Spatrick
764061da546Spatrick Decl *parser_persistent_decl = CopyDecl(persistent_decl);
765061da546Spatrick
766061da546Spatrick if (!parser_persistent_decl)
767061da546Spatrick return;
768061da546Spatrick
769061da546Spatrick NamedDecl *parser_named_decl = dyn_cast<NamedDecl>(parser_persistent_decl);
770061da546Spatrick
771061da546Spatrick if (!parser_named_decl)
772061da546Spatrick return;
773061da546Spatrick
774061da546Spatrick if (clang::FunctionDecl *parser_function_decl =
775061da546Spatrick llvm::dyn_cast<clang::FunctionDecl>(parser_named_decl)) {
776061da546Spatrick MaybeRegisterFunctionBody(parser_function_decl);
777061da546Spatrick }
778061da546Spatrick
779be691f3bSpatrick LLDB_LOG(log, " CEDM::FEVD Found persistent decl {0}", name);
780061da546Spatrick
781061da546Spatrick context.AddNamedDecl(parser_named_decl);
782061da546Spatrick }
783061da546Spatrick
LookUpLldbClass(NameSearchContext & context)784dda28197Spatrick void ClangExpressionDeclMap::LookUpLldbClass(NameSearchContext &context) {
785*f6aab3d8Srobert Log *log = GetLog(LLDBLog::Expressions);
786061da546Spatrick
787061da546Spatrick StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
788061da546Spatrick SymbolContext sym_ctx;
789061da546Spatrick if (frame != nullptr)
790061da546Spatrick sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
791061da546Spatrick lldb::eSymbolContextBlock);
792061da546Spatrick
793061da546Spatrick if (m_ctx_obj) {
794061da546Spatrick Status status;
795061da546Spatrick lldb::ValueObjectSP ctx_obj_ptr = m_ctx_obj->AddressOf(status);
796061da546Spatrick if (!ctx_obj_ptr || status.Fail())
797061da546Spatrick return;
798061da546Spatrick
799dda28197Spatrick AddContextClassType(context, TypeFromUser(m_ctx_obj->GetCompilerType()));
800061da546Spatrick return;
801061da546Spatrick }
802061da546Spatrick
803061da546Spatrick // Clang is looking for the type of "this"
804061da546Spatrick
805061da546Spatrick if (frame == nullptr)
806061da546Spatrick return;
807061da546Spatrick
808061da546Spatrick // Find the block that defines the function represented by "sym_ctx"
809061da546Spatrick Block *function_block = sym_ctx.GetFunctionBlock();
810061da546Spatrick
811061da546Spatrick if (!function_block)
812061da546Spatrick return;
813061da546Spatrick
814061da546Spatrick CompilerDeclContext function_decl_ctx = function_block->GetDeclContext();
815061da546Spatrick
816061da546Spatrick if (!function_decl_ctx)
817061da546Spatrick return;
818061da546Spatrick
819061da546Spatrick clang::CXXMethodDecl *method_decl =
820dda28197Spatrick TypeSystemClang::DeclContextGetAsCXXMethodDecl(function_decl_ctx);
821061da546Spatrick
822061da546Spatrick if (method_decl) {
823*f6aab3d8Srobert if (auto capturedThis = GetCapturedThisValueObject(frame)) {
824*f6aab3d8Srobert // We're inside a lambda and we captured a 'this'.
825*f6aab3d8Srobert // Import the outer class's AST instead of the
826*f6aab3d8Srobert // (unnamed) lambda structure AST so unqualified
827*f6aab3d8Srobert // member lookups are understood by the Clang parser.
828*f6aab3d8Srobert //
829*f6aab3d8Srobert // If we're in a lambda which didn't capture 'this',
830*f6aab3d8Srobert // $__lldb_class will correspond to the lambda closure
831*f6aab3d8Srobert // AST and references to captures will resolve like
832*f6aab3d8Srobert // regular member varaiable accesses do.
833*f6aab3d8Srobert TypeFromUser pointee_type =
834*f6aab3d8Srobert capturedThis->GetCompilerType().GetPointeeType();
835*f6aab3d8Srobert
836*f6aab3d8Srobert LLDB_LOG(log,
837*f6aab3d8Srobert " CEDM::FEVD Adding captured type ({0} for"
838*f6aab3d8Srobert " $__lldb_class: {1}",
839*f6aab3d8Srobert capturedThis->GetTypeName(), capturedThis->GetName());
840*f6aab3d8Srobert
841*f6aab3d8Srobert AddContextClassType(context, pointee_type);
842*f6aab3d8Srobert return;
843*f6aab3d8Srobert }
844*f6aab3d8Srobert
845061da546Spatrick clang::CXXRecordDecl *class_decl = method_decl->getParent();
846061da546Spatrick
847061da546Spatrick QualType class_qual_type(class_decl->getTypeForDecl(), 0);
848061da546Spatrick
849*f6aab3d8Srobert TypeFromUser class_user_type(
850*f6aab3d8Srobert class_qual_type.getAsOpaquePtr(),
851*f6aab3d8Srobert function_decl_ctx.GetTypeSystem()->weak_from_this());
852061da546Spatrick
853*f6aab3d8Srobert LLDB_LOG(log, " CEDM::FEVD Adding type for $__lldb_class: {0}",
854dda28197Spatrick class_qual_type.getAsString());
855061da546Spatrick
856dda28197Spatrick AddContextClassType(context, class_user_type);
857061da546Spatrick return;
858061da546Spatrick }
859061da546Spatrick
860061da546Spatrick // This branch will get hit if we are executing code in the context of
861061da546Spatrick // a function that claims to have an object pointer (through
862061da546Spatrick // DW_AT_object_pointer?) but is not formally a method of the class.
863061da546Spatrick // In that case, just look up the "this" variable in the current scope
864061da546Spatrick // and use its type.
865061da546Spatrick // FIXME: This code is formally correct, but clang doesn't currently
866061da546Spatrick // emit DW_AT_object_pointer
867061da546Spatrick // for C++ so it hasn't actually been tested.
868061da546Spatrick
869*f6aab3d8Srobert VariableList *vars = frame->GetVariableList(false, nullptr);
870061da546Spatrick
871061da546Spatrick lldb::VariableSP this_var = vars->FindVariable(ConstString("this"));
872061da546Spatrick
873061da546Spatrick if (this_var && this_var->IsInScope(frame) &&
874061da546Spatrick this_var->LocationIsValidForFrame(frame)) {
875061da546Spatrick Type *this_type = this_var->GetType();
876061da546Spatrick
877061da546Spatrick if (!this_type)
878061da546Spatrick return;
879061da546Spatrick
880061da546Spatrick TypeFromUser pointee_type =
881061da546Spatrick this_type->GetForwardCompilerType().GetPointeeType();
882061da546Spatrick
883*f6aab3d8Srobert LLDB_LOG(log, " FEVD Adding type for $__lldb_class: {0}",
884061da546Spatrick ClangUtil::GetQualType(pointee_type).getAsString());
885061da546Spatrick
886dda28197Spatrick AddContextClassType(context, pointee_type);
887061da546Spatrick }
888061da546Spatrick }
889061da546Spatrick
LookUpLldbObjCClass(NameSearchContext & context)890dda28197Spatrick void ClangExpressionDeclMap::LookUpLldbObjCClass(NameSearchContext &context) {
891*f6aab3d8Srobert Log *log = GetLog(LLDBLog::Expressions);
892061da546Spatrick
893061da546Spatrick StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
894061da546Spatrick
895061da546Spatrick if (m_ctx_obj) {
896061da546Spatrick Status status;
897061da546Spatrick lldb::ValueObjectSP ctx_obj_ptr = m_ctx_obj->AddressOf(status);
898061da546Spatrick if (!ctx_obj_ptr || status.Fail())
899061da546Spatrick return;
900061da546Spatrick
901dda28197Spatrick AddOneType(context, TypeFromUser(m_ctx_obj->GetCompilerType()));
902061da546Spatrick return;
903061da546Spatrick }
904061da546Spatrick
905061da546Spatrick // Clang is looking for the type of "*self"
906061da546Spatrick
907061da546Spatrick if (!frame)
908061da546Spatrick return;
909061da546Spatrick
910061da546Spatrick SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
911061da546Spatrick lldb::eSymbolContextBlock);
912061da546Spatrick
913061da546Spatrick // Find the block that defines the function represented by "sym_ctx"
914061da546Spatrick Block *function_block = sym_ctx.GetFunctionBlock();
915061da546Spatrick
916061da546Spatrick if (!function_block)
917061da546Spatrick return;
918061da546Spatrick
919061da546Spatrick CompilerDeclContext function_decl_ctx = function_block->GetDeclContext();
920061da546Spatrick
921061da546Spatrick if (!function_decl_ctx)
922061da546Spatrick return;
923061da546Spatrick
924061da546Spatrick clang::ObjCMethodDecl *method_decl =
925dda28197Spatrick TypeSystemClang::DeclContextGetAsObjCMethodDecl(function_decl_ctx);
926061da546Spatrick
927061da546Spatrick if (method_decl) {
928061da546Spatrick ObjCInterfaceDecl *self_interface = method_decl->getClassInterface();
929061da546Spatrick
930061da546Spatrick if (!self_interface)
931061da546Spatrick return;
932061da546Spatrick
933061da546Spatrick const clang::Type *interface_type = self_interface->getTypeForDecl();
934061da546Spatrick
935061da546Spatrick if (!interface_type)
936061da546Spatrick return; // This is unlikely, but we have seen crashes where this
937061da546Spatrick // occurred
938061da546Spatrick
939*f6aab3d8Srobert TypeFromUser class_user_type(
940*f6aab3d8Srobert QualType(interface_type, 0).getAsOpaquePtr(),
941*f6aab3d8Srobert function_decl_ctx.GetTypeSystem()->weak_from_this());
942061da546Spatrick
943061da546Spatrick LLDB_LOG(log, " FEVD[{0}] Adding type for $__lldb_objc_class: {1}",
944dda28197Spatrick ClangUtil::ToString(interface_type));
945061da546Spatrick
946dda28197Spatrick AddOneType(context, class_user_type);
947061da546Spatrick return;
948061da546Spatrick }
949061da546Spatrick // This branch will get hit if we are executing code in the context of
950061da546Spatrick // a function that claims to have an object pointer (through
951061da546Spatrick // DW_AT_object_pointer?) but is not formally a method of the class.
952061da546Spatrick // In that case, just look up the "self" variable in the current scope
953061da546Spatrick // and use its type.
954061da546Spatrick
955*f6aab3d8Srobert VariableList *vars = frame->GetVariableList(false, nullptr);
956061da546Spatrick
957061da546Spatrick lldb::VariableSP self_var = vars->FindVariable(ConstString("self"));
958061da546Spatrick
959061da546Spatrick if (!self_var)
960061da546Spatrick return;
961061da546Spatrick if (!self_var->IsInScope(frame))
962061da546Spatrick return;
963061da546Spatrick if (!self_var->LocationIsValidForFrame(frame))
964061da546Spatrick return;
965061da546Spatrick
966061da546Spatrick Type *self_type = self_var->GetType();
967061da546Spatrick
968061da546Spatrick if (!self_type)
969061da546Spatrick return;
970061da546Spatrick
971061da546Spatrick CompilerType self_clang_type = self_type->GetFullCompilerType();
972061da546Spatrick
973dda28197Spatrick if (TypeSystemClang::IsObjCClassType(self_clang_type)) {
974061da546Spatrick return;
975061da546Spatrick }
976dda28197Spatrick if (!TypeSystemClang::IsObjCObjectPointerType(self_clang_type))
977061da546Spatrick return;
978061da546Spatrick self_clang_type = self_clang_type.GetPointeeType();
979061da546Spatrick
980061da546Spatrick if (!self_clang_type)
981061da546Spatrick return;
982061da546Spatrick
983061da546Spatrick LLDB_LOG(log, " FEVD[{0}] Adding type for $__lldb_objc_class: {1}",
984dda28197Spatrick ClangUtil::ToString(self_type->GetFullCompilerType()));
985061da546Spatrick
986061da546Spatrick TypeFromUser class_user_type(self_clang_type);
987061da546Spatrick
988dda28197Spatrick AddOneType(context, class_user_type);
989061da546Spatrick }
990061da546Spatrick
LookupLocalVarNamespace(SymbolContext & sym_ctx,NameSearchContext & name_context)991061da546Spatrick void ClangExpressionDeclMap::LookupLocalVarNamespace(
992061da546Spatrick SymbolContext &sym_ctx, NameSearchContext &name_context) {
993061da546Spatrick if (sym_ctx.block == nullptr)
994061da546Spatrick return;
995061da546Spatrick
996061da546Spatrick CompilerDeclContext frame_decl_context = sym_ctx.block->GetDeclContext();
997061da546Spatrick if (!frame_decl_context)
998061da546Spatrick return;
999061da546Spatrick
1000dda28197Spatrick TypeSystemClang *frame_ast = llvm::dyn_cast_or_null<TypeSystemClang>(
1001061da546Spatrick frame_decl_context.GetTypeSystem());
1002061da546Spatrick if (!frame_ast)
1003061da546Spatrick return;
1004061da546Spatrick
1005061da546Spatrick clang::NamespaceDecl *namespace_decl =
1006061da546Spatrick m_clang_ast_context->GetUniqueNamespaceDeclaration(
1007dda28197Spatrick g_lldb_local_vars_namespace_cstr, nullptr, OptionalClangModuleID());
1008061da546Spatrick if (!namespace_decl)
1009061da546Spatrick return;
1010061da546Spatrick
1011061da546Spatrick name_context.AddNamedDecl(namespace_decl);
1012061da546Spatrick clang::DeclContext *ctxt = clang::Decl::castToDeclContext(namespace_decl);
1013061da546Spatrick ctxt->setHasExternalVisibleStorage(true);
1014dda28197Spatrick name_context.m_found_local_vars_nsp = true;
1015061da546Spatrick }
1016061da546Spatrick
LookupInModulesDeclVendor(NameSearchContext & context,ConstString name)1017061da546Spatrick void ClangExpressionDeclMap::LookupInModulesDeclVendor(
1018dda28197Spatrick NameSearchContext &context, ConstString name) {
1019*f6aab3d8Srobert Log *log = GetLog(LLDBLog::Expressions);
1020061da546Spatrick
1021061da546Spatrick if (!m_target)
1022061da546Spatrick return;
1023061da546Spatrick
1024be691f3bSpatrick std::shared_ptr<ClangModulesDeclVendor> modules_decl_vendor =
1025be691f3bSpatrick GetClangModulesDeclVendor();
1026061da546Spatrick if (!modules_decl_vendor)
1027061da546Spatrick return;
1028061da546Spatrick
1029061da546Spatrick bool append = false;
1030061da546Spatrick uint32_t max_matches = 1;
1031061da546Spatrick std::vector<clang::NamedDecl *> decls;
1032061da546Spatrick
1033061da546Spatrick if (!modules_decl_vendor->FindDecls(name, append, max_matches, decls))
1034061da546Spatrick return;
1035061da546Spatrick
1036061da546Spatrick assert(!decls.empty() && "FindDecls returned true but no decls?");
1037061da546Spatrick clang::NamedDecl *const decl_from_modules = decls[0];
1038061da546Spatrick
1039061da546Spatrick LLDB_LOG(log,
1040dda28197Spatrick " CAS::FEVD Matching decl found for "
1041*f6aab3d8Srobert "\"{0}\" in the modules",
1042dda28197Spatrick name);
1043061da546Spatrick
1044061da546Spatrick clang::Decl *copied_decl = CopyDecl(decl_from_modules);
1045061da546Spatrick if (!copied_decl) {
1046dda28197Spatrick LLDB_LOG(log, " CAS::FEVD - Couldn't export a "
1047dda28197Spatrick "declaration from the modules");
1048061da546Spatrick return;
1049061da546Spatrick }
1050061da546Spatrick
1051061da546Spatrick if (auto copied_function = dyn_cast<clang::FunctionDecl>(copied_decl)) {
1052061da546Spatrick MaybeRegisterFunctionBody(copied_function);
1053061da546Spatrick
1054061da546Spatrick context.AddNamedDecl(copied_function);
1055061da546Spatrick
1056dda28197Spatrick context.m_found_function_with_type_info = true;
1057dda28197Spatrick context.m_found_function = true;
1058061da546Spatrick } else if (auto copied_var = dyn_cast<clang::VarDecl>(copied_decl)) {
1059061da546Spatrick context.AddNamedDecl(copied_var);
1060dda28197Spatrick context.m_found_variable = true;
1061061da546Spatrick }
1062061da546Spatrick }
1063061da546Spatrick
LookupLocalVariable(NameSearchContext & context,ConstString name,SymbolContext & sym_ctx,const CompilerDeclContext & namespace_decl)1064061da546Spatrick bool ClangExpressionDeclMap::LookupLocalVariable(
1065dda28197Spatrick NameSearchContext &context, ConstString name, SymbolContext &sym_ctx,
1066dda28197Spatrick const CompilerDeclContext &namespace_decl) {
1067061da546Spatrick if (sym_ctx.block == nullptr)
1068061da546Spatrick return false;
1069061da546Spatrick
1070061da546Spatrick CompilerDeclContext decl_context = sym_ctx.block->GetDeclContext();
1071061da546Spatrick if (!decl_context)
1072061da546Spatrick return false;
1073061da546Spatrick
1074061da546Spatrick // Make sure that the variables are parsed so that we have the
1075061da546Spatrick // declarations.
1076061da546Spatrick StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
1077061da546Spatrick VariableListSP vars = frame->GetInScopeVariableList(true);
1078061da546Spatrick for (size_t i = 0; i < vars->GetSize(); i++)
1079061da546Spatrick vars->GetVariableAtIndex(i)->GetDecl();
1080061da546Spatrick
1081061da546Spatrick // Search for declarations matching the name. Do not include imported
1082061da546Spatrick // decls in the search if we are looking for decls in the artificial
1083061da546Spatrick // namespace $__lldb_local_vars.
1084061da546Spatrick std::vector<CompilerDecl> found_decls =
1085061da546Spatrick decl_context.FindDeclByName(name, namespace_decl.IsValid());
1086061da546Spatrick
1087061da546Spatrick VariableSP var;
1088061da546Spatrick bool variable_found = false;
1089061da546Spatrick for (CompilerDecl decl : found_decls) {
1090061da546Spatrick for (size_t vi = 0, ve = vars->GetSize(); vi != ve; ++vi) {
1091061da546Spatrick VariableSP candidate_var = vars->GetVariableAtIndex(vi);
1092061da546Spatrick if (candidate_var->GetDecl() == decl) {
1093061da546Spatrick var = candidate_var;
1094061da546Spatrick break;
1095061da546Spatrick }
1096061da546Spatrick }
1097061da546Spatrick
1098061da546Spatrick if (var && !variable_found) {
1099061da546Spatrick variable_found = true;
1100061da546Spatrick ValueObjectSP valobj = ValueObjectVariable::Create(frame, var);
1101dda28197Spatrick AddOneVariable(context, var, valobj);
1102dda28197Spatrick context.m_found_variable = true;
1103061da546Spatrick }
1104061da546Spatrick }
1105*f6aab3d8Srobert
1106*f6aab3d8Srobert // We're in a local_var_lookup but haven't found any local variables
1107*f6aab3d8Srobert // so far. When performing a variable lookup from within the context of
1108*f6aab3d8Srobert // a lambda, we count the lambda captures as local variables. Thus,
1109*f6aab3d8Srobert // see if we captured any variables with the requested 'name'.
1110*f6aab3d8Srobert if (!variable_found) {
1111*f6aab3d8Srobert auto find_capture = [](ConstString varname,
1112*f6aab3d8Srobert StackFrame *frame) -> ValueObjectSP {
1113*f6aab3d8Srobert if (auto lambda = ClangExpressionUtil::GetLambdaValueObject(frame)) {
1114*f6aab3d8Srobert if (auto capture = lambda->GetChildMemberWithName(varname, true)) {
1115*f6aab3d8Srobert return capture;
1116*f6aab3d8Srobert }
1117*f6aab3d8Srobert }
1118*f6aab3d8Srobert
1119*f6aab3d8Srobert return nullptr;
1120*f6aab3d8Srobert };
1121*f6aab3d8Srobert
1122*f6aab3d8Srobert if (auto capture = find_capture(name, frame)) {
1123*f6aab3d8Srobert variable_found = true;
1124*f6aab3d8Srobert context.m_found_variable = true;
1125*f6aab3d8Srobert AddOneVariable(context, std::move(capture), std::move(find_capture));
1126*f6aab3d8Srobert }
1127*f6aab3d8Srobert }
1128*f6aab3d8Srobert
1129061da546Spatrick return variable_found;
1130061da546Spatrick }
1131061da546Spatrick
1132061da546Spatrick /// Structure to hold the info needed when comparing function
1133061da546Spatrick /// declarations.
1134061da546Spatrick namespace {
1135061da546Spatrick struct FuncDeclInfo {
1136061da546Spatrick ConstString m_name;
1137061da546Spatrick CompilerType m_copied_type;
1138061da546Spatrick uint32_t m_decl_lvl;
1139061da546Spatrick SymbolContext m_sym_ctx;
1140061da546Spatrick };
1141061da546Spatrick } // namespace
1142061da546Spatrick
SearchFunctionsInSymbolContexts(const SymbolContextList & sc_list,const CompilerDeclContext & frame_decl_context)1143061da546Spatrick SymbolContextList ClangExpressionDeclMap::SearchFunctionsInSymbolContexts(
1144061da546Spatrick const SymbolContextList &sc_list,
1145061da546Spatrick const CompilerDeclContext &frame_decl_context) {
1146061da546Spatrick // First, symplify things by looping through the symbol contexts to
1147061da546Spatrick // remove unwanted functions and separate out the functions we want to
1148061da546Spatrick // compare and prune into a separate list. Cache the info needed about
1149061da546Spatrick // the function declarations in a vector for efficiency.
1150061da546Spatrick uint32_t num_indices = sc_list.GetSize();
1151061da546Spatrick SymbolContextList sc_sym_list;
1152061da546Spatrick std::vector<FuncDeclInfo> decl_infos;
1153061da546Spatrick decl_infos.reserve(num_indices);
1154061da546Spatrick clang::DeclContext *frame_decl_ctx =
1155061da546Spatrick (clang::DeclContext *)frame_decl_context.GetOpaqueDeclContext();
1156dda28197Spatrick TypeSystemClang *ast = llvm::dyn_cast_or_null<TypeSystemClang>(
1157061da546Spatrick frame_decl_context.GetTypeSystem());
1158061da546Spatrick
1159061da546Spatrick for (uint32_t index = 0; index < num_indices; ++index) {
1160061da546Spatrick FuncDeclInfo fdi;
1161061da546Spatrick SymbolContext sym_ctx;
1162061da546Spatrick sc_list.GetContextAtIndex(index, sym_ctx);
1163061da546Spatrick
1164061da546Spatrick // We don't know enough about symbols to compare them, but we should
1165061da546Spatrick // keep them in the list.
1166061da546Spatrick Function *function = sym_ctx.function;
1167061da546Spatrick if (!function) {
1168061da546Spatrick sc_sym_list.Append(sym_ctx);
1169061da546Spatrick continue;
1170061da546Spatrick }
1171061da546Spatrick // Filter out functions without declaration contexts, as well as
1172061da546Spatrick // class/instance methods, since they'll be skipped in the code that
1173061da546Spatrick // follows anyway.
1174061da546Spatrick CompilerDeclContext func_decl_context = function->GetDeclContext();
1175061da546Spatrick if (!func_decl_context ||
1176061da546Spatrick func_decl_context.IsClassMethod(nullptr, nullptr, nullptr))
1177061da546Spatrick continue;
1178061da546Spatrick // We can only prune functions for which we can copy the type.
1179061da546Spatrick CompilerType func_clang_type = function->GetType()->GetFullCompilerType();
1180061da546Spatrick CompilerType copied_func_type = GuardedCopyType(func_clang_type);
1181061da546Spatrick if (!copied_func_type) {
1182061da546Spatrick sc_sym_list.Append(sym_ctx);
1183061da546Spatrick continue;
1184061da546Spatrick }
1185061da546Spatrick
1186061da546Spatrick fdi.m_sym_ctx = sym_ctx;
1187061da546Spatrick fdi.m_name = function->GetName();
1188061da546Spatrick fdi.m_copied_type = copied_func_type;
1189061da546Spatrick fdi.m_decl_lvl = LLDB_INVALID_DECL_LEVEL;
1190061da546Spatrick if (fdi.m_copied_type && func_decl_context) {
1191061da546Spatrick // Call CountDeclLevels to get the number of parent scopes we have
1192061da546Spatrick // to look through before we find the function declaration. When
1193061da546Spatrick // comparing functions of the same type, the one with a lower count
1194061da546Spatrick // will be closer to us in the lookup scope and shadows the other.
1195061da546Spatrick clang::DeclContext *func_decl_ctx =
1196061da546Spatrick (clang::DeclContext *)func_decl_context.GetOpaqueDeclContext();
1197061da546Spatrick fdi.m_decl_lvl = ast->CountDeclLevels(frame_decl_ctx, func_decl_ctx,
1198061da546Spatrick &fdi.m_name, &fdi.m_copied_type);
1199061da546Spatrick }
1200061da546Spatrick decl_infos.emplace_back(fdi);
1201061da546Spatrick }
1202061da546Spatrick
1203061da546Spatrick // Loop through the functions in our cache looking for matching types,
1204061da546Spatrick // then compare their scope levels to see which is closer.
1205061da546Spatrick std::multimap<CompilerType, const FuncDeclInfo *> matches;
1206061da546Spatrick for (const FuncDeclInfo &fdi : decl_infos) {
1207061da546Spatrick const CompilerType t = fdi.m_copied_type;
1208061da546Spatrick auto q = matches.find(t);
1209061da546Spatrick if (q != matches.end()) {
1210061da546Spatrick if (q->second->m_decl_lvl > fdi.m_decl_lvl)
1211061da546Spatrick // This function is closer; remove the old set.
1212061da546Spatrick matches.erase(t);
1213061da546Spatrick else if (q->second->m_decl_lvl < fdi.m_decl_lvl)
1214061da546Spatrick // The functions in our set are closer - skip this one.
1215061da546Spatrick continue;
1216061da546Spatrick }
1217061da546Spatrick matches.insert(std::make_pair(t, &fdi));
1218061da546Spatrick }
1219061da546Spatrick
1220061da546Spatrick // Loop through our matches and add their symbol contexts to our list.
1221061da546Spatrick SymbolContextList sc_func_list;
1222061da546Spatrick for (const auto &q : matches)
1223061da546Spatrick sc_func_list.Append(q.second->m_sym_ctx);
1224061da546Spatrick
1225061da546Spatrick // Rejoin the lists with the functions in front.
1226061da546Spatrick sc_func_list.Append(sc_sym_list);
1227061da546Spatrick return sc_func_list;
1228061da546Spatrick }
1229061da546Spatrick
LookupFunction(NameSearchContext & context,lldb::ModuleSP module_sp,ConstString name,const CompilerDeclContext & namespace_decl)1230dda28197Spatrick void ClangExpressionDeclMap::LookupFunction(
1231dda28197Spatrick NameSearchContext &context, lldb::ModuleSP module_sp, ConstString name,
1232dda28197Spatrick const CompilerDeclContext &namespace_decl) {
1233061da546Spatrick if (!m_parser_vars)
1234061da546Spatrick return;
1235061da546Spatrick
1236061da546Spatrick Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
1237061da546Spatrick
1238061da546Spatrick std::vector<clang::NamedDecl *> decls_from_modules;
1239061da546Spatrick
1240061da546Spatrick if (target) {
1241be691f3bSpatrick if (std::shared_ptr<ClangModulesDeclVendor> decl_vendor =
1242be691f3bSpatrick GetClangModulesDeclVendor()) {
1243061da546Spatrick decl_vendor->FindDecls(name, false, UINT32_MAX, decls_from_modules);
1244061da546Spatrick }
1245061da546Spatrick }
1246061da546Spatrick
1247061da546Spatrick SymbolContextList sc_list;
1248061da546Spatrick if (namespace_decl && module_sp) {
1249*f6aab3d8Srobert ModuleFunctionSearchOptions function_options;
1250*f6aab3d8Srobert function_options.include_inlines = false;
1251*f6aab3d8Srobert function_options.include_symbols = false;
1252061da546Spatrick
1253dda28197Spatrick module_sp->FindFunctions(name, namespace_decl, eFunctionNameTypeBase,
1254*f6aab3d8Srobert function_options, sc_list);
1255061da546Spatrick } else if (target && !namespace_decl) {
1256*f6aab3d8Srobert ModuleFunctionSearchOptions function_options;
1257*f6aab3d8Srobert function_options.include_inlines = false;
1258*f6aab3d8Srobert function_options.include_symbols = true;
1259061da546Spatrick
1260061da546Spatrick // TODO Fix FindFunctions so that it doesn't return
1261061da546Spatrick // instance methods for eFunctionNameTypeBase.
1262061da546Spatrick
1263061da546Spatrick target->GetImages().FindFunctions(
1264*f6aab3d8Srobert name, eFunctionNameTypeFull | eFunctionNameTypeBase, function_options,
1265*f6aab3d8Srobert sc_list);
1266061da546Spatrick }
1267061da546Spatrick
1268061da546Spatrick // If we found more than one function, see if we can use the frame's decl
1269061da546Spatrick // context to remove functions that are shadowed by other functions which
1270061da546Spatrick // match in type but are nearer in scope.
1271061da546Spatrick //
1272061da546Spatrick // AddOneFunction will not add a function whose type has already been
1273061da546Spatrick // added, so if there's another function in the list with a matching type,
1274061da546Spatrick // check to see if their decl context is a parent of the current frame's or
1275061da546Spatrick // was imported via a and using statement, and pick the best match
1276061da546Spatrick // according to lookup rules.
1277061da546Spatrick if (sc_list.GetSize() > 1) {
1278061da546Spatrick // Collect some info about our frame's context.
1279061da546Spatrick StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
1280061da546Spatrick SymbolContext frame_sym_ctx;
1281061da546Spatrick if (frame != nullptr)
1282061da546Spatrick frame_sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
1283061da546Spatrick lldb::eSymbolContextBlock);
1284061da546Spatrick CompilerDeclContext frame_decl_context =
1285061da546Spatrick frame_sym_ctx.block != nullptr ? frame_sym_ctx.block->GetDeclContext()
1286061da546Spatrick : CompilerDeclContext();
1287061da546Spatrick
1288061da546Spatrick // We can't do this without a compiler decl context for our frame.
1289061da546Spatrick if (frame_decl_context) {
1290061da546Spatrick sc_list = SearchFunctionsInSymbolContexts(sc_list, frame_decl_context);
1291061da546Spatrick }
1292061da546Spatrick }
1293061da546Spatrick
1294061da546Spatrick if (sc_list.GetSize()) {
1295061da546Spatrick Symbol *extern_symbol = nullptr;
1296061da546Spatrick Symbol *non_extern_symbol = nullptr;
1297061da546Spatrick
1298061da546Spatrick for (uint32_t index = 0, num_indices = sc_list.GetSize();
1299061da546Spatrick index < num_indices; ++index) {
1300061da546Spatrick SymbolContext sym_ctx;
1301061da546Spatrick sc_list.GetContextAtIndex(index, sym_ctx);
1302061da546Spatrick
1303061da546Spatrick if (sym_ctx.function) {
1304061da546Spatrick CompilerDeclContext decl_ctx = sym_ctx.function->GetDeclContext();
1305061da546Spatrick
1306061da546Spatrick if (!decl_ctx)
1307061da546Spatrick continue;
1308061da546Spatrick
1309061da546Spatrick // Filter out class/instance methods.
1310061da546Spatrick if (decl_ctx.IsClassMethod(nullptr, nullptr, nullptr))
1311061da546Spatrick continue;
1312061da546Spatrick
1313dda28197Spatrick AddOneFunction(context, sym_ctx.function, nullptr);
1314dda28197Spatrick context.m_found_function_with_type_info = true;
1315dda28197Spatrick context.m_found_function = true;
1316061da546Spatrick } else if (sym_ctx.symbol) {
1317061da546Spatrick if (sym_ctx.symbol->GetType() == eSymbolTypeReExported && target) {
1318061da546Spatrick sym_ctx.symbol = sym_ctx.symbol->ResolveReExportedSymbol(*target);
1319061da546Spatrick if (sym_ctx.symbol == nullptr)
1320061da546Spatrick continue;
1321061da546Spatrick }
1322061da546Spatrick
1323061da546Spatrick if (sym_ctx.symbol->IsExternal())
1324061da546Spatrick extern_symbol = sym_ctx.symbol;
1325061da546Spatrick else
1326061da546Spatrick non_extern_symbol = sym_ctx.symbol;
1327061da546Spatrick }
1328061da546Spatrick }
1329061da546Spatrick
1330dda28197Spatrick if (!context.m_found_function_with_type_info) {
1331061da546Spatrick for (clang::NamedDecl *decl : decls_from_modules) {
1332061da546Spatrick if (llvm::isa<clang::FunctionDecl>(decl)) {
1333061da546Spatrick clang::NamedDecl *copied_decl =
1334061da546Spatrick llvm::cast_or_null<FunctionDecl>(CopyDecl(decl));
1335061da546Spatrick if (copied_decl) {
1336061da546Spatrick context.AddNamedDecl(copied_decl);
1337dda28197Spatrick context.m_found_function_with_type_info = true;
1338061da546Spatrick }
1339061da546Spatrick }
1340061da546Spatrick }
1341061da546Spatrick }
1342061da546Spatrick
1343dda28197Spatrick if (!context.m_found_function_with_type_info) {
1344061da546Spatrick if (extern_symbol) {
1345dda28197Spatrick AddOneFunction(context, nullptr, extern_symbol);
1346dda28197Spatrick context.m_found_function = true;
1347061da546Spatrick } else if (non_extern_symbol) {
1348dda28197Spatrick AddOneFunction(context, nullptr, non_extern_symbol);
1349dda28197Spatrick context.m_found_function = true;
1350061da546Spatrick }
1351061da546Spatrick }
1352061da546Spatrick }
1353061da546Spatrick }
1354061da546Spatrick
FindExternalVisibleDecls(NameSearchContext & context,lldb::ModuleSP module_sp,const CompilerDeclContext & namespace_decl)1355061da546Spatrick void ClangExpressionDeclMap::FindExternalVisibleDecls(
1356061da546Spatrick NameSearchContext &context, lldb::ModuleSP module_sp,
1357dda28197Spatrick const CompilerDeclContext &namespace_decl) {
1358061da546Spatrick assert(m_ast_context);
1359061da546Spatrick
1360*f6aab3d8Srobert Log *log = GetLog(LLDBLog::Expressions);
1361061da546Spatrick
1362061da546Spatrick const ConstString name(context.m_decl_name.getAsString().c_str());
1363061da546Spatrick if (IgnoreName(name, false))
1364061da546Spatrick return;
1365061da546Spatrick
1366061da546Spatrick // Only look for functions by name out in our symbols if the function doesn't
1367061da546Spatrick // start with our phony prefix of '$'
1368061da546Spatrick
1369061da546Spatrick Target *target = nullptr;
1370061da546Spatrick StackFrame *frame = nullptr;
1371061da546Spatrick SymbolContext sym_ctx;
1372061da546Spatrick if (m_parser_vars) {
1373061da546Spatrick target = m_parser_vars->m_exe_ctx.GetTargetPtr();
1374061da546Spatrick frame = m_parser_vars->m_exe_ctx.GetFramePtr();
1375061da546Spatrick }
1376061da546Spatrick if (frame != nullptr)
1377061da546Spatrick sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
1378061da546Spatrick lldb::eSymbolContextBlock);
1379061da546Spatrick
1380061da546Spatrick // Try the persistent decls, which take precedence over all else.
1381061da546Spatrick if (!namespace_decl)
1382dda28197Spatrick SearchPersistenDecls(context, name);
1383061da546Spatrick
1384061da546Spatrick if (name.GetStringRef().startswith("$") && !namespace_decl) {
1385061da546Spatrick if (name == "$__lldb_class") {
1386dda28197Spatrick LookUpLldbClass(context);
1387061da546Spatrick return;
1388061da546Spatrick }
1389061da546Spatrick
1390061da546Spatrick if (name == "$__lldb_objc_class") {
1391dda28197Spatrick LookUpLldbObjCClass(context);
1392061da546Spatrick return;
1393061da546Spatrick }
1394061da546Spatrick if (name == g_lldb_local_vars_namespace_cstr) {
1395061da546Spatrick LookupLocalVarNamespace(sym_ctx, context);
1396061da546Spatrick return;
1397061da546Spatrick }
1398061da546Spatrick
1399061da546Spatrick // any other $__lldb names should be weeded out now
1400061da546Spatrick if (name.GetStringRef().startswith("$__lldb"))
1401061da546Spatrick return;
1402061da546Spatrick
1403061da546Spatrick // No ParserVars means we can't do register or variable lookup.
1404061da546Spatrick if (!m_parser_vars || !m_parser_vars->m_persistent_vars)
1405061da546Spatrick return;
1406061da546Spatrick
1407061da546Spatrick ExpressionVariableSP pvar_sp(
1408061da546Spatrick m_parser_vars->m_persistent_vars->GetVariable(name));
1409061da546Spatrick
1410061da546Spatrick if (pvar_sp) {
1411dda28197Spatrick AddOneVariable(context, pvar_sp);
1412061da546Spatrick return;
1413061da546Spatrick }
1414061da546Spatrick
1415061da546Spatrick assert(name.GetStringRef().startswith("$"));
1416061da546Spatrick llvm::StringRef reg_name = name.GetStringRef().substr(1);
1417061da546Spatrick
1418061da546Spatrick if (m_parser_vars->m_exe_ctx.GetRegisterContext()) {
1419061da546Spatrick const RegisterInfo *reg_info(
1420061da546Spatrick m_parser_vars->m_exe_ctx.GetRegisterContext()->GetRegisterInfoByName(
1421061da546Spatrick reg_name));
1422061da546Spatrick
1423061da546Spatrick if (reg_info) {
1424dda28197Spatrick LLDB_LOG(log, " CEDM::FEVD Found register {0}", reg_info->name);
1425061da546Spatrick
1426dda28197Spatrick AddOneRegister(context, reg_info);
1427061da546Spatrick }
1428061da546Spatrick }
1429061da546Spatrick return;
1430061da546Spatrick }
1431061da546Spatrick
1432061da546Spatrick bool local_var_lookup = !namespace_decl || (namespace_decl.GetName() ==
1433061da546Spatrick g_lldb_local_vars_namespace_cstr);
1434061da546Spatrick if (frame && local_var_lookup)
1435dda28197Spatrick if (LookupLocalVariable(context, name, sym_ctx, namespace_decl))
1436061da546Spatrick return;
1437061da546Spatrick
1438061da546Spatrick if (target) {
1439061da546Spatrick ValueObjectSP valobj;
1440061da546Spatrick VariableSP var;
1441dda28197Spatrick var = FindGlobalVariable(*target, module_sp, name, namespace_decl);
1442061da546Spatrick
1443061da546Spatrick if (var) {
1444061da546Spatrick valobj = ValueObjectVariable::Create(target, var);
1445dda28197Spatrick AddOneVariable(context, var, valobj);
1446dda28197Spatrick context.m_found_variable = true;
1447061da546Spatrick return;
1448061da546Spatrick }
1449061da546Spatrick }
1450061da546Spatrick
1451dda28197Spatrick LookupFunction(context, module_sp, name, namespace_decl);
1452061da546Spatrick
1453061da546Spatrick // Try the modules next.
1454dda28197Spatrick if (!context.m_found_function_with_type_info)
1455dda28197Spatrick LookupInModulesDeclVendor(context, name);
1456061da546Spatrick
1457dda28197Spatrick if (target && !context.m_found_variable && !namespace_decl) {
1458061da546Spatrick // We couldn't find a non-symbol variable for this. Now we'll hunt for a
1459061da546Spatrick // generic data symbol, and -- if it is found -- treat it as a variable.
1460061da546Spatrick Status error;
1461061da546Spatrick
1462061da546Spatrick const Symbol *data_symbol =
1463061da546Spatrick m_parser_vars->m_sym_ctx.FindBestGlobalDataSymbol(name, error);
1464061da546Spatrick
1465061da546Spatrick if (!error.Success()) {
1466061da546Spatrick const unsigned diag_id =
1467061da546Spatrick m_ast_context->getDiagnostics().getCustomDiagID(
1468061da546Spatrick clang::DiagnosticsEngine::Level::Error, "%0");
1469061da546Spatrick m_ast_context->getDiagnostics().Report(diag_id) << error.AsCString();
1470061da546Spatrick }
1471061da546Spatrick
1472061da546Spatrick if (data_symbol) {
1473061da546Spatrick std::string warning("got name from symbols: ");
1474061da546Spatrick warning.append(name.AsCString());
1475061da546Spatrick const unsigned diag_id =
1476061da546Spatrick m_ast_context->getDiagnostics().getCustomDiagID(
1477061da546Spatrick clang::DiagnosticsEngine::Level::Warning, "%0");
1478061da546Spatrick m_ast_context->getDiagnostics().Report(diag_id) << warning.c_str();
1479dda28197Spatrick AddOneGenericVariable(context, *data_symbol);
1480dda28197Spatrick context.m_found_variable = true;
1481061da546Spatrick }
1482061da546Spatrick }
1483061da546Spatrick }
1484061da546Spatrick
GetVariableValue(VariableSP & var,lldb_private::Value & var_location,TypeFromUser * user_type,TypeFromParser * parser_type)1485061da546Spatrick bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var,
1486061da546Spatrick lldb_private::Value &var_location,
1487061da546Spatrick TypeFromUser *user_type,
1488061da546Spatrick TypeFromParser *parser_type) {
1489*f6aab3d8Srobert Log *log = GetLog(LLDBLog::Expressions);
1490061da546Spatrick
1491061da546Spatrick Type *var_type = var->GetType();
1492061da546Spatrick
1493061da546Spatrick if (!var_type) {
1494dda28197Spatrick LLDB_LOG(log, "Skipped a definition because it has no type");
1495061da546Spatrick return false;
1496061da546Spatrick }
1497061da546Spatrick
1498061da546Spatrick CompilerType var_clang_type = var_type->GetFullCompilerType();
1499061da546Spatrick
1500061da546Spatrick if (!var_clang_type) {
1501dda28197Spatrick LLDB_LOG(log, "Skipped a definition because it has no Clang type");
1502061da546Spatrick return false;
1503061da546Spatrick }
1504061da546Spatrick
1505*f6aab3d8Srobert auto ts = var_type->GetForwardCompilerType().GetTypeSystem();
1506*f6aab3d8Srobert auto clang_ast = ts.dyn_cast_or_null<TypeSystemClang>();
1507061da546Spatrick
1508061da546Spatrick if (!clang_ast) {
1509dda28197Spatrick LLDB_LOG(log, "Skipped a definition because it has no Clang AST");
1510061da546Spatrick return false;
1511061da546Spatrick }
1512061da546Spatrick
1513*f6aab3d8Srobert DWARFExpressionList &var_location_list = var->LocationExpressionList();
1514061da546Spatrick
1515061da546Spatrick Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
1516061da546Spatrick Status err;
1517061da546Spatrick
1518061da546Spatrick if (var->GetLocationIsConstantValueData()) {
1519061da546Spatrick DataExtractor const_value_extractor;
1520*f6aab3d8Srobert if (var_location_list.GetExpressionData(const_value_extractor)) {
1521061da546Spatrick var_location = Value(const_value_extractor.GetDataStart(),
1522061da546Spatrick const_value_extractor.GetByteSize());
1523be691f3bSpatrick var_location.SetValueType(Value::ValueType::HostAddress);
1524061da546Spatrick } else {
1525dda28197Spatrick LLDB_LOG(log, "Error evaluating constant variable: {0}", err.AsCString());
1526061da546Spatrick return false;
1527061da546Spatrick }
1528061da546Spatrick }
1529061da546Spatrick
1530061da546Spatrick CompilerType type_to_use = GuardedCopyType(var_clang_type);
1531061da546Spatrick
1532061da546Spatrick if (!type_to_use) {
1533dda28197Spatrick LLDB_LOG(log,
1534061da546Spatrick "Couldn't copy a variable's type into the parser's AST context");
1535061da546Spatrick
1536061da546Spatrick return false;
1537061da546Spatrick }
1538061da546Spatrick
1539061da546Spatrick if (parser_type)
1540061da546Spatrick *parser_type = TypeFromParser(type_to_use);
1541061da546Spatrick
1542be691f3bSpatrick if (var_location.GetContextType() == Value::ContextType::Invalid)
1543061da546Spatrick var_location.SetCompilerType(type_to_use);
1544061da546Spatrick
1545be691f3bSpatrick if (var_location.GetValueType() == Value::ValueType::FileAddress) {
1546061da546Spatrick SymbolContext var_sc;
1547061da546Spatrick var->CalculateSymbolContext(&var_sc);
1548061da546Spatrick
1549061da546Spatrick if (!var_sc.module_sp)
1550061da546Spatrick return false;
1551061da546Spatrick
1552061da546Spatrick Address so_addr(var_location.GetScalar().ULongLong(),
1553061da546Spatrick var_sc.module_sp->GetSectionList());
1554061da546Spatrick
1555061da546Spatrick lldb::addr_t load_addr = so_addr.GetLoadAddress(target);
1556061da546Spatrick
1557061da546Spatrick if (load_addr != LLDB_INVALID_ADDRESS) {
1558061da546Spatrick var_location.GetScalar() = load_addr;
1559be691f3bSpatrick var_location.SetValueType(Value::ValueType::LoadAddress);
1560061da546Spatrick }
1561061da546Spatrick }
1562061da546Spatrick
1563061da546Spatrick if (user_type)
1564061da546Spatrick *user_type = TypeFromUser(var_clang_type);
1565061da546Spatrick
1566061da546Spatrick return true;
1567061da546Spatrick }
1568061da546Spatrick
1569*f6aab3d8Srobert ClangExpressionVariable::ParserVars *
AddExpressionVariable(NameSearchContext & context,TypeFromParser const & pt,ValueObjectSP valobj)1570*f6aab3d8Srobert ClangExpressionDeclMap::AddExpressionVariable(NameSearchContext &context,
1571*f6aab3d8Srobert TypeFromParser const &pt,
1572dda28197Spatrick ValueObjectSP valobj) {
1573061da546Spatrick clang::QualType parser_opaque_type =
1574061da546Spatrick QualType::getFromOpaquePtr(pt.GetOpaqueQualType());
1575061da546Spatrick
1576061da546Spatrick if (parser_opaque_type.isNull())
1577*f6aab3d8Srobert return nullptr;
1578061da546Spatrick
1579061da546Spatrick if (const clang::Type *parser_type = parser_opaque_type.getTypePtr()) {
1580061da546Spatrick if (const TagType *tag_type = dyn_cast<TagType>(parser_type))
1581061da546Spatrick CompleteType(tag_type->getDecl());
1582061da546Spatrick if (const ObjCObjectPointerType *objc_object_ptr_type =
1583061da546Spatrick dyn_cast<ObjCObjectPointerType>(parser_type))
1584061da546Spatrick CompleteType(objc_object_ptr_type->getInterfaceDecl());
1585061da546Spatrick }
1586061da546Spatrick
1587061da546Spatrick bool is_reference = pt.IsReferenceType();
1588061da546Spatrick
1589061da546Spatrick NamedDecl *var_decl = nullptr;
1590061da546Spatrick if (is_reference)
1591061da546Spatrick var_decl = context.AddVarDecl(pt);
1592061da546Spatrick else
1593061da546Spatrick var_decl = context.AddVarDecl(pt.GetLValueReferenceType());
1594061da546Spatrick
1595061da546Spatrick std::string decl_name(context.m_decl_name.getAsString());
1596061da546Spatrick ConstString entity_name(decl_name.c_str());
1597061da546Spatrick ClangExpressionVariable *entity(new ClangExpressionVariable(valobj));
1598061da546Spatrick m_found_entities.AddNewlyConstructedVariable(entity);
1599061da546Spatrick
1600061da546Spatrick assert(entity);
1601061da546Spatrick entity->EnableParserVars(GetParserID());
1602061da546Spatrick ClangExpressionVariable::ParserVars *parser_vars =
1603061da546Spatrick entity->GetParserVars(GetParserID());
1604*f6aab3d8Srobert
1605061da546Spatrick parser_vars->m_named_decl = var_decl;
1606061da546Spatrick
1607061da546Spatrick if (is_reference)
1608061da546Spatrick entity->m_flags |= ClangExpressionVariable::EVTypeIsReference;
1609061da546Spatrick
1610*f6aab3d8Srobert return parser_vars;
1611*f6aab3d8Srobert }
1612*f6aab3d8Srobert
AddOneVariable(NameSearchContext & context,ValueObjectSP valobj,ValueObjectProviderTy valobj_provider)1613*f6aab3d8Srobert void ClangExpressionDeclMap::AddOneVariable(
1614*f6aab3d8Srobert NameSearchContext &context, ValueObjectSP valobj,
1615*f6aab3d8Srobert ValueObjectProviderTy valobj_provider) {
1616*f6aab3d8Srobert assert(m_parser_vars.get());
1617*f6aab3d8Srobert assert(valobj);
1618*f6aab3d8Srobert
1619*f6aab3d8Srobert Log *log = GetLog(LLDBLog::Expressions);
1620*f6aab3d8Srobert
1621*f6aab3d8Srobert Value var_location = valobj->GetValue();
1622*f6aab3d8Srobert
1623*f6aab3d8Srobert TypeFromUser user_type = valobj->GetCompilerType();
1624*f6aab3d8Srobert
1625*f6aab3d8Srobert auto clang_ast =
1626*f6aab3d8Srobert user_type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>();
1627*f6aab3d8Srobert
1628*f6aab3d8Srobert if (!clang_ast) {
1629*f6aab3d8Srobert LLDB_LOG(log, "Skipped a definition because it has no Clang AST");
1630*f6aab3d8Srobert return;
1631*f6aab3d8Srobert }
1632*f6aab3d8Srobert
1633*f6aab3d8Srobert TypeFromParser parser_type = GuardedCopyType(user_type);
1634*f6aab3d8Srobert
1635*f6aab3d8Srobert if (!parser_type) {
1636*f6aab3d8Srobert LLDB_LOG(log,
1637*f6aab3d8Srobert "Couldn't copy a variable's type into the parser's AST context");
1638*f6aab3d8Srobert
1639*f6aab3d8Srobert return;
1640*f6aab3d8Srobert }
1641*f6aab3d8Srobert
1642*f6aab3d8Srobert if (var_location.GetContextType() == Value::ContextType::Invalid)
1643*f6aab3d8Srobert var_location.SetCompilerType(parser_type);
1644*f6aab3d8Srobert
1645*f6aab3d8Srobert ClangExpressionVariable::ParserVars *parser_vars =
1646*f6aab3d8Srobert AddExpressionVariable(context, parser_type, valobj);
1647*f6aab3d8Srobert
1648*f6aab3d8Srobert if (!parser_vars)
1649*f6aab3d8Srobert return;
1650*f6aab3d8Srobert
1651*f6aab3d8Srobert LLDB_LOG(log, " CEDM::FEVD Found variable {0}, returned\n{1} (original {2})",
1652*f6aab3d8Srobert context.m_decl_name, ClangUtil::DumpDecl(parser_vars->m_named_decl),
1653*f6aab3d8Srobert ClangUtil::ToString(user_type));
1654*f6aab3d8Srobert
1655*f6aab3d8Srobert parser_vars->m_llvm_value = nullptr;
1656*f6aab3d8Srobert parser_vars->m_lldb_value = std::move(var_location);
1657*f6aab3d8Srobert parser_vars->m_lldb_valobj_provider = std::move(valobj_provider);
1658*f6aab3d8Srobert }
1659*f6aab3d8Srobert
AddOneVariable(NameSearchContext & context,VariableSP var,ValueObjectSP valobj)1660*f6aab3d8Srobert void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
1661*f6aab3d8Srobert VariableSP var,
1662*f6aab3d8Srobert ValueObjectSP valobj) {
1663*f6aab3d8Srobert assert(m_parser_vars.get());
1664*f6aab3d8Srobert
1665*f6aab3d8Srobert Log *log = GetLog(LLDBLog::Expressions);
1666*f6aab3d8Srobert
1667*f6aab3d8Srobert TypeFromUser ut;
1668*f6aab3d8Srobert TypeFromParser pt;
1669*f6aab3d8Srobert Value var_location;
1670*f6aab3d8Srobert
1671*f6aab3d8Srobert if (!GetVariableValue(var, var_location, &ut, &pt))
1672*f6aab3d8Srobert return;
1673*f6aab3d8Srobert
1674*f6aab3d8Srobert ClangExpressionVariable::ParserVars *parser_vars =
1675*f6aab3d8Srobert AddExpressionVariable(context, pt, std::move(valobj));
1676*f6aab3d8Srobert
1677*f6aab3d8Srobert if (!parser_vars)
1678*f6aab3d8Srobert return;
1679*f6aab3d8Srobert
1680*f6aab3d8Srobert LLDB_LOG(log, " CEDM::FEVD Found variable {0}, returned\n{1} (original {2})",
1681*f6aab3d8Srobert context.m_decl_name, ClangUtil::DumpDecl(parser_vars->m_named_decl),
1682*f6aab3d8Srobert ClangUtil::ToString(ut));
1683*f6aab3d8Srobert
1684*f6aab3d8Srobert parser_vars->m_llvm_value = nullptr;
1685*f6aab3d8Srobert parser_vars->m_lldb_value = var_location;
1686*f6aab3d8Srobert parser_vars->m_lldb_var = var;
1687061da546Spatrick }
1688061da546Spatrick
AddOneVariable(NameSearchContext & context,ExpressionVariableSP & pvar_sp)1689061da546Spatrick void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
1690dda28197Spatrick ExpressionVariableSP &pvar_sp) {
1691*f6aab3d8Srobert Log *log = GetLog(LLDBLog::Expressions);
1692061da546Spatrick
1693061da546Spatrick TypeFromUser user_type(
1694061da546Spatrick llvm::cast<ClangExpressionVariable>(pvar_sp.get())->GetTypeFromUser());
1695061da546Spatrick
1696061da546Spatrick TypeFromParser parser_type(GuardedCopyType(user_type));
1697061da546Spatrick
1698061da546Spatrick if (!parser_type.GetOpaqueQualType()) {
1699dda28197Spatrick LLDB_LOG(log, " CEDM::FEVD Couldn't import type for pvar {0}",
1700dda28197Spatrick pvar_sp->GetName());
1701061da546Spatrick return;
1702061da546Spatrick }
1703061da546Spatrick
1704061da546Spatrick NamedDecl *var_decl =
1705061da546Spatrick context.AddVarDecl(parser_type.GetLValueReferenceType());
1706061da546Spatrick
1707061da546Spatrick llvm::cast<ClangExpressionVariable>(pvar_sp.get())
1708061da546Spatrick ->EnableParserVars(GetParserID());
1709061da546Spatrick ClangExpressionVariable::ParserVars *parser_vars =
1710061da546Spatrick llvm::cast<ClangExpressionVariable>(pvar_sp.get())
1711061da546Spatrick ->GetParserVars(GetParserID());
1712061da546Spatrick parser_vars->m_named_decl = var_decl;
1713061da546Spatrick parser_vars->m_llvm_value = nullptr;
1714061da546Spatrick parser_vars->m_lldb_value.Clear();
1715061da546Spatrick
1716*f6aab3d8Srobert LLDB_LOG(log, " CEDM::FEVD Added pvar {0}, returned\n{1}",
1717061da546Spatrick pvar_sp->GetName(), ClangUtil::DumpDecl(var_decl));
1718061da546Spatrick }
1719061da546Spatrick
AddOneGenericVariable(NameSearchContext & context,const Symbol & symbol)1720061da546Spatrick void ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context,
1721dda28197Spatrick const Symbol &symbol) {
1722061da546Spatrick assert(m_parser_vars.get());
1723061da546Spatrick
1724*f6aab3d8Srobert Log *log = GetLog(LLDBLog::Expressions);
1725061da546Spatrick
1726061da546Spatrick Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
1727061da546Spatrick
1728061da546Spatrick if (target == nullptr)
1729061da546Spatrick return;
1730061da546Spatrick
1731*f6aab3d8Srobert auto scratch_ast_context = GetScratchContext(*target);
1732061da546Spatrick if (!scratch_ast_context)
1733061da546Spatrick return;
1734061da546Spatrick
1735061da546Spatrick TypeFromUser user_type(scratch_ast_context->GetBasicType(eBasicTypeVoid)
1736061da546Spatrick .GetPointerType()
1737061da546Spatrick .GetLValueReferenceType());
1738061da546Spatrick TypeFromParser parser_type(m_clang_ast_context->GetBasicType(eBasicTypeVoid)
1739061da546Spatrick .GetPointerType()
1740061da546Spatrick .GetLValueReferenceType());
1741061da546Spatrick NamedDecl *var_decl = context.AddVarDecl(parser_type);
1742061da546Spatrick
1743061da546Spatrick std::string decl_name(context.m_decl_name.getAsString());
1744061da546Spatrick ConstString entity_name(decl_name.c_str());
1745061da546Spatrick ClangExpressionVariable *entity(new ClangExpressionVariable(
1746061da546Spatrick m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), entity_name,
1747061da546Spatrick user_type, m_parser_vars->m_target_info.byte_order,
1748061da546Spatrick m_parser_vars->m_target_info.address_byte_size));
1749061da546Spatrick m_found_entities.AddNewlyConstructedVariable(entity);
1750061da546Spatrick
1751061da546Spatrick entity->EnableParserVars(GetParserID());
1752061da546Spatrick ClangExpressionVariable::ParserVars *parser_vars =
1753061da546Spatrick entity->GetParserVars(GetParserID());
1754061da546Spatrick
1755061da546Spatrick const Address symbol_address = symbol.GetAddress();
1756061da546Spatrick lldb::addr_t symbol_load_addr = symbol_address.GetLoadAddress(target);
1757061da546Spatrick
1758be691f3bSpatrick // parser_vars->m_lldb_value.SetContext(Value::ContextType::ClangType,
1759061da546Spatrick // user_type.GetOpaqueQualType());
1760061da546Spatrick parser_vars->m_lldb_value.SetCompilerType(user_type);
1761061da546Spatrick parser_vars->m_lldb_value.GetScalar() = symbol_load_addr;
1762be691f3bSpatrick parser_vars->m_lldb_value.SetValueType(Value::ValueType::LoadAddress);
1763061da546Spatrick
1764061da546Spatrick parser_vars->m_named_decl = var_decl;
1765061da546Spatrick parser_vars->m_llvm_value = nullptr;
1766061da546Spatrick parser_vars->m_lldb_sym = &symbol;
1767061da546Spatrick
1768*f6aab3d8Srobert LLDB_LOG(log, " CEDM::FEVD Found variable {0}, returned\n{1}", decl_name,
1769dda28197Spatrick ClangUtil::DumpDecl(var_decl));
1770061da546Spatrick }
1771061da546Spatrick
AddOneRegister(NameSearchContext & context,const RegisterInfo * reg_info)1772061da546Spatrick void ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context,
1773dda28197Spatrick const RegisterInfo *reg_info) {
1774*f6aab3d8Srobert Log *log = GetLog(LLDBLog::Expressions);
1775061da546Spatrick
1776061da546Spatrick CompilerType clang_type =
1777061da546Spatrick m_clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(
1778061da546Spatrick reg_info->encoding, reg_info->byte_size * 8);
1779061da546Spatrick
1780061da546Spatrick if (!clang_type) {
1781dda28197Spatrick LLDB_LOG(log, " Tried to add a type for {0}, but couldn't get one",
1782dda28197Spatrick context.m_decl_name.getAsString());
1783061da546Spatrick return;
1784061da546Spatrick }
1785061da546Spatrick
1786061da546Spatrick TypeFromParser parser_clang_type(clang_type);
1787061da546Spatrick
1788061da546Spatrick NamedDecl *var_decl = context.AddVarDecl(parser_clang_type);
1789061da546Spatrick
1790061da546Spatrick ClangExpressionVariable *entity(new ClangExpressionVariable(
1791061da546Spatrick m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
1792061da546Spatrick m_parser_vars->m_target_info.byte_order,
1793061da546Spatrick m_parser_vars->m_target_info.address_byte_size));
1794061da546Spatrick m_found_entities.AddNewlyConstructedVariable(entity);
1795061da546Spatrick
1796061da546Spatrick std::string decl_name(context.m_decl_name.getAsString());
1797061da546Spatrick entity->SetName(ConstString(decl_name.c_str()));
1798061da546Spatrick entity->SetRegisterInfo(reg_info);
1799061da546Spatrick entity->EnableParserVars(GetParserID());
1800061da546Spatrick ClangExpressionVariable::ParserVars *parser_vars =
1801061da546Spatrick entity->GetParserVars(GetParserID());
1802061da546Spatrick parser_vars->m_named_decl = var_decl;
1803061da546Spatrick parser_vars->m_llvm_value = nullptr;
1804061da546Spatrick parser_vars->m_lldb_value.Clear();
1805061da546Spatrick entity->m_flags |= ClangExpressionVariable::EVBareRegister;
1806061da546Spatrick
1807*f6aab3d8Srobert LLDB_LOG(log, " CEDM::FEVD Added register {0}, returned\n{1}",
1808dda28197Spatrick context.m_decl_name.getAsString(), ClangUtil::DumpDecl(var_decl));
1809061da546Spatrick }
1810061da546Spatrick
AddOneFunction(NameSearchContext & context,Function * function,Symbol * symbol)1811061da546Spatrick void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
1812dda28197Spatrick Function *function,
1813dda28197Spatrick Symbol *symbol) {
1814061da546Spatrick assert(m_parser_vars.get());
1815061da546Spatrick
1816*f6aab3d8Srobert Log *log = GetLog(LLDBLog::Expressions);
1817061da546Spatrick
1818061da546Spatrick NamedDecl *function_decl = nullptr;
1819061da546Spatrick Address fun_address;
1820061da546Spatrick CompilerType function_clang_type;
1821061da546Spatrick
1822061da546Spatrick bool is_indirect_function = false;
1823061da546Spatrick
1824061da546Spatrick if (function) {
1825061da546Spatrick Type *function_type = function->GetType();
1826061da546Spatrick
1827061da546Spatrick const auto lang = function->GetCompileUnit()->GetLanguage();
1828061da546Spatrick const auto name = function->GetMangled().GetMangledName().AsCString();
1829061da546Spatrick const bool extern_c = (Language::LanguageIsC(lang) &&
1830061da546Spatrick !CPlusPlusLanguage::IsCPPMangledName(name)) ||
1831061da546Spatrick (Language::LanguageIsObjC(lang) &&
1832061da546Spatrick !Language::LanguageIsCPlusPlus(lang));
1833061da546Spatrick
1834061da546Spatrick if (!extern_c) {
1835061da546Spatrick TypeSystem *type_system = function->GetDeclContext().GetTypeSystem();
1836dda28197Spatrick if (llvm::isa<TypeSystemClang>(type_system)) {
1837061da546Spatrick clang::DeclContext *src_decl_context =
1838061da546Spatrick (clang::DeclContext *)function->GetDeclContext()
1839061da546Spatrick .GetOpaqueDeclContext();
1840061da546Spatrick clang::FunctionDecl *src_function_decl =
1841061da546Spatrick llvm::dyn_cast_or_null<clang::FunctionDecl>(src_decl_context);
1842061da546Spatrick if (src_function_decl &&
1843061da546Spatrick src_function_decl->getTemplateSpecializationInfo()) {
1844061da546Spatrick clang::FunctionTemplateDecl *function_template =
1845061da546Spatrick src_function_decl->getTemplateSpecializationInfo()->getTemplate();
1846061da546Spatrick clang::FunctionTemplateDecl *copied_function_template =
1847061da546Spatrick llvm::dyn_cast_or_null<clang::FunctionTemplateDecl>(
1848061da546Spatrick CopyDecl(function_template));
1849061da546Spatrick if (copied_function_template) {
1850061da546Spatrick if (log) {
1851061da546Spatrick StreamString ss;
1852061da546Spatrick
1853061da546Spatrick function->DumpSymbolContext(&ss);
1854061da546Spatrick
1855061da546Spatrick LLDB_LOG(log,
1856dda28197Spatrick " CEDM::FEVD Imported decl for function template"
1857*f6aab3d8Srobert " {0} (description {1}), returned\n{2}",
1858dda28197Spatrick copied_function_template->getNameAsString(),
1859061da546Spatrick ss.GetData(),
1860061da546Spatrick ClangUtil::DumpDecl(copied_function_template));
1861061da546Spatrick }
1862061da546Spatrick
1863061da546Spatrick context.AddNamedDecl(copied_function_template);
1864061da546Spatrick }
1865061da546Spatrick } else if (src_function_decl) {
1866061da546Spatrick if (clang::FunctionDecl *copied_function_decl =
1867061da546Spatrick llvm::dyn_cast_or_null<clang::FunctionDecl>(
1868061da546Spatrick CopyDecl(src_function_decl))) {
1869061da546Spatrick if (log) {
1870061da546Spatrick StreamString ss;
1871061da546Spatrick
1872061da546Spatrick function->DumpSymbolContext(&ss);
1873061da546Spatrick
1874061da546Spatrick LLDB_LOG(log,
1875*f6aab3d8Srobert " CEDM::FEVD Imported decl for function {0} "
1876*f6aab3d8Srobert "(description {1}), returned\n{2}",
1877dda28197Spatrick copied_function_decl->getNameAsString(), ss.GetData(),
1878dda28197Spatrick ClangUtil::DumpDecl(copied_function_decl));
1879061da546Spatrick }
1880061da546Spatrick
1881061da546Spatrick context.AddNamedDecl(copied_function_decl);
1882061da546Spatrick return;
1883061da546Spatrick } else {
1884dda28197Spatrick LLDB_LOG(log, " Failed to import the function decl for '{0}'",
1885dda28197Spatrick src_function_decl->getName());
1886061da546Spatrick }
1887061da546Spatrick }
1888061da546Spatrick }
1889061da546Spatrick }
1890061da546Spatrick
1891061da546Spatrick if (!function_type) {
1892dda28197Spatrick LLDB_LOG(log, " Skipped a function because it has no type");
1893061da546Spatrick return;
1894061da546Spatrick }
1895061da546Spatrick
1896061da546Spatrick function_clang_type = function_type->GetFullCompilerType();
1897061da546Spatrick
1898061da546Spatrick if (!function_clang_type) {
1899dda28197Spatrick LLDB_LOG(log, " Skipped a function because it has no Clang type");
1900061da546Spatrick return;
1901061da546Spatrick }
1902061da546Spatrick
1903061da546Spatrick fun_address = function->GetAddressRange().GetBaseAddress();
1904061da546Spatrick
1905061da546Spatrick CompilerType copied_function_type = GuardedCopyType(function_clang_type);
1906061da546Spatrick if (copied_function_type) {
1907061da546Spatrick function_decl = context.AddFunDecl(copied_function_type, extern_c);
1908061da546Spatrick
1909061da546Spatrick if (!function_decl) {
1910dda28197Spatrick LLDB_LOG(log, " Failed to create a function decl for '{0}' ({1:x})",
1911dda28197Spatrick function_type->GetName(), function_type->GetID());
1912061da546Spatrick
1913061da546Spatrick return;
1914061da546Spatrick }
1915061da546Spatrick } else {
1916061da546Spatrick // We failed to copy the type we found
1917dda28197Spatrick LLDB_LOG(log,
1918dda28197Spatrick " Failed to import the function type '{0}' ({1:x})"
1919*f6aab3d8Srobert " into the expression parser AST context",
1920dda28197Spatrick function_type->GetName(), function_type->GetID());
1921061da546Spatrick
1922061da546Spatrick return;
1923061da546Spatrick }
1924061da546Spatrick } else if (symbol) {
1925061da546Spatrick fun_address = symbol->GetAddress();
1926061da546Spatrick function_decl = context.AddGenericFunDecl();
1927061da546Spatrick is_indirect_function = symbol->IsIndirect();
1928061da546Spatrick } else {
1929dda28197Spatrick LLDB_LOG(log, " AddOneFunction called with no function and no symbol");
1930061da546Spatrick return;
1931061da546Spatrick }
1932061da546Spatrick
1933061da546Spatrick Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
1934061da546Spatrick
1935061da546Spatrick lldb::addr_t load_addr =
1936061da546Spatrick fun_address.GetCallableLoadAddress(target, is_indirect_function);
1937061da546Spatrick
1938061da546Spatrick ClangExpressionVariable *entity(new ClangExpressionVariable(
1939061da546Spatrick m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
1940061da546Spatrick m_parser_vars->m_target_info.byte_order,
1941061da546Spatrick m_parser_vars->m_target_info.address_byte_size));
1942061da546Spatrick m_found_entities.AddNewlyConstructedVariable(entity);
1943061da546Spatrick
1944061da546Spatrick std::string decl_name(context.m_decl_name.getAsString());
1945061da546Spatrick entity->SetName(ConstString(decl_name.c_str()));
1946061da546Spatrick entity->SetCompilerType(function_clang_type);
1947061da546Spatrick entity->EnableParserVars(GetParserID());
1948061da546Spatrick
1949061da546Spatrick ClangExpressionVariable::ParserVars *parser_vars =
1950061da546Spatrick entity->GetParserVars(GetParserID());
1951061da546Spatrick
1952061da546Spatrick if (load_addr != LLDB_INVALID_ADDRESS) {
1953be691f3bSpatrick parser_vars->m_lldb_value.SetValueType(Value::ValueType::LoadAddress);
1954061da546Spatrick parser_vars->m_lldb_value.GetScalar() = load_addr;
1955061da546Spatrick } else {
1956061da546Spatrick // We have to try finding a file address.
1957061da546Spatrick
1958061da546Spatrick lldb::addr_t file_addr = fun_address.GetFileAddress();
1959061da546Spatrick
1960be691f3bSpatrick parser_vars->m_lldb_value.SetValueType(Value::ValueType::FileAddress);
1961061da546Spatrick parser_vars->m_lldb_value.GetScalar() = file_addr;
1962061da546Spatrick }
1963061da546Spatrick
1964061da546Spatrick parser_vars->m_named_decl = function_decl;
1965061da546Spatrick parser_vars->m_llvm_value = nullptr;
1966061da546Spatrick
1967061da546Spatrick if (log) {
1968061da546Spatrick StreamString ss;
1969061da546Spatrick
1970061da546Spatrick fun_address.Dump(&ss,
1971061da546Spatrick m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
1972061da546Spatrick Address::DumpStyleResolvedDescription);
1973061da546Spatrick
1974061da546Spatrick LLDB_LOG(log,
1975*f6aab3d8Srobert " CEDM::FEVD Found {0} function {1} (description {2}), "
1976*f6aab3d8Srobert "returned\n{3}",
1977dda28197Spatrick (function ? "specific" : "generic"), decl_name, ss.GetData(),
1978dda28197Spatrick ClangUtil::DumpDecl(function_decl));
1979061da546Spatrick }
1980061da546Spatrick }
1981061da546Spatrick
AddContextClassType(NameSearchContext & context,const TypeFromUser & ut)1982dda28197Spatrick void ClangExpressionDeclMap::AddContextClassType(NameSearchContext &context,
1983dda28197Spatrick const TypeFromUser &ut) {
1984061da546Spatrick CompilerType copied_clang_type = GuardedCopyType(ut);
1985061da546Spatrick
1986*f6aab3d8Srobert Log *log = GetLog(LLDBLog::Expressions);
1987061da546Spatrick
1988061da546Spatrick if (!copied_clang_type) {
1989dda28197Spatrick LLDB_LOG(log,
1990061da546Spatrick "ClangExpressionDeclMap::AddThisType - Couldn't import the type");
1991061da546Spatrick
1992061da546Spatrick return;
1993061da546Spatrick }
1994061da546Spatrick
1995061da546Spatrick if (copied_clang_type.IsAggregateType() &&
1996061da546Spatrick copied_clang_type.GetCompleteType()) {
1997061da546Spatrick CompilerType void_clang_type =
1998061da546Spatrick m_clang_ast_context->GetBasicType(eBasicTypeVoid);
1999061da546Spatrick CompilerType void_ptr_clang_type = void_clang_type.GetPointerType();
2000061da546Spatrick
2001061da546Spatrick CompilerType method_type = m_clang_ast_context->CreateFunctionType(
2002061da546Spatrick void_clang_type, &void_ptr_clang_type, 1, false, 0);
2003061da546Spatrick
2004061da546Spatrick const bool is_virtual = false;
2005061da546Spatrick const bool is_static = false;
2006061da546Spatrick const bool is_inline = false;
2007061da546Spatrick const bool is_explicit = false;
2008061da546Spatrick const bool is_attr_used = true;
2009061da546Spatrick const bool is_artificial = false;
2010061da546Spatrick
2011061da546Spatrick CXXMethodDecl *method_decl = m_clang_ast_context->AddMethodToCXXRecordType(
2012061da546Spatrick copied_clang_type.GetOpaqueQualType(), "$__lldb_expr", nullptr,
2013061da546Spatrick method_type, lldb::eAccessPublic, is_virtual, is_static, is_inline,
2014061da546Spatrick is_explicit, is_attr_used, is_artificial);
2015061da546Spatrick
2016061da546Spatrick LLDB_LOG(log,
2017061da546Spatrick " CEDM::AddThisType Added function $__lldb_expr "
2018061da546Spatrick "(description {0}) for this type\n{1}",
2019061da546Spatrick ClangUtil::ToString(copied_clang_type),
2020061da546Spatrick ClangUtil::DumpDecl(method_decl));
2021061da546Spatrick }
2022061da546Spatrick
2023061da546Spatrick if (!copied_clang_type.IsValid())
2024061da546Spatrick return;
2025061da546Spatrick
2026061da546Spatrick TypeSourceInfo *type_source_info = m_ast_context->getTrivialTypeSourceInfo(
2027061da546Spatrick QualType::getFromOpaquePtr(copied_clang_type.GetOpaqueQualType()));
2028061da546Spatrick
2029061da546Spatrick if (!type_source_info)
2030061da546Spatrick return;
2031061da546Spatrick
2032061da546Spatrick // Construct a typedef type because if "*this" is a templated type we can't
2033061da546Spatrick // just return ClassTemplateSpecializationDecls in response to name queries.
2034061da546Spatrick // Using a typedef makes this much more robust.
2035061da546Spatrick
2036061da546Spatrick TypedefDecl *typedef_decl = TypedefDecl::Create(
2037061da546Spatrick *m_ast_context, m_ast_context->getTranslationUnitDecl(), SourceLocation(),
2038061da546Spatrick SourceLocation(), context.m_decl_name.getAsIdentifierInfo(),
2039061da546Spatrick type_source_info);
2040061da546Spatrick
2041061da546Spatrick if (!typedef_decl)
2042061da546Spatrick return;
2043061da546Spatrick
2044061da546Spatrick context.AddNamedDecl(typedef_decl);
2045061da546Spatrick }
2046061da546Spatrick
AddOneType(NameSearchContext & context,const TypeFromUser & ut)2047061da546Spatrick void ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
2048dda28197Spatrick const TypeFromUser &ut) {
2049061da546Spatrick CompilerType copied_clang_type = GuardedCopyType(ut);
2050061da546Spatrick
2051061da546Spatrick if (!copied_clang_type) {
2052*f6aab3d8Srobert Log *log = GetLog(LLDBLog::Expressions);
2053061da546Spatrick
2054dda28197Spatrick LLDB_LOG(log,
2055dda28197Spatrick "ClangExpressionDeclMap::AddOneType - Couldn't import the type");
2056061da546Spatrick
2057061da546Spatrick return;
2058061da546Spatrick }
2059061da546Spatrick
2060061da546Spatrick context.AddTypeDecl(copied_clang_type);
2061061da546Spatrick }
2062