blob: 5212712b104561311fe7de63ecf5b6f7b66aa70c [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- ClangExpressionDeclMap.cpp -----------------------------*- C++ -*-===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Chris Lattner30fdc8d2010-06-08 16:52:24 +00006//
7//===----------------------------------------------------------------------===//
8
Sean Callanan4dbb2712015-09-25 20:35:58 +00009#include "ClangExpressionDeclMap.h"
10
11#include "ASTDumper.h"
12#include "ClangASTSource.h"
13#include "ClangModulesDeclVendor.h"
14#include "ClangPersistentVariables.h"
15
Chris Lattner30fdc8d2010-06-08 16:52:24 +000016#include "lldb/Core/Address.h"
17#include "lldb/Core/Module.h"
Greg Clayton9191db42013-10-21 18:40:51 +000018#include "lldb/Core/ModuleSpec.h"
Sean Callanane4ec90e2010-12-16 03:17:46 +000019#include "lldb/Core/ValueObjectConstResult.h"
Sean Callanan9b3569b2011-12-10 03:12:34 +000020#include "lldb/Core/ValueObjectVariable.h"
Sean Callanan96d27302013-04-11 00:09:05 +000021#include "lldb/Expression/Materializer.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000022#include "lldb/Symbol/ClangASTContext.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000023#include "lldb/Symbol/CompileUnit.h"
Paul Hermand628cbb2015-09-15 23:44:17 +000024#include "lldb/Symbol/CompilerDecl.h"
Greg Clayton99558cc42015-08-24 23:46:31 +000025#include "lldb/Symbol/CompilerDeclContext.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000026#include "lldb/Symbol/Function.h"
27#include "lldb/Symbol/ObjectFile.h"
28#include "lldb/Symbol/SymbolContext.h"
Siva Chandra9293fc42016-01-07 23:32:34 +000029#include "lldb/Symbol/SymbolFile.h"
Sean Callanan503aa522011-10-12 00:12:34 +000030#include "lldb/Symbol/SymbolVendor.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000031#include "lldb/Symbol/Type.h"
32#include "lldb/Symbol/TypeList.h"
33#include "lldb/Symbol/Variable.h"
34#include "lldb/Symbol/VariableList.h"
Sean Callanana0d56432014-11-11 02:49:44 +000035#include "lldb/Target/CPPLanguageRuntime.h"
Sean Callanan1d180662010-07-20 23:31:16 +000036#include "lldb/Target/ExecutionContext.h"
Sean Callanane0b23b52012-11-15 02:02:04 +000037#include "lldb/Target/ObjCLanguageRuntime.h"
Sean Callananea22d422010-07-16 00:09:46 +000038#include "lldb/Target/Process.h"
Sean Callananf4b9bd32010-10-05 20:18:48 +000039#include "lldb/Target/RegisterContext.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000040#include "lldb/Target/StackFrame.h"
Sean Callanan1d180662010-07-20 23:31:16 +000041#include "lldb/Target/Target.h"
Jim Ingham895c9822010-12-07 01:56:02 +000042#include "lldb/Target/Thread.h"
Zachary Turner01c32432017-02-14 19:06:07 +000043#include "lldb/Utility/Endian.h"
Zachary Turner6f9e6902017-03-03 20:56:28 +000044#include "lldb/Utility/Log.h"
Pavel Labathd821c992018-08-07 11:07:21 +000045#include "lldb/Utility/RegisterValue.h"
Zachary Turner97206d52017-05-12 04:51:55 +000046#include "lldb/Utility/Status.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000047#include "lldb/lldb-private.h"
48#include "clang/AST/ASTConsumer.h"
49#include "clang/AST/ASTContext.h"
Sean Callanan68e44232017-09-28 20:20:25 +000050#include "clang/AST/ASTImporter.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000051#include "clang/AST/Decl.h"
52#include "clang/AST/DeclarationName.h"
Sean Callanan68e44232017-09-28 20:20:25 +000053#include "clang/AST/RecursiveASTVisitor.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000054
Siva Chandra0f4873d2015-09-03 23:27:10 +000055#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
56
Greg Clayton83c5cd92010-11-14 22:13:40 +000057using namespace lldb;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000058using namespace lldb_private;
59using namespace clang;
60
Kate Stoneb9c1b512016-09-06 20:57:50 +000061namespace {
62const char *g_lldb_local_vars_namespace_cstr = "$__lldb_local_vars";
Siva Chandra03ff5c82016-02-05 19:10:04 +000063} // anonymous namespace
64
Kate Stoneb9c1b512016-09-06 20:57:50 +000065ClangExpressionDeclMap::ClangExpressionDeclMap(
66 bool keep_result_in_memory,
67 Materializer::PersistentVariableDelegate *result_delegate,
Krasimir Georgiev7ffc4682019-02-05 11:35:45 +000068 ExecutionContext &exe_ctx, ValueObject *ctx_obj)
Kate Stoneb9c1b512016-09-06 20:57:50 +000069 : ClangASTSource(exe_ctx.GetTargetSP()), m_found_entities(),
70 m_struct_members(), m_keep_result_in_memory(keep_result_in_memory),
Krasimir Georgiev7ffc4682019-02-05 11:35:45 +000071 m_result_delegate(result_delegate), m_ctx_obj(ctx_obj), m_parser_vars(),
72 m_struct_vars() {
Kate Stoneb9c1b512016-09-06 20:57:50 +000073 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
Jonas Devlieghere70355ac2019-02-12 03:47:39 +0000135 if (m_parser_vars) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000136 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,
Adrian Prantl0e4c4822019-03-06 21:22:25 +0000312 ConstString name,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000313 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,
Adrian Prantl0e4c4822019-03-06 21:22:25 +0000427 ConstString name,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000428 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,
Adrian Prantl0e4c4822019-03-06 21:22:25 +0000607 ConstString name,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000608 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
Adrian Prantl0e4c4822019-03-06 21:22:25 +0000705addr_t ClangExpressionDeclMap::GetSymbolAddress(ConstString name,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000706 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(
Adrian Prantl0e4c4822019-03-06 21:22:25 +0000718 Target &target, ModuleSP &module, ConstString name,
Kate Stoneb9c1b512016-09-06 20:57:50 +0000719 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) {
Aleksandr Urakov40624a02019-02-05 09:14:36 +0000931 if (m_ctx_obj) {
932 Status status;
933 lldb::ValueObjectSP ctx_obj_ptr = m_ctx_obj->AddressOf(status);
934 if (!ctx_obj_ptr || status.Fail())
935 return;
936
937 AddThisType(context, TypeFromUser(m_ctx_obj->GetCompilerType()),
938 current_id);
939
940 m_struct_vars->m_object_pointer_type =
941 TypeFromUser(ctx_obj_ptr->GetCompilerType());
942
943 return;
944 }
945
Kate Stoneb9c1b512016-09-06 20:57:50 +0000946 // Clang is looking for the type of "this"
947
948 if (frame == NULL)
949 return;
950
951 // Find the block that defines the function represented by "sym_ctx"
952 Block *function_block = sym_ctx.GetFunctionBlock();
953
954 if (!function_block)
955 return;
956
957 CompilerDeclContext function_decl_ctx = function_block->GetDeclContext();
958
959 if (!function_decl_ctx)
960 return;
961
962 clang::CXXMethodDecl *method_decl =
963 ClangASTContext::DeclContextGetAsCXXMethodDecl(function_decl_ctx);
964
965 if (method_decl) {
966 clang::CXXRecordDecl *class_decl = method_decl->getParent();
967
968 QualType class_qual_type(class_decl->getTypeForDecl(), 0);
969
970 TypeFromUser class_user_type(
971 class_qual_type.getAsOpaquePtr(),
972 ClangASTContext::GetASTContext(&class_decl->getASTContext()));
973
974 if (log) {
975 ASTDumper ast_dumper(class_qual_type);
976 log->Printf(" CEDM::FEVD[%u] Adding type for $__lldb_class: %s",
977 current_id, ast_dumper.GetCString());
Siva Chandra03ff5c82016-02-05 19:10:04 +0000978 }
979
Kate Stoneb9c1b512016-09-06 20:57:50 +0000980 AddThisType(context, class_user_type, current_id);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000981
Kate Stoneb9c1b512016-09-06 20:57:50 +0000982 if (method_decl->isInstance()) {
983 // self is a pointer to the object
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000984
Kate Stoneb9c1b512016-09-06 20:57:50 +0000985 QualType class_pointer_type =
986 method_decl->getASTContext().getPointerType(class_qual_type);
987
988 TypeFromUser self_user_type(
989 class_pointer_type.getAsOpaquePtr(),
990 ClangASTContext::GetASTContext(&method_decl->getASTContext()));
991
992 m_struct_vars->m_object_pointer_type = self_user_type;
993 }
994 } else {
Adrian Prantl05097242018-04-30 16:49:04 +0000995 // This branch will get hit if we are executing code in the context of
996 // a function that claims to have an object pointer (through
997 // DW_AT_object_pointer?) but is not formally a method of the class.
998 // In that case, just look up the "this" variable in the current scope
999 // and use its type.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001000 // FIXME: This code is formally correct, but clang doesn't currently
1001 // emit DW_AT_object_pointer
1002 // for C++ so it hasn't actually been tested.
1003
1004 VariableList *vars = frame->GetVariableList(false);
1005
1006 lldb::VariableSP this_var = vars->FindVariable(ConstString("this"));
1007
1008 if (this_var && this_var->IsInScope(frame) &&
1009 this_var->LocationIsValidForFrame(frame)) {
1010 Type *this_type = this_var->GetType();
1011
1012 if (!this_type)
Sean Callananb2269162011-10-21 22:18:07 +00001013 return;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001014
Kate Stoneb9c1b512016-09-06 20:57:50 +00001015 TypeFromUser pointee_type =
1016 this_type->GetForwardCompilerType().GetPointeeType();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001017
Kate Stoneb9c1b512016-09-06 20:57:50 +00001018 if (pointee_type.IsValid()) {
1019 if (log) {
1020 ASTDumper ast_dumper(pointee_type);
1021 log->Printf(" FEVD[%u] Adding type for $__lldb_class: %s",
1022 current_id, ast_dumper.GetCString());
1023 }
1024
1025 AddThisType(context, pointee_type, current_id);
1026 TypeFromUser this_user_type(this_type->GetFullCompilerType());
1027 m_struct_vars->m_object_pointer_type = this_user_type;
1028 return;
1029 }
Sean Callanan503aa522011-10-12 00:12:34 +00001030 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001031 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001032
Kate Stoneb9c1b512016-09-06 20:57:50 +00001033 return;
1034 }
1035
1036 static ConstString g_lldb_objc_class_name("$__lldb_objc_class");
1037 if (name == g_lldb_objc_class_name) {
Aleksandr Urakov40624a02019-02-05 09:14:36 +00001038 if (m_ctx_obj) {
1039 Status status;
1040 lldb::ValueObjectSP ctx_obj_ptr = m_ctx_obj->AddressOf(status);
1041 if (!ctx_obj_ptr || status.Fail())
1042 return;
1043
1044 AddOneType(context, TypeFromUser(m_ctx_obj->GetCompilerType()),
1045 current_id);
1046
1047 m_struct_vars->m_object_pointer_type =
1048 TypeFromUser(ctx_obj_ptr->GetCompilerType());
1049
1050 return;
1051 }
1052
Kate Stoneb9c1b512016-09-06 20:57:50 +00001053 // Clang is looking for the type of "*self"
1054
1055 if (!frame)
1056 return;
1057
1058 SymbolContext sym_ctx = frame->GetSymbolContext(
1059 lldb::eSymbolContextFunction | lldb::eSymbolContextBlock);
1060
1061 // Find the block that defines the function represented by "sym_ctx"
1062 Block *function_block = sym_ctx.GetFunctionBlock();
1063
1064 if (!function_block)
1065 return;
1066
1067 CompilerDeclContext function_decl_ctx = function_block->GetDeclContext();
1068
1069 if (!function_decl_ctx)
1070 return;
1071
1072 clang::ObjCMethodDecl *method_decl =
1073 ClangASTContext::DeclContextGetAsObjCMethodDecl(function_decl_ctx);
1074
1075 if (method_decl) {
1076 ObjCInterfaceDecl *self_interface = method_decl->getClassInterface();
1077
1078 if (!self_interface)
1079 return;
1080
1081 const clang::Type *interface_type = self_interface->getTypeForDecl();
1082
1083 if (!interface_type)
1084 return; // This is unlikely, but we have seen crashes where this
1085 // occurred
1086
1087 TypeFromUser class_user_type(
1088 QualType(interface_type, 0).getAsOpaquePtr(),
1089 ClangASTContext::GetASTContext(&method_decl->getASTContext()));
1090
1091 if (log) {
1092 ASTDumper ast_dumper(interface_type);
1093 log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s",
1094 current_id, ast_dumper.GetCString());
1095 }
1096
1097 AddOneType(context, class_user_type, current_id);
1098
1099 if (method_decl->isInstanceMethod()) {
1100 // self is a pointer to the object
1101
1102 QualType class_pointer_type =
1103 method_decl->getASTContext().getObjCObjectPointerType(
1104 QualType(interface_type, 0));
1105
1106 TypeFromUser self_user_type(
1107 class_pointer_type.getAsOpaquePtr(),
1108 ClangASTContext::GetASTContext(&method_decl->getASTContext()));
1109
1110 m_struct_vars->m_object_pointer_type = self_user_type;
1111 } else {
1112 // self is a Class pointer
1113 QualType class_type = method_decl->getASTContext().getObjCClassType();
1114
1115 TypeFromUser self_user_type(
1116 class_type.getAsOpaquePtr(),
1117 ClangASTContext::GetASTContext(&method_decl->getASTContext()));
1118
1119 m_struct_vars->m_object_pointer_type = self_user_type;
1120 }
1121
1122 return;
1123 } else {
Adrian Prantl05097242018-04-30 16:49:04 +00001124 // This branch will get hit if we are executing code in the context of
1125 // a function that claims to have an object pointer (through
1126 // DW_AT_object_pointer?) but is not formally a method of the class.
1127 // In that case, just look up the "self" variable in the current scope
1128 // and use its type.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001129
1130 VariableList *vars = frame->GetVariableList(false);
1131
1132 lldb::VariableSP self_var = vars->FindVariable(ConstString("self"));
1133
1134 if (self_var && self_var->IsInScope(frame) &&
1135 self_var->LocationIsValidForFrame(frame)) {
1136 Type *self_type = self_var->GetType();
1137
1138 if (!self_type)
1139 return;
1140
1141 CompilerType self_clang_type = self_type->GetFullCompilerType();
1142
1143 if (ClangASTContext::IsObjCClassType(self_clang_type)) {
1144 return;
1145 } else if (ClangASTContext::IsObjCObjectPointerType(
1146 self_clang_type)) {
1147 self_clang_type = self_clang_type.GetPointeeType();
1148
1149 if (!self_clang_type)
1150 return;
1151
1152 if (log) {
1153 ASTDumper ast_dumper(self_type->GetFullCompilerType());
1154 log->Printf(" FEVD[%u] Adding type for $__lldb_objc_class: %s",
1155 current_id, ast_dumper.GetCString());
1156 }
1157
1158 TypeFromUser class_user_type(self_clang_type);
1159
1160 AddOneType(context, class_user_type, current_id);
1161
1162 TypeFromUser self_user_type(self_type->GetFullCompilerType());
1163
1164 m_struct_vars->m_object_pointer_type = self_user_type;
1165 return;
1166 }
1167 }
1168 }
1169
1170 return;
1171 }
1172
1173 if (name == ConstString(g_lldb_local_vars_namespace_cstr)) {
1174 CompilerDeclContext frame_decl_context =
1175 sym_ctx.block != nullptr ? sym_ctx.block->GetDeclContext()
1176 : CompilerDeclContext();
1177
1178 if (frame_decl_context) {
1179 ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(
1180 frame_decl_context.GetTypeSystem());
1181
1182 if (ast) {
1183 clang::NamespaceDecl *namespace_decl =
1184 ClangASTContext::GetUniqueNamespaceDeclaration(
Sean Callanan1b3c43b2017-09-26 17:25:34 +00001185 m_ast_context, name.GetCString(), nullptr);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001186 if (namespace_decl) {
1187 context.AddNamedDecl(namespace_decl);
1188 clang::DeclContext *clang_decl_ctx =
1189 clang::Decl::castToDeclContext(namespace_decl);
1190 clang_decl_ctx->setHasExternalVisibleStorage(true);
1191 context.m_found.local_vars_nsp = true;
1192 }
1193 }
1194 }
1195
1196 return;
1197 }
1198
1199 // any other $__lldb names should be weeded out now
Sean Callanan1b3c43b2017-09-26 17:25:34 +00001200 if (name.GetStringRef().startswith("$__lldb"))
Kate Stoneb9c1b512016-09-06 20:57:50 +00001201 return;
1202
1203 ExpressionVariableSP pvar_sp(
1204 m_parser_vars->m_persistent_vars->GetVariable(name));
1205
1206 if (pvar_sp) {
1207 AddOneVariable(context, pvar_sp, current_id);
1208 return;
1209 }
1210
1211 const char *reg_name(&name.GetCString()[1]);
1212
1213 if (m_parser_vars->m_exe_ctx.GetRegisterContext()) {
1214 const RegisterInfo *reg_info(
1215 m_parser_vars->m_exe_ctx.GetRegisterContext()->GetRegisterInfoByName(
1216 reg_name));
1217
1218 if (reg_info) {
Sean Callanan503aa522011-10-12 00:12:34 +00001219 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001220 log->Printf(" CEDM::FEVD[%u] Found register %s", current_id,
1221 reg_info->name);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001222
Kate Stoneb9c1b512016-09-06 20:57:50 +00001223 AddOneRegister(context, reg_info, current_id);
1224 }
1225 }
1226 } else {
1227 ValueObjectSP valobj;
1228 VariableSP var;
1229
1230 bool local_var_lookup =
1231 !namespace_decl || (namespace_decl.GetName() ==
1232 ConstString(g_lldb_local_vars_namespace_cstr));
1233 if (frame && local_var_lookup) {
1234 CompilerDeclContext compiler_decl_context =
1235 sym_ctx.block != nullptr ? sym_ctx.block->GetDeclContext()
1236 : CompilerDeclContext();
1237
1238 if (compiler_decl_context) {
1239 // Make sure that the variables are parsed so that we have the
1240 // declarations.
1241 VariableListSP vars = frame->GetInScopeVariableList(true);
1242 for (size_t i = 0; i < vars->GetSize(); i++)
1243 vars->GetVariableAtIndex(i)->GetDecl();
1244
1245 // Search for declarations matching the name. Do not include imported
Adrian Prantl05097242018-04-30 16:49:04 +00001246 // decls in the search if we are looking for decls in the artificial
1247 // namespace $__lldb_local_vars.
Kate Stoneb9c1b512016-09-06 20:57:50 +00001248 std::vector<CompilerDecl> found_decls =
1249 compiler_decl_context.FindDeclByName(name,
1250 namespace_decl.IsValid());
1251
1252 bool variable_found = false;
1253 for (CompilerDecl decl : found_decls) {
1254 for (size_t vi = 0, ve = vars->GetSize(); vi != ve; ++vi) {
1255 VariableSP candidate_var = vars->GetVariableAtIndex(vi);
1256 if (candidate_var->GetDecl() == decl) {
1257 var = candidate_var;
1258 break;
1259 }
1260 }
1261
Sean Callananc02a1c02017-04-24 23:14:04 +00001262 if (var && !variable_found) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001263 variable_found = true;
1264 valobj = ValueObjectVariable::Create(frame, var);
1265 AddOneVariable(context, var, valobj, current_id);
1266 context.m_found.variable = true;
1267 }
1268 }
1269 if (variable_found)
1270 return;
1271 }
1272 }
1273 if (target) {
1274 var = FindGlobalVariable(*target, module_sp, name, &namespace_decl, NULL);
1275
1276 if (var) {
1277 valobj = ValueObjectVariable::Create(target, var);
1278 AddOneVariable(context, var, valobj, current_id);
1279 context.m_found.variable = true;
1280 return;
1281 }
Sean Callanan503aa522011-10-12 00:12:34 +00001282 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001283
Kate Stoneb9c1b512016-09-06 20:57:50 +00001284 std::vector<clang::NamedDecl *> decls_from_modules;
Sean Callanan503aa522011-10-12 00:12:34 +00001285
Kate Stoneb9c1b512016-09-06 20:57:50 +00001286 if (target) {
1287 if (ClangModulesDeclVendor *decl_vendor =
1288 target->GetClangModulesDeclVendor()) {
1289 decl_vendor->FindDecls(name, false, UINT32_MAX, decls_from_modules);
1290 }
1291 }
Sean Callananb3a36df2016-03-19 00:51:43 +00001292
Sean Callananc02a1c02017-04-24 23:14:04 +00001293 const bool include_inlines = false;
1294 const bool append = false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001295
Sean Callananc02a1c02017-04-24 23:14:04 +00001296 if (namespace_decl && module_sp) {
1297 const bool include_symbols = false;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001298
Sean Callananc02a1c02017-04-24 23:14:04 +00001299 module_sp->FindFunctions(name, &namespace_decl, eFunctionNameTypeBase,
1300 include_symbols, include_inlines, append,
1301 sc_list);
1302 } else if (target && !namespace_decl) {
1303 const bool include_symbols = true;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001304
Sean Callananc02a1c02017-04-24 23:14:04 +00001305 // TODO Fix FindFunctions so that it doesn't return
1306 // instance methods for eFunctionNameTypeBase.
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001307
Sean Callananc02a1c02017-04-24 23:14:04 +00001308 target->GetImages().FindFunctions(name, eFunctionNameTypeFull,
1309 include_symbols, include_inlines,
1310 append, sc_list);
1311 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001312
Adrian Prantl05097242018-04-30 16:49:04 +00001313 // If we found more than one function, see if we can use the frame's decl
1314 // context to remove functions that are shadowed by other functions which
1315 // match in type but are nearer in scope.
Sean Callananc02a1c02017-04-24 23:14:04 +00001316 //
1317 // AddOneFunction will not add a function whose type has already been
Adrian Prantl05097242018-04-30 16:49:04 +00001318 // added, so if there's another function in the list with a matching type,
1319 // check to see if their decl context is a parent of the current frame's or
1320 // was imported via a and using statement, and pick the best match
1321 // according to lookup rules.
Sean Callananc02a1c02017-04-24 23:14:04 +00001322 if (sc_list.GetSize() > 1) {
1323 // Collect some info about our frame's context.
1324 StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
1325 SymbolContext frame_sym_ctx;
1326 if (frame != nullptr)
1327 frame_sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
1328 lldb::eSymbolContextBlock);
1329 CompilerDeclContext frame_decl_context =
1330 frame_sym_ctx.block != nullptr ? frame_sym_ctx.block->GetDeclContext()
1331 : CompilerDeclContext();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001332
Sean Callananc02a1c02017-04-24 23:14:04 +00001333 // We can't do this without a compiler decl context for our frame.
1334 if (frame_decl_context) {
1335 clang::DeclContext *frame_decl_ctx =
1336 (clang::DeclContext *)frame_decl_context.GetOpaqueDeclContext();
1337 ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(
1338 frame_decl_context.GetTypeSystem());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001339
Sean Callananc02a1c02017-04-24 23:14:04 +00001340 // Structure to hold the info needed when comparing function
1341 // declarations.
1342 struct FuncDeclInfo {
1343 ConstString m_name;
1344 CompilerType m_copied_type;
1345 uint32_t m_decl_lvl;
1346 SymbolContext m_sym_ctx;
1347 };
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001348
Adrian Prantl05097242018-04-30 16:49:04 +00001349 // First, symplify things by looping through the symbol contexts to
1350 // remove unwanted functions and separate out the functions we want to
1351 // compare and prune into a separate list. Cache the info needed about
1352 // the function declarations in a vector for efficiency.
Sean Callananc02a1c02017-04-24 23:14:04 +00001353 SymbolContextList sc_sym_list;
1354 uint32_t num_indices = sc_list.GetSize();
1355 std::vector<FuncDeclInfo> fdi_cache;
1356 fdi_cache.reserve(num_indices);
1357 for (uint32_t index = 0; index < num_indices; ++index) {
1358 FuncDeclInfo fdi;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001359 SymbolContext sym_ctx;
1360 sc_list.GetContextAtIndex(index, sym_ctx);
1361
Adrian Prantl05097242018-04-30 16:49:04 +00001362 // We don't know enough about symbols to compare them, but we should
1363 // keep them in the list.
Sean Callananc02a1c02017-04-24 23:14:04 +00001364 Function *function = sym_ctx.function;
1365 if (!function) {
1366 sc_sym_list.Append(sym_ctx);
1367 continue;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001368 }
Sean Callananc02a1c02017-04-24 23:14:04 +00001369 // Filter out functions without declaration contexts, as well as
Adrian Prantl05097242018-04-30 16:49:04 +00001370 // class/instance methods, since they'll be skipped in the code that
1371 // follows anyway.
Sean Callananc02a1c02017-04-24 23:14:04 +00001372 CompilerDeclContext func_decl_context = function->GetDeclContext();
1373 if (!func_decl_context ||
1374 func_decl_context.IsClassMethod(nullptr, nullptr, nullptr))
1375 continue;
1376 // We can only prune functions for which we can copy the type.
1377 CompilerType func_clang_type =
1378 function->GetType()->GetFullCompilerType();
1379 CompilerType copied_func_type = GuardedCopyType(func_clang_type);
1380 if (!copied_func_type) {
1381 sc_sym_list.Append(sym_ctx);
1382 continue;
1383 }
1384
1385 fdi.m_sym_ctx = sym_ctx;
1386 fdi.m_name = function->GetName();
1387 fdi.m_copied_type = copied_func_type;
1388 fdi.m_decl_lvl = LLDB_INVALID_DECL_LEVEL;
1389 if (fdi.m_copied_type && func_decl_context) {
Adrian Prantl05097242018-04-30 16:49:04 +00001390 // Call CountDeclLevels to get the number of parent scopes we have
1391 // to look through before we find the function declaration. When
1392 // comparing functions of the same type, the one with a lower count
1393 // will be closer to us in the lookup scope and shadows the other.
Sean Callananc02a1c02017-04-24 23:14:04 +00001394 clang::DeclContext *func_decl_ctx =
1395 (clang::DeclContext *)func_decl_context.GetOpaqueDeclContext();
1396 fdi.m_decl_lvl = ast->CountDeclLevels(
1397 frame_decl_ctx, func_decl_ctx, &fdi.m_name, &fdi.m_copied_type);
1398 }
1399 fdi_cache.emplace_back(fdi);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001400 }
1401
Sean Callananc02a1c02017-04-24 23:14:04 +00001402 // Loop through the functions in our cache looking for matching types,
1403 // then compare their scope levels to see which is closer.
1404 std::multimap<CompilerType, const FuncDeclInfo *> matches;
1405 for (const FuncDeclInfo &fdi : fdi_cache) {
1406 const CompilerType t = fdi.m_copied_type;
1407 auto q = matches.find(t);
1408 if (q != matches.end()) {
1409 if (q->second->m_decl_lvl > fdi.m_decl_lvl)
1410 // This function is closer; remove the old set.
1411 matches.erase(t);
1412 else if (q->second->m_decl_lvl < fdi.m_decl_lvl)
1413 // The functions in our set are closer - skip this one.
1414 continue;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001415 }
Sean Callananc02a1c02017-04-24 23:14:04 +00001416 matches.insert(std::make_pair(t, &fdi));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001417 }
1418
Sean Callananc02a1c02017-04-24 23:14:04 +00001419 // Loop through our matches and add their symbol contexts to our list.
1420 SymbolContextList sc_func_list;
1421 for (const auto &q : matches)
1422 sc_func_list.Append(q.second->m_sym_ctx);
1423
1424 // Rejoin the lists with the functions in front.
1425 sc_list = sc_func_list;
1426 sc_list.Append(sc_sym_list);
1427 }
1428 }
1429
1430 if (sc_list.GetSize()) {
1431 Symbol *extern_symbol = NULL;
1432 Symbol *non_extern_symbol = NULL;
1433
1434 for (uint32_t index = 0, num_indices = sc_list.GetSize();
1435 index < num_indices; ++index) {
1436 SymbolContext sym_ctx;
1437 sc_list.GetContextAtIndex(index, sym_ctx);
1438
1439 if (sym_ctx.function) {
1440 CompilerDeclContext decl_ctx = sym_ctx.function->GetDeclContext();
1441
1442 if (!decl_ctx)
1443 continue;
1444
1445 // Filter out class/instance methods.
1446 if (decl_ctx.IsClassMethod(nullptr, nullptr, nullptr))
1447 continue;
1448
1449 AddOneFunction(context, sym_ctx.function, NULL, current_id);
1450 context.m_found.function_with_type_info = true;
1451 context.m_found.function = true;
1452 } else if (sym_ctx.symbol) {
1453 if (sym_ctx.symbol->GetType() == eSymbolTypeReExported && target) {
1454 sym_ctx.symbol = sym_ctx.symbol->ResolveReExportedSymbol(*target);
1455 if (sym_ctx.symbol == NULL)
1456 continue;
1457 }
1458
1459 if (sym_ctx.symbol->IsExternal())
1460 extern_symbol = sym_ctx.symbol;
1461 else
1462 non_extern_symbol = sym_ctx.symbol;
1463 }
1464 }
1465
1466 if (!context.m_found.function_with_type_info) {
1467 for (clang::NamedDecl *decl : decls_from_modules) {
1468 if (llvm::isa<clang::FunctionDecl>(decl)) {
1469 clang::NamedDecl *copied_decl =
Sean Callanan68e44232017-09-28 20:20:25 +00001470 llvm::cast_or_null<FunctionDecl>(CopyDecl(decl));
Sean Callananc02a1c02017-04-24 23:14:04 +00001471 if (copied_decl) {
1472 context.AddNamedDecl(copied_decl);
1473 context.m_found.function_with_type_info = true;
1474 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001475 }
1476 }
1477 }
1478
1479 if (!context.m_found.function_with_type_info) {
Sean Callananc02a1c02017-04-24 23:14:04 +00001480 if (extern_symbol) {
1481 AddOneFunction(context, NULL, extern_symbol, current_id);
1482 context.m_found.function = true;
1483 } else if (non_extern_symbol) {
1484 AddOneFunction(context, NULL, non_extern_symbol, current_id);
1485 context.m_found.function = true;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001486 }
1487 }
Sean Callananb3a36df2016-03-19 00:51:43 +00001488 }
Sean Callananc02a1c02017-04-24 23:14:04 +00001489
1490 if (!context.m_found.function_with_type_info) {
1491 // Try the modules next.
1492
1493 do {
1494 if (ClangModulesDeclVendor *modules_decl_vendor =
1495 m_target->GetClangModulesDeclVendor()) {
1496 bool append = false;
1497 uint32_t max_matches = 1;
1498 std::vector<clang::NamedDecl *> decls;
1499
1500 if (!modules_decl_vendor->FindDecls(name, append, max_matches, decls))
1501 break;
1502
1503 clang::NamedDecl *const decl_from_modules = decls[0];
1504
1505 if (llvm::isa<clang::FunctionDecl>(decl_from_modules)) {
1506 if (log) {
1507 log->Printf(" CAS::FEVD[%u] Matching function found for "
1508 "\"%s\" in the modules",
1509 current_id, name.GetCString());
1510 }
1511
Sean Callanan68e44232017-09-28 20:20:25 +00001512 clang::Decl *copied_decl = CopyDecl(decl_from_modules);
Sean Callananc02a1c02017-04-24 23:14:04 +00001513 clang::FunctionDecl *copied_function_decl =
1514 copied_decl ? dyn_cast<clang::FunctionDecl>(copied_decl)
1515 : nullptr;
1516
1517 if (!copied_function_decl) {
1518 if (log)
1519 log->Printf(" CAS::FEVD[%u] - Couldn't export a function "
1520 "declaration from the modules",
1521 current_id);
1522
1523 break;
1524 }
1525
1526 MaybeRegisterFunctionBody(copied_function_decl);
1527
1528 context.AddNamedDecl(copied_function_decl);
1529
1530 context.m_found.function_with_type_info = true;
1531 context.m_found.function = true;
1532 } else if (llvm::isa<clang::VarDecl>(decl_from_modules)) {
1533 if (log) {
1534 log->Printf(" CAS::FEVD[%u] Matching variable found for "
1535 "\"%s\" in the modules",
1536 current_id, name.GetCString());
1537 }
1538
Sean Callanan68e44232017-09-28 20:20:25 +00001539 clang::Decl *copied_decl = CopyDecl(decl_from_modules);
Sean Callananc02a1c02017-04-24 23:14:04 +00001540 clang::VarDecl *copied_var_decl =
1541 copied_decl ? dyn_cast_or_null<clang::VarDecl>(copied_decl)
1542 : nullptr;
1543
1544 if (!copied_var_decl) {
1545 if (log)
1546 log->Printf(" CAS::FEVD[%u] - Couldn't export a variable "
1547 "declaration from the modules",
1548 current_id);
1549
1550 break;
1551 }
1552
1553 context.AddNamedDecl(copied_var_decl);
1554
1555 context.m_found.variable = true;
1556 }
1557 }
1558 } while (0);
1559 }
1560
1561 if (target && !context.m_found.variable && !namespace_decl) {
Adrian Prantl05097242018-04-30 16:49:04 +00001562 // We couldn't find a non-symbol variable for this. Now we'll hunt for a
1563 // generic data symbol, and -- if it is found -- treat it as a variable.
Sean Callanan9c99faa2017-05-16 23:46:13 +00001564 Status error;
Stephane Sezer30fa7e22017-10-24 22:56:05 +00001565
Sean Callanan9c99faa2017-05-16 23:46:13 +00001566 const Symbol *data_symbol =
1567 m_parser_vars->m_sym_ctx.FindBestGlobalDataSymbol(name, error);
Stephane Sezer30fa7e22017-10-24 22:56:05 +00001568
Sean Callanan9c99faa2017-05-16 23:46:13 +00001569 if (!error.Success()) {
1570 const unsigned diag_id =
1571 m_ast_context->getDiagnostics().getCustomDiagID(
1572 clang::DiagnosticsEngine::Level::Error, "%0");
1573 m_ast_context->getDiagnostics().Report(diag_id) << error.AsCString();
1574 }
Stephane Sezer30fa7e22017-10-24 22:56:05 +00001575
Sean Callananc02a1c02017-04-24 23:14:04 +00001576 if (data_symbol) {
1577 std::string warning("got name from symbols: ");
1578 warning.append(name.AsCString());
1579 const unsigned diag_id =
1580 m_ast_context->getDiagnostics().getCustomDiagID(
1581 clang::DiagnosticsEngine::Level::Warning, "%0");
1582 m_ast_context->getDiagnostics().Report(diag_id) << warning.c_str();
1583 AddOneGenericVariable(context, *data_symbol, current_id);
1584 context.m_found.variable = true;
1585 }
1586 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001587 }
Sean Callanan6b4067c2010-07-17 00:43:37 +00001588}
Greg Claytona2721472011-06-25 00:44:06 +00001589
Kate Stoneb9c1b512016-09-06 20:57:50 +00001590bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var,
1591 lldb_private::Value &var_location,
1592 TypeFromUser *user_type,
1593 TypeFromParser *parser_type) {
1594 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001595
Kate Stoneb9c1b512016-09-06 20:57:50 +00001596 Type *var_type = var->GetType();
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001597
Kate Stoneb9c1b512016-09-06 20:57:50 +00001598 if (!var_type) {
Sean Callananea22d422010-07-16 00:09:46 +00001599 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001600 log->PutCString("Skipped a definition because it has no type");
1601 return false;
1602 }
1603
1604 CompilerType var_clang_type = var_type->GetFullCompilerType();
1605
1606 if (!var_clang_type) {
1607 if (log)
1608 log->PutCString("Skipped a definition because it has no Clang type");
1609 return false;
1610 }
1611
1612 ClangASTContext *clang_ast = llvm::dyn_cast_or_null<ClangASTContext>(
1613 var_type->GetForwardCompilerType().GetTypeSystem());
1614
1615 if (!clang_ast) {
1616 if (log)
1617 log->PutCString("Skipped a definition because it has no Clang AST");
1618 return false;
1619 }
1620
1621 ASTContext *ast = clang_ast->getASTContext();
1622
1623 if (!ast) {
1624 if (log)
1625 log->PutCString(
1626 "There is no AST context for the current execution context");
1627 return false;
1628 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001629
1630 DWARFExpression &var_location_expr = var->LocationExpression();
1631
1632 Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
Zachary Turner97206d52017-05-12 04:51:55 +00001633 Status err;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001634
1635 if (var->GetLocationIsConstantValueData()) {
1636 DataExtractor const_value_extractor;
1637
1638 if (var_location_expr.GetExpressionData(const_value_extractor)) {
1639 var_location = Value(const_value_extractor.GetDataStart(),
1640 const_value_extractor.GetByteSize());
1641 var_location.SetValueType(Value::eValueTypeHostAddress);
1642 } else {
1643 if (log)
1644 log->Printf("Error evaluating constant variable: %s", err.AsCString());
1645 return false;
Greg Clayton7b462cc2010-10-15 22:48:33 +00001646 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001647 }
1648
1649 CompilerType type_to_use = GuardedCopyType(var_clang_type);
1650
1651 if (!type_to_use) {
1652 if (log)
1653 log->Printf(
1654 "Couldn't copy a variable's type into the parser's AST context");
1655
1656 return false;
1657 }
1658
1659 if (parser_type)
1660 *parser_type = TypeFromParser(type_to_use);
1661
1662 if (var_location.GetContextType() == Value::eContextTypeInvalid)
1663 var_location.SetCompilerType(type_to_use);
1664
1665 if (var_location.GetValueType() == Value::eValueTypeFileAddress) {
1666 SymbolContext var_sc;
1667 var->CalculateSymbolContext(&var_sc);
1668
1669 if (!var_sc.module_sp)
1670 return false;
1671
1672 Address so_addr(var_location.GetScalar().ULongLong(),
1673 var_sc.module_sp->GetSectionList());
1674
1675 lldb::addr_t load_addr = so_addr.GetLoadAddress(target);
1676
1677 if (load_addr != LLDB_INVALID_ADDRESS) {
1678 var_location.GetScalar() = load_addr;
1679 var_location.SetValueType(Value::eValueTypeLoadAddress);
1680 }
1681 }
1682
1683 if (user_type)
1684 *user_type = TypeFromUser(var_clang_type);
1685
1686 return true;
Sean Callanan468574b2010-06-22 23:46:24 +00001687}
1688
Kate Stoneb9c1b512016-09-06 20:57:50 +00001689void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
1690 VariableSP var,
1691 ValueObjectSP valobj,
1692 unsigned int current_id) {
1693 assert(m_parser_vars.get());
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001694
Kate Stoneb9c1b512016-09-06 20:57:50 +00001695 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001696
Kate Stoneb9c1b512016-09-06 20:57:50 +00001697 TypeFromUser ut;
1698 TypeFromParser pt;
1699 Value var_location;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001700
Kate Stoneb9c1b512016-09-06 20:57:50 +00001701 if (!GetVariableValue(var, var_location, &ut, &pt))
1702 return;
1703
1704 clang::QualType parser_opaque_type =
1705 QualType::getFromOpaquePtr(pt.GetOpaqueQualType());
1706
1707 if (parser_opaque_type.isNull())
1708 return;
1709
1710 if (const clang::Type *parser_type = parser_opaque_type.getTypePtr()) {
1711 if (const TagType *tag_type = dyn_cast<TagType>(parser_type))
1712 CompleteType(tag_type->getDecl());
1713 if (const ObjCObjectPointerType *objc_object_ptr_type =
1714 dyn_cast<ObjCObjectPointerType>(parser_type))
1715 CompleteType(objc_object_ptr_type->getInterfaceDecl());
1716 }
1717
1718 bool is_reference = pt.IsReferenceType();
1719
1720 NamedDecl *var_decl = NULL;
1721 if (is_reference)
1722 var_decl = context.AddVarDecl(pt);
1723 else
1724 var_decl = context.AddVarDecl(pt.GetLValueReferenceType());
1725
1726 std::string decl_name(context.m_decl_name.getAsString());
1727 ConstString entity_name(decl_name.c_str());
1728 ClangExpressionVariable *entity(new ClangExpressionVariable(valobj));
1729 m_found_entities.AddNewlyConstructedVariable(entity);
1730
1731 assert(entity);
1732 entity->EnableParserVars(GetParserID());
1733 ClangExpressionVariable::ParserVars *parser_vars =
1734 entity->GetParserVars(GetParserID());
1735 parser_vars->m_parser_type = pt;
1736 parser_vars->m_named_decl = var_decl;
1737 parser_vars->m_llvm_value = NULL;
1738 parser_vars->m_lldb_value = var_location;
1739 parser_vars->m_lldb_var = var;
1740
1741 if (is_reference)
1742 entity->m_flags |= ClangExpressionVariable::EVTypeIsReference;
1743
1744 if (log) {
1745 ASTDumper orig_dumper(ut.GetOpaqueQualType());
1746 ASTDumper ast_dumper(var_decl);
1747 log->Printf(" CEDM::FEVD[%u] Found variable %s, returned %s (original %s)",
1748 current_id, decl_name.c_str(), ast_dumper.GetCString(),
1749 orig_dumper.GetCString());
1750 }
1751}
1752
1753void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,
1754 ExpressionVariableSP &pvar_sp,
1755 unsigned int current_id) {
1756 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1757
1758 TypeFromUser user_type(
1759 llvm::cast<ClangExpressionVariable>(pvar_sp.get())->GetTypeFromUser());
1760
1761 TypeFromParser parser_type(GuardedCopyType(user_type));
1762
1763 if (!parser_type.GetOpaqueQualType()) {
1764 if (log)
1765 log->Printf(" CEDM::FEVD[%u] Couldn't import type for pvar %s",
1766 current_id, pvar_sp->GetName().GetCString());
1767 return;
1768 }
1769
1770 NamedDecl *var_decl =
1771 context.AddVarDecl(parser_type.GetLValueReferenceType());
1772
1773 llvm::cast<ClangExpressionVariable>(pvar_sp.get())
1774 ->EnableParserVars(GetParserID());
1775 ClangExpressionVariable::ParserVars *parser_vars =
1776 llvm::cast<ClangExpressionVariable>(pvar_sp.get())
1777 ->GetParserVars(GetParserID());
1778 parser_vars->m_parser_type = parser_type;
1779 parser_vars->m_named_decl = var_decl;
1780 parser_vars->m_llvm_value = NULL;
1781 parser_vars->m_lldb_value.Clear();
1782
1783 if (log) {
1784 ASTDumper ast_dumper(var_decl);
1785 log->Printf(" CEDM::FEVD[%u] Added pvar %s, returned %s", current_id,
1786 pvar_sp->GetName().GetCString(), ast_dumper.GetCString());
1787 }
1788}
1789
1790void ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context,
1791 const Symbol &symbol,
1792 unsigned int current_id) {
1793 assert(m_parser_vars.get());
1794
1795 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1796
1797 Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
1798
1799 if (target == NULL)
1800 return;
1801
1802 ASTContext *scratch_ast_context =
1803 target->GetScratchClangASTContext()->getASTContext();
1804
1805 TypeFromUser user_type(
1806 ClangASTContext::GetBasicType(scratch_ast_context, eBasicTypeVoid)
1807 .GetPointerType()
1808 .GetLValueReferenceType());
1809 TypeFromParser parser_type(
1810 ClangASTContext::GetBasicType(m_ast_context, eBasicTypeVoid)
1811 .GetPointerType()
1812 .GetLValueReferenceType());
1813 NamedDecl *var_decl = context.AddVarDecl(parser_type);
1814
1815 std::string decl_name(context.m_decl_name.getAsString());
1816 ConstString entity_name(decl_name.c_str());
1817 ClangExpressionVariable *entity(new ClangExpressionVariable(
1818 m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), entity_name,
1819 user_type, m_parser_vars->m_target_info.byte_order,
1820 m_parser_vars->m_target_info.address_byte_size));
1821 m_found_entities.AddNewlyConstructedVariable(entity);
1822
1823 entity->EnableParserVars(GetParserID());
1824 ClangExpressionVariable::ParserVars *parser_vars =
1825 entity->GetParserVars(GetParserID());
1826
1827 const Address symbol_address = symbol.GetAddress();
1828 lldb::addr_t symbol_load_addr = symbol_address.GetLoadAddress(target);
1829
1830 // parser_vars->m_lldb_value.SetContext(Value::eContextTypeClangType,
1831 // user_type.GetOpaqueQualType());
1832 parser_vars->m_lldb_value.SetCompilerType(user_type);
1833 parser_vars->m_lldb_value.GetScalar() = symbol_load_addr;
1834 parser_vars->m_lldb_value.SetValueType(Value::eValueTypeLoadAddress);
1835
1836 parser_vars->m_parser_type = parser_type;
1837 parser_vars->m_named_decl = var_decl;
1838 parser_vars->m_llvm_value = NULL;
1839 parser_vars->m_lldb_sym = &symbol;
1840
1841 if (log) {
1842 ASTDumper ast_dumper(var_decl);
1843
1844 log->Printf(" CEDM::FEVD[%u] Found variable %s, returned %s", current_id,
1845 decl_name.c_str(), ast_dumper.GetCString());
1846 }
1847}
1848
1849bool ClangExpressionDeclMap::ResolveUnknownTypes() {
1850 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1851 Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
1852
Sean Callanan68e44232017-09-28 20:20:25 +00001853 ClangASTContextForExpressions *scratch_ast_context =
1854 static_cast<ClangASTContextForExpressions*>(
1855 target->GetScratchClangASTContext());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001856
1857 for (size_t index = 0, num_entities = m_found_entities.GetSize();
1858 index < num_entities; ++index) {
1859 ExpressionVariableSP entity = m_found_entities.GetVariableAtIndex(index);
1860
1861 ClangExpressionVariable::ParserVars *parser_vars =
1862 llvm::cast<ClangExpressionVariable>(entity.get())
1863 ->GetParserVars(GetParserID());
1864
1865 if (entity->m_flags & ClangExpressionVariable::EVUnknownType) {
1866 const NamedDecl *named_decl = parser_vars->m_named_decl;
1867 const VarDecl *var_decl = dyn_cast<VarDecl>(named_decl);
1868
1869 if (!var_decl) {
Sean Callanane0a64f72011-12-01 21:04:37 +00001870 if (log)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001871 log->Printf("Entity of unknown type does not have a VarDecl");
1872 return false;
1873 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001874
Kate Stoneb9c1b512016-09-06 20:57:50 +00001875 if (log) {
1876 ASTDumper ast_dumper(const_cast<VarDecl *>(var_decl));
1877 log->Printf("Variable of unknown type now has Decl %s",
Greg Clayton64bc6ca2011-10-20 00:47:21 +00001878 ast_dumper.GetCString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001879 }
1880
1881 QualType var_type = var_decl->getType();
1882 TypeFromParser parser_type(
1883 var_type.getAsOpaquePtr(),
1884 ClangASTContext::GetASTContext(&var_decl->getASTContext()));
1885
Sean Callanan68e44232017-09-28 20:20:25 +00001886 lldb::opaque_compiler_type_t copied_type = 0;
1887 if (m_ast_importer_sp) {
1888 copied_type = m_ast_importer_sp->CopyType(
1889 scratch_ast_context->getASTContext(), &var_decl->getASTContext(),
1890 var_type.getAsOpaquePtr());
1891 } else if (HasMerger()) {
1892 copied_type = CopyTypeWithMerger(
1893 var_decl->getASTContext(),
1894 scratch_ast_context->GetMergerUnchecked(),
1895 var_type).getAsOpaquePtr();
1896 } else {
Pavel Labath9344e452017-10-17 21:52:29 +00001897 lldbassert(0 && "No mechanism to copy a resolved unknown type!");
Sean Callanan68e44232017-09-28 20:20:25 +00001898 return false;
1899 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001900
1901 if (!copied_type) {
1902 if (log)
1903 log->Printf("ClangExpressionDeclMap::ResolveUnknownType - Couldn't "
1904 "import the type for a variable");
1905
1906 return (bool)lldb::ExpressionVariableSP();
1907 }
1908
1909 TypeFromUser user_type(copied_type, scratch_ast_context);
1910
1911 // parser_vars->m_lldb_value.SetContext(Value::eContextTypeClangType,
1912 // user_type.GetOpaqueQualType());
1913 parser_vars->m_lldb_value.SetCompilerType(user_type);
1914 parser_vars->m_parser_type = parser_type;
1915
1916 entity->SetCompilerType(user_type);
1917
1918 entity->m_flags &= ~(ClangExpressionVariable::EVUnknownType);
Greg Clayton7b462cc2010-10-15 22:48:33 +00001919 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001920 }
1921
1922 return true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001923}
Sean Callanan5666b672010-08-04 01:02:13 +00001924
Kate Stoneb9c1b512016-09-06 20:57:50 +00001925void ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context,
1926 const RegisterInfo *reg_info,
1927 unsigned int current_id) {
1928 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001929
Kate Stoneb9c1b512016-09-06 20:57:50 +00001930 CompilerType clang_type =
1931 ClangASTContext::GetBuiltinTypeForEncodingAndBitSize(
1932 m_ast_context, reg_info->encoding, reg_info->byte_size * 8);
Sean Callanan7736a202016-04-29 18:09:03 +00001933
Kate Stoneb9c1b512016-09-06 20:57:50 +00001934 if (!clang_type) {
1935 if (log)
1936 log->Printf(" Tried to add a type for %s, but couldn't get one",
1937 context.m_decl_name.getAsString().c_str());
1938 return;
1939 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001940
Kate Stoneb9c1b512016-09-06 20:57:50 +00001941 TypeFromParser parser_clang_type(clang_type);
Sean Callananfa4fab72013-02-01 06:55:48 +00001942
Kate Stoneb9c1b512016-09-06 20:57:50 +00001943 NamedDecl *var_decl = context.AddVarDecl(parser_clang_type);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001944
Kate Stoneb9c1b512016-09-06 20:57:50 +00001945 ClangExpressionVariable *entity(new ClangExpressionVariable(
1946 m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
1947 m_parser_vars->m_target_info.byte_order,
1948 m_parser_vars->m_target_info.address_byte_size));
1949 m_found_entities.AddNewlyConstructedVariable(entity);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001950
Kate Stoneb9c1b512016-09-06 20:57:50 +00001951 std::string decl_name(context.m_decl_name.getAsString());
1952 entity->SetName(ConstString(decl_name.c_str()));
1953 entity->SetRegisterInfo(reg_info);
1954 entity->EnableParserVars(GetParserID());
1955 ClangExpressionVariable::ParserVars *parser_vars =
1956 entity->GetParserVars(GetParserID());
1957 parser_vars->m_parser_type = parser_clang_type;
1958 parser_vars->m_named_decl = var_decl;
1959 parser_vars->m_llvm_value = NULL;
1960 parser_vars->m_lldb_value.Clear();
1961 entity->m_flags |= ClangExpressionVariable::EVBareRegister;
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00001962
Kate Stoneb9c1b512016-09-06 20:57:50 +00001963 if (log) {
1964 ASTDumper ast_dumper(var_decl);
1965 log->Printf(" CEDM::FEVD[%d] Added register %s, returned %s", current_id,
1966 context.m_decl_name.getAsString().c_str(),
1967 ast_dumper.GetCString());
1968 }
1969}
1970
1971void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,
1972 Function *function, Symbol *symbol,
1973 unsigned int current_id) {
1974 assert(m_parser_vars.get());
1975
1976 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
1977
1978 NamedDecl *function_decl = NULL;
1979 Address fun_address;
1980 CompilerType function_clang_type;
1981
1982 bool is_indirect_function = false;
1983
1984 if (function) {
1985 Type *function_type = function->GetType();
1986
Luke Drummondf5bb1d62016-12-19 17:22:44 +00001987 const auto lang = function->GetCompileUnit()->GetLanguage();
1988 const auto name = function->GetMangled().GetMangledName().AsCString();
1989 const bool extern_c = (Language::LanguageIsC(lang) &&
1990 !CPlusPlusLanguage::IsCPPMangledName(name)) ||
1991 (Language::LanguageIsObjC(lang) &&
1992 !Language::LanguageIsCPlusPlus(lang));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001993
1994 if (!extern_c) {
1995 TypeSystem *type_system = function->GetDeclContext().GetTypeSystem();
Davide Italianofe34df52017-09-30 21:16:56 +00001996 if (llvm::isa<ClangASTContext>(type_system)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00001997 clang::DeclContext *src_decl_context =
1998 (clang::DeclContext *)function->GetDeclContext()
1999 .GetOpaqueDeclContext();
2000 clang::FunctionDecl *src_function_decl =
2001 llvm::dyn_cast_or_null<clang::FunctionDecl>(src_decl_context);
Sean Callanan09e91ac2017-05-11 22:08:05 +00002002 if (src_function_decl &&
2003 src_function_decl->getTemplateSpecializationInfo()) {
2004 clang::FunctionTemplateDecl *function_template =
2005 src_function_decl->getTemplateSpecializationInfo()->getTemplate();
2006 clang::FunctionTemplateDecl *copied_function_template =
2007 llvm::dyn_cast_or_null<clang::FunctionTemplateDecl>(
Sean Callanan68e44232017-09-28 20:20:25 +00002008 CopyDecl(function_template));
Sean Callanan09e91ac2017-05-11 22:08:05 +00002009 if (copied_function_template) {
2010 if (log) {
2011 ASTDumper ast_dumper((clang::Decl *)copied_function_template);
2012
2013 StreamString ss;
2014
2015 function->DumpSymbolContext(&ss);
2016
2017 log->Printf(" CEDM::FEVD[%u] Imported decl for function template"
2018 " %s (description %s), returned %s",
2019 current_id,
2020 copied_function_template->getNameAsString().c_str(),
2021 ss.GetData(), ast_dumper.GetCString());
2022 }
2023
2024 context.AddNamedDecl(copied_function_template);
2025 }
2026 } else if (src_function_decl) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002027 if (clang::FunctionDecl *copied_function_decl =
2028 llvm::dyn_cast_or_null<clang::FunctionDecl>(
Sean Callanan68e44232017-09-28 20:20:25 +00002029 CopyDecl(src_function_decl))) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00002030 if (log) {
2031 ASTDumper ast_dumper((clang::Decl *)copied_function_decl);
2032
2033 StreamString ss;
2034
2035 function->DumpSymbolContext(&ss);
2036
2037 log->Printf(" CEDM::FEVD[%u] Imported decl for function %s "
2038 "(description %s), returned %s",
2039 current_id,
2040 copied_function_decl->getNameAsString().c_str(),
2041 ss.GetData(), ast_dumper.GetCString());
2042 }
2043
2044 context.AddNamedDecl(copied_function_decl);
2045 return;
2046 } else {
2047 if (log) {
2048 log->Printf(" Failed to import the function decl for '%s'",
2049 src_function_decl->getName().str().c_str());
2050 }
2051 }
Sean Callanan7736a202016-04-29 18:09:03 +00002052 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002053 }
Sean Callananfc55f5d2010-09-21 00:44:12 +00002054 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00002055
Kate Stoneb9c1b512016-09-06 20:57:50 +00002056 if (!function_type) {
2057 if (log)
2058 log->PutCString(" Skipped a function because it has no type");
2059 return;
2060 }
2061
2062 function_clang_type = function_type->GetFullCompilerType();
2063
2064 if (!function_clang_type) {
2065 if (log)
2066 log->PutCString(" Skipped a function because it has no Clang type");
2067 return;
2068 }
2069
2070 fun_address = function->GetAddressRange().GetBaseAddress();
2071
2072 CompilerType copied_function_type = GuardedCopyType(function_clang_type);
2073 if (copied_function_type) {
2074 function_decl = context.AddFunDecl(copied_function_type, extern_c);
2075
2076 if (!function_decl) {
2077 if (log) {
2078 log->Printf(
2079 " Failed to create a function decl for '%s' {0x%8.8" PRIx64 "}",
2080 function_type->GetName().GetCString(), function_type->GetID());
2081 }
2082
Sean Callanan3b436d22015-10-23 21:45:02 +00002083 return;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002084 }
2085 } else {
2086 // We failed to copy the type we found
2087 if (log) {
2088 log->Printf(" Failed to import the function type '%s' {0x%8.8" PRIx64
2089 "} into the expression parser AST contenxt",
2090 function_type->GetName().GetCString(),
2091 function_type->GetID());
2092 }
2093
2094 return;
2095 }
2096 } else if (symbol) {
2097 fun_address = symbol->GetAddress();
2098 function_decl = context.AddGenericFunDecl();
2099 is_indirect_function = symbol->IsIndirect();
2100 } else {
2101 if (log)
2102 log->PutCString(" AddOneFunction called with no function and no symbol");
2103 return;
2104 }
2105
2106 Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
2107
2108 lldb::addr_t load_addr =
2109 fun_address.GetCallableLoadAddress(target, is_indirect_function);
2110
2111 ClangExpressionVariable *entity(new ClangExpressionVariable(
2112 m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
2113 m_parser_vars->m_target_info.byte_order,
2114 m_parser_vars->m_target_info.address_byte_size));
2115 m_found_entities.AddNewlyConstructedVariable(entity);
2116
2117 std::string decl_name(context.m_decl_name.getAsString());
2118 entity->SetName(ConstString(decl_name.c_str()));
2119 entity->SetCompilerType(function_clang_type);
2120 entity->EnableParserVars(GetParserID());
2121
2122 ClangExpressionVariable::ParserVars *parser_vars =
2123 entity->GetParserVars(GetParserID());
2124
2125 if (load_addr != LLDB_INVALID_ADDRESS) {
2126 parser_vars->m_lldb_value.SetValueType(Value::eValueTypeLoadAddress);
2127 parser_vars->m_lldb_value.GetScalar() = load_addr;
2128 } else {
2129 // We have to try finding a file address.
2130
2131 lldb::addr_t file_addr = fun_address.GetFileAddress();
2132
2133 parser_vars->m_lldb_value.SetValueType(Value::eValueTypeFileAddress);
2134 parser_vars->m_lldb_value.GetScalar() = file_addr;
2135 }
2136
2137 parser_vars->m_named_decl = function_decl;
2138 parser_vars->m_llvm_value = NULL;
2139
2140 if (log) {
Pavel Labath03a77e92018-03-21 11:10:57 +00002141 std::string function_str =
2142 function_decl ? ASTDumper(function_decl).GetCString() : "nullptr";
Kate Stoneb9c1b512016-09-06 20:57:50 +00002143
2144 StreamString ss;
2145
2146 fun_address.Dump(&ss,
2147 m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),
2148 Address::DumpStyleResolvedDescription);
2149
2150 log->Printf(
2151 " CEDM::FEVD[%u] Found %s function %s (description %s), returned %s",
2152 current_id, (function ? "specific" : "generic"), decl_name.c_str(),
Pavel Labath03a77e92018-03-21 11:10:57 +00002153 ss.GetData(), function_str.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002154 }
2155}
2156
2157void ClangExpressionDeclMap::AddThisType(NameSearchContext &context,
Aleksandr Urakov40624a02019-02-05 09:14:36 +00002158 const TypeFromUser &ut,
Kate Stoneb9c1b512016-09-06 20:57:50 +00002159 unsigned int current_id) {
2160 CompilerType copied_clang_type = GuardedCopyType(ut);
2161
2162 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
2163
2164 if (!copied_clang_type) {
2165 if (log)
2166 log->Printf(
2167 "ClangExpressionDeclMap::AddThisType - Couldn't import the type");
Sean Callanan3b436d22015-10-23 21:45:02 +00002168
2169 return;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002170 }
2171
2172 if (copied_clang_type.IsAggregateType() &&
2173 copied_clang_type.GetCompleteType()) {
2174 CompilerType void_clang_type =
2175 ClangASTContext::GetBasicType(m_ast_context, eBasicTypeVoid);
2176 CompilerType void_ptr_clang_type = void_clang_type.GetPointerType();
2177
2178 CompilerType method_type = ClangASTContext::CreateFunctionType(
2179 m_ast_context, void_clang_type, &void_ptr_clang_type, 1, false, 0);
2180
2181 const bool is_virtual = false;
2182 const bool is_static = false;
2183 const bool is_inline = false;
2184 const bool is_explicit = false;
2185 const bool is_attr_used = true;
2186 const bool is_artificial = false;
2187
2188 CXXMethodDecl *method_decl =
2189 ClangASTContext::GetASTContext(m_ast_context)
2190 ->AddMethodToCXXRecordType(
Davide Italiano675767a2018-03-27 19:40:50 +00002191 copied_clang_type.GetOpaqueQualType(), "$__lldb_expr", NULL,
Kate Stoneb9c1b512016-09-06 20:57:50 +00002192 method_type, lldb::eAccessPublic, is_virtual, is_static,
2193 is_inline, is_explicit, is_attr_used, is_artificial);
2194
2195 if (log) {
2196 ASTDumper method_ast_dumper((clang::Decl *)method_decl);
2197 ASTDumper type_ast_dumper(copied_clang_type);
2198
2199 log->Printf(" CEDM::AddThisType Added function $__lldb_expr "
2200 "(description %s) for this type %s",
2201 method_ast_dumper.GetCString(), type_ast_dumper.GetCString());
2202 }
2203 }
2204
2205 if (!copied_clang_type.IsValid())
2206 return;
2207
2208 TypeSourceInfo *type_source_info = m_ast_context->getTrivialTypeSourceInfo(
2209 QualType::getFromOpaquePtr(copied_clang_type.GetOpaqueQualType()));
2210
2211 if (!type_source_info)
2212 return;
2213
2214 // Construct a typedef type because if "*this" is a templated type we can't
2215 // just return ClassTemplateSpecializationDecls in response to name queries.
2216 // Using a typedef makes this much more robust.
2217
2218 TypedefDecl *typedef_decl = TypedefDecl::Create(
2219 *m_ast_context, m_ast_context->getTranslationUnitDecl(), SourceLocation(),
2220 SourceLocation(), context.m_decl_name.getAsIdentifierInfo(),
2221 type_source_info);
2222
2223 if (!typedef_decl)
2224 return;
2225
2226 context.AddNamedDecl(typedef_decl);
2227
2228 return;
Sean Callananfa4fab72013-02-01 06:55:48 +00002229}
2230
Kate Stoneb9c1b512016-09-06 20:57:50 +00002231void ClangExpressionDeclMap::AddOneType(NameSearchContext &context,
Aleksandr Urakov40624a02019-02-05 09:14:36 +00002232 const TypeFromUser &ut,
Kate Stoneb9c1b512016-09-06 20:57:50 +00002233 unsigned int current_id) {
2234 CompilerType copied_clang_type = GuardedCopyType(ut);
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00002235
Kate Stoneb9c1b512016-09-06 20:57:50 +00002236 if (!copied_clang_type) {
2237 Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
Sean Callananfa4fab72013-02-01 06:55:48 +00002238
Kate Stoneb9c1b512016-09-06 20:57:50 +00002239 if (log)
2240 log->Printf(
2241 "ClangExpressionDeclMap::AddOneType - Couldn't import the type");
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00002242
Kate Stoneb9c1b512016-09-06 20:57:50 +00002243 return;
2244 }
Sylvestre Ledruceab3ac2014-07-06 17:54:58 +00002245
Kate Stoneb9c1b512016-09-06 20:57:50 +00002246 context.AddTypeDecl(copied_clang_type);
Sean Callanan5666b672010-08-04 01:02:13 +00002247}