Coverage Report

Created: 2022-01-15 10:30

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- AppleObjCDeclVendor.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 "AppleObjCDeclVendor.h"
10
11
#include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"
12
#include "Plugins/ExpressionParser/Clang/ClangUtil.h"
13
#include "Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h"
14
#include "lldb/Core/Module.h"
15
#include "lldb/Target/Process.h"
16
#include "lldb/Target/Target.h"
17
#include "lldb/Utility/Log.h"
18
19
#include "clang/AST/ASTContext.h"
20
#include "clang/AST/DeclObjC.h"
21
#include "clang/AST/ExternalASTSource.h"
22
23
using namespace lldb_private;
24
25
class lldb_private::AppleObjCExternalASTSource
26
    : public clang::ExternalASTSource {
27
public:
28
  AppleObjCExternalASTSource(AppleObjCDeclVendor &decl_vendor)
29
1.10k
      : m_decl_vendor(decl_vendor) {}
30
31
  bool FindExternalVisibleDeclsByName(const clang::DeclContext *decl_ctx,
32
49
                                      clang::DeclarationName name) override {
33
34
49
    Log *log(GetLogIfAllCategoriesSet(
35
49
        LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
36
37
49
    if (log) {
38
0
      LLDB_LOGF(log,
39
0
                "AppleObjCExternalASTSource::FindExternalVisibleDeclsByName"
40
0
                " on (ASTContext*)%p Looking for %s in (%sDecl*)%p",
41
0
                static_cast<void *>(&decl_ctx->getParentASTContext()),
42
0
                name.getAsString().c_str(), decl_ctx->getDeclKindName(),
43
0
                static_cast<const void *>(decl_ctx));
44
0
    }
45
46
49
    do {
47
49
      const clang::ObjCInterfaceDecl *interface_decl =
48
49
          llvm::dyn_cast<clang::ObjCInterfaceDecl>(decl_ctx);
49
50
49
      if (!interface_decl)
51
0
        break;
52
53
49
      clang::ObjCInterfaceDecl *non_const_interface_decl =
54
49
          const_cast<clang::ObjCInterfaceDecl *>(interface_decl);
55
56
49
      if (!m_decl_vendor.FinishDecl(non_const_interface_decl))
57
0
        break;
58
59
49
      clang::DeclContext::lookup_result result =
60
49
          non_const_interface_decl->lookup(name);
61
62
49
      return (!result.empty());
63
49
    } while (
false0
);
64
65
0
    SetNoExternalVisibleDeclsForName(decl_ctx, name);
66
0
    return false;
67
49
  }
68
69
0
  void CompleteType(clang::TagDecl *tag_decl) override {
70
71
0
    Log *log(GetLogIfAllCategoriesSet(
72
0
        LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
73
74
0
    LLDB_LOGF(log,
75
0
              "AppleObjCExternalASTSource::CompleteType on "
76
0
              "(ASTContext*)%p Completing (TagDecl*)%p named %s",
77
0
              static_cast<void *>(&tag_decl->getASTContext()),
78
0
              static_cast<void *>(tag_decl), tag_decl->getName().str().c_str());
79
80
0
    LLDB_LOG(log, "  AOEAS::CT Before:\n{1}", ClangUtil::DumpDecl(tag_decl));
81
82
0
    LLDB_LOG(log, "  AOEAS::CT After:{1}", ClangUtil::DumpDecl(tag_decl));
83
0
  }
84
85
125
  void CompleteType(clang::ObjCInterfaceDecl *interface_decl) override {
86
87
125
    Log *log(GetLogIfAllCategoriesSet(
88
125
        LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
89
90
125
    if (log) {
91
0
      LLDB_LOGF(log,
92
0
                "AppleObjCExternalASTSource::CompleteType on "
93
0
                "(ASTContext*)%p Completing (ObjCInterfaceDecl*)%p named %s",
94
0
                static_cast<void *>(&interface_decl->getASTContext()),
95
0
                static_cast<void *>(interface_decl),
96
0
                interface_decl->getName().str().c_str());
97
98
0
      LLDB_LOGF(log, "  AOEAS::CT Before:");
99
0
      LLDB_LOG(log, "    [CT] {0}", ClangUtil::DumpDecl(interface_decl));
100
0
    }
101
102
125
    m_decl_vendor.FinishDecl(interface_decl);
103
104
125
    if (log) {
105
0
      LLDB_LOGF(log, "  [CT] After:");
106
0
      LLDB_LOG(log, "    [CT] {0}", ClangUtil::DumpDecl(interface_decl));
107
0
    }
108
125
  }
109
110
  bool layoutRecordType(
111
      const clang::RecordDecl *Record, uint64_t &Size, uint64_t &Alignment,
112
      llvm::DenseMap<const clang::FieldDecl *, uint64_t> &FieldOffsets,
113
      llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
114
          &BaseOffsets,
115
      llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>
116
0
          &VirtualBaseOffsets) override {
117
0
    return false;
118
0
  }
119
120
0
  void StartTranslationUnit(clang::ASTConsumer *Consumer) override {
121
0
    clang::TranslationUnitDecl *translation_unit_decl =
122
0
        m_decl_vendor.m_ast_ctx.getASTContext().getTranslationUnitDecl();
123
0
    translation_unit_decl->setHasExternalVisibleStorage();
124
0
    translation_unit_decl->setHasExternalLexicalStorage();
125
0
  }
126
127
private:
128
  AppleObjCDeclVendor &m_decl_vendor;
129
};
130
131
AppleObjCDeclVendor::AppleObjCDeclVendor(ObjCLanguageRuntime &runtime)
132
    : ClangDeclVendor(eAppleObjCDeclVendor), m_runtime(runtime),
133
      m_ast_ctx(
134
          "AppleObjCDeclVendor AST",
135
          runtime.GetProcess()->GetTarget().GetArchitecture().GetTriple()),
136
1.10k
      m_type_realizer_sp(m_runtime.GetEncodingToType()) {
137
1.10k
  m_external_source = new AppleObjCExternalASTSource(*this);
138
1.10k
  llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> external_source_owning_ptr(
139
1.10k
      m_external_source);
140
1.10k
  m_ast_ctx.getASTContext().setExternalSource(external_source_owning_ptr);
141
1.10k
}
142
143
clang::ObjCInterfaceDecl *
144
662
AppleObjCDeclVendor::GetDeclForISA(ObjCLanguageRuntime::ObjCISA isa) {
145
662
  ISAToInterfaceMap::const_iterator iter = m_isa_to_interface.find(isa);
146
147
662
  if (iter != m_isa_to_interface.end())
148
43
    return iter->second;
149
150
619
  clang::ASTContext &ast_ctx = m_ast_ctx.getASTContext();
151
152
619
  ObjCLanguageRuntime::ClassDescriptorSP descriptor =
153
619
      m_runtime.GetClassDescriptorFromISA(isa);
154
155
619
  if (!descriptor)
156
0
    return nullptr;
157
158
619
  ConstString name(descriptor->GetClassName());
159
160
619
  clang::IdentifierInfo &identifier_info =
161
619
      ast_ctx.Idents.get(name.GetStringRef());
162
163
619
  clang::ObjCInterfaceDecl *new_iface_decl = clang::ObjCInterfaceDecl::Create(
164
619
      ast_ctx, ast_ctx.getTranslationUnitDecl(), clang::SourceLocation(),
165
619
      &identifier_info, nullptr, nullptr);
166
167
619
  ClangASTMetadata meta_data;
168
619
  meta_data.SetISAPtr(isa);
169
619
  m_ast_ctx.SetMetadata(new_iface_decl, meta_data);
170
171
619
  new_iface_decl->setHasExternalVisibleStorage();
172
619
  new_iface_decl->setHasExternalLexicalStorage();
173
174
619
  ast_ctx.getTranslationUnitDecl()->addDecl(new_iface_decl);
175
176
619
  m_isa_to_interface[isa] = new_iface_decl;
177
178
619
  return new_iface_decl;
179
619
}
180
181
class ObjCRuntimeMethodType {
182
public:
183
24.3k
  ObjCRuntimeMethodType(const char *types) : m_is_valid(false) {
184
24.3k
    const char *cursor = types;
185
24.3k
    enum ParserState { Start = 0, InType, InPos } state = Start;
186
24.3k
    const char *type = nullptr;
187
24.3k
    int brace_depth = 0;
188
189
24.3k
    uint32_t stepsLeft = 256;
190
191
483k
    while (true) {
192
483k
      if (--stepsLeft == 0) {
193
0
        m_is_valid = false;
194
0
        return;
195
0
      }
196
197
483k
      switch (state) {
198
24.3k
      case Start: {
199
24.3k
        switch (*cursor) {
200
24.3k
        default:
201
24.3k
          state = InType;
202
24.3k
          type = cursor;
203
24.3k
          break;
204
0
        case '\0':
205
0
          m_is_valid = true;
206
0
          return;
207
0
        case '0':
208
0
        case '1':
209
0
        case '2':
210
0
        case '3':
211
0
        case '4':
212
0
        case '5':
213
0
        case '6':
214
0
        case '7':
215
0
        case '8':
216
0
        case '9':
217
0
          m_is_valid = false;
218
0
          return;
219
24.3k
        }
220
24.3k
      } break;
221
227k
      case InType: {
222
227k
        switch (*cursor) {
223
126k
        default:
224
126k
          ++cursor;
225
126k
          break;
226
24.3k
        case '0':
227
48.8k
        case '1':
228
62.5k
        case '2':
229
66.2k
        case '3':
230
68.7k
        case '4':
231
69.2k
        case '5':
232
69.2k
        case '6':
233
69.3k
        case '7':
234
93.8k
        case '8':
235
93.8k
        case '9':
236
93.8k
          if (!brace_depth) {
237
93.4k
            state = InPos;
238
93.4k
            if (type) {
239
93.4k
              m_type_vector.push_back(std::string(type, (cursor - type)));
240
93.4k
            } else {
241
0
              m_is_valid = false;
242
0
              return;
243
0
            }
244
93.4k
            type = nullptr;
245
93.4k
          } else {
246
406
            ++cursor;
247
406
          }
248
93.8k
          break;
249
93.8k
        case '[':
250
3.24k
        case '{':
251
3.24k
        case '(':
252
3.24k
          ++brace_depth;
253
3.24k
          ++cursor;
254
3.24k
          break;
255
171
        case ']':
256
3.24k
        case '}':
257
3.24k
        case ')':
258
3.24k
          if (!brace_depth) {
259
0
            m_is_valid = false;
260
0
            return;
261
0
          }
262
3.24k
          --brace_depth;
263
3.24k
          ++cursor;
264
3.24k
          break;
265
0
        case '\0':
266
0
          m_is_valid = false;
267
0
          return;
268
227k
        }
269
227k
      } break;
270
231k
      case InPos: {
271
231k
        switch (*cursor) {
272
69.0k
        default:
273
69.0k
          state = InType;
274
69.0k
          type = cursor;
275
69.0k
          break;
276
26.7k
        case '0':
277
51.0k
        case '1':
278
68.3k
        case '2':
279
72.0k
        case '3':
280
87.6k
        case '4':
281
87.9k
        case '5':
282
112k
        case '6':
283
112k
        case '7':
284
138k
        case '8':
285
138k
        case '9':
286
138k
          ++cursor;
287
138k
          break;
288
24.3k
        case '\0':
289
24.3k
          m_is_valid = true;
290
24.3k
          return;
291
231k
        }
292
231k
      } 
break207k
;
293
483k
      }
294
483k
    }
295
24.3k
  }
296
297
  clang::ObjCMethodDecl *
298
  BuildMethod(TypeSystemClang &clang_ast_ctxt,
299
              clang::ObjCInterfaceDecl *interface_decl, const char *name,
300
              bool instance,
301
24.3k
              ObjCLanguageRuntime::EncodingToTypeSP type_realizer_sp) {
302
24.3k
    if (!m_is_valid || m_type_vector.size() < 3)
303
0
      return nullptr;
304
305
24.3k
    clang::ASTContext &ast_ctx(interface_decl->getASTContext());
306
307
24.3k
    const bool isInstance = instance;
308
24.3k
    const bool isVariadic = false;
309
24.3k
    const bool isPropertyAccessor = false;
310
24.3k
    const bool isSynthesizedAccessorStub = false;
311
24.3k
    const bool isImplicitlyDeclared = true;
312
24.3k
    const bool isDefined = false;
313
24.3k
    const clang::ObjCMethodDecl::ImplementationControl impControl =
314
24.3k
        clang::ObjCMethodDecl::None;
315
24.3k
    const bool HasRelatedResultType = false;
316
24.3k
    const bool for_expression = true;
317
318
24.3k
    std::vector<clang::IdentifierInfo *> selector_components;
319
320
24.3k
    const char *name_cursor = name;
321
24.3k
    bool is_zero_argument = true;
322
323
44.7k
    while (*name_cursor != '\0') {
324
30.9k
      const char *colon_loc = strchr(name_cursor, ':');
325
30.9k
      if (!colon_loc) {
326
10.5k
        selector_components.push_back(
327
10.5k
            &ast_ctx.Idents.get(llvm::StringRef(name_cursor)));
328
10.5k
        break;
329
20.4k
      } else {
330
20.4k
        is_zero_argument = false;
331
20.4k
        selector_components.push_back(&ast_ctx.Idents.get(
332
20.4k
            llvm::StringRef(name_cursor, colon_loc - name_cursor)));
333
20.4k
        name_cursor = colon_loc + 1;
334
20.4k
      }
335
30.9k
    }
336
337
24.3k
    clang::IdentifierInfo **identifier_infos = selector_components.data();
338
24.3k
    if (!identifier_infos) {
339
0
      return nullptr;
340
0
    }
341
342
24.3k
    clang::Selector sel = ast_ctx.Selectors.getSelector(
343
24.3k
        is_zero_argument ? 
010.5k
:
selector_components.size()13.7k
,
344
24.3k
        identifier_infos);
345
346
24.3k
    clang::QualType ret_type =
347
24.3k
        ClangUtil::GetQualType(type_realizer_sp->RealizeType(
348
24.3k
            clang_ast_ctxt, m_type_vector[0].c_str(), for_expression));
349
350
24.3k
    if (ret_type.isNull())
351
771
      return nullptr;
352
353
23.5k
    clang::ObjCMethodDecl *ret = clang::ObjCMethodDecl::Create(
354
23.5k
        ast_ctx, clang::SourceLocation(), clang::SourceLocation(), sel,
355
23.5k
        ret_type, nullptr, interface_decl, isInstance, isVariadic,
356
23.5k
        isPropertyAccessor, isSynthesizedAccessorStub, isImplicitlyDeclared,
357
23.5k
        isDefined, impControl, HasRelatedResultType);
358
359
23.5k
    std::vector<clang::ParmVarDecl *> parm_vars;
360
361
41.4k
    for (size_t ai = 3, ae = m_type_vector.size(); ai != ae; 
++ai17.8k
) {
362
19.1k
      const bool for_expression = true;
363
19.1k
      clang::QualType arg_type =
364
19.1k
          ClangUtil::GetQualType(type_realizer_sp->RealizeType(
365
19.1k
              clang_ast_ctxt, m_type_vector[ai].c_str(), for_expression));
366
367
19.1k
      if (arg_type.isNull())
368
1.24k
        return nullptr; // well, we just wasted a bunch of time.  Wish we could
369
                        // delete the stuff we'd just made!
370
371
17.8k
      parm_vars.push_back(clang::ParmVarDecl::Create(
372
17.8k
          ast_ctx, ret, clang::SourceLocation(), clang::SourceLocation(),
373
17.8k
          nullptr, arg_type, nullptr, clang::SC_None, nullptr));
374
17.8k
    }
375
376
22.3k
    ret->setMethodParams(ast_ctx,
377
22.3k
                         llvm::ArrayRef<clang::ParmVarDecl *>(parm_vars),
378
22.3k
                         llvm::ArrayRef<clang::SourceLocation>());
379
380
22.3k
    return ret;
381
23.5k
  }
382
383
0
  explicit operator bool() { return m_is_valid; }
384
385
0
  size_t GetNumTypes() { return m_type_vector.size(); }
386
387
0
  const char *GetTypeAtIndex(size_t idx) { return m_type_vector[idx].c_str(); }
388
389
private:
390
  typedef std::vector<std::string> TypeVector;
391
392
  TypeVector m_type_vector;
393
  bool m_is_valid;
394
};
395
396
440
bool AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl) {
397
440
  Log *log(GetLogIfAllCategoriesSet(
398
440
      LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
399
400
440
  ClangASTMetadata *metadata = m_ast_ctx.GetMetadata(interface_decl);
401
440
  ObjCLanguageRuntime::ObjCISA objc_isa = 0;
402
440
  if (metadata)
403
440
    objc_isa = metadata->GetISAPtr();
404
405
440
  if (!objc_isa)
406
0
    return false;
407
408
440
  if (!interface_decl->hasExternalVisibleStorage())
409
43
    return true;
410
411
397
  interface_decl->startDefinition();
412
413
397
  interface_decl->setHasExternalVisibleStorage(false);
414
397
  interface_decl->setHasExternalLexicalStorage(false);
415
416
397
  ObjCLanguageRuntime::ClassDescriptorSP descriptor =
417
397
      m_runtime.GetClassDescriptorFromISA(objc_isa);
418
419
397
  if (!descriptor)
420
0
    return false;
421
422
397
  auto superclass_func = [interface_decl,
423
397
                          this](ObjCLanguageRuntime::ObjCISA isa) {
424
266
    clang::ObjCInterfaceDecl *superclass_decl = GetDeclForISA(isa);
425
426
266
    if (!superclass_decl)
427
0
      return;
428
429
266
    FinishDecl(superclass_decl);
430
266
    clang::ASTContext &context = m_ast_ctx.getASTContext();
431
266
    interface_decl->setSuperClass(context.getTrivialTypeSourceInfo(
432
266
        context.getObjCInterfaceType(superclass_decl)));
433
266
  };
434
435
397
  auto instance_method_func =
436
15.9k
      [log, interface_decl, this](const char *name, const char *types) -> bool {
437
15.9k
    if (!name || !types)
438
0
      return false; // skip this one
439
440
15.9k
    ObjCRuntimeMethodType method_type(types);
441
442
15.9k
    clang::ObjCMethodDecl *method_decl = method_type.BuildMethod(
443
15.9k
        m_ast_ctx, interface_decl, name, true, m_type_realizer_sp);
444
445
15.9k
    LLDB_LOGF(log, "[  AOTV::FD] Instance method [%s] [%s]", name, types);
446
447
15.9k
    if (method_decl)
448
14.2k
      interface_decl->addDecl(method_decl);
449
450
15.9k
    return false;
451
15.9k
  };
452
453
397
  auto class_method_func = [log, interface_decl,
454
8.36k
                            this](const char *name, const char *types) -> bool {
455
8.36k
    if (!name || !types)
456
0
      return false; // skip this one
457
458
8.36k
    ObjCRuntimeMethodType method_type(types);
459
460
8.36k
    clang::ObjCMethodDecl *method_decl = method_type.BuildMethod(
461
8.36k
        m_ast_ctx, interface_decl, name, false, m_type_realizer_sp);
462
463
8.36k
    LLDB_LOGF(log, "[  AOTV::FD] Class method [%s] [%s]", name, types);
464
465
8.36k
    if (method_decl)
466
8.04k
      interface_decl->addDecl(method_decl);
467
468
8.36k
    return false;
469
8.36k
  };
470
471
397
  auto ivar_func = [log, interface_decl,
472
397
                    this](const char *name, const char *type,
473
478
                          lldb::addr_t offset_ptr, uint64_t size) -> bool {
474
478
    if (!name || !type)
475
0
      return false;
476
477
478
    const bool for_expression = false;
478
479
478
    LLDB_LOGF(log,
480
478
              "[  AOTV::FD] Instance variable [%s] [%s], offset at %" PRIx64,
481
478
              name, type, offset_ptr);
482
483
478
    CompilerType ivar_type = m_runtime.GetEncodingToType()->RealizeType(
484
478
        m_ast_ctx, type, for_expression);
485
486
478
    if (ivar_type.IsValid()) {
487
466
      clang::TypeSourceInfo *const type_source_info = nullptr;
488
466
      const bool is_synthesized = false;
489
466
      clang::ObjCIvarDecl *ivar_decl = clang::ObjCIvarDecl::Create(
490
466
          m_ast_ctx.getASTContext(), interface_decl, clang::SourceLocation(),
491
466
          clang::SourceLocation(), &m_ast_ctx.getASTContext().Idents.get(name),
492
466
          ClangUtil::GetQualType(ivar_type),
493
466
          type_source_info, // TypeSourceInfo *
494
466
          clang::ObjCIvarDecl::Public, nullptr, is_synthesized);
495
496
466
      if (ivar_decl) {
497
466
        interface_decl->addDecl(ivar_decl);
498
466
      }
499
466
    }
500
501
478
    return false;
502
478
  };
503
504
397
  LLDB_LOG(log,
505
397
           "[AppleObjCDeclVendor::FinishDecl] Finishing Objective-C "
506
397
           "interface for %s",
507
397
           descriptor->GetClassName().AsCString());
508
509
397
  if (!descriptor->Describe(superclass_func, instance_method_func,
510
397
                            class_method_func, ivar_func))
511
1
    return false;
512
513
396
  if (log) {
514
0
    LLDB_LOGF(
515
0
        log,
516
0
        "[AppleObjCDeclVendor::FinishDecl] Finished Objective-C interface");
517
518
0
    LLDB_LOG(log, "  [AOTV::FD] {0}", ClangUtil::DumpDecl(interface_decl));
519
0
  }
520
521
396
  return true;
522
397
}
523
524
uint32_t AppleObjCDeclVendor::FindDecls(ConstString name, bool append,
525
                                        uint32_t max_matches,
526
13.6k
                                        std::vector<CompilerDecl> &decls) {
527
528
13.6k
  Log *log(GetLogIfAllCategoriesSet(
529
13.6k
      LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
530
531
13.6k
  LLDB_LOGF(log, "AppleObjCDeclVendor::FindDecls ('%s', %s, %u, )",
532
13.6k
            (const char *)name.AsCString(), append ? "true" : "false",
533
13.6k
            max_matches);
534
535
13.6k
  if (!append)
536
12.7k
    decls.clear();
537
538
13.6k
  uint32_t ret = 0;
539
540
13.6k
  do {
541
    // See if the type is already in our ASTContext.
542
543
13.6k
    clang::ASTContext &ast_ctx = m_ast_ctx.getASTContext();
544
545
13.6k
    clang::IdentifierInfo &identifier_info =
546
13.6k
        ast_ctx.Idents.get(name.GetStringRef());
547
13.6k
    clang::DeclarationName decl_name =
548
13.6k
        ast_ctx.DeclarationNames.getIdentifier(&identifier_info);
549
550
13.6k
    clang::DeclContext::lookup_result lookup_result =
551
13.6k
        ast_ctx.getTranslationUnitDecl()->lookup(decl_name);
552
553
13.6k
    if (!lookup_result.empty()) {
554
1.30k
      if (clang::ObjCInterfaceDecl *result_iface_decl =
555
1.30k
             llvm::dyn_cast<clang::ObjCInterfaceDecl>(*lookup_result.begin())) {
556
1.30k
        if (log) {
557
0
          clang::QualType result_iface_type =
558
0
              ast_ctx.getObjCInterfaceType(result_iface_decl);
559
560
0
          uint64_t isa_value = LLDB_INVALID_ADDRESS;
561
0
          ClangASTMetadata *metadata = m_ast_ctx.GetMetadata(result_iface_decl);
562
0
          if (metadata)
563
0
            isa_value = metadata->GetISAPtr();
564
565
0
          LLDB_LOG(log,
566
0
                   "AOCTV::FT Found %s (isa 0x%" PRIx64 ") in the ASTContext",
567
0
                   result_iface_type.getAsString(), isa_value);
568
0
        }
569
570
1.30k
        decls.push_back(m_ast_ctx.GetCompilerDecl(result_iface_decl));
571
1.30k
        ret++;
572
1.30k
        break;
573
1.30k
      } else {
574
0
        LLDB_LOGF(log, "AOCTV::FT There's something in the ASTContext, but "
575
0
                       "it's not something we know about");
576
0
        break;
577
0
      }
578
12.3k
    } else if (log) {
579
21
      LLDB_LOGF(log, "AOCTV::FT Couldn't find %s in the ASTContext",
580
21
                name.AsCString());
581
21
    }
582
583
    // It's not.  If it exists, we have to put it into our ASTContext.
584
585
12.3k
    ObjCLanguageRuntime::ObjCISA isa = m_runtime.GetISA(name);
586
587
12.3k
    if (!isa) {
588
11.9k
      LLDB_LOGF(log, "AOCTV::FT Couldn't find the isa");
589
590
11.9k
      break;
591
11.9k
    }
592
593
396
    clang::ObjCInterfaceDecl *iface_decl = GetDeclForISA(isa);
594
595
396
    if (!iface_decl) {
596
0
      LLDB_LOGF(log,
597
0
                "AOCTV::FT Couldn't get the Objective-C interface for "
598
0
                "isa 0x%" PRIx64,
599
0
                (uint64_t)isa);
600
601
0
      break;
602
0
    }
603
604
396
    if (log) {
605
0
      clang::QualType new_iface_type = ast_ctx.getObjCInterfaceType(iface_decl);
606
607
0
      LLDB_LOG(log, "AOCTV::FT Created {1} (isa 0x{2:x})",
608
0
               new_iface_type.getAsString(), (uint64_t)isa);
609
0
    }
610
611
396
    decls.push_back(m_ast_ctx.GetCompilerDecl(iface_decl));
612
396
    ret++;
613
396
    break;
614
396
  } while (
false0
);
615
616
0
  return ret;
617
13.6k
}