================ @@ -0,0 +1,468 @@ +//===-- DILAST.cpp --------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "lldb/Core/DILAST.h" +#include "lldb/API/SBType.h" +#include "lldb/Core/ValueObjectRegister.h" +#include "lldb/Core/ValueObjectVariable.h" +#include "lldb/Symbol/TypeList.h" +#include "lldb/Symbol/VariableList.h" +#include "lldb/Target/LanguageRuntime.h" +#include "lldb/Target/RegisterContext.h" +#include "llvm/ADT/StringRef.h" + +#include <vector> + +namespace lldb_private { + +lldb::ValueObjectSP DILGetSPWithLock(lldb::ValueObjectSP in_valobj_sp, + lldb::DynamicValueType use_dynamic, + bool use_synthetic) { + Process::StopLocker stop_locker; + std::unique_lock<std::recursive_mutex> lock; + Status error; + + if (!in_valobj_sp) { + error.SetErrorString("invalid value object"); + return in_valobj_sp; + } + + lldb::ValueObjectSP value_sp = in_valobj_sp; + + Target *target = value_sp->GetTargetSP().get(); + // If this ValueObject holds an error, then it is valuable for that. + if (value_sp->GetError().Fail()) + return value_sp; + + if (!target) + return lldb::ValueObjectSP(); + + lock = std::unique_lock<std::recursive_mutex>(target->GetAPIMutex()); + + lldb::ProcessSP process_sp(value_sp->GetProcessSP()); + if (process_sp && !stop_locker.TryLock(&process_sp->GetRunLock())) { + // We don't allow people to play around with ValueObject if the process + // is running. If you want to look at values, pause the process, then + // look. + error.SetErrorString("process must be stopped."); + return lldb::ValueObjectSP(); + } + + if (use_dynamic != lldb::eNoDynamicValues) { + lldb::ValueObjectSP dynamic_sp = value_sp->GetDynamicValue(use_dynamic); + if (dynamic_sp) + value_sp = dynamic_sp; + } + + if (use_synthetic) { + lldb::ValueObjectSP synthetic_sp = value_sp->GetSyntheticValue(); + if (synthetic_sp) + value_sp = synthetic_sp; + } + + if (!value_sp) + error.SetErrorString("invalid value object"); + + return value_sp; +} + +CompilerType DILASTNode::result_type_deref() const { + auto type = result_type(); + return type.IsReferenceType() ? type.GetNonReferenceType() : type; +} + +static std::unordered_map<std::string, CompilerType> context_args; + +bool IsContextVar(const std::string &name) { + return context_args.find(name) != context_args.end(); +} + +static lldb::ValueObjectSP +LookupStaticIdentifier(lldb::TargetSP target_sp, + const llvm::StringRef &name_ref, + ConstString unqualified_name) { + // List global variable with the same "basename". There can be many matches + // from other scopes (namespaces, classes), so we do additional filtering + // later. + std::vector<lldb::ValueObjectSP> values; + VariableList variable_list; + ConstString name(name_ref); + target_sp->GetImages().FindGlobalVariables( + name, (size_t)std::numeric_limits<uint32_t>::max, variable_list); + if (!variable_list.Empty()) { + ExecutionContextScope *exe_scope = target_sp->GetProcessSP().get(); + if (exe_scope == nullptr) + exe_scope = target_sp.get(); + for (const lldb::VariableSP &var_sp : variable_list) { + lldb::ValueObjectSP valobj_sp( + ValueObjectVariable::Create(exe_scope, var_sp)); + if (valobj_sp) + values.push_back(valobj_sp); + } + } + + // Find the corrent variable by matching the name. lldb::SBValue::GetName() + // can return strings like "::globarVar", "ns::i" or "int const ns::foo" + // depending on the version and the platform. + for (uint32_t i = 0; i < values.size(); ++i) { + lldb::ValueObjectSP val = values[i]; + llvm::StringRef val_name_sstr = val->GetName().GetStringRef(); + llvm::StringRef name_sstr = name.GetStringRef(); + + if (val->GetVariable() && val->GetVariable()->NameMatches(unqualified_name)) + return val; + + if (val_name_sstr == name_sstr || + val_name_sstr == llvm::formatv("::{0}", name_sstr).str() || + val_name_sstr.ends_with(llvm::formatv(" {0}", name_sstr).str()) || + val_name_sstr.ends_with(llvm::formatv("*{0}", name_sstr).str()) || + val_name_sstr.ends_with(llvm::formatv("&{0}", name_sstr).str())) + return val; + } + lldb::ValueObjectSP empty_obj_sp; + return empty_obj_sp; +} + +struct EnumMember { + CompilerType type; + ConstString name; + llvm::APSInt value; +}; + +static std::vector<EnumMember> GetEnumMembers(CompilerType type) { + std::vector<EnumMember> enum_member_list; + if (type.IsValid()) { + type.ForEachEnumerator( + [&enum_member_list](const CompilerType &integer_type, ConstString name, + const llvm::APSInt &value) -> bool { + EnumMember enum_member = {integer_type, name, value}; + enum_member_list.push_back(enum_member); + return true; // Keep iterating + }); + } + return enum_member_list; +} + +CompilerType +ResolveTypeByName(const std::string &name, + std::shared_ptr<ExecutionContextScope> ctx_scope) { + // Internally types don't have global scope qualifier in their names and + // LLDB doesn't support queries with it too. + llvm::StringRef name_ref(name); + bool global_scope = false; + + if (name_ref.starts_with("::")) { + name_ref = name_ref.drop_front(2); + global_scope = true; + } + + std::vector<CompilerType> result_type_list; + lldb::TargetSP target_sp = ctx_scope->CalculateTarget(); + const char *type_name = name_ref.data(); + if (type_name && type_name[0] && target_sp) { + ModuleList &images = target_sp->GetImages(); + ConstString const_type_name(type_name); + TypeQuery query(type_name); + TypeResults results; + images.FindTypes(nullptr, query, results); + for (const lldb::TypeSP &type_sp : results.GetTypeMap().Types()) + if (type_sp) + result_type_list.push_back(type_sp->GetFullCompilerType()); + + if (auto process_sp = target_sp->GetProcessSP()) { + for (auto *runtime : process_sp->GetLanguageRuntimes()) { + if (auto *vendor = runtime->GetDeclVendor()) { + auto types = vendor->FindTypes(const_type_name, UINT32_MAX); + for (auto type : types) + result_type_list.push_back(type); + } + } + } + + if (result_type_list.size() == 0) { + for (auto type_system_sp : target_sp->GetScratchTypeSystems()) + if (auto compiler_type = + type_system_sp->GetBuiltinTypeByName(const_type_name)) + result_type_list.push_back(compiler_type); + } + } + + // We've found multiple types, try finding the "correct" one. + CompilerType full_match; + std::vector<CompilerType> partial_matches; + + for (uint32_t i = 0; i < result_type_list.size(); ++i) { + CompilerType type = result_type_list[i]; + llvm::StringRef type_name_ref = type.GetTypeName().GetStringRef(); + ; + + if (type_name_ref == name_ref) + full_match = type; + else if (type_name_ref.ends_with(name_ref)) + partial_matches.push_back(type); + } + + if (global_scope) { + // Look only for full matches when looking for a globally qualified type. + if (full_match.IsValid()) + return full_match; + } else { + // We're looking for type, but there may be multiple candidates and which + // one is correct may depend on the currect scope. For now just pick the + // most "probable" type. + + // Full match is always correct if we're currently in the global scope. + if (full_match.IsValid()) + return full_match; + + // If we have partial matches, pick a "random" one. + if (partial_matches.size() > 0) + return partial_matches.back(); + } + + CompilerType empty_type; + return empty_type; +} + +static lldb::VariableSP DILFindVariable(ConstString name, + VariableList *variable_list) { + lldb::VariableSP exact_match; + std::vector<lldb::VariableSP> possible_matches; + + typedef std::vector<lldb::VariableSP> collection; + typedef collection::iterator iterator; + + iterator pos, end = variable_list->end(); + for (pos = variable_list->begin(); pos != end; ++pos) { + llvm::StringRef str_ref_name = pos->get()->GetName().GetStringRef(); + // Check for global vars, which might start with '::'. + if (str_ref_name.size() > 2 && str_ref_name[0] == ':' && + str_ref_name[1] == ':') + str_ref_name = str_ref_name.drop_front(2); + + ConstString tmp_name(str_ref_name); + if (tmp_name == name) ---------------- cmtice wrote:
Done. https://github.com/llvm/llvm-project/pull/95738 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits