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