20#include "clang/AST/ASTContext.h"
21#include "clang/AST/DeclObjC.h"
22#include "clang/AST/ExternalASTSource.h"
27 :
public clang::ExternalASTSource {
33 clang::DeclarationName name)
override {
40 "AppleObjCExternalASTSource::FindExternalVisibleDeclsByName"
41 " on (ASTContext*)%p Looking for %s in (%sDecl*)%p",
42 static_cast<void *
>(&decl_ctx->getParentASTContext()),
43 name.getAsString().c_str(), decl_ctx->getDeclKindName(),
44 static_cast<const void *
>(decl_ctx));
48 const clang::ObjCInterfaceDecl *interface_decl =
49 llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl_ctx);
54 clang::ObjCInterfaceDecl *non_const_interface_decl =
55 const_cast<clang::ObjCInterfaceDecl *
>(interface_decl);
60 clang::DeclContext::lookup_result result =
61 non_const_interface_decl->lookup(name);
63 return (!result.empty());
66 SetNoExternalVisibleDeclsForName(decl_ctx, name);
76 "AppleObjCExternalASTSource::CompleteType on "
77 "(ASTContext*)%p Completing (TagDecl*)%p named %s",
78 static_cast<void *
>(&tag_decl->getASTContext()),
79 static_cast<void *
>(tag_decl), tag_decl->getName().str().c_str());
86 void CompleteType(clang::ObjCInterfaceDecl *interface_decl)
override {
93 "AppleObjCExternalASTSource::CompleteType on "
94 "(ASTContext*)%p Completing (ObjCInterfaceDecl*)%p named %s",
95 static_cast<void *
>(&interface_decl->getASTContext()),
96 static_cast<void *
>(interface_decl),
97 interface_decl->getName().str().c_str());
112 const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
113 llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
114 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
116 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
117 &VirtualBaseOffsets)
override {
122 clang::TranslationUnitDecl *translation_unit_decl =
124 translation_unit_decl->setHasExternalVisibleStorage();
125 translation_unit_decl->setHasExternalLexicalStorage();
134 m_type_realizer_sp(m_runtime.GetEncodingToType()) {
135 m_ast_ctx = std::make_shared<TypeSystemClang>(
136 "AppleObjCDeclVendor AST",
139 llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> external_source_owning_ptr(
141 m_ast_ctx->getASTContext().setExternalSource(external_source_owning_ptr);
144clang::ObjCInterfaceDecl *
151 clang::ASTContext &ast_ctx =
m_ast_ctx->getASTContext();
161 clang::IdentifierInfo &identifier_info =
164 clang::ObjCInterfaceDecl *new_iface_decl = clang::ObjCInterfaceDecl::Create(
165 ast_ctx, ast_ctx.getTranslationUnitDecl(), clang::SourceLocation(),
166 &identifier_info,
nullptr,
nullptr);
170 m_ast_ctx->SetMetadata(new_iface_decl, meta_data);
172 new_iface_decl->setHasExternalVisibleStorage();
173 new_iface_decl->setHasExternalLexicalStorage();
175 ast_ctx.getTranslationUnitDecl()->addDecl(new_iface_decl);
179 return new_iface_decl;
185 const char *cursor = types;
186 enum ParserState { Start = 0, InType, InPos } state = Start;
187 const char *type =
nullptr;
190 uint32_t stepsLeft = 256;
193 if (--stepsLeft == 0) {
240 m_type_vector.push_back(std::string(type, (cursor - type)));
298 clang::ObjCMethodDecl *
300 clang::ObjCInterfaceDecl *interface_decl,
const char *name,
303 if (!m_is_valid || m_type_vector.size() < 3)
306 clang::ASTContext &ast_ctx(interface_decl->getASTContext());
308 const bool isInstance = instance;
309 const bool isVariadic =
false;
310 const bool isPropertyAccessor =
false;
311 const bool isSynthesizedAccessorStub =
false;
312 const bool isImplicitlyDeclared =
true;
313 const bool isDefined =
false;
314 const clang::ObjCImplementationControl impControl =
315 clang::ObjCImplementationControl::None;
316 const bool HasRelatedResultType =
false;
317 const bool for_expression =
true;
319 std::vector<const clang::IdentifierInfo *> selector_components;
321 const char *name_cursor = name;
322 bool is_zero_argument =
true;
324 while (*name_cursor !=
'\0') {
325 const char *colon_loc = strchr(name_cursor,
':');
327 selector_components.push_back(
328 &ast_ctx.Idents.get(llvm::StringRef(name_cursor)));
331 is_zero_argument =
false;
332 selector_components.push_back(&ast_ctx.Idents.get(
333 llvm::StringRef(name_cursor, colon_loc - name_cursor)));
334 name_cursor = colon_loc + 1;
338 const clang::IdentifierInfo **identifier_infos = selector_components.data();
339 if (!identifier_infos) {
343 clang::Selector sel = ast_ctx.Selectors.getSelector(
344 is_zero_argument ? 0 : selector_components.size(),
347 clang::QualType ret_type =
349 clang_ast_ctxt, m_type_vector[0].c_str(), for_expression));
351 if (ret_type.isNull())
354 clang::ObjCMethodDecl *ret = clang::ObjCMethodDecl::Create(
355 ast_ctx, clang::SourceLocation(), clang::SourceLocation(), sel,
356 ret_type,
nullptr, interface_decl, isInstance, isVariadic,
357 isPropertyAccessor, isSynthesizedAccessorStub, isImplicitlyDeclared,
358 isDefined, impControl, HasRelatedResultType);
360 std::vector<clang::ParmVarDecl *> parm_vars;
362 for (
size_t ai = 3, ae = m_type_vector.size(); ai != ae; ++ai) {
363 const bool for_expression =
true;
364 clang::QualType arg_type =
366 clang_ast_ctxt, m_type_vector[ai].c_str(), for_expression));
368 if (arg_type.isNull())
372 parm_vars.push_back(clang::ParmVarDecl::Create(
373 ast_ctx, ret, clang::SourceLocation(), clang::SourceLocation(),
374 nullptr, arg_type,
nullptr, clang::SC_None,
nullptr));
377 ret->setMethodParams(ast_ctx,
378 llvm::ArrayRef<clang::ParmVarDecl *>(parm_vars),
379 llvm::ArrayRef<clang::SourceLocation>());
384 explicit operator bool() {
return m_is_valid; }
394 bool m_is_valid =
false;
402 if (std::optional<ClangASTMetadata> metadata =
404 objc_isa = metadata->GetISAPtr();
409 if (!interface_decl->hasExternalVisibleStorage())
412 interface_decl->startDefinition();
414 interface_decl->setHasExternalVisibleStorage(
false);
415 interface_decl->setHasExternalLexicalStorage(
false);
423 auto superclass_func = [interface_decl,
425 clang::ObjCInterfaceDecl *superclass_decl =
GetDeclForISA(isa);
427 if (!superclass_decl)
431 clang::ASTContext &context =
m_ast_ctx->getASTContext();
432 interface_decl->setSuperClass(context.getTrivialTypeSourceInfo(
433 context.getObjCInterfaceType(superclass_decl)));
436 auto instance_method_func =
437 [log, interface_decl,
this](
const char *name,
const char *types) ->
bool {
443 clang::ObjCMethodDecl *method_decl = method_type.
BuildMethod(
446 LLDB_LOGF(log,
"[ AOTV::FD] Instance method [%s] [%s]", name, types);
449 interface_decl->addDecl(method_decl);
454 auto class_method_func = [log, interface_decl,
455 this](
const char *name,
const char *types) ->
bool {
461 clang::ObjCMethodDecl *method_decl = method_type.
BuildMethod(
464 LLDB_LOGF(log,
"[ AOTV::FD] Class method [%s] [%s]", name, types);
467 interface_decl->addDecl(method_decl);
472 auto ivar_func = [log, interface_decl,
473 this](
const char *name,
const char *type,
478 const bool for_expression =
false;
481 "[ AOTV::FD] Instance variable [%s] [%s], offset at %" PRIx64,
482 name, type, offset_ptr);
488 clang::TypeSourceInfo *
const type_source_info =
nullptr;
489 const bool is_synthesized =
false;
490 clang::ObjCIvarDecl *ivar_decl = clang::ObjCIvarDecl::Create(
491 m_ast_ctx->getASTContext(), interface_decl, clang::SourceLocation(),
492 clang::SourceLocation(), &
m_ast_ctx->getASTContext().Idents.get(name),
495 clang::ObjCIvarDecl::Public,
nullptr, is_synthesized);
498 interface_decl->addDecl(ivar_decl);
506 "[AppleObjCDeclVendor::FinishDecl] Finishing Objective-C "
508 descriptor->GetClassName().AsCString());
510 if (!descriptor->Describe(superclass_func, instance_method_func,
511 class_method_func, ivar_func))
517 "[AppleObjCDeclVendor::FinishDecl] Finished Objective-C interface");
526 uint32_t max_matches,
527 std::vector<CompilerDecl> &decls) {
532 LLDB_LOGF(log,
"AppleObjCDeclVendor::FindDecls ('%s', %s, %u, )",
533 (
const char *)name.
AsCString(), append ?
"true" :
"false",
544 clang::ASTContext &ast_ctx =
m_ast_ctx->getASTContext();
546 clang::IdentifierInfo &identifier_info =
548 clang::DeclarationName decl_name =
549 ast_ctx.DeclarationNames.getIdentifier(&identifier_info);
551 clang::DeclContext::lookup_result lookup_result =
552 ast_ctx.getTranslationUnitDecl()->lookup(decl_name);
554 if (!lookup_result.empty()) {
555 if (clang::ObjCInterfaceDecl *result_iface_decl =
556 llvm::dyn_cast<clang::ObjCInterfaceDecl>(*lookup_result.begin())) {
558 clang::QualType result_iface_type =
559 ast_ctx.getObjCInterfaceType(result_iface_decl);
562 if (std::optional<ClangASTMetadata> metadata =
563 m_ast_ctx->GetMetadata(result_iface_decl))
564 isa_value = metadata->GetISAPtr();
567 "AOCTV::FT Found %s (isa 0x%" PRIx64
") in the ASTContext",
568 result_iface_type.getAsString().data(), isa_value);
571 decls.push_back(
m_ast_ctx->GetCompilerDecl(result_iface_decl));
575 LLDB_LOGF(log,
"AOCTV::FT There's something in the ASTContext, but "
576 "it's not something we know about");
580 LLDB_LOGF(log,
"AOCTV::FT Couldn't find %s in the ASTContext",
589 LLDB_LOGF(log,
"AOCTV::FT Couldn't find the isa");
598 "AOCTV::FT Couldn't get the Objective-C interface for "
606 clang::QualType new_iface_type = ast_ctx.getObjCInterfaceType(iface_decl);
608 LLDB_LOG(log,
"AOCTV::FT Created {1} (isa 0x{2:x})",
609 new_iface_type.getAsString(), (uint64_t)isa);
612 decls.push_back(
m_ast_ctx->GetCompilerDecl(iface_decl));
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOGF(log,...)
ObjCRuntimeMethodType(const char *types)
const char * GetTypeAtIndex(size_t idx)
clang::ObjCMethodDecl * BuildMethod(TypeSystemClang &clang_ast_ctxt, clang::ObjCInterfaceDecl *interface_decl, const char *name, bool instance, ObjCLanguageRuntime::EncodingToTypeSP type_realizer_sp)
std::vector< std::string > TypeVector
ObjCLanguageRuntime::EncodingToTypeSP m_type_realizer_sp
uint32_t FindDecls(ConstString name, bool append, uint32_t max_matches, std::vector< CompilerDecl > &decls) override
Look up the set of Decls that the DeclVendor currently knows about matching a given name.
bool FinishDecl(clang::ObjCInterfaceDecl *decl)
AppleObjCExternalASTSource * m_external_source
std::shared_ptr< TypeSystemClang > m_ast_ctx
friend class AppleObjCExternalASTSource
AppleObjCDeclVendor(ObjCLanguageRuntime &runtime)
ObjCLanguageRuntime & m_runtime
ISAToInterfaceMap m_isa_to_interface
clang::ObjCInterfaceDecl * GetDeclForISA(ObjCLanguageRuntime::ObjCISA isa)
void CompleteType(clang::TagDecl *tag_decl) override
void StartTranslationUnit(clang::ASTConsumer *Consumer) override
bool FindExternalVisibleDeclsByName(const clang::DeclContext *decl_ctx, clang::DeclarationName name) override
AppleObjCExternalASTSource(AppleObjCDeclVendor &decl_vendor)
AppleObjCDeclVendor & m_decl_vendor
bool layoutRecordType(const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment, llvm::DenseMap< const clang::FieldDecl *, uint64_t > &FieldOffsets, llvm::DenseMap< const clang::CXXRecordDecl *, clang::CharUnits > &BaseOffsets, llvm::DenseMap< const clang::CXXRecordDecl *, clang::CharUnits > &VirtualBaseOffsets) override
void CompleteType(clang::ObjCInterfaceDecl *interface_decl) override
llvm::Triple & GetTriple()
Architecture triple accessor.
Generic representation of a type in a programming language.
A uniqued constant string class.
const char * AsCString(const char *value_if_empty=nullptr) const
Get the string value as a C string.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
virtual ObjCISA GetISA(ConstString name)
virtual EncodingToTypeSP GetEncodingToType()
std::shared_ptr< ClassDescriptor > ClassDescriptorSP
virtual ClassDescriptorSP GetClassDescriptorFromISA(ObjCISA isa)
std::shared_ptr< EncodingToType > EncodingToTypeSP
Target & GetTarget()
Get the target object pointer for this module.
const ArchSpec & GetArchitecture() const
A TypeSystem implementation based on Clang.
#define LLDB_INVALID_ADDRESS
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
static clang::QualType GetQualType(const CompilerType &ct)
static std::string DumpDecl(const clang::Decl *d)
Returns a textual representation of the given Decl's AST.