Bug Summary

File:build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
Warning:line 770, column 38
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ClangASTSource.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/build-llvm/tools/clang/stage2-bins -resource-dir /usr/lib/llvm-15/lib/clang/15.0.0 -isystem /usr/include/libxml2 -D HAVE_ROUND -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I tools/lldb/source/Plugins/ExpressionParser/Clang -I /build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/lldb/source/Plugins/ExpressionParser/Clang -I /build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/lldb/include -I tools/lldb/include -I include -I /build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/llvm/include -I /usr/include/python3.9 -I /build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/clang/include -I tools/lldb/../clang/include -I /build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/lldb/source -I tools/lldb/source -D _FORTIFY_SOURCE=2 -D NDEBUG -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/backward -internal-isystem /usr/lib/llvm-15/lib/clang/15.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/10/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fmacro-prefix-map=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/= -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fcoverage-prefix-map=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/= -O3 -Wno-unused-command-line-argument -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-redundant-move -Wno-pessimizing-move -Wno-noexcept-type -Wno-comment -Wno-deprecated-declarations -Wno-unknown-pragmas -Wno-strict-aliasing -Wno-stringop-truncation -std=c++14 -fdeprecated-macro -fdebug-compilation-dir=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/build-llvm/tools/clang/stage2-bins=build-llvm/tools/clang/stage2-bins -fdebug-prefix-map=/build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/= -ferror-limit 19 -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-04-20-140412-16051-1 -x c++ /build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
1//===-- ClangASTSource.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 "ClangASTSource.h"
10
11#include "ClangDeclVendor.h"
12#include "ClangModulesDeclVendor.h"
13
14#include "lldb/Core/Module.h"
15#include "lldb/Core/ModuleList.h"
16#include "lldb/Symbol/CompilerDeclContext.h"
17#include "lldb/Symbol/Function.h"
18#include "lldb/Symbol/SymbolFile.h"
19#include "lldb/Symbol/TaggedASTType.h"
20#include "lldb/Target/Target.h"
21#include "lldb/Utility/LLDBLog.h"
22#include "lldb/Utility/Log.h"
23#include "clang/AST/ASTContext.h"
24#include "clang/AST/RecordLayout.h"
25#include "clang/Basic/SourceManager.h"
26
27#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
28#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
29#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
30
31#include <memory>
32#include <vector>
33
34using namespace clang;
35using namespace lldb_private;
36
37// Scoped class that will remove an active lexical decl from the set when it
38// goes out of scope.
39namespace {
40class ScopedLexicalDeclEraser {
41public:
42 ScopedLexicalDeclEraser(std::set<const clang::Decl *> &decls,
43 const clang::Decl *decl)
44 : m_active_lexical_decls(decls), m_decl(decl) {}
45
46 ~ScopedLexicalDeclEraser() { m_active_lexical_decls.erase(m_decl); }
47
48private:
49 std::set<const clang::Decl *> &m_active_lexical_decls;
50 const clang::Decl *m_decl;
51};
52}
53
54ClangASTSource::ClangASTSource(
55 const lldb::TargetSP &target,
56 const std::shared_ptr<ClangASTImporter> &importer)
57 : m_lookups_enabled(false), m_target(target), m_ast_context(nullptr),
58 m_ast_importer_sp(importer), m_active_lexical_decls(),
59 m_active_lookups() {
60 assert(m_ast_importer_sp && "No ClangASTImporter passed to ClangASTSource?")(static_cast <bool> (m_ast_importer_sp && "No ClangASTImporter passed to ClangASTSource?"
) ? void (0) : __assert_fail ("m_ast_importer_sp && \"No ClangASTImporter passed to ClangASTSource?\""
, "lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, 60, __extension__ __PRETTY_FUNCTION__))
;
61}
62
63void ClangASTSource::InstallASTContext(TypeSystemClang &clang_ast_context) {
64 m_ast_context = &clang_ast_context.getASTContext();
65 m_clang_ast_context = &clang_ast_context;
66 m_file_manager = &m_ast_context->getSourceManager().getFileManager();
67 m_ast_importer_sp->InstallMapCompleter(m_ast_context, *this);
68}
69
70ClangASTSource::~ClangASTSource() {
71 m_ast_importer_sp->ForgetDestination(m_ast_context);
72
73 if (!m_target)
74 return;
75
76 // Unregister the current ASTContext as a source for all scratch
77 // ASTContexts in the ClangASTImporter. Without this the scratch AST might
78 // query the deleted ASTContext for additional type information.
79 // We unregister from *all* scratch ASTContexts in case a type got exported
80 // to a scratch AST that isn't the best fitting scratch ASTContext.
81 TypeSystemClang *scratch_ast = ScratchTypeSystemClang::GetForTarget(
82 *m_target, ScratchTypeSystemClang::DefaultAST, false);
83
84 if (!scratch_ast)
85 return;
86
87 ScratchTypeSystemClang *default_scratch_ast =
88 llvm::cast<ScratchTypeSystemClang>(scratch_ast);
89 // Unregister from the default scratch AST (and all sub-ASTs).
90 default_scratch_ast->ForgetSource(m_ast_context, *m_ast_importer_sp);
91}
92
93void ClangASTSource::StartTranslationUnit(ASTConsumer *Consumer) {
94 if (!m_ast_context)
95 return;
96
97 m_ast_context->getTranslationUnitDecl()->setHasExternalVisibleStorage();
98 m_ast_context->getTranslationUnitDecl()->setHasExternalLexicalStorage();
99}
100
101// The core lookup interface.
102bool ClangASTSource::FindExternalVisibleDeclsByName(
103 const DeclContext *decl_ctx, DeclarationName clang_decl_name) {
104 if (!m_ast_context) {
105 SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
106 return false;
107 }
108
109 std::string decl_name(clang_decl_name.getAsString());
110
111 switch (clang_decl_name.getNameKind()) {
112 // Normal identifiers.
113 case DeclarationName::Identifier: {
114 clang::IdentifierInfo *identifier_info =
115 clang_decl_name.getAsIdentifierInfo();
116
117 if (!identifier_info || identifier_info->getBuiltinID() != 0) {
118 SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
119 return false;
120 }
121 } break;
122
123 // Operator names.
124 case DeclarationName::CXXOperatorName:
125 case DeclarationName::CXXLiteralOperatorName:
126 break;
127
128 // Using directives found in this context.
129 // Tell Sema we didn't find any or we'll end up getting asked a *lot*.
130 case DeclarationName::CXXUsingDirective:
131 SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
132 return false;
133
134 case DeclarationName::ObjCZeroArgSelector:
135 case DeclarationName::ObjCOneArgSelector:
136 case DeclarationName::ObjCMultiArgSelector: {
137 llvm::SmallVector<NamedDecl *, 1> method_decls;
138
139 NameSearchContext method_search_context(*m_clang_ast_context, method_decls,
140 clang_decl_name, decl_ctx);
141
142 FindObjCMethodDecls(method_search_context);
143
144 SetExternalVisibleDeclsForName(decl_ctx, clang_decl_name, method_decls);
145 return (method_decls.size() > 0);
146 }
147 // These aren't possible in the global context.
148 case DeclarationName::CXXConstructorName:
149 case DeclarationName::CXXDestructorName:
150 case DeclarationName::CXXConversionFunctionName:
151 case DeclarationName::CXXDeductionGuideName:
152 SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
153 return false;
154 }
155
156 if (!GetLookupsEnabled()) {
157 // Wait until we see a '$' at the start of a name before we start doing any
158 // lookups so we can avoid lookup up all of the builtin types.
159 if (!decl_name.empty() && decl_name[0] == '$') {
160 SetLookupsEnabled(true);
161 } else {
162 SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
163 return false;
164 }
165 }
166
167 ConstString const_decl_name(decl_name.c_str());
168
169 const char *uniqued_const_decl_name = const_decl_name.GetCString();
170 if (m_active_lookups.find(uniqued_const_decl_name) !=
171 m_active_lookups.end()) {
172 // We are currently looking up this name...
173 SetNoExternalVisibleDeclsForName(decl_ctx, clang_decl_name);
174 return false;
175 }
176 m_active_lookups.insert(uniqued_const_decl_name);
177 llvm::SmallVector<NamedDecl *, 4> name_decls;
178 NameSearchContext name_search_context(*m_clang_ast_context, name_decls,
179 clang_decl_name, decl_ctx);
180 FindExternalVisibleDecls(name_search_context);
181 SetExternalVisibleDeclsForName(decl_ctx, clang_decl_name, name_decls);
182 m_active_lookups.erase(uniqued_const_decl_name);
183 return (name_decls.size() != 0);
184}
185
186TagDecl *ClangASTSource::FindCompleteType(const TagDecl *decl) {
187 Log *log = GetLog(LLDBLog::Expressions);
188
189 if (const NamespaceDecl *namespace_context =
190 dyn_cast<NamespaceDecl>(decl->getDeclContext())) {
191 ClangASTImporter::NamespaceMapSP namespace_map =
192 m_ast_importer_sp->GetNamespaceMap(namespace_context);
193
194 LLDB_LOGV(log, " CTD Inspecting namespace map{0} ({1} entries)",do { ::lldb_private::Log *log_private = (log); if (log_private
&& log_private->GetVerbose()) log_private->Format
("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CTD Inspecting namespace map{0} ({1} entries)"
, namespace_map.get(), namespace_map->size()); } while (0)
195 namespace_map.get(), namespace_map->size())do { ::lldb_private::Log *log_private = (log); if (log_private
&& log_private->GetVerbose()) log_private->Format
("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CTD Inspecting namespace map{0} ({1} entries)"
, namespace_map.get(), namespace_map->size()); } while (0)
;
196
197 if (!namespace_map)
198 return nullptr;
199
200 for (const ClangASTImporter::NamespaceMapItem &item : *namespace_map) {
201 LLDB_LOG(log, " CTD Searching namespace {0} in module {1}",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CTD Searching namespace {0} in module {1}"
, item.second.GetName(), item.first->GetFileSpec().GetFilename
()); } while (0)
202 item.second.GetName(), item.first->GetFileSpec().GetFilename())do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CTD Searching namespace {0} in module {1}"
, item.second.GetName(), item.first->GetFileSpec().GetFilename
()); } while (0)
;
203
204 TypeList types;
205
206 ConstString name(decl->getName());
207
208 item.first->FindTypesInNamespace(name, item.second, UINT32_MAX(4294967295U), types);
209
210 for (uint32_t ti = 0, te = types.GetSize(); ti != te; ++ti) {
211 lldb::TypeSP type = types.GetTypeAtIndex(ti);
212
213 if (!type)
214 continue;
215
216 CompilerType clang_type(type->GetFullCompilerType());
217
218 if (!ClangUtil::IsClangType(clang_type))
219 continue;
220
221 const TagType *tag_type =
222 ClangUtil::GetQualType(clang_type)->getAs<TagType>();
223
224 if (!tag_type)
225 continue;
226
227 TagDecl *candidate_tag_decl =
228 const_cast<TagDecl *>(tag_type->getDecl());
229
230 if (TypeSystemClang::GetCompleteDecl(
231 &candidate_tag_decl->getASTContext(), candidate_tag_decl))
232 return candidate_tag_decl;
233 }
234 }
235 } else {
236 TypeList types;
237
238 ConstString name(decl->getName());
239
240 const ModuleList &module_list = m_target->GetImages();
241
242 bool exact_match = false;
243 llvm::DenseSet<SymbolFile *> searched_symbol_files;
244 module_list.FindTypes(nullptr, name, exact_match, UINT32_MAX(4294967295U),
245 searched_symbol_files, types);
246
247 for (uint32_t ti = 0, te = types.GetSize(); ti != te; ++ti) {
248 lldb::TypeSP type = types.GetTypeAtIndex(ti);
249
250 if (!type)
251 continue;
252
253 CompilerType clang_type(type->GetFullCompilerType());
254
255 if (!ClangUtil::IsClangType(clang_type))
256 continue;
257
258 const TagType *tag_type =
259 ClangUtil::GetQualType(clang_type)->getAs<TagType>();
260
261 if (!tag_type)
262 continue;
263
264 TagDecl *candidate_tag_decl = const_cast<TagDecl *>(tag_type->getDecl());
265
266 // We have found a type by basename and we need to make sure the decl
267 // contexts are the same before we can try to complete this type with
268 // another
269 if (!TypeSystemClang::DeclsAreEquivalent(const_cast<TagDecl *>(decl),
270 candidate_tag_decl))
271 continue;
272
273 if (TypeSystemClang::GetCompleteDecl(&candidate_tag_decl->getASTContext(),
274 candidate_tag_decl))
275 return candidate_tag_decl;
276 }
277 }
278 return nullptr;
279}
280
281void ClangASTSource::CompleteType(TagDecl *tag_decl) {
282 Log *log = GetLog(LLDBLog::Expressions);
283
284 if (log) {
285 LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CompleteTagDecl on (ASTContext*){0} Completing "
"(TagDecl*){1} named {2}", m_clang_ast_context->getDisplayName
(), tag_decl, tag_decl->getName()); } while (0)
286 " CompleteTagDecl on (ASTContext*){0} Completing "do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CompleteTagDecl on (ASTContext*){0} Completing "
"(TagDecl*){1} named {2}", m_clang_ast_context->getDisplayName
(), tag_decl, tag_decl->getName()); } while (0)
287 "(TagDecl*){1} named {2}",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CompleteTagDecl on (ASTContext*){0} Completing "
"(TagDecl*){1} named {2}", m_clang_ast_context->getDisplayName
(), tag_decl, tag_decl->getName()); } while (0)
288 m_clang_ast_context->getDisplayName(), tag_decl,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CompleteTagDecl on (ASTContext*){0} Completing "
"(TagDecl*){1} named {2}", m_clang_ast_context->getDisplayName
(), tag_decl, tag_decl->getName()); } while (0)
289 tag_decl->getName())do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CompleteTagDecl on (ASTContext*){0} Completing "
"(TagDecl*){1} named {2}", m_clang_ast_context->getDisplayName
(), tag_decl, tag_decl->getName()); } while (0)
;
290
291 LLDB_LOG(log, " CTD Before:\n{0}", ClangUtil::DumpDecl(tag_decl))do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CTD Before:\n{0}", ClangUtil::DumpDecl(tag_decl
)); } while (0)
;
292 }
293
294 auto iter = m_active_lexical_decls.find(tag_decl);
295 if (iter != m_active_lexical_decls.end())
296 return;
297 m_active_lexical_decls.insert(tag_decl);
298 ScopedLexicalDeclEraser eraser(m_active_lexical_decls, tag_decl);
299
300 if (!m_ast_importer_sp->CompleteTagDecl(tag_decl)) {
301 // We couldn't complete the type. Maybe there's a definition somewhere
302 // else that can be completed.
303 if (TagDecl *alternate = FindCompleteType(tag_decl))
304 m_ast_importer_sp->CompleteTagDeclWithOrigin(tag_decl, alternate);
305 }
306
307 LLDB_LOG(log, " [CTD] After:\n{0}", ClangUtil::DumpDecl(tag_decl))do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " [CTD] After:\n{0}", ClangUtil::DumpDecl(tag_decl
)); } while (0)
;
308}
309
310void ClangASTSource::CompleteType(clang::ObjCInterfaceDecl *interface_decl) {
311 Log *log = GetLog(LLDBLog::Expressions);
312
313 LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " [CompleteObjCInterfaceDecl] on (ASTContext*){0} '{1}' "
"Completing an ObjCInterfaceDecl named {1}", m_ast_context, m_clang_ast_context
->getDisplayName(), interface_decl->getName()); } while
(0)
314 " [CompleteObjCInterfaceDecl] on (ASTContext*){0} '{1}' "do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " [CompleteObjCInterfaceDecl] on (ASTContext*){0} '{1}' "
"Completing an ObjCInterfaceDecl named {1}", m_ast_context, m_clang_ast_context
->getDisplayName(), interface_decl->getName()); } while
(0)
315 "Completing an ObjCInterfaceDecl named {1}",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " [CompleteObjCInterfaceDecl] on (ASTContext*){0} '{1}' "
"Completing an ObjCInterfaceDecl named {1}", m_ast_context, m_clang_ast_context
->getDisplayName(), interface_decl->getName()); } while
(0)
316 m_ast_context, m_clang_ast_context->getDisplayName(),do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " [CompleteObjCInterfaceDecl] on (ASTContext*){0} '{1}' "
"Completing an ObjCInterfaceDecl named {1}", m_ast_context, m_clang_ast_context
->getDisplayName(), interface_decl->getName()); } while
(0)
317 interface_decl->getName())do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " [CompleteObjCInterfaceDecl] on (ASTContext*){0} '{1}' "
"Completing an ObjCInterfaceDecl named {1}", m_ast_context, m_clang_ast_context
->getDisplayName(), interface_decl->getName()); } while
(0)
;
318 LLDB_LOG(log, " [COID] Before:\n{0}",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " [COID] Before:\n{0}", ClangUtil::DumpDecl(
interface_decl)); } while (0)
319 ClangUtil::DumpDecl(interface_decl))do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " [COID] Before:\n{0}", ClangUtil::DumpDecl(
interface_decl)); } while (0)
;
320
321 ClangASTImporter::DeclOrigin original = m_ast_importer_sp->GetDeclOrigin(interface_decl);
322
323 if (original.Valid()) {
324 if (ObjCInterfaceDecl *original_iface_decl =
325 dyn_cast<ObjCInterfaceDecl>(original.decl)) {
326 ObjCInterfaceDecl *complete_iface_decl =
327 GetCompleteObjCInterface(original_iface_decl);
328
329 if (complete_iface_decl && (complete_iface_decl != original_iface_decl)) {
330 m_ast_importer_sp->SetDeclOrigin(interface_decl, complete_iface_decl);
331 }
332 }
333 }
334
335 m_ast_importer_sp->CompleteObjCInterfaceDecl(interface_decl);
336
337 if (interface_decl->getSuperClass() &&
338 interface_decl->getSuperClass() != interface_decl)
339 CompleteType(interface_decl->getSuperClass());
340
341 LLDB_LOG(log, " [COID] After:")do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " [COID] After:"); } while (0)
;
342 LLDB_LOG(log, " [COID] {0}", ClangUtil::DumpDecl(interface_decl))do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " [COID] {0}", ClangUtil::DumpDecl(interface_decl
)); } while (0)
;
343}
344
345clang::ObjCInterfaceDecl *ClangASTSource::GetCompleteObjCInterface(
346 const clang::ObjCInterfaceDecl *interface_decl) {
347 lldb::ProcessSP process(m_target->GetProcessSP());
348
349 if (!process)
350 return nullptr;
351
352 ObjCLanguageRuntime *language_runtime(ObjCLanguageRuntime::Get(*process));
353
354 if (!language_runtime)
355 return nullptr;
356
357 ConstString class_name(interface_decl->getNameAsString().c_str());
358
359 lldb::TypeSP complete_type_sp(
360 language_runtime->LookupInCompleteClassCache(class_name));
361
362 if (!complete_type_sp)
363 return nullptr;
364
365 TypeFromUser complete_type =
366 TypeFromUser(complete_type_sp->GetFullCompilerType());
367 lldb::opaque_compiler_type_t complete_opaque_type =
368 complete_type.GetOpaqueQualType();
369
370 if (!complete_opaque_type)
371 return nullptr;
372
373 const clang::Type *complete_clang_type =
374 QualType::getFromOpaquePtr(complete_opaque_type).getTypePtr();
375 const ObjCInterfaceType *complete_interface_type =
376 dyn_cast<ObjCInterfaceType>(complete_clang_type);
377
378 if (!complete_interface_type)
379 return nullptr;
380
381 ObjCInterfaceDecl *complete_iface_decl(complete_interface_type->getDecl());
382
383 return complete_iface_decl;
384}
385
386void ClangASTSource::FindExternalLexicalDecls(
387 const DeclContext *decl_context,
388 llvm::function_ref<bool(Decl::Kind)> predicate,
389 llvm::SmallVectorImpl<Decl *> &decls) {
390
391 Log *log = GetLog(LLDBLog::Expressions);
392
393 const Decl *context_decl = dyn_cast<Decl>(decl_context);
394
395 if (!context_decl)
396 return;
397
398 auto iter = m_active_lexical_decls.find(context_decl);
399 if (iter != m_active_lexical_decls.end())
400 return;
401 m_active_lexical_decls.insert(context_decl);
402 ScopedLexicalDeclEraser eraser(m_active_lexical_decls, context_decl);
403
404 if (log) {
405 if (const NamedDecl *context_named_decl = dyn_cast<NamedDecl>(context_decl))
406 LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in "
"'{2}' (%sDecl*){3}", m_ast_context, m_clang_ast_context->
getDisplayName(), context_named_decl->getNameAsString().c_str
(), context_decl->getDeclKindName(), static_cast<const void
*>(context_decl)); } while (0)
407 "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in "do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in "
"'{2}' (%sDecl*){3}", m_ast_context, m_clang_ast_context->
getDisplayName(), context_named_decl->getNameAsString().c_str
(), context_decl->getDeclKindName(), static_cast<const void
*>(context_decl)); } while (0)
408 "'{2}' (%sDecl*){3}",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in "
"'{2}' (%sDecl*){3}", m_ast_context, m_clang_ast_context->
getDisplayName(), context_named_decl->getNameAsString().c_str
(), context_decl->getDeclKindName(), static_cast<const void
*>(context_decl)); } while (0)
409 m_ast_context, m_clang_ast_context->getDisplayName(),do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in "
"'{2}' (%sDecl*){3}", m_ast_context, m_clang_ast_context->
getDisplayName(), context_named_decl->getNameAsString().c_str
(), context_decl->getDeclKindName(), static_cast<const void
*>(context_decl)); } while (0)
410 context_named_decl->getNameAsString().c_str(),do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in "
"'{2}' (%sDecl*){3}", m_ast_context, m_clang_ast_context->
getDisplayName(), context_named_decl->getNameAsString().c_str
(), context_decl->getDeclKindName(), static_cast<const void
*>(context_decl)); } while (0)
411 context_decl->getDeclKindName(),do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in "
"'{2}' (%sDecl*){3}", m_ast_context, m_clang_ast_context->
getDisplayName(), context_named_decl->getNameAsString().c_str
(), context_decl->getDeclKindName(), static_cast<const void
*>(context_decl)); } while (0)
412 static_cast<const void *>(context_decl))do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in "
"'{2}' (%sDecl*){3}", m_ast_context, m_clang_ast_context->
getDisplayName(), context_named_decl->getNameAsString().c_str
(), context_decl->getDeclKindName(), static_cast<const void
*>(context_decl)); } while (0)
;
413 else if (context_decl)
414 LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in "
"({2}Decl*){3}", m_ast_context, m_clang_ast_context->getDisplayName
(), context_decl->getDeclKindName(), static_cast<const void
*>(context_decl)); } while (0)
415 "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in "do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in "
"({2}Decl*){3}", m_ast_context, m_clang_ast_context->getDisplayName
(), context_decl->getDeclKindName(), static_cast<const void
*>(context_decl)); } while (0)
416 "({2}Decl*){3}",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in "
"({2}Decl*){3}", m_ast_context, m_clang_ast_context->getDisplayName
(), context_decl->getDeclKindName(), static_cast<const void
*>(context_decl)); } while (0)
417 m_ast_context, m_clang_ast_context->getDisplayName(),do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in "
"({2}Decl*){3}", m_ast_context, m_clang_ast_context->getDisplayName
(), context_decl->getDeclKindName(), static_cast<const void
*>(context_decl)); } while (0)
418 context_decl->getDeclKindName(),do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in "
"({2}Decl*){3}", m_ast_context, m_clang_ast_context->getDisplayName
(), context_decl->getDeclKindName(), static_cast<const void
*>(context_decl)); } while (0)
419 static_cast<const void *>(context_decl))do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in "
"({2}Decl*){3}", m_ast_context, m_clang_ast_context->getDisplayName
(), context_decl->getDeclKindName(), static_cast<const void
*>(context_decl)); } while (0)
;
420 else
421 LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in a "
"NULL context", m_ast_context, m_clang_ast_context->getDisplayName
()); } while (0)
422 "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in a "do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in a "
"NULL context", m_ast_context, m_clang_ast_context->getDisplayName
()); } while (0)
423 "NULL context",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in a "
"NULL context", m_ast_context, m_clang_ast_context->getDisplayName
()); } while (0)
424 m_ast_context, m_clang_ast_context->getDisplayName())do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "FindExternalLexicalDecls on (ASTContext*){0} '{1}' in a "
"NULL context", m_ast_context, m_clang_ast_context->getDisplayName
()); } while (0)
;
425 }
426
427 ClangASTImporter::DeclOrigin original = m_ast_importer_sp->GetDeclOrigin(context_decl);
428
429 if (!original.Valid())
430 return;
431
432 LLDB_LOG(log, " FELD Original decl {0} (Decl*){1:x}:\n{2}",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " FELD Original decl {0} (Decl*){1:x}:\n{2}", static_cast
<void *>(original.ctx), static_cast<void *>(original
.decl), ClangUtil::DumpDecl(original.decl)); } while (0)
433 static_cast<void *>(original.ctx),do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " FELD Original decl {0} (Decl*){1:x}:\n{2}", static_cast
<void *>(original.ctx), static_cast<void *>(original
.decl), ClangUtil::DumpDecl(original.decl)); } while (0)
434 static_cast<void *>(original.decl),do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " FELD Original decl {0} (Decl*){1:x}:\n{2}", static_cast
<void *>(original.ctx), static_cast<void *>(original
.decl), ClangUtil::DumpDecl(original.decl)); } while (0)
435 ClangUtil::DumpDecl(original.decl))do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " FELD Original decl {0} (Decl*){1:x}:\n{2}", static_cast
<void *>(original.ctx), static_cast<void *>(original
.decl), ClangUtil::DumpDecl(original.decl)); } while (0)
;
436
437 if (ObjCInterfaceDecl *original_iface_decl =
438 dyn_cast<ObjCInterfaceDecl>(original.decl)) {
439 ObjCInterfaceDecl *complete_iface_decl =
440 GetCompleteObjCInterface(original_iface_decl);
441
442 if (complete_iface_decl && (complete_iface_decl != original_iface_decl)) {
443 original.decl = complete_iface_decl;
444 original.ctx = &complete_iface_decl->getASTContext();
445
446 m_ast_importer_sp->SetDeclOrigin(context_decl, complete_iface_decl);
447 }
448 }
449
450 if (TagDecl *original_tag_decl = dyn_cast<TagDecl>(original.decl)) {
451 ExternalASTSource *external_source = original.ctx->getExternalSource();
452
453 if (external_source)
454 external_source->CompleteType(original_tag_decl);
455 }
456
457 const DeclContext *original_decl_context =
458 dyn_cast<DeclContext>(original.decl);
459
460 if (!original_decl_context)
461 return;
462
463 // Indicates whether we skipped any Decls of the original DeclContext.
464 bool SkippedDecls = false;
465 for (Decl *decl : original_decl_context->decls()) {
466 // The predicate function returns true if the passed declaration kind is
467 // the one we are looking for.
468 // See clang::ExternalASTSource::FindExternalLexicalDecls()
469 if (predicate(decl->getKind())) {
470 if (log) {
471 std::string ast_dump = ClangUtil::DumpDecl(decl);
472 if (const NamedDecl *context_named_decl =
473 dyn_cast<NamedDecl>(context_decl))
474 LLDB_LOG(log, " FELD Adding [to {0}Decl {1}] lexical {2}Decl {3}",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " FELD Adding [to {0}Decl {1}] lexical {2}Decl {3}"
, context_named_decl->getDeclKindName(), context_named_decl
->getName(), decl->getDeclKindName(), ast_dump); } while
(0)
475 context_named_decl->getDeclKindName(),do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " FELD Adding [to {0}Decl {1}] lexical {2}Decl {3}"
, context_named_decl->getDeclKindName(), context_named_decl
->getName(), decl->getDeclKindName(), ast_dump); } while
(0)
476 context_named_decl->getName(), decl->getDeclKindName(),do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " FELD Adding [to {0}Decl {1}] lexical {2}Decl {3}"
, context_named_decl->getDeclKindName(), context_named_decl
->getName(), decl->getDeclKindName(), ast_dump); } while
(0)
477 ast_dump)do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " FELD Adding [to {0}Decl {1}] lexical {2}Decl {3}"
, context_named_decl->getDeclKindName(), context_named_decl
->getName(), decl->getDeclKindName(), ast_dump); } while
(0)
;
478 else
479 LLDB_LOG(log, " FELD Adding lexical {0}Decl {1}",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " FELD Adding lexical {0}Decl {1}", decl->getDeclKindName
(), ast_dump); } while (0)
480 decl->getDeclKindName(), ast_dump)do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " FELD Adding lexical {0}Decl {1}", decl->getDeclKindName
(), ast_dump); } while (0)
;
481 }
482
483 Decl *copied_decl = CopyDecl(decl);
484
485 if (!copied_decl)
486 continue;
487
488 // FIXME: We should add the copied decl to the 'decls' list. This would
489 // add the copied Decl into the DeclContext and make sure that we
490 // correctly propagate that we added some Decls back to Clang.
491 // By leaving 'decls' empty we incorrectly return false from
492 // DeclContext::LoadLexicalDeclsFromExternalStorage which might cause
493 // lookup issues later on.
494 // We can't just add them for now as the ASTImporter already added the
495 // decl into the DeclContext and this would add it twice.
496
497 if (FieldDecl *copied_field = dyn_cast<FieldDecl>(copied_decl)) {
498 QualType copied_field_type = copied_field->getType();
499
500 m_ast_importer_sp->RequireCompleteType(copied_field_type);
501 }
502 } else {
503 SkippedDecls = true;
504 }
505 }
506
507 // CopyDecl may build a lookup table which may set up ExternalLexicalStorage
508 // to false. However, since we skipped some of the external Decls we must
509 // set it back!
510 if (SkippedDecls) {
511 decl_context->setHasExternalLexicalStorage(true);
512 // This sets HasLazyExternalLexicalLookups to true. By setting this bit we
513 // ensure that the lookup table is rebuilt, which means the external source
514 // is consulted again when a clang::DeclContext::lookup is called.
515 const_cast<DeclContext *>(decl_context)->setMustBuildLookupTable();
516 }
517}
518
519void ClangASTSource::FindExternalVisibleDecls(NameSearchContext &context) {
520 assert(m_ast_context)(static_cast <bool> (m_ast_context) ? void (0) : __assert_fail
("m_ast_context", "lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, 520, __extension__ __PRETTY_FUNCTION__))
;
521
522 const ConstString name(context.m_decl_name.getAsString().c_str());
523
524 Log *log = GetLog(LLDBLog::Expressions);
525
526 if (log) {
527 if (!context.m_decl_context)
528 LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "ClangASTSource::FindExternalVisibleDecls on " "(ASTContext*){0} '{1}' for '{2}' in a NULL DeclContext"
, m_ast_context, m_clang_ast_context->getDisplayName(), name
); } while (0)
529 "ClangASTSource::FindExternalVisibleDecls on "do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "ClangASTSource::FindExternalVisibleDecls on " "(ASTContext*){0} '{1}' for '{2}' in a NULL DeclContext"
, m_ast_context, m_clang_ast_context->getDisplayName(), name
); } while (0)
530 "(ASTContext*){0} '{1}' for '{2}' in a NULL DeclContext",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "ClangASTSource::FindExternalVisibleDecls on " "(ASTContext*){0} '{1}' for '{2}' in a NULL DeclContext"
, m_ast_context, m_clang_ast_context->getDisplayName(), name
); } while (0)
531 m_ast_context, m_clang_ast_context->getDisplayName(), name)do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "ClangASTSource::FindExternalVisibleDecls on " "(ASTContext*){0} '{1}' for '{2}' in a NULL DeclContext"
, m_ast_context, m_clang_ast_context->getDisplayName(), name
); } while (0)
;
532 else if (const NamedDecl *context_named_decl =
533 dyn_cast<NamedDecl>(context.m_decl_context))
534 LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "ClangASTSource::FindExternalVisibleDecls on " "(ASTContext*){0} '{1}' for '{2}' in '{3}'"
, m_ast_context, m_clang_ast_context->getDisplayName(), name
, context_named_decl->getName()); } while (0)
535 "ClangASTSource::FindExternalVisibleDecls on "do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "ClangASTSource::FindExternalVisibleDecls on " "(ASTContext*){0} '{1}' for '{2}' in '{3}'"
, m_ast_context, m_clang_ast_context->getDisplayName(), name
, context_named_decl->getName()); } while (0)
536 "(ASTContext*){0} '{1}' for '{2}' in '{3}'",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "ClangASTSource::FindExternalVisibleDecls on " "(ASTContext*){0} '{1}' for '{2}' in '{3}'"
, m_ast_context, m_clang_ast_context->getDisplayName(), name
, context_named_decl->getName()); } while (0)
537 m_ast_context, m_clang_ast_context->getDisplayName(), name,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "ClangASTSource::FindExternalVisibleDecls on " "(ASTContext*){0} '{1}' for '{2}' in '{3}'"
, m_ast_context, m_clang_ast_context->getDisplayName(), name
, context_named_decl->getName()); } while (0)
538 context_named_decl->getName())do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "ClangASTSource::FindExternalVisibleDecls on " "(ASTContext*){0} '{1}' for '{2}' in '{3}'"
, m_ast_context, m_clang_ast_context->getDisplayName(), name
, context_named_decl->getName()); } while (0)
;
539 else
540 LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "ClangASTSource::FindExternalVisibleDecls on " "(ASTContext*){0} '{1}' for '{2}' in a '{3}'"
, m_ast_context, m_clang_ast_context->getDisplayName(), name
, context.m_decl_context->getDeclKindName()); } while (0)
541 "ClangASTSource::FindExternalVisibleDecls on "do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "ClangASTSource::FindExternalVisibleDecls on " "(ASTContext*){0} '{1}' for '{2}' in a '{3}'"
, m_ast_context, m_clang_ast_context->getDisplayName(), name
, context.m_decl_context->getDeclKindName()); } while (0)
542 "(ASTContext*){0} '{1}' for '{2}' in a '{3}'",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "ClangASTSource::FindExternalVisibleDecls on " "(ASTContext*){0} '{1}' for '{2}' in a '{3}'"
, m_ast_context, m_clang_ast_context->getDisplayName(), name
, context.m_decl_context->getDeclKindName()); } while (0)
543 m_ast_context, m_clang_ast_context->getDisplayName(), name,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "ClangASTSource::FindExternalVisibleDecls on " "(ASTContext*){0} '{1}' for '{2}' in a '{3}'"
, m_ast_context, m_clang_ast_context->getDisplayName(), name
, context.m_decl_context->getDeclKindName()); } while (0)
544 context.m_decl_context->getDeclKindName())do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "ClangASTSource::FindExternalVisibleDecls on " "(ASTContext*){0} '{1}' for '{2}' in a '{3}'"
, m_ast_context, m_clang_ast_context->getDisplayName(), name
, context.m_decl_context->getDeclKindName()); } while (0)
;
545 }
546
547 if (isa<NamespaceDecl>(context.m_decl_context)) {
548 LookupInNamespace(context);
549 } else if (isa<ObjCInterfaceDecl>(context.m_decl_context)) {
550 FindObjCPropertyAndIvarDecls(context);
551 } else if (!isa<TranslationUnitDecl>(context.m_decl_context)) {
552 // we shouldn't be getting FindExternalVisibleDecls calls for these
553 return;
554 } else {
555 CompilerDeclContext namespace_decl;
556
557 LLDB_LOG(log, " CAS::FEVD Searching the root namespace")do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CAS::FEVD Searching the root namespace"); } while
(0)
;
558
559 FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl);
560 }
561
562 if (!context.m_namespace_map->empty()) {
563 if (log && log->GetVerbose())
564 LLDB_LOG(log, " CAS::FEVD Registering namespace map {0} ({1} entries)",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CAS::FEVD Registering namespace map {0} ({1} entries)"
, context.m_namespace_map.get(), context.m_namespace_map->
size()); } while (0)
565 context.m_namespace_map.get(), context.m_namespace_map->size())do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CAS::FEVD Registering namespace map {0} ({1} entries)"
, context.m_namespace_map.get(), context.m_namespace_map->
size()); } while (0)
;
566
567 NamespaceDecl *clang_namespace_decl =
568 AddNamespace(context, context.m_namespace_map);
569
570 if (clang_namespace_decl)
571 clang_namespace_decl->setHasExternalVisibleStorage();
572 }
573}
574
575clang::Sema *ClangASTSource::getSema() {
576 return m_clang_ast_context->getSema();
577}
578
579bool ClangASTSource::IgnoreName(const ConstString name,
580 bool ignore_all_dollar_names) {
581 static const ConstString id_name("id");
582 static const ConstString Class_name("Class");
583
584 if (m_ast_context->getLangOpts().ObjC)
585 if (name == id_name || name == Class_name)
586 return true;
587
588 StringRef name_string_ref = name.GetStringRef();
589
590 // The ClangASTSource is not responsible for finding $-names.
591 return name_string_ref.empty() ||
592 (ignore_all_dollar_names && name_string_ref.startswith("$")) ||
593 name_string_ref.startswith("_$");
594}
595
596void ClangASTSource::FindExternalVisibleDecls(
597 NameSearchContext &context, lldb::ModuleSP module_sp,
598 CompilerDeclContext &namespace_decl) {
599 assert(m_ast_context)(static_cast <bool> (m_ast_context) ? void (0) : __assert_fail
("m_ast_context", "lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, 599, __extension__ __PRETTY_FUNCTION__))
;
600
601 Log *log = GetLog(LLDBLog::Expressions);
602
603 SymbolContextList sc_list;
604
605 const ConstString name(context.m_decl_name.getAsString().c_str());
606 if (IgnoreName(name, true))
607 return;
608
609 if (!m_target)
610 return;
611
612 FillNamespaceMap(context, module_sp, namespace_decl);
613
614 if (context.m_found_type)
615 return;
616
617 TypeList types;
618 const bool exact_match = true;
619 llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
620 if (module_sp && namespace_decl)
621 module_sp->FindTypesInNamespace(name, namespace_decl, 1, types);
622 else {
623 m_target->GetImages().FindTypes(module_sp.get(), name, exact_match, 1,
624 searched_symbol_files, types);
625 }
626
627 if (size_t num_types = types.GetSize()) {
628 for (size_t ti = 0; ti < num_types; ++ti) {
629 lldb::TypeSP type_sp = types.GetTypeAtIndex(ti);
630
631 if (log) {
632 const char *name_string = type_sp->GetName().GetCString();
633
634 LLDB_LOG(log, " CAS::FEVD Matching type found for \"{0}\": {1}", name,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CAS::FEVD Matching type found for \"{0}\": {1}"
, name, (name_string ? name_string : "<anonymous>")); }
while (0)
635 (name_string ? name_string : "<anonymous>"))do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CAS::FEVD Matching type found for \"{0}\": {1}"
, name, (name_string ? name_string : "<anonymous>")); }
while (0)
;
636 }
637
638 CompilerType full_type = type_sp->GetFullCompilerType();
639
640 CompilerType copied_clang_type(GuardedCopyType(full_type));
641
642 if (!copied_clang_type) {
643 LLDB_LOG(log, " CAS::FEVD - Couldn't export a type")do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CAS::FEVD - Couldn't export a type"); } while (
0)
;
644
645 continue;
646 }
647
648 context.AddTypeDecl(copied_clang_type);
649
650 context.m_found_type = true;
651 break;
652 }
653 }
654
655 if (!context.m_found_type) {
656 // Try the modules next.
657 FindDeclInModules(context, name);
658 }
659
660 if (!context.m_found_type) {
661 FindDeclInObjCRuntime(context, name);
662 }
663}
664
665void ClangASTSource::FillNamespaceMap(
666 NameSearchContext &context, lldb::ModuleSP module_sp,
667 const CompilerDeclContext &namespace_decl) {
668 const ConstString name(context.m_decl_name.getAsString().c_str());
669 if (IgnoreName(name, true))
670 return;
671
672 Log *log = GetLog(LLDBLog::Expressions);
673
674 if (module_sp && namespace_decl) {
675 CompilerDeclContext found_namespace_decl;
676
677 if (SymbolFile *symbol_file = module_sp->GetSymbolFile()) {
678 found_namespace_decl = symbol_file->FindNamespace(name, namespace_decl);
679
680 if (found_namespace_decl) {
681 context.m_namespace_map->push_back(
682 std::pair<lldb::ModuleSP, CompilerDeclContext>(
683 module_sp, found_namespace_decl));
684
685 LLDB_LOG(log, " CAS::FEVD Found namespace {0} in module {1}", name,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CAS::FEVD Found namespace {0} in module {1}", name
, module_sp->GetFileSpec().GetFilename()); } while (0)
686 module_sp->GetFileSpec().GetFilename())do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CAS::FEVD Found namespace {0} in module {1}", name
, module_sp->GetFileSpec().GetFilename()); } while (0)
;
687 }
688 }
689 return;
690 }
691
692 for (lldb::ModuleSP image : m_target->GetImages().Modules()) {
693 if (!image)
694 continue;
695
696 CompilerDeclContext found_namespace_decl;
697
698 SymbolFile *symbol_file = image->GetSymbolFile();
699
700 if (!symbol_file)
701 continue;
702
703 found_namespace_decl = symbol_file->FindNamespace(name, namespace_decl);
704
705 if (found_namespace_decl) {
706 context.m_namespace_map->push_back(
707 std::pair<lldb::ModuleSP, CompilerDeclContext>(image,
708 found_namespace_decl));
709
710 LLDB_LOG(log, " CAS::FEVD Found namespace {0} in module {1}", name,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CAS::FEVD Found namespace {0} in module {1}", name
, image->GetFileSpec().GetFilename()); } while (0)
711 image->GetFileSpec().GetFilename())do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CAS::FEVD Found namespace {0} in module {1}", name
, image->GetFileSpec().GetFilename()); } while (0)
;
712 }
713 }
714}
715
716template <class D> class TaggedASTDecl {
717public:
718 TaggedASTDecl() : decl(nullptr) {}
719 TaggedASTDecl(D *_decl) : decl(_decl) {}
720 bool IsValid() const { return (decl != nullptr); }
721 bool IsInvalid() const { return !IsValid(); }
722 D *operator->() const { return decl; }
723 D *decl;
724};
725
726template <class D2, template <class D> class TD, class D1>
727TD<D2> DynCast(TD<D1> source) {
728 return TD<D2>(dyn_cast<D2>(source.decl));
729}
730
731template <class D = Decl> class DeclFromParser;
732template <class D = Decl> class DeclFromUser;
733
734template <class D> class DeclFromParser : public TaggedASTDecl<D> {
735public:
736 DeclFromParser() : TaggedASTDecl<D>() {}
737 DeclFromParser(D *_decl) : TaggedASTDecl<D>(_decl) {}
738
739 DeclFromUser<D> GetOrigin(ClangASTSource &source);
740};
741
742template <class D> class DeclFromUser : public TaggedASTDecl<D> {
743public:
744 DeclFromUser() : TaggedASTDecl<D>() {}
745 DeclFromUser(D *_decl) : TaggedASTDecl<D>(_decl) {}
746
747 DeclFromParser<D> Import(ClangASTSource &source);
748};
749
750template <class D>
751DeclFromUser<D> DeclFromParser<D>::GetOrigin(ClangASTSource &source) {
752 ClangASTImporter::DeclOrigin origin = source.GetDeclOrigin(this->decl);
753 if (!origin.Valid())
754 return DeclFromUser<D>();
755 return DeclFromUser<D>(dyn_cast<D>(origin.decl));
756}
757
758template <class D>
759DeclFromParser<D> DeclFromUser<D>::Import(ClangASTSource &source) {
760 DeclFromParser<> parser_generic_decl(source.CopyDecl(this->decl));
761 if (parser_generic_decl.IsInvalid())
762 return DeclFromParser<D>();
763 return DeclFromParser<D>(dyn_cast<D>(parser_generic_decl.decl));
764}
765
766bool ClangASTSource::FindObjCMethodDeclsWithOrigin(
767 NameSearchContext &context, ObjCInterfaceDecl *original_interface_decl,
768 const char *log_info) {
769 const DeclarationName &decl_name(context.m_decl_name);
770 clang::ASTContext *original_ctx = &original_interface_decl->getASTContext();
8
Called C++ object pointer is null
771
772 Selector original_selector;
773
774 if (decl_name.isObjCZeroArgSelector()) {
775 IdentifierInfo *ident = &original_ctx->Idents.get(decl_name.getAsString());
776 original_selector = original_ctx->Selectors.getSelector(0, &ident);
777 } else if (decl_name.isObjCOneArgSelector()) {
778 const std::string &decl_name_string = decl_name.getAsString();
779 std::string decl_name_string_without_colon(decl_name_string.c_str(),
780 decl_name_string.length() - 1);
781 IdentifierInfo *ident =
782 &original_ctx->Idents.get(decl_name_string_without_colon);
783 original_selector = original_ctx->Selectors.getSelector(1, &ident);
784 } else {
785 SmallVector<IdentifierInfo *, 4> idents;
786
787 clang::Selector sel = decl_name.getObjCSelector();
788
789 unsigned num_args = sel.getNumArgs();
790
791 for (unsigned i = 0; i != num_args; ++i) {
792 idents.push_back(&original_ctx->Idents.get(sel.getNameForSlot(i)));
793 }
794
795 original_selector =
796 original_ctx->Selectors.getSelector(num_args, idents.data());
797 }
798
799 DeclarationName original_decl_name(original_selector);
800
801 llvm::SmallVector<NamedDecl *, 1> methods;
802
803 TypeSystemClang::GetCompleteDecl(original_ctx, original_interface_decl);
804
805 if (ObjCMethodDecl *instance_method_decl =
806 original_interface_decl->lookupInstanceMethod(original_selector)) {
807 methods.push_back(instance_method_decl);
808 } else if (ObjCMethodDecl *class_method_decl =
809 original_interface_decl->lookupClassMethod(
810 original_selector)) {
811 methods.push_back(class_method_decl);
812 }
813
814 if (methods.empty()) {
815 return false;
816 }
817
818 for (NamedDecl *named_decl : methods) {
819 if (!named_decl)
820 continue;
821
822 ObjCMethodDecl *result_method = dyn_cast<ObjCMethodDecl>(named_decl);
823
824 if (!result_method)
825 continue;
826
827 Decl *copied_decl = CopyDecl(result_method);
828
829 if (!copied_decl)
830 continue;
831
832 ObjCMethodDecl *copied_method_decl = dyn_cast<ObjCMethodDecl>(copied_decl);
833
834 if (!copied_method_decl)
835 continue;
836
837 Log *log = GetLog(LLDBLog::Expressions);
838
839 LLDB_LOG(log, " CAS::FOMD found ({0}) {1}", log_info,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CAS::FOMD found ({0}) {1}", log_info, ClangUtil
::DumpDecl(copied_method_decl)); } while (0)
840 ClangUtil::DumpDecl(copied_method_decl))do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CAS::FOMD found ({0}) {1}", log_info, ClangUtil
::DumpDecl(copied_method_decl)); } while (0)
;
841
842 context.AddNamedDecl(copied_method_decl);
843 }
844
845 return true;
846}
847
848void ClangASTSource::FindDeclInModules(NameSearchContext &context,
849 ConstString name) {
850 Log *log = GetLog(LLDBLog::Expressions);
851
852 std::shared_ptr<ClangModulesDeclVendor> modules_decl_vendor =
853 GetClangModulesDeclVendor();
854 if (!modules_decl_vendor)
855 return;
856
857 bool append = false;
858 uint32_t max_matches = 1;
859 std::vector<clang::NamedDecl *> decls;
860
861 if (!modules_decl_vendor->FindDecls(name, append, max_matches, decls))
862 return;
863
864 LLDB_LOG(log, " CAS::FEVD Matching entity found for \"{0}\" in the modules",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CAS::FEVD Matching entity found for \"{0}\" in the modules"
, name); } while (0)
865 name)do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CAS::FEVD Matching entity found for \"{0}\" in the modules"
, name); } while (0)
;
866
867 clang::NamedDecl *const decl_from_modules = decls[0];
868
869 if (llvm::isa<clang::TypeDecl>(decl_from_modules) ||
870 llvm::isa<clang::ObjCContainerDecl>(decl_from_modules) ||
871 llvm::isa<clang::EnumConstantDecl>(decl_from_modules)) {
872 clang::Decl *copied_decl = CopyDecl(decl_from_modules);
873 clang::NamedDecl *copied_named_decl =
874 copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
875
876 if (!copied_named_decl) {
877 LLDB_LOG(log, " CAS::FEVD - Couldn't export a type from the modules")do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CAS::FEVD - Couldn't export a type from the modules"
); } while (0)
;
878
879 return;
880 }
881
882 context.AddNamedDecl(copied_named_decl);
883
884 context.m_found_type = true;
885 }
886}
887
888void ClangASTSource::FindDeclInObjCRuntime(NameSearchContext &context,
889 ConstString name) {
890 Log *log = GetLog(LLDBLog::Expressions);
891
892 lldb::ProcessSP process(m_target->GetProcessSP());
893
894 if (!process)
895 return;
896
897 ObjCLanguageRuntime *language_runtime(ObjCLanguageRuntime::Get(*process));
898
899 if (!language_runtime)
900 return;
901
902 DeclVendor *decl_vendor = language_runtime->GetDeclVendor();
903
904 if (!decl_vendor)
905 return;
906
907 bool append = false;
908 uint32_t max_matches = 1;
909 std::vector<clang::NamedDecl *> decls;
910
911 auto *clang_decl_vendor = llvm::cast<ClangDeclVendor>(decl_vendor);
912 if (!clang_decl_vendor->FindDecls(name, append, max_matches, decls))
913 return;
914
915 LLDB_LOG(log, " CAS::FEVD Matching type found for \"{0}\" in the runtime",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CAS::FEVD Matching type found for \"{0}\" in the runtime"
, name); } while (0)
916 name)do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CAS::FEVD Matching type found for \"{0}\" in the runtime"
, name); } while (0)
;
917
918 clang::Decl *copied_decl = CopyDecl(decls[0]);
919 clang::NamedDecl *copied_named_decl =
920 copied_decl ? dyn_cast<clang::NamedDecl>(copied_decl) : nullptr;
921
922 if (!copied_named_decl) {
923 LLDB_LOG(log, " CAS::FEVD - Couldn't export a type from the runtime")do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CAS::FEVD - Couldn't export a type from the runtime"
); } while (0)
;
924
925 return;
926 }
927
928 context.AddNamedDecl(copied_named_decl);
929}
930
931void ClangASTSource::FindObjCMethodDecls(NameSearchContext &context) {
932 Log *log = GetLog(LLDBLog::Expressions);
933
934 const DeclarationName &decl_name(context.m_decl_name);
935 const DeclContext *decl_ctx(context.m_decl_context);
936
937 const ObjCInterfaceDecl *interface_decl =
938 dyn_cast<ObjCInterfaceDecl>(decl_ctx);
1
Assuming 'decl_ctx' is a 'ObjCInterfaceDecl'
939
940 if (!interface_decl
1.1
'interface_decl' is non-null
)
2
Taking false branch
941 return;
942
943 do {
944 ClangASTImporter::DeclOrigin original = m_ast_importer_sp->GetDeclOrigin(interface_decl);
945
946 if (!original.Valid())
3
Taking false branch
947 break;
948
949 ObjCInterfaceDecl *original_interface_decl =
5
'original_interface_decl' initialized to a null pointer value
950 dyn_cast<ObjCInterfaceDecl>(original.decl);
4
Assuming field 'decl' is not a 'ObjCInterfaceDecl'
951
952 if (FindObjCMethodDeclsWithOrigin(context, original_interface_decl,
6
Passing null pointer value via 2nd parameter 'original_interface_decl'
7
Calling 'ClangASTSource::FindObjCMethodDeclsWithOrigin'
953 "at origin"))
954 return; // found it, no need to look any further
955 } while (false);
956
957 StreamString ss;
958
959 if (decl_name.isObjCZeroArgSelector()) {
960 ss.Printf("%s", decl_name.getAsString().c_str());
961 } else if (decl_name.isObjCOneArgSelector()) {
962 ss.Printf("%s", decl_name.getAsString().c_str());
963 } else {
964 clang::Selector sel = decl_name.getObjCSelector();
965
966 for (unsigned i = 0, e = sel.getNumArgs(); i != e; ++i) {
967 llvm::StringRef r = sel.getNameForSlot(i);
968 ss.Printf("%s:", r.str().c_str());
969 }
970 }
971 ss.Flush();
972
973 if (ss.GetString().contains("$__lldb"))
974 return; // we don't need any results
975
976 ConstString selector_name(ss.GetString());
977
978 LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "ClangASTSource::FindObjCMethodDecls on (ASTContext*){0} '{1}' "
"for selector [{2} {3}]", m_ast_context, m_clang_ast_context
->getDisplayName(), interface_decl->getName(), selector_name
); } while (0)
979 "ClangASTSource::FindObjCMethodDecls on (ASTContext*){0} '{1}' "do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "ClangASTSource::FindObjCMethodDecls on (ASTContext*){0} '{1}' "
"for selector [{2} {3}]", m_ast_context, m_clang_ast_context
->getDisplayName(), interface_decl->getName(), selector_name
); } while (0)
980 "for selector [{2} {3}]",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "ClangASTSource::FindObjCMethodDecls on (ASTContext*){0} '{1}' "
"for selector [{2} {3}]", m_ast_context, m_clang_ast_context
->getDisplayName(), interface_decl->getName(), selector_name
); } while (0)
981 m_ast_context, m_clang_ast_context->getDisplayName(),do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "ClangASTSource::FindObjCMethodDecls on (ASTContext*){0} '{1}' "
"for selector [{2} {3}]", m_ast_context, m_clang_ast_context
->getDisplayName(), interface_decl->getName(), selector_name
); } while (0)
982 interface_decl->getName(), selector_name)do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "ClangASTSource::FindObjCMethodDecls on (ASTContext*){0} '{1}' "
"for selector [{2} {3}]", m_ast_context, m_clang_ast_context
->getDisplayName(), interface_decl->getName(), selector_name
); } while (0)
;
983 SymbolContextList sc_list;
984
985 ModuleFunctionSearchOptions function_options;
986 function_options.include_symbols = false;
987 function_options.include_inlines = false;
988
989 std::string interface_name = interface_decl->getNameAsString();
990
991 do {
992 StreamString ms;
993 ms.Printf("-[%s %s]", interface_name.c_str(), selector_name.AsCString());
994 ms.Flush();
995 ConstString instance_method_name(ms.GetString());
996
997 sc_list.Clear();
998 m_target->GetImages().FindFunctions(instance_method_name,
999 lldb::eFunctionNameTypeFull,
1000 function_options, sc_list);
1001
1002 if (sc_list.GetSize())
1003 break;
1004
1005 ms.Clear();
1006 ms.Printf("+[%s %s]", interface_name.c_str(), selector_name.AsCString());
1007 ms.Flush();
1008 ConstString class_method_name(ms.GetString());
1009
1010 sc_list.Clear();
1011 m_target->GetImages().FindFunctions(class_method_name,
1012 lldb::eFunctionNameTypeFull,
1013 function_options, sc_list);
1014
1015 if (sc_list.GetSize())
1016 break;
1017
1018 // Fall back and check for methods in categories. If we find methods this
1019 // way, we need to check that they're actually in categories on the desired
1020 // class.
1021
1022 SymbolContextList candidate_sc_list;
1023
1024 m_target->GetImages().FindFunctions(selector_name,
1025 lldb::eFunctionNameTypeSelector,
1026 function_options, candidate_sc_list);
1027
1028 for (uint32_t ci = 0, ce = candidate_sc_list.GetSize(); ci != ce; ++ci) {
1029 SymbolContext candidate_sc;
1030
1031 if (!candidate_sc_list.GetContextAtIndex(ci, candidate_sc))
1032 continue;
1033
1034 if (!candidate_sc.function)
1035 continue;
1036
1037 const char *candidate_name = candidate_sc.function->GetName().AsCString();
1038
1039 const char *cursor = candidate_name;
1040
1041 if (*cursor != '+' && *cursor != '-')
1042 continue;
1043
1044 ++cursor;
1045
1046 if (*cursor != '[')
1047 continue;
1048
1049 ++cursor;
1050
1051 size_t interface_len = interface_name.length();
1052
1053 if (strncmp(cursor, interface_name.c_str(), interface_len))
1054 continue;
1055
1056 cursor += interface_len;
1057
1058 if (*cursor == ' ' || *cursor == '(')
1059 sc_list.Append(candidate_sc);
1060 }
1061 } while (false);
1062
1063 if (sc_list.GetSize()) {
1064 // We found a good function symbol. Use that.
1065
1066 for (uint32_t i = 0, e = sc_list.GetSize(); i != e; ++i) {
1067 SymbolContext sc;
1068
1069 if (!sc_list.GetContextAtIndex(i, sc))
1070 continue;
1071
1072 if (!sc.function)
1073 continue;
1074
1075 CompilerDeclContext function_decl_ctx = sc.function->GetDeclContext();
1076 if (!function_decl_ctx)
1077 continue;
1078
1079 ObjCMethodDecl *method_decl =
1080 TypeSystemClang::DeclContextGetAsObjCMethodDecl(function_decl_ctx);
1081
1082 if (!method_decl)
1083 continue;
1084
1085 ObjCInterfaceDecl *found_interface_decl =
1086 method_decl->getClassInterface();
1087
1088 if (!found_interface_decl)
1089 continue;
1090
1091 if (found_interface_decl->getName() == interface_decl->getName()) {
1092 Decl *copied_decl = CopyDecl(method_decl);
1093
1094 if (!copied_decl)
1095 continue;
1096
1097 ObjCMethodDecl *copied_method_decl =
1098 dyn_cast<ObjCMethodDecl>(copied_decl);
1099
1100 if (!copied_method_decl)
1101 continue;
1102
1103 LLDB_LOG(log, " CAS::FOMD found (in symbols)\n{0}",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CAS::FOMD found (in symbols)\n{0}", ClangUtil::
DumpDecl(copied_method_decl)); } while (0)
1104 ClangUtil::DumpDecl(copied_method_decl))do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CAS::FOMD found (in symbols)\n{0}", ClangUtil::
DumpDecl(copied_method_decl)); } while (0)
;
1105
1106 context.AddNamedDecl(copied_method_decl);
1107 }
1108 }
1109
1110 return;
1111 }
1112
1113 // Try the debug information.
1114
1115 do {
1116 ObjCInterfaceDecl *complete_interface_decl = GetCompleteObjCInterface(
1117 const_cast<ObjCInterfaceDecl *>(interface_decl));
1118
1119 if (!complete_interface_decl)
1120 break;
1121
1122 // We found the complete interface. The runtime never needs to be queried
1123 // in this scenario.
1124
1125 DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl(
1126 complete_interface_decl);
1127
1128 if (complete_interface_decl == interface_decl)
1129 break; // already checked this one
1130
1131 LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CAS::FOPD trying origin " "(ObjCInterfaceDecl*){0}/(ASTContext*){1}..."
, complete_interface_decl, &complete_iface_decl->getASTContext
()); } while (0)
1132 "CAS::FOPD trying origin "do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CAS::FOPD trying origin " "(ObjCInterfaceDecl*){0}/(ASTContext*){1}..."
, complete_interface_decl, &complete_iface_decl->getASTContext
()); } while (0)
1133 "(ObjCInterfaceDecl*){0}/(ASTContext*){1}...",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CAS::FOPD trying origin " "(ObjCInterfaceDecl*){0}/(ASTContext*){1}..."
, complete_interface_decl, &complete_iface_decl->getASTContext
()); } while (0)
1134 complete_interface_decl, &complete_iface_decl->getASTContext())do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CAS::FOPD trying origin " "(ObjCInterfaceDecl*){0}/(ASTContext*){1}..."
, complete_interface_decl, &complete_iface_decl->getASTContext
()); } while (0)
;
1135
1136 FindObjCMethodDeclsWithOrigin(context, complete_interface_decl,
1137 "in debug info");
1138
1139 return;
1140 } while (false);
1141
1142 do {
1143 // Check the modules only if the debug information didn't have a complete
1144 // interface.
1145
1146 if (std::shared_ptr<ClangModulesDeclVendor> modules_decl_vendor =
1147 GetClangModulesDeclVendor()) {
1148 ConstString interface_name(interface_decl->getNameAsString().c_str());
1149 bool append = false;
1150 uint32_t max_matches = 1;
1151 std::vector<clang::NamedDecl *> decls;
1152
1153 if (!modules_decl_vendor->FindDecls(interface_name, append, max_matches,
1154 decls))
1155 break;
1156
1157 ObjCInterfaceDecl *interface_decl_from_modules =
1158 dyn_cast<ObjCInterfaceDecl>(decls[0]);
1159
1160 if (!interface_decl_from_modules)
1161 break;
1162
1163 if (FindObjCMethodDeclsWithOrigin(context, interface_decl_from_modules,
1164 "in modules"))
1165 return;
1166 }
1167 } while (false);
1168
1169 do {
1170 // Check the runtime only if the debug information didn't have a complete
1171 // interface and the modules don't get us anywhere.
1172
1173 lldb::ProcessSP process(m_target->GetProcessSP());
1174
1175 if (!process)
1176 break;
1177
1178 ObjCLanguageRuntime *language_runtime(ObjCLanguageRuntime::Get(*process));
1179
1180 if (!language_runtime)
1181 break;
1182
1183 DeclVendor *decl_vendor = language_runtime->GetDeclVendor();
1184
1185 if (!decl_vendor)
1186 break;
1187
1188 ConstString interface_name(interface_decl->getNameAsString().c_str());
1189 bool append = false;
1190 uint32_t max_matches = 1;
1191 std::vector<clang::NamedDecl *> decls;
1192
1193 auto *clang_decl_vendor = llvm::cast<ClangDeclVendor>(decl_vendor);
1194 if (!clang_decl_vendor->FindDecls(interface_name, append, max_matches,
1195 decls))
1196 break;
1197
1198 ObjCInterfaceDecl *runtime_interface_decl =
1199 dyn_cast<ObjCInterfaceDecl>(decls[0]);
1200
1201 if (!runtime_interface_decl)
1202 break;
1203
1204 FindObjCMethodDeclsWithOrigin(context, runtime_interface_decl,
1205 "in runtime");
1206 } while (false);
1207}
1208
1209static bool FindObjCPropertyAndIvarDeclsWithOrigin(
1210 NameSearchContext &context, ClangASTSource &source,
1211 DeclFromUser<const ObjCInterfaceDecl> &origin_iface_decl) {
1212 Log *log = GetLog(LLDBLog::Expressions);
1213
1214 if (origin_iface_decl.IsInvalid())
1215 return false;
1216
1217 std::string name_str = context.m_decl_name.getAsString();
1218 StringRef name(name_str);
1219 IdentifierInfo &name_identifier(
1220 origin_iface_decl->getASTContext().Idents.get(name));
1221
1222 DeclFromUser<ObjCPropertyDecl> origin_property_decl(
1223 origin_iface_decl->FindPropertyDeclaration(
1224 &name_identifier, ObjCPropertyQueryKind::OBJC_PR_query_instance));
1225
1226 bool found = false;
1227
1228 if (origin_property_decl.IsValid()) {
1229 DeclFromParser<ObjCPropertyDecl> parser_property_decl(
1230 origin_property_decl.Import(source));
1231 if (parser_property_decl.IsValid()) {
1232 LLDB_LOG(log, " CAS::FOPD found\n{0}",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CAS::FOPD found\n{0}", ClangUtil::DumpDecl(parser_property_decl
.decl)); } while (0)
1233 ClangUtil::DumpDecl(parser_property_decl.decl))do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CAS::FOPD found\n{0}", ClangUtil::DumpDecl(parser_property_decl
.decl)); } while (0)
;
1234
1235 context.AddNamedDecl(parser_property_decl.decl);
1236 found = true;
1237 }
1238 }
1239
1240 DeclFromUser<ObjCIvarDecl> origin_ivar_decl(
1241 origin_iface_decl->getIvarDecl(&name_identifier));
1242
1243 if (origin_ivar_decl.IsValid()) {
1244 DeclFromParser<ObjCIvarDecl> parser_ivar_decl(
1245 origin_ivar_decl.Import(source));
1246 if (parser_ivar_decl.IsValid()) {
1247 LLDB_LOG(log, " CAS::FOPD found\n{0}",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CAS::FOPD found\n{0}", ClangUtil::DumpDecl(parser_ivar_decl
.decl)); } while (0)
1248 ClangUtil::DumpDecl(parser_ivar_decl.decl))do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CAS::FOPD found\n{0}", ClangUtil::DumpDecl(parser_ivar_decl
.decl)); } while (0)
;
1249
1250 context.AddNamedDecl(parser_ivar_decl.decl);
1251 found = true;
1252 }
1253 }
1254
1255 return found;
1256}
1257
1258void ClangASTSource::FindObjCPropertyAndIvarDecls(NameSearchContext &context) {
1259 Log *log = GetLog(LLDBLog::Expressions);
1260
1261 DeclFromParser<const ObjCInterfaceDecl> parser_iface_decl(
1262 cast<ObjCInterfaceDecl>(context.m_decl_context));
1263 DeclFromUser<const ObjCInterfaceDecl> origin_iface_decl(
1264 parser_iface_decl.GetOrigin(*this));
1265
1266 ConstString class_name(parser_iface_decl->getNameAsString().c_str());
1267
1268 LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "ClangASTSource::FindObjCPropertyAndIvarDecls on "
"(ASTContext*){0} '{1}' for '{2}.{3}'", m_ast_context, m_clang_ast_context
->getDisplayName(), parser_iface_decl->getName(), context
.m_decl_name.getAsString()); } while (0)
1269 "ClangASTSource::FindObjCPropertyAndIvarDecls on "do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "ClangASTSource::FindObjCPropertyAndIvarDecls on "
"(ASTContext*){0} '{1}' for '{2}.{3}'", m_ast_context, m_clang_ast_context
->getDisplayName(), parser_iface_decl->getName(), context
.m_decl_name.getAsString()); } while (0)
1270 "(ASTContext*){0} '{1}' for '{2}.{3}'",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "ClangASTSource::FindObjCPropertyAndIvarDecls on "
"(ASTContext*){0} '{1}' for '{2}.{3}'", m_ast_context, m_clang_ast_context
->getDisplayName(), parser_iface_decl->getName(), context
.m_decl_name.getAsString()); } while (0)
1271 m_ast_context, m_clang_ast_context->getDisplayName(),do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "ClangASTSource::FindObjCPropertyAndIvarDecls on "
"(ASTContext*){0} '{1}' for '{2}.{3}'", m_ast_context, m_clang_ast_context
->getDisplayName(), parser_iface_decl->getName(), context
.m_decl_name.getAsString()); } while (0)
1272 parser_iface_decl->getName(), context.m_decl_name.getAsString())do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "ClangASTSource::FindObjCPropertyAndIvarDecls on "
"(ASTContext*){0} '{1}' for '{2}.{3}'", m_ast_context, m_clang_ast_context
->getDisplayName(), parser_iface_decl->getName(), context
.m_decl_name.getAsString()); } while (0)
;
1273
1274 if (FindObjCPropertyAndIvarDeclsWithOrigin(context, *this, origin_iface_decl))
1275 return;
1276
1277 LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CAS::FOPD couldn't find the property on origin "
"(ObjCInterfaceDecl*){0}/(ASTContext*){1}, searching " "elsewhere..."
, origin_iface_decl.decl, &origin_iface_decl->getASTContext
()); } while (0)
1278 "CAS::FOPD couldn't find the property on origin "do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CAS::FOPD couldn't find the property on origin "
"(ObjCInterfaceDecl*){0}/(ASTContext*){1}, searching " "elsewhere..."
, origin_iface_decl.decl, &origin_iface_decl->getASTContext
()); } while (0)
1279 "(ObjCInterfaceDecl*){0}/(ASTContext*){1}, searching "do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CAS::FOPD couldn't find the property on origin "
"(ObjCInterfaceDecl*){0}/(ASTContext*){1}, searching " "elsewhere..."
, origin_iface_decl.decl, &origin_iface_decl->getASTContext
()); } while (0)
1280 "elsewhere...",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CAS::FOPD couldn't find the property on origin "
"(ObjCInterfaceDecl*){0}/(ASTContext*){1}, searching " "elsewhere..."
, origin_iface_decl.decl, &origin_iface_decl->getASTContext
()); } while (0)
1281 origin_iface_decl.decl, &origin_iface_decl->getASTContext())do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CAS::FOPD couldn't find the property on origin "
"(ObjCInterfaceDecl*){0}/(ASTContext*){1}, searching " "elsewhere..."
, origin_iface_decl.decl, &origin_iface_decl->getASTContext
()); } while (0)
;
1282
1283 SymbolContext null_sc;
1284 TypeList type_list;
1285
1286 do {
1287 ObjCInterfaceDecl *complete_interface_decl = GetCompleteObjCInterface(
1288 const_cast<ObjCInterfaceDecl *>(parser_iface_decl.decl));
1289
1290 if (!complete_interface_decl)
1291 break;
1292
1293 // We found the complete interface. The runtime never needs to be queried
1294 // in this scenario.
1295
1296 DeclFromUser<const ObjCInterfaceDecl> complete_iface_decl(
1297 complete_interface_decl);
1298
1299 if (complete_iface_decl.decl == origin_iface_decl.decl)
1300 break; // already checked this one
1301
1302 LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CAS::FOPD trying origin " "(ObjCInterfaceDecl*){0}/(ASTContext*){1}..."
, complete_iface_decl.decl, &complete_iface_decl->getASTContext
()); } while (0)
1303 "CAS::FOPD trying origin "do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CAS::FOPD trying origin " "(ObjCInterfaceDecl*){0}/(ASTContext*){1}..."
, complete_iface_decl.decl, &complete_iface_decl->getASTContext
()); } while (0)
1304 "(ObjCInterfaceDecl*){0}/(ASTContext*){1}...",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CAS::FOPD trying origin " "(ObjCInterfaceDecl*){0}/(ASTContext*){1}..."
, complete_iface_decl.decl, &complete_iface_decl->getASTContext
()); } while (0)
1305 complete_iface_decl.decl, &complete_iface_decl->getASTContext())do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CAS::FOPD trying origin " "(ObjCInterfaceDecl*){0}/(ASTContext*){1}..."
, complete_iface_decl.decl, &complete_iface_decl->getASTContext
()); } while (0)
;
1306
1307 FindObjCPropertyAndIvarDeclsWithOrigin(context, *this, complete_iface_decl);
1308
1309 return;
1310 } while (false);
1311
1312 do {
1313 // Check the modules only if the debug information didn't have a complete
1314 // interface.
1315
1316 std::shared_ptr<ClangModulesDeclVendor> modules_decl_vendor =
1317 GetClangModulesDeclVendor();
1318
1319 if (!modules_decl_vendor)
1320 break;
1321
1322 bool append = false;
1323 uint32_t max_matches = 1;
1324 std::vector<clang::NamedDecl *> decls;
1325
1326 if (!modules_decl_vendor->FindDecls(class_name, append, max_matches, decls))
1327 break;
1328
1329 DeclFromUser<const ObjCInterfaceDecl> interface_decl_from_modules(
1330 dyn_cast<ObjCInterfaceDecl>(decls[0]));
1331
1332 if (!interface_decl_from_modules.IsValid())
1333 break;
1334
1335 LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CAS::FOPD[{0}] trying module " "(ObjCInterfaceDecl*){0}/(ASTContext*){1}..."
, interface_decl_from_modules.decl, &interface_decl_from_modules
->getASTContext()); } while (0)
1336 "CAS::FOPD[{0}] trying module "do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CAS::FOPD[{0}] trying module " "(ObjCInterfaceDecl*){0}/(ASTContext*){1}..."
, interface_decl_from_modules.decl, &interface_decl_from_modules
->getASTContext()); } while (0)
1337 "(ObjCInterfaceDecl*){0}/(ASTContext*){1}...",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CAS::FOPD[{0}] trying module " "(ObjCInterfaceDecl*){0}/(ASTContext*){1}..."
, interface_decl_from_modules.decl, &interface_decl_from_modules
->getASTContext()); } while (0)
1338 interface_decl_from_modules.decl,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CAS::FOPD[{0}] trying module " "(ObjCInterfaceDecl*){0}/(ASTContext*){1}..."
, interface_decl_from_modules.decl, &interface_decl_from_modules
->getASTContext()); } while (0)
1339 &interface_decl_from_modules->getASTContext())do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CAS::FOPD[{0}] trying module " "(ObjCInterfaceDecl*){0}/(ASTContext*){1}..."
, interface_decl_from_modules.decl, &interface_decl_from_modules
->getASTContext()); } while (0)
;
1340
1341 if (FindObjCPropertyAndIvarDeclsWithOrigin(context, *this,
1342 interface_decl_from_modules))
1343 return;
1344 } while (false);
1345
1346 do {
1347 // Check the runtime only if the debug information didn't have a complete
1348 // interface and nothing was in the modules.
1349
1350 lldb::ProcessSP process(m_target->GetProcessSP());
1351
1352 if (!process)
1353 return;
1354
1355 ObjCLanguageRuntime *language_runtime(ObjCLanguageRuntime::Get(*process));
1356
1357 if (!language_runtime)
1358 return;
1359
1360 DeclVendor *decl_vendor = language_runtime->GetDeclVendor();
1361
1362 if (!decl_vendor)
1363 break;
1364
1365 bool append = false;
1366 uint32_t max_matches = 1;
1367 std::vector<clang::NamedDecl *> decls;
1368
1369 auto *clang_decl_vendor = llvm::cast<ClangDeclVendor>(decl_vendor);
1370 if (!clang_decl_vendor->FindDecls(class_name, append, max_matches, decls))
1371 break;
1372
1373 DeclFromUser<const ObjCInterfaceDecl> interface_decl_from_runtime(
1374 dyn_cast<ObjCInterfaceDecl>(decls[0]));
1375
1376 if (!interface_decl_from_runtime.IsValid())
1377 break;
1378
1379 LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CAS::FOPD[{0}] trying runtime " "(ObjCInterfaceDecl*){0}/(ASTContext*){1}..."
, interface_decl_from_runtime.decl, &interface_decl_from_runtime
->getASTContext()); } while (0)
1380 "CAS::FOPD[{0}] trying runtime "do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CAS::FOPD[{0}] trying runtime " "(ObjCInterfaceDecl*){0}/(ASTContext*){1}..."
, interface_decl_from_runtime.decl, &interface_decl_from_runtime
->getASTContext()); } while (0)
1381 "(ObjCInterfaceDecl*){0}/(ASTContext*){1}...",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CAS::FOPD[{0}] trying runtime " "(ObjCInterfaceDecl*){0}/(ASTContext*){1}..."
, interface_decl_from_runtime.decl, &interface_decl_from_runtime
->getASTContext()); } while (0)
1382 interface_decl_from_runtime.decl,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CAS::FOPD[{0}] trying runtime " "(ObjCInterfaceDecl*){0}/(ASTContext*){1}..."
, interface_decl_from_runtime.decl, &interface_decl_from_runtime
->getASTContext()); } while (0)
1383 &interface_decl_from_runtime->getASTContext())do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CAS::FOPD[{0}] trying runtime " "(ObjCInterfaceDecl*){0}/(ASTContext*){1}..."
, interface_decl_from_runtime.decl, &interface_decl_from_runtime
->getASTContext()); } while (0)
;
1384
1385 if (FindObjCPropertyAndIvarDeclsWithOrigin(context, *this,
1386 interface_decl_from_runtime))
1387 return;
1388 } while (false);
1389}
1390
1391void ClangASTSource::LookupInNamespace(NameSearchContext &context) {
1392 const NamespaceDecl *namespace_context =
1393 dyn_cast<NamespaceDecl>(context.m_decl_context);
1394
1395 Log *log = GetLog(LLDBLog::Expressions);
1396
1397 ClangASTImporter::NamespaceMapSP namespace_map =
1398 m_ast_importer_sp->GetNamespaceMap(namespace_context);
1399
1400 LLDB_LOGV(log, " CAS::FEVD Inspecting namespace map {0} ({1} entries)",do { ::lldb_private::Log *log_private = (log); if (log_private
&& log_private->GetVerbose()) log_private->Format
("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CAS::FEVD Inspecting namespace map {0} ({1} entries)"
, namespace_map.get(), namespace_map->size()); } while (0)
1401 namespace_map.get(), namespace_map->size())do { ::lldb_private::Log *log_private = (log); if (log_private
&& log_private->GetVerbose()) log_private->Format
("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CAS::FEVD Inspecting namespace map {0} ({1} entries)"
, namespace_map.get(), namespace_map->size()); } while (0)
;
1402
1403 if (!namespace_map)
1404 return;
1405
1406 for (ClangASTImporter::NamespaceMap::iterator i = namespace_map->begin(),
1407 e = namespace_map->end();
1408 i != e; ++i) {
1409 LLDB_LOG(log, " CAS::FEVD Searching namespace {0} in module {1}",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CAS::FEVD Searching namespace {0} in module {1}"
, i->second.GetName(), i->first->GetFileSpec().GetFilename
()); } while (0)
1410 i->second.GetName(), i->first->GetFileSpec().GetFilename())do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CAS::FEVD Searching namespace {0} in module {1}"
, i->second.GetName(), i->first->GetFileSpec().GetFilename
()); } while (0)
;
1411
1412 FindExternalVisibleDecls(context, i->first, i->second);
1413 }
1414}
1415
1416typedef llvm::DenseMap<const FieldDecl *, uint64_t> FieldOffsetMap;
1417typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetMap;
1418
1419template <class D, class O>
1420static bool ImportOffsetMap(llvm::DenseMap<const D *, O> &destination_map,
1421 llvm::DenseMap<const D *, O> &source_map,
1422 ClangASTSource &source) {
1423 // When importing fields into a new record, clang has a hard requirement that
1424 // fields be imported in field offset order. Since they are stored in a
1425 // DenseMap with a pointer as the key type, this means we cannot simply
1426 // iterate over the map, as the order will be non-deterministic. Instead we
1427 // have to sort by the offset and then insert in sorted order.
1428 typedef llvm::DenseMap<const D *, O> MapType;
1429 typedef typename MapType::value_type PairType;
1430 std::vector<PairType> sorted_items;
1431 sorted_items.reserve(source_map.size());
1432 sorted_items.assign(source_map.begin(), source_map.end());
1433 llvm::sort(sorted_items.begin(), sorted_items.end(),
1434 [](const PairType &lhs, const PairType &rhs) {
1435 return lhs.second < rhs.second;
1436 });
1437
1438 for (const auto &item : sorted_items) {
1439 DeclFromUser<D> user_decl(const_cast<D *>(item.first));
1440 DeclFromParser<D> parser_decl(user_decl.Import(source));
1441 if (parser_decl.IsInvalid())
1442 return false;
1443 destination_map.insert(
1444 std::pair<const D *, O>(parser_decl.decl, item.second));
1445 }
1446
1447 return true;
1448}
1449
1450template <bool IsVirtual>
1451bool ExtractBaseOffsets(const ASTRecordLayout &record_layout,
1452 DeclFromUser<const CXXRecordDecl> &record,
1453 BaseOffsetMap &base_offsets) {
1454 for (CXXRecordDecl::base_class_const_iterator
1455 bi = (IsVirtual ? record->vbases_begin() : record->bases_begin()),
1456 be = (IsVirtual ? record->vbases_end() : record->bases_end());
1457 bi != be; ++bi) {
1458 if (!IsVirtual && bi->isVirtual())
1459 continue;
1460
1461 const clang::Type *origin_base_type = bi->getType().getTypePtr();
1462 const clang::RecordType *origin_base_record_type =
1463 origin_base_type->getAs<RecordType>();
1464
1465 if (!origin_base_record_type)
1466 return false;
1467
1468 DeclFromUser<RecordDecl> origin_base_record(
1469 origin_base_record_type->getDecl());
1470
1471 if (origin_base_record.IsInvalid())
1472 return false;
1473
1474 DeclFromUser<CXXRecordDecl> origin_base_cxx_record(
1475 DynCast<CXXRecordDecl>(origin_base_record));
1476
1477 if (origin_base_cxx_record.IsInvalid())
1478 return false;
1479
1480 CharUnits base_offset;
1481
1482 if (IsVirtual)
1483 base_offset =
1484 record_layout.getVBaseClassOffset(origin_base_cxx_record.decl);
1485 else
1486 base_offset =
1487 record_layout.getBaseClassOffset(origin_base_cxx_record.decl);
1488
1489 base_offsets.insert(std::pair<const CXXRecordDecl *, CharUnits>(
1490 origin_base_cxx_record.decl, base_offset));
1491 }
1492
1493 return true;
1494}
1495
1496bool ClangASTSource::layoutRecordType(const RecordDecl *record, uint64_t &size,
1497 uint64_t &alignment,
1498 FieldOffsetMap &field_offsets,
1499 BaseOffsetMap &base_offsets,
1500 BaseOffsetMap &virtual_base_offsets) {
1501
1502 Log *log = GetLog(LLDBLog::Expressions);
1503
1504 LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "LayoutRecordType on (ASTContext*){0} '{1}' for (RecordDecl*)"
"{2} [name = '{3}']", m_ast_context, m_clang_ast_context->
getDisplayName(), record, record->getName()); } while (0)
1505 "LayoutRecordType on (ASTContext*){0} '{1}' for (RecordDecl*)"do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "LayoutRecordType on (ASTContext*){0} '{1}' for (RecordDecl*)"
"{2} [name = '{3}']", m_ast_context, m_clang_ast_context->
getDisplayName(), record, record->getName()); } while (0)
1506 "{2} [name = '{3}']",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "LayoutRecordType on (ASTContext*){0} '{1}' for (RecordDecl*)"
"{2} [name = '{3}']", m_ast_context, m_clang_ast_context->
getDisplayName(), record, record->getName()); } while (0)
1507 m_ast_context, m_clang_ast_context->getDisplayName(), record,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "LayoutRecordType on (ASTContext*){0} '{1}' for (RecordDecl*)"
"{2} [name = '{3}']", m_ast_context, m_clang_ast_context->
getDisplayName(), record, record->getName()); } while (0)
1508 record->getName())do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "LayoutRecordType on (ASTContext*){0} '{1}' for (RecordDecl*)"
"{2} [name = '{3}']", m_ast_context, m_clang_ast_context->
getDisplayName(), record, record->getName()); } while (0)
;
1509
1510 DeclFromParser<const RecordDecl> parser_record(record);
1511 DeclFromUser<const RecordDecl> origin_record(
1512 parser_record.GetOrigin(*this));
1513
1514 if (origin_record.IsInvalid())
1515 return false;
1516
1517 FieldOffsetMap origin_field_offsets;
1518 BaseOffsetMap origin_base_offsets;
1519 BaseOffsetMap origin_virtual_base_offsets;
1520
1521 TypeSystemClang::GetCompleteDecl(
1522 &origin_record->getASTContext(),
1523 const_cast<RecordDecl *>(origin_record.decl));
1524
1525 clang::RecordDecl *definition = origin_record.decl->getDefinition();
1526 if (!definition || !definition->isCompleteDefinition())
1527 return false;
1528
1529 const ASTRecordLayout &record_layout(
1530 origin_record->getASTContext().getASTRecordLayout(origin_record.decl));
1531
1532 int field_idx = 0, field_count = record_layout.getFieldCount();
1533
1534 for (RecordDecl::field_iterator fi = origin_record->field_begin(),
1535 fe = origin_record->field_end();
1536 fi != fe; ++fi) {
1537 if (field_idx >= field_count)
1538 return false; // Layout didn't go well. Bail out.
1539
1540 uint64_t field_offset = record_layout.getFieldOffset(field_idx);
1541
1542 origin_field_offsets.insert(
1543 std::pair<const FieldDecl *, uint64_t>(*fi, field_offset));
1544
1545 field_idx++;
1546 }
1547
1548 lldbassert(&record->getASTContext() == m_ast_context)lldb_private::lldb_assert(static_cast<bool>(&record
->getASTContext() == m_ast_context), "&record->getASTContext() == m_ast_context"
, __FUNCTION__, "lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, 1548)
;
1549
1550 DeclFromUser<const CXXRecordDecl> origin_cxx_record(
1551 DynCast<const CXXRecordDecl>(origin_record));
1552
1553 if (origin_cxx_record.IsValid()) {
1554 if (!ExtractBaseOffsets<false>(record_layout, origin_cxx_record,
1555 origin_base_offsets) ||
1556 !ExtractBaseOffsets<true>(record_layout, origin_cxx_record,
1557 origin_virtual_base_offsets))
1558 return false;
1559 }
1560
1561 if (!ImportOffsetMap(field_offsets, origin_field_offsets, *this) ||
1562 !ImportOffsetMap(base_offsets, origin_base_offsets, *this) ||
1563 !ImportOffsetMap(virtual_base_offsets, origin_virtual_base_offsets,
1564 *this))
1565 return false;
1566
1567 size = record_layout.getSize().getQuantity() * m_ast_context->getCharWidth();
1568 alignment = record_layout.getAlignment().getQuantity() *
1569 m_ast_context->getCharWidth();
1570
1571 if (log) {
1572 LLDB_LOG(log, "LRT returned:")do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "LRT returned:"); } while (0)
;
1573 LLDB_LOG(log, "LRT Original = (RecordDecl*){0}",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "LRT Original = (RecordDecl*){0}", static_cast<
const void *>(origin_record.decl)); } while (0)
1574 static_cast<const void *>(origin_record.decl))do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "LRT Original = (RecordDecl*){0}", static_cast<
const void *>(origin_record.decl)); } while (0)
;
1575 LLDB_LOG(log, "LRT Size = {0}", size)do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "LRT Size = {0}", size); } while (0)
;
1576 LLDB_LOG(log, "LRT Alignment = {0}", alignment)do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "LRT Alignment = {0}", alignment); } while (0)
;
1577 LLDB_LOG(log, "LRT Fields:")do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "LRT Fields:"); } while (0)
;
1578 for (RecordDecl::field_iterator fi = record->field_begin(),
1579 fe = record->field_end();
1580 fi != fe; ++fi) {
1581 LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "LRT (FieldDecl*){0}, Name = '{1}', Type = '{2}', Offset = "
"{3} bits", *fi, fi->getName(), fi->getType().getAsString
(), field_offsets[*fi]); } while (0)
1582 "LRT (FieldDecl*){0}, Name = '{1}', Type = '{2}', Offset = "do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "LRT (FieldDecl*){0}, Name = '{1}', Type = '{2}', Offset = "
"{3} bits", *fi, fi->getName(), fi->getType().getAsString
(), field_offsets[*fi]); } while (0)
1583 "{3} bits",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "LRT (FieldDecl*){0}, Name = '{1}', Type = '{2}', Offset = "
"{3} bits", *fi, fi->getName(), fi->getType().getAsString
(), field_offsets[*fi]); } while (0)
1584 *fi, fi->getName(), fi->getType().getAsString(),do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "LRT (FieldDecl*){0}, Name = '{1}', Type = '{2}', Offset = "
"{3} bits", *fi, fi->getName(), fi->getType().getAsString
(), field_offsets[*fi]); } while (0)
1585 field_offsets[*fi])do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "LRT (FieldDecl*){0}, Name = '{1}', Type = '{2}', Offset = "
"{3} bits", *fi, fi->getName(), fi->getType().getAsString
(), field_offsets[*fi]); } while (0)
;
1586 }
1587 DeclFromParser<const CXXRecordDecl> parser_cxx_record =
1588 DynCast<const CXXRecordDecl>(parser_record);
1589 if (parser_cxx_record.IsValid()) {
1590 LLDB_LOG(log, "LRT Bases:")do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "LRT Bases:"); } while (0)
;
1591 for (CXXRecordDecl::base_class_const_iterator
1592 bi = parser_cxx_record->bases_begin(),
1593 be = parser_cxx_record->bases_end();
1594 bi != be; ++bi) {
1595 bool is_virtual = bi->isVirtual();
1596
1597 QualType base_type = bi->getType();
1598 const RecordType *base_record_type = base_type->getAs<RecordType>();
1599 DeclFromParser<RecordDecl> base_record(base_record_type->getDecl());
1600 DeclFromParser<CXXRecordDecl> base_cxx_record =
1601 DynCast<CXXRecordDecl>(base_record);
1602
1603 LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "LRT {0}(CXXRecordDecl*){1}, Name = '{2}', Offset = "
"{3} chars", (is_virtual ? "Virtual " : ""), base_cxx_record
.decl, base_cxx_record.decl->getName(), (is_virtual ? virtual_base_offsets
[base_cxx_record.decl].getQuantity() : base_offsets[base_cxx_record
.decl].getQuantity())); } while (0)
1604 "LRT {0}(CXXRecordDecl*){1}, Name = '{2}', Offset = "do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "LRT {0}(CXXRecordDecl*){1}, Name = '{2}', Offset = "
"{3} chars", (is_virtual ? "Virtual " : ""), base_cxx_record
.decl, base_cxx_record.decl->getName(), (is_virtual ? virtual_base_offsets
[base_cxx_record.decl].getQuantity() : base_offsets[base_cxx_record
.decl].getQuantity())); } while (0)
1605 "{3} chars",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "LRT {0}(CXXRecordDecl*){1}, Name = '{2}', Offset = "
"{3} chars", (is_virtual ? "Virtual " : ""), base_cxx_record
.decl, base_cxx_record.decl->getName(), (is_virtual ? virtual_base_offsets
[base_cxx_record.decl].getQuantity() : base_offsets[base_cxx_record
.decl].getQuantity())); } while (0)
1606 (is_virtual ? "Virtual " : ""), base_cxx_record.decl,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "LRT {0}(CXXRecordDecl*){1}, Name = '{2}', Offset = "
"{3} chars", (is_virtual ? "Virtual " : ""), base_cxx_record
.decl, base_cxx_record.decl->getName(), (is_virtual ? virtual_base_offsets
[base_cxx_record.decl].getQuantity() : base_offsets[base_cxx_record
.decl].getQuantity())); } while (0)
1607 base_cxx_record.decl->getName(),do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "LRT {0}(CXXRecordDecl*){1}, Name = '{2}', Offset = "
"{3} chars", (is_virtual ? "Virtual " : ""), base_cxx_record
.decl, base_cxx_record.decl->getName(), (is_virtual ? virtual_base_offsets
[base_cxx_record.decl].getQuantity() : base_offsets[base_cxx_record
.decl].getQuantity())); } while (0)
1608 (is_virtualdo { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "LRT {0}(CXXRecordDecl*){1}, Name = '{2}', Offset = "
"{3} chars", (is_virtual ? "Virtual " : ""), base_cxx_record
.decl, base_cxx_record.decl->getName(), (is_virtual ? virtual_base_offsets
[base_cxx_record.decl].getQuantity() : base_offsets[base_cxx_record
.decl].getQuantity())); } while (0)
1609 ? virtual_base_offsets[base_cxx_record.decl].getQuantity()do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "LRT {0}(CXXRecordDecl*){1}, Name = '{2}', Offset = "
"{3} chars", (is_virtual ? "Virtual " : ""), base_cxx_record
.decl, base_cxx_record.decl->getName(), (is_virtual ? virtual_base_offsets
[base_cxx_record.decl].getQuantity() : base_offsets[base_cxx_record
.decl].getQuantity())); } while (0)
1610 : base_offsets[base_cxx_record.decl].getQuantity()))do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "LRT {0}(CXXRecordDecl*){1}, Name = '{2}', Offset = "
"{3} chars", (is_virtual ? "Virtual " : ""), base_cxx_record
.decl, base_cxx_record.decl->getName(), (is_virtual ? virtual_base_offsets
[base_cxx_record.decl].getQuantity() : base_offsets[base_cxx_record
.decl].getQuantity())); } while (0)
;
1611 }
1612 } else {
1613 LLDB_LOG(log, "LRD Not a CXXRecord, so no bases")do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "LRD Not a CXXRecord, so no bases"); } while (0
)
;
1614 }
1615 }
1616
1617 return true;
1618}
1619
1620void ClangASTSource::CompleteNamespaceMap(
1621 ClangASTImporter::NamespaceMapSP &namespace_map, ConstString name,
1622 ClangASTImporter::NamespaceMapSP &parent_map) const {
1623
1624 Log *log = GetLog(LLDBLog::Expressions);
1625
1626 if (log) {
1627 if (parent_map && parent_map->size())
1628 LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CompleteNamespaceMap on (ASTContext*){0} '{1}' Searching "
"for namespace {2} in namespace {3}", m_ast_context, m_clang_ast_context
->getDisplayName(), name, parent_map->begin()->second
.GetName()); } while (0)
1629 "CompleteNamespaceMap on (ASTContext*){0} '{1}' Searching "do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CompleteNamespaceMap on (ASTContext*){0} '{1}' Searching "
"for namespace {2} in namespace {3}", m_ast_context, m_clang_ast_context
->getDisplayName(), name, parent_map->begin()->second
.GetName()); } while (0)
1630 "for namespace {2} in namespace {3}",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CompleteNamespaceMap on (ASTContext*){0} '{1}' Searching "
"for namespace {2} in namespace {3}", m_ast_context, m_clang_ast_context
->getDisplayName(), name, parent_map->begin()->second
.GetName()); } while (0)
1631 m_ast_context, m_clang_ast_context->getDisplayName(), name,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CompleteNamespaceMap on (ASTContext*){0} '{1}' Searching "
"for namespace {2} in namespace {3}", m_ast_context, m_clang_ast_context
->getDisplayName(), name, parent_map->begin()->second
.GetName()); } while (0)
1632 parent_map->begin()->second.GetName())do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CompleteNamespaceMap on (ASTContext*){0} '{1}' Searching "
"for namespace {2} in namespace {3}", m_ast_context, m_clang_ast_context
->getDisplayName(), name, parent_map->begin()->second
.GetName()); } while (0)
;
1633 else
1634 LLDB_LOG(log,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CompleteNamespaceMap on (ASTContext*){0} '{1}' Searching "
"for namespace {2}", m_ast_context, m_clang_ast_context->
getDisplayName(), name); } while (0)
1635 "CompleteNamespaceMap on (ASTContext*){0} '{1}' Searching "do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CompleteNamespaceMap on (ASTContext*){0} '{1}' Searching "
"for namespace {2}", m_ast_context, m_clang_ast_context->
getDisplayName(), name); } while (0)
1636 "for namespace {2}",do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CompleteNamespaceMap on (ASTContext*){0} '{1}' Searching "
"for namespace {2}", m_ast_context, m_clang_ast_context->
getDisplayName(), name); } while (0)
1637 m_ast_context, m_clang_ast_context->getDisplayName(), name)do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, "CompleteNamespaceMap on (ASTContext*){0} '{1}' Searching "
"for namespace {2}", m_ast_context, m_clang_ast_context->
getDisplayName(), name); } while (0)
;
1638 }
1639
1640 if (parent_map) {
1641 for (ClangASTImporter::NamespaceMap::iterator i = parent_map->begin(),
1642 e = parent_map->end();
1643 i != e; ++i) {
1644 CompilerDeclContext found_namespace_decl;
1645
1646 lldb::ModuleSP module_sp = i->first;
1647 CompilerDeclContext module_parent_namespace_decl = i->second;
1648
1649 SymbolFile *symbol_file = module_sp->GetSymbolFile();
1650
1651 if (!symbol_file)
1652 continue;
1653
1654 found_namespace_decl =
1655 symbol_file->FindNamespace(name, module_parent_namespace_decl);
1656
1657 if (!found_namespace_decl)
1658 continue;
1659
1660 namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>(
1661 module_sp, found_namespace_decl));
1662
1663 LLDB_LOG(log, " CMN Found namespace {0} in module {1}", name,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CMN Found namespace {0} in module {1}", name, module_sp
->GetFileSpec().GetFilename()); } while (0)
1664 module_sp->GetFileSpec().GetFilename())do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CMN Found namespace {0} in module {1}", name, module_sp
->GetFileSpec().GetFilename()); } while (0)
;
1665 }
1666 } else {
1667 CompilerDeclContext null_namespace_decl;
1668 for (lldb::ModuleSP image : m_target->GetImages().Modules()) {
1669 if (!image)
1670 continue;
1671
1672 CompilerDeclContext found_namespace_decl;
1673
1674 SymbolFile *symbol_file = image->GetSymbolFile();
1675
1676 if (!symbol_file)
1677 continue;
1678
1679 found_namespace_decl =
1680 symbol_file->FindNamespace(name, null_namespace_decl);
1681
1682 if (!found_namespace_decl)
1683 continue;
1684
1685 namespace_map->push_back(std::pair<lldb::ModuleSP, CompilerDeclContext>(
1686 image, found_namespace_decl));
1687
1688 LLDB_LOG(log, " CMN[{0}] Found namespace {0} in module {1}", name,do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CMN[{0}] Found namespace {0} in module {1}", name
, image->GetFileSpec().GetFilename()); } while (0)
1689 image->GetFileSpec().GetFilename())do { ::lldb_private::Log *log_private = (log); if (log_private
) log_private->Format("lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp"
, __func__, " CMN[{0}] Found namespace {0} in module {1}", name
, image->GetFileSpec().GetFilename()); } while (0)
;
1690 }
1691 }
1692}
1693
1694NamespaceDecl *ClangASTSource::AddNamespace(
1695 NameSearchContext &context,
1696 ClangASTImporter::NamespaceMapSP &namespace_decls) {
1697 if (!namespace_decls)
1698 return nullptr;
1699
1700 const CompilerDeclContext &namespace_decl = namespace_decls->begin()->second;
1701
1702 clang::ASTContext *src_ast =
1703 TypeSystemClang::DeclContextGetTypeSystemClang(namespace_decl);
1704 if (!src_ast)
1705 return nullptr;
1706 clang::NamespaceDecl *src_namespace_decl =
1707 TypeSystemClang::DeclContextGetAsNamespaceDecl(namespace_decl);
1708
1709 if (!src_namespace_decl)
1710 return nullptr;
1711
1712 Decl *copied_decl = CopyDecl(src_namespace_decl);
1713
1714 if (!copied_decl)
1715 return nullptr;
1716
1717 NamespaceDecl *copied_namespace_decl = dyn_cast<NamespaceDecl>(copied_decl);
1718
1719 if (!copied_namespace_decl)
1720 return nullptr;
1721
1722 context.m_decls.push_back(copied_namespace_decl);
1723
1724 m_ast_importer_sp->RegisterNamespaceMap(copied_namespace_decl,
1725 namespace_decls);
1726
1727 return dyn_cast<NamespaceDecl>(copied_decl);
1728}
1729
1730clang::Decl *ClangASTSource::CopyDecl(Decl *src_decl) {
1731 return m_ast_importer_sp->CopyDecl(m_ast_context, src_decl);
1732}
1733
1734ClangASTImporter::DeclOrigin ClangASTSource::GetDeclOrigin(const clang::Decl *decl) {
1735 return m_ast_importer_sp->GetDeclOrigin(decl);
1736}
1737
1738CompilerType ClangASTSource::GuardedCopyType(const CompilerType &src_type) {
1739 TypeSystemClang *src_ast =
1740 llvm::dyn_cast_or_null<TypeSystemClang>(src_type.GetTypeSystem());
1741 if (src_ast == nullptr)
1742 return CompilerType();
1743
1744 QualType copied_qual_type = ClangUtil::GetQualType(
1745 m_ast_importer_sp->CopyType(*m_clang_ast_context, src_type));
1746
1747 if (copied_qual_type.getAsOpaquePtr() &&
1748 copied_qual_type->getCanonicalTypeInternal().isNull())
1749 // this shouldn't happen, but we're hardening because the AST importer
1750 // seems to be generating bad types on occasion.
1751 return CompilerType();
1752
1753 return m_clang_ast_context->GetType(copied_qual_type);
1754}
1755
1756std::shared_ptr<ClangModulesDeclVendor>
1757ClangASTSource::GetClangModulesDeclVendor() {
1758 auto persistent_vars = llvm::cast<ClangPersistentVariables>(
1759 m_target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC));
1760 return persistent_vars->GetClangModulesDeclVendor();
1761}