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