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