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 {
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));
47 const clang::ObjCInterfaceDecl *interface_decl =
48 llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl_ctx);
53 clang::ObjCInterfaceDecl *non_const_interface_decl =
54 const_cast<clang::ObjCInterfaceDecl *
>(interface_decl);
59 clang::DeclContext::lookup_result result =
60 non_const_interface_decl->lookup(name);
62 return (!result.empty());
65 SetNoExternalVisibleDeclsForName(decl_ctx, name);
75 "AppleObjCExternalASTSource::CompleteType on "
76 "(ASTContext*)%p Completing (TagDecl*)%p named %s",
77 static_cast<void *
>(&tag_decl->getASTContext()),
78 static_cast<void *
>(tag_decl), tag_decl->getName().str().c_str());
85 void CompleteType(clang::ObjCInterfaceDecl *interface_decl)
override {
91 "AppleObjCExternalASTSource::CompleteType on "
92 "(ASTContext*)%p Completing (ObjCInterfaceDecl*)%p named %s",
93 static_cast<void *
>(&interface_decl->getASTContext()),
94 static_cast<void *
>(interface_decl),
95 interface_decl->getName().str().c_str());
107 const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
108 llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
109 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
111 llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
112 &VirtualBaseOffsets)
override {
117 clang::TranslationUnitDecl *translation_unit_decl =
118 m_decl_vendor.m_ast_ctx->getASTContext().getTranslationUnitDecl();
119 translation_unit_decl->setHasExternalVisibleStorage();
120 translation_unit_decl->setHasExternalLexicalStorage();
130 m_ast_ctx = std::make_shared<TypeSystemClang>(
131 "AppleObjCDeclVendor AST",
133 auto external_source_owning_ptr =
134 llvm::makeIntrusiveRefCnt<AppleObjCExternalASTSource>(*
this);
136 m_ast_ctx->getASTContext().setExternalSource(external_source_owning_ptr);
139clang::ObjCInterfaceDecl *
146 clang::ASTContext &ast_ctx =
m_ast_ctx->getASTContext();
149 m_runtime.GetClassDescriptorFromISA(isa);
156 clang::IdentifierInfo &identifier_info =
159 clang::ObjCInterfaceDecl *new_iface_decl = clang::ObjCInterfaceDecl::Create(
160 ast_ctx, ast_ctx.getTranslationUnitDecl(), clang::SourceLocation(),
161 &identifier_info,
nullptr,
nullptr);
165 m_ast_ctx->SetMetadata(new_iface_decl, meta_data);
167 new_iface_decl->setHasExternalVisibleStorage();
168 new_iface_decl->setHasExternalLexicalStorage();
170 ast_ctx.getTranslationUnitDecl()->addDecl(new_iface_decl);
174 return new_iface_decl;
180 const char *cursor = types;
181 enum ParserState { Start = 0, InType, InPos } state = Start;
182 const char *type =
nullptr;
185 uint32_t stepsLeft = 256;
188 if (--stepsLeft == 0) {
293 clang::ObjCMethodDecl *
295 clang::ObjCInterfaceDecl *interface_decl,
const char *name,
301 clang::ASTContext &ast_ctx(interface_decl->getASTContext());
303 const bool isInstance = instance;
304 const bool isVariadic =
false;
305 const bool isPropertyAccessor =
false;
306 const bool isSynthesizedAccessorStub =
false;
307 const bool isImplicitlyDeclared =
true;
308 const bool isDefined =
false;
309 const clang::ObjCImplementationControl impControl =
310 clang::ObjCImplementationControl::None;
311 const bool HasRelatedResultType =
false;
312 const bool for_expression =
true;
314 std::vector<const clang::IdentifierInfo *> selector_components;
316 const char *name_cursor = name;
317 bool is_zero_argument =
true;
319 while (*name_cursor !=
'\0') {
320 const char *colon_loc = strchr(name_cursor,
':');
322 selector_components.push_back(
323 &ast_ctx.Idents.get(llvm::StringRef(name_cursor)));
326 is_zero_argument =
false;
327 selector_components.push_back(&ast_ctx.Idents.get(
328 llvm::StringRef(name_cursor, colon_loc - name_cursor)));
329 name_cursor = colon_loc + 1;
333 const clang::IdentifierInfo **identifier_infos = selector_components.data();
334 if (!identifier_infos) {
338 clang::Selector sel = ast_ctx.Selectors.getSelector(
339 is_zero_argument ? 0 : selector_components.size(),
342 clang::QualType ret_type =
346 if (ret_type.isNull())
349 clang::ObjCMethodDecl *ret = clang::ObjCMethodDecl::Create(
350 ast_ctx, clang::SourceLocation(), clang::SourceLocation(), sel,
351 ret_type,
nullptr, interface_decl, isInstance, isVariadic,
352 isPropertyAccessor, isSynthesizedAccessorStub, isImplicitlyDeclared,
353 isDefined, impControl, HasRelatedResultType);
355 std::vector<clang::ParmVarDecl *> parm_vars;
357 for (
size_t ai = 3, ae =
m_type_vector.size(); ai != ae; ++ai) {
358 const bool for_expression =
true;
359 clang::QualType arg_type =
363 if (arg_type.isNull())
367 parm_vars.push_back(clang::ParmVarDecl::Create(
368 ast_ctx, ret, clang::SourceLocation(), clang::SourceLocation(),
369 nullptr, arg_type,
nullptr, clang::SC_None,
nullptr));
372 ret->setMethodParams(ast_ctx,
373 llvm::ArrayRef<clang::ParmVarDecl *>(parm_vars),
374 llvm::ArrayRef<clang::SourceLocation>());
397 if (std::optional<ClangASTMetadata> metadata =
399 objc_isa = metadata->GetISAPtr();
404 if (!interface_decl->hasExternalVisibleStorage())
407 interface_decl->startDefinition();
409 interface_decl->setHasExternalVisibleStorage(
false);
410 interface_decl->setHasExternalLexicalStorage(
false);
413 m_runtime.GetClassDescriptorFromISA(objc_isa);
418 auto superclass_func = [interface_decl,
420 clang::ObjCInterfaceDecl *superclass_decl =
GetDeclForISA(isa);
422 if (!superclass_decl)
426 clang::ASTContext &context =
m_ast_ctx->getASTContext();
427 interface_decl->setSuperClass(context.getTrivialTypeSourceInfo(
428 context.getObjCInterfaceType(superclass_decl)));
431 auto instance_method_func =
432 [log, interface_decl,
this](
const char *name,
const char *types) ->
bool {
438 clang::ObjCMethodDecl *method_decl = method_type.
BuildMethod(
441 LLDB_LOGF(log,
"[ AOTV::FD] Instance method [%s] [%s]", name, types);
444 interface_decl->addDecl(method_decl);
449 auto class_method_func = [log, interface_decl,
450 this](
const char *name,
const char *types) ->
bool {
456 clang::ObjCMethodDecl *method_decl = method_type.
BuildMethod(
459 LLDB_LOGF(log,
"[ AOTV::FD] Class method [%s] [%s]", name, types);
462 interface_decl->addDecl(method_decl);
467 auto ivar_func = [log, interface_decl,
468 this](
const char *name,
const char *type,
473 const bool for_expression =
false;
476 "[ AOTV::FD] Instance variable [%s] [%s], offset at %" PRIx64,
477 name, type, offset_ptr);
483 clang::TypeSourceInfo *
const type_source_info =
nullptr;
484 const bool is_synthesized =
false;
485 clang::ObjCIvarDecl *ivar_decl = clang::ObjCIvarDecl::Create(
486 m_ast_ctx->getASTContext(), interface_decl, clang::SourceLocation(),
487 clang::SourceLocation(), &
m_ast_ctx->getASTContext().Idents.get(name),
490 clang::ObjCIvarDecl::Public,
nullptr, is_synthesized);
493 interface_decl->addDecl(ivar_decl);
501 "[AppleObjCDeclVendor::FinishDecl] Finishing Objective-C "
503 descriptor->GetClassName().AsCString());
505 if (!descriptor->Describe(superclass_func, instance_method_func,
506 class_method_func, ivar_func))
510 "[AppleObjCDeclVendor::FinishDecl] Finished Objective-C interface");
518 uint32_t max_matches,
519 std::vector<CompilerDecl> &decls) {
524 LLDB_LOGF(log,
"AppleObjCDeclVendor::FindDecls ('%s', %s, %u, )",
525 (
const char *)name.
AsCString(), append ?
"true" :
"false",
533 clang::ASTContext &ast_ctx =
m_ast_ctx->getASTContext();
535 clang::IdentifierInfo &identifier_info =
537 clang::DeclarationName decl_name =
538 ast_ctx.DeclarationNames.getIdentifier(&identifier_info);
540 clang::DeclContext::lookup_result lookup_result =
541 ast_ctx.getTranslationUnitDecl()->lookup(decl_name);
543 if (!lookup_result.empty()) {
544 if (clang::ObjCInterfaceDecl *result_iface_decl =
545 llvm::dyn_cast<clang::ObjCInterfaceDecl>(*lookup_result.begin())) {
547 clang::QualType result_iface_type =
548 ast_ctx.getObjCInterfaceType(result_iface_decl);
551 if (std::optional<ClangASTMetadata> metadata =
552 m_ast_ctx->GetMetadata(result_iface_decl))
553 isa_value = metadata->GetISAPtr();
556 "AOCTV::FT Found %s (isa 0x%" PRIx64
") in the ASTContext",
557 result_iface_type.getAsString().data(), isa_value);
560 decls.push_back(
m_ast_ctx->GetCompilerDecl(result_iface_decl));
564 LLDB_LOGF(log,
"AOCTV::FT There's something in the ASTContext, but "
565 "it's not something we know about");
569 LLDB_LOGF(log,
"AOCTV::FT Couldn't find %s in the ASTContext",
577 LLDB_LOGF(log,
"AOCTV::FT Couldn't find the isa");
586 "AOCTV::FT Couldn't get the Objective-C interface for "
594 clang::QualType new_iface_type = ast_ctx.getObjCInterfaceType(iface_decl);
596 LLDB_LOG(log,
"AOCTV::FT Created {0} (isa 0x{1:x})",
597 new_iface_type.getAsString(), (uint64_t)isa);
600 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
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.
DeclVendor(DeclVendorKind kind)
std::shared_ptr< ClassDescriptor > ClassDescriptorSP
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.