/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
Line | Count | Source (jump to first uncovered line) |
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 | 2.07k | : m_target_sp(target_sp) {} |
34 | | |
35 | | ExpressionVariableSP ClangPersistentVariables::CreatePersistentVariable( |
36 | 113 | const lldb::ValueObjectSP &valobj_sp) { |
37 | 113 | return AddNewlyConstructedVariable(new ClangExpressionVariable(valobj_sp)); |
38 | 113 | } |
39 | | |
40 | | ExpressionVariableSP ClangPersistentVariables::CreatePersistentVariable( |
41 | | ExecutionContextScope *exe_scope, ConstString name, |
42 | | const CompilerType &compiler_type, lldb::ByteOrder byte_order, |
43 | 6.89k | uint32_t addr_byte_size) { |
44 | 6.89k | return AddNewlyConstructedVariable(new ClangExpressionVariable( |
45 | 6.89k | exe_scope, name, compiler_type, byte_order, addr_byte_size)); |
46 | 6.89k | } |
47 | | |
48 | | void ClangPersistentVariables::RemovePersistentVariable( |
49 | 270 | lldb::ExpressionVariableSP variable) { |
50 | 270 | 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 | 270 | if (m_next_persistent_variable_id == 0) |
57 | 0 | return; |
58 | | |
59 | 270 | llvm::StringRef name = variable->GetName().GetStringRef(); |
60 | | // Remove the prefix from the variable that only the indes is left. |
61 | 270 | if (!name.consume_front(GetPersistentVariablePrefix(false))) |
62 | 0 | return; |
63 | | |
64 | | // Check if the variable contained a variable id. |
65 | 270 | uint32_t variable_id; |
66 | 270 | if (name.getAsInteger(10, variable_id)) |
67 | 0 | 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 | 270 | if (variable_id == m_next_persistent_variable_id - 1) |
71 | 270 | m_next_persistent_variable_id--; |
72 | 270 | } |
73 | | |
74 | | std::optional<CompilerType> |
75 | | ClangPersistentVariables::GetCompilerTypeFromPersistentDecl( |
76 | 14 | ConstString type_name) { |
77 | 14 | PersistentDecl p = m_persistent_decls.lookup(type_name.GetCString()); |
78 | | |
79 | 14 | if (p.m_decl == nullptr) |
80 | 6 | return std::nullopt; |
81 | | |
82 | 8 | if (clang::TypeDecl *tdecl = llvm::dyn_cast<clang::TypeDecl>(p.m_decl)) { |
83 | 8 | opaque_compiler_type_t t = static_cast<opaque_compiler_type_t>( |
84 | 8 | const_cast<clang::Type *>(tdecl->getTypeForDecl())); |
85 | 8 | return CompilerType(p.m_context, t); |
86 | 8 | } |
87 | 0 | return std::nullopt; |
88 | 8 | } |
89 | | |
90 | | void ClangPersistentVariables::RegisterPersistentDecl( |
91 | | ConstString name, clang::NamedDecl *decl, |
92 | 77 | std::shared_ptr<TypeSystemClang> ctx) { |
93 | 77 | PersistentDecl p = {decl, ctx}; |
94 | 77 | m_persistent_decls.insert(std::make_pair(name.GetCString(), p)); |
95 | | |
96 | 77 | if (clang::EnumDecl *enum_decl = llvm::dyn_cast<clang::EnumDecl>(decl)) { |
97 | 6 | for (clang::EnumConstantDecl *enumerator_decl : enum_decl->enumerators()) { |
98 | 6 | p = {enumerator_decl, ctx}; |
99 | 6 | m_persistent_decls.insert(std::make_pair( |
100 | 6 | ConstString(enumerator_decl->getNameAsString()).GetCString(), p)); |
101 | 6 | } |
102 | 2 | } |
103 | 77 | } |
104 | | |
105 | | clang::NamedDecl * |
106 | 31.9k | ClangPersistentVariables::GetPersistentDecl(ConstString name) { |
107 | 31.9k | return m_persistent_decls.lookup(name.GetCString()).m_decl; |
108 | 31.9k | } |
109 | | |
110 | | std::shared_ptr<ClangASTImporter> |
111 | 12.1k | ClangPersistentVariables::GetClangASTImporter() { |
112 | 12.1k | if (!m_ast_importer_sp) { |
113 | 2.07k | m_ast_importer_sp = std::make_shared<ClangASTImporter>(); |
114 | 2.07k | } |
115 | 12.1k | return m_ast_importer_sp; |
116 | 12.1k | } |
117 | | |
118 | | std::shared_ptr<ClangModulesDeclVendor> |
119 | 42.3k | ClangPersistentVariables::GetClangModulesDeclVendor() { |
120 | 42.3k | if (!m_modules_decl_vendor_sp) { |
121 | 1.23k | m_modules_decl_vendor_sp.reset( |
122 | 1.23k | ClangModulesDeclVendor::Create(*m_target_sp)); |
123 | 1.23k | } |
124 | 42.3k | return m_modules_decl_vendor_sp; |
125 | 42.3k | } |
126 | | |
127 | | ConstString |
128 | 6.98k | ClangPersistentVariables::GetNextPersistentVariableName(bool is_error) { |
129 | 6.98k | llvm::SmallString<64> name; |
130 | 6.98k | { |
131 | 6.98k | llvm::raw_svector_ostream os(name); |
132 | 6.98k | os << GetPersistentVariablePrefix(is_error) |
133 | 6.98k | << m_next_persistent_variable_id++; |
134 | 6.98k | } |
135 | 6.98k | return ConstString(name); |
136 | 6.98k | } |