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);
}
}