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