1 //===-- ClangPersistentVariables.cpp --------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "ClangPersistentVariables.h"
10 #include "ClangASTImporter.h"
11 #include "ClangModulesDeclVendor.h"
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"
20 #include "clang/AST/Decl.h"
22 #include "llvm/ADT/StringMap.h"
27 using namespace lldb_private
;
29 char ClangPersistentVariables::ID
;
31 ClangPersistentVariables::ClangPersistentVariables(
32 std::shared_ptr
<Target
> target_sp
)
33 : m_target_sp(target_sp
) {}
35 ExpressionVariableSP
ClangPersistentVariables::CreatePersistentVariable(
36 const lldb::ValueObjectSP
&valobj_sp
) {
37 return AddNewlyConstructedVariable(new ClangExpressionVariable(valobj_sp
));
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
));
48 void ClangPersistentVariables::RemovePersistentVariable(
49 lldb::ExpressionVariableSP variable
) {
50 RemoveVariable(variable
);
52 // Check if the removed variable was the last one that was created. If yes,
53 // reuse the variable id for the next variable.
55 // Nothing to do if we have not assigned a variable id so far.
56 if (m_next_persistent_variable_id
== 0)
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)))
64 // Check if the variable contained a variable id.
66 if (name
.getAsInteger(10, variable_id
))
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
--;
74 std::optional
<CompilerType
>
75 ClangPersistentVariables::GetCompilerTypeFromPersistentDecl(
76 ConstString type_name
) {
77 PersistentDecl p
= m_persistent_decls
.lookup(type_name
.GetCString());
79 if (p
.m_decl
== nullptr)
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
);
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
));
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
));
106 ClangPersistentVariables::GetPersistentDecl(ConstString name
) {
107 return m_persistent_decls
.lookup(name
.GetCString()).m_decl
;
110 std::shared_ptr
<ClangASTImporter
>
111 ClangPersistentVariables::GetClangASTImporter() {
112 if (!m_ast_importer_sp
) {
113 m_ast_importer_sp
= std::make_shared
<ClangASTImporter
>();
115 return m_ast_importer_sp
;
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
));
124 return m_modules_decl_vendor_sp
;
128 ClangPersistentVariables::GetNextPersistentVariableName(bool is_error
) {
129 llvm::SmallString
<64> name
;
131 llvm::raw_svector_ostream
os(name
);
132 os
<< GetPersistentVariablePrefix(is_error
)
133 << m_next_persistent_variable_id
++;
135 return ConstString(name
);