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 |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | ||||
34 | using namespace clang; | |||
35 | using namespace lldb_private; | |||
36 | ||||
37 | // Scoped class that will remove an active lexical decl from the set when it | |||
38 | // goes out of scope. | |||
39 | namespace { | |||
40 | class ScopedLexicalDeclEraser { | |||
41 | public: | |||
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 | ||||
48 | private: | |||
49 | std::set<const clang::Decl *> &m_active_lexical_decls; | |||
50 | const clang::Decl *m_decl; | |||
51 | }; | |||
52 | } | |||
53 | ||||
54 | ClangASTSource::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 | ||||
63 | void 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 | ||||
70 | ClangASTSource::~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 | ||||
93 | void 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. | |||
102 | bool 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 | ||||
186 | TagDecl *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 | ||||
281 | void 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 | ||||
310 | void 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 | ||||
345 | clang::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 | ||||
386 | void 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 | ||||
519 | void 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 | ||||
575 | clang::Sema *ClangASTSource::getSema() { | |||
576 | return m_clang_ast_context->getSema(); | |||
577 | } | |||
578 | ||||
579 | bool 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 | ||||
596 | void 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 | ||||
665 | void 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 | ||||
716 | template <class D> class TaggedASTDecl { | |||
717 | public: | |||
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 | ||||
726 | template <class D2, template <class D> class TD, class D1> | |||
727 | TD<D2> DynCast(TD<D1> source) { | |||
728 | return TD<D2>(dyn_cast<D2>(source.decl)); | |||
729 | } | |||
730 | ||||
731 | template <class D = Decl> class DeclFromParser; | |||
732 | template <class D = Decl> class DeclFromUser; | |||
733 | ||||
734 | template <class D> class DeclFromParser : public TaggedASTDecl<D> { | |||
735 | public: | |||
736 | DeclFromParser() : TaggedASTDecl<D>() {} | |||
737 | DeclFromParser(D *_decl) : TaggedASTDecl<D>(_decl) {} | |||
738 | ||||
739 | DeclFromUser<D> GetOrigin(ClangASTSource &source); | |||
740 | }; | |||
741 | ||||
742 | template <class D> class DeclFromUser : public TaggedASTDecl<D> { | |||
743 | public: | |||
744 | DeclFromUser() : TaggedASTDecl<D>() {} | |||
745 | DeclFromUser(D *_decl) : TaggedASTDecl<D>(_decl) {} | |||
746 | ||||
747 | DeclFromParser<D> Import(ClangASTSource &source); | |||
748 | }; | |||
749 | ||||
750 | template <class D> | |||
751 | DeclFromUser<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 | ||||
758 | template <class D> | |||
759 | DeclFromParser<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 | ||||
766 | bool 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(); | |||
| ||||
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 | ||||
848 | void 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 | ||||
888 | void 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 | ||||
931 | void 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); | |||
| ||||
939 | ||||
940 | if (!interface_decl
| |||
941 | return; | |||
942 | ||||
943 | do { | |||
944 | ClangASTImporter::DeclOrigin original = m_ast_importer_sp->GetDeclOrigin(interface_decl); | |||
945 | ||||
946 | if (!original.Valid()) | |||
947 | break; | |||
948 | ||||
949 | ObjCInterfaceDecl *original_interface_decl = | |||
950 | dyn_cast<ObjCInterfaceDecl>(original.decl); | |||
951 | ||||
952 | if (FindObjCMethodDeclsWithOrigin(context, original_interface_decl, | |||
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 | ||||
1209 | static 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 | ||||
1258 | void 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 | ||||
1391 | void 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 | ||||
1416 | typedef llvm::DenseMap<const FieldDecl *, uint64_t> FieldOffsetMap; | |||
1417 | typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetMap; | |||
1418 | ||||
1419 | template <class D, class O> | |||
1420 | static 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 | ||||
1450 | template <bool IsVirtual> | |||
1451 | bool 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 | ||||
1496 | bool 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 | ||||
1620 | void 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 | ||||
1694 | NamespaceDecl *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 | ||||
1730 | clang::Decl *ClangASTSource::CopyDecl(Decl *src_decl) { | |||
1731 | return m_ast_importer_sp->CopyDecl(m_ast_context, src_decl); | |||
1732 | } | |||
1733 | ||||
1734 | ClangASTImporter::DeclOrigin ClangASTSource::GetDeclOrigin(const clang::Decl *decl) { | |||
1735 | return m_ast_importer_sp->GetDeclOrigin(decl); | |||
1736 | } | |||
1737 | ||||
1738 | CompilerType 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 | ||||
1756 | std::shared_ptr<ClangModulesDeclVendor> | |||
1757 | ClangASTSource::GetClangModulesDeclVendor() { | |||
1758 | auto persistent_vars = llvm::cast<ClangPersistentVariables>( | |||
1759 | m_target->GetPersistentExpressionStateForLanguage(lldb::eLanguageTypeC)); | |||
1760 | return persistent_vars->GetClangModulesDeclVendor(); | |||
1761 | } |