1//===-- ClangPersistentVariables.cpp --------------------------------------===// 2// 3// 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 6// 7//===----------------------------------------------------------------------===// 8 9#include "ClangPersistentVariables.h" 10#include "ClangASTImporter.h" 11#include "ClangModulesDeclVendor.h" 12 13#include "Plugins/TypeSystem/Clang/TypeSystemClang.h" 14#include "lldb/Core/Value.h" 15#include "lldb/Target/Target.h" 16#include "lldb/Utility/DataExtractor.h" 17#include "lldb/Utility/Log.h" 18#include "lldb/Utility/StreamString.h" 19 20#include "clang/AST/Decl.h" 21 22#include "llvm/ADT/StringMap.h" 23#include <optional> 24#include <memory> 25 26using namespace lldb; 27using namespace lldb_private; 28 29ClangPersistentVariables::ClangPersistentVariables( 30 std::shared_ptr<Target> target_sp) 31 : lldb_private::PersistentExpressionState(LLVMCastKind::eKindClang), 32 m_target_sp(target_sp) {} 33 34ExpressionVariableSP ClangPersistentVariables::CreatePersistentVariable( 35 const lldb::ValueObjectSP &valobj_sp) { 36 return AddNewlyConstructedVariable(new ClangExpressionVariable(valobj_sp)); 37} 38 39ExpressionVariableSP ClangPersistentVariables::CreatePersistentVariable( 40 ExecutionContextScope *exe_scope, ConstString name, 41 const CompilerType &compiler_type, lldb::ByteOrder byte_order, 42 uint32_t addr_byte_size) { 43 return AddNewlyConstructedVariable(new ClangExpressionVariable( 44 exe_scope, name, compiler_type, byte_order, addr_byte_size)); 45} 46 47void ClangPersistentVariables::RemovePersistentVariable( 48 lldb::ExpressionVariableSP variable) { 49 RemoveVariable(variable); 50 51 // Check if the removed variable was the last one that was created. If yes, 52 // reuse the variable id for the next variable. 53 54 // Nothing to do if we have not assigned a variable id so far. 55 if (m_next_persistent_variable_id == 0) 56 return; 57 58 llvm::StringRef name = variable->GetName().GetStringRef(); 59 // Remove the prefix from the variable that only the indes is left. 60 if (!name.consume_front(GetPersistentVariablePrefix(false))) 61 return; 62 63 // Check if the variable contained a variable id. 64 uint32_t variable_id; 65 if (name.getAsInteger(10, variable_id)) 66 return; 67 // If it's the most recent variable id that was assigned, make sure that this 68 // variable id will be used for the next persistent variable. 69 if (variable_id == m_next_persistent_variable_id - 1) 70 m_next_persistent_variable_id--; 71} 72 73std::optional<CompilerType> 74ClangPersistentVariables::GetCompilerTypeFromPersistentDecl( 75 ConstString type_name) { 76 PersistentDecl p = m_persistent_decls.lookup(type_name.GetCString()); 77 78 if (p.m_decl == nullptr) 79 return std::nullopt; 80 81 if (clang::TypeDecl *tdecl = llvm::dyn_cast<clang::TypeDecl>(p.m_decl)) { 82 opaque_compiler_type_t t = static_cast<opaque_compiler_type_t>( 83 const_cast<clang::Type *>(tdecl->getTypeForDecl())); 84 return CompilerType(p.m_context, t); 85 } 86 return std::nullopt; 87} 88 89void ClangPersistentVariables::RegisterPersistentDecl( 90 ConstString name, clang::NamedDecl *decl, 91 std::shared_ptr<TypeSystemClang> ctx) { 92 PersistentDecl p = {decl, ctx}; 93 m_persistent_decls.insert(std::make_pair(name.GetCString(), p)); 94 95 if (clang::EnumDecl *enum_decl = llvm::dyn_cast<clang::EnumDecl>(decl)) { 96 for (clang::EnumConstantDecl *enumerator_decl : enum_decl->enumerators()) { 97 p = {enumerator_decl, ctx}; 98 m_persistent_decls.insert(std::make_pair( 99 ConstString(enumerator_decl->getNameAsString()).GetCString(), p)); 100 } 101 } 102} 103 104clang::NamedDecl * 105ClangPersistentVariables::GetPersistentDecl(ConstString name) { 106 return m_persistent_decls.lookup(name.GetCString()).m_decl; 107} 108 109std::shared_ptr<ClangASTImporter> 110ClangPersistentVariables::GetClangASTImporter() { 111 if (!m_ast_importer_sp) { 112 m_ast_importer_sp = std::make_shared<ClangASTImporter>(); 113 } 114 return m_ast_importer_sp; 115} 116 117std::shared_ptr<ClangModulesDeclVendor> 118ClangPersistentVariables::GetClangModulesDeclVendor() { 119 if (!m_modules_decl_vendor_sp) { 120 m_modules_decl_vendor_sp.reset( 121 ClangModulesDeclVendor::Create(*m_target_sp)); 122 } 123 return m_modules_decl_vendor_sp; 124} 125 126ConstString 127ClangPersistentVariables::GetNextPersistentVariableName(bool is_error) { 128 llvm::SmallString<64> name; 129 { 130 llvm::raw_svector_ostream os(name); 131 os << GetPersistentVariablePrefix(is_error) 132 << m_next_persistent_variable_id++; 133 } 134 return ConstString(name); 135} 136