blob: 745341b2d045e5459569527445cf2ac876dde5b0 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- ClangExpressionDeclMap.cpp -----------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006//
7//===----------------------------------------------------------------------===//
8
Sean Callanan4dbb2712015-09-25 20:35:58 +00009#include "ClangExpressionDeclMap.h"
10
11#include "ASTDumper.h"
12#include "ClangASTSource.h"
13#include "ClangModulesDeclVendor.h"
14#include "ClangPersistentVariables.h"
15
Chris Lattner30fdc8d2010-06-08 16:52:24 +000016#include "lldb/Core/Address.h"
17#include "lldb/Core/Module.h"
Greg Clayton9191db42013-10-21 18:40:51 +000018#include "lldb/Core/ModuleSpec.h"
Sean Callanane4ec90e2010-12-16 03:17:46 +000019#include "lldb/Core/ValueObjectConstResult.h"
Sean Callanan9b3569b2011-12-10 03:12:34 +000020#include "lldb/Core/ValueObjectVariable.h"
Sean Callanan96d27302013-04-11 00:09:05 +000021#include "lldb/Expression/Materializer.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022#include "lldb/Symbol/ClangASTContext.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000023#include "lldb/Symbol/CompileUnit.h"
Paul Hermand628cbb2015-09-15 23:44:17 +000024#include "lldb/Symbol/CompilerDecl.h"
Greg Clayton99558cc42015-08-24 23:46:31 +000025#include "lldb/Symbol/CompilerDeclContext.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026#include "lldb/Symbol/Function.h"
27#include "lldb/Symbol/ObjectFile.h"
28#include "lldb/Symbol/SymbolContext.h"
Siva Chandra9293fc42016-01-07 23:32:34 +000029#include "lldb/Symbol/SymbolFile.h"
Sean Callanan503aa522011-10-12 00:12:34 +000030#include "lldb/Symbol/SymbolVendor.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031#include "lldb/Symbol/Type.h"
32#include "lldb/Symbol/TypeList.h"
33#include "lldb/Symbol/Variable.h"
34#include "lldb/Symbol/VariableList.h"
Sean Callanana0d56432014-11-11 02:49:44 +000035#include "lldb/Target/CPPLanguageRuntime.h"
Sean Callanan1d180662010-07-20 23:31:16 +000036#include "lldb/Target/ExecutionContext.h"
Sean Callanane0b23b52012-11-15 02:02:04 +000037#include "lldb/Target/ObjCLanguageRuntime.h"
Sean Callananea22d422010-07-16 00:09:46 +000038#include "lldb/Target/Process.h"
Sean Callananf4b9bd32010-10-05 20:18:48 +000039#include "lldb/Target/RegisterContext.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000040#include "lldb/Target/StackFrame.h"
Sean Callanan1d180662010-07-20 23:31:16 +000041#include "lldb/Target/Target.h"
Jim Ingham895c9822010-12-07 01:56:02 +000042#include "lldb/Target/Thread.h"
Zachary Turner01c32432017-02-14 19:06:07 +000043#include "lldb/Utility/Endian.h"
Zachary Turner6f9e6902017-03-03 20:56:28 +000044#include "lldb/Utility/Log.h"
Pavel Labathd821c992018-08-07 11:07:21 +000045#include "lldb/Utility/RegisterValue.h"
Zachary Turner97206d52017-05-12 04:51:55 +000046#include "lldb/Utility/Status.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000047#include "lldb/lldb-private.h"
48#include "clang/AST/ASTConsumer.h"
49#include "clang/AST/ASTContext.h"
Sean Callanan68e44232017-09-28 20:20:25 +000050#include "clang/AST/ASTImporter.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000051#include "clang/AST/Decl.h"
52#include "clang/AST/DeclarationName.h"
Sean Callanan68e44232017-09-28 20:20:25 +000053#include "clang/AST/RecursiveASTVisitor.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000054
Siva Chandra0f4873d2015-09-03 23:27:10 +000055#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
56
Greg Clayton83c5cd92010-11-14 22:13:40 +000057using namespace lldb;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000058using namespace lldb_private;
59using namespace clang;
60
Kate Stoneb9c1b512016-09-06 20:57:50 +000061namespace {
62const char *g_lldb_local_vars_namespace_cstr = "$__lldb_local_vars";
Siva Chandra03ff5c82016-02-05 19:10:04 +000063} // anonymous namespace
64
Kate Stoneb9c1b512016-09-06 20:57:50 +000065ClangExpressionDeclMap::ClangExpressionDeclMap(
66 bool keep_result_in_memory,
67 Materializer::PersistentVariableDelegate *result_delegate,
68 ExecutionContext &exe_ctx)
69 : ClangASTSource(exe_ctx.GetTargetSP()), m_found_entities(),
70 m_struct_members(), m_keep_result_in_memory(keep_result_in_memory),
71 m_result_delegate(result_delegate), m_parser_vars(), m_struct_vars() {
72 EnableStructVars();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000073}
74
Kate Stoneb9c1b512016-09-06 20:57:50 +000075ClangExpressionDeclMap::~ClangExpressionDeclMap() {
76 // Note: The model is now that the parser's AST context and all associated
77 // data does not vanish until the expression has been executed. This means
78 // that valuable lookup data (like namespaces) doesn't vanish, but
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000079
Kate Stoneb9c1b512016-09-06 20:57:50 +000080 DidParse();
81 DisableStructVars();
Sean Callanan979f74d2010-12-03 01:38:59 +000082}
Sean Callananbe3a1b12010-10-26 00:31:56 +000083
Kate Stoneb9c1b512016-09-06 20:57:50 +000084bool ClangExpressionDeclMap::WillParse(ExecutionContext &exe_ctx,
85 Materializer *materializer) {
86 ClangASTMetrics::ClearLocalCounters();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000087
Kate Stoneb9c1b512016-09-06 20:57:50 +000088 EnableParserVars();
89 m_parser_vars->m_exe_ctx = exe_ctx;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000090
Kate Stoneb9c1b512016-09-06 20:57:50 +000091 Target *target = exe_ctx.GetTargetPtr();
92 if (exe_ctx.GetFramePtr())
93 m_parser_vars->m_sym_ctx =
94 exe_ctx.GetFramePtr()->GetSymbolContext(lldb::eSymbolContextEverything);
95 else if (exe_ctx.GetThreadPtr() &&
96 exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(0))
97 m_parser_vars->m_sym_ctx =
98 exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(0)->GetSymbolContext(
99 lldb::eSymbolContextEverything);
100 else if (exe_ctx.GetProcessPtr()) {
101 m_parser_vars->m_sym_ctx.Clear(true);
102 m_parser_vars->m_sym_ctx.target_sp = exe_ctx.GetTargetSP();
103 } else if (target) {
104 m_parser_vars->m_sym_ctx.Clear(true);
105 m_parser_vars->m_sym_ctx.target_sp = exe_ctx.GetTargetSP();
106 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000107
Kate Stoneb9c1b512016-09-06 20:57:50 +0000108 if (target) {
109 m_parser_vars->m_persistent_vars = llvm::cast<ClangPersistentVariables>(
110 target->GetPersistentExpressionStateForLanguage(eLanguageTypeC));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000111
Kate Stoneb9c1b512016-09-06 20:57:50 +0000112 if (!target->GetScratchClangASTContext())
113 return false;
114 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000115
Kate Stoneb9c1b512016-09-06 20:57:50 +0000116 m_parser_vars->m_target_info = GetTargetInfo();
117 m_parser_vars->m_materializer = materializer;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000118
Kate Stoneb9c1b512016-09-06 20:57:50 +0000119 return true;
Sean Callanan979f74d2010-12-03 01:38:59 +0000120}
121
Kate Stoneb9c1b512016-09-06 20:57:50 +0000122void ClangExpressionDeclMap::InstallCodeGenerator(
123 clang::ASTConsumer *code_gen) {
124 assert(m_parser_vars);
125 m_parser_vars->m_code_gen = code_gen;
Sean Callanan80c97592015-05-01 00:47:29 +0000126}
127
Kate Stoneb9c1b512016-09-06 20:57:50 +0000128void ClangExpressionDeclMap::DidParse() {
129 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan8106d802013-03-08 20:04:57 +0000130
Kate Stoneb9c1b512016-09-06 20:57:50 +0000131 if (log)
132 ClangASTMetrics::DumpCounters(log);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000133
Kate Stoneb9c1b512016-09-06 20:57:50 +0000134 if (m_parser_vars.get()) {
135 for (size_t entity_index = 0, num_entities = m_found_entities.GetSize();
136 entity_index < num_entities; ++entity_index) {
137 ExpressionVariableSP var_sp(
138 m_found_entities.GetVariableAtIndex(entity_index));
139 if (var_sp)
140 llvm::cast<ClangExpressionVariable>(var_sp.get())
141 ->DisableParserVars(GetParserID());
Sean Callanan6b1b9532010-10-08 01:58:41 +0000142 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000143
144 for (size_t pvar_index = 0,
145 num_pvars = m_parser_vars->m_persistent_vars->GetSize();
146 pvar_index < num_pvars; ++pvar_index) {
147 ExpressionVariableSP pvar_sp(
148 m_parser_vars->m_persistent_vars->GetVariableAtIndex(pvar_index));
149 if (ClangExpressionVariable *clang_var =
150 llvm::dyn_cast<ClangExpressionVariable>(pvar_sp.get()))
151 clang_var->DisableParserVars(GetParserID());
152 }
153
154 DisableParserVars();
155 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000156}
157
Sean Callanan549c9f72010-07-13 21:41:46 +0000158// Interface for IRForTarget
159
Kate Stoneb9c1b512016-09-06 20:57:50 +0000160ClangExpressionDeclMap::TargetInfo ClangExpressionDeclMap::GetTargetInfo() {
161 assert(m_parser_vars.get());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000162
Kate Stoneb9c1b512016-09-06 20:57:50 +0000163 TargetInfo ret;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000164
Kate Stoneb9c1b512016-09-06 20:57:50 +0000165 ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
Sean Callanan933693b2012-02-10 01:22:05 +0000166
Kate Stoneb9c1b512016-09-06 20:57:50 +0000167 Process *process = exe_ctx.GetProcessPtr();
168 if (process) {
169 ret.byte_order = process->GetByteOrder();
170 ret.address_byte_size = process->GetAddressByteSize();
171 } else {
172 Target *target = exe_ctx.GetTargetPtr();
173 if (target) {
174 ret.byte_order = target->GetArchitecture().GetByteOrder();
175 ret.address_byte_size = target->GetArchitecture().GetAddressByteSize();
Sean Callanan933693b2012-02-10 01:22:05 +0000176 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000177 }
Sean Callanan933693b2012-02-10 01:22:05 +0000178
Kate Stoneb9c1b512016-09-06 20:57:50 +0000179 return ret;
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000180}
181
Sean Callanan68e44232017-09-28 20:20:25 +0000182namespace {
183/// This class walks an AST and ensures that all DeclContexts defined inside the
184/// current source file are properly complete.
185///
186/// This is used to ensure that persistent types defined in the current source
187/// file migrate completely to the persistent AST context before they are
188/// reused. If that didn't happen, it would be impoossible to complete them
189/// because their origin would be gone.
190///
191/// The stragtegy used by this class is to check the SourceLocation (to be
192/// specific, the FileID) and see if it's the FileID for the current expression.
193/// Alternate strategies could include checking whether an ExternalASTMerger,
194/// set up to not have the current context as a source, can find an original for
195/// the type.
196class Completer : public clang::RecursiveASTVisitor<Completer> {
197private:
198 clang::ASTImporter &m_exporter; /// Used to import Decl contents
199 clang::FileID m_file; /// The file that's going away
200 llvm::DenseSet<clang::Decl *> m_completed; /// Visited Decls, to avoid cycles
201
202 bool ImportAndCheckCompletable(clang::Decl *decl) {
203 (void)m_exporter.Import(decl);
204 if (m_completed.count(decl))
205 return false;
206 if (!llvm::isa<DeclContext>(decl))
207 return false;
208 const clang::SourceLocation loc = decl->getLocation();
209 if (!loc.isValid())
210 return false;
211 const clang::FileID file =
212 m_exporter.getFromContext().getSourceManager().getFileID(loc);
213 if (file != m_file)
214 return false;
Adrian Prantl05097242018-04-30 16:49:04 +0000215 // We are assuming the Decl was parsed in this very expression, so it
216 // should not have external storage.
Sean Callanan68e44232017-09-28 20:20:25 +0000217 lldbassert(!llvm::cast<DeclContext>(decl)->hasExternalLexicalStorage());
218 return true;
219 }
220
221 void Complete(clang::Decl *decl) {
222 m_completed.insert(decl);
223 auto *decl_context = llvm::cast<DeclContext>(decl);
224 (void)m_exporter.Import(decl);
225 m_exporter.CompleteDecl(decl);
226 for (Decl *child : decl_context->decls())
227 if (ImportAndCheckCompletable(child))
228 Complete(child);
229 }
230
231 void MaybeComplete(clang::Decl *decl) {
232 if (ImportAndCheckCompletable(decl))
233 Complete(decl);
234 }
235
236public:
237 Completer(clang::ASTImporter &exporter, clang::FileID file)
238 : m_exporter(exporter), m_file(file) {}
239
240 // Implements the RecursiveASTVisitor's core API. It is called on each Decl
241 // that the RecursiveASTVisitor encounters, and returns true if the traversal
242 // should continue.
243 bool VisitDecl(clang::Decl *decl) {
244 MaybeComplete(decl);
245 return true;
246 }
247};
248}
249
250static void CompleteAllDeclContexts(clang::ASTImporter &exporter,
251 clang::FileID file,
252 clang::QualType root) {
253 clang::QualType canonical_type = root.getCanonicalType();
254 if (clang::TagDecl *tag_decl = canonical_type->getAsTagDecl()) {
255 Completer(exporter, file).TraverseDecl(tag_decl);
256 } else if (auto interface_type = llvm::dyn_cast<ObjCInterfaceType>(
257 canonical_type.getTypePtr())) {
258 Completer(exporter, file).TraverseDecl(interface_type->getDecl());
259 } else {
260 Completer(exporter, file).TraverseType(canonical_type);
261 }
262}
263
264static clang::QualType ExportAllDeclaredTypes(
265 clang::ExternalASTMerger &merger,
266 clang::ASTContext &source, clang::FileManager &source_file_manager,
267 const clang::ExternalASTMerger::OriginMap &source_origin_map,
268 clang::FileID file, clang::QualType root) {
269 clang::ExternalASTMerger::ImporterSource importer_source =
270 { source, source_file_manager, source_origin_map };
271 merger.AddSources(importer_source);
272 clang::ASTImporter &exporter = merger.ImporterForOrigin(source);
273 CompleteAllDeclContexts(exporter, file, root);
274 clang::QualType ret = exporter.Import(root);
275 merger.RemoveSources(importer_source);
276 return ret;
277}
278
279TypeFromUser ClangExpressionDeclMap::DeportType(ClangASTContext &target,
280 ClangASTContext &source,
281 TypeFromParser parser_type) {
282 assert (&target == m_target->GetScratchClangASTContext());
283 assert ((TypeSystem*)&source == parser_type.GetTypeSystem());
284 assert (source.getASTContext() == m_ast_context);
285
286 if (m_ast_importer_sp) {
287 return TypeFromUser(m_ast_importer_sp->DeportType(
288 target.getASTContext(), source.getASTContext(),
289 parser_type.GetOpaqueQualType()),
290 &target);
291 } else if (m_merger_up) {
292 clang::FileID source_file =
293 source.getASTContext()->getSourceManager().getFileID(
294 source.getASTContext()->getTranslationUnitDecl()->getLocation());
295 auto scratch_ast_context = static_cast<ClangASTContextForExpressions*>(
296 m_target->GetScratchClangASTContext());
297 clang::QualType exported_type = ExportAllDeclaredTypes(
298 scratch_ast_context->GetMergerUnchecked(),
299 *source.getASTContext(), *source.getFileManager(),
300 m_merger_up->GetOrigins(),
301 source_file,
302 clang::QualType::getFromOpaquePtr(parser_type.GetOpaqueQualType()));
303 return TypeFromUser(exported_type.getAsOpaquePtr(), &target);
304 } else {
Pavel Labath9344e452017-10-17 21:52:29 +0000305 lldbassert(0 && "No mechanism for deporting a type!");
Sean Callanan68e44232017-09-28 20:20:25 +0000306 return TypeFromUser();
307 }
308}
309
Kate Stoneb9c1b512016-09-06 20:57:50 +0000310bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
311 const ConstString &name,
312 TypeFromParser parser_type,
313 bool is_result,
314 bool is_lvalue) {
315 assert(m_parser_vars.get());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000316
Kate Stoneb9c1b512016-09-06 20:57:50 +0000317 ClangASTContext *ast =
318 llvm::dyn_cast_or_null<ClangASTContext>(parser_type.GetTypeSystem());
319 if (ast == nullptr)
320 return false;
Greg Claytonf73034f2015-09-08 18:15:05 +0000321
Kate Stoneb9c1b512016-09-06 20:57:50 +0000322 if (m_parser_vars->m_materializer && is_result) {
Zachary Turner97206d52017-05-12 04:51:55 +0000323 Status err;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000324
Sean Callanan933693b2012-02-10 01:22:05 +0000325 ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
326 Target *target = exe_ctx.GetTargetPtr();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000327 if (target == nullptr)
328 return false;
Greg Claytonc14ee322011-09-22 04:58:26 +0000329
Sean Callanan68e44232017-09-28 20:20:25 +0000330 TypeFromUser user_type =
331 DeportType(*target->GetScratchClangASTContext(), *ast, parser_type);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000332
Kate Stoneb9c1b512016-09-06 20:57:50 +0000333 uint32_t offset = m_parser_vars->m_materializer->AddResultVariable(
334 user_type, is_lvalue, m_keep_result_in_memory, m_result_delegate, err);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000335
Kate Stoneb9c1b512016-09-06 20:57:50 +0000336 ClangExpressionVariable *var = new ClangExpressionVariable(
337 exe_ctx.GetBestExecutionContextScope(), name, user_type,
338 m_parser_vars->m_target_info.byte_order,
339 m_parser_vars->m_target_info.address_byte_size);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000340
Kate Stoneb9c1b512016-09-06 20:57:50 +0000341 m_found_entities.AddNewlyConstructedVariable(var);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000342
Sean Callananbc8ac342015-09-04 20:49:51 +0000343 var->EnableParserVars(GetParserID());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000344
Kate Stoneb9c1b512016-09-06 20:57:50 +0000345 ClangExpressionVariable::ParserVars *parser_vars =
346 var->GetParserVars(GetParserID());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000347
Sean Callanan3c495c12013-01-15 23:29:36 +0000348 parser_vars->m_named_decl = decl;
349 parser_vars->m_parser_type = parser_type;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000350
Kate Stoneb9c1b512016-09-06 20:57:50 +0000351 var->EnableJITVars(GetParserID());
352
353 ClangExpressionVariable::JITVars *jit_vars = var->GetJITVars(GetParserID());
354
355 jit_vars->m_offset = offset;
356
Sean Callanan64dfc9a2010-08-23 23:09:38 +0000357 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000358 }
359
360 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
361 ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
362 Target *target = exe_ctx.GetTargetPtr();
363 if (target == NULL)
364 return false;
365
366 ClangASTContext *context(target->GetScratchClangASTContext());
367
Sean Callanan68e44232017-09-28 20:20:25 +0000368 TypeFromUser user_type = DeportType(*context, *ast, parser_type);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000369
370 if (!user_type.GetOpaqueQualType()) {
371 if (log)
372 log->Printf("Persistent variable's type wasn't copied successfully");
373 return false;
374 }
375
376 if (!m_parser_vars->m_target_info.IsValid())
377 return false;
378
379 ClangExpressionVariable *var = llvm::cast<ClangExpressionVariable>(
380 m_parser_vars->m_persistent_vars
381 ->CreatePersistentVariable(
382 exe_ctx.GetBestExecutionContextScope(), name, user_type,
383 m_parser_vars->m_target_info.byte_order,
384 m_parser_vars->m_target_info.address_byte_size)
385 .get());
386
387 if (!var)
388 return false;
389
390 var->m_frozen_sp->SetHasCompleteType();
391
392 if (is_result)
393 var->m_flags |= ClangExpressionVariable::EVNeedsFreezeDry;
394 else
395 var->m_flags |=
396 ClangExpressionVariable::EVKeepInTarget; // explicitly-declared
397 // persistent variables should
398 // persist
399
400 if (is_lvalue) {
401 var->m_flags |= ClangExpressionVariable::EVIsProgramReference;
402 } else {
403 var->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated;
404 var->m_flags |= ClangExpressionVariable::EVNeedsAllocation;
405 }
406
407 if (m_keep_result_in_memory) {
408 var->m_flags |= ClangExpressionVariable::EVKeepInTarget;
409 }
410
411 if (log)
412 log->Printf("Created persistent variable with flags 0x%hx", var->m_flags);
413
414 var->EnableParserVars(GetParserID());
415
416 ClangExpressionVariable::ParserVars *parser_vars =
417 var->GetParserVars(GetParserID());
418
419 parser_vars->m_named_decl = decl;
420 parser_vars->m_parser_type = parser_type;
421
422 return true;
Sean Callanan2235f322010-08-11 03:57:18 +0000423}
424
Kate Stoneb9c1b512016-09-06 20:57:50 +0000425bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl,
426 const ConstString &name,
427 llvm::Value *value, size_t size,
428 lldb::offset_t alignment) {
429 assert(m_struct_vars.get());
430 assert(m_parser_vars.get());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000431
Kate Stoneb9c1b512016-09-06 20:57:50 +0000432 bool is_persistent_variable = false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000433
Kate Stoneb9c1b512016-09-06 20:57:50 +0000434 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000435
Kate Stoneb9c1b512016-09-06 20:57:50 +0000436 m_struct_vars->m_struct_laid_out = false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000437
Kate Stoneb9c1b512016-09-06 20:57:50 +0000438 if (ClangExpressionVariable::FindVariableInList(m_struct_members, decl,
439 GetParserID()))
440 return true;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000441
Kate Stoneb9c1b512016-09-06 20:57:50 +0000442 ClangExpressionVariable *var(ClangExpressionVariable::FindVariableInList(
443 m_found_entities, decl, GetParserID()));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000444
Kate Stoneb9c1b512016-09-06 20:57:50 +0000445 if (!var) {
446 var = ClangExpressionVariable::FindVariableInList(
447 *m_parser_vars->m_persistent_vars, decl, GetParserID());
448 is_persistent_variable = true;
449 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000450
Kate Stoneb9c1b512016-09-06 20:57:50 +0000451 if (!var)
452 return false;
453
454 if (log)
455 log->Printf("Adding value for (NamedDecl*)%p [%s - %s] to the structure",
456 static_cast<const void *>(decl), name.GetCString(),
457 var->GetName().GetCString());
458
459 // We know entity->m_parser_vars is valid because we used a parser variable
460 // to find it
461
462 ClangExpressionVariable::ParserVars *parser_vars =
463 llvm::cast<ClangExpressionVariable>(var)->GetParserVars(GetParserID());
464
465 parser_vars->m_llvm_value = value;
466
467 if (ClangExpressionVariable::JITVars *jit_vars =
468 llvm::cast<ClangExpressionVariable>(var)->GetJITVars(GetParserID())) {
469 // We already laid this out; do not touch
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000470
Sean Callanan823bb4c2010-08-30 22:17:16 +0000471 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000472 log->Printf("Already placed at 0x%llx",
473 (unsigned long long)jit_vars->m_offset);
474 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000475
Kate Stoneb9c1b512016-09-06 20:57:50 +0000476 llvm::cast<ClangExpressionVariable>(var)->EnableJITVars(GetParserID());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000477
Kate Stoneb9c1b512016-09-06 20:57:50 +0000478 ClangExpressionVariable::JITVars *jit_vars =
479 llvm::cast<ClangExpressionVariable>(var)->GetJITVars(GetParserID());
Sean Callanan3c495c12013-01-15 23:29:36 +0000480
Kate Stoneb9c1b512016-09-06 20:57:50 +0000481 jit_vars->m_alignment = alignment;
482 jit_vars->m_size = size;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000483
Kate Stoneb9c1b512016-09-06 20:57:50 +0000484 m_struct_members.AddVariable(var->shared_from_this());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000485
Kate Stoneb9c1b512016-09-06 20:57:50 +0000486 if (m_parser_vars->m_materializer) {
487 uint32_t offset = 0;
488
Zachary Turner97206d52017-05-12 04:51:55 +0000489 Status err;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000490
491 if (is_persistent_variable) {
492 ExpressionVariableSP var_sp(var->shared_from_this());
493 offset = m_parser_vars->m_materializer->AddPersistentVariable(
494 var_sp, nullptr, err);
495 } else {
496 if (const lldb_private::Symbol *sym = parser_vars->m_lldb_sym)
497 offset = m_parser_vars->m_materializer->AddSymbol(*sym, err);
498 else if (const RegisterInfo *reg_info = var->GetRegisterInfo())
499 offset = m_parser_vars->m_materializer->AddRegister(*reg_info, err);
500 else if (parser_vars->m_lldb_var)
501 offset = m_parser_vars->m_materializer->AddVariable(
502 parser_vars->m_lldb_var, err);
Sean Callanan1582ee62013-04-18 22:06:33 +0000503 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000504
Kate Stoneb9c1b512016-09-06 20:57:50 +0000505 if (!err.Success())
506 return false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000507
Kate Stoneb9c1b512016-09-06 20:57:50 +0000508 if (log)
509 log->Printf("Placed at 0x%llx", (unsigned long long)offset);
Sean Callanan3c495c12013-01-15 23:29:36 +0000510
Kate Stoneb9c1b512016-09-06 20:57:50 +0000511 jit_vars->m_offset =
512 offset; // TODO DoStructLayout() should not change this.
513 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000514
Kate Stoneb9c1b512016-09-06 20:57:50 +0000515 return true;
516}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000517
Kate Stoneb9c1b512016-09-06 20:57:50 +0000518bool ClangExpressionDeclMap::DoStructLayout() {
519 assert(m_struct_vars.get());
Sean Callanan3dd6a422013-04-11 21:16:36 +0000520
Kate Stoneb9c1b512016-09-06 20:57:50 +0000521 if (m_struct_vars->m_struct_laid_out)
522 return true;
Sean Callanandf667652013-04-11 02:05:11 +0000523
Kate Stoneb9c1b512016-09-06 20:57:50 +0000524 if (!m_parser_vars->m_materializer)
525 return false;
526
527 m_struct_vars->m_struct_alignment =
528 m_parser_vars->m_materializer->GetStructAlignment();
529 m_struct_vars->m_struct_size =
530 m_parser_vars->m_materializer->GetStructByteSize();
531 m_struct_vars->m_struct_laid_out = true;
532 return true;
533}
534
535bool ClangExpressionDeclMap::GetStructInfo(uint32_t &num_elements, size_t &size,
536 lldb::offset_t &alignment) {
537 assert(m_struct_vars.get());
538
539 if (!m_struct_vars->m_struct_laid_out)
540 return false;
541
542 num_elements = m_struct_members.GetSize();
543 size = m_struct_vars->m_struct_size;
544 alignment = m_struct_vars->m_struct_alignment;
545
546 return true;
547}
548
549bool ClangExpressionDeclMap::GetStructElement(const NamedDecl *&decl,
550 llvm::Value *&value,
551 lldb::offset_t &offset,
552 ConstString &name,
553 uint32_t index) {
554 assert(m_struct_vars.get());
555
556 if (!m_struct_vars->m_struct_laid_out)
557 return false;
558
559 if (index >= m_struct_members.GetSize())
560 return false;
561
562 ExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(index));
563
564 if (!member_sp)
565 return false;
566
567 ClangExpressionVariable::ParserVars *parser_vars =
568 llvm::cast<ClangExpressionVariable>(member_sp.get())
569 ->GetParserVars(GetParserID());
570 ClangExpressionVariable::JITVars *jit_vars =
571 llvm::cast<ClangExpressionVariable>(member_sp.get())
572 ->GetJITVars(GetParserID());
573
574 if (!parser_vars || !jit_vars || !member_sp->GetValueObject())
575 return false;
576
577 decl = parser_vars->m_named_decl;
578 value = parser_vars->m_llvm_value;
579 offset = jit_vars->m_offset;
580 name = member_sp->GetName();
581
582 return true;
583}
584
585bool ClangExpressionDeclMap::GetFunctionInfo(const NamedDecl *decl,
586 uint64_t &ptr) {
587 ClangExpressionVariable *entity(ClangExpressionVariable::FindVariableInList(
588 m_found_entities, decl, GetParserID()));
589
590 if (!entity)
591 return false;
592
Adrian Prantl05097242018-04-30 16:49:04 +0000593 // We know m_parser_vars is valid since we searched for the variable by its
594 // NamedDecl
Kate Stoneb9c1b512016-09-06 20:57:50 +0000595
596 ClangExpressionVariable::ParserVars *parser_vars =
597 entity->GetParserVars(GetParserID());
598
599 ptr = parser_vars->m_lldb_value.GetScalar().ULongLong();
600
601 return true;
602}
603
604addr_t ClangExpressionDeclMap::GetSymbolAddress(Target &target,
605 Process *process,
606 const ConstString &name,
607 lldb::SymbolType symbol_type,
608 lldb_private::Module *module) {
609 SymbolContextList sc_list;
610
611 if (module)
612 module->FindSymbolsWithNameAndType(name, symbol_type, sc_list);
613 else
614 target.GetImages().FindSymbolsWithNameAndType(name, symbol_type, sc_list);
615
616 const uint32_t num_matches = sc_list.GetSize();
617 addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
618
619 for (uint32_t i = 0;
620 i < num_matches &&
621 (symbol_load_addr == 0 || symbol_load_addr == LLDB_INVALID_ADDRESS);
622 i++) {
623 SymbolContext sym_ctx;
624 sc_list.GetContextAtIndex(i, sym_ctx);
625
626 const Address sym_address = sym_ctx.symbol->GetAddress();
627
628 if (!sym_address.IsValid())
629 continue;
630
631 switch (sym_ctx.symbol->GetType()) {
632 case eSymbolTypeCode:
633 case eSymbolTypeTrampoline:
634 symbol_load_addr = sym_address.GetCallableLoadAddress(&target);
635 break;
636
637 case eSymbolTypeResolver:
638 symbol_load_addr = sym_address.GetCallableLoadAddress(&target, true);
639 break;
640
641 case eSymbolTypeReExported: {
642 ConstString reexport_name = sym_ctx.symbol->GetReExportedSymbolName();
643 if (reexport_name) {
644 ModuleSP reexport_module_sp;
645 ModuleSpec reexport_module_spec;
646 reexport_module_spec.GetPlatformFileSpec() =
647 sym_ctx.symbol->GetReExportedSymbolSharedLibrary();
648 if (reexport_module_spec.GetPlatformFileSpec()) {
649 reexport_module_sp =
650 target.GetImages().FindFirstModule(reexport_module_spec);
651 if (!reexport_module_sp) {
652 reexport_module_spec.GetPlatformFileSpec().GetDirectory().Clear();
653 reexport_module_sp =
654 target.GetImages().FindFirstModule(reexport_module_spec);
655 }
Sean Callanandf667652013-04-11 02:05:11 +0000656 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000657 symbol_load_addr = GetSymbolAddress(
658 target, process, sym_ctx.symbol->GetReExportedSymbolName(),
659 symbol_type, reexport_module_sp.get());
660 }
661 } break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000662
Kate Stoneb9c1b512016-09-06 20:57:50 +0000663 case eSymbolTypeData:
664 case eSymbolTypeRuntime:
665 case eSymbolTypeVariable:
666 case eSymbolTypeLocal:
667 case eSymbolTypeParam:
668 case eSymbolTypeInvalid:
669 case eSymbolTypeAbsolute:
670 case eSymbolTypeException:
671 case eSymbolTypeSourceFile:
672 case eSymbolTypeHeaderFile:
673 case eSymbolTypeObjectFile:
674 case eSymbolTypeCommonBlock:
675 case eSymbolTypeBlock:
676 case eSymbolTypeVariableType:
677 case eSymbolTypeLineEntry:
678 case eSymbolTypeLineHeader:
679 case eSymbolTypeScopeBegin:
680 case eSymbolTypeScopeEnd:
681 case eSymbolTypeAdditional:
682 case eSymbolTypeCompiler:
683 case eSymbolTypeInstrumentation:
684 case eSymbolTypeUndefined:
685 case eSymbolTypeObjCClass:
686 case eSymbolTypeObjCMetaClass:
687 case eSymbolTypeObjCIVar:
688 symbol_load_addr = sym_address.GetLoadAddress(&target);
689 break;
Sean Callanandf667652013-04-11 02:05:11 +0000690 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000691 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000692
Kate Stoneb9c1b512016-09-06 20:57:50 +0000693 if (symbol_load_addr == LLDB_INVALID_ADDRESS && process) {
694 ObjCLanguageRuntime *runtime = process->GetObjCLanguageRuntime();
Sean Callanan549c9f72010-07-13 21:41:46 +0000695
Kate Stoneb9c1b512016-09-06 20:57:50 +0000696 if (runtime) {
697 symbol_load_addr = runtime->LookupRuntimeSymbol(name);
Greg Clayton084db102011-06-23 04:25:29 +0000698 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000699 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000700
Kate Stoneb9c1b512016-09-06 20:57:50 +0000701 return symbol_load_addr;
Sean Callananc3a16002011-01-17 23:42:46 +0000702}
703
Kate Stoneb9c1b512016-09-06 20:57:50 +0000704addr_t ClangExpressionDeclMap::GetSymbolAddress(const ConstString &name,
705 lldb::SymbolType symbol_type) {
706 assert(m_parser_vars.get());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000707
Kate Stoneb9c1b512016-09-06 20:57:50 +0000708 if (!m_parser_vars->m_exe_ctx.GetTargetPtr())
709 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000710
Kate Stoneb9c1b512016-09-06 20:57:50 +0000711 return GetSymbolAddress(m_parser_vars->m_exe_ctx.GetTargetRef(),
712 m_parser_vars->m_exe_ctx.GetProcessPtr(), name,
713 symbol_type);
Sean Callanand9ca42a2011-05-08 02:21:26 +0000714}
715
Kate Stoneb9c1b512016-09-06 20:57:50 +0000716lldb::VariableSP ClangExpressionDeclMap::FindGlobalVariable(
717 Target &target, ModuleSP &module, const ConstString &name,
718 CompilerDeclContext *namespace_decl, TypeFromUser *type) {
719 VariableList vars;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000720
Kate Stoneb9c1b512016-09-06 20:57:50 +0000721 if (module && namespace_decl)
Pavel Labath34cda142018-05-31 09:46:26 +0000722 module->FindGlobalVariables(name, namespace_decl, -1, vars);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000723 else
Pavel Labath34cda142018-05-31 09:46:26 +0000724 target.GetImages().FindGlobalVariables(name, -1, vars);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000725
Kate Stoneb9c1b512016-09-06 20:57:50 +0000726 if (vars.GetSize()) {
727 if (type) {
728 for (size_t i = 0; i < vars.GetSize(); ++i) {
729 VariableSP var_sp = vars.GetVariableAtIndex(i);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000730
Kate Stoneb9c1b512016-09-06 20:57:50 +0000731 if (ClangASTContext::AreTypesSame(
732 *type, var_sp->GetType()->GetFullCompilerType()))
733 return var_sp;
734 }
735 } else {
736 return vars.GetVariableAtIndex(0);
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000737 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000738 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000739
Kate Stoneb9c1b512016-09-06 20:57:50 +0000740 return VariableSP();
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000741}
742
Kate Stoneb9c1b512016-09-06 20:57:50 +0000743ClangASTContext *ClangExpressionDeclMap::GetClangASTContext() {
744 StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
745 if (frame == nullptr)
746 return nullptr;
Siva Chandra03ff5c82016-02-05 19:10:04 +0000747
Kate Stoneb9c1b512016-09-06 20:57:50 +0000748 SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
749 lldb::eSymbolContextBlock);
750 if (sym_ctx.block == nullptr)
751 return nullptr;
Siva Chandra03ff5c82016-02-05 19:10:04 +0000752
Kate Stoneb9c1b512016-09-06 20:57:50 +0000753 CompilerDeclContext frame_decl_context = sym_ctx.block->GetDeclContext();
754 if (!frame_decl_context)
755 return nullptr;
Siva Chandra03ff5c82016-02-05 19:10:04 +0000756
Kate Stoneb9c1b512016-09-06 20:57:50 +0000757 return llvm::dyn_cast_or_null<ClangASTContext>(
758 frame_decl_context.GetTypeSystem());
Siva Chandra03ff5c82016-02-05 19:10:04 +0000759}
760
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000761// Interface for ClangASTSource
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000762
Kate Stoneb9c1b512016-09-06 20:57:50 +0000763void ClangExpressionDeclMap::FindExternalVisibleDecls(
764 NameSearchContext &context) {
765 assert(m_ast_context);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000766
Kate Stoneb9c1b512016-09-06 20:57:50 +0000767 ClangASTMetrics::RegisterVisibleQuery();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000768
Kate Stoneb9c1b512016-09-06 20:57:50 +0000769 const ConstString name(context.m_decl_name.getAsString().c_str());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000770
Kate Stoneb9c1b512016-09-06 20:57:50 +0000771 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000772
Kate Stoneb9c1b512016-09-06 20:57:50 +0000773 if (GetImportInProgress()) {
774 if (log && log->GetVerbose())
775 log->Printf("Ignoring a query during an import");
776 return;
777 }
778
779 static unsigned int invocation_id = 0;
780 unsigned int current_id = invocation_id++;
781
782 if (log) {
783 if (!context.m_decl_context)
784 log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for "
785 "'%s' in a NULL DeclContext",
786 current_id, name.GetCString());
787 else if (const NamedDecl *context_named_decl =
788 dyn_cast<NamedDecl>(context.m_decl_context))
789 log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for "
790 "'%s' in '%s'",
791 current_id, name.GetCString(),
792 context_named_decl->getNameAsString().c_str());
793 else
794 log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for "
795 "'%s' in a '%s'",
796 current_id, name.GetCString(),
797 context.m_decl_context->getDeclKindName());
798 }
799
800 if (const NamespaceDecl *namespace_context =
801 dyn_cast<NamespaceDecl>(context.m_decl_context)) {
802 if (namespace_context->getName().str() ==
803 std::string(g_lldb_local_vars_namespace_cstr)) {
804 CompilerDeclContext compiler_decl_ctx(
805 GetClangASTContext(), const_cast<void *>(static_cast<const void *>(
806 context.m_decl_context)));
807 FindExternalVisibleDecls(context, lldb::ModuleSP(), compiler_decl_ctx,
808 current_id);
809 return;
Sean Callanan6abfabf2010-11-19 20:20:02 +0000810 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000811
Kate Stoneb9c1b512016-09-06 20:57:50 +0000812 ClangASTImporter::NamespaceMapSP namespace_map =
Sean Callanan68e44232017-09-28 20:20:25 +0000813 m_ast_importer_sp
814 ? m_ast_importer_sp->GetNamespaceMap(namespace_context)
815 : ClangASTImporter::NamespaceMapSP();
816
817 if (!namespace_map)
818 return;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000819
820 if (log && log->GetVerbose())
821 log->Printf(" CEDM::FEVD[%u] Inspecting (NamespaceMap*)%p (%d entries)",
822 current_id, static_cast<void *>(namespace_map.get()),
823 (int)namespace_map->size());
Sean Callanan68e44232017-09-28 20:20:25 +0000824
Kate Stoneb9c1b512016-09-06 20:57:50 +0000825 for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(),
826 e = namespace_map->end();
827 i != e; ++i) {
828 if (log)
829 log->Printf(" CEDM::FEVD[%u] Searching namespace %s in module %s",
830 current_id, i->second.GetName().AsCString(),
831 i->first->GetFileSpec().GetFilename().GetCString());
832
833 FindExternalVisibleDecls(context, i->first, i->second, current_id);
834 }
835 } else if (isa<TranslationUnitDecl>(context.m_decl_context)) {
836 CompilerDeclContext namespace_decl;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000837
Sean Callanan503aa522011-10-12 00:12:34 +0000838 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000839 log->Printf(" CEDM::FEVD[%u] Searching the root namespace", current_id);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000840
Kate Stoneb9c1b512016-09-06 20:57:50 +0000841 FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl,
842 current_id);
843 }
Sean Callananc02a1c02017-04-24 23:14:04 +0000844
845 ClangASTSource::FindExternalVisibleDecls(context);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000846}
847
848void ClangExpressionDeclMap::FindExternalVisibleDecls(
849 NameSearchContext &context, lldb::ModuleSP module_sp,
850 CompilerDeclContext &namespace_decl, unsigned int current_id) {
851 assert(m_ast_context);
852
853 std::function<void(clang::FunctionDecl *)> MaybeRegisterFunctionBody =
854 [this](clang::FunctionDecl *copied_function_decl) {
855 if (copied_function_decl->getBody() && m_parser_vars->m_code_gen) {
856 DeclGroupRef decl_group_ref(copied_function_decl);
857 m_parser_vars->m_code_gen->HandleTopLevelDecl(decl_group_ref);
858 }
859 };
860
861 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
862
863 SymbolContextList sc_list;
864
865 const ConstString name(context.m_decl_name.getAsString().c_str());
Sean Callanan1b3c43b2017-09-26 17:25:34 +0000866 if (IgnoreName(name, false))
Kate Stoneb9c1b512016-09-06 20:57:50 +0000867 return;
868
Adrian Prantl05097242018-04-30 16:49:04 +0000869 // Only look for functions by name out in our symbols if the function doesn't
870 // start with our phony prefix of '$'
Kate Stoneb9c1b512016-09-06 20:57:50 +0000871 Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
872 StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
873 SymbolContext sym_ctx;
874 if (frame != nullptr)
875 sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
876 lldb::eSymbolContextBlock);
877
878 // Try the persistent decls, which take precedence over all else.
879 if (!namespace_decl) {
880 do {
881 if (!target)
882 break;
883
884 ClangASTContext *scratch_clang_ast_context =
885 target->GetScratchClangASTContext();
886
887 if (!scratch_clang_ast_context)
888 break;
889
890 ASTContext *scratch_ast_context =
891 scratch_clang_ast_context->getASTContext();
892
893 if (!scratch_ast_context)
894 break;
895
896 NamedDecl *persistent_decl =
897 m_parser_vars->m_persistent_vars->GetPersistentDecl(name);
898
899 if (!persistent_decl)
900 break;
901
Sean Callanan68e44232017-09-28 20:20:25 +0000902 Decl *parser_persistent_decl = CopyDecl(persistent_decl);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000903
904 if (!parser_persistent_decl)
905 break;
906
907 NamedDecl *parser_named_decl =
908 dyn_cast<NamedDecl>(parser_persistent_decl);
909
910 if (!parser_named_decl)
911 break;
912
913 if (clang::FunctionDecl *parser_function_decl =
914 llvm::dyn_cast<clang::FunctionDecl>(parser_named_decl)) {
915 MaybeRegisterFunctionBody(parser_function_decl);
916 }
917
918 if (log)
919 log->Printf(" CEDM::FEVD[%u] Found persistent decl %s", current_id,
920 name.GetCString());
921
922 context.AddNamedDecl(parser_named_decl);
923 } while (0);
924 }
925
Sean Callanan1b3c43b2017-09-26 17:25:34 +0000926 if (name.GetCString()[0] == '$' && !namespace_decl) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000927 static ConstString g_lldb_class_name("$__lldb_class");
928
929 if (name == g_lldb_class_name) {
930 // Clang is looking for the type of "this"
931
932 if (frame == NULL)
933 return;
934
935 // Find the block that defines the function represented by "sym_ctx"
936 Block *function_block = sym_ctx.GetFunctionBlock();
937
938 if (!function_block)
939 return;
940
941 CompilerDeclContext function_decl_ctx = function_block->GetDeclContext();
942
943 if (!function_decl_ctx)
944 return;
945
946 clang::CXXMethodDecl *method_decl =
947 ClangASTContext::DeclContextGetAsCXXMethodDecl(function_decl_ctx);
948
949 if (method_decl) {
950 clang::CXXRecordDecl *class_decl = method_decl->getParent();
951
952 QualType class_qual_type(class_decl->getTypeForDecl(), 0);
953
954 TypeFromUser class_user_type(
955 class_qual_type.getAsOpaquePtr(),
956 ClangASTContext::GetASTContext(&class_decl->getASTContext()));
957
958 if (log) {
959 ASTDumper ast_dumper(class_qual_type);
960 log->Printf(" CEDM::FEVD[%u] Adding type for $__lldb_class: %s",
961 current_id, ast_dumper.GetCString());
Siva Chandra03ff5c82016-02-05 19:10:04 +0000962 }
963
Kate Stoneb9c1b512016-09-06 20:57:50 +0000964 AddThisType(context, class_user_type, current_id);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000965
Kate Stoneb9c1b512016-09-06 20:57:50 +0000966 if (method_decl->isInstance()) {
967 // self is a pointer to the object
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000968
Kate Stoneb9c1b512016-09-06 20:57:50 +0000969 QualType class_pointer_type =
970 method_decl->getASTContext().getPointerType(class_qual_type);
971
972 TypeFromUser self_user_type(
973 class_pointer_type.getAsOpaquePtr(),
974 ClangASTContext::GetASTContext(&method_decl->getASTContext()));
975
976 m_struct_vars->m_object_pointer_type = self_user_type;
977 }
978 } else {
Adrian Prantl05097242018-04-30 16:49:04 +0000979 // This branch will get hit if we are executing code in the context of
980 // a function that claims to have an object pointer (through
981 // DW_AT_object_pointer?) but is not formally a method of the class.
982 // In that case, just look up the "this" variable in the current scope
983 // and use its type.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000984 // FIXME: This code is formally correct, but clang doesn't currently
985 // emit DW_AT_object_pointer
986 // for C++ so it hasn't actually been tested.
987
988 VariableList *vars = frame->GetVariableList(false);
989
990 lldb::VariableSP this_var = vars->FindVariable(ConstString("this"));
991
992 if (this_var && this_var->IsInScope(frame) &&
993 this_var->LocationIsValidForFrame(frame)) {
994 Type *this_type = this_var->GetType();
995
996 if (!this_type)
Sean Callananb2269162011-10-21 22:18:07 +0000997 return;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000998
Kate Stoneb9c1b512016-09-06 20:57:50 +0000999 TypeFromUser pointee_type =
1000 this_type->GetForwardCompilerType().GetPointeeType();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001001
Kate Stoneb9c1b512016-09-06 20:57:50 +00001002 if (pointee_type.IsValid()) {
1003 if (log) {
1004 ASTDumper ast_dumper(pointee_type);
1005 log->Printf(" FEVD[%u] Adding type for $__lldb_class: %s",
1006 current_id, ast_dumper.GetCString());
1007 }
1008
1009 AddThisType(context, pointee_type, current_id);
1010 TypeFromUser this_user_type(this_type->GetFullCompilerType());
1011 m_struct_vars->m_object_pointer_type = this_user_type;
1012 return;
1013 }
Sean Callanan503aa522011-10-12 00:12:34 +00001014 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001015 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001016
Kate Stoneb9c1b512016-09-06 20:57:50 +00001017 return;
1018 }
1019
1020 static ConstString g_lldb_objc_class_name("$__lldb_objc_class");
1021 if (name == g_lldb_objc_class_name) {
1022 // Clang is looking for the type of "*self"
1023
1024 if (!frame)
1025 return;
1026
1027 SymbolContext sym_ctx = frame->GetSymbolContext(
1028 lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);
1029
1030 // Find the block that defines the function represented by "sym_ctx"
1031 Block *function_block = sym_ctx.GetFunctionBlock();
1032
1033 if (!function_block)
1034 return;
1035
1036 CompilerDeclContext function_decl_ctx = function_block->GetDeclContext();
1037
1038 if (!function_decl_ctx)
1039 return;
1040
1041 clang::ObjCMethodDecl *method_decl =
1042 ClangASTContext::DeclContextGetAsObjCMethodDecl(function_decl_ctx);
1043
1044 if (method_decl) {
1045 ObjCInterfaceDecl *self_interface = method_decl->getClassInterface();
1046
1047 if (!self_interface)
1048 return;
1049
1050 const clang::Type *interface_type = self_interface->getTypeForDecl();
1051
1052 if (!interface_type)
1053 return; // This is unlikely, but we have seen crashes where this
1054 // occurred
1055
1056 TypeFromUser class_user_type(
1057 QualType(interface_type, 0).getAsOpaquePtr(),
1058 ClangASTContext::GetASTContext(&method_decl->getASTContext()));
1059
1060 if (log) {
1061 ASTDumper ast_dumper(interface_type);
1062 log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s",
1063 current_id, ast_dumper.GetCString());
1064 }
1065
1066 AddOneType(context, class_user_type, current_id);
1067
1068 if (method_decl->isInstanceMethod()) {
1069 // self is a pointer to the object
1070
1071 QualType class_pointer_type =
1072 method_decl->getASTContext().getObjCObjectPointerType(
1073 QualType(interface_type, 0));
1074
1075 TypeFromUser self_user_type(
1076 class_pointer_type.getAsOpaquePtr(),
1077 ClangASTContext::GetASTContext(&method_decl->getASTContext()));
1078
1079 m_struct_vars->m_object_pointer_type = self_user_type;
1080 } else {
1081 // self is a Class pointer
1082 QualType class_type = method_decl->getASTContext().getObjCClassType();
1083
1084 TypeFromUser self_user_type(
1085 class_type.getAsOpaquePtr(),
1086 ClangASTContext::GetASTContext(&method_decl->getASTContext()));
1087
1088 m_struct_vars->m_object_pointer_type = self_user_type;
1089 }
1090
1091 return;
1092 } else {
Adrian Prantl05097242018-04-30 16:49:04 +00001093 // This branch will get hit if we are executing code in the context of
1094 // a function that claims to have an object pointer (through
1095 // DW_AT_object_pointer?) but is not formally a method of the class.
1096 // In that case, just look up the "self" variable in the current scope
1097 // and use its type.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001098
1099 VariableList *vars = frame->GetVariableList(false);
1100
1101 lldb::VariableSP self_var = vars->FindVariable(ConstString("self"));
1102
1103 if (self_var && self_var->IsInScope(frame) &&
1104 self_var->LocationIsValidForFrame(frame)) {
1105 Type *self_type = self_var->GetType();
1106
1107 if (!self_type)
1108 return;
1109
1110 CompilerType self_clang_type = self_type->GetFullCompilerType();
1111
1112 if (ClangASTContext::IsObjCClassType(self_clang_type)) {
1113 return;
1114 } else if (ClangASTContext::IsObjCObjectPointerType(
1115 self_clang_type)) {
1116 self_clang_type = self_clang_type.GetPointeeType();
1117
1118 if (!self_clang_type)
1119 return;
1120
1121 if (log) {
1122 ASTDumper ast_dumper(self_type->GetFullCompilerType());
1123 log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s",
1124 current_id, ast_dumper.GetCString());
1125 }
1126
1127 TypeFromUser class_user_type(self_clang_type);
1128
1129 AddOneType(context, class_user_type, current_id);
1130
1131 TypeFromUser self_user_type(self_type->GetFullCompilerType());
1132
1133 m_struct_vars->m_object_pointer_type = self_user_type;
1134 return;
1135 }
1136 }
1137 }
1138
1139 return;
1140 }
1141
1142 if (name == ConstString(g_lldb_local_vars_namespace_cstr)) {
1143 CompilerDeclContext frame_decl_context =
1144 sym_ctx.block != nullptr ? sym_ctx.block->GetDeclContext()
1145 : CompilerDeclContext();
1146
1147 if (frame_decl_context) {
1148 ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(
1149 frame_decl_context.GetTypeSystem());
1150
1151 if (ast) {
1152 clang::NamespaceDecl *namespace_decl =
1153 ClangASTContext::GetUniqueNamespaceDeclaration(
Sean Callanan1b3c43b2017-09-26 17:25:34 +00001154 m_ast_context, name.GetCString(), nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001155 if (namespace_decl) {
1156 context.AddNamedDecl(namespace_decl);
1157 clang::DeclContext *clang_decl_ctx =
1158 clang::Decl::castToDeclContext(namespace_decl);
1159 clang_decl_ctx->setHasExternalVisibleStorage(true);
1160 context.m_found.local_vars_nsp = true;
1161 }
1162 }
1163 }
1164
1165 return;
1166 }
1167
1168 // any other $__lldb names should be weeded out now
Sean Callanan1b3c43b2017-09-26 17:25:34 +00001169 if (name.GetStringRef().startswith("$__lldb"))
Kate Stoneb9c1b512016-09-06 20:57:50 +00001170 return;
1171
1172 ExpressionVariableSP pvar_sp(
1173 m_parser_vars->m_persistent_vars->GetVariable(name));
1174
1175 if (pvar_sp) {
1176 AddOneVariable(context, pvar_sp, current_id);
1177 return;
1178 }
1179
1180 const char *reg_name(&name.GetCString()[1]);
1181
1182 if (m_parser_vars->m_exe_ctx.GetRegisterContext()) {
1183 const RegisterInfo *reg_info(
1184 m_parser_vars->m_exe_ctx.GetRegisterContext()->GetRegisterInfoByName(
1185 reg_name));
1186
1187 if (reg_info) {
Sean Callanan503aa522011-10-12 00:12:34 +00001188 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001189 log->Printf(" CEDM::FEVD[%u] Found register %s", current_id,
1190 reg_info->name);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001191
Kate Stoneb9c1b512016-09-06 20:57:50 +00001192 AddOneRegister(context, reg_info, current_id);
1193 }
1194 }
1195 } else {
1196 ValueObjectSP valobj;
1197 VariableSP var;
1198
1199 bool local_var_lookup =
1200 !namespace_decl || (namespace_decl.GetName() ==
1201 ConstString(g_lldb_local_vars_namespace_cstr));
1202 if (frame && local_var_lookup) {
1203 CompilerDeclContext compiler_decl_context =
1204 sym_ctx.block != nullptr ? sym_ctx.block->GetDeclContext()
1205 : CompilerDeclContext();
1206
1207 if (compiler_decl_context) {
1208 // Make sure that the variables are parsed so that we have the
1209 // declarations.
1210 VariableListSP vars = frame->GetInScopeVariableList(true);
1211 for (size_t i = 0; i < vars->GetSize(); i++)
1212 vars->GetVariableAtIndex(i)->GetDecl();
1213
1214 // Search for declarations matching the name. Do not include imported
Adrian Prantl05097242018-04-30 16:49:04 +00001215 // decls in the search if we are looking for decls in the artificial
1216 // namespace $__lldb_local_vars.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001217 std::vector<CompilerDecl> found_decls =
1218 compiler_decl_context.FindDeclByName(name,
1219 namespace_decl.IsValid());
1220
1221 bool variable_found = false;
1222 for (CompilerDecl decl : found_decls) {
1223 for (size_t vi = 0, ve = vars->GetSize(); vi != ve; ++vi) {
1224 VariableSP candidate_var = vars->GetVariableAtIndex(vi);
1225 if (candidate_var->GetDecl() == decl) {
1226 var = candidate_var;
1227 break;
1228 }
1229 }
1230
Sean Callananc02a1c02017-04-24 23:14:04 +00001231 if (var && !variable_found) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001232 variable_found = true;
1233 valobj = ValueObjectVariable::Create(frame, var);
1234 AddOneVariable(context, var, valobj, current_id);
1235 context.m_found.variable = true;
1236 }
1237 }
1238 if (variable_found)
1239 return;
1240 }
1241 }
1242 if (target) {
1243 var = FindGlobalVariable(*target, module_sp, name, &namespace_decl, NULL);
1244
1245 if (var) {
1246 valobj = ValueObjectVariable::Create(target, var);
1247 AddOneVariable(context, var, valobj, current_id);
1248 context.m_found.variable = true;
1249 return;
1250 }
Sean Callanan503aa522011-10-12 00:12:34 +00001251 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001252
Kate Stoneb9c1b512016-09-06 20:57:50 +00001253 std::vector<clang::NamedDecl *> decls_from_modules;
Sean Callanan503aa522011-10-12 00:12:34 +00001254
Kate Stoneb9c1b512016-09-06 20:57:50 +00001255 if (target) {
1256 if (ClangModulesDeclVendor *decl_vendor =
1257 target->GetClangModulesDeclVendor()) {
1258 decl_vendor->FindDecls(name, false, UINT32_MAX, decls_from_modules);
1259 }
1260 }
Sean Callananb3a36df2016-03-19 00:51:43 +00001261
Sean Callananc02a1c02017-04-24 23:14:04 +00001262 const bool include_inlines = false;
1263 const bool append = false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001264
Sean Callananc02a1c02017-04-24 23:14:04 +00001265 if (namespace_decl && module_sp) {
1266 const bool include_symbols = false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001267
Sean Callananc02a1c02017-04-24 23:14:04 +00001268 module_sp->FindFunctions(name, &namespace_decl, eFunctionNameTypeBase,
1269 include_symbols, include_inlines, append,
1270 sc_list);
1271 } else if (target && !namespace_decl) {
1272 const bool include_symbols = true;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001273
Sean Callananc02a1c02017-04-24 23:14:04 +00001274 // TODO Fix FindFunctions so that it doesn't return
1275 // instance methods for eFunctionNameTypeBase.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001276
Sean Callananc02a1c02017-04-24 23:14:04 +00001277 target->GetImages().FindFunctions(name, eFunctionNameTypeFull,
1278 include_symbols, include_inlines,
1279 append, sc_list);
1280 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001281
Adrian Prantl05097242018-04-30 16:49:04 +00001282 // If we found more than one function, see if we can use the frame's decl
1283 // context to remove functions that are shadowed by other functions which
1284 // match in type but are nearer in scope.
Sean Callananc02a1c02017-04-24 23:14:04 +00001285 //
1286 // AddOneFunction will not add a function whose type has already been
Adrian Prantl05097242018-04-30 16:49:04 +00001287 // added, so if there's another function in the list with a matching type,
1288 // check to see if their decl context is a parent of the current frame's or
1289 // was imported via a and using statement, and pick the best match
1290 // according to lookup rules.
Sean Callananc02a1c02017-04-24 23:14:04 +00001291 if (sc_list.GetSize() > 1) {
1292 // Collect some info about our frame's context.
1293 StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
1294 SymbolContext frame_sym_ctx;
1295 if (frame != nullptr)
1296 frame_sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
1297 lldb::eSymbolContextBlock);
1298 CompilerDeclContext frame_decl_context =
1299 frame_sym_ctx.block != nullptr ? frame_sym_ctx.block->GetDeclContext()
1300 : CompilerDeclContext();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001301
Sean Callananc02a1c02017-04-24 23:14:04 +00001302 // We can't do this without a compiler decl context for our frame.
1303 if (frame_decl_context) {
1304 clang::DeclContext *frame_decl_ctx =
1305 (clang::DeclContext *)frame_decl_context.GetOpaqueDeclContext();
1306 ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(
1307 frame_decl_context.GetTypeSystem());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001308
Sean Callananc02a1c02017-04-24 23:14:04 +00001309 // Structure to hold the info needed when comparing function
1310 // declarations.
1311 struct FuncDeclInfo {
1312 ConstString m_name;
1313 CompilerType m_copied_type;
1314 uint32_t m_decl_lvl;
1315 SymbolContext m_sym_ctx;
1316 };
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001317
Adrian Prantl05097242018-04-30 16:49:04 +00001318 // First, symplify things by looping through the symbol contexts to
1319 // remove unwanted functions and separate out the functions we want to
1320 // compare and prune into a separate list. Cache the info needed about
1321 // the function declarations in a vector for efficiency.
Sean Callananc02a1c02017-04-24 23:14:04 +00001322 SymbolContextList sc_sym_list;
1323 uint32_t num_indices = sc_list.GetSize();
1324 std::vector<FuncDeclInfo> fdi_cache;
1325 fdi_cache.reserve(num_indices);
1326 for (uint32_t index = 0; index < num_indices; ++index) {
1327 FuncDeclInfo fdi;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001328 SymbolContext sym_ctx;
1329 sc_list.GetContextAtIndex(index, sym_ctx);
1330
Adrian Prantl05097242018-04-30 16:49:04 +00001331 // We don't know enough about symbols to compare them, but we should
1332 // keep them in the list.
Sean Callananc02a1c02017-04-24 23:14:04 +00001333 Function *function = sym_ctx.function;
1334 if (!function) {
1335 sc_sym_list.Append(sym_ctx);
1336 continue;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001337 }
Sean Callananc02a1c02017-04-24 23:14:04 +00001338 // Filter out functions without declaration contexts, as well as
Adrian Prantl05097242018-04-30 16:49:04 +00001339 // class/instance methods, since they'll be skipped in the code that
1340 // follows anyway.
Sean Callananc02a1c02017-04-24 23:14:04 +00001341 CompilerDeclContext func_decl_context = function->GetDeclContext();
1342 if (!func_decl_context ||
1343 func_decl_context.IsClassMethod(nullptr, nullptr, nullptr))
1344 continue;
1345 // We can only prune functions for which we can copy the type.
1346 CompilerType func_clang_type =
1347 function->GetType()->GetFullCompilerType();
1348 CompilerType copied_func_type = GuardedCopyType(func_clang_type);
1349 if (!copied_func_type) {
1350 sc_sym_list.Append(sym_ctx);
1351 continue;
1352 }
1353
1354 fdi.m_sym_ctx = sym_ctx;
1355 fdi.m_name = function->GetName();
1356 fdi.m_copied_type = copied_func_type;
1357 fdi.m_decl_lvl = LLDB_INVALID_DECL_LEVEL;
1358 if (fdi.m_copied_type && func_decl_context) {
Adrian Prantl05097242018-04-30 16:49:04 +00001359 // Call CountDeclLevels to get the number of parent scopes we have
1360 // to look through before we find the function declaration. When
1361 // comparing functions of the same type, the one with a lower count
1362 // will be closer to us in the lookup scope and shadows the other.
Sean Callananc02a1c02017-04-24 23:14:04 +00001363 clang::DeclContext *func_decl_ctx =
1364 (clang::DeclContext *)func_decl_context.GetOpaqueDeclContext();
1365 fdi.m_decl_lvl = ast->CountDeclLevels(
1366 frame_decl_ctx, func_decl_ctx, &fdi.m_name, &fdi.m_copied_type);
1367 }
1368 fdi_cache.emplace_back(fdi);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001369 }
1370
Sean Callananc02a1c02017-04-24 23:14:04 +00001371 // Loop through the functions in our cache looking for matching types,
1372 // then compare their scope levels to see which is closer.
1373 std::multimap<CompilerType, const FuncDeclInfo *> matches;
1374 for (const FuncDeclInfo &fdi : fdi_cache) {
1375 const CompilerType t = fdi.m_copied_type;
1376 auto q = matches.find(t);
1377 if (q != matches.end()) {
1378 if (q->second->m_decl_lvl > fdi.m_decl_lvl)
1379 // This function is closer; remove the old set.
1380 matches.erase(t);
1381 else if (q->second->m_decl_lvl < fdi.m_decl_lvl)
1382 // The functions in our set are closer - skip this one.
1383 continue;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001384 }
Sean Callananc02a1c02017-04-24 23:14:04 +00001385 matches.insert(std::make_pair(t, &fdi));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001386 }
1387
Sean Callananc02a1c02017-04-24 23:14:04 +00001388 // Loop through our matches and add their symbol contexts to our list.
1389 SymbolContextList sc_func_list;
1390 for (const auto &q : matches)
1391 sc_func_list.Append(q.second->m_sym_ctx);
1392
1393 // Rejoin the lists with the functions in front.
1394 sc_list = sc_func_list;
1395 sc_list.Append(sc_sym_list);
1396 }
1397 }
1398
1399 if (sc_list.GetSize()) {
1400 Symbol *extern_symbol = NULL;
1401 Symbol *non_extern_symbol = NULL;
1402
1403 for (uint32_t index = 0, num_indices = sc_list.GetSize();
1404 index < num_indices; ++index) {
1405 SymbolContext sym_ctx;
1406 sc_list.GetContextAtIndex(index, sym_ctx);
1407
1408 if (sym_ctx.function) {
1409 CompilerDeclContext decl_ctx = sym_ctx.function->GetDeclContext();
1410
1411 if (!decl_ctx)
1412 continue;
1413
1414 // Filter out class/instance methods.
1415 if (decl_ctx.IsClassMethod(nullptr, nullptr, nullptr))
1416 continue;
1417
1418 AddOneFunction(context, sym_ctx.function, NULL, current_id);
1419 context.m_found.function_with_type_info = true;
1420 context.m_found.function = true;
1421 } else if (sym_ctx.symbol) {
1422 if (sym_ctx.symbol->GetType() == eSymbolTypeReExported && target) {
1423 sym_ctx.symbol = sym_ctx.symbol->ResolveReExportedSymbol(*target);
1424 if (sym_ctx.symbol == NULL)
1425 continue;
1426 }
1427
1428 if (sym_ctx.symbol->IsExternal())
1429 extern_symbol = sym_ctx.symbol;
1430 else
1431 non_extern_symbol = sym_ctx.symbol;
1432 }
1433 }
1434
1435 if (!context.m_found.function_with_type_info) {
1436 for (clang::NamedDecl *decl : decls_from_modules) {
1437 if (llvm::isa<clang::FunctionDecl>(decl)) {
1438 clang::NamedDecl *copied_decl =
Sean Callanan68e44232017-09-28 20:20:25 +00001439 llvm::cast_or_null<FunctionDecl>(CopyDecl(decl));
Sean Callananc02a1c02017-04-24 23:14:04 +00001440 if (copied_decl) {
1441 context.AddNamedDecl(copied_decl);
1442 context.m_found.function_with_type_info = true;
1443 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001444 }
1445 }
1446 }
1447
1448 if (!context.m_found.function_with_type_info) {
Sean Callananc02a1c02017-04-24 23:14:04 +00001449 if (extern_symbol) {
1450 AddOneFunction(context, NULL, extern_symbol, current_id);
1451 context.m_found.function = true;
1452 } else if (non_extern_symbol) {
1453 AddOneFunction(context, NULL, non_extern_symbol, current_id);
1454 context.m_found.function = true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001455 }
1456 }
Sean Callananb3a36df2016-03-19 00:51:43 +00001457 }
Sean Callananc02a1c02017-04-24 23:14:04 +00001458
1459 if (!context.m_found.function_with_type_info) {
1460 // Try the modules next.
1461
1462 do {
1463 if (ClangModulesDeclVendor *modules_decl_vendor =
1464 m_target->GetClangModulesDeclVendor()) {
1465 bool append = false;
1466 uint32_t max_matches = 1;
1467 std::vector<clang::NamedDecl *> decls;
1468
1469 if (!modules_decl_vendor->FindDecls(name, append, max_matches, decls))
1470 break;
1471
1472 clang::NamedDecl *const decl_from_modules = decls[0];
1473
1474 if (llvm::isa<clang::FunctionDecl>(decl_from_modules)) {
1475 if (log) {
1476 log->Printf(" CAS::FEVD[%u] Matching function found for "
1477 "\"%s\" in the modules",
1478 current_id, name.GetCString());
1479 }
1480
Sean Callanan68e44232017-09-28 20:20:25 +00001481 clang::Decl *copied_decl = CopyDecl(decl_from_modules);
Sean Callananc02a1c02017-04-24 23:14:04 +00001482 clang::FunctionDecl *copied_function_decl =
1483 copied_decl ? dyn_cast<clang::FunctionDecl>(copied_decl)
1484 : nullptr;
1485
1486 if (!copied_function_decl) {
1487 if (log)
1488 log->Printf(" CAS::FEVD[%u] - Couldn't export a function "
1489 "declaration from the modules",
1490 current_id);
1491
1492 break;
1493 }
1494
1495 MaybeRegisterFunctionBody(copied_function_decl);
1496
1497 context.AddNamedDecl(copied_function_decl);
1498
1499 context.m_found.function_with_type_info = true;
1500 context.m_found.function = true;
1501 } else if (llvm::isa<clang::VarDecl>(decl_from_modules)) {
1502 if (log) {
1503 log->Printf(" CAS::FEVD[%u] Matching variable found for "
1504 "\"%s\" in the modules",
1505 current_id, name.GetCString());
1506 }
1507
Sean Callanan68e44232017-09-28 20:20:25 +00001508 clang::Decl *copied_decl = CopyDecl(decl_from_modules);
Sean Callananc02a1c02017-04-24 23:14:04 +00001509 clang::VarDecl *copied_var_decl =
1510 copied_decl ? dyn_cast_or_null<clang::VarDecl>(copied_decl)
1511 : nullptr;
1512
1513 if (!copied_var_decl) {
1514 if (log)
1515 log->Printf(" CAS::FEVD[%u] - Couldn't export a variable "
1516 "declaration from the modules",
1517 current_id);
1518
1519 break;
1520 }
1521
1522 context.AddNamedDecl(copied_var_decl);
1523
1524 context.m_found.variable = true;
1525 }
1526 }
1527 } while (0);
1528 }
1529
1530 if (target && !context.m_found.variable && !namespace_decl) {
Adrian Prantl05097242018-04-30 16:49:04 +00001531 // We couldn't find a non-symbol variable for this. Now we'll hunt for a
1532 // generic data symbol, and -- if it is found -- treat it as a variable.
Sean Callanan9c99faa2017-05-16 23:46:13 +00001533 Status error;
Stephane Sezer30fa7e22017-10-24 22:56:05 +00001534
Sean Callanan9c99faa2017-05-16 23:46:13 +00001535 const Symbol *data_symbol =
1536 m_parser_vars->m_sym_ctx.FindBestGlobalDataSymbol(name, error);
Stephane Sezer30fa7e22017-10-24 22:56:05 +00001537
Sean Callanan9c99faa2017-05-16 23:46:13 +00001538 if (!error.Success()) {
1539 const unsigned diag_id =
1540 m_ast_context->getDiagnostics().getCustomDiagID(
1541 clang::DiagnosticsEngine::Level::Error, "%0");
1542 m_ast_context->getDiagnostics().Report(diag_id) << error.AsCString();
1543 }
Stephane Sezer30fa7e22017-10-24 22:56:05 +00001544
Sean Callananc02a1c02017-04-24 23:14:04 +00001545 if (data_symbol) {
1546 std::string warning("got name from symbols: ");
1547 warning.append(name.AsCString());
1548 const unsigned diag_id =
1549 m_ast_context->getDiagnostics().getCustomDiagID(
1550 clang::DiagnosticsEngine::Level::Warning, "%0");
1551 m_ast_context->getDiagnostics().Report(diag_id) << warning.c_str();
1552 AddOneGenericVariable(context, *data_symbol, current_id);
1553 context.m_found.variable = true;
1554 }
1555 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001556 }
Sean Callanan6b4067c2010-07-17 00:43:37 +00001557}
Greg Claytona2721472011-06-25 00:44:06 +00001558
Kate Stoneb9c1b512016-09-06 20:57:50 +00001559bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var,
1560 lldb_private::Value &var_location,
1561 TypeFromUser *user_type,
1562 TypeFromParser *parser_type) {
1563 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001564
Kate Stoneb9c1b512016-09-06 20:57:50 +00001565 Type *var_type = var->GetType();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001566
Kate Stoneb9c1b512016-09-06 20:57:50 +00001567 if (!var_type) {
Sean Callananea22d422010-07-16 00:09:46 +00001568 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001569 log->PutCString("Skipped a definition because it has no type");
1570 return false;
1571 }
1572
1573 CompilerType var_clang_type = var_type->GetFullCompilerType();
1574
1575 if (!var_clang_type) {
1576 if (log)
1577 log->PutCString("Skipped a definition because it has no Clang type");
1578 return false;
1579 }
1580
1581 ClangASTContext *clang_ast = llvm::dyn_cast_or_null<ClangASTContext>(
1582 var_type->GetForwardCompilerType().GetTypeSystem());
1583
1584 if (!clang_ast) {
1585 if (log)
1586 log->PutCString("Skipped a definition because it has no Clang AST");
1587 return false;
1588 }
1589
1590 ASTContext *ast = clang_ast->getASTContext();
1591
1592 if (!ast) {
1593 if (log)
1594 log->PutCString(
1595 "There is no AST context for the current execution context");
1596 return false;
1597 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001598
1599 DWARFExpression &var_location_expr = var->LocationExpression();
1600
1601 Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
Zachary Turner97206d52017-05-12 04:51:55 +00001602 Status err;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001603
1604 if (var->GetLocationIsConstantValueData()) {
1605 DataExtractor const_value_extractor;
1606
1607 if (var_location_expr.GetExpressionData(const_value_extractor)) {
1608 var_location = Value(const_value_extractor.GetDataStart(),
1609 const_value_extractor.GetByteSize());
1610 var_location.SetValueType(Value::eValueTypeHostAddress);
1611 } else {
1612 if (log)
1613 log->Printf("Error evaluating constant variable: %s", err.AsCString());
1614 return false;
Greg Clayton7b462cc2010-10-15 22:48:33 +00001615 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001616 }
1617
1618 CompilerType type_to_use = GuardedCopyType(var_clang_type);
1619
1620 if (!type_to_use) {
1621 if (log)
1622 log->Printf(
1623 "Couldn't copy a variable's type into the parser's AST context");
1624
1625 return false;
1626 }
1627
1628 if (parser_type)
1629 *parser_type = TypeFromParser(type_to_use);
1630
1631 if (var_location.GetContextType() == Value::eContextTypeInvalid)
1632 var_location.SetCompilerType(type_to_use);
1633
1634 if (var_location.GetValueType() == Value::eValueTypeFileAddress) {
1635 SymbolContext var_sc;
1636 var->CalculateSymbolContext(&var_sc);
1637
1638 if (!var_sc.module_sp)
1639 return false;
1640
1641 Address so_addr(var_location.GetScalar().ULongLong(),
1642 var_sc.module_sp->GetSectionList());
1643
1644 lldb::addr_t load_addr = so_addr.GetLoadAddress(target);
1645
1646 if (load_addr != LLDB_INVALID_ADDRESS) {
1647 var_location.GetScalar() = load_addr;
1648 var_location.SetValueType(Value::eValueTypeLoadAddress);
1649 }
1650 }
1651
1652 if (user_type)
1653 *user_type = TypeFromUser(var_clang_type);
1654
1655 return true;
Sean Callanan468574b2010-06-22 23:46:24 +00001656}
1657
Kate Stoneb9c1b512016-09-06 20:57:50 +00001658void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
1659 VariableSP var,
1660 ValueObjectSP valobj,
1661 unsigned int current_id) {
1662 assert(m_parser_vars.get());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001663
Kate Stoneb9c1b512016-09-06 20:57:50 +00001664 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001665
Kate Stoneb9c1b512016-09-06 20:57:50 +00001666 TypeFromUser ut;
1667 TypeFromParser pt;
1668 Value var_location;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001669
Kate Stoneb9c1b512016-09-06 20:57:50 +00001670 if (!GetVariableValue(var, var_location, &ut, &pt))
1671 return;
1672
1673 clang::QualType parser_opaque_type =
1674 QualType::getFromOpaquePtr(pt.GetOpaqueQualType());
1675
1676 if (parser_opaque_type.isNull())
1677 return;
1678
1679 if (const clang::Type *parser_type = parser_opaque_type.getTypePtr()) {
1680 if (const TagType *tag_type = dyn_cast<TagType>(parser_type))
1681 CompleteType(tag_type->getDecl());
1682 if (const ObjCObjectPointerType *objc_object_ptr_type =
1683 dyn_cast<ObjCObjectPointerType>(parser_type))
1684 CompleteType(objc_object_ptr_type->getInterfaceDecl());
1685 }
1686
1687 bool is_reference = pt.IsReferenceType();
1688
1689 NamedDecl *var_decl = NULL;
1690 if (is_reference)
1691 var_decl = context.AddVarDecl(pt);
1692 else
1693 var_decl = context.AddVarDecl(pt.GetLValueReferenceType());
1694
1695 std::string decl_name(context.m_decl_name.getAsString());
1696 ConstString entity_name(decl_name.c_str());
1697 ClangExpressionVariable *entity(new ClangExpressionVariable(valobj));
1698 m_found_entities.AddNewlyConstructedVariable(entity);
1699
1700 assert(entity);
1701 entity->EnableParserVars(GetParserID());
1702 ClangExpressionVariable::ParserVars *parser_vars =
1703 entity->GetParserVars(GetParserID());
1704 parser_vars->m_parser_type = pt;
1705 parser_vars->m_named_decl = var_decl;
1706 parser_vars->m_llvm_value = NULL;
1707 parser_vars->m_lldb_value = var_location;
1708 parser_vars->m_lldb_var = var;
1709
1710 if (is_reference)
1711 entity->m_flags |= ClangExpressionVariable::EVTypeIsReference;
1712
1713 if (log) {
1714 ASTDumper orig_dumper(ut.GetOpaqueQualType());
1715 ASTDumper ast_dumper(var_decl);
1716 log->Printf(" CEDM::FEVD[%u] Found variable %s, returned %s (original %s)",
1717 current_id, decl_name.c_str(), ast_dumper.GetCString(),
1718 orig_dumper.GetCString());
1719 }
1720}
1721
1722void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
1723 ExpressionVariableSP &pvar_sp,
1724 unsigned int current_id) {
1725 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1726
1727 TypeFromUser user_type(
1728 llvm::cast<ClangExpressionVariable>(pvar_sp.get())->GetTypeFromUser());
1729
1730 TypeFromParser parser_type(GuardedCopyType(user_type));
1731
1732 if (!parser_type.GetOpaqueQualType()) {
1733 if (log)
1734 log->Printf(" CEDM::FEVD[%u] Couldn't import type for pvar %s",
1735 current_id, pvar_sp->GetName().GetCString());
1736 return;
1737 }
1738
1739 NamedDecl *var_decl =
1740 context.AddVarDecl(parser_type.GetLValueReferenceType());
1741
1742 llvm::cast<ClangExpressionVariable>(pvar_sp.get())
1743 ->EnableParserVars(GetParserID());
1744 ClangExpressionVariable::ParserVars *parser_vars =
1745 llvm::cast<ClangExpressionVariable>(pvar_sp.get())
1746 ->GetParserVars(GetParserID());
1747 parser_vars->m_parser_type = parser_type;
1748 parser_vars->m_named_decl = var_decl;
1749 parser_vars->m_llvm_value = NULL;
1750 parser_vars->m_lldb_value.Clear();
1751
1752 if (log) {
1753 ASTDumper ast_dumper(var_decl);
1754 log->Printf(" CEDM::FEVD[%u] Added pvar %s, returned %s", current_id,
1755 pvar_sp->GetName().GetCString(), ast_dumper.GetCString());
1756 }
1757}
1758
1759void ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context,
1760 const Symbol &symbol,
1761 unsigned int current_id) {
1762 assert(m_parser_vars.get());
1763
1764 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1765
1766 Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
1767
1768 if (target == NULL)
1769 return;
1770
1771 ASTContext *scratch_ast_context =
1772 target->GetScratchClangASTContext()->getASTContext();
1773
1774 TypeFromUser user_type(
1775 ClangASTContext::GetBasicType(scratch_ast_context, eBasicTypeVoid)
1776 .GetPointerType()
1777 .GetLValueReferenceType());
1778 TypeFromParser parser_type(
1779 ClangASTContext::GetBasicType(m_ast_context, eBasicTypeVoid)
1780 .GetPointerType()
1781 .GetLValueReferenceType());
1782 NamedDecl *var_decl = context.AddVarDecl(parser_type);
1783
1784 std::string decl_name(context.m_decl_name.getAsString());
1785 ConstString entity_name(decl_name.c_str());
1786 ClangExpressionVariable *entity(new ClangExpressionVariable(
1787 m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), entity_name,
1788 user_type, m_parser_vars->m_target_info.byte_order,
1789 m_parser_vars->m_target_info.address_byte_size));
1790 m_found_entities.AddNewlyConstructedVariable(entity);
1791
1792 entity->EnableParserVars(GetParserID());
1793 ClangExpressionVariable::ParserVars *parser_vars =
1794 entity->GetParserVars(GetParserID());
1795
1796 const Address symbol_address = symbol.GetAddress();
1797 lldb::addr_t symbol_load_addr = symbol_address.GetLoadAddress(target);
1798
1799 // parser_vars->m_lldb_value.SetContext(Value::eContextTypeClangType,
1800 // user_type.GetOpaqueQualType());
1801 parser_vars->m_lldb_value.SetCompilerType(user_type);
1802 parser_vars->m_lldb_value.GetScalar() = symbol_load_addr;
1803 parser_vars->m_lldb_value.SetValueType(Value::eValueTypeLoadAddress);
1804
1805 parser_vars->m_parser_type = parser_type;
1806 parser_vars->m_named_decl = var_decl;
1807 parser_vars->m_llvm_value = NULL;
1808 parser_vars->m_lldb_sym = &symbol;
1809
1810 if (log) {
1811 ASTDumper ast_dumper(var_decl);
1812
1813 log->Printf(" CEDM::FEVD[%u] Found variable %s, returned %s", current_id,
1814 decl_name.c_str(), ast_dumper.GetCString());
1815 }
1816}
1817
1818bool ClangExpressionDeclMap::ResolveUnknownTypes() {
1819 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1820 Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
1821
Sean Callanan68e44232017-09-28 20:20:25 +00001822 ClangASTContextForExpressions *scratch_ast_context =
1823 static_cast<ClangASTContextForExpressions*>(
1824 target->GetScratchClangASTContext());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001825
1826 for (size_t index = 0, num_entities = m_found_entities.GetSize();
1827 index < num_entities; ++index) {
1828 ExpressionVariableSP entity = m_found_entities.GetVariableAtIndex(index);
1829
1830 ClangExpressionVariable::ParserVars *parser_vars =
1831 llvm::cast<ClangExpressionVariable>(entity.get())
1832 ->GetParserVars(GetParserID());
1833
1834 if (entity->m_flags & ClangExpressionVariable::EVUnknownType) {
1835 const NamedDecl *named_decl = parser_vars->m_named_decl;
1836 const VarDecl *var_decl = dyn_cast<VarDecl>(named_decl);
1837
1838 if (!var_decl) {
Sean Callanane0a64f72011-12-01 21:04:37 +00001839 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001840 log->Printf("Entity of unknown type does not have a VarDecl");
1841 return false;
1842 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001843
Kate Stoneb9c1b512016-09-06 20:57:50 +00001844 if (log) {
1845 ASTDumper ast_dumper(const_cast<VarDecl *>(var_decl));
1846 log->Printf("Variable of unknown type now has Decl %s",
Greg Clayton64bc6ca2011-10-20 00:47:21 +00001847 ast_dumper.GetCString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001848 }
1849
1850 QualType var_type = var_decl->getType();
1851 TypeFromParser parser_type(
1852 var_type.getAsOpaquePtr(),
1853 ClangASTContext::GetASTContext(&var_decl->getASTContext()));
1854
Sean Callanan68e44232017-09-28 20:20:25 +00001855 lldb::opaque_compiler_type_t copied_type = 0;
1856 if (m_ast_importer_sp) {
1857 copied_type = m_ast_importer_sp->CopyType(
1858 scratch_ast_context->getASTContext(), &var_decl->getASTContext(),
1859 var_type.getAsOpaquePtr());
1860 } else if (HasMerger()) {
1861 copied_type = CopyTypeWithMerger(
1862 var_decl->getASTContext(),
1863 scratch_ast_context->GetMergerUnchecked(),
1864 var_type).getAsOpaquePtr();
1865 } else {
Pavel Labath9344e452017-10-17 21:52:29 +00001866 lldbassert(0 && "No mechanism to copy a resolved unknown type!");
Sean Callanan68e44232017-09-28 20:20:25 +00001867 return false;
1868 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001869
1870 if (!copied_type) {
1871 if (log)
1872 log->Printf("ClangExpressionDeclMap::ResolveUnknownType - Couldn't "
1873 "import the type for a variable");
1874
1875 return (bool)lldb::ExpressionVariableSP();
1876 }
1877
1878 TypeFromUser user_type(copied_type, scratch_ast_context);
1879
1880 // parser_vars->m_lldb_value.SetContext(Value::eContextTypeClangType,
1881 // user_type.GetOpaqueQualType());
1882 parser_vars->m_lldb_value.SetCompilerType(user_type);
1883 parser_vars->m_parser_type = parser_type;
1884
1885 entity->SetCompilerType(user_type);
1886
1887 entity->m_flags &= ~(ClangExpressionVariable::EVUnknownType);
Greg Clayton7b462cc2010-10-15 22:48:33 +00001888 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001889 }
1890
1891 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001892}
Sean Callanan5666b672010-08-04 01:02:13 +00001893
Kate Stoneb9c1b512016-09-06 20:57:50 +00001894void ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context,
1895 const RegisterInfo *reg_info,
1896 unsigned int current_id) {
1897 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001898
Kate Stoneb9c1b512016-09-06 20:57:50 +00001899 CompilerType clang_type =
1900 ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(
1901 m_ast_context, reg_info->encoding, reg_info->byte_size * 8);
Sean Callanan7736a202016-04-29 18:09:03 +00001902
Kate Stoneb9c1b512016-09-06 20:57:50 +00001903 if (!clang_type) {
1904 if (log)
1905 log->Printf(" Tried to add a type for %s, but couldn't get one",
1906 context.m_decl_name.getAsString().c_str());
1907 return;
1908 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001909
Kate Stoneb9c1b512016-09-06 20:57:50 +00001910 TypeFromParser parser_clang_type(clang_type);
Sean Callananfa4fab72013-02-01 06:55:48 +00001911
Kate Stoneb9c1b512016-09-06 20:57:50 +00001912 NamedDecl *var_decl = context.AddVarDecl(parser_clang_type);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001913
Kate Stoneb9c1b512016-09-06 20:57:50 +00001914 ClangExpressionVariable *entity(new ClangExpressionVariable(
1915 m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
1916 m_parser_vars->m_target_info.byte_order,
1917 m_parser_vars->m_target_info.address_byte_size));
1918 m_found_entities.AddNewlyConstructedVariable(entity);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001919
Kate Stoneb9c1b512016-09-06 20:57:50 +00001920 std::string decl_name(context.m_decl_name.getAsString());
1921 entity->SetName(ConstString(decl_name.c_str()));
1922 entity->SetRegisterInfo(reg_info);
1923 entity->EnableParserVars(GetParserID());
1924 ClangExpressionVariable::ParserVars *parser_vars =
1925 entity->GetParserVars(GetParserID());
1926 parser_vars->m_parser_type = parser_clang_type;
1927 parser_vars->m_named_decl = var_decl;
1928 parser_vars->m_llvm_value = NULL;
1929 parser_vars->m_lldb_value.Clear();
1930 entity->m_flags |= ClangExpressionVariable::EVBareRegister;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001931
Kate Stoneb9c1b512016-09-06 20:57:50 +00001932 if (log) {
1933 ASTDumper ast_dumper(var_decl);
1934 log->Printf(" CEDM::FEVD[%d] Added register %s, returned %s", current_id,
1935 context.m_decl_name.getAsString().c_str(),
1936 ast_dumper.GetCString());
1937 }
1938}
1939
1940void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
1941 Function *function, Symbol *symbol,
1942 unsigned int current_id) {
1943 assert(m_parser_vars.get());
1944
1945 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1946
1947 NamedDecl *function_decl = NULL;
1948 Address fun_address;
1949 CompilerType function_clang_type;
1950
1951 bool is_indirect_function = false;
1952
1953 if (function) {
1954 Type *function_type = function->GetType();
1955
Luke Drummondf5bb1d62016-12-19 17:22:44 +00001956 const auto lang = function->GetCompileUnit()->GetLanguage();
1957 const auto name = function->GetMangled().GetMangledName().AsCString();
1958 const bool extern_c = (Language::LanguageIsC(lang) &&
1959 !CPlusPlusLanguage::IsCPPMangledName(name)) ||
1960 (Language::LanguageIsObjC(lang) &&
1961 !Language::LanguageIsCPlusPlus(lang));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001962
1963 if (!extern_c) {
1964 TypeSystem *type_system = function->GetDeclContext().GetTypeSystem();
Davide Italianofe34df52017-09-30 21:16:56 +00001965 if (llvm::isa<ClangASTContext>(type_system)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001966 clang::DeclContext *src_decl_context =
1967 (clang::DeclContext *)function->GetDeclContext()
1968 .GetOpaqueDeclContext();
1969 clang::FunctionDecl *src_function_decl =
1970 llvm::dyn_cast_or_null<clang::FunctionDecl>(src_decl_context);
Sean Callanan09e91ac2017-05-11 22:08:05 +00001971 if (src_function_decl &&
1972 src_function_decl->getTemplateSpecializationInfo()) {
1973 clang::FunctionTemplateDecl *function_template =
1974 src_function_decl->getTemplateSpecializationInfo()->getTemplate();
1975 clang::FunctionTemplateDecl *copied_function_template =
1976 llvm::dyn_cast_or_null<clang::FunctionTemplateDecl>(
Sean Callanan68e44232017-09-28 20:20:25 +00001977 CopyDecl(function_template));
Sean Callanan09e91ac2017-05-11 22:08:05 +00001978 if (copied_function_template) {
1979 if (log) {
1980 ASTDumper ast_dumper((clang::Decl *)copied_function_template);
1981
1982 StreamString ss;
1983
1984 function->DumpSymbolContext(&ss);
1985
1986 log->Printf(" CEDM::FEVD[%u] Imported decl for function template"
1987 " %s (description %s), returned %s",
1988 current_id,
1989 copied_function_template->getNameAsString().c_str(),
1990 ss.GetData(), ast_dumper.GetCString());
1991 }
1992
1993 context.AddNamedDecl(copied_function_template);
1994 }
1995 } else if (src_function_decl) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001996 if (clang::FunctionDecl *copied_function_decl =
1997 llvm::dyn_cast_or_null<clang::FunctionDecl>(
Sean Callanan68e44232017-09-28 20:20:25 +00001998 CopyDecl(src_function_decl))) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001999 if (log) {
2000 ASTDumper ast_dumper((clang::Decl *)copied_function_decl);
2001
2002 StreamString ss;
2003
2004 function->DumpSymbolContext(&ss);
2005
2006 log->Printf(" CEDM::FEVD[%u] Imported decl for function %s "
2007 "(description %s), returned %s",
2008 current_id,
2009 copied_function_decl->getNameAsString().c_str(),
2010 ss.GetData(), ast_dumper.GetCString());
2011 }
2012
2013 context.AddNamedDecl(copied_function_decl);
2014 return;
2015 } else {
2016 if (log) {
2017 log->Printf(" Failed to import the function decl for '%s'",
2018 src_function_decl->getName().str().c_str());
2019 }
2020 }
Sean Callanan7736a202016-04-29 18:09:03 +00002021 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002022 }
Sean Callananfc55f5d2010-09-21 00:44:12 +00002023 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00002024
Kate Stoneb9c1b512016-09-06 20:57:50 +00002025 if (!function_type) {
2026 if (log)
2027 log->PutCString(" Skipped a function because it has no type");
2028 return;
2029 }
2030
2031 function_clang_type = function_type->GetFullCompilerType();
2032
2033 if (!function_clang_type) {
2034 if (log)
2035 log->PutCString(" Skipped a function because it has no Clang type");
2036 return;
2037 }
2038
2039 fun_address = function->GetAddressRange().GetBaseAddress();
2040
2041 CompilerType copied_function_type = GuardedCopyType(function_clang_type);
2042 if (copied_function_type) {
2043 function_decl = context.AddFunDecl(copied_function_type, extern_c);
2044
2045 if (!function_decl) {
2046 if (log) {
2047 log->Printf(
2048 " Failed to create a function decl for '%s' {0x%8.8" PRIx64 "}",
2049 function_type->GetName().GetCString(), function_type->GetID());
2050 }
2051
Sean Callanan3b436d22015-10-23 21:45:02 +00002052 return;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002053 }
2054 } else {
2055 // We failed to copy the type we found
2056 if (log) {
2057 log->Printf(" Failed to import the function type '%s' {0x%8.8" PRIx64
2058 "} into the expression parser AST contenxt",
2059 function_type->GetName().GetCString(),
2060 function_type->GetID());
2061 }
2062
2063 return;
2064 }
2065 } else if (symbol) {
2066 fun_address = symbol->GetAddress();
2067 function_decl = context.AddGenericFunDecl();
2068 is_indirect_function = symbol->IsIndirect();
2069 } else {
2070 if (log)
2071 log->PutCString(" AddOneFunction called with no function and no symbol");
2072 return;
2073 }
2074
2075 Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
2076
2077 lldb::addr_t load_addr =
2078 fun_address.GetCallableLoadAddress(target, is_indirect_function);
2079
2080 ClangExpressionVariable *entity(new ClangExpressionVariable(
2081 m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
2082 m_parser_vars->m_target_info.byte_order,
2083 m_parser_vars->m_target_info.address_byte_size));
2084 m_found_entities.AddNewlyConstructedVariable(entity);
2085
2086 std::string decl_name(context.m_decl_name.getAsString());
2087 entity->SetName(ConstString(decl_name.c_str()));
2088 entity->SetCompilerType(function_clang_type);
2089 entity->EnableParserVars(GetParserID());
2090
2091 ClangExpressionVariable::ParserVars *parser_vars =
2092 entity->GetParserVars(GetParserID());
2093
2094 if (load_addr != LLDB_INVALID_ADDRESS) {
2095 parser_vars->m_lldb_value.SetValueType(Value::eValueTypeLoadAddress);
2096 parser_vars->m_lldb_value.GetScalar() = load_addr;
2097 } else {
2098 // We have to try finding a file address.
2099
2100 lldb::addr_t file_addr = fun_address.GetFileAddress();
2101
2102 parser_vars->m_lldb_value.SetValueType(Value::eValueTypeFileAddress);
2103 parser_vars->m_lldb_value.GetScalar() = file_addr;
2104 }
2105
2106 parser_vars->m_named_decl = function_decl;
2107 parser_vars->m_llvm_value = NULL;
2108
2109 if (log) {
Pavel Labath03a77e92018-03-21 11:10:57 +00002110 std::string function_str =
2111 function_decl ? ASTDumper(function_decl).GetCString() : "nullptr";
Kate Stoneb9c1b512016-09-06 20:57:50 +00002112
2113 StreamString ss;
2114
2115 fun_address.Dump(&ss,
2116 m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
2117 Address::DumpStyleResolvedDescription);
2118
2119 log->Printf(
2120 " CEDM::FEVD[%u] Found %s function %s (description %s), returned %s",
2121 current_id, (function ? "specific" : "generic"), decl_name.c_str(),
Pavel Labath03a77e92018-03-21 11:10:57 +00002122 ss.GetData(), function_str.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002123 }
2124}
2125
2126void ClangExpressionDeclMap::AddThisType(NameSearchContext &context,
2127 TypeFromUser &ut,
2128 unsigned int current_id) {
2129 CompilerType copied_clang_type = GuardedCopyType(ut);
2130
2131 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
2132
2133 if (!copied_clang_type) {
2134 if (log)
2135 log->Printf(
2136 "ClangExpressionDeclMap::AddThisType - Couldn't import the type");
Sean Callanan3b436d22015-10-23 21:45:02 +00002137
2138 return;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002139 }
2140
2141 if (copied_clang_type.IsAggregateType() &&
2142 copied_clang_type.GetCompleteType()) {
2143 CompilerType void_clang_type =
2144 ClangASTContext::GetBasicType(m_ast_context, eBasicTypeVoid);
2145 CompilerType void_ptr_clang_type = void_clang_type.GetPointerType();
2146
2147 CompilerType method_type = ClangASTContext::CreateFunctionType(
2148 m_ast_context, void_clang_type, &void_ptr_clang_type, 1, false, 0);
2149
2150 const bool is_virtual = false;
2151 const bool is_static = false;
2152 const bool is_inline = false;
2153 const bool is_explicit = false;
2154 const bool is_attr_used = true;
2155 const bool is_artificial = false;
2156
2157 CXXMethodDecl *method_decl =
2158 ClangASTContext::GetASTContext(m_ast_context)
2159 ->AddMethodToCXXRecordType(
Davide Italiano675767a2018-03-27 19:40:50 +00002160 copied_clang_type.GetOpaqueQualType(), "$__lldb_expr", NULL,
Kate Stoneb9c1b512016-09-06 20:57:50 +00002161 method_type, lldb::eAccessPublic, is_virtual, is_static,
2162 is_inline, is_explicit, is_attr_used, is_artificial);
2163
2164 if (log) {
2165 ASTDumper method_ast_dumper((clang::Decl *)method_decl);
2166 ASTDumper type_ast_dumper(copied_clang_type);
2167
2168 log->Printf(" CEDM::AddThisType Added function $__lldb_expr "
2169 "(description %s) for this type %s",
2170 method_ast_dumper.GetCString(), type_ast_dumper.GetCString());
2171 }
2172 }
2173
2174 if (!copied_clang_type.IsValid())
2175 return;
2176
2177 TypeSourceInfo *type_source_info = m_ast_context->getTrivialTypeSourceInfo(
2178 QualType::getFromOpaquePtr(copied_clang_type.GetOpaqueQualType()));
2179
2180 if (!type_source_info)
2181 return;
2182
2183 // Construct a typedef type because if "*this" is a templated type we can't
2184 // just return ClassTemplateSpecializationDecls in response to name queries.
2185 // Using a typedef makes this much more robust.
2186
2187 TypedefDecl *typedef_decl = TypedefDecl::Create(
2188 *m_ast_context, m_ast_context->getTranslationUnitDecl(), SourceLocation(),
2189 SourceLocation(), context.m_decl_name.getAsIdentifierInfo(),
2190 type_source_info);
2191
2192 if (!typedef_decl)
2193 return;
2194
2195 context.AddNamedDecl(typedef_decl);
2196
2197 return;
Sean Callananfa4fab72013-02-01 06:55:48 +00002198}
2199
Kate Stoneb9c1b512016-09-06 20:57:50 +00002200void ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
2201 TypeFromUser &ut,
2202 unsigned int current_id) {
2203 CompilerType copied_clang_type = GuardedCopyType(ut);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00002204
Kate Stoneb9c1b512016-09-06 20:57:50 +00002205 if (!copied_clang_type) {
2206 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sean Callananfa4fab72013-02-01 06:55:48 +00002207
Kate Stoneb9c1b512016-09-06 20:57:50 +00002208 if (log)
2209 log->Printf(
2210 "ClangExpressionDeclMap::AddOneType - Couldn't import the type");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00002211
Kate Stoneb9c1b512016-09-06 20:57:50 +00002212 return;
2213 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00002214
Kate Stoneb9c1b512016-09-06 20:57:50 +00002215 context.AddTypeDecl(copied_clang_type);
Sean Callanan5666b672010-08-04 01:02:13 +00002216}