20#include "clang/AST/ASTContext.h"
21#include "clang/AST/DeclObjC.h"
22#include "clang/AST/ExternalASTSource.h"
27 :
public clang::ExternalASTSource {
33 const clang::DeclContext *decl_ctx, clang::DeclarationName name,
34 const clang::DeclContext *original_dc)
override {
41 "AppleObjCExternalASTSource::FindExternalVisibleDeclsByName"
42 " on (ASTContext*)%p Looking for %s in (%sDecl*)%p",
43 static_cast<void *
>(&decl_ctx->getParentASTContext()),
44 name.getAsString().c_str(), decl_ctx->getDeclKindName(),
45 static_cast<const void *
>(decl_ctx));
49 const clang::ObjCInterfaceDecl *interface_decl =
50 llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl_ctx);
55 clang::ObjCInterfaceDecl *non_const_interface_decl =
56 const_cast<clang::ObjCInterfaceDecl *
>(interface_decl);
61 clang::DeclContext::lookup_result result =
62 non_const_interface_decl->lookup(name);
64 return (!result.empty());
67 SetNoExternalVisibleDeclsForName(decl_ctx, name);
77 "AppleObjCExternalASTSource::CompleteType on "
78 "(ASTContext*)%p Completing (TagDecl*)%p named %s",
79 static_cast<void *
>(&tag_decl->getASTContext()),
80 static_cast<void *
>(tag_decl), tag_decl->getName().str().c_str());
87 void CompleteType(clang::ObjCInterfaceDecl *interface_decl)
override {
94 "AppleObjCExternalASTSource::CompleteType on "
95 "(ASTContext*)%p Completing (ObjCInterfaceDecl*)%p named %s",
96 static_cast<void *
>(&interface_decl->getASTContext()),
97 static_cast<void *
>(interface_decl),
98 interface_decl->getName().str().c_str());
113 const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
114 llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
115 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
117 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
118 &VirtualBaseOffsets)
override {
123 clang::TranslationUnitDecl *translation_unit_decl =
125 translation_unit_decl->setHasExternalVisibleStorage();
126 translation_unit_decl->setHasExternalLexicalStorage();
135 m_type_realizer_sp(m_runtime.GetEncodingToType()) {
136 m_ast_ctx = std::make_shared<TypeSystemClang>(
137 "AppleObjCDeclVendor AST",
140 llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> external_source_owning_ptr(
142 m_ast_ctx->getASTContext().setExternalSource(external_source_owning_ptr);
145clang::ObjCInterfaceDecl *
152 clang::ASTContext &ast_ctx =
m_ast_ctx->getASTContext();
162 clang::IdentifierInfo &identifier_info =
165 clang::ObjCInterfaceDecl *new_iface_decl = clang::ObjCInterfaceDecl::Create(
166 ast_ctx, ast_ctx.getTranslationUnitDecl(), clang::SourceLocation(),
167 &identifier_info,
nullptr,
nullptr);
171 m_ast_ctx->SetMetadata(new_iface_decl, meta_data);
173 new_iface_decl->setHasExternalVisibleStorage();
174 new_iface_decl->setHasExternalLexicalStorage();
176 ast_ctx.getTranslationUnitDecl()->addDecl(new_iface_decl);
180 return new_iface_decl;
186 const char *cursor = types;
187 enum ParserState { Start = 0, InType, InPos } state = Start;
188 const char *type =
nullptr;
191 uint32_t stepsLeft = 256;
194 if (--stepsLeft == 0) {
241 m_type_vector.push_back(std::string(type, (cursor - type)));
299 clang::ObjCMethodDecl *
301 clang::ObjCInterfaceDecl *interface_decl,
const char *name,
304 if (!m_is_valid || m_type_vector.size() < 3)
307 clang::ASTContext &ast_ctx(interface_decl->getASTContext());
309 const bool isInstance = instance;
310 const bool isVariadic =
false;
311 const bool isPropertyAccessor =
false;
312 const bool isSynthesizedAccessorStub =
false;
313 const bool isImplicitlyDeclared =
true;
314 const bool isDefined =
false;
315 const clang::ObjCImplementationControl impControl =
316 clang::ObjCImplementationControl::None;
317 const bool HasRelatedResultType =
false;
318 const bool for_expression =
true;
320 std::vector<const clang::IdentifierInfo *> selector_components;
322 const char *name_cursor = name;
323 bool is_zero_argument =
true;
325 while (*name_cursor !=
'\0') {
326 const char *colon_loc = strchr(name_cursor,
':');
328 selector_components.push_back(
329 &ast_ctx.Idents.get(llvm::StringRef(name_cursor)));
332 is_zero_argument =
false;
333 selector_components.push_back(&ast_ctx.Idents.get(
334 llvm::StringRef(name_cursor, colon_loc - name_cursor)));
335 name_cursor = colon_loc + 1;
339 const clang::IdentifierInfo **identifier_infos = selector_components.data();
340 if (!identifier_infos) {
344 clang::Selector sel = ast_ctx.Selectors.getSelector(
345 is_zero_argument ? 0 : selector_components.size(),
348 clang::QualType ret_type =
350 clang_ast_ctxt, m_type_vector[0].c_str(), for_expression));
352 if (ret_type.isNull())
355 clang::ObjCMethodDecl *ret = clang::ObjCMethodDecl::Create(
356 ast_ctx, clang::SourceLocation(), clang::SourceLocation(), sel,
357 ret_type,
nullptr, interface_decl, isInstance, isVariadic,
358 isPropertyAccessor, isSynthesizedAccessorStub, isImplicitlyDeclared,
359 isDefined, impControl, HasRelatedResultType);
361 std::vector<clang::ParmVarDecl *> parm_vars;
363 for (
size_t ai = 3, ae = m_type_vector.size(); ai != ae; ++ai) {
364 const bool for_expression =
true;
365 clang::QualType arg_type =
367 clang_ast_ctxt, m_type_vector[ai].c_str(), for_expression));
369 if (arg_type.isNull())
373 parm_vars.push_back(clang::ParmVarDecl::Create(
374 ast_ctx, ret, clang::SourceLocation(), clang::SourceLocation(),
375 nullptr, arg_type,
nullptr, clang::SC_None,
nullptr));
378 ret->setMethodParams(ast_ctx,
379 llvm::ArrayRef<clang::ParmVarDecl *>(parm_vars),
380 llvm::ArrayRef<clang::SourceLocation>());
385 explicit operator bool() {
return m_is_valid; }
395 bool m_is_valid =
false;
403 if (std::optional<ClangASTMetadata> metadata =
405 objc_isa = metadata->GetISAPtr();
410 if (!interface_decl->hasExternalVisibleStorage())
413 interface_decl->startDefinition();
415 interface_decl->setHasExternalVisibleStorage(
false);
416 interface_decl->setHasExternalLexicalStorage(
false);
424 auto superclass_func = [interface_decl,
426 clang::ObjCInterfaceDecl *superclass_decl =
GetDeclForISA(isa);
428 if (!superclass_decl)
432 clang::ASTContext &context =
m_ast_ctx->getASTContext();
433 interface_decl->setSuperClass(context.getTrivialTypeSourceInfo(
434 context.getObjCInterfaceType(superclass_decl)));
437 auto instance_method_func =
438 [log, interface_decl,
this](
const char *name,
const char *types) ->
bool {
444 clang::ObjCMethodDecl *method_decl = method_type.
BuildMethod(
447 LLDB_LOGF(log,
"[ AOTV::FD] Instance method [%s] [%s]", name, types);
450 interface_decl->addDecl(method_decl);
455 auto class_method_func = [log, interface_decl,
456 this](
const char *name,
const char *types) ->
bool {
462 clang::ObjCMethodDecl *method_decl = method_type.
BuildMethod(
465 LLDB_LOGF(log,
"[ AOTV::FD] Class method [%s] [%s]", name, types);
468 interface_decl->addDecl(method_decl);
473 auto ivar_func = [log, interface_decl,
474 this](
const char *name,
const char *type,
479 const bool for_expression =
false;
482 "[ AOTV::FD] Instance variable [%s] [%s], offset at %" PRIx64,
483 name, type, offset_ptr);
489 clang::TypeSourceInfo *
const type_source_info =
nullptr;
490 const bool is_synthesized =
false;
491 clang::ObjCIvarDecl *ivar_decl = clang::ObjCIvarDecl::Create(
492 m_ast_ctx->getASTContext(), interface_decl, clang::SourceLocation(),
493 clang::SourceLocation(), &
m_ast_ctx->getASTContext().Idents.get(name),
496 clang::ObjCIvarDecl::Public,
nullptr, is_synthesized);
499 interface_decl->addDecl(ivar_decl);
507 "[AppleObjCDeclVendor::FinishDecl] Finishing Objective-C "
509 descriptor->GetClassName().AsCString());
511 if (!descriptor->Describe(superclass_func, instance_method_func,
512 class_method_func, ivar_func))
518 "[AppleObjCDeclVendor::FinishDecl] Finished Objective-C interface");
527 uint32_t max_matches,
528 std::vector<CompilerDecl> &decls) {
533 LLDB_LOGF(log,
"AppleObjCDeclVendor::FindDecls ('%s', %s, %u, )",
534 (
const char *)name.
AsCString(), append ?
"true" :
"false",
545 clang::ASTContext &ast_ctx =
m_ast_ctx->getASTContext();
547 clang::IdentifierInfo &identifier_info =
549 clang::DeclarationName decl_name =
550 ast_ctx.DeclarationNames.getIdentifier(&identifier_info);
552 clang::DeclContext::lookup_result lookup_result =
553 ast_ctx.getTranslationUnitDecl()->lookup(decl_name);
555 if (!lookup_result.empty()) {
556 if (clang::ObjCInterfaceDecl *result_iface_decl =
557 llvm::dyn_cast<clang::ObjCInterfaceDecl>(*lookup_result.begin())) {
559 clang::QualType result_iface_type =
560 ast_ctx.getObjCInterfaceType(result_iface_decl);
563 if (std::optional<ClangASTMetadata> metadata =
564 m_ast_ctx->GetMetadata(result_iface_decl))
565 isa_value = metadata->GetISAPtr();
568 "AOCTV::FT Found %s (isa 0x%" PRIx64
") in the ASTContext",
569 result_iface_type.getAsString().data(), isa_value);
572 decls.push_back(
m_ast_ctx->GetCompilerDecl(result_iface_decl));
576 LLDB_LOGF(log,
"AOCTV::FT There's something in the ASTContext, but "
577 "it's not something we know about");
581 LLDB_LOGF(log,
"AOCTV::FT Couldn't find %s in the ASTContext",
590 LLDB_LOGF(log,
"AOCTV::FT Couldn't find the isa");
599 "AOCTV::FT Couldn't get the Objective-C interface for "
607 clang::QualType new_iface_type = ast_ctx.getObjCInterfaceType(iface_decl);
609 LLDB_LOG(log,
"AOCTV::FT Created {0} (isa 0x{1:x})",
610 new_iface_type.getAsString(), (uint64_t)isa);
613 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
AppleObjCExternalASTSource(AppleObjCDeclVendor &decl_vendor)
AppleObjCDeclVendor & m_decl_vendor
bool FindExternalVisibleDeclsByName(const clang::DeclContext *decl_ctx, clang::DeclarationName name, const clang::DeclContext *original_dc) override
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.