void ASTExporter::VisitFunctionDecl()

in facebook-clang-plugins/libtooling/ASTExporter.h [1541:1655]


void ASTExporter<ATDWriter>::VisitFunctionDecl(const FunctionDecl *D) {
  ASTExporter<ATDWriter>::VisitDeclaratorDecl(D);
  // We purposedly do not call VisitDeclContext(D).

  auto DNkind = D->getDeclName().getNameKind();
  bool ShouldMangleName = Mangler->shouldMangleDeclName(D) &&
                          DNkind != DeclarationName::CXXDeductionGuideName &&
                          DNkind != DeclarationName::CXXUsingDirective;
  bool IsInlineSpecified = D->isInlineSpecified();
  bool IsModulePrivate = D->isModulePrivate();
  bool IsPure = D->isPure();
  bool IsDeletedAsWritten = D->isDeletedAsWritten();
  bool IsCpp = Mangler->getASTContext().getLangOpts().CPlusPlus;
  bool IsVariadic = D->isVariadic();
  bool IsStatic = false; // static functions
  if (D->getStorageClass() == SC_Static) {
    IsStatic = true;
  }
  auto IsNoReturn = D->isNoReturn();
  bool IsConstexpr = D->isConstexpr();
  bool HasParameters = !D->param_empty();
  const FunctionDecl *DeclWithBody = D;
  // FunctionDecl::hasBody() will set DeclWithBody pointer to decl that
  // has body. If there is no body in all decls of that function,
  // then we need to set DeclWithBody to nullptr manually
  if (!D->hasBody(DeclWithBody)) {
    DeclWithBody = nullptr;
  }
  bool HasDeclarationBody = D->doesThisDeclarationHaveABody();
  FunctionTemplateDecl *TemplateDecl = D->getPrimaryTemplate();
  int size = ShouldMangleName + IsCpp + IsInlineSpecified + IsModulePrivate +
             IsPure + IsDeletedAsWritten + IsNoReturn + IsConstexpr +
             IsVariadic + IsStatic + HasParameters + (bool)DeclWithBody +
             HasDeclarationBody + (bool)TemplateDecl;
  ObjectScope Scope(OF, size);

  if (ShouldMangleName) {
    OF.emitTag("mangled_name");
    SmallString<64> Buf;
    llvm::raw_svector_ostream StrOS(Buf);
    GlobalDecl GD;
    if (const auto *CD = dyn_cast<CXXConstructorDecl>(D)) {
      GD = GlobalDecl(CD, Ctor_Base);
    } else if (const auto *DD = dyn_cast<CXXDestructorDecl>(D)) {
      GD = GlobalDecl(DD, Dtor_Base);
    } else {
      GD = GlobalDecl(D);
    }
    Mangler->mangleName(GD, StrOS);
    // mangled names can get ridiculously long, so hash them to a fixed size
    OF.emitString(std::to_string(fnv64Hash(StrOS)));
  }

  OF.emitFlag("is_cpp", IsCpp);
  OF.emitFlag("is_inline", IsInlineSpecified);
  OF.emitFlag("is_module_private", IsModulePrivate);
  OF.emitFlag("is_pure", IsPure);
  OF.emitFlag("is_delete_as_written", IsDeletedAsWritten);
  OF.emitFlag("is_no_return", IsNoReturn);
  OF.emitFlag("is_constexpr", IsConstexpr);
  OF.emitFlag("is_variadic", IsVariadic);
  OF.emitFlag("is_static", IsStatic);

  //  if (const FunctionProtoType *FPT =
  //  D->getType()->getAs<FunctionProtoType>()) {
  //    FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
  //    switch (EPI.ExceptionSpec.Type) {
  //    default: break;
  //    case EST_Unevaluated:
  //      OS << " noexcept-unevaluated " << EPI.ExceptionSpec.SourceDecl;
  //      break;
  //    case EST_Uninstantiated:
  //      OS << " noexcept-uninstantiated " << EPI.ExceptionSpec.SourceTemplate;
  //      break;
  //    }
  //  }
  //
  //  const FunctionTemplateSpecializationInfo *FTSI =
  //      D->getTemplateSpecializationInfo();
  //  bool HasTemplateSpecialization = FTSI;
  //
  //
  //  if (HasTemplateSpecialization) {
  //    dumpTemplateArgumentList(*FTSI->TemplateArguments);
  //  }

  if (HasParameters) {
    FunctionDecl::param_const_iterator I = D->param_begin(), E = D->param_end();
    if (I != E) {
      OF.emitTag("parameters");
      ArrayScope Scope(OF, std::distance(I, E));
      for (; I != E; ++I) {
        dumpDecl(*I);
      }
    }
  }

  if (DeclWithBody) {
    OF.emitTag("decl_ptr_with_body");
    dumpPointer(DeclWithBody);
  }

  if (HasDeclarationBody) {
    const Stmt *Body = D->getBody();
    if (Body) {
      OF.emitTag("body");
      dumpStmt(Body);
    }
  }
  if (TemplateDecl) {
    OF.emitTag("template_specialization");
    dumpTemplateSpecialization(TemplateDecl,
                               *D->getTemplateSpecializationArgs());
  }
}