blob: 0811a79999201eab03934e2b2c86c330017bdabb [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- ClangExpressionDeclMap.cpp -----------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Sean Callanan4dbb2712015-09-25 20:35:58 +000010#include "ClangExpressionDeclMap.h"
11
12#include "ASTDumper.h"
13#include "ClangASTSource.h"
14#include "ClangModulesDeclVendor.h"
15#include "ClangPersistentVariables.h"
16
Chris Lattner30fdc8d2010-06-08 16:52:24 +000017#include "lldb/Core/Address.h"
18#include "lldb/Core/Module.h"
Greg Clayton9191db42013-10-21 18:40:51 +000019#include "lldb/Core/ModuleSpec.h"
Greg Clayton7349bd92011-05-09 20:18:18 +000020#include "lldb/Core/RegisterValue.h"
Sean Callanane4ec90e2010-12-16 03:17:46 +000021#include "lldb/Core/ValueObjectConstResult.h"
Sean Callanan9b3569b2011-12-10 03:12:34 +000022#include "lldb/Core/ValueObjectVariable.h"
Sean Callanan96d27302013-04-11 00:09:05 +000023#include "lldb/Expression/Materializer.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000024#include "lldb/Symbol/ClangASTContext.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000025#include "lldb/Symbol/CompileUnit.h"
Paul Hermand628cbb2015-09-15 23:44:17 +000026#include "lldb/Symbol/CompilerDecl.h"
Greg Clayton99558cc42015-08-24 23:46:31 +000027#include "lldb/Symbol/CompilerDeclContext.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000028#include "lldb/Symbol/Function.h"
29#include "lldb/Symbol/ObjectFile.h"
30#include "lldb/Symbol/SymbolContext.h"
Siva Chandra9293fc42016-01-07 23:32:34 +000031#include "lldb/Symbol/SymbolFile.h"
Sean Callanan503aa522011-10-12 00:12:34 +000032#include "lldb/Symbol/SymbolVendor.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000033#include "lldb/Symbol/Type.h"
34#include "lldb/Symbol/TypeList.h"
35#include "lldb/Symbol/Variable.h"
36#include "lldb/Symbol/VariableList.h"
Sean Callanana0d56432014-11-11 02:49:44 +000037#include "lldb/Target/CPPLanguageRuntime.h"
Sean Callanan1d180662010-07-20 23:31:16 +000038#include "lldb/Target/ExecutionContext.h"
Sean Callanane0b23b52012-11-15 02:02:04 +000039#include "lldb/Target/ObjCLanguageRuntime.h"
Sean Callananea22d422010-07-16 00:09:46 +000040#include "lldb/Target/Process.h"
Sean Callananf4b9bd32010-10-05 20:18:48 +000041#include "lldb/Target/RegisterContext.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000042#include "lldb/Target/StackFrame.h"
Sean Callanan1d180662010-07-20 23:31:16 +000043#include "lldb/Target/Target.h"
Jim Ingham895c9822010-12-07 01:56:02 +000044#include "lldb/Target/Thread.h"
Zachary Turner01c32432017-02-14 19:06:07 +000045#include "lldb/Utility/Endian.h"
Zachary Turner6f9e6902017-03-03 20:56:28 +000046#include "lldb/Utility/Log.h"
Zachary Turner97206d52017-05-12 04:51:55 +000047#include "lldb/Utility/Status.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000048#include "lldb/lldb-private.h"
49#include "clang/AST/ASTConsumer.h"
50#include "clang/AST/ASTContext.h"
Sean Callanan68e44232017-09-28 20:20:25 +000051#include "clang/AST/ASTImporter.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000052#include "clang/AST/Decl.h"
53#include "clang/AST/DeclarationName.h"
Sean Callanan68e44232017-09-28 20:20:25 +000054#include "clang/AST/RecursiveASTVisitor.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000055
Siva Chandra0f4873d2015-09-03 23:27:10 +000056#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
57
Greg Clayton83c5cd92010-11-14 22:13:40 +000058using namespace lldb;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000059using namespace lldb_private;
60using namespace clang;
61
Kate Stoneb9c1b512016-09-06 20:57:50 +000062namespace {
63const char *g_lldb_local_vars_namespace_cstr = "$__lldb_local_vars";
Siva Chandra03ff5c82016-02-05 19:10:04 +000064} // anonymous namespace
65
Kate Stoneb9c1b512016-09-06 20:57:50 +000066ClangExpressionDeclMap::ClangExpressionDeclMap(
67 bool keep_result_in_memory,
68 Materializer::PersistentVariableDelegate *result_delegate,
69 ExecutionContext &exe_ctx)
70 : ClangASTSource(exe_ctx.GetTargetSP()), m_found_entities(),
71 m_struct_members(), m_keep_result_in_memory(keep_result_in_memory),
72 m_result_delegate(result_delegate), m_parser_vars(), m_struct_vars() {
73 EnableStructVars();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000074}
75
Kate Stoneb9c1b512016-09-06 20:57:50 +000076ClangExpressionDeclMap::~ClangExpressionDeclMap() {
77 // Note: The model is now that the parser's AST context and all associated
78 // data does not vanish until the expression has been executed. This means
79 // that valuable lookup data (like namespaces) doesn't vanish, but
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000080
Kate Stoneb9c1b512016-09-06 20:57:50 +000081 DidParse();
82 DisableStructVars();
Sean Callanan979f74d2010-12-03 01:38:59 +000083}
Sean Callananbe3a1b12010-10-26 00:31:56 +000084
Kate Stoneb9c1b512016-09-06 20:57:50 +000085bool ClangExpressionDeclMap::WillParse(ExecutionContext &exe_ctx,
86 Materializer *materializer) {
87 ClangASTMetrics::ClearLocalCounters();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000088
Kate Stoneb9c1b512016-09-06 20:57:50 +000089 EnableParserVars();
90 m_parser_vars->m_exe_ctx = exe_ctx;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +000091
Kate Stoneb9c1b512016-09-06 20:57:50 +000092 Target *target = exe_ctx.GetTargetPtr();
93 if (exe_ctx.GetFramePtr())
94 m_parser_vars->m_sym_ctx =
95 exe_ctx.GetFramePtr()->GetSymbolContext(lldb::eSymbolContextEverything);
96 else if (exe_ctx.GetThreadPtr() &&
97 exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(0))
98 m_parser_vars->m_sym_ctx =
99 exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(0)->GetSymbolContext(
100 lldb::eSymbolContextEverything);
101 else if (exe_ctx.GetProcessPtr()) {
102 m_parser_vars->m_sym_ctx.Clear(true);
103 m_parser_vars->m_sym_ctx.target_sp = exe_ctx.GetTargetSP();
104 } else if (target) {
105 m_parser_vars->m_sym_ctx.Clear(true);
106 m_parser_vars->m_sym_ctx.target_sp = exe_ctx.GetTargetSP();
107 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000108
Kate Stoneb9c1b512016-09-06 20:57:50 +0000109 if (target) {
110 m_parser_vars->m_persistent_vars = llvm::cast<ClangPersistentVariables>(
111 target->GetPersistentExpressionStateForLanguage(eLanguageTypeC));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000112
Kate Stoneb9c1b512016-09-06 20:57:50 +0000113 if (!target->GetScratchClangASTContext())
114 return false;
115 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000116
Kate Stoneb9c1b512016-09-06 20:57:50 +0000117 m_parser_vars->m_target_info = GetTargetInfo();
118 m_parser_vars->m_materializer = materializer;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000119
Kate Stoneb9c1b512016-09-06 20:57:50 +0000120 return true;
Sean Callanan979f74d2010-12-03 01:38:59 +0000121}
122
Kate Stoneb9c1b512016-09-06 20:57:50 +0000123void ClangExpressionDeclMap::InstallCodeGenerator(
124 clang::ASTConsumer *code_gen) {
125 assert(m_parser_vars);
126 m_parser_vars->m_code_gen = code_gen;
Sean Callanan80c97592015-05-01 00:47:29 +0000127}
128
Kate Stoneb9c1b512016-09-06 20:57:50 +0000129void ClangExpressionDeclMap::DidParse() {
130 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sean Callanan8106d802013-03-08 20:04:57 +0000131
Kate Stoneb9c1b512016-09-06 20:57:50 +0000132 if (log)
133 ClangASTMetrics::DumpCounters(log);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000134
Kate Stoneb9c1b512016-09-06 20:57:50 +0000135 if (m_parser_vars.get()) {
136 for (size_t entity_index = 0, num_entities = m_found_entities.GetSize();
137 entity_index < num_entities; ++entity_index) {
138 ExpressionVariableSP var_sp(
139 m_found_entities.GetVariableAtIndex(entity_index));
140 if (var_sp)
141 llvm::cast<ClangExpressionVariable>(var_sp.get())
142 ->DisableParserVars(GetParserID());
Sean Callanan6b1b9532010-10-08 01:58:41 +0000143 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000144
145 for (size_t pvar_index = 0,
146 num_pvars = m_parser_vars->m_persistent_vars->GetSize();
147 pvar_index < num_pvars; ++pvar_index) {
148 ExpressionVariableSP pvar_sp(
149 m_parser_vars->m_persistent_vars->GetVariableAtIndex(pvar_index));
150 if (ClangExpressionVariable *clang_var =
151 llvm::dyn_cast<ClangExpressionVariable>(pvar_sp.get()))
152 clang_var->DisableParserVars(GetParserID());
153 }
154
155 DisableParserVars();
156 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000157}
158
Sean Callanan549c9f72010-07-13 21:41:46 +0000159// Interface for IRForTarget
160
Kate Stoneb9c1b512016-09-06 20:57:50 +0000161ClangExpressionDeclMap::TargetInfo ClangExpressionDeclMap::GetTargetInfo() {
162 assert(m_parser_vars.get());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000163
Kate Stoneb9c1b512016-09-06 20:57:50 +0000164 TargetInfo ret;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000165
Kate Stoneb9c1b512016-09-06 20:57:50 +0000166 ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
Sean Callanan933693b2012-02-10 01:22:05 +0000167
Kate Stoneb9c1b512016-09-06 20:57:50 +0000168 Process *process = exe_ctx.GetProcessPtr();
169 if (process) {
170 ret.byte_order = process->GetByteOrder();
171 ret.address_byte_size = process->GetAddressByteSize();
172 } else {
173 Target *target = exe_ctx.GetTargetPtr();
174 if (target) {
175 ret.byte_order = target->GetArchitecture().GetByteOrder();
176 ret.address_byte_size = target->GetArchitecture().GetAddressByteSize();
Sean Callanan933693b2012-02-10 01:22:05 +0000177 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000178 }
Sean Callanan933693b2012-02-10 01:22:05 +0000179
Kate Stoneb9c1b512016-09-06 20:57:50 +0000180 return ret;
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000181}
182
Sean Callanan68e44232017-09-28 20:20:25 +0000183namespace {
184/// This class walks an AST and ensures that all DeclContexts defined inside the
185/// current source file are properly complete.
186///
187/// This is used to ensure that persistent types defined in the current source
188/// file migrate completely to the persistent AST context before they are
189/// reused. If that didn't happen, it would be impoossible to complete them
190/// because their origin would be gone.
191///
192/// The stragtegy used by this class is to check the SourceLocation (to be
193/// specific, the FileID) and see if it's the FileID for the current expression.
194/// Alternate strategies could include checking whether an ExternalASTMerger,
195/// set up to not have the current context as a source, can find an original for
196/// the type.
197class Completer : public clang::RecursiveASTVisitor<Completer> {
198private:
199 clang::ASTImporter &m_exporter; /// Used to import Decl contents
200 clang::FileID m_file; /// The file that's going away
201 llvm::DenseSet<clang::Decl *> m_completed; /// Visited Decls, to avoid cycles
202
203 bool ImportAndCheckCompletable(clang::Decl *decl) {
204 (void)m_exporter.Import(decl);
205 if (m_completed.count(decl))
206 return false;
207 if (!llvm::isa<DeclContext>(decl))
208 return false;
209 const clang::SourceLocation loc = decl->getLocation();
210 if (!loc.isValid())
211 return false;
212 const clang::FileID file =
213 m_exporter.getFromContext().getSourceManager().getFileID(loc);
214 if (file != m_file)
215 return false;
Adrian Prantl05097242018-04-30 16:49:04 +0000216 // We are assuming the Decl was parsed in this very expression, so it
217 // should not have external storage.
Sean Callanan68e44232017-09-28 20:20:25 +0000218 lldbassert(!llvm::cast<DeclContext>(decl)->hasExternalLexicalStorage());
219 return true;
220 }
221
222 void Complete(clang::Decl *decl) {
223 m_completed.insert(decl);
224 auto *decl_context = llvm::cast<DeclContext>(decl);
225 (void)m_exporter.Import(decl);
226 m_exporter.CompleteDecl(decl);
227 for (Decl *child : decl_context->decls())
228 if (ImportAndCheckCompletable(child))
229 Complete(child);
230 }
231
232 void MaybeComplete(clang::Decl *decl) {
233 if (ImportAndCheckCompletable(decl))
234 Complete(decl);
235 }
236
237public:
238 Completer(clang::ASTImporter &exporter, clang::FileID file)
239 : m_exporter(exporter), m_file(file) {}
240
241 // Implements the RecursiveASTVisitor's core API. It is called on each Decl
242 // that the RecursiveASTVisitor encounters, and returns true if the traversal
243 // should continue.
244 bool VisitDecl(clang::Decl *decl) {
245 MaybeComplete(decl);
246 return true;
247 }
248};
249}
250
251static void CompleteAllDeclContexts(clang::ASTImporter &exporter,
252 clang::FileID file,
253 clang::QualType root) {
254 clang::QualType canonical_type = root.getCanonicalType();
255 if (clang::TagDecl *tag_decl = canonical_type->getAsTagDecl()) {
256 Completer(exporter, file).TraverseDecl(tag_decl);
257 } else if (auto interface_type = llvm::dyn_cast<ObjCInterfaceType>(
258 canonical_type.getTypePtr())) {
259 Completer(exporter, file).TraverseDecl(interface_type->getDecl());
260 } else {
261 Completer(exporter, file).TraverseType(canonical_type);
262 }
263}
264
265static clang::QualType ExportAllDeclaredTypes(
266 clang::ExternalASTMerger &merger,
267 clang::ASTContext &source, clang::FileManager &source_file_manager,
268 const clang::ExternalASTMerger::OriginMap &source_origin_map,
269 clang::FileID file, clang::QualType root) {
270 clang::ExternalASTMerger::ImporterSource importer_source =
271 { source, source_file_manager, source_origin_map };
272 merger.AddSources(importer_source);
273 clang::ASTImporter &exporter = merger.ImporterForOrigin(source);
274 CompleteAllDeclContexts(exporter, file, root);
275 clang::QualType ret = exporter.Import(root);
276 merger.RemoveSources(importer_source);
277 return ret;
278}
279
280TypeFromUser ClangExpressionDeclMap::DeportType(ClangASTContext &target,
281 ClangASTContext &source,
282 TypeFromParser parser_type) {
283 assert (&target == m_target->GetScratchClangASTContext());
284 assert ((TypeSystem*)&source == parser_type.GetTypeSystem());
285 assert (source.getASTContext() == m_ast_context);
286
287 if (m_ast_importer_sp) {
288 return TypeFromUser(m_ast_importer_sp->DeportType(
289 target.getASTContext(), source.getASTContext(),
290 parser_type.GetOpaqueQualType()),
291 &target);
292 } else if (m_merger_up) {
293 clang::FileID source_file =
294 source.getASTContext()->getSourceManager().getFileID(
295 source.getASTContext()->getTranslationUnitDecl()->getLocation());
296 auto scratch_ast_context = static_cast<ClangASTContextForExpressions*>(
297 m_target->GetScratchClangASTContext());
298 clang::QualType exported_type = ExportAllDeclaredTypes(
299 scratch_ast_context->GetMergerUnchecked(),
300 *source.getASTContext(), *source.getFileManager(),
301 m_merger_up->GetOrigins(),
302 source_file,
303 clang::QualType::getFromOpaquePtr(parser_type.GetOpaqueQualType()));
304 return TypeFromUser(exported_type.getAsOpaquePtr(), &target);
305 } else {
Pavel Labath9344e452017-10-17 21:52:29 +0000306 lldbassert(0 && "No mechanism for deporting a type!");
Sean Callanan68e44232017-09-28 20:20:25 +0000307 return TypeFromUser();
308 }
309}
310
Kate Stoneb9c1b512016-09-06 20:57:50 +0000311bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
312 const ConstString &name,
313 TypeFromParser parser_type,
314 bool is_result,
315 bool is_lvalue) {
316 assert(m_parser_vars.get());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000317
Kate Stoneb9c1b512016-09-06 20:57:50 +0000318 ClangASTContext *ast =
319 llvm::dyn_cast_or_null<ClangASTContext>(parser_type.GetTypeSystem());
320 if (ast == nullptr)
321 return false;
Greg Claytonf73034f2015-09-08 18:15:05 +0000322
Kate Stoneb9c1b512016-09-06 20:57:50 +0000323 if (m_parser_vars->m_materializer && is_result) {
Zachary Turner97206d52017-05-12 04:51:55 +0000324 Status err;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000325
Sean Callanan933693b2012-02-10 01:22:05 +0000326 ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
327 Target *target = exe_ctx.GetTargetPtr();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000328 if (target == nullptr)
329 return false;
Greg Claytonc14ee322011-09-22 04:58:26 +0000330
Sean Callanan68e44232017-09-28 20:20:25 +0000331 TypeFromUser user_type =
332 DeportType(*target->GetScratchClangASTContext(), *ast, parser_type);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000333
Kate Stoneb9c1b512016-09-06 20:57:50 +0000334 uint32_t offset = m_parser_vars->m_materializer->AddResultVariable(
335 user_type, is_lvalue, m_keep_result_in_memory, m_result_delegate, err);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000336
Kate Stoneb9c1b512016-09-06 20:57:50 +0000337 ClangExpressionVariable *var = new ClangExpressionVariable(
338 exe_ctx.GetBestExecutionContextScope(), name, user_type,
339 m_parser_vars->m_target_info.byte_order,
340 m_parser_vars->m_target_info.address_byte_size);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000341
Kate Stoneb9c1b512016-09-06 20:57:50 +0000342 m_found_entities.AddNewlyConstructedVariable(var);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000343
Sean Callananbc8ac342015-09-04 20:49:51 +0000344 var->EnableParserVars(GetParserID());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000345
Kate Stoneb9c1b512016-09-06 20:57:50 +0000346 ClangExpressionVariable::ParserVars *parser_vars =
347 var->GetParserVars(GetParserID());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000348
Sean Callanan3c495c12013-01-15 23:29:36 +0000349 parser_vars->m_named_decl = decl;
350 parser_vars->m_parser_type = parser_type;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000351
Kate Stoneb9c1b512016-09-06 20:57:50 +0000352 var->EnableJITVars(GetParserID());
353
354 ClangExpressionVariable::JITVars *jit_vars = var->GetJITVars(GetParserID());
355
356 jit_vars->m_offset = offset;
357
Sean Callanan64dfc9a2010-08-23 23:09:38 +0000358 return true;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000359 }
360
361 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
362 ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;
363 Target *target = exe_ctx.GetTargetPtr();
364 if (target == NULL)
365 return false;
366
367 ClangASTContext *context(target->GetScratchClangASTContext());
368
Sean Callanan68e44232017-09-28 20:20:25 +0000369 TypeFromUser user_type = DeportType(*context, *ast, parser_type);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000370
371 if (!user_type.GetOpaqueQualType()) {
372 if (log)
373 log->Printf("Persistent variable's type wasn't copied successfully");
374 return false;
375 }
376
377 if (!m_parser_vars->m_target_info.IsValid())
378 return false;
379
380 ClangExpressionVariable *var = llvm::cast<ClangExpressionVariable>(
381 m_parser_vars->m_persistent_vars
382 ->CreatePersistentVariable(
383 exe_ctx.GetBestExecutionContextScope(), name, user_type,
384 m_parser_vars->m_target_info.byte_order,
385 m_parser_vars->m_target_info.address_byte_size)
386 .get());
387
388 if (!var)
389 return false;
390
391 var->m_frozen_sp->SetHasCompleteType();
392
393 if (is_result)
394 var->m_flags |= ClangExpressionVariable::EVNeedsFreezeDry;
395 else
396 var->m_flags |=
397 ClangExpressionVariable::EVKeepInTarget; // explicitly-declared
398 // persistent variables should
399 // persist
400
401 if (is_lvalue) {
402 var->m_flags |= ClangExpressionVariable::EVIsProgramReference;
403 } else {
404 var->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated;
405 var->m_flags |= ClangExpressionVariable::EVNeedsAllocation;
406 }
407
408 if (m_keep_result_in_memory) {
409 var->m_flags |= ClangExpressionVariable::EVKeepInTarget;
410 }
411
412 if (log)
413 log->Printf("Created persistent variable with flags 0x%hx", var->m_flags);
414
415 var->EnableParserVars(GetParserID());
416
417 ClangExpressionVariable::ParserVars *parser_vars =
418 var->GetParserVars(GetParserID());
419
420 parser_vars->m_named_decl = decl;
421 parser_vars->m_parser_type = parser_type;
422
423 return true;
Sean Callanan2235f322010-08-11 03:57:18 +0000424}
425
Kate Stoneb9c1b512016-09-06 20:57:50 +0000426bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl,
427 const ConstString &name,
428 llvm::Value *value, size_t size,
429 lldb::offset_t alignment) {
430 assert(m_struct_vars.get());
431 assert(m_parser_vars.get());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000432
Kate Stoneb9c1b512016-09-06 20:57:50 +0000433 bool is_persistent_variable = false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000434
Kate Stoneb9c1b512016-09-06 20:57:50 +0000435 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000436
Kate Stoneb9c1b512016-09-06 20:57:50 +0000437 m_struct_vars->m_struct_laid_out = false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000438
Kate Stoneb9c1b512016-09-06 20:57:50 +0000439 if (ClangExpressionVariable::FindVariableInList(m_struct_members, decl,
440 GetParserID()))
441 return true;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000442
Kate Stoneb9c1b512016-09-06 20:57:50 +0000443 ClangExpressionVariable *var(ClangExpressionVariable::FindVariableInList(
444 m_found_entities, decl, GetParserID()));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000445
Kate Stoneb9c1b512016-09-06 20:57:50 +0000446 if (!var) {
447 var = ClangExpressionVariable::FindVariableInList(
448 *m_parser_vars->m_persistent_vars, decl, GetParserID());
449 is_persistent_variable = true;
450 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000451
Kate Stoneb9c1b512016-09-06 20:57:50 +0000452 if (!var)
453 return false;
454
455 if (log)
456 log->Printf("Adding value for (NamedDecl*)%p [%s - %s] to the structure",
457 static_cast<const void *>(decl), name.GetCString(),
458 var->GetName().GetCString());
459
460 // We know entity->m_parser_vars is valid because we used a parser variable
461 // to find it
462
463 ClangExpressionVariable::ParserVars *parser_vars =
464 llvm::cast<ClangExpressionVariable>(var)->GetParserVars(GetParserID());
465
466 parser_vars->m_llvm_value = value;
467
468 if (ClangExpressionVariable::JITVars *jit_vars =
469 llvm::cast<ClangExpressionVariable>(var)->GetJITVars(GetParserID())) {
470 // We already laid this out; do not touch
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000471
Sean Callanan823bb4c2010-08-30 22:17:16 +0000472 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000473 log->Printf("Already placed at 0x%llx",
474 (unsigned long long)jit_vars->m_offset);
475 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000476
Kate Stoneb9c1b512016-09-06 20:57:50 +0000477 llvm::cast<ClangExpressionVariable>(var)->EnableJITVars(GetParserID());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000478
Kate Stoneb9c1b512016-09-06 20:57:50 +0000479 ClangExpressionVariable::JITVars *jit_vars =
480 llvm::cast<ClangExpressionVariable>(var)->GetJITVars(GetParserID());
Sean Callanan3c495c12013-01-15 23:29:36 +0000481
Kate Stoneb9c1b512016-09-06 20:57:50 +0000482 jit_vars->m_alignment = alignment;
483 jit_vars->m_size = size;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000484
Kate Stoneb9c1b512016-09-06 20:57:50 +0000485 m_struct_members.AddVariable(var->shared_from_this());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000486
Kate Stoneb9c1b512016-09-06 20:57:50 +0000487 if (m_parser_vars->m_materializer) {
488 uint32_t offset = 0;
489
Zachary Turner97206d52017-05-12 04:51:55 +0000490 Status err;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000491
492 if (is_persistent_variable) {
493 ExpressionVariableSP var_sp(var->shared_from_this());
494 offset = m_parser_vars->m_materializer->AddPersistentVariable(
495 var_sp, nullptr, err);
496 } else {
497 if (const lldb_private::Symbol *sym = parser_vars->m_lldb_sym)
498 offset = m_parser_vars->m_materializer->AddSymbol(*sym, err);
499 else if (const RegisterInfo *reg_info = var->GetRegisterInfo())
500 offset = m_parser_vars->m_materializer->AddRegister(*reg_info, err);
501 else if (parser_vars->m_lldb_var)
502 offset = m_parser_vars->m_materializer->AddVariable(
503 parser_vars->m_lldb_var, err);
Sean Callanan1582ee62013-04-18 22:06:33 +0000504 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000505
Kate Stoneb9c1b512016-09-06 20:57:50 +0000506 if (!err.Success())
507 return false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000508
Kate Stoneb9c1b512016-09-06 20:57:50 +0000509 if (log)
510 log->Printf("Placed at 0x%llx", (unsigned long long)offset);
Sean Callanan3c495c12013-01-15 23:29:36 +0000511
Kate Stoneb9c1b512016-09-06 20:57:50 +0000512 jit_vars->m_offset =
513 offset; // TODO DoStructLayout() should not change this.
514 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000515
Kate Stoneb9c1b512016-09-06 20:57:50 +0000516 return true;
517}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000518
Kate Stoneb9c1b512016-09-06 20:57:50 +0000519bool ClangExpressionDeclMap::DoStructLayout() {
520 assert(m_struct_vars.get());
Sean Callanan3dd6a422013-04-11 21:16:36 +0000521
Kate Stoneb9c1b512016-09-06 20:57:50 +0000522 if (m_struct_vars->m_struct_laid_out)
523 return true;
Sean Callanandf667652013-04-11 02:05:11 +0000524
Kate Stoneb9c1b512016-09-06 20:57:50 +0000525 if (!m_parser_vars->m_materializer)
526 return false;
527
528 m_struct_vars->m_struct_alignment =
529 m_parser_vars->m_materializer->GetStructAlignment();
530 m_struct_vars->m_struct_size =
531 m_parser_vars->m_materializer->GetStructByteSize();
532 m_struct_vars->m_struct_laid_out = true;
533 return true;
534}
535
536bool ClangExpressionDeclMap::GetStructInfo(uint32_t &num_elements, size_t &size,
537 lldb::offset_t &alignment) {
538 assert(m_struct_vars.get());
539
540 if (!m_struct_vars->m_struct_laid_out)
541 return false;
542
543 num_elements = m_struct_members.GetSize();
544 size = m_struct_vars->m_struct_size;
545 alignment = m_struct_vars->m_struct_alignment;
546
547 return true;
548}
549
550bool ClangExpressionDeclMap::GetStructElement(const NamedDecl *&decl,
551 llvm::Value *&value,
552 lldb::offset_t &offset,
553 ConstString &name,
554 uint32_t index) {
555 assert(m_struct_vars.get());
556
557 if (!m_struct_vars->m_struct_laid_out)
558 return false;
559
560 if (index >= m_struct_members.GetSize())
561 return false;
562
563 ExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(index));
564
565 if (!member_sp)
566 return false;
567
568 ClangExpressionVariable::ParserVars *parser_vars =
569 llvm::cast<ClangExpressionVariable>(member_sp.get())
570 ->GetParserVars(GetParserID());
571 ClangExpressionVariable::JITVars *jit_vars =
572 llvm::cast<ClangExpressionVariable>(member_sp.get())
573 ->GetJITVars(GetParserID());
574
575 if (!parser_vars || !jit_vars || !member_sp->GetValueObject())
576 return false;
577
578 decl = parser_vars->m_named_decl;
579 value = parser_vars->m_llvm_value;
580 offset = jit_vars->m_offset;
581 name = member_sp->GetName();
582
583 return true;
584}
585
586bool ClangExpressionDeclMap::GetFunctionInfo(const NamedDecl *decl,
587 uint64_t &ptr) {
588 ClangExpressionVariable *entity(ClangExpressionVariable::FindVariableInList(
589 m_found_entities, decl, GetParserID()));
590
591 if (!entity)
592 return false;
593
Adrian Prantl05097242018-04-30 16:49:04 +0000594 // We know m_parser_vars is valid since we searched for the variable by its
595 // NamedDecl
Kate Stoneb9c1b512016-09-06 20:57:50 +0000596
597 ClangExpressionVariable::ParserVars *parser_vars =
598 entity->GetParserVars(GetParserID());
599
600 ptr = parser_vars->m_lldb_value.GetScalar().ULongLong();
601
602 return true;
603}
604
605addr_t ClangExpressionDeclMap::GetSymbolAddress(Target &target,
606 Process *process,
607 const ConstString &name,
608 lldb::SymbolType symbol_type,
609 lldb_private::Module *module) {
610 SymbolContextList sc_list;
611
612 if (module)
613 module->FindSymbolsWithNameAndType(name, symbol_type, sc_list);
614 else
615 target.GetImages().FindSymbolsWithNameAndType(name, symbol_type, sc_list);
616
617 const uint32_t num_matches = sc_list.GetSize();
618 addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;
619
620 for (uint32_t i = 0;
621 i < num_matches &&
622 (symbol_load_addr == 0 || symbol_load_addr == LLDB_INVALID_ADDRESS);
623 i++) {
624 SymbolContext sym_ctx;
625 sc_list.GetContextAtIndex(i, sym_ctx);
626
627 const Address sym_address = sym_ctx.symbol->GetAddress();
628
629 if (!sym_address.IsValid())
630 continue;
631
632 switch (sym_ctx.symbol->GetType()) {
633 case eSymbolTypeCode:
634 case eSymbolTypeTrampoline:
635 symbol_load_addr = sym_address.GetCallableLoadAddress(&target);
636 break;
637
638 case eSymbolTypeResolver:
639 symbol_load_addr = sym_address.GetCallableLoadAddress(&target, true);
640 break;
641
642 case eSymbolTypeReExported: {
643 ConstString reexport_name = sym_ctx.symbol->GetReExportedSymbolName();
644 if (reexport_name) {
645 ModuleSP reexport_module_sp;
646 ModuleSpec reexport_module_spec;
647 reexport_module_spec.GetPlatformFileSpec() =
648 sym_ctx.symbol->GetReExportedSymbolSharedLibrary();
649 if (reexport_module_spec.GetPlatformFileSpec()) {
650 reexport_module_sp =
651 target.GetImages().FindFirstModule(reexport_module_spec);
652 if (!reexport_module_sp) {
653 reexport_module_spec.GetPlatformFileSpec().GetDirectory().Clear();
654 reexport_module_sp =
655 target.GetImages().FindFirstModule(reexport_module_spec);
656 }
Sean Callanandf667652013-04-11 02:05:11 +0000657 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000658 symbol_load_addr = GetSymbolAddress(
659 target, process, sym_ctx.symbol->GetReExportedSymbolName(),
660 symbol_type, reexport_module_sp.get());
661 }
662 } break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000663
Kate Stoneb9c1b512016-09-06 20:57:50 +0000664 case eSymbolTypeData:
665 case eSymbolTypeRuntime:
666 case eSymbolTypeVariable:
667 case eSymbolTypeLocal:
668 case eSymbolTypeParam:
669 case eSymbolTypeInvalid:
670 case eSymbolTypeAbsolute:
671 case eSymbolTypeException:
672 case eSymbolTypeSourceFile:
673 case eSymbolTypeHeaderFile:
674 case eSymbolTypeObjectFile:
675 case eSymbolTypeCommonBlock:
676 case eSymbolTypeBlock:
677 case eSymbolTypeVariableType:
678 case eSymbolTypeLineEntry:
679 case eSymbolTypeLineHeader:
680 case eSymbolTypeScopeBegin:
681 case eSymbolTypeScopeEnd:
682 case eSymbolTypeAdditional:
683 case eSymbolTypeCompiler:
684 case eSymbolTypeInstrumentation:
685 case eSymbolTypeUndefined:
686 case eSymbolTypeObjCClass:
687 case eSymbolTypeObjCMetaClass:
688 case eSymbolTypeObjCIVar:
689 symbol_load_addr = sym_address.GetLoadAddress(&target);
690 break;
Sean Callanandf667652013-04-11 02:05:11 +0000691 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000692 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000693
Kate Stoneb9c1b512016-09-06 20:57:50 +0000694 if (symbol_load_addr == LLDB_INVALID_ADDRESS && process) {
695 ObjCLanguageRuntime *runtime = process->GetObjCLanguageRuntime();
Sean Callanan549c9f72010-07-13 21:41:46 +0000696
Kate Stoneb9c1b512016-09-06 20:57:50 +0000697 if (runtime) {
698 symbol_load_addr = runtime->LookupRuntimeSymbol(name);
Greg Clayton084db102011-06-23 04:25:29 +0000699 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000700 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000701
Kate Stoneb9c1b512016-09-06 20:57:50 +0000702 return symbol_load_addr;
Sean Callananc3a16002011-01-17 23:42:46 +0000703}
704
Kate Stoneb9c1b512016-09-06 20:57:50 +0000705addr_t ClangExpressionDeclMap::GetSymbolAddress(const ConstString &name,
706 lldb::SymbolType symbol_type) {
707 assert(m_parser_vars.get());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000708
Kate Stoneb9c1b512016-09-06 20:57:50 +0000709 if (!m_parser_vars->m_exe_ctx.GetTargetPtr())
710 return false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000711
Kate Stoneb9c1b512016-09-06 20:57:50 +0000712 return GetSymbolAddress(m_parser_vars->m_exe_ctx.GetTargetRef(),
713 m_parser_vars->m_exe_ctx.GetProcessPtr(), name,
714 symbol_type);
Sean Callanand9ca42a2011-05-08 02:21:26 +0000715}
716
Kate Stoneb9c1b512016-09-06 20:57:50 +0000717lldb::VariableSP ClangExpressionDeclMap::FindGlobalVariable(
718 Target &target, ModuleSP &module, const ConstString &name,
719 CompilerDeclContext *namespace_decl, TypeFromUser *type) {
720 VariableList vars;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000721
Kate Stoneb9c1b512016-09-06 20:57:50 +0000722 if (module && namespace_decl)
Pavel Labath34cda142018-05-31 09:46:26 +0000723 module->FindGlobalVariables(name, namespace_decl, -1, vars);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000724 else
Pavel Labath34cda142018-05-31 09:46:26 +0000725 target.GetImages().FindGlobalVariables(name, -1, vars);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000726
Kate Stoneb9c1b512016-09-06 20:57:50 +0000727 if (vars.GetSize()) {
728 if (type) {
729 for (size_t i = 0; i < vars.GetSize(); ++i) {
730 VariableSP var_sp = vars.GetVariableAtIndex(i);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000731
Kate Stoneb9c1b512016-09-06 20:57:50 +0000732 if (ClangASTContext::AreTypesSame(
733 *type, var_sp->GetType()->GetFullCompilerType()))
734 return var_sp;
735 }
736 } else {
737 return vars.GetVariableAtIndex(0);
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000738 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000739 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +0000740
Kate Stoneb9c1b512016-09-06 20:57:50 +0000741 return VariableSP();
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000742}
743
Kate Stoneb9c1b512016-09-06 20:57:50 +0000744ClangASTContext *ClangExpressionDeclMap::GetClangASTContext() {
745 StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
746 if (frame == nullptr)
747 return nullptr;
Siva Chandra03ff5c82016-02-05 19:10:04 +0000748
Kate Stoneb9c1b512016-09-06 20:57:50 +0000749 SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
750 lldb::eSymbolContextBlock);
751 if (sym_ctx.block == nullptr)
752 return nullptr;
Siva Chandra03ff5c82016-02-05 19:10:04 +0000753
Kate Stoneb9c1b512016-09-06 20:57:50 +0000754 CompilerDeclContext frame_decl_context = sym_ctx.block->GetDeclContext();
755 if (!frame_decl_context)
756 return nullptr;
Siva Chandra03ff5c82016-02-05 19:10:04 +0000757
Kate Stoneb9c1b512016-09-06 20:57:50 +0000758 return llvm::dyn_cast_or_null<ClangASTContext>(
759 frame_decl_context.GetTypeSystem());
Siva Chandra03ff5c82016-02-05 19:10:04 +0000760}
761
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000762// Interface for ClangASTSource
Sean Callanan3bfdaa22011-09-15 02:13:07 +0000763
Kate Stoneb9c1b512016-09-06 20:57:50 +0000764void ClangExpressionDeclMap::FindExternalVisibleDecls(
765 NameSearchContext &context) {
766 assert(m_ast_context);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000767
Kate Stoneb9c1b512016-09-06 20:57:50 +0000768 ClangASTMetrics::RegisterVisibleQuery();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000769
Kate Stoneb9c1b512016-09-06 20:57:50 +0000770 const ConstString name(context.m_decl_name.getAsString().c_str());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000771
Kate Stoneb9c1b512016-09-06 20:57:50 +0000772 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000773
Kate Stoneb9c1b512016-09-06 20:57:50 +0000774 if (GetImportInProgress()) {
775 if (log && log->GetVerbose())
776 log->Printf("Ignoring a query during an import");
777 return;
778 }
779
780 static unsigned int invocation_id = 0;
781 unsigned int current_id = invocation_id++;
782
783 if (log) {
784 if (!context.m_decl_context)
785 log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for "
786 "'%s' in a NULL DeclContext",
787 current_id, name.GetCString());
788 else if (const NamedDecl *context_named_decl =
789 dyn_cast<NamedDecl>(context.m_decl_context))
790 log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for "
791 "'%s' in '%s'",
792 current_id, name.GetCString(),
793 context_named_decl->getNameAsString().c_str());
794 else
795 log->Printf("ClangExpressionDeclMap::FindExternalVisibleDecls[%u] for "
796 "'%s' in a '%s'",
797 current_id, name.GetCString(),
798 context.m_decl_context->getDeclKindName());
799 }
800
801 if (const NamespaceDecl *namespace_context =
802 dyn_cast<NamespaceDecl>(context.m_decl_context)) {
803 if (namespace_context->getName().str() ==
804 std::string(g_lldb_local_vars_namespace_cstr)) {
805 CompilerDeclContext compiler_decl_ctx(
806 GetClangASTContext(), const_cast<void *>(static_cast<const void *>(
807 context.m_decl_context)));
808 FindExternalVisibleDecls(context, lldb::ModuleSP(), compiler_decl_ctx,
809 current_id);
810 return;
Sean Callanan6abfabf2010-11-19 20:20:02 +0000811 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000812
Kate Stoneb9c1b512016-09-06 20:57:50 +0000813 ClangASTImporter::NamespaceMapSP namespace_map =
Sean Callanan68e44232017-09-28 20:20:25 +0000814 m_ast_importer_sp
815 ? m_ast_importer_sp->GetNamespaceMap(namespace_context)
816 : ClangASTImporter::NamespaceMapSP();
817
818 if (!namespace_map)
819 return;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000820
821 if (log && log->GetVerbose())
822 log->Printf(" CEDM::FEVD[%u] Inspecting (NamespaceMap*)%p (%d entries)",
823 current_id, static_cast<void *>(namespace_map.get()),
824 (int)namespace_map->size());
Sean Callanan68e44232017-09-28 20:20:25 +0000825
Kate Stoneb9c1b512016-09-06 20:57:50 +0000826 for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(),
827 e = namespace_map->end();
828 i != e; ++i) {
829 if (log)
830 log->Printf(" CEDM::FEVD[%u] Searching namespace %s in module %s",
831 current_id, i->second.GetName().AsCString(),
832 i->first->GetFileSpec().GetFilename().GetCString());
833
834 FindExternalVisibleDecls(context, i->first, i->second, current_id);
835 }
836 } else if (isa<TranslationUnitDecl>(context.m_decl_context)) {
837 CompilerDeclContext namespace_decl;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000838
Sean Callanan503aa522011-10-12 00:12:34 +0000839 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +0000840 log->Printf(" CEDM::FEVD[%u] Searching the root namespace", current_id);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000841
Kate Stoneb9c1b512016-09-06 20:57:50 +0000842 FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl,
843 current_id);
844 }
Sean Callananc02a1c02017-04-24 23:14:04 +0000845
846 ClangASTSource::FindExternalVisibleDecls(context);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000847}
848
849void ClangExpressionDeclMap::FindExternalVisibleDecls(
850 NameSearchContext &context, lldb::ModuleSP module_sp,
851 CompilerDeclContext &namespace_decl, unsigned int current_id) {
852 assert(m_ast_context);
853
854 std::function<void(clang::FunctionDecl *)> MaybeRegisterFunctionBody =
855 [this](clang::FunctionDecl *copied_function_decl) {
856 if (copied_function_decl->getBody() && m_parser_vars->m_code_gen) {
857 DeclGroupRef decl_group_ref(copied_function_decl);
858 m_parser_vars->m_code_gen->HandleTopLevelDecl(decl_group_ref);
859 }
860 };
861
862 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
863
864 SymbolContextList sc_list;
865
866 const ConstString name(context.m_decl_name.getAsString().c_str());
Sean Callanan1b3c43b2017-09-26 17:25:34 +0000867 if (IgnoreName(name, false))
Kate Stoneb9c1b512016-09-06 20:57:50 +0000868 return;
869
Adrian Prantl05097242018-04-30 16:49:04 +0000870 // Only look for functions by name out in our symbols if the function doesn't
871 // start with our phony prefix of '$'
Kate Stoneb9c1b512016-09-06 20:57:50 +0000872 Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
873 StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
874 SymbolContext sym_ctx;
875 if (frame != nullptr)
876 sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
877 lldb::eSymbolContextBlock);
878
879 // Try the persistent decls, which take precedence over all else.
880 if (!namespace_decl) {
881 do {
882 if (!target)
883 break;
884
885 ClangASTContext *scratch_clang_ast_context =
886 target->GetScratchClangASTContext();
887
888 if (!scratch_clang_ast_context)
889 break;
890
891 ASTContext *scratch_ast_context =
892 scratch_clang_ast_context->getASTContext();
893
894 if (!scratch_ast_context)
895 break;
896
897 NamedDecl *persistent_decl =
898 m_parser_vars->m_persistent_vars->GetPersistentDecl(name);
899
900 if (!persistent_decl)
901 break;
902
Sean Callanan68e44232017-09-28 20:20:25 +0000903 Decl *parser_persistent_decl = CopyDecl(persistent_decl);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000904
905 if (!parser_persistent_decl)
906 break;
907
908 NamedDecl *parser_named_decl =
909 dyn_cast<NamedDecl>(parser_persistent_decl);
910
911 if (!parser_named_decl)
912 break;
913
914 if (clang::FunctionDecl *parser_function_decl =
915 llvm::dyn_cast<clang::FunctionDecl>(parser_named_decl)) {
916 MaybeRegisterFunctionBody(parser_function_decl);
917 }
918
919 if (log)
920 log->Printf(" CEDM::FEVD[%u] Found persistent decl %s", current_id,
921 name.GetCString());
922
923 context.AddNamedDecl(parser_named_decl);
924 } while (0);
925 }
926
Sean Callanan1b3c43b2017-09-26 17:25:34 +0000927 if (name.GetCString()[0] == '$' && !namespace_decl) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000928 static ConstString g_lldb_class_name("$__lldb_class");
929
930 if (name == g_lldb_class_name) {
931 // Clang is looking for the type of "this"
932
933 if (frame == NULL)
934 return;
935
936 // Find the block that defines the function represented by "sym_ctx"
937 Block *function_block = sym_ctx.GetFunctionBlock();
938
939 if (!function_block)
940 return;
941
942 CompilerDeclContext function_decl_ctx = function_block->GetDeclContext();
943
944 if (!function_decl_ctx)
945 return;
946
947 clang::CXXMethodDecl *method_decl =
948 ClangASTContext::DeclContextGetAsCXXMethodDecl(function_decl_ctx);
949
950 if (method_decl) {
951 clang::CXXRecordDecl *class_decl = method_decl->getParent();
952
953 QualType class_qual_type(class_decl->getTypeForDecl(), 0);
954
955 TypeFromUser class_user_type(
956 class_qual_type.getAsOpaquePtr(),
957 ClangASTContext::GetASTContext(&class_decl->getASTContext()));
958
959 if (log) {
960 ASTDumper ast_dumper(class_qual_type);
961 log->Printf(" CEDM::FEVD[%u] Adding type for $__lldb_class: %s",
962 current_id, ast_dumper.GetCString());
Siva Chandra03ff5c82016-02-05 19:10:04 +0000963 }
964
Kate Stoneb9c1b512016-09-06 20:57:50 +0000965 AddThisType(context, class_user_type, current_id);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000966
Kate Stoneb9c1b512016-09-06 20:57:50 +0000967 if (method_decl->isInstance()) {
968 // self is a pointer to the object
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000969
Kate Stoneb9c1b512016-09-06 20:57:50 +0000970 QualType class_pointer_type =
971 method_decl->getASTContext().getPointerType(class_qual_type);
972
973 TypeFromUser self_user_type(
974 class_pointer_type.getAsOpaquePtr(),
975 ClangASTContext::GetASTContext(&method_decl->getASTContext()));
976
977 m_struct_vars->m_object_pointer_type = self_user_type;
978 }
979 } else {
Adrian Prantl05097242018-04-30 16:49:04 +0000980 // This branch will get hit if we are executing code in the context of
981 // a function that claims to have an object pointer (through
982 // DW_AT_object_pointer?) but is not formally a method of the class.
983 // In that case, just look up the "this" variable in the current scope
984 // and use its type.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000985 // FIXME: This code is formally correct, but clang doesn't currently
986 // emit DW_AT_object_pointer
987 // for C++ so it hasn't actually been tested.
988
989 VariableList *vars = frame->GetVariableList(false);
990
991 lldb::VariableSP this_var = vars->FindVariable(ConstString("this"));
992
993 if (this_var && this_var->IsInScope(frame) &&
994 this_var->LocationIsValidForFrame(frame)) {
995 Type *this_type = this_var->GetType();
996
997 if (!this_type)
Sean Callananb2269162011-10-21 22:18:07 +0000998 return;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000999
Kate Stoneb9c1b512016-09-06 20:57:50 +00001000 TypeFromUser pointee_type =
1001 this_type->GetForwardCompilerType().GetPointeeType();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001002
Kate Stoneb9c1b512016-09-06 20:57:50 +00001003 if (pointee_type.IsValid()) {
1004 if (log) {
1005 ASTDumper ast_dumper(pointee_type);
1006 log->Printf(" FEVD[%u] Adding type for $__lldb_class: %s",
1007 current_id, ast_dumper.GetCString());
1008 }
1009
1010 AddThisType(context, pointee_type, current_id);
1011 TypeFromUser this_user_type(this_type->GetFullCompilerType());
1012 m_struct_vars->m_object_pointer_type = this_user_type;
1013 return;
1014 }
Sean Callanan503aa522011-10-12 00:12:34 +00001015 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001016 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001017
Kate Stoneb9c1b512016-09-06 20:57:50 +00001018 return;
1019 }
1020
1021 static ConstString g_lldb_objc_class_name("$__lldb_objc_class");
1022 if (name == g_lldb_objc_class_name) {
1023 // Clang is looking for the type of "*self"
1024
1025 if (!frame)
1026 return;
1027
1028 SymbolContext sym_ctx = frame->GetSymbolContext(
1029 lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);
1030
1031 // Find the block that defines the function represented by "sym_ctx"
1032 Block *function_block = sym_ctx.GetFunctionBlock();
1033
1034 if (!function_block)
1035 return;
1036
1037 CompilerDeclContext function_decl_ctx = function_block->GetDeclContext();
1038
1039 if (!function_decl_ctx)
1040 return;
1041
1042 clang::ObjCMethodDecl *method_decl =
1043 ClangASTContext::DeclContextGetAsObjCMethodDecl(function_decl_ctx);
1044
1045 if (method_decl) {
1046 ObjCInterfaceDecl *self_interface = method_decl->getClassInterface();
1047
1048 if (!self_interface)
1049 return;
1050
1051 const clang::Type *interface_type = self_interface->getTypeForDecl();
1052
1053 if (!interface_type)
1054 return; // This is unlikely, but we have seen crashes where this
1055 // occurred
1056
1057 TypeFromUser class_user_type(
1058 QualType(interface_type, 0).getAsOpaquePtr(),
1059 ClangASTContext::GetASTContext(&method_decl->getASTContext()));
1060
1061 if (log) {
1062 ASTDumper ast_dumper(interface_type);
1063 log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s",
1064 current_id, ast_dumper.GetCString());
1065 }
1066
1067 AddOneType(context, class_user_type, current_id);
1068
1069 if (method_decl->isInstanceMethod()) {
1070 // self is a pointer to the object
1071
1072 QualType class_pointer_type =
1073 method_decl->getASTContext().getObjCObjectPointerType(
1074 QualType(interface_type, 0));
1075
1076 TypeFromUser self_user_type(
1077 class_pointer_type.getAsOpaquePtr(),
1078 ClangASTContext::GetASTContext(&method_decl->getASTContext()));
1079
1080 m_struct_vars->m_object_pointer_type = self_user_type;
1081 } else {
1082 // self is a Class pointer
1083 QualType class_type = method_decl->getASTContext().getObjCClassType();
1084
1085 TypeFromUser self_user_type(
1086 class_type.getAsOpaquePtr(),
1087 ClangASTContext::GetASTContext(&method_decl->getASTContext()));
1088
1089 m_struct_vars->m_object_pointer_type = self_user_type;
1090 }
1091
1092 return;
1093 } else {
Adrian Prantl05097242018-04-30 16:49:04 +00001094 // This branch will get hit if we are executing code in the context of
1095 // a function that claims to have an object pointer (through
1096 // DW_AT_object_pointer?) but is not formally a method of the class.
1097 // In that case, just look up the "self" variable in the current scope
1098 // and use its type.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001099
1100 VariableList *vars = frame->GetVariableList(false);
1101
1102 lldb::VariableSP self_var = vars->FindVariable(ConstString("self"));
1103
1104 if (self_var && self_var->IsInScope(frame) &&
1105 self_var->LocationIsValidForFrame(frame)) {
1106 Type *self_type = self_var->GetType();
1107
1108 if (!self_type)
1109 return;
1110
1111 CompilerType self_clang_type = self_type->GetFullCompilerType();
1112
1113 if (ClangASTContext::IsObjCClassType(self_clang_type)) {
1114 return;
1115 } else if (ClangASTContext::IsObjCObjectPointerType(
1116 self_clang_type)) {
1117 self_clang_type = self_clang_type.GetPointeeType();
1118
1119 if (!self_clang_type)
1120 return;
1121
1122 if (log) {
1123 ASTDumper ast_dumper(self_type->GetFullCompilerType());
1124 log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s",
1125 current_id, ast_dumper.GetCString());
1126 }
1127
1128 TypeFromUser class_user_type(self_clang_type);
1129
1130 AddOneType(context, class_user_type, current_id);
1131
1132 TypeFromUser self_user_type(self_type->GetFullCompilerType());
1133
1134 m_struct_vars->m_object_pointer_type = self_user_type;
1135 return;
1136 }
1137 }
1138 }
1139
1140 return;
1141 }
1142
1143 if (name == ConstString(g_lldb_local_vars_namespace_cstr)) {
1144 CompilerDeclContext frame_decl_context =
1145 sym_ctx.block != nullptr ? sym_ctx.block->GetDeclContext()
1146 : CompilerDeclContext();
1147
1148 if (frame_decl_context) {
1149 ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(
1150 frame_decl_context.GetTypeSystem());
1151
1152 if (ast) {
1153 clang::NamespaceDecl *namespace_decl =
1154 ClangASTContext::GetUniqueNamespaceDeclaration(
Sean Callanan1b3c43b2017-09-26 17:25:34 +00001155 m_ast_context, name.GetCString(), nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001156 if (namespace_decl) {
1157 context.AddNamedDecl(namespace_decl);
1158 clang::DeclContext *clang_decl_ctx =
1159 clang::Decl::castToDeclContext(namespace_decl);
1160 clang_decl_ctx->setHasExternalVisibleStorage(true);
1161 context.m_found.local_vars_nsp = true;
1162 }
1163 }
1164 }
1165
1166 return;
1167 }
1168
1169 // any other $__lldb names should be weeded out now
Sean Callanan1b3c43b2017-09-26 17:25:34 +00001170 if (name.GetStringRef().startswith("$__lldb"))
Kate Stoneb9c1b512016-09-06 20:57:50 +00001171 return;
1172
1173 ExpressionVariableSP pvar_sp(
1174 m_parser_vars->m_persistent_vars->GetVariable(name));
1175
1176 if (pvar_sp) {
1177 AddOneVariable(context, pvar_sp, current_id);
1178 return;
1179 }
1180
1181 const char *reg_name(&name.GetCString()[1]);
1182
1183 if (m_parser_vars->m_exe_ctx.GetRegisterContext()) {
1184 const RegisterInfo *reg_info(
1185 m_parser_vars->m_exe_ctx.GetRegisterContext()->GetRegisterInfoByName(
1186 reg_name));
1187
1188 if (reg_info) {
Sean Callanan503aa522011-10-12 00:12:34 +00001189 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001190 log->Printf(" CEDM::FEVD[%u] Found register %s", current_id,
1191 reg_info->name);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001192
Kate Stoneb9c1b512016-09-06 20:57:50 +00001193 AddOneRegister(context, reg_info, current_id);
1194 }
1195 }
1196 } else {
1197 ValueObjectSP valobj;
1198 VariableSP var;
1199
1200 bool local_var_lookup =
1201 !namespace_decl || (namespace_decl.GetName() ==
1202 ConstString(g_lldb_local_vars_namespace_cstr));
1203 if (frame && local_var_lookup) {
1204 CompilerDeclContext compiler_decl_context =
1205 sym_ctx.block != nullptr ? sym_ctx.block->GetDeclContext()
1206 : CompilerDeclContext();
1207
1208 if (compiler_decl_context) {
1209 // Make sure that the variables are parsed so that we have the
1210 // declarations.
1211 VariableListSP vars = frame->GetInScopeVariableList(true);
1212 for (size_t i = 0; i < vars->GetSize(); i++)
1213 vars->GetVariableAtIndex(i)->GetDecl();
1214
1215 // Search for declarations matching the name. Do not include imported
Adrian Prantl05097242018-04-30 16:49:04 +00001216 // decls in the search if we are looking for decls in the artificial
1217 // namespace $__lldb_local_vars.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001218 std::vector<CompilerDecl> found_decls =
1219 compiler_decl_context.FindDeclByName(name,
1220 namespace_decl.IsValid());
1221
1222 bool variable_found = false;
1223 for (CompilerDecl decl : found_decls) {
1224 for (size_t vi = 0, ve = vars->GetSize(); vi != ve; ++vi) {
1225 VariableSP candidate_var = vars->GetVariableAtIndex(vi);
1226 if (candidate_var->GetDecl() == decl) {
1227 var = candidate_var;
1228 break;
1229 }
1230 }
1231
Sean Callananc02a1c02017-04-24 23:14:04 +00001232 if (var && !variable_found) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001233 variable_found = true;
1234 valobj = ValueObjectVariable::Create(frame, var);
1235 AddOneVariable(context, var, valobj, current_id);
1236 context.m_found.variable = true;
1237 }
1238 }
1239 if (variable_found)
1240 return;
1241 }
1242 }
1243 if (target) {
1244 var = FindGlobalVariable(*target, module_sp, name, &namespace_decl, NULL);
1245
1246 if (var) {
1247 valobj = ValueObjectVariable::Create(target, var);
1248 AddOneVariable(context, var, valobj, current_id);
1249 context.m_found.variable = true;
1250 return;
1251 }
Sean Callanan503aa522011-10-12 00:12:34 +00001252 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001253
Kate Stoneb9c1b512016-09-06 20:57:50 +00001254 std::vector<clang::NamedDecl *> decls_from_modules;
Sean Callanan503aa522011-10-12 00:12:34 +00001255
Kate Stoneb9c1b512016-09-06 20:57:50 +00001256 if (target) {
1257 if (ClangModulesDeclVendor *decl_vendor =
1258 target->GetClangModulesDeclVendor()) {
1259 decl_vendor->FindDecls(name, false, UINT32_MAX, decls_from_modules);
1260 }
1261 }
Sean Callananb3a36df2016-03-19 00:51:43 +00001262
Sean Callananc02a1c02017-04-24 23:14:04 +00001263 const bool include_inlines = false;
1264 const bool append = false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001265
Sean Callananc02a1c02017-04-24 23:14:04 +00001266 if (namespace_decl && module_sp) {
1267 const bool include_symbols = false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001268
Sean Callananc02a1c02017-04-24 23:14:04 +00001269 module_sp->FindFunctions(name, &namespace_decl, eFunctionNameTypeBase,
1270 include_symbols, include_inlines, append,
1271 sc_list);
1272 } else if (target && !namespace_decl) {
1273 const bool include_symbols = true;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001274
Sean Callananc02a1c02017-04-24 23:14:04 +00001275 // TODO Fix FindFunctions so that it doesn't return
1276 // instance methods for eFunctionNameTypeBase.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001277
Sean Callananc02a1c02017-04-24 23:14:04 +00001278 target->GetImages().FindFunctions(name, eFunctionNameTypeFull,
1279 include_symbols, include_inlines,
1280 append, sc_list);
1281 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001282
Adrian Prantl05097242018-04-30 16:49:04 +00001283 // If we found more than one function, see if we can use the frame's decl
1284 // context to remove functions that are shadowed by other functions which
1285 // match in type but are nearer in scope.
Sean Callananc02a1c02017-04-24 23:14:04 +00001286 //
1287 // AddOneFunction will not add a function whose type has already been
Adrian Prantl05097242018-04-30 16:49:04 +00001288 // added, so if there's another function in the list with a matching type,
1289 // check to see if their decl context is a parent of the current frame's or
1290 // was imported via a and using statement, and pick the best match
1291 // according to lookup rules.
Sean Callananc02a1c02017-04-24 23:14:04 +00001292 if (sc_list.GetSize() > 1) {
1293 // Collect some info about our frame's context.
1294 StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
1295 SymbolContext frame_sym_ctx;
1296 if (frame != nullptr)
1297 frame_sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
1298 lldb::eSymbolContextBlock);
1299 CompilerDeclContext frame_decl_context =
1300 frame_sym_ctx.block != nullptr ? frame_sym_ctx.block->GetDeclContext()
1301 : CompilerDeclContext();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001302
Sean Callananc02a1c02017-04-24 23:14:04 +00001303 // We can't do this without a compiler decl context for our frame.
1304 if (frame_decl_context) {
1305 clang::DeclContext *frame_decl_ctx =
1306 (clang::DeclContext *)frame_decl_context.GetOpaqueDeclContext();
1307 ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(
1308 frame_decl_context.GetTypeSystem());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001309
Sean Callananc02a1c02017-04-24 23:14:04 +00001310 // Structure to hold the info needed when comparing function
1311 // declarations.
1312 struct FuncDeclInfo {
1313 ConstString m_name;
1314 CompilerType m_copied_type;
1315 uint32_t m_decl_lvl;
1316 SymbolContext m_sym_ctx;
1317 };
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001318
Adrian Prantl05097242018-04-30 16:49:04 +00001319 // First, symplify things by looping through the symbol contexts to
1320 // remove unwanted functions and separate out the functions we want to
1321 // compare and prune into a separate list. Cache the info needed about
1322 // the function declarations in a vector for efficiency.
Sean Callananc02a1c02017-04-24 23:14:04 +00001323 SymbolContextList sc_sym_list;
1324 uint32_t num_indices = sc_list.GetSize();
1325 std::vector<FuncDeclInfo> fdi_cache;
1326 fdi_cache.reserve(num_indices);
1327 for (uint32_t index = 0; index < num_indices; ++index) {
1328 FuncDeclInfo fdi;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001329 SymbolContext sym_ctx;
1330 sc_list.GetContextAtIndex(index, sym_ctx);
1331
Adrian Prantl05097242018-04-30 16:49:04 +00001332 // We don't know enough about symbols to compare them, but we should
1333 // keep them in the list.
Sean Callananc02a1c02017-04-24 23:14:04 +00001334 Function *function = sym_ctx.function;
1335 if (!function) {
1336 sc_sym_list.Append(sym_ctx);
1337 continue;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001338 }
Sean Callananc02a1c02017-04-24 23:14:04 +00001339 // Filter out functions without declaration contexts, as well as
Adrian Prantl05097242018-04-30 16:49:04 +00001340 // class/instance methods, since they'll be skipped in the code that
1341 // follows anyway.
Sean Callananc02a1c02017-04-24 23:14:04 +00001342 CompilerDeclContext func_decl_context = function->GetDeclContext();
1343 if (!func_decl_context ||
1344 func_decl_context.IsClassMethod(nullptr, nullptr, nullptr))
1345 continue;
1346 // We can only prune functions for which we can copy the type.
1347 CompilerType func_clang_type =
1348 function->GetType()->GetFullCompilerType();
1349 CompilerType copied_func_type = GuardedCopyType(func_clang_type);
1350 if (!copied_func_type) {
1351 sc_sym_list.Append(sym_ctx);
1352 continue;
1353 }
1354
1355 fdi.m_sym_ctx = sym_ctx;
1356 fdi.m_name = function->GetName();
1357 fdi.m_copied_type = copied_func_type;
1358 fdi.m_decl_lvl = LLDB_INVALID_DECL_LEVEL;
1359 if (fdi.m_copied_type && func_decl_context) {
Adrian Prantl05097242018-04-30 16:49:04 +00001360 // Call CountDeclLevels to get the number of parent scopes we have
1361 // to look through before we find the function declaration. When
1362 // comparing functions of the same type, the one with a lower count
1363 // will be closer to us in the lookup scope and shadows the other.
Sean Callananc02a1c02017-04-24 23:14:04 +00001364 clang::DeclContext *func_decl_ctx =
1365 (clang::DeclContext *)func_decl_context.GetOpaqueDeclContext();
1366 fdi.m_decl_lvl = ast->CountDeclLevels(
1367 frame_decl_ctx, func_decl_ctx, &fdi.m_name, &fdi.m_copied_type);
1368 }
1369 fdi_cache.emplace_back(fdi);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001370 }
1371
Sean Callananc02a1c02017-04-24 23:14:04 +00001372 // Loop through the functions in our cache looking for matching types,
1373 // then compare their scope levels to see which is closer.
1374 std::multimap<CompilerType, const FuncDeclInfo *> matches;
1375 for (const FuncDeclInfo &fdi : fdi_cache) {
1376 const CompilerType t = fdi.m_copied_type;
1377 auto q = matches.find(t);
1378 if (q != matches.end()) {
1379 if (q->second->m_decl_lvl > fdi.m_decl_lvl)
1380 // This function is closer; remove the old set.
1381 matches.erase(t);
1382 else if (q->second->m_decl_lvl < fdi.m_decl_lvl)
1383 // The functions in our set are closer - skip this one.
1384 continue;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001385 }
Sean Callananc02a1c02017-04-24 23:14:04 +00001386 matches.insert(std::make_pair(t, &fdi));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001387 }
1388
Sean Callananc02a1c02017-04-24 23:14:04 +00001389 // Loop through our matches and add their symbol contexts to our list.
1390 SymbolContextList sc_func_list;
1391 for (const auto &q : matches)
1392 sc_func_list.Append(q.second->m_sym_ctx);
1393
1394 // Rejoin the lists with the functions in front.
1395 sc_list = sc_func_list;
1396 sc_list.Append(sc_sym_list);
1397 }
1398 }
1399
1400 if (sc_list.GetSize()) {
1401 Symbol *extern_symbol = NULL;
1402 Symbol *non_extern_symbol = NULL;
1403
1404 for (uint32_t index = 0, num_indices = sc_list.GetSize();
1405 index < num_indices; ++index) {
1406 SymbolContext sym_ctx;
1407 sc_list.GetContextAtIndex(index, sym_ctx);
1408
1409 if (sym_ctx.function) {
1410 CompilerDeclContext decl_ctx = sym_ctx.function->GetDeclContext();
1411
1412 if (!decl_ctx)
1413 continue;
1414
1415 // Filter out class/instance methods.
1416 if (decl_ctx.IsClassMethod(nullptr, nullptr, nullptr))
1417 continue;
1418
1419 AddOneFunction(context, sym_ctx.function, NULL, current_id);
1420 context.m_found.function_with_type_info = true;
1421 context.m_found.function = true;
1422 } else if (sym_ctx.symbol) {
1423 if (sym_ctx.symbol->GetType() == eSymbolTypeReExported && target) {
1424 sym_ctx.symbol = sym_ctx.symbol->ResolveReExportedSymbol(*target);
1425 if (sym_ctx.symbol == NULL)
1426 continue;
1427 }
1428
1429 if (sym_ctx.symbol->IsExternal())
1430 extern_symbol = sym_ctx.symbol;
1431 else
1432 non_extern_symbol = sym_ctx.symbol;
1433 }
1434 }
1435
1436 if (!context.m_found.function_with_type_info) {
1437 for (clang::NamedDecl *decl : decls_from_modules) {
1438 if (llvm::isa<clang::FunctionDecl>(decl)) {
1439 clang::NamedDecl *copied_decl =
Sean Callanan68e44232017-09-28 20:20:25 +00001440 llvm::cast_or_null<FunctionDecl>(CopyDecl(decl));
Sean Callananc02a1c02017-04-24 23:14:04 +00001441 if (copied_decl) {
1442 context.AddNamedDecl(copied_decl);
1443 context.m_found.function_with_type_info = true;
1444 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001445 }
1446 }
1447 }
1448
1449 if (!context.m_found.function_with_type_info) {
Sean Callananc02a1c02017-04-24 23:14:04 +00001450 if (extern_symbol) {
1451 AddOneFunction(context, NULL, extern_symbol, current_id);
1452 context.m_found.function = true;
1453 } else if (non_extern_symbol) {
1454 AddOneFunction(context, NULL, non_extern_symbol, current_id);
1455 context.m_found.function = true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001456 }
1457 }
Sean Callananb3a36df2016-03-19 00:51:43 +00001458 }
Sean Callananc02a1c02017-04-24 23:14:04 +00001459
1460 if (!context.m_found.function_with_type_info) {
1461 // Try the modules next.
1462
1463 do {
1464 if (ClangModulesDeclVendor *modules_decl_vendor =
1465 m_target->GetClangModulesDeclVendor()) {
1466 bool append = false;
1467 uint32_t max_matches = 1;
1468 std::vector<clang::NamedDecl *> decls;
1469
1470 if (!modules_decl_vendor->FindDecls(name, append, max_matches, decls))
1471 break;
1472
1473 clang::NamedDecl *const decl_from_modules = decls[0];
1474
1475 if (llvm::isa<clang::FunctionDecl>(decl_from_modules)) {
1476 if (log) {
1477 log->Printf(" CAS::FEVD[%u] Matching function found for "
1478 "\"%s\" in the modules",
1479 current_id, name.GetCString());
1480 }
1481
Sean Callanan68e44232017-09-28 20:20:25 +00001482 clang::Decl *copied_decl = CopyDecl(decl_from_modules);
Sean Callananc02a1c02017-04-24 23:14:04 +00001483 clang::FunctionDecl *copied_function_decl =
1484 copied_decl ? dyn_cast<clang::FunctionDecl>(copied_decl)
1485 : nullptr;
1486
1487 if (!copied_function_decl) {
1488 if (log)
1489 log->Printf(" CAS::FEVD[%u] - Couldn't export a function "
1490 "declaration from the modules",
1491 current_id);
1492
1493 break;
1494 }
1495
1496 MaybeRegisterFunctionBody(copied_function_decl);
1497
1498 context.AddNamedDecl(copied_function_decl);
1499
1500 context.m_found.function_with_type_info = true;
1501 context.m_found.function = true;
1502 } else if (llvm::isa<clang::VarDecl>(decl_from_modules)) {
1503 if (log) {
1504 log->Printf(" CAS::FEVD[%u] Matching variable found for "
1505 "\"%s\" in the modules",
1506 current_id, name.GetCString());
1507 }
1508
Sean Callanan68e44232017-09-28 20:20:25 +00001509 clang::Decl *copied_decl = CopyDecl(decl_from_modules);
Sean Callananc02a1c02017-04-24 23:14:04 +00001510 clang::VarDecl *copied_var_decl =
1511 copied_decl ? dyn_cast_or_null<clang::VarDecl>(copied_decl)
1512 : nullptr;
1513
1514 if (!copied_var_decl) {
1515 if (log)
1516 log->Printf(" CAS::FEVD[%u] - Couldn't export a variable "
1517 "declaration from the modules",
1518 current_id);
1519
1520 break;
1521 }
1522
1523 context.AddNamedDecl(copied_var_decl);
1524
1525 context.m_found.variable = true;
1526 }
1527 }
1528 } while (0);
1529 }
1530
1531 if (target && !context.m_found.variable && !namespace_decl) {
Adrian Prantl05097242018-04-30 16:49:04 +00001532 // We couldn't find a non-symbol variable for this. Now we'll hunt for a
1533 // generic data symbol, and -- if it is found -- treat it as a variable.
Sean Callanan9c99faa2017-05-16 23:46:13 +00001534 Status error;
Stephane Sezer30fa7e22017-10-24 22:56:05 +00001535
Sean Callanan9c99faa2017-05-16 23:46:13 +00001536 const Symbol *data_symbol =
1537 m_parser_vars->m_sym_ctx.FindBestGlobalDataSymbol(name, error);
Stephane Sezer30fa7e22017-10-24 22:56:05 +00001538
Sean Callanan9c99faa2017-05-16 23:46:13 +00001539 if (!error.Success()) {
1540 const unsigned diag_id =
1541 m_ast_context->getDiagnostics().getCustomDiagID(
1542 clang::DiagnosticsEngine::Level::Error, "%0");
1543 m_ast_context->getDiagnostics().Report(diag_id) << error.AsCString();
1544 }
Stephane Sezer30fa7e22017-10-24 22:56:05 +00001545
Sean Callananc02a1c02017-04-24 23:14:04 +00001546 if (data_symbol) {
1547 std::string warning("got name from symbols: ");
1548 warning.append(name.AsCString());
1549 const unsigned diag_id =
1550 m_ast_context->getDiagnostics().getCustomDiagID(
1551 clang::DiagnosticsEngine::Level::Warning, "%0");
1552 m_ast_context->getDiagnostics().Report(diag_id) << warning.c_str();
1553 AddOneGenericVariable(context, *data_symbol, current_id);
1554 context.m_found.variable = true;
1555 }
1556 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001557 }
Sean Callanan6b4067c2010-07-17 00:43:37 +00001558}
Greg Claytona2721472011-06-25 00:44:06 +00001559
Kate Stoneb9c1b512016-09-06 20:57:50 +00001560bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var,
1561 lldb_private::Value &var_location,
1562 TypeFromUser *user_type,
1563 TypeFromParser *parser_type) {
1564 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001565
Kate Stoneb9c1b512016-09-06 20:57:50 +00001566 Type *var_type = var->GetType();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001567
Kate Stoneb9c1b512016-09-06 20:57:50 +00001568 if (!var_type) {
Sean Callananea22d422010-07-16 00:09:46 +00001569 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001570 log->PutCString("Skipped a definition because it has no type");
1571 return false;
1572 }
1573
1574 CompilerType var_clang_type = var_type->GetFullCompilerType();
1575
1576 if (!var_clang_type) {
1577 if (log)
1578 log->PutCString("Skipped a definition because it has no Clang type");
1579 return false;
1580 }
1581
1582 ClangASTContext *clang_ast = llvm::dyn_cast_or_null<ClangASTContext>(
1583 var_type->GetForwardCompilerType().GetTypeSystem());
1584
1585 if (!clang_ast) {
1586 if (log)
1587 log->PutCString("Skipped a definition because it has no Clang AST");
1588 return false;
1589 }
1590
1591 ASTContext *ast = clang_ast->getASTContext();
1592
1593 if (!ast) {
1594 if (log)
1595 log->PutCString(
1596 "There is no AST context for the current execution context");
1597 return false;
1598 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001599
1600 DWARFExpression &var_location_expr = var->LocationExpression();
1601
1602 Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
Zachary Turner97206d52017-05-12 04:51:55 +00001603 Status err;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001604
1605 if (var->GetLocationIsConstantValueData()) {
1606 DataExtractor const_value_extractor;
1607
1608 if (var_location_expr.GetExpressionData(const_value_extractor)) {
1609 var_location = Value(const_value_extractor.GetDataStart(),
1610 const_value_extractor.GetByteSize());
1611 var_location.SetValueType(Value::eValueTypeHostAddress);
1612 } else {
1613 if (log)
1614 log->Printf("Error evaluating constant variable: %s", err.AsCString());
1615 return false;
Greg Clayton7b462cc2010-10-15 22:48:33 +00001616 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001617 }
1618
1619 CompilerType type_to_use = GuardedCopyType(var_clang_type);
1620
1621 if (!type_to_use) {
1622 if (log)
1623 log->Printf(
1624 "Couldn't copy a variable's type into the parser's AST context");
1625
1626 return false;
1627 }
1628
1629 if (parser_type)
1630 *parser_type = TypeFromParser(type_to_use);
1631
1632 if (var_location.GetContextType() == Value::eContextTypeInvalid)
1633 var_location.SetCompilerType(type_to_use);
1634
1635 if (var_location.GetValueType() == Value::eValueTypeFileAddress) {
1636 SymbolContext var_sc;
1637 var->CalculateSymbolContext(&var_sc);
1638
1639 if (!var_sc.module_sp)
1640 return false;
1641
1642 Address so_addr(var_location.GetScalar().ULongLong(),
1643 var_sc.module_sp->GetSectionList());
1644
1645 lldb::addr_t load_addr = so_addr.GetLoadAddress(target);
1646
1647 if (load_addr != LLDB_INVALID_ADDRESS) {
1648 var_location.GetScalar() = load_addr;
1649 var_location.SetValueType(Value::eValueTypeLoadAddress);
1650 }
1651 }
1652
1653 if (user_type)
1654 *user_type = TypeFromUser(var_clang_type);
1655
1656 return true;
Sean Callanan468574b2010-06-22 23:46:24 +00001657}
1658
Kate Stoneb9c1b512016-09-06 20:57:50 +00001659void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
1660 VariableSP var,
1661 ValueObjectSP valobj,
1662 unsigned int current_id) {
1663 assert(m_parser_vars.get());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001664
Kate Stoneb9c1b512016-09-06 20:57:50 +00001665 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001666
Kate Stoneb9c1b512016-09-06 20:57:50 +00001667 TypeFromUser ut;
1668 TypeFromParser pt;
1669 Value var_location;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001670
Kate Stoneb9c1b512016-09-06 20:57:50 +00001671 if (!GetVariableValue(var, var_location, &ut, &pt))
1672 return;
1673
1674 clang::QualType parser_opaque_type =
1675 QualType::getFromOpaquePtr(pt.GetOpaqueQualType());
1676
1677 if (parser_opaque_type.isNull())
1678 return;
1679
1680 if (const clang::Type *parser_type = parser_opaque_type.getTypePtr()) {
1681 if (const TagType *tag_type = dyn_cast<TagType>(parser_type))
1682 CompleteType(tag_type->getDecl());
1683 if (const ObjCObjectPointerType *objc_object_ptr_type =
1684 dyn_cast<ObjCObjectPointerType>(parser_type))
1685 CompleteType(objc_object_ptr_type->getInterfaceDecl());
1686 }
1687
1688 bool is_reference = pt.IsReferenceType();
1689
1690 NamedDecl *var_decl = NULL;
1691 if (is_reference)
1692 var_decl = context.AddVarDecl(pt);
1693 else
1694 var_decl = context.AddVarDecl(pt.GetLValueReferenceType());
1695
1696 std::string decl_name(context.m_decl_name.getAsString());
1697 ConstString entity_name(decl_name.c_str());
1698 ClangExpressionVariable *entity(new ClangExpressionVariable(valobj));
1699 m_found_entities.AddNewlyConstructedVariable(entity);
1700
1701 assert(entity);
1702 entity->EnableParserVars(GetParserID());
1703 ClangExpressionVariable::ParserVars *parser_vars =
1704 entity->GetParserVars(GetParserID());
1705 parser_vars->m_parser_type = pt;
1706 parser_vars->m_named_decl = var_decl;
1707 parser_vars->m_llvm_value = NULL;
1708 parser_vars->m_lldb_value = var_location;
1709 parser_vars->m_lldb_var = var;
1710
1711 if (is_reference)
1712 entity->m_flags |= ClangExpressionVariable::EVTypeIsReference;
1713
1714 if (log) {
1715 ASTDumper orig_dumper(ut.GetOpaqueQualType());
1716 ASTDumper ast_dumper(var_decl);
1717 log->Printf(" CEDM::FEVD[%u] Found variable %s, returned %s (original %s)",
1718 current_id, decl_name.c_str(), ast_dumper.GetCString(),
1719 orig_dumper.GetCString());
1720 }
1721}
1722
1723void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
1724 ExpressionVariableSP &pvar_sp,
1725 unsigned int current_id) {
1726 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1727
1728 TypeFromUser user_type(
1729 llvm::cast<ClangExpressionVariable>(pvar_sp.get())->GetTypeFromUser());
1730
1731 TypeFromParser parser_type(GuardedCopyType(user_type));
1732
1733 if (!parser_type.GetOpaqueQualType()) {
1734 if (log)
1735 log->Printf(" CEDM::FEVD[%u] Couldn't import type for pvar %s",
1736 current_id, pvar_sp->GetName().GetCString());
1737 return;
1738 }
1739
1740 NamedDecl *var_decl =
1741 context.AddVarDecl(parser_type.GetLValueReferenceType());
1742
1743 llvm::cast<ClangExpressionVariable>(pvar_sp.get())
1744 ->EnableParserVars(GetParserID());
1745 ClangExpressionVariable::ParserVars *parser_vars =
1746 llvm::cast<ClangExpressionVariable>(pvar_sp.get())
1747 ->GetParserVars(GetParserID());
1748 parser_vars->m_parser_type = parser_type;
1749 parser_vars->m_named_decl = var_decl;
1750 parser_vars->m_llvm_value = NULL;
1751 parser_vars->m_lldb_value.Clear();
1752
1753 if (log) {
1754 ASTDumper ast_dumper(var_decl);
1755 log->Printf(" CEDM::FEVD[%u] Added pvar %s, returned %s", current_id,
1756 pvar_sp->GetName().GetCString(), ast_dumper.GetCString());
1757 }
1758}
1759
1760void ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context,
1761 const Symbol &symbol,
1762 unsigned int current_id) {
1763 assert(m_parser_vars.get());
1764
1765 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1766
1767 Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
1768
1769 if (target == NULL)
1770 return;
1771
1772 ASTContext *scratch_ast_context =
1773 target->GetScratchClangASTContext()->getASTContext();
1774
1775 TypeFromUser user_type(
1776 ClangASTContext::GetBasicType(scratch_ast_context, eBasicTypeVoid)
1777 .GetPointerType()
1778 .GetLValueReferenceType());
1779 TypeFromParser parser_type(
1780 ClangASTContext::GetBasicType(m_ast_context, eBasicTypeVoid)
1781 .GetPointerType()
1782 .GetLValueReferenceType());
1783 NamedDecl *var_decl = context.AddVarDecl(parser_type);
1784
1785 std::string decl_name(context.m_decl_name.getAsString());
1786 ConstString entity_name(decl_name.c_str());
1787 ClangExpressionVariable *entity(new ClangExpressionVariable(
1788 m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), entity_name,
1789 user_type, m_parser_vars->m_target_info.byte_order,
1790 m_parser_vars->m_target_info.address_byte_size));
1791 m_found_entities.AddNewlyConstructedVariable(entity);
1792
1793 entity->EnableParserVars(GetParserID());
1794 ClangExpressionVariable::ParserVars *parser_vars =
1795 entity->GetParserVars(GetParserID());
1796
1797 const Address symbol_address = symbol.GetAddress();
1798 lldb::addr_t symbol_load_addr = symbol_address.GetLoadAddress(target);
1799
1800 // parser_vars->m_lldb_value.SetContext(Value::eContextTypeClangType,
1801 // user_type.GetOpaqueQualType());
1802 parser_vars->m_lldb_value.SetCompilerType(user_type);
1803 parser_vars->m_lldb_value.GetScalar() = symbol_load_addr;
1804 parser_vars->m_lldb_value.SetValueType(Value::eValueTypeLoadAddress);
1805
1806 parser_vars->m_parser_type = parser_type;
1807 parser_vars->m_named_decl = var_decl;
1808 parser_vars->m_llvm_value = NULL;
1809 parser_vars->m_lldb_sym = &symbol;
1810
1811 if (log) {
1812 ASTDumper ast_dumper(var_decl);
1813
1814 log->Printf(" CEDM::FEVD[%u] Found variable %s, returned %s", current_id,
1815 decl_name.c_str(), ast_dumper.GetCString());
1816 }
1817}
1818
1819bool ClangExpressionDeclMap::ResolveUnknownTypes() {
1820 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1821 Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
1822
Sean Callanan68e44232017-09-28 20:20:25 +00001823 ClangASTContextForExpressions *scratch_ast_context =
1824 static_cast<ClangASTContextForExpressions*>(
1825 target->GetScratchClangASTContext());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001826
1827 for (size_t index = 0, num_entities = m_found_entities.GetSize();
1828 index < num_entities; ++index) {
1829 ExpressionVariableSP entity = m_found_entities.GetVariableAtIndex(index);
1830
1831 ClangExpressionVariable::ParserVars *parser_vars =
1832 llvm::cast<ClangExpressionVariable>(entity.get())
1833 ->GetParserVars(GetParserID());
1834
1835 if (entity->m_flags & ClangExpressionVariable::EVUnknownType) {
1836 const NamedDecl *named_decl = parser_vars->m_named_decl;
1837 const VarDecl *var_decl = dyn_cast<VarDecl>(named_decl);
1838
1839 if (!var_decl) {
Sean Callanane0a64f72011-12-01 21:04:37 +00001840 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001841 log->Printf("Entity of unknown type does not have a VarDecl");
1842 return false;
1843 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001844
Kate Stoneb9c1b512016-09-06 20:57:50 +00001845 if (log) {
1846 ASTDumper ast_dumper(const_cast<VarDecl *>(var_decl));
1847 log->Printf("Variable of unknown type now has Decl %s",
Greg Clayton64bc6ca2011-10-20 00:47:21 +00001848 ast_dumper.GetCString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001849 }
1850
1851 QualType var_type = var_decl->getType();
1852 TypeFromParser parser_type(
1853 var_type.getAsOpaquePtr(),
1854 ClangASTContext::GetASTContext(&var_decl->getASTContext()));
1855
Sean Callanan68e44232017-09-28 20:20:25 +00001856 lldb::opaque_compiler_type_t copied_type = 0;
1857 if (m_ast_importer_sp) {
1858 copied_type = m_ast_importer_sp->CopyType(
1859 scratch_ast_context->getASTContext(), &var_decl->getASTContext(),
1860 var_type.getAsOpaquePtr());
1861 } else if (HasMerger()) {
1862 copied_type = CopyTypeWithMerger(
1863 var_decl->getASTContext(),
1864 scratch_ast_context->GetMergerUnchecked(),
1865 var_type).getAsOpaquePtr();
1866 } else {
Pavel Labath9344e452017-10-17 21:52:29 +00001867 lldbassert(0 && "No mechanism to copy a resolved unknown type!");
Sean Callanan68e44232017-09-28 20:20:25 +00001868 return false;
1869 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001870
1871 if (!copied_type) {
1872 if (log)
1873 log->Printf("ClangExpressionDeclMap::ResolveUnknownType - Couldn't "
1874 "import the type for a variable");
1875
1876 return (bool)lldb::ExpressionVariableSP();
1877 }
1878
1879 TypeFromUser user_type(copied_type, scratch_ast_context);
1880
1881 // parser_vars->m_lldb_value.SetContext(Value::eContextTypeClangType,
1882 // user_type.GetOpaqueQualType());
1883 parser_vars->m_lldb_value.SetCompilerType(user_type);
1884 parser_vars->m_parser_type = parser_type;
1885
1886 entity->SetCompilerType(user_type);
1887
1888 entity->m_flags &= ~(ClangExpressionVariable::EVUnknownType);
Greg Clayton7b462cc2010-10-15 22:48:33 +00001889 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001890 }
1891
1892 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001893}
Sean Callanan5666b672010-08-04 01:02:13 +00001894
Kate Stoneb9c1b512016-09-06 20:57:50 +00001895void ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context,
1896 const RegisterInfo *reg_info,
1897 unsigned int current_id) {
1898 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001899
Kate Stoneb9c1b512016-09-06 20:57:50 +00001900 CompilerType clang_type =
1901 ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(
1902 m_ast_context, reg_info->encoding, reg_info->byte_size * 8);
Sean Callanan7736a202016-04-29 18:09:03 +00001903
Kate Stoneb9c1b512016-09-06 20:57:50 +00001904 if (!clang_type) {
1905 if (log)
1906 log->Printf(" Tried to add a type for %s, but couldn't get one",
1907 context.m_decl_name.getAsString().c_str());
1908 return;
1909 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001910
Kate Stoneb9c1b512016-09-06 20:57:50 +00001911 TypeFromParser parser_clang_type(clang_type);
Sean Callananfa4fab72013-02-01 06:55:48 +00001912
Kate Stoneb9c1b512016-09-06 20:57:50 +00001913 NamedDecl *var_decl = context.AddVarDecl(parser_clang_type);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001914
Kate Stoneb9c1b512016-09-06 20:57:50 +00001915 ClangExpressionVariable *entity(new ClangExpressionVariable(
1916 m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
1917 m_parser_vars->m_target_info.byte_order,
1918 m_parser_vars->m_target_info.address_byte_size));
1919 m_found_entities.AddNewlyConstructedVariable(entity);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001920
Kate Stoneb9c1b512016-09-06 20:57:50 +00001921 std::string decl_name(context.m_decl_name.getAsString());
1922 entity->SetName(ConstString(decl_name.c_str()));
1923 entity->SetRegisterInfo(reg_info);
1924 entity->EnableParserVars(GetParserID());
1925 ClangExpressionVariable::ParserVars *parser_vars =
1926 entity->GetParserVars(GetParserID());
1927 parser_vars->m_parser_type = parser_clang_type;
1928 parser_vars->m_named_decl = var_decl;
1929 parser_vars->m_llvm_value = NULL;
1930 parser_vars->m_lldb_value.Clear();
1931 entity->m_flags |= ClangExpressionVariable::EVBareRegister;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001932
Kate Stoneb9c1b512016-09-06 20:57:50 +00001933 if (log) {
1934 ASTDumper ast_dumper(var_decl);
1935 log->Printf(" CEDM::FEVD[%d] Added register %s, returned %s", current_id,
1936 context.m_decl_name.getAsString().c_str(),
1937 ast_dumper.GetCString());
1938 }
1939}
1940
1941void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
1942 Function *function, Symbol *symbol,
1943 unsigned int current_id) {
1944 assert(m_parser_vars.get());
1945
1946 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1947
1948 NamedDecl *function_decl = NULL;
1949 Address fun_address;
1950 CompilerType function_clang_type;
1951
1952 bool is_indirect_function = false;
1953
1954 if (function) {
1955 Type *function_type = function->GetType();
1956
Luke Drummondf5bb1d62016-12-19 17:22:44 +00001957 const auto lang = function->GetCompileUnit()->GetLanguage();
1958 const auto name = function->GetMangled().GetMangledName().AsCString();
1959 const bool extern_c = (Language::LanguageIsC(lang) &&
1960 !CPlusPlusLanguage::IsCPPMangledName(name)) ||
1961 (Language::LanguageIsObjC(lang) &&
1962 !Language::LanguageIsCPlusPlus(lang));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001963
1964 if (!extern_c) {
1965 TypeSystem *type_system = function->GetDeclContext().GetTypeSystem();
Davide Italianofe34df52017-09-30 21:16:56 +00001966 if (llvm::isa<ClangASTContext>(type_system)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001967 clang::DeclContext *src_decl_context =
1968 (clang::DeclContext *)function->GetDeclContext()
1969 .GetOpaqueDeclContext();
1970 clang::FunctionDecl *src_function_decl =
1971 llvm::dyn_cast_or_null<clang::FunctionDecl>(src_decl_context);
Sean Callanan09e91ac2017-05-11 22:08:05 +00001972 if (src_function_decl &&
1973 src_function_decl->getTemplateSpecializationInfo()) {
1974 clang::FunctionTemplateDecl *function_template =
1975 src_function_decl->getTemplateSpecializationInfo()->getTemplate();
1976 clang::FunctionTemplateDecl *copied_function_template =
1977 llvm::dyn_cast_or_null<clang::FunctionTemplateDecl>(
Sean Callanan68e44232017-09-28 20:20:25 +00001978 CopyDecl(function_template));
Sean Callanan09e91ac2017-05-11 22:08:05 +00001979 if (copied_function_template) {
1980 if (log) {
1981 ASTDumper ast_dumper((clang::Decl *)copied_function_template);
1982
1983 StreamString ss;
1984
1985 function->DumpSymbolContext(&ss);
1986
1987 log->Printf(" CEDM::FEVD[%u] Imported decl for function template"
1988 " %s (description %s), returned %s",
1989 current_id,
1990 copied_function_template->getNameAsString().c_str(),
1991 ss.GetData(), ast_dumper.GetCString());
1992 }
1993
1994 context.AddNamedDecl(copied_function_template);
1995 }
1996 } else if (src_function_decl) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001997 if (clang::FunctionDecl *copied_function_decl =
1998 llvm::dyn_cast_or_null<clang::FunctionDecl>(
Sean Callanan68e44232017-09-28 20:20:25 +00001999 CopyDecl(src_function_decl))) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002000 if (log) {
2001 ASTDumper ast_dumper((clang::Decl *)copied_function_decl);
2002
2003 StreamString ss;
2004
2005 function->DumpSymbolContext(&ss);
2006
2007 log->Printf(" CEDM::FEVD[%u] Imported decl for function %s "
2008 "(description %s), returned %s",
2009 current_id,
2010 copied_function_decl->getNameAsString().c_str(),
2011 ss.GetData(), ast_dumper.GetCString());
2012 }
2013
2014 context.AddNamedDecl(copied_function_decl);
2015 return;
2016 } else {
2017 if (log) {
2018 log->Printf(" Failed to import the function decl for '%s'",
2019 src_function_decl->getName().str().c_str());
2020 }
2021 }
Sean Callanan7736a202016-04-29 18:09:03 +00002022 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002023 }
Sean Callananfc55f5d2010-09-21 00:44:12 +00002024 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00002025
Kate Stoneb9c1b512016-09-06 20:57:50 +00002026 if (!function_type) {
2027 if (log)
2028 log->PutCString(" Skipped a function because it has no type");
2029 return;
2030 }
2031
2032 function_clang_type = function_type->GetFullCompilerType();
2033
2034 if (!function_clang_type) {
2035 if (log)
2036 log->PutCString(" Skipped a function because it has no Clang type");
2037 return;
2038 }
2039
2040 fun_address = function->GetAddressRange().GetBaseAddress();
2041
2042 CompilerType copied_function_type = GuardedCopyType(function_clang_type);
2043 if (copied_function_type) {
2044 function_decl = context.AddFunDecl(copied_function_type, extern_c);
2045
2046 if (!function_decl) {
2047 if (log) {
2048 log->Printf(
2049 " Failed to create a function decl for '%s' {0x%8.8" PRIx64 "}",
2050 function_type->GetName().GetCString(), function_type->GetID());
2051 }
2052
Sean Callanan3b436d22015-10-23 21:45:02 +00002053 return;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002054 }
2055 } else {
2056 // We failed to copy the type we found
2057 if (log) {
2058 log->Printf(" Failed to import the function type '%s' {0x%8.8" PRIx64
2059 "} into the expression parser AST contenxt",
2060 function_type->GetName().GetCString(),
2061 function_type->GetID());
2062 }
2063
2064 return;
2065 }
2066 } else if (symbol) {
2067 fun_address = symbol->GetAddress();
2068 function_decl = context.AddGenericFunDecl();
2069 is_indirect_function = symbol->IsIndirect();
2070 } else {
2071 if (log)
2072 log->PutCString(" AddOneFunction called with no function and no symbol");
2073 return;
2074 }
2075
2076 Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
2077
2078 lldb::addr_t load_addr =
2079 fun_address.GetCallableLoadAddress(target, is_indirect_function);
2080
2081 ClangExpressionVariable *entity(new ClangExpressionVariable(
2082 m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
2083 m_parser_vars->m_target_info.byte_order,
2084 m_parser_vars->m_target_info.address_byte_size));
2085 m_found_entities.AddNewlyConstructedVariable(entity);
2086
2087 std::string decl_name(context.m_decl_name.getAsString());
2088 entity->SetName(ConstString(decl_name.c_str()));
2089 entity->SetCompilerType(function_clang_type);
2090 entity->EnableParserVars(GetParserID());
2091
2092 ClangExpressionVariable::ParserVars *parser_vars =
2093 entity->GetParserVars(GetParserID());
2094
2095 if (load_addr != LLDB_INVALID_ADDRESS) {
2096 parser_vars->m_lldb_value.SetValueType(Value::eValueTypeLoadAddress);
2097 parser_vars->m_lldb_value.GetScalar() = load_addr;
2098 } else {
2099 // We have to try finding a file address.
2100
2101 lldb::addr_t file_addr = fun_address.GetFileAddress();
2102
2103 parser_vars->m_lldb_value.SetValueType(Value::eValueTypeFileAddress);
2104 parser_vars->m_lldb_value.GetScalar() = file_addr;
2105 }
2106
2107 parser_vars->m_named_decl = function_decl;
2108 parser_vars->m_llvm_value = NULL;
2109
2110 if (log) {
Pavel Labath03a77e92018-03-21 11:10:57 +00002111 std::string function_str =
2112 function_decl ? ASTDumper(function_decl).GetCString() : "nullptr";
Kate Stoneb9c1b512016-09-06 20:57:50 +00002113
2114 StreamString ss;
2115
2116 fun_address.Dump(&ss,
2117 m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
2118 Address::DumpStyleResolvedDescription);
2119
2120 log->Printf(
2121 " CEDM::FEVD[%u] Found %s function %s (description %s), returned %s",
2122 current_id, (function ? "specific" : "generic"), decl_name.c_str(),
Pavel Labath03a77e92018-03-21 11:10:57 +00002123 ss.GetData(), function_str.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002124 }
2125}
2126
2127void ClangExpressionDeclMap::AddThisType(NameSearchContext &context,
2128 TypeFromUser &ut,
2129 unsigned int current_id) {
2130 CompilerType copied_clang_type = GuardedCopyType(ut);
2131
2132 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
2133
2134 if (!copied_clang_type) {
2135 if (log)
2136 log->Printf(
2137 "ClangExpressionDeclMap::AddThisType - Couldn't import the type");
Sean Callanan3b436d22015-10-23 21:45:02 +00002138
2139 return;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002140 }
2141
2142 if (copied_clang_type.IsAggregateType() &&
2143 copied_clang_type.GetCompleteType()) {
2144 CompilerType void_clang_type =
2145 ClangASTContext::GetBasicType(m_ast_context, eBasicTypeVoid);
2146 CompilerType void_ptr_clang_type = void_clang_type.GetPointerType();
2147
2148 CompilerType method_type = ClangASTContext::CreateFunctionType(
2149 m_ast_context, void_clang_type, &void_ptr_clang_type, 1, false, 0);
2150
2151 const bool is_virtual = false;
2152 const bool is_static = false;
2153 const bool is_inline = false;
2154 const bool is_explicit = false;
2155 const bool is_attr_used = true;
2156 const bool is_artificial = false;
2157
2158 CXXMethodDecl *method_decl =
2159 ClangASTContext::GetASTContext(m_ast_context)
2160 ->AddMethodToCXXRecordType(
Davide Italiano675767a2018-03-27 19:40:50 +00002161 copied_clang_type.GetOpaqueQualType(), "$__lldb_expr", NULL,
Kate Stoneb9c1b512016-09-06 20:57:50 +00002162 method_type, lldb::eAccessPublic, is_virtual, is_static,
2163 is_inline, is_explicit, is_attr_used, is_artificial);
2164
2165 if (log) {
2166 ASTDumper method_ast_dumper((clang::Decl *)method_decl);
2167 ASTDumper type_ast_dumper(copied_clang_type);
2168
2169 log->Printf(" CEDM::AddThisType Added function $__lldb_expr "
2170 "(description %s) for this type %s",
2171 method_ast_dumper.GetCString(), type_ast_dumper.GetCString());
2172 }
2173 }
2174
2175 if (!copied_clang_type.IsValid())
2176 return;
2177
2178 TypeSourceInfo *type_source_info = m_ast_context->getTrivialTypeSourceInfo(
2179 QualType::getFromOpaquePtr(copied_clang_type.GetOpaqueQualType()));
2180
2181 if (!type_source_info)
2182 return;
2183
2184 // Construct a typedef type because if "*this" is a templated type we can't
2185 // just return ClassTemplateSpecializationDecls in response to name queries.
2186 // Using a typedef makes this much more robust.
2187
2188 TypedefDecl *typedef_decl = TypedefDecl::Create(
2189 *m_ast_context, m_ast_context->getTranslationUnitDecl(), SourceLocation(),
2190 SourceLocation(), context.m_decl_name.getAsIdentifierInfo(),
2191 type_source_info);
2192
2193 if (!typedef_decl)
2194 return;
2195
2196 context.AddNamedDecl(typedef_decl);
2197
2198 return;
Sean Callananfa4fab72013-02-01 06:55:48 +00002199}
2200
Kate Stoneb9c1b512016-09-06 20:57:50 +00002201void ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
2202 TypeFromUser &ut,
2203 unsigned int current_id) {
2204 CompilerType copied_clang_type = GuardedCopyType(ut);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00002205
Kate Stoneb9c1b512016-09-06 20:57:50 +00002206 if (!copied_clang_type) {
2207 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sean Callananfa4fab72013-02-01 06:55:48 +00002208
Kate Stoneb9c1b512016-09-06 20:57:50 +00002209 if (log)
2210 log->Printf(
2211 "ClangExpressionDeclMap::AddOneType - Couldn't import the type");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00002212
Kate Stoneb9c1b512016-09-06 20:57:50 +00002213 return;
2214 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00002215
Kate Stoneb9c1b512016-09-06 20:57:50 +00002216 context.AddTypeDecl(copied_clang_type);
Sean Callanan5666b672010-08-04 01:02:13 +00002217}