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