void addSubNodes(CXXRecordDecl* RD) { addSubNodes(cast<RecordDecl>(RD)); if (RD->isDefinition()) { // FIXME: This breaks XML generation //Doc.addAttribute("num_bases", RD->getNumBases()); for (CXXRecordDecl::base_class_iterator base = RD->bases_begin(), bend = RD->bases_end(); base != bend; ++base) { Doc.addSubNode("Base"); Doc.addAttribute("id", base->getType()); AccessSpecifier as = base->getAccessSpecifierAsWritten(); const char* as_name = ""; switch(as) { case AS_none: as_name = ""; break; case AS_public: as_name = "public"; break; case AS_protected: as_name = "protected"; break; case AS_private: as_name = "private"; break; } Doc.addAttributeOptional("access", as_name); Doc.addAttribute("is_virtual", base->isVirtual()); Doc.toParent(); } } }
void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) { // FIXME: add printing of pragma attributes if required. if (!Policy.SuppressSpecifiers && D->isModulePrivate()) Out << "__module_private__ "; Out << D->getKindName(); prettyPrintAttributes(D); if (D->getIdentifier()) { Out << ' ' << *D; if (auto S = dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) printTemplateArguments(S->getTemplateArgs(), S->getTemplateParameters()); else if (auto S = dyn_cast<ClassTemplateSpecializationDecl>(D)) printTemplateArguments(S->getTemplateArgs()); } if (D->isCompleteDefinition()) { // Print the base classes if (D->getNumBases()) { Out << " : "; for (CXXRecordDecl::base_class_iterator Base = D->bases_begin(), BaseEnd = D->bases_end(); Base != BaseEnd; ++Base) { if (Base != D->bases_begin()) Out << ", "; if (Base->isVirtual()) Out << "virtual "; AccessSpecifier AS = Base->getAccessSpecifierAsWritten(); if (AS != AS_none) { Print(AS); Out << " "; } Out << Base->getType().getAsString(Policy); if (Base->isPackExpansion()) Out << "..."; } } // Print the class definition // FIXME: Doesn't print access specifiers, e.g., "public:" if (Policy.TerseOutput) { Out << " {}"; } else { Out << " {\n"; VisitDeclContext(D); Indent() << "}"; } } }