void ASTExporter::VisitBlockDecl()

in facebook-clang-plugins/libtooling/ASTExporter.h [2997:3077]


void ASTExporter<ATDWriter>::VisitBlockDecl(const BlockDecl *D) {
  VisitDecl(D);
  // We purposedly do not call VisitDeclContext(D).

  ObjCMethodDecl::param_const_iterator PCII = D->param_begin(),
                                       PCIE = D->param_end();
  bool HasParameters = PCII != PCIE;
  bool IsVariadic = D->isVariadic();
  bool CapturesCXXThis = D->capturesCXXThis();
  BlockDecl::capture_const_iterator CII = D->capture_begin(),
                                    CIE = D->capture_end();
  bool HasCapturedVariables = CII != CIE;
  const Stmt *Body = D->getBody();

  std::string MangledName;
  const DeclContext *DC = D->getDeclContext();
  if (auto ND = dyn_cast<NamedDecl>(DC)) {
    if (!isa<FunctionDecl>(ND) && !isa<VarDecl>(ND) && ND->getIdentifier()) {
      MangledName = ND->getIdentifier()->getName().str();
    } else if (!isa<CXXConstructorDecl>(DC) && !isa<CXXDestructorDecl>(DC)) {
      SmallString<64> Buf;
      llvm::raw_svector_ostream StrOS(Buf);
      Mangler->mangleBlock(DC, D, StrOS);
      MangledName = StrOS.str().str();
    }
  }

  int size = 0 + HasParameters + IsVariadic + CapturesCXXThis +
             HasCapturedVariables + (bool)Body;
  if (!MangledName.empty())
    ++size;

  ObjectScope Scope(OF, size); // not covered by tests

  if (HasParameters) {
    OF.emitTag("parameters");
    ArrayScope Scope(OF, std::distance(PCII, PCIE));
    for (; PCII != PCIE; ++PCII) {
      dumpDecl(*PCII);
    }
  }

  OF.emitFlag("is_variadic", IsVariadic);
  OF.emitFlag("captures_cxx_this", CapturesCXXThis);

  if (HasCapturedVariables) {
    OF.emitTag("captured_variables");
    ArrayScope Scope(OF, std::distance(CII, CIE));
    for (; CII != CIE; ++CII) {
      bool IsByRef = CII->isByRef();
      bool IsNested = CII->isNested();
      bool HasVariable = CII->getVariable();
      bool HasCopyExpr = CII->hasCopyExpr();
      ObjectScope Scope(OF,
                        0 + IsByRef + IsNested + HasVariable +
                            HasCopyExpr); // not covered by tests

      OF.emitFlag("is_by_ref", IsByRef);
      OF.emitFlag("is_nested", IsNested);

      if (HasVariable) {
        OF.emitTag("variable");
        dumpDeclRef(*CII->getVariable());
      }

      if (HasCopyExpr) {
        OF.emitTag("copy_expr");
        dumpStmt(CII->getCopyExpr());
      }
    }
  }
  if (Body) {
    OF.emitTag("body");
    dumpStmt(Body);
  }

  if (!MangledName.empty()) {
    OF.emitTag("mangled_name");
    OF.emitString(MangledName);
  }
}