1 | //===-- ClangExternalASTSourceCallbacks.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 "Plugins/ExpressionParser/Clang/ClangExternalASTSourceCallbacks.h" |
10 | #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" |
11 | |
12 | #include "clang/AST/Decl.h" |
13 | #include "clang/AST/DeclObjC.h" |
14 | #include "clang/Basic/Module.h" |
15 | #include <optional> |
16 | |
17 | using namespace lldb_private; |
18 | |
19 | char ClangExternalASTSourceCallbacks::ID; |
20 | |
21 | void ClangExternalASTSourceCallbacks::CompleteType(clang::TagDecl *tag_decl) { |
22 | m_ast.CompleteTagDecl(tag_decl); |
23 | } |
24 | |
25 | void ClangExternalASTSourceCallbacks::CompleteType( |
26 | clang::ObjCInterfaceDecl *objc_decl) { |
27 | m_ast.CompleteObjCInterfaceDecl(objc_decl); |
28 | } |
29 | |
30 | bool ClangExternalASTSourceCallbacks::layoutRecordType( |
31 | const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment, |
32 | llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets, |
33 | llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &BaseOffsets, |
34 | llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> |
35 | &VirtualBaseOffsets) { |
36 | return m_ast.LayoutRecordType(record_decl: Record, size&: Size, alignment&: Alignment, field_offsets&: FieldOffsets, |
37 | base_offsets&: BaseOffsets, vbase_offsets&: VirtualBaseOffsets); |
38 | } |
39 | |
40 | void ClangExternalASTSourceCallbacks::FindExternalLexicalDecls( |
41 | const clang::DeclContext *decl_ctx, |
42 | llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant, |
43 | llvm::SmallVectorImpl<clang::Decl *> &decls) { |
44 | if (decl_ctx) { |
45 | clang::TagDecl *tag_decl = llvm::dyn_cast<clang::TagDecl>( |
46 | Val: const_cast<clang::DeclContext *>(decl_ctx)); |
47 | if (tag_decl) |
48 | CompleteType(tag_decl); |
49 | } |
50 | } |
51 | |
52 | bool ClangExternalASTSourceCallbacks::FindExternalVisibleDeclsByName( |
53 | const clang::DeclContext *DC, clang::DeclarationName Name, |
54 | const clang::DeclContext *OriginalDC) { |
55 | llvm::SmallVector<clang::NamedDecl *, 4> decls; |
56 | // Objective-C methods are not added into the LookupPtr when they originate |
57 | // from an external source. SetExternalVisibleDeclsForName() adds them. |
58 | if (auto *oid = llvm::dyn_cast<clang::ObjCInterfaceDecl>(Val: DC)) { |
59 | clang::ObjCContainerDecl::method_range noload_methods(oid->noload_decls()); |
60 | for (auto *omd : noload_methods) |
61 | if (omd->getDeclName() == Name) |
62 | decls.push_back(omd); |
63 | } |
64 | return !SetExternalVisibleDeclsForName(DC, Name, Decls: decls).empty(); |
65 | } |
66 | |
67 | OptionalClangModuleID |
68 | ClangExternalASTSourceCallbacks::RegisterModule(clang::Module *module) { |
69 | m_modules.push_back(x: module); |
70 | unsigned id = m_modules.size(); |
71 | m_ids.insert(KV: {module, id}); |
72 | return OptionalClangModuleID(id); |
73 | } |
74 | |
75 | std::optional<clang::ASTSourceDescriptor> |
76 | ClangExternalASTSourceCallbacks::getSourceDescriptor(unsigned id) { |
77 | if (clang::Module *module = getModule(ID: id)) |
78 | return {*module}; |
79 | return {}; |
80 | } |
81 | |
82 | clang::Module *ClangExternalASTSourceCallbacks::getModule(unsigned id) { |
83 | if (id && id <= m_modules.size()) |
84 | return m_modules[id - 1]; |
85 | return nullptr; |
86 | } |
87 | |
88 | OptionalClangModuleID |
89 | ClangExternalASTSourceCallbacks::GetIDForModule(clang::Module *module) { |
90 | return OptionalClangModuleID(m_ids[module]); |
91 | } |
92 | |