/// Returns true if the given C++ class is a container.
///
/// Our heuristic for this is whether it contains a method named 'begin()' or a
/// nested type named 'iterator'.
static bool isContainerClass(const ASTContext &Ctx, const CXXRecordDecl *RD) {
  // Don't record any path information.
  CXXBasePaths Paths(false, false, false);

  const IdentifierInfo &BeginII = Ctx.Idents.get("begin");
  DeclarationName BeginName = Ctx.DeclarationNames.getIdentifier(&BeginII);
  DeclContext::lookup_const_result BeginDecls = RD->lookup(BeginName);
  if (!BeginDecls.empty())
    return true;
  if (RD->lookupInBases(&CXXRecordDecl::FindOrdinaryMember,
                        BeginName.getAsOpaquePtr(),
                        Paths))
    return true;
  
  const IdentifierInfo &IterII = Ctx.Idents.get("iterator");
  DeclarationName IteratorName = Ctx.DeclarationNames.getIdentifier(&IterII);
  DeclContext::lookup_const_result IterDecls = RD->lookup(IteratorName);
  if (!IterDecls.empty())
    return true;
  if (RD->lookupInBases(&CXXRecordDecl::FindOrdinaryMember,
                        IteratorName.getAsOpaquePtr(),
                        Paths))
    return true;

  return false;
}
/// Returns true if the given C++ class contains a member with the given name.
static bool hasMember(const ASTContext &Ctx, const CXXRecordDecl *RD,
                      StringRef Name) {
  const IdentifierInfo &II = Ctx.Idents.get(Name);
  DeclarationName DeclName = Ctx.DeclarationNames.getIdentifier(&II);
  if (!RD->lookup(DeclName).empty())
    return true;

  CXXBasePaths Paths(false, false, false);
  if (RD->lookupInBases(&CXXRecordDecl::FindOrdinaryMember,
                        DeclName.getAsOpaquePtr(),
                        Paths))
    return true;

  return false;
}
Example #3
0
void StmtProfiler::VisitName(DeclarationName Name) {
  ID.AddPointer(Name.getAsOpaquePtr());
}