Path: blob/main/contrib/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
39648 views
//===-- ClangExpressionDeclMap.cpp ----------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "ClangExpressionDeclMap.h"910#include "ClangASTSource.h"11#include "ClangExpressionUtil.h"12#include "ClangExpressionVariable.h"13#include "ClangModulesDeclVendor.h"14#include "ClangPersistentVariables.h"15#include "ClangUtil.h"1617#include "NameSearchContext.h"18#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"19#include "lldb/Core/Address.h"20#include "lldb/Core/Module.h"21#include "lldb/Core/ModuleSpec.h"22#include "lldb/Core/ValueObjectConstResult.h"23#include "lldb/Core/ValueObjectVariable.h"24#include "lldb/Expression/DiagnosticManager.h"25#include "lldb/Expression/Materializer.h"26#include "lldb/Symbol/CompileUnit.h"27#include "lldb/Symbol/CompilerDecl.h"28#include "lldb/Symbol/CompilerDeclContext.h"29#include "lldb/Symbol/Function.h"30#include "lldb/Symbol/ObjectFile.h"31#include "lldb/Symbol/SymbolContext.h"32#include "lldb/Symbol/SymbolFile.h"33#include "lldb/Symbol/SymbolVendor.h"34#include "lldb/Symbol/Type.h"35#include "lldb/Symbol/TypeList.h"36#include "lldb/Symbol/Variable.h"37#include "lldb/Symbol/VariableList.h"38#include "lldb/Target/ExecutionContext.h"39#include "lldb/Target/Process.h"40#include "lldb/Target/RegisterContext.h"41#include "lldb/Target/StackFrame.h"42#include "lldb/Target/Target.h"43#include "lldb/Target/Thread.h"44#include "lldb/Utility/Endian.h"45#include "lldb/Utility/LLDBLog.h"46#include "lldb/Utility/Log.h"47#include "lldb/Utility/RegisterValue.h"48#include "lldb/Utility/Status.h"49#include "lldb/lldb-private-types.h"50#include "lldb/lldb-private.h"51#include "clang/AST/ASTConsumer.h"52#include "clang/AST/ASTContext.h"53#include "clang/AST/ASTImporter.h"54#include "clang/AST/Decl.h"55#include "clang/AST/DeclarationName.h"56#include "clang/AST/RecursiveASTVisitor.h"5758#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"59#include "Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h"60#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"6162using namespace lldb;63using namespace lldb_private;64using namespace clang;6566static const char *g_lldb_local_vars_namespace_cstr = "$__lldb_local_vars";6768namespace {69/// A lambda is represented by Clang as an artifical class whose70/// members are the lambda captures. If we capture a 'this' pointer,71/// the artifical class will contain a member variable named 'this'.72/// The function returns a ValueObject for the captured 'this' if such73/// member exists. If no 'this' was captured, return a nullptr.74lldb::ValueObjectSP GetCapturedThisValueObject(StackFrame *frame) {75assert(frame);7677if (auto thisValSP = frame->FindVariable(ConstString("this")))78if (auto thisThisValSP = thisValSP->GetChildMemberWithName("this"))79return thisThisValSP;8081return nullptr;82}83} // namespace8485ClangExpressionDeclMap::ClangExpressionDeclMap(86bool keep_result_in_memory,87Materializer::PersistentVariableDelegate *result_delegate,88const lldb::TargetSP &target,89const std::shared_ptr<ClangASTImporter> &importer, ValueObject *ctx_obj)90: ClangASTSource(target, importer), m_found_entities(), m_struct_members(),91m_keep_result_in_memory(keep_result_in_memory),92m_result_delegate(result_delegate), m_ctx_obj(ctx_obj), m_parser_vars(),93m_struct_vars() {94EnableStructVars();95}9697ClangExpressionDeclMap::~ClangExpressionDeclMap() {98// Note: The model is now that the parser's AST context and all associated99// data does not vanish until the expression has been executed. This means100// that valuable lookup data (like namespaces) doesn't vanish, but101102DidParse();103DisableStructVars();104}105106bool ClangExpressionDeclMap::WillParse(ExecutionContext &exe_ctx,107Materializer *materializer) {108EnableParserVars();109m_parser_vars->m_exe_ctx = exe_ctx;110111Target *target = exe_ctx.GetTargetPtr();112if (exe_ctx.GetFramePtr())113m_parser_vars->m_sym_ctx =114exe_ctx.GetFramePtr()->GetSymbolContext(lldb::eSymbolContextEverything);115else if (exe_ctx.GetThreadPtr() &&116exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(0))117m_parser_vars->m_sym_ctx =118exe_ctx.GetThreadPtr()->GetStackFrameAtIndex(0)->GetSymbolContext(119lldb::eSymbolContextEverything);120else if (exe_ctx.GetProcessPtr()) {121m_parser_vars->m_sym_ctx.Clear(true);122m_parser_vars->m_sym_ctx.target_sp = exe_ctx.GetTargetSP();123} else if (target) {124m_parser_vars->m_sym_ctx.Clear(true);125m_parser_vars->m_sym_ctx.target_sp = exe_ctx.GetTargetSP();126}127128if (target) {129m_parser_vars->m_persistent_vars = llvm::cast<ClangPersistentVariables>(130target->GetPersistentExpressionStateForLanguage(eLanguageTypeC));131132if (!ScratchTypeSystemClang::GetForTarget(*target))133return false;134}135136m_parser_vars->m_target_info = GetTargetInfo();137m_parser_vars->m_materializer = materializer;138139return true;140}141142void ClangExpressionDeclMap::InstallCodeGenerator(143clang::ASTConsumer *code_gen) {144assert(m_parser_vars);145m_parser_vars->m_code_gen = code_gen;146}147148void ClangExpressionDeclMap::InstallDiagnosticManager(149DiagnosticManager &diag_manager) {150assert(m_parser_vars);151m_parser_vars->m_diagnostics = &diag_manager;152}153154void ClangExpressionDeclMap::DidParse() {155if (m_parser_vars && m_parser_vars->m_persistent_vars) {156for (size_t entity_index = 0, num_entities = m_found_entities.GetSize();157entity_index < num_entities; ++entity_index) {158ExpressionVariableSP var_sp(159m_found_entities.GetVariableAtIndex(entity_index));160if (var_sp)161llvm::cast<ClangExpressionVariable>(var_sp.get())162->DisableParserVars(GetParserID());163}164165for (size_t pvar_index = 0,166num_pvars = m_parser_vars->m_persistent_vars->GetSize();167pvar_index < num_pvars; ++pvar_index) {168ExpressionVariableSP pvar_sp(169m_parser_vars->m_persistent_vars->GetVariableAtIndex(pvar_index));170if (ClangExpressionVariable *clang_var =171llvm::dyn_cast<ClangExpressionVariable>(pvar_sp.get()))172clang_var->DisableParserVars(GetParserID());173}174175DisableParserVars();176}177}178179// Interface for IRForTarget180181ClangExpressionDeclMap::TargetInfo ClangExpressionDeclMap::GetTargetInfo() {182assert(m_parser_vars.get());183184TargetInfo ret;185186ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;187188Process *process = exe_ctx.GetProcessPtr();189if (process) {190ret.byte_order = process->GetByteOrder();191ret.address_byte_size = process->GetAddressByteSize();192} else {193Target *target = exe_ctx.GetTargetPtr();194if (target) {195ret.byte_order = target->GetArchitecture().GetByteOrder();196ret.address_byte_size = target->GetArchitecture().GetAddressByteSize();197}198}199200return ret;201}202203TypeFromUser ClangExpressionDeclMap::DeportType(TypeSystemClang &target,204TypeSystemClang &source,205TypeFromParser parser_type) {206assert(&target == GetScratchContext(*m_target).get());207assert((TypeSystem *)&source ==208parser_type.GetTypeSystem().GetSharedPointer().get());209assert(&source.getASTContext() == m_ast_context);210211return TypeFromUser(m_ast_importer_sp->DeportType(target, parser_type));212}213214bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,215ConstString name,216TypeFromParser parser_type,217bool is_result,218bool is_lvalue) {219assert(m_parser_vars.get());220auto ast = parser_type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>();221if (ast == nullptr)222return false;223224// Check if we already declared a persistent variable with the same name.225if (lldb::ExpressionVariableSP conflicting_var =226m_parser_vars->m_persistent_vars->GetVariable(name)) {227std::string msg = llvm::formatv("redefinition of persistent variable '{0}'",228name).str();229m_parser_vars->m_diagnostics->AddDiagnostic(230msg, lldb::eSeverityError, DiagnosticOrigin::eDiagnosticOriginLLDB);231return false;232}233234if (m_parser_vars->m_materializer && is_result) {235Status err;236237ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;238Target *target = exe_ctx.GetTargetPtr();239if (target == nullptr)240return false;241242auto clang_ast_context = GetScratchContext(*target);243if (!clang_ast_context)244return false;245246TypeFromUser user_type = DeportType(*clang_ast_context, *ast, parser_type);247248uint32_t offset = m_parser_vars->m_materializer->AddResultVariable(249user_type, is_lvalue, m_keep_result_in_memory, m_result_delegate, err);250251ClangExpressionVariable *var = new ClangExpressionVariable(252exe_ctx.GetBestExecutionContextScope(), name, user_type,253m_parser_vars->m_target_info.byte_order,254m_parser_vars->m_target_info.address_byte_size);255256m_found_entities.AddNewlyConstructedVariable(var);257258var->EnableParserVars(GetParserID());259260ClangExpressionVariable::ParserVars *parser_vars =261var->GetParserVars(GetParserID());262263parser_vars->m_named_decl = decl;264265var->EnableJITVars(GetParserID());266267ClangExpressionVariable::JITVars *jit_vars = var->GetJITVars(GetParserID());268269jit_vars->m_offset = offset;270271return true;272}273274Log *log = GetLog(LLDBLog::Expressions);275ExecutionContext &exe_ctx = m_parser_vars->m_exe_ctx;276Target *target = exe_ctx.GetTargetPtr();277if (target == nullptr)278return false;279280auto context = GetScratchContext(*target);281if (!context)282return false;283284TypeFromUser user_type = DeportType(*context, *ast, parser_type);285286if (!user_type.GetOpaqueQualType()) {287LLDB_LOG(log, "Persistent variable's type wasn't copied successfully");288return false;289}290291if (!m_parser_vars->m_target_info.IsValid())292return false;293294if (!m_parser_vars->m_persistent_vars)295return false;296297ClangExpressionVariable *var = llvm::cast<ClangExpressionVariable>(298m_parser_vars->m_persistent_vars299->CreatePersistentVariable(300exe_ctx.GetBestExecutionContextScope(), name, user_type,301m_parser_vars->m_target_info.byte_order,302m_parser_vars->m_target_info.address_byte_size)303.get());304305if (!var)306return false;307308var->m_frozen_sp->SetHasCompleteType();309310if (is_result)311var->m_flags |= ClangExpressionVariable::EVNeedsFreezeDry;312else313var->m_flags |=314ClangExpressionVariable::EVKeepInTarget; // explicitly-declared315// persistent variables should316// persist317318if (is_lvalue) {319var->m_flags |= ClangExpressionVariable::EVIsProgramReference;320} else {321var->m_flags |= ClangExpressionVariable::EVIsLLDBAllocated;322var->m_flags |= ClangExpressionVariable::EVNeedsAllocation;323}324325if (m_keep_result_in_memory) {326var->m_flags |= ClangExpressionVariable::EVKeepInTarget;327}328329LLDB_LOG(log, "Created persistent variable with flags {0:x}", var->m_flags);330331var->EnableParserVars(GetParserID());332333ClangExpressionVariable::ParserVars *parser_vars =334var->GetParserVars(GetParserID());335336parser_vars->m_named_decl = decl;337338return true;339}340341bool ClangExpressionDeclMap::AddValueToStruct(const NamedDecl *decl,342ConstString name,343llvm::Value *value, size_t size,344lldb::offset_t alignment) {345assert(m_struct_vars.get());346assert(m_parser_vars.get());347348bool is_persistent_variable = false;349350Log *log = GetLog(LLDBLog::Expressions);351352m_struct_vars->m_struct_laid_out = false;353354if (ClangExpressionVariable::FindVariableInList(m_struct_members, decl,355GetParserID()))356return true;357358ClangExpressionVariable *var(ClangExpressionVariable::FindVariableInList(359m_found_entities, decl, GetParserID()));360361if (!var && m_parser_vars->m_persistent_vars) {362var = ClangExpressionVariable::FindVariableInList(363*m_parser_vars->m_persistent_vars, decl, GetParserID());364is_persistent_variable = true;365}366367if (!var)368return false;369370LLDB_LOG(log, "Adding value for (NamedDecl*){0} [{1} - {2}] to the structure",371decl, name, var->GetName());372373// We know entity->m_parser_vars is valid because we used a parser variable374// to find it375376ClangExpressionVariable::ParserVars *parser_vars =377llvm::cast<ClangExpressionVariable>(var)->GetParserVars(GetParserID());378379parser_vars->m_llvm_value = value;380381if (ClangExpressionVariable::JITVars *jit_vars =382llvm::cast<ClangExpressionVariable>(var)->GetJITVars(GetParserID())) {383// We already laid this out; do not touch384385LLDB_LOG(log, "Already placed at {0:x}", jit_vars->m_offset);386}387388llvm::cast<ClangExpressionVariable>(var)->EnableJITVars(GetParserID());389390ClangExpressionVariable::JITVars *jit_vars =391llvm::cast<ClangExpressionVariable>(var)->GetJITVars(GetParserID());392393jit_vars->m_alignment = alignment;394jit_vars->m_size = size;395396m_struct_members.AddVariable(var->shared_from_this());397398if (m_parser_vars->m_materializer) {399uint32_t offset = 0;400401Status err;402403if (is_persistent_variable) {404ExpressionVariableSP var_sp(var->shared_from_this());405offset = m_parser_vars->m_materializer->AddPersistentVariable(406var_sp, nullptr, err);407} else {408if (const lldb_private::Symbol *sym = parser_vars->m_lldb_sym)409offset = m_parser_vars->m_materializer->AddSymbol(*sym, err);410else if (const RegisterInfo *reg_info = var->GetRegisterInfo())411offset = m_parser_vars->m_materializer->AddRegister(*reg_info, err);412else if (parser_vars->m_lldb_var)413offset = m_parser_vars->m_materializer->AddVariable(414parser_vars->m_lldb_var, err);415else if (parser_vars->m_lldb_valobj_provider) {416offset = m_parser_vars->m_materializer->AddValueObject(417name, parser_vars->m_lldb_valobj_provider, err);418}419}420421if (!err.Success())422return false;423424LLDB_LOG(log, "Placed at {0:x}", offset);425426jit_vars->m_offset =427offset; // TODO DoStructLayout() should not change this.428}429430return true;431}432433bool ClangExpressionDeclMap::DoStructLayout() {434assert(m_struct_vars.get());435436if (m_struct_vars->m_struct_laid_out)437return true;438439if (!m_parser_vars->m_materializer)440return false;441442m_struct_vars->m_struct_alignment =443m_parser_vars->m_materializer->GetStructAlignment();444m_struct_vars->m_struct_size =445m_parser_vars->m_materializer->GetStructByteSize();446m_struct_vars->m_struct_laid_out = true;447return true;448}449450bool ClangExpressionDeclMap::GetStructInfo(uint32_t &num_elements, size_t &size,451lldb::offset_t &alignment) {452assert(m_struct_vars.get());453454if (!m_struct_vars->m_struct_laid_out)455return false;456457num_elements = m_struct_members.GetSize();458size = m_struct_vars->m_struct_size;459alignment = m_struct_vars->m_struct_alignment;460461return true;462}463464bool ClangExpressionDeclMap::GetStructElement(const NamedDecl *&decl,465llvm::Value *&value,466lldb::offset_t &offset,467ConstString &name,468uint32_t index) {469assert(m_struct_vars.get());470471if (!m_struct_vars->m_struct_laid_out)472return false;473474if (index >= m_struct_members.GetSize())475return false;476477ExpressionVariableSP member_sp(m_struct_members.GetVariableAtIndex(index));478479if (!member_sp)480return false;481482ClangExpressionVariable::ParserVars *parser_vars =483llvm::cast<ClangExpressionVariable>(member_sp.get())484->GetParserVars(GetParserID());485ClangExpressionVariable::JITVars *jit_vars =486llvm::cast<ClangExpressionVariable>(member_sp.get())487->GetJITVars(GetParserID());488489if (!parser_vars || !jit_vars || !member_sp->GetValueObject())490return false;491492decl = parser_vars->m_named_decl;493value = parser_vars->m_llvm_value;494offset = jit_vars->m_offset;495name = member_sp->GetName();496497return true;498}499500bool ClangExpressionDeclMap::GetFunctionInfo(const NamedDecl *decl,501uint64_t &ptr) {502ClangExpressionVariable *entity(ClangExpressionVariable::FindVariableInList(503m_found_entities, decl, GetParserID()));504505if (!entity)506return false;507508// We know m_parser_vars is valid since we searched for the variable by its509// NamedDecl510511ClangExpressionVariable::ParserVars *parser_vars =512entity->GetParserVars(GetParserID());513514ptr = parser_vars->m_lldb_value.GetScalar().ULongLong();515516return true;517}518519addr_t ClangExpressionDeclMap::GetSymbolAddress(Target &target,520Process *process,521ConstString name,522lldb::SymbolType symbol_type,523lldb_private::Module *module) {524SymbolContextList sc_list;525526if (module)527module->FindSymbolsWithNameAndType(name, symbol_type, sc_list);528else529target.GetImages().FindSymbolsWithNameAndType(name, symbol_type, sc_list);530531addr_t symbol_load_addr = LLDB_INVALID_ADDRESS;532533for (const SymbolContext &sym_ctx : sc_list) {534if (symbol_load_addr != 0 && symbol_load_addr != LLDB_INVALID_ADDRESS)535break;536537const Address sym_address = sym_ctx.symbol->GetAddress();538539if (!sym_address.IsValid())540continue;541542switch (sym_ctx.symbol->GetType()) {543case eSymbolTypeCode:544case eSymbolTypeTrampoline:545symbol_load_addr = sym_address.GetCallableLoadAddress(&target);546break;547548case eSymbolTypeResolver:549symbol_load_addr = sym_address.GetCallableLoadAddress(&target, true);550break;551552case eSymbolTypeReExported: {553ConstString reexport_name = sym_ctx.symbol->GetReExportedSymbolName();554if (reexport_name) {555ModuleSP reexport_module_sp;556ModuleSpec reexport_module_spec;557reexport_module_spec.GetPlatformFileSpec() =558sym_ctx.symbol->GetReExportedSymbolSharedLibrary();559if (reexport_module_spec.GetPlatformFileSpec()) {560reexport_module_sp =561target.GetImages().FindFirstModule(reexport_module_spec);562if (!reexport_module_sp) {563reexport_module_spec.GetPlatformFileSpec().ClearDirectory();564reexport_module_sp =565target.GetImages().FindFirstModule(reexport_module_spec);566}567}568symbol_load_addr = GetSymbolAddress(569target, process, sym_ctx.symbol->GetReExportedSymbolName(),570symbol_type, reexport_module_sp.get());571}572} break;573574case eSymbolTypeData:575case eSymbolTypeRuntime:576case eSymbolTypeVariable:577case eSymbolTypeLocal:578case eSymbolTypeParam:579case eSymbolTypeInvalid:580case eSymbolTypeAbsolute:581case eSymbolTypeException:582case eSymbolTypeSourceFile:583case eSymbolTypeHeaderFile:584case eSymbolTypeObjectFile:585case eSymbolTypeCommonBlock:586case eSymbolTypeBlock:587case eSymbolTypeVariableType:588case eSymbolTypeLineEntry:589case eSymbolTypeLineHeader:590case eSymbolTypeScopeBegin:591case eSymbolTypeScopeEnd:592case eSymbolTypeAdditional:593case eSymbolTypeCompiler:594case eSymbolTypeInstrumentation:595case eSymbolTypeUndefined:596case eSymbolTypeObjCClass:597case eSymbolTypeObjCMetaClass:598case eSymbolTypeObjCIVar:599symbol_load_addr = sym_address.GetLoadAddress(&target);600break;601}602}603604if (symbol_load_addr == LLDB_INVALID_ADDRESS && process) {605ObjCLanguageRuntime *runtime = ObjCLanguageRuntime::Get(*process);606607if (runtime) {608symbol_load_addr = runtime->LookupRuntimeSymbol(name);609}610}611612return symbol_load_addr;613}614615addr_t ClangExpressionDeclMap::GetSymbolAddress(ConstString name,616lldb::SymbolType symbol_type) {617assert(m_parser_vars.get());618619if (!m_parser_vars->m_exe_ctx.GetTargetPtr())620return false;621622return GetSymbolAddress(m_parser_vars->m_exe_ctx.GetTargetRef(),623m_parser_vars->m_exe_ctx.GetProcessPtr(), name,624symbol_type);625}626627lldb::VariableSP ClangExpressionDeclMap::FindGlobalVariable(628Target &target, ModuleSP &module, ConstString name,629const CompilerDeclContext &namespace_decl) {630VariableList vars;631632if (module && namespace_decl)633module->FindGlobalVariables(name, namespace_decl, -1, vars);634else635target.GetImages().FindGlobalVariables(name, -1, vars);636637if (vars.GetSize() == 0)638return VariableSP();639return vars.GetVariableAtIndex(0);640}641642TypeSystemClang *ClangExpressionDeclMap::GetTypeSystemClang() {643StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();644if (frame == nullptr)645return nullptr;646647SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |648lldb::eSymbolContextBlock);649if (sym_ctx.block == nullptr)650return nullptr;651652CompilerDeclContext frame_decl_context = sym_ctx.block->GetDeclContext();653if (!frame_decl_context)654return nullptr;655656return llvm::dyn_cast_or_null<TypeSystemClang>(657frame_decl_context.GetTypeSystem());658}659660// Interface for ClangASTSource661662void ClangExpressionDeclMap::FindExternalVisibleDecls(663NameSearchContext &context) {664assert(m_ast_context);665666const ConstString name(context.m_decl_name.getAsString().c_str());667668Log *log = GetLog(LLDBLog::Expressions);669670if (log) {671if (!context.m_decl_context)672LLDB_LOG(log,673"ClangExpressionDeclMap::FindExternalVisibleDecls for "674"'{0}' in a NULL DeclContext",675name);676else if (const NamedDecl *context_named_decl =677dyn_cast<NamedDecl>(context.m_decl_context))678LLDB_LOG(log,679"ClangExpressionDeclMap::FindExternalVisibleDecls for "680"'{0}' in '{1}'",681name, context_named_decl->getNameAsString());682else683LLDB_LOG(log,684"ClangExpressionDeclMap::FindExternalVisibleDecls for "685"'{0}' in a '{1}'",686name, context.m_decl_context->getDeclKindName());687}688689if (const NamespaceDecl *namespace_context =690dyn_cast<NamespaceDecl>(context.m_decl_context)) {691if (namespace_context->getName().str() ==692std::string(g_lldb_local_vars_namespace_cstr)) {693CompilerDeclContext compiler_decl_ctx =694m_clang_ast_context->CreateDeclContext(695const_cast<clang::DeclContext *>(context.m_decl_context));696FindExternalVisibleDecls(context, lldb::ModuleSP(), compiler_decl_ctx);697return;698}699700ClangASTImporter::NamespaceMapSP namespace_map =701m_ast_importer_sp->GetNamespaceMap(namespace_context);702703if (!namespace_map)704return;705706LLDB_LOGV(log, " CEDM::FEVD Inspecting (NamespaceMap*){0:x} ({1} entries)",707namespace_map.get(), namespace_map->size());708709for (ClangASTImporter::NamespaceMapItem &n : *namespace_map) {710LLDB_LOG(log, " CEDM::FEVD Searching namespace {0} in module {1}",711n.second.GetName(), n.first->GetFileSpec().GetFilename());712713FindExternalVisibleDecls(context, n.first, n.second);714}715} else if (isa<TranslationUnitDecl>(context.m_decl_context)) {716CompilerDeclContext namespace_decl;717718LLDB_LOG(log, " CEDM::FEVD Searching the root namespace");719720FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl);721}722723ClangASTSource::FindExternalVisibleDecls(context);724}725726void ClangExpressionDeclMap::MaybeRegisterFunctionBody(727FunctionDecl *copied_function_decl) {728if (copied_function_decl->getBody() && m_parser_vars->m_code_gen) {729clang::DeclGroupRef decl_group_ref(copied_function_decl);730m_parser_vars->m_code_gen->HandleTopLevelDecl(decl_group_ref);731}732}733734clang::NamedDecl *ClangExpressionDeclMap::GetPersistentDecl(ConstString name) {735if (!m_parser_vars)736return nullptr;737Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();738if (!target)739return nullptr;740741ScratchTypeSystemClang::GetForTarget(*target);742743if (!m_parser_vars->m_persistent_vars)744return nullptr;745return m_parser_vars->m_persistent_vars->GetPersistentDecl(name);746}747748void ClangExpressionDeclMap::SearchPersistenDecls(NameSearchContext &context,749const ConstString name) {750Log *log = GetLog(LLDBLog::Expressions);751752NamedDecl *persistent_decl = GetPersistentDecl(name);753754if (!persistent_decl)755return;756757Decl *parser_persistent_decl = CopyDecl(persistent_decl);758759if (!parser_persistent_decl)760return;761762NamedDecl *parser_named_decl = dyn_cast<NamedDecl>(parser_persistent_decl);763764if (!parser_named_decl)765return;766767if (clang::FunctionDecl *parser_function_decl =768llvm::dyn_cast<clang::FunctionDecl>(parser_named_decl)) {769MaybeRegisterFunctionBody(parser_function_decl);770}771772LLDB_LOG(log, " CEDM::FEVD Found persistent decl {0}", name);773774context.AddNamedDecl(parser_named_decl);775}776777void ClangExpressionDeclMap::LookUpLldbClass(NameSearchContext &context) {778Log *log = GetLog(LLDBLog::Expressions);779780StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();781SymbolContext sym_ctx;782if (frame != nullptr)783sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |784lldb::eSymbolContextBlock);785786if (m_ctx_obj) {787Status status;788lldb::ValueObjectSP ctx_obj_ptr = m_ctx_obj->AddressOf(status);789if (!ctx_obj_ptr || status.Fail())790return;791792AddContextClassType(context, TypeFromUser(m_ctx_obj->GetCompilerType()));793return;794}795796// Clang is looking for the type of "this"797798if (frame == nullptr)799return;800801// Find the block that defines the function represented by "sym_ctx"802Block *function_block = sym_ctx.GetFunctionBlock();803804if (!function_block)805return;806807CompilerDeclContext function_decl_ctx = function_block->GetDeclContext();808809if (!function_decl_ctx)810return;811812clang::CXXMethodDecl *method_decl =813TypeSystemClang::DeclContextGetAsCXXMethodDecl(function_decl_ctx);814815if (method_decl) {816if (auto capturedThis = GetCapturedThisValueObject(frame)) {817// We're inside a lambda and we captured a 'this'.818// Import the outer class's AST instead of the819// (unnamed) lambda structure AST so unqualified820// member lookups are understood by the Clang parser.821//822// If we're in a lambda which didn't capture 'this',823// $__lldb_class will correspond to the lambda closure824// AST and references to captures will resolve like825// regular member varaiable accesses do.826TypeFromUser pointee_type =827capturedThis->GetCompilerType().GetPointeeType();828829LLDB_LOG(log,830" CEDM::FEVD Adding captured type ({0} for"831" $__lldb_class: {1}",832capturedThis->GetTypeName(), capturedThis->GetName());833834AddContextClassType(context, pointee_type);835return;836}837838clang::CXXRecordDecl *class_decl = method_decl->getParent();839840QualType class_qual_type(class_decl->getTypeForDecl(), 0);841842TypeFromUser class_user_type(843class_qual_type.getAsOpaquePtr(),844function_decl_ctx.GetTypeSystem()->weak_from_this());845846LLDB_LOG(log, " CEDM::FEVD Adding type for $__lldb_class: {0}",847class_qual_type.getAsString());848849AddContextClassType(context, class_user_type);850return;851}852853// This branch will get hit if we are executing code in the context of854// a function that claims to have an object pointer (through855// DW_AT_object_pointer?) but is not formally a method of the class.856// In that case, just look up the "this" variable in the current scope857// and use its type.858// FIXME: This code is formally correct, but clang doesn't currently859// emit DW_AT_object_pointer860// for C++ so it hasn't actually been tested.861862VariableList *vars = frame->GetVariableList(false, nullptr);863864lldb::VariableSP this_var = vars->FindVariable(ConstString("this"));865866if (this_var && this_var->IsInScope(frame) &&867this_var->LocationIsValidForFrame(frame)) {868Type *this_type = this_var->GetType();869870if (!this_type)871return;872873TypeFromUser pointee_type =874this_type->GetForwardCompilerType().GetPointeeType();875876LLDB_LOG(log, " FEVD Adding type for $__lldb_class: {0}",877ClangUtil::GetQualType(pointee_type).getAsString());878879AddContextClassType(context, pointee_type);880}881}882883void ClangExpressionDeclMap::LookUpLldbObjCClass(NameSearchContext &context) {884Log *log = GetLog(LLDBLog::Expressions);885886StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();887888if (m_ctx_obj) {889Status status;890lldb::ValueObjectSP ctx_obj_ptr = m_ctx_obj->AddressOf(status);891if (!ctx_obj_ptr || status.Fail())892return;893894AddOneType(context, TypeFromUser(m_ctx_obj->GetCompilerType()));895return;896}897898// Clang is looking for the type of "*self"899900if (!frame)901return;902903SymbolContext sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |904lldb::eSymbolContextBlock);905906// Find the block that defines the function represented by "sym_ctx"907Block *function_block = sym_ctx.GetFunctionBlock();908909if (!function_block)910return;911912CompilerDeclContext function_decl_ctx = function_block->GetDeclContext();913914if (!function_decl_ctx)915return;916917clang::ObjCMethodDecl *method_decl =918TypeSystemClang::DeclContextGetAsObjCMethodDecl(function_decl_ctx);919920if (method_decl) {921ObjCInterfaceDecl *self_interface = method_decl->getClassInterface();922923if (!self_interface)924return;925926const clang::Type *interface_type = self_interface->getTypeForDecl();927928if (!interface_type)929return; // This is unlikely, but we have seen crashes where this930// occurred931932TypeFromUser class_user_type(933QualType(interface_type, 0).getAsOpaquePtr(),934function_decl_ctx.GetTypeSystem()->weak_from_this());935936LLDB_LOG(log, " FEVD[{0}] Adding type for $__lldb_objc_class: {1}",937ClangUtil::ToString(interface_type));938939AddOneType(context, class_user_type);940return;941}942// This branch will get hit if we are executing code in the context of943// a function that claims to have an object pointer (through944// DW_AT_object_pointer?) but is not formally a method of the class.945// In that case, just look up the "self" variable in the current scope946// and use its type.947948VariableList *vars = frame->GetVariableList(false, nullptr);949950lldb::VariableSP self_var = vars->FindVariable(ConstString("self"));951952if (!self_var)953return;954if (!self_var->IsInScope(frame))955return;956if (!self_var->LocationIsValidForFrame(frame))957return;958959Type *self_type = self_var->GetType();960961if (!self_type)962return;963964CompilerType self_clang_type = self_type->GetFullCompilerType();965966if (TypeSystemClang::IsObjCClassType(self_clang_type)) {967return;968}969if (!TypeSystemClang::IsObjCObjectPointerType(self_clang_type))970return;971self_clang_type = self_clang_type.GetPointeeType();972973if (!self_clang_type)974return;975976LLDB_LOG(log, " FEVD[{0}] Adding type for $__lldb_objc_class: {1}",977ClangUtil::ToString(self_type->GetFullCompilerType()));978979TypeFromUser class_user_type(self_clang_type);980981AddOneType(context, class_user_type);982}983984void ClangExpressionDeclMap::LookupLocalVarNamespace(985SymbolContext &sym_ctx, NameSearchContext &name_context) {986if (sym_ctx.block == nullptr)987return;988989CompilerDeclContext frame_decl_context = sym_ctx.block->GetDeclContext();990if (!frame_decl_context)991return;992993TypeSystemClang *frame_ast = llvm::dyn_cast_or_null<TypeSystemClang>(994frame_decl_context.GetTypeSystem());995if (!frame_ast)996return;997998clang::NamespaceDecl *namespace_decl =999m_clang_ast_context->GetUniqueNamespaceDeclaration(1000g_lldb_local_vars_namespace_cstr, nullptr, OptionalClangModuleID());1001if (!namespace_decl)1002return;10031004name_context.AddNamedDecl(namespace_decl);1005clang::DeclContext *ctxt = clang::Decl::castToDeclContext(namespace_decl);1006ctxt->setHasExternalVisibleStorage(true);1007name_context.m_found_local_vars_nsp = true;1008}10091010void ClangExpressionDeclMap::LookupInModulesDeclVendor(1011NameSearchContext &context, ConstString name) {1012Log *log = GetLog(LLDBLog::Expressions);10131014if (!m_target)1015return;10161017std::shared_ptr<ClangModulesDeclVendor> modules_decl_vendor =1018GetClangModulesDeclVendor();1019if (!modules_decl_vendor)1020return;10211022bool append = false;1023uint32_t max_matches = 1;1024std::vector<clang::NamedDecl *> decls;10251026if (!modules_decl_vendor->FindDecls(name, append, max_matches, decls))1027return;10281029assert(!decls.empty() && "FindDecls returned true but no decls?");1030clang::NamedDecl *const decl_from_modules = decls[0];10311032LLDB_LOG(log,1033" CAS::FEVD Matching decl found for "1034"\"{0}\" in the modules",1035name);10361037clang::Decl *copied_decl = CopyDecl(decl_from_modules);1038if (!copied_decl) {1039LLDB_LOG(log, " CAS::FEVD - Couldn't export a "1040"declaration from the modules");1041return;1042}10431044if (auto copied_function = dyn_cast<clang::FunctionDecl>(copied_decl)) {1045MaybeRegisterFunctionBody(copied_function);10461047context.AddNamedDecl(copied_function);10481049context.m_found_function_with_type_info = true;1050} else if (auto copied_var = dyn_cast<clang::VarDecl>(copied_decl)) {1051context.AddNamedDecl(copied_var);1052context.m_found_variable = true;1053}1054}10551056bool ClangExpressionDeclMap::LookupLocalVariable(1057NameSearchContext &context, ConstString name, SymbolContext &sym_ctx,1058const CompilerDeclContext &namespace_decl) {1059if (sym_ctx.block == nullptr)1060return false;10611062CompilerDeclContext decl_context = sym_ctx.block->GetDeclContext();1063if (!decl_context)1064return false;10651066// Make sure that the variables are parsed so that we have the1067// declarations.1068StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();1069VariableListSP vars = frame->GetInScopeVariableList(true);1070for (size_t i = 0; i < vars->GetSize(); i++)1071vars->GetVariableAtIndex(i)->GetDecl();10721073// Search for declarations matching the name. Do not include imported1074// decls in the search if we are looking for decls in the artificial1075// namespace $__lldb_local_vars.1076std::vector<CompilerDecl> found_decls =1077decl_context.FindDeclByName(name, namespace_decl.IsValid());10781079VariableSP var;1080bool variable_found = false;1081for (CompilerDecl decl : found_decls) {1082for (size_t vi = 0, ve = vars->GetSize(); vi != ve; ++vi) {1083VariableSP candidate_var = vars->GetVariableAtIndex(vi);1084if (candidate_var->GetDecl() == decl) {1085var = candidate_var;1086break;1087}1088}10891090if (var && !variable_found) {1091variable_found = true;1092ValueObjectSP valobj = ValueObjectVariable::Create(frame, var);1093AddOneVariable(context, var, valobj);1094context.m_found_variable = true;1095}1096}10971098// We're in a local_var_lookup but haven't found any local variables1099// so far. When performing a variable lookup from within the context of1100// a lambda, we count the lambda captures as local variables. Thus,1101// see if we captured any variables with the requested 'name'.1102if (!variable_found) {1103auto find_capture = [](ConstString varname,1104StackFrame *frame) -> ValueObjectSP {1105if (auto lambda = ClangExpressionUtil::GetLambdaValueObject(frame)) {1106if (auto capture = lambda->GetChildMemberWithName(varname)) {1107return capture;1108}1109}11101111return nullptr;1112};11131114if (auto capture = find_capture(name, frame)) {1115variable_found = true;1116context.m_found_variable = true;1117AddOneVariable(context, std::move(capture), std::move(find_capture));1118}1119}11201121return variable_found;1122}11231124/// Structure to hold the info needed when comparing function1125/// declarations.1126namespace {1127struct FuncDeclInfo {1128ConstString m_name;1129CompilerType m_copied_type;1130uint32_t m_decl_lvl;1131SymbolContext m_sym_ctx;1132};1133} // namespace11341135SymbolContextList ClangExpressionDeclMap::SearchFunctionsInSymbolContexts(1136const SymbolContextList &sc_list,1137const CompilerDeclContext &frame_decl_context) {1138// First, symplify things by looping through the symbol contexts to1139// remove unwanted functions and separate out the functions we want to1140// compare and prune into a separate list. Cache the info needed about1141// the function declarations in a vector for efficiency.1142SymbolContextList sc_sym_list;1143std::vector<FuncDeclInfo> decl_infos;1144decl_infos.reserve(sc_list.GetSize());1145clang::DeclContext *frame_decl_ctx =1146(clang::DeclContext *)frame_decl_context.GetOpaqueDeclContext();1147TypeSystemClang *ast = llvm::dyn_cast_or_null<TypeSystemClang>(1148frame_decl_context.GetTypeSystem());11491150for (const SymbolContext &sym_ctx : sc_list) {1151FuncDeclInfo fdi;11521153// We don't know enough about symbols to compare them, but we should1154// keep them in the list.1155Function *function = sym_ctx.function;1156if (!function) {1157sc_sym_list.Append(sym_ctx);1158continue;1159}1160// Filter out functions without declaration contexts, as well as1161// class/instance methods, since they'll be skipped in the code that1162// follows anyway.1163CompilerDeclContext func_decl_context = function->GetDeclContext();1164if (!func_decl_context || func_decl_context.IsClassMethod())1165continue;1166// We can only prune functions for which we can copy the type.1167CompilerType func_clang_type = function->GetType()->GetFullCompilerType();1168CompilerType copied_func_type = GuardedCopyType(func_clang_type);1169if (!copied_func_type) {1170sc_sym_list.Append(sym_ctx);1171continue;1172}11731174fdi.m_sym_ctx = sym_ctx;1175fdi.m_name = function->GetName();1176fdi.m_copied_type = copied_func_type;1177fdi.m_decl_lvl = LLDB_INVALID_DECL_LEVEL;1178if (fdi.m_copied_type && func_decl_context) {1179// Call CountDeclLevels to get the number of parent scopes we have1180// to look through before we find the function declaration. When1181// comparing functions of the same type, the one with a lower count1182// will be closer to us in the lookup scope and shadows the other.1183clang::DeclContext *func_decl_ctx =1184(clang::DeclContext *)func_decl_context.GetOpaqueDeclContext();1185fdi.m_decl_lvl = ast->CountDeclLevels(frame_decl_ctx, func_decl_ctx,1186&fdi.m_name, &fdi.m_copied_type);1187}1188decl_infos.emplace_back(fdi);1189}11901191// Loop through the functions in our cache looking for matching types,1192// then compare their scope levels to see which is closer.1193std::multimap<CompilerType, const FuncDeclInfo *> matches;1194for (const FuncDeclInfo &fdi : decl_infos) {1195const CompilerType t = fdi.m_copied_type;1196auto q = matches.find(t);1197if (q != matches.end()) {1198if (q->second->m_decl_lvl > fdi.m_decl_lvl)1199// This function is closer; remove the old set.1200matches.erase(t);1201else if (q->second->m_decl_lvl < fdi.m_decl_lvl)1202// The functions in our set are closer - skip this one.1203continue;1204}1205matches.insert(std::make_pair(t, &fdi));1206}12071208// Loop through our matches and add their symbol contexts to our list.1209SymbolContextList sc_func_list;1210for (const auto &q : matches)1211sc_func_list.Append(q.second->m_sym_ctx);12121213// Rejoin the lists with the functions in front.1214sc_func_list.Append(sc_sym_list);1215return sc_func_list;1216}12171218void ClangExpressionDeclMap::LookupFunction(1219NameSearchContext &context, lldb::ModuleSP module_sp, ConstString name,1220const CompilerDeclContext &namespace_decl) {1221if (!m_parser_vars)1222return;12231224Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();12251226std::vector<clang::NamedDecl *> decls_from_modules;12271228if (target) {1229if (std::shared_ptr<ClangModulesDeclVendor> decl_vendor =1230GetClangModulesDeclVendor()) {1231decl_vendor->FindDecls(name, false, UINT32_MAX, decls_from_modules);1232}1233}12341235SymbolContextList sc_list;1236if (namespace_decl && module_sp) {1237ModuleFunctionSearchOptions function_options;1238function_options.include_inlines = false;1239function_options.include_symbols = false;12401241module_sp->FindFunctions(name, namespace_decl, eFunctionNameTypeBase,1242function_options, sc_list);1243} else if (target && !namespace_decl) {1244ModuleFunctionSearchOptions function_options;1245function_options.include_inlines = false;1246function_options.include_symbols = true;12471248// TODO Fix FindFunctions so that it doesn't return1249// instance methods for eFunctionNameTypeBase.12501251target->GetImages().FindFunctions(1252name, eFunctionNameTypeFull | eFunctionNameTypeBase, function_options,1253sc_list);1254}12551256// If we found more than one function, see if we can use the frame's decl1257// context to remove functions that are shadowed by other functions which1258// match in type but are nearer in scope.1259//1260// AddOneFunction will not add a function whose type has already been1261// added, so if there's another function in the list with a matching type,1262// check to see if their decl context is a parent of the current frame's or1263// was imported via a and using statement, and pick the best match1264// according to lookup rules.1265if (sc_list.GetSize() > 1) {1266// Collect some info about our frame's context.1267StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();1268SymbolContext frame_sym_ctx;1269if (frame != nullptr)1270frame_sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |1271lldb::eSymbolContextBlock);1272CompilerDeclContext frame_decl_context =1273frame_sym_ctx.block != nullptr ? frame_sym_ctx.block->GetDeclContext()1274: CompilerDeclContext();12751276// We can't do this without a compiler decl context for our frame.1277if (frame_decl_context) {1278sc_list = SearchFunctionsInSymbolContexts(sc_list, frame_decl_context);1279}1280}12811282if (sc_list.GetSize()) {1283Symbol *extern_symbol = nullptr;1284Symbol *non_extern_symbol = nullptr;12851286for (const SymbolContext &sym_ctx : sc_list) {1287if (sym_ctx.function) {1288CompilerDeclContext decl_ctx = sym_ctx.function->GetDeclContext();12891290if (!decl_ctx)1291continue;12921293// Filter out class/instance methods.1294if (decl_ctx.IsClassMethod())1295continue;12961297AddOneFunction(context, sym_ctx.function, nullptr);1298context.m_found_function_with_type_info = true;1299} else if (sym_ctx.symbol) {1300Symbol *symbol = sym_ctx.symbol;1301if (target && symbol->GetType() == eSymbolTypeReExported) {1302symbol = symbol->ResolveReExportedSymbol(*target);1303if (symbol == nullptr)1304continue;1305}13061307if (symbol->IsExternal())1308extern_symbol = symbol;1309else1310non_extern_symbol = symbol;1311}1312}13131314if (!context.m_found_function_with_type_info) {1315for (clang::NamedDecl *decl : decls_from_modules) {1316if (llvm::isa<clang::FunctionDecl>(decl)) {1317clang::NamedDecl *copied_decl =1318llvm::cast_or_null<FunctionDecl>(CopyDecl(decl));1319if (copied_decl) {1320context.AddNamedDecl(copied_decl);1321context.m_found_function_with_type_info = true;1322}1323}1324}1325}13261327if (!context.m_found_function_with_type_info) {1328if (extern_symbol) {1329AddOneFunction(context, nullptr, extern_symbol);1330} else if (non_extern_symbol) {1331AddOneFunction(context, nullptr, non_extern_symbol);1332}1333}1334}1335}13361337void ClangExpressionDeclMap::FindExternalVisibleDecls(1338NameSearchContext &context, lldb::ModuleSP module_sp,1339const CompilerDeclContext &namespace_decl) {1340assert(m_ast_context);13411342Log *log = GetLog(LLDBLog::Expressions);13431344const ConstString name(context.m_decl_name.getAsString().c_str());1345if (IgnoreName(name, false))1346return;13471348// Only look for functions by name out in our symbols if the function doesn't1349// start with our phony prefix of '$'13501351Target *target = nullptr;1352StackFrame *frame = nullptr;1353SymbolContext sym_ctx;1354if (m_parser_vars) {1355target = m_parser_vars->m_exe_ctx.GetTargetPtr();1356frame = m_parser_vars->m_exe_ctx.GetFramePtr();1357}1358if (frame != nullptr)1359sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |1360lldb::eSymbolContextBlock);13611362// Try the persistent decls, which take precedence over all else.1363if (!namespace_decl)1364SearchPersistenDecls(context, name);13651366if (name.GetStringRef().starts_with("$") && !namespace_decl) {1367if (name == "$__lldb_class") {1368LookUpLldbClass(context);1369return;1370}13711372if (name == "$__lldb_objc_class") {1373LookUpLldbObjCClass(context);1374return;1375}1376if (name == g_lldb_local_vars_namespace_cstr) {1377LookupLocalVarNamespace(sym_ctx, context);1378return;1379}13801381// any other $__lldb names should be weeded out now1382if (name.GetStringRef().starts_with("$__lldb"))1383return;13841385// No ParserVars means we can't do register or variable lookup.1386if (!m_parser_vars || !m_parser_vars->m_persistent_vars)1387return;13881389ExpressionVariableSP pvar_sp(1390m_parser_vars->m_persistent_vars->GetVariable(name));13911392if (pvar_sp) {1393AddOneVariable(context, pvar_sp);1394return;1395}13961397assert(name.GetStringRef().starts_with("$"));1398llvm::StringRef reg_name = name.GetStringRef().substr(1);13991400if (m_parser_vars->m_exe_ctx.GetRegisterContext()) {1401const RegisterInfo *reg_info(1402m_parser_vars->m_exe_ctx.GetRegisterContext()->GetRegisterInfoByName(1403reg_name));14041405if (reg_info) {1406LLDB_LOG(log, " CEDM::FEVD Found register {0}", reg_info->name);14071408AddOneRegister(context, reg_info);1409}1410}1411return;1412}14131414bool local_var_lookup = !namespace_decl || (namespace_decl.GetName() ==1415g_lldb_local_vars_namespace_cstr);1416if (frame && local_var_lookup)1417if (LookupLocalVariable(context, name, sym_ctx, namespace_decl))1418return;14191420if (target) {1421ValueObjectSP valobj;1422VariableSP var;1423var = FindGlobalVariable(*target, module_sp, name, namespace_decl);14241425if (var) {1426valobj = ValueObjectVariable::Create(target, var);1427AddOneVariable(context, var, valobj);1428context.m_found_variable = true;1429return;1430}1431}14321433LookupFunction(context, module_sp, name, namespace_decl);14341435// Try the modules next.1436if (!context.m_found_function_with_type_info)1437LookupInModulesDeclVendor(context, name);14381439if (target && !context.m_found_variable && !namespace_decl) {1440// We couldn't find a non-symbol variable for this. Now we'll hunt for a1441// generic data symbol, and -- if it is found -- treat it as a variable.1442Status error;14431444const Symbol *data_symbol =1445m_parser_vars->m_sym_ctx.FindBestGlobalDataSymbol(name, error);14461447if (!error.Success()) {1448const unsigned diag_id =1449m_ast_context->getDiagnostics().getCustomDiagID(1450clang::DiagnosticsEngine::Level::Error, "%0");1451m_ast_context->getDiagnostics().Report(diag_id) << error.AsCString();1452}14531454if (data_symbol) {1455std::string warning("got name from symbols: ");1456warning.append(name.AsCString());1457const unsigned diag_id =1458m_ast_context->getDiagnostics().getCustomDiagID(1459clang::DiagnosticsEngine::Level::Warning, "%0");1460m_ast_context->getDiagnostics().Report(diag_id) << warning.c_str();1461AddOneGenericVariable(context, *data_symbol);1462context.m_found_variable = true;1463}1464}1465}14661467bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var,1468lldb_private::Value &var_location,1469TypeFromUser *user_type,1470TypeFromParser *parser_type) {1471Log *log = GetLog(LLDBLog::Expressions);14721473Type *var_type = var->GetType();14741475if (!var_type) {1476LLDB_LOG(log, "Skipped a definition because it has no type");1477return false;1478}14791480CompilerType var_clang_type = var_type->GetFullCompilerType();14811482if (!var_clang_type) {1483LLDB_LOG(log, "Skipped a definition because it has no Clang type");1484return false;1485}14861487auto ts = var_type->GetForwardCompilerType().GetTypeSystem();1488auto clang_ast = ts.dyn_cast_or_null<TypeSystemClang>();14891490if (!clang_ast) {1491LLDB_LOG(log, "Skipped a definition because it has no Clang AST");1492return false;1493}14941495DWARFExpressionList &var_location_list = var->LocationExpressionList();14961497Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();1498Status err;14991500if (var->GetLocationIsConstantValueData()) {1501DataExtractor const_value_extractor;1502if (var_location_list.GetExpressionData(const_value_extractor)) {1503var_location = Value(const_value_extractor.GetDataStart(),1504const_value_extractor.GetByteSize());1505var_location.SetValueType(Value::ValueType::HostAddress);1506} else {1507LLDB_LOG(log, "Error evaluating constant variable: {0}", err.AsCString());1508return false;1509}1510}15111512CompilerType type_to_use = GuardedCopyType(var_clang_type);15131514if (!type_to_use) {1515LLDB_LOG(log,1516"Couldn't copy a variable's type into the parser's AST context");15171518return false;1519}15201521if (parser_type)1522*parser_type = TypeFromParser(type_to_use);15231524if (var_location.GetContextType() == Value::ContextType::Invalid)1525var_location.SetCompilerType(type_to_use);15261527if (var_location.GetValueType() == Value::ValueType::FileAddress) {1528SymbolContext var_sc;1529var->CalculateSymbolContext(&var_sc);15301531if (!var_sc.module_sp)1532return false;15331534Address so_addr(var_location.GetScalar().ULongLong(),1535var_sc.module_sp->GetSectionList());15361537lldb::addr_t load_addr = so_addr.GetLoadAddress(target);15381539if (load_addr != LLDB_INVALID_ADDRESS) {1540var_location.GetScalar() = load_addr;1541var_location.SetValueType(Value::ValueType::LoadAddress);1542}1543}15441545if (user_type)1546*user_type = TypeFromUser(var_clang_type);15471548return true;1549}15501551ClangExpressionVariable::ParserVars *1552ClangExpressionDeclMap::AddExpressionVariable(NameSearchContext &context,1553TypeFromParser const &pt,1554ValueObjectSP valobj) {1555clang::QualType parser_opaque_type =1556QualType::getFromOpaquePtr(pt.GetOpaqueQualType());15571558if (parser_opaque_type.isNull())1559return nullptr;15601561if (const clang::Type *parser_type = parser_opaque_type.getTypePtr()) {1562if (const TagType *tag_type = dyn_cast<TagType>(parser_type))1563CompleteType(tag_type->getDecl());1564if (const ObjCObjectPointerType *objc_object_ptr_type =1565dyn_cast<ObjCObjectPointerType>(parser_type))1566CompleteType(objc_object_ptr_type->getInterfaceDecl());1567}15681569bool is_reference = pt.IsReferenceType();15701571NamedDecl *var_decl = nullptr;1572if (is_reference)1573var_decl = context.AddVarDecl(pt);1574else1575var_decl = context.AddVarDecl(pt.GetLValueReferenceType());15761577std::string decl_name(context.m_decl_name.getAsString());1578ConstString entity_name(decl_name.c_str());1579ClangExpressionVariable *entity(new ClangExpressionVariable(valobj));1580m_found_entities.AddNewlyConstructedVariable(entity);15811582assert(entity);1583entity->EnableParserVars(GetParserID());1584ClangExpressionVariable::ParserVars *parser_vars =1585entity->GetParserVars(GetParserID());15861587parser_vars->m_named_decl = var_decl;15881589if (is_reference)1590entity->m_flags |= ClangExpressionVariable::EVTypeIsReference;15911592return parser_vars;1593}15941595void ClangExpressionDeclMap::AddOneVariable(1596NameSearchContext &context, ValueObjectSP valobj,1597ValueObjectProviderTy valobj_provider) {1598assert(m_parser_vars.get());1599assert(valobj);16001601Log *log = GetLog(LLDBLog::Expressions);16021603Value var_location = valobj->GetValue();16041605TypeFromUser user_type = valobj->GetCompilerType();16061607auto clang_ast =1608user_type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>();16091610if (!clang_ast) {1611LLDB_LOG(log, "Skipped a definition because it has no Clang AST");1612return;1613}16141615TypeFromParser parser_type = GuardedCopyType(user_type);16161617if (!parser_type) {1618LLDB_LOG(log,1619"Couldn't copy a variable's type into the parser's AST context");16201621return;1622}16231624if (var_location.GetContextType() == Value::ContextType::Invalid)1625var_location.SetCompilerType(parser_type);16261627ClangExpressionVariable::ParserVars *parser_vars =1628AddExpressionVariable(context, parser_type, valobj);16291630if (!parser_vars)1631return;16321633LLDB_LOG(log, " CEDM::FEVD Found variable {0}, returned\n{1} (original {2})",1634context.m_decl_name, ClangUtil::DumpDecl(parser_vars->m_named_decl),1635ClangUtil::ToString(user_type));16361637parser_vars->m_llvm_value = nullptr;1638parser_vars->m_lldb_value = std::move(var_location);1639parser_vars->m_lldb_valobj_provider = std::move(valobj_provider);1640}16411642void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,1643VariableSP var,1644ValueObjectSP valobj) {1645assert(m_parser_vars.get());16461647Log *log = GetLog(LLDBLog::Expressions);16481649TypeFromUser ut;1650TypeFromParser pt;1651Value var_location;16521653if (!GetVariableValue(var, var_location, &ut, &pt))1654return;16551656ClangExpressionVariable::ParserVars *parser_vars =1657AddExpressionVariable(context, pt, std::move(valobj));16581659if (!parser_vars)1660return;16611662LLDB_LOG(log, " CEDM::FEVD Found variable {0}, returned\n{1} (original {2})",1663context.m_decl_name, ClangUtil::DumpDecl(parser_vars->m_named_decl),1664ClangUtil::ToString(ut));16651666parser_vars->m_llvm_value = nullptr;1667parser_vars->m_lldb_value = var_location;1668parser_vars->m_lldb_var = var;1669}16701671void ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context,1672ExpressionVariableSP &pvar_sp) {1673Log *log = GetLog(LLDBLog::Expressions);16741675TypeFromUser user_type(1676llvm::cast<ClangExpressionVariable>(pvar_sp.get())->GetTypeFromUser());16771678TypeFromParser parser_type(GuardedCopyType(user_type));16791680if (!parser_type.GetOpaqueQualType()) {1681LLDB_LOG(log, " CEDM::FEVD Couldn't import type for pvar {0}",1682pvar_sp->GetName());1683return;1684}16851686NamedDecl *var_decl =1687context.AddVarDecl(parser_type.GetLValueReferenceType());16881689llvm::cast<ClangExpressionVariable>(pvar_sp.get())1690->EnableParserVars(GetParserID());1691ClangExpressionVariable::ParserVars *parser_vars =1692llvm::cast<ClangExpressionVariable>(pvar_sp.get())1693->GetParserVars(GetParserID());1694parser_vars->m_named_decl = var_decl;1695parser_vars->m_llvm_value = nullptr;1696parser_vars->m_lldb_value.Clear();16971698LLDB_LOG(log, " CEDM::FEVD Added pvar {0}, returned\n{1}",1699pvar_sp->GetName(), ClangUtil::DumpDecl(var_decl));1700}17011702void ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context,1703const Symbol &symbol) {1704assert(m_parser_vars.get());17051706Log *log = GetLog(LLDBLog::Expressions);17071708Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();17091710if (target == nullptr)1711return;17121713auto scratch_ast_context = GetScratchContext(*target);1714if (!scratch_ast_context)1715return;17161717TypeFromUser user_type(scratch_ast_context->GetBasicType(eBasicTypeVoid)1718.GetPointerType()1719.GetLValueReferenceType());1720TypeFromParser parser_type(m_clang_ast_context->GetBasicType(eBasicTypeVoid)1721.GetPointerType()1722.GetLValueReferenceType());1723NamedDecl *var_decl = context.AddVarDecl(parser_type);17241725std::string decl_name(context.m_decl_name.getAsString());1726ConstString entity_name(decl_name.c_str());1727ClangExpressionVariable *entity(new ClangExpressionVariable(1728m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), entity_name,1729user_type, m_parser_vars->m_target_info.byte_order,1730m_parser_vars->m_target_info.address_byte_size));1731m_found_entities.AddNewlyConstructedVariable(entity);17321733entity->EnableParserVars(GetParserID());1734ClangExpressionVariable::ParserVars *parser_vars =1735entity->GetParserVars(GetParserID());17361737const Address symbol_address = symbol.GetAddress();1738lldb::addr_t symbol_load_addr = symbol_address.GetLoadAddress(target);17391740// parser_vars->m_lldb_value.SetContext(Value::ContextType::ClangType,1741// user_type.GetOpaqueQualType());1742parser_vars->m_lldb_value.SetCompilerType(user_type);1743parser_vars->m_lldb_value.GetScalar() = symbol_load_addr;1744parser_vars->m_lldb_value.SetValueType(Value::ValueType::LoadAddress);17451746parser_vars->m_named_decl = var_decl;1747parser_vars->m_llvm_value = nullptr;1748parser_vars->m_lldb_sym = &symbol;17491750LLDB_LOG(log, " CEDM::FEVD Found variable {0}, returned\n{1}", decl_name,1751ClangUtil::DumpDecl(var_decl));1752}17531754void ClangExpressionDeclMap::AddOneRegister(NameSearchContext &context,1755const RegisterInfo *reg_info) {1756Log *log = GetLog(LLDBLog::Expressions);17571758CompilerType clang_type =1759m_clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(1760reg_info->encoding, reg_info->byte_size * 8);17611762if (!clang_type) {1763LLDB_LOG(log, " Tried to add a type for {0}, but couldn't get one",1764context.m_decl_name.getAsString());1765return;1766}17671768TypeFromParser parser_clang_type(clang_type);17691770NamedDecl *var_decl = context.AddVarDecl(parser_clang_type);17711772ClangExpressionVariable *entity(new ClangExpressionVariable(1773m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),1774m_parser_vars->m_target_info.byte_order,1775m_parser_vars->m_target_info.address_byte_size));1776m_found_entities.AddNewlyConstructedVariable(entity);17771778std::string decl_name(context.m_decl_name.getAsString());1779entity->SetName(ConstString(decl_name.c_str()));1780entity->SetRegisterInfo(reg_info);1781entity->EnableParserVars(GetParserID());1782ClangExpressionVariable::ParserVars *parser_vars =1783entity->GetParserVars(GetParserID());1784parser_vars->m_named_decl = var_decl;1785parser_vars->m_llvm_value = nullptr;1786parser_vars->m_lldb_value.Clear();1787entity->m_flags |= ClangExpressionVariable::EVBareRegister;17881789LLDB_LOG(log, " CEDM::FEVD Added register {0}, returned\n{1}",1790context.m_decl_name.getAsString(), ClangUtil::DumpDecl(var_decl));1791}17921793void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context,1794Function *function,1795Symbol *symbol) {1796assert(m_parser_vars.get());17971798Log *log = GetLog(LLDBLog::Expressions);17991800NamedDecl *function_decl = nullptr;1801Address fun_address;1802CompilerType function_clang_type;18031804bool is_indirect_function = false;18051806if (function) {1807Type *function_type = function->GetType();18081809const auto lang = function->GetCompileUnit()->GetLanguage();1810const auto name = function->GetMangled().GetMangledName().AsCString();1811const bool extern_c = (Language::LanguageIsC(lang) &&1812!CPlusPlusLanguage::IsCPPMangledName(name)) ||1813(Language::LanguageIsObjC(lang) &&1814!Language::LanguageIsCPlusPlus(lang));18151816if (!extern_c) {1817TypeSystem *type_system = function->GetDeclContext().GetTypeSystem();1818if (llvm::isa<TypeSystemClang>(type_system)) {1819clang::DeclContext *src_decl_context =1820(clang::DeclContext *)function->GetDeclContext()1821.GetOpaqueDeclContext();1822clang::FunctionDecl *src_function_decl =1823llvm::dyn_cast_or_null<clang::FunctionDecl>(src_decl_context);1824if (src_function_decl &&1825src_function_decl->getTemplateSpecializationInfo()) {1826clang::FunctionTemplateDecl *function_template =1827src_function_decl->getTemplateSpecializationInfo()->getTemplate();1828clang::FunctionTemplateDecl *copied_function_template =1829llvm::dyn_cast_or_null<clang::FunctionTemplateDecl>(1830CopyDecl(function_template));1831if (copied_function_template) {1832if (log) {1833StreamString ss;18341835function->DumpSymbolContext(&ss);18361837LLDB_LOG(log,1838" CEDM::FEVD Imported decl for function template"1839" {0} (description {1}), returned\n{2}",1840copied_function_template->getNameAsString(),1841ss.GetData(),1842ClangUtil::DumpDecl(copied_function_template));1843}18441845context.AddNamedDecl(copied_function_template);1846}1847} else if (src_function_decl) {1848if (clang::FunctionDecl *copied_function_decl =1849llvm::dyn_cast_or_null<clang::FunctionDecl>(1850CopyDecl(src_function_decl))) {1851if (log) {1852StreamString ss;18531854function->DumpSymbolContext(&ss);18551856LLDB_LOG(log,1857" CEDM::FEVD Imported decl for function {0} "1858"(description {1}), returned\n{2}",1859copied_function_decl->getNameAsString(), ss.GetData(),1860ClangUtil::DumpDecl(copied_function_decl));1861}18621863context.AddNamedDecl(copied_function_decl);1864return;1865} else {1866LLDB_LOG(log, " Failed to import the function decl for '{0}'",1867src_function_decl->getName());1868}1869}1870}1871}18721873if (!function_type) {1874LLDB_LOG(log, " Skipped a function because it has no type");1875return;1876}18771878function_clang_type = function_type->GetFullCompilerType();18791880if (!function_clang_type) {1881LLDB_LOG(log, " Skipped a function because it has no Clang type");1882return;1883}18841885fun_address = function->GetAddressRange().GetBaseAddress();18861887CompilerType copied_function_type = GuardedCopyType(function_clang_type);1888if (copied_function_type) {1889function_decl = context.AddFunDecl(copied_function_type, extern_c);18901891if (!function_decl) {1892LLDB_LOG(log, " Failed to create a function decl for '{0}' ({1:x})",1893function_type->GetName(), function_type->GetID());18941895return;1896}1897} else {1898// We failed to copy the type we found1899LLDB_LOG(log,1900" Failed to import the function type '{0}' ({1:x})"1901" into the expression parser AST context",1902function_type->GetName(), function_type->GetID());19031904return;1905}1906} else if (symbol) {1907fun_address = symbol->GetAddress();1908function_decl = context.AddGenericFunDecl();1909is_indirect_function = symbol->IsIndirect();1910} else {1911LLDB_LOG(log, " AddOneFunction called with no function and no symbol");1912return;1913}19141915Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();19161917lldb::addr_t load_addr =1918fun_address.GetCallableLoadAddress(target, is_indirect_function);19191920ClangExpressionVariable *entity(new ClangExpressionVariable(1921m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),1922m_parser_vars->m_target_info.byte_order,1923m_parser_vars->m_target_info.address_byte_size));1924m_found_entities.AddNewlyConstructedVariable(entity);19251926std::string decl_name(context.m_decl_name.getAsString());1927entity->SetName(ConstString(decl_name.c_str()));1928entity->SetCompilerType(function_clang_type);1929entity->EnableParserVars(GetParserID());19301931ClangExpressionVariable::ParserVars *parser_vars =1932entity->GetParserVars(GetParserID());19331934if (load_addr != LLDB_INVALID_ADDRESS) {1935parser_vars->m_lldb_value.SetValueType(Value::ValueType::LoadAddress);1936parser_vars->m_lldb_value.GetScalar() = load_addr;1937} else {1938// We have to try finding a file address.19391940lldb::addr_t file_addr = fun_address.GetFileAddress();19411942parser_vars->m_lldb_value.SetValueType(Value::ValueType::FileAddress);1943parser_vars->m_lldb_value.GetScalar() = file_addr;1944}19451946parser_vars->m_named_decl = function_decl;1947parser_vars->m_llvm_value = nullptr;19481949if (log) {1950StreamString ss;19511952fun_address.Dump(&ss,1953m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(),1954Address::DumpStyleResolvedDescription);19551956LLDB_LOG(log,1957" CEDM::FEVD Found {0} function {1} (description {2}), "1958"returned\n{3}",1959(function ? "specific" : "generic"), decl_name, ss.GetData(),1960ClangUtil::DumpDecl(function_decl));1961}1962}19631964void ClangExpressionDeclMap::AddContextClassType(NameSearchContext &context,1965const TypeFromUser &ut) {1966CompilerType copied_clang_type = GuardedCopyType(ut);19671968Log *log = GetLog(LLDBLog::Expressions);19691970if (!copied_clang_type) {1971LLDB_LOG(log,1972"ClangExpressionDeclMap::AddThisType - Couldn't import the type");19731974return;1975}19761977if (copied_clang_type.IsAggregateType() &&1978copied_clang_type.GetCompleteType()) {1979CompilerType void_clang_type =1980m_clang_ast_context->GetBasicType(eBasicTypeVoid);1981CompilerType void_ptr_clang_type = void_clang_type.GetPointerType();19821983CompilerType method_type = m_clang_ast_context->CreateFunctionType(1984void_clang_type, &void_ptr_clang_type, 1, false, 0);19851986const bool is_virtual = false;1987const bool is_static = false;1988const bool is_inline = false;1989const bool is_explicit = false;1990const bool is_attr_used = true;1991const bool is_artificial = false;19921993CXXMethodDecl *method_decl = m_clang_ast_context->AddMethodToCXXRecordType(1994copied_clang_type.GetOpaqueQualType(), "$__lldb_expr", nullptr,1995method_type, lldb::eAccessPublic, is_virtual, is_static, is_inline,1996is_explicit, is_attr_used, is_artificial);19971998LLDB_LOG(log,1999" CEDM::AddThisType Added function $__lldb_expr "2000"(description {0}) for this type\n{1}",2001ClangUtil::ToString(copied_clang_type),2002ClangUtil::DumpDecl(method_decl));2003}20042005if (!copied_clang_type.IsValid())2006return;20072008TypeSourceInfo *type_source_info = m_ast_context->getTrivialTypeSourceInfo(2009QualType::getFromOpaquePtr(copied_clang_type.GetOpaqueQualType()));20102011if (!type_source_info)2012return;20132014// Construct a typedef type because if "*this" is a templated type we can't2015// just return ClassTemplateSpecializationDecls in response to name queries.2016// Using a typedef makes this much more robust.20172018TypedefDecl *typedef_decl = TypedefDecl::Create(2019*m_ast_context, m_ast_context->getTranslationUnitDecl(), SourceLocation(),2020SourceLocation(), context.m_decl_name.getAsIdentifierInfo(),2021type_source_info);20222023if (!typedef_decl)2024return;20252026context.AddNamedDecl(typedef_decl);2027}20282029void ClangExpressionDeclMap::AddOneType(NameSearchContext &context,2030const TypeFromUser &ut) {2031CompilerType copied_clang_type = GuardedCopyType(ut);20322033if (!copied_clang_type) {2034Log *log = GetLog(LLDBLog::Expressions);20352036LLDB_LOG(log,2037"ClangExpressionDeclMap::AddOneType - Couldn't import the type");20382039return;2040}20412042context.AddTypeDecl(copied_clang_type);2043}204420452046