12#include "clang/AST/Attr.h"
13#include "clang/AST/Comment.h"
14#include "clang/AST/DeclFriend.h"
15#include "clang/AST/Mangle.h"
16#include "clang/Index/USRGeneration.h"
17#include "clang/Lex/Lexer.h"
18#include "llvm/ADT/StringExtras.h"
19#include "llvm/Support/SHA1.h"
21using clang::comments::FullComment;
28static SmallString<16> exprToString(
const clang::Expr *E) {
29 clang::LangOptions Opts;
30 clang::PrintingPolicy Policy(Opts);
31 SmallString<16> Result;
32 llvm::raw_svector_ostream OS(Result);
33 E->printPretty(OS,
nullptr, Policy);
39 return llvm::SHA1::hash(arrayRefFromStringRef(USR));
45 const T *D,
bool &IsAnonymousNamespace);
49 const DeclaratorDecl *D,
50 bool IsStatic =
false);
53 llvm::raw_ostream &Stream) {
54 Stream <<
"template <";
56 for (
unsigned i = 0; i < TemplateParams->size(); ++i) {
60 const NamedDecl *Param = TemplateParams->getParam(i);
61 if (
const auto *TTP = llvm::dyn_cast<TemplateTypeParmDecl>(Param)) {
62 if (TTP->wasDeclaredWithTypename())
66 if (TTP->isParameterPack())
68 Stream <<
" " << TTP->getNameAsString();
73 if (TTP->hasTypeConstraint()) {
75 TTP->getTypeConstraint()->print(
76 Stream, TTP->getASTContext().getPrintingPolicy());
78 }
else if (
const auto *NTTP =
79 llvm::dyn_cast<NonTypeTemplateParmDecl>(Param)) {
80 NTTP->getType().print(Stream, NTTP->getASTContext().getPrintingPolicy());
81 if (NTTP->isParameterPack())
83 Stream <<
" " << NTTP->getNameAsString();
84 }
else if (
const auto *TTPD =
85 llvm::dyn_cast<TemplateTemplateParmDecl>(Param)) {
86 Stream <<
"template <";
88 Stream <<
"> class " << TTPD->getNameAsString();
97static llvm::SmallString<256>
99 llvm::SmallString<256> Result;
100 llvm::raw_svector_ostream Stream(Result);
101 const ASTContext &Ctx =
FuncDecl->getASTContext();
102 const auto *Method = llvm::dyn_cast<CXXMethodDecl>(
FuncDecl);
104 if (
const auto *TmplDecl =
FuncDecl->getDescribedTemplate())
108 if (Method && Method->isVirtual())
109 Stream <<
"virtual ";
112 FuncDecl->getReturnType().print(Stream, Ctx.getPrintingPolicy());
115 Stream <<
" " <<
FuncDecl->getNameAsString() <<
"(";
118 for (
unsigned I = 0; I <
FuncDecl->getNumParams(); ++I) {
121 const ParmVarDecl *ParamDecl =
FuncDecl->getParamDecl(I);
122 QualType ParamType = ParamDecl->getType();
123 ParamType.print(Stream, Ctx.getPrintingPolicy());
126 if (!ParamDecl->getName().empty())
127 Stream <<
" " << ParamDecl->getNameAsString();
130 if (ParamDecl->hasDefaultArg() &&
131 !ParamDecl->hasUninstantiatedDefaultArg()) {
132 if (
const Expr *DefaultArg = ParamDecl->getDefaultArg()) {
134 DefaultArg->printPretty(Stream,
nullptr, Ctx.getPrintingPolicy());
150 if (Method->isDeleted())
151 Stream <<
" = delete";
152 if (Method->size_overridden_methods())
153 Stream <<
" override";
154 if (Method->hasAttr<clang::FinalAttr>())
156 if (Method->isConst())
158 if (Method->isPureVirtual())
162 if (
auto ExceptionSpecType =
FuncDecl->getExceptionSpecType())
163 Stream <<
" " << ExceptionSpecType;
169 llvm::SmallString<16> Result;
170 llvm::raw_svector_ostream Stream(Result);
171 const ASTContext &Ctx = Alias->getASTContext();
172 if (
const auto *TmplDecl = Alias->getDescribedTemplate())
174 Stream <<
"using " << Alias->getNameAsString() <<
" = ";
175 QualType Q = Alias->getUnderlyingType();
176 Q.print(Stream, Ctx.getPrintingPolicy());
183 llvm::SmallString<16> Result;
184 LangOptions LangOpts;
185 PrintingPolicy Policy(LangOpts);
186 Policy.SuppressTagKeyword =
false;
187 Policy.FullyQualifiedName =
true;
188 Policy.IncludeNewlines =
false;
189 llvm::raw_svector_ostream OS(Result);
190 if (
const auto *TD = CXXRD->getDescribedClassTemplate()) {
192 bool FirstParam =
true;
193 for (
const auto *Param : *TD->getTemplateParameters()) {
196 Param->print(OS, Policy);
202 if (CXXRD->isStruct())
204 else if (CXXRD->isClass())
206 else if (CXXRD->isUnion())
209 OS << CXXRD->getNameAsString();
214 if (CXXRD->isCompleteDefinition() && CXXRD->getNumBases() > 0) {
216 bool FirstBase =
true;
217 for (
const auto &Base : CXXRD->bases()) {
220 if (Base.isVirtual())
222 OS << getAccessSpelling(Base.getAccessSpecifier()) <<
" ";
223 OS << Base.getType().getAsString(Policy);
243static llvm::SmallString<128>
245 llvm::SmallString<128> Path;
246 for (
auto R = Namespaces.rbegin(), E = Namespaces.rend(); R != E; ++R)
247 llvm::sys::path::append(Path, R->Name);
252 llvm::SmallVector<Reference, 4> Namespaces;
280 std::string getCommandName(
unsigned CommandID)
const;
281 bool isWhitespaceOnly(StringRef S)
const;
289 for (comments::Comment *Child :
290 llvm::make_range(C->child_begin(), C->child_end())) {
291 CurrentCI.Children.emplace_back(std::make_unique<CommentInfo>());
298 if (!isWhitespaceOnly(C->getText()))
299 CurrentCI.Text = C->getText();
303 const InlineCommandComment *C) {
304 CurrentCI.Name = getCommandName(C->getCommandID());
305 for (
unsigned I = 0, E = C->getNumArgs(); I != E; ++I)
306 CurrentCI.Args.push_back(C->getArgText(I));
310 const HTMLStartTagComment *C) {
311 CurrentCI.Name = C->getTagName();
312 CurrentCI.SelfClosing = C->isSelfClosing();
313 for (
unsigned I = 0, E = C->getNumAttrs(); I < E; ++I) {
314 const HTMLStartTagComment::Attribute &Attr = C->getAttr(I);
315 CurrentCI.AttrKeys.push_back(Attr.Name);
316 CurrentCI.AttrValues.push_back(Attr.Value);
321 const HTMLEndTagComment *C) {
322 CurrentCI.Name = C->getTagName();
323 CurrentCI.SelfClosing =
true;
327 const BlockCommandComment *C) {
328 CurrentCI.Name = getCommandName(C->getCommandID());
329 for (
unsigned I = 0, E = C->getNumArgs(); I < E; ++I)
330 CurrentCI.Args.push_back(C->getArgText(I));
334 const ParamCommandComment *C) {
335 CurrentCI.Direction =
336 ParamCommandComment::getDirectionAsString(C->getDirection());
337 CurrentCI.Explicit = C->isDirectionExplicit();
338 if (C->hasParamName())
339 CurrentCI.ParamName = C->getParamNameAsWritten();
343 const TParamCommandComment *C) {
344 if (C->hasParamName())
345 CurrentCI.ParamName = C->getParamNameAsWritten();
349 const VerbatimBlockComment *C) {
350 CurrentCI.Name = getCommandName(C->getCommandID());
351 CurrentCI.CloseName = C->getCloseName();
355 const VerbatimBlockLineComment *C) {
356 if (!isWhitespaceOnly(C->getText()))
357 CurrentCI.Text = C->getText();
361 const VerbatimLineComment *C) {
362 if (!isWhitespaceOnly(C->getText()))
363 CurrentCI.Text = C->getText();
366bool ClangDocCommentVisitor::isWhitespaceOnly(llvm::StringRef S)
const {
367 return llvm::all_of(S, isspace);
370std::string ClangDocCommentVisitor::getCommandName(
unsigned CommandID)
const {
371 const CommandInfo *
Info = CommandTraits::getBuiltinCommandInfo(CommandID);
375 return "<not a builtin command>";
381 return Lexer::getSourceText(CharSourceRange::getTokenRange(R),
382 D->getASTContext().getSourceManager(),
383 D->getASTContext().getLangOpts())
387template <
typename T>
static std::string
serialize(T &I) {
388 SmallString<2048> Buffer;
389 llvm::BitstreamWriter Stream(Buffer);
392 return Buffer.str().str();
414 llvm_unreachable(
"unhandled enumerator");
423 llvm::SmallString<128> USR;
424 if (index::generateUSRForDecl(D, USR))
430 if (
const TagDecl *D = T->getAsTagDecl())
431 return D->getDefinition();
436 if (
const RecordDecl *D = T->getAsRecordDecl())
437 return D->getDefinition();
442 const PrintingPolicy &Policy) {
451 if (isa<EnumDecl>(TD)) {
453 }
else if (isa<RecordDecl>(TD)) {
466static bool isPublic(
const clang::AccessSpecifier AS,
467 const clang::Linkage Link) {
468 if (AS == clang::AccessSpecifier::AS_private)
470 if ((Link == clang::Linkage::Module) || (Link == clang::Linkage::External))
476 const NamedDecl *D) {
477 bool IsAnonymousNamespace =
false;
478 if (
const auto *N = dyn_cast<NamespaceDecl>(D))
479 IsAnonymousNamespace = N->isAnonymousNamespace();
481 (!IsInAnonymousNamespace && !IsAnonymousNamespace &&
482 isPublic(D->getAccessUnsafe(), D->getLinkageInternal()));
536template <
typename ChildType>
538 if (Child.Namespace.empty()) {
540 auto ParentNS = std::make_unique<NamespaceInfo>();
541 InsertChild(ParentNS->Children, std::forward<ChildType>(Child));
545 switch (Child.Namespace[0].RefType) {
547 auto ParentNS = std::make_unique<NamespaceInfo>();
548 ParentNS->USR = Child.Namespace[0].USR;
549 InsertChild(ParentNS->Children, std::forward<ChildType>(Child));
553 auto ParentRec = std::make_unique<RecordInfo>();
554 ParentRec->USR = Child.Namespace[0].USR;
555 InsertChild(ParentRec->Children, std::forward<ChildType>(Child));
567 llvm_unreachable(
"Invalid reference type for parent namespace");
586 AccessSpecifier SecondAS) {
587 if (FirstAS == AccessSpecifier::AS_none ||
588 SecondAS == AccessSpecifier::AS_none)
589 return AccessSpecifier::AS_none;
590 if (FirstAS == AccessSpecifier::AS_private ||
591 SecondAS == AccessSpecifier::AS_private)
592 return AccessSpecifier::AS_private;
593 if (FirstAS == AccessSpecifier::AS_protected ||
594 SecondAS == AccessSpecifier::AS_protected)
595 return AccessSpecifier::AS_protected;
596 return AccessSpecifier::AS_public;
602 AccessSpecifier Access = AccessSpecifier::AS_public) {
603 for (
const FieldDecl *F : D->fields()) {
608 const auto *CxxRD = dyn_cast<CXXRecordDecl>(D);
611 for (Decl *CxxDecl : CxxRD->decls()) {
612 auto *VD = dyn_cast<VarDecl>(CxxDecl);
617 if (VD->isStaticDataMember())
623 for (
const EnumConstantDecl *E : D->enumerators()) {
624 std::string ValueExpr;
625 if (
const Expr *InitExpr = E->getInitExpr())
627 SmallString<16> ValueStr;
628 E->getInitVal().toString(ValueStr);
629 I.
Members.emplace_back(E->getNameAsString(), ValueStr.str(), ValueExpr);
630 ASTContext &Context = E->getASTContext();
631 if (RawComment *Comment =
632 E->getASTContext().getRawCommentForDeclNoCache(E)) {
633 Comment->setAttached();
634 if (comments::FullComment *Fc = Comment->parse(Context,
nullptr, E)) {
644 auto &LO = D->getLangOpts();
645 for (
const ParmVarDecl *P : D->parameters()) {
656 if (!D->isThisDeclarationADefinition())
659 for (
const CXXBaseSpecifier &B : D->bases()) {
662 if (
const auto *Ty = B.getType()->getAs<TemplateSpecializationType>()) {
663 const TemplateDecl *D = Ty->getTemplateName().getAsTemplateDecl();
673 for (
const CXXBaseSpecifier &B : D->vbases()) {
686 const T *D,
bool &IsInAnonymousNamespace) {
687 const DeclContext *DC = D->getDeclContext();
689 if (
const auto *N = dyn_cast<NamespaceDecl>(DC)) {
690 std::string Namespace;
691 if (N->isAnonymousNamespace()) {
692 Namespace =
"@nonymous_namespace";
693 IsInAnonymousNamespace =
true;
695 Namespace = N->getNameAsString();
698 N->getQualifiedNameAsString());
699 }
else if (
const auto *N = dyn_cast<RecordDecl>(DC))
700 Namespaces.emplace_back(
getUSRForDecl(N), N->getNameAsString(),
702 N->getQualifiedNameAsString());
703 else if (
const auto *N = dyn_cast<FunctionDecl>(DC))
704 Namespaces.emplace_back(
getUSRForDecl(N), N->getNameAsString(),
706 N->getQualifiedNameAsString());
707 else if (
const auto *N = dyn_cast<EnumDecl>(DC))
708 Namespaces.emplace_back(
getUSRForDecl(N), N->getNameAsString(),
710 }
while ((DC = DC->getParent()));
715 if ((Namespaces.empty() && isa<RecordDecl>(D)) ||
717 Namespaces.emplace_back(
SymbolID(),
"GlobalNamespace",
723 const clang::Decl *D) {
724 if (
const TemplateParameterList *ParamList =
725 D->getDescribedTemplateParams()) {
729 for (
const NamedDecl *ND : *ParamList) {
737 const TemplateArgument &Arg) {
741 llvm::raw_string_ostream Stream(Str);
742 Arg.print(PrintingPolicy(D->getLangOpts()), Stream,
false);
748 bool &IsInAnonymousNamespace) {
750 if (
auto ConversionDecl = dyn_cast_or_null<CXXConversionDecl>(D);
751 ConversionDecl && ConversionDecl->getConversionType()
753 ->isTemplateTypeParmType())
754 I.
Name =
"operator " + ConversionDecl->getConversionType().getAsString();
756 I.
Name = D->getNameAsString();
766 Location Loc,
bool &IsInAnonymousNamespace) {
768 if (D->isThisDeclarationADefinition())
771 I.
Loc.emplace_back(Loc);
773 auto *Mangler = ItaniumMangleContext::create(
774 D->getASTContext(), D->getASTContext().getDiagnostics());
775 std::string MangledName;
776 llvm::raw_string_ostream MangledStream(MangledName);
777 if (
auto *CXXD = dyn_cast<CXXRecordDecl>(D))
778 Mangler->mangleCXXVTable(CXXD, MangledStream);
780 MangledStream << D->getNameAsString();
783 if (MangledName.size() > 250) {
784 auto SymbolID = llvm::toStringRef(llvm::toHex(I.
USR)).str();
793 std::vector<ConstraintInfo> &ConstraintInfos) {
794 if (Constraint->getStmtClass() == Stmt::ParenExprClass) {
797 }
else if (Constraint->getStmtClass() == Stmt::BinaryOperatorClass) {
798 auto *BinaryOpExpr = dyn_cast<BinaryOperator>(Constraint);
801 }
else if (Constraint->getStmtClass() ==
802 Stmt::ConceptSpecializationExprClass) {
803 auto *Concept = dyn_cast<ConceptSpecializationExpr>(Constraint);
805 Concept->getNamedConcept()->getNameAsString());
807 ConstraintInfos.push_back(CI);
812 if (!D || !D->hasAssociatedConstraints())
815 SmallVector<AssociatedConstraint> AssociatedConstraints;
816 D->getAssociatedConstraints(AssociatedConstraints);
817 for (
const auto &Constraint : AssociatedConstraints) {
822 if (
const auto *ConstraintExpr =
823 dyn_cast_or_null<ConceptSpecializationExpr>(
824 Constraint.ConstraintExpr)) {
826 ConstraintExpr->getNamedConcept()->getNameAsString());
836 const FullComment *FC,
Location Loc,
837 bool &IsInAnonymousNamespace) {
839 auto &LO = D->getLangOpts();
850 if (
const FunctionTemplateSpecializationInfo *FTSI =
851 D->getTemplateSpecializationInfo()) {
854 I.
Template->Specialization.emplace();
855 auto &Specialization = *I.
Template->Specialization;
857 Specialization.SpecializationOf =
getUSRForDecl(FTSI->getTemplate());
860 if (FTSI->TemplateArguments) {
861 for (
const TemplateArgument &Arg : FTSI->TemplateArguments->asArray()) {
869 assert(D &&
"Expect non-null FieldDecl in populateMemberTypeInfo");
871 ASTContext &Context = D->getASTContext();
874 RawComment *Comment = Context.getRawCommentForDeclNoCache(D);
878 Comment->setAttached();
879 if (comments::FullComment *Fc = Comment->parse(Context,
nullptr, D)) {
886 const DeclaratorDecl *D,
bool IsStatic) {
891 D->getNameAsString(),
899 AccessSpecifier ParentAccess = AccessSpecifier::AS_public) {
901 if (!D->isThisDeclarationADefinition())
903 for (
const CXXBaseSpecifier &B : D->bases()) {
904 if (
const auto *Base = B.getType()->getAsCXXRecordDecl()) {
905 if (Base->isCompleteDefinition()) {
912 if (
const auto *Ty = B.getType()->getAs<TemplateSpecializationType>()) {
913 const TemplateDecl *D = Ty->getTemplateName().getAsTemplateDecl();
915 BI.Name = B.getType().getAsString();
918 BI.Name = Base->getNameAsString();
921 for (
const auto &Decl : Base->decls())
922 if (
const auto *
MD = dyn_cast<CXXMethodDecl>(Decl)) {
924 if (
MD->getAccessUnsafe() == AccessSpecifier::AS_private ||
925 !
MD->isUserProvided())
933 bool IsInAnonymousNamespace;
935 IsInAnonymousNamespace);
938 BI.Children.Functions.emplace_back(std::move(FI));
940 I.
Bases.emplace_back(std::move(BI));
945 I.
Bases.back().Access);
951std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
954 auto NSI = std::make_unique<NamespaceInfo>();
955 bool IsInAnonymousNamespace =
false;
960 NSI->Name = D->isAnonymousNamespace()
961 ? llvm::SmallString<16>(
"@nonymous_namespace")
964 if (NSI->Namespace.empty() && NSI->USR ==
SymbolID())
965 return {std::unique_ptr<Info>{std::move(NSI)},
nullptr};
973 if (!D->hasDefinition() || !D->hasFriends())
976 for (
const FriendDecl *FD : D->friends()) {
977 if (FD->isUnsupportedFriend())
981 const auto *ActualDecl = FD->getFriendDecl();
983 const auto *FriendTypeInfo = FD->getFriendType();
986 ActualDecl = FriendTypeInfo->getType()->getAsCXXRecordDecl();
993 if (
const auto *ActualTD = dyn_cast_or_null<TemplateDecl>(ActualDecl)) {
994 if (isa<RecordDecl>(ActualTD->getTemplatedDecl()))
997 for (
const auto *Param : ActualTD->getTemplateParameters()->asArray())
1000 ActualDecl = ActualTD->getTemplatedDecl();
1003 if (
auto *
FuncDecl = dyn_cast_or_null<FunctionDecl>(ActualDecl)) {
1017 RI.
Friends.push_back(std::move(F));
1021std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
1025 auto RI = std::make_unique<RecordInfo>();
1026 bool IsInAnonymousNamespace =
false;
1032 RI->TagType = D->getTagKind();
1035 if (
const auto *C = dyn_cast<CXXRecordDecl>(D)) {
1037 if (
const TypedefNameDecl *TD = C->getTypedefNameForAnonDecl()) {
1038 RI->Name = TD->getNameAsString();
1039 RI->IsTypeDef =
true;
1053 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1055 RI->Template.emplace();
1056 RI->Template->Specialization.emplace();
1057 auto &Specialization = *RI->Template->Specialization;
1060 auto SpecOf = CTSD->getSpecializedTemplateOrPartial();
1061 if (
auto *SpecTD = dyn_cast<ClassTemplateDecl *>(SpecOf))
1063 else if (
auto *SpecTD =
1064 dyn_cast<ClassTemplatePartialSpecializationDecl *>(SpecOf))
1072 if (
const ClassTemplatePartialSpecializationDecl *CTPSD =
1073 dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) {
1074 if (
const ASTTemplateArgumentListInfo *AsWritten =
1075 CTPSD->getTemplateArgsAsWritten()) {
1076 for (
unsigned Idx = 0; Idx < AsWritten->getNumTemplateArgs(); Idx++) {
1077 Specialization.Params.emplace_back(
1082 for (
const TemplateArgument &Arg : CTSD->getTemplateArgs().asArray()) {
1091 return {std::move(RI), std::move(Parent)};
1094std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
1098 bool IsInAnonymousNamespace =
false;
1100 Func.
Access = clang::AccessSpecifier::AS_none;
1108std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
1112 bool IsInAnonymousNamespace =
false;
1120 const NamedDecl *Parent =
nullptr;
1121 if (
const auto *SD =
1122 dyn_cast<ClassTemplateSpecializationDecl>(D->getParent()))
1123 Parent = SD->getSpecializedTemplate();
1125 Parent = D->getParent();
1130 Parent->getQualifiedNameAsString()};
1131 Func.
Access = D->getAccess();
1138 assert(D &&
"Invalid Decl when extracting comment");
1139 ASTContext &Context = D->getASTContext();
1140 RawComment *Comment = Context.getRawCommentForDeclNoCache(D);
1144 Comment->setAttached();
1145 if (comments::FullComment *Fc = Comment->parse(Context,
nullptr, D)) {
1151std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
1155 bool IsInAnonymousNamespace =
false;
1162 auto &LO = D->getLangOpts();
1165 if (
Info.Underlying.Type.
Name.empty()) {
1171 Info.IsUsing =
false;
1180std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
1184 bool IsInAnonymousNamespace =
false;
1190 const LangOptions &LO = D->getLangOpts();
1193 Info.IsUsing =
true;
1201std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
1205 bool IsInAnonymousNamespace =
false;
1211 Enum.Scoped = D->isScoped();
1213 auto Name = D->getIntegerType().getAsString();
1214 Enum.BaseType =
TypeInfo(Name, Name);
1222std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
1227 bool IsInAnonymousNamespace =
false;
1229 Concept.IsType = D->isTypeConcept();
1230 Concept.DefLoc = Loc;
1231 Concept.ConstraintExpression = exprToString(D->getConstraintExpr());
1233 if (
auto *ConceptParams = D->getTemplateParameters()) {
1234 for (
const auto *Param : ConceptParams->asArray()) {
1235 Concept.Template.Params.emplace_back(
1246std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
1250 bool IsInAnonymousNamespace =
false;
1255 if (D->getStorageClass() == StorageClass::SC_Static)
static llvm::cl::opt< bool > PublicOnly("public", llvm::cl::desc("Document only public declarations."), llvm::cl::init(false), llvm::cl::cat(ClangDocCategory))
void emitBlock(const NamespaceInfo &I)
static void parseFields(RecordInfo &I, const RecordDecl *D, bool PublicOnly, AccessSpecifier Access=AccessSpecifier::AS_public)
static void extractCommentFromDecl(const Decl *D, TypedefInfo &Info)
static void populateConstraints(TemplateInfo &I, const TemplateDecl *D)
static bool shouldSerializeInfo(bool PublicOnly, bool IsInAnonymousNamespace, const NamedDecl *D)
static std::unique_ptr< Info > makeAndInsertIntoParent(ChildType Child)
static RecordDecl * getRecordDeclForType(const QualType &T)
std::pair< std::unique_ptr< Info >, std::unique_ptr< Info > > emitInfo(const NamespaceDecl *D, const FullComment *FC, Location Loc, bool PublicOnly)
static bool isPublic(const clang::AccessSpecifier AS, const clang::Linkage Link)
static void parseFriends(RecordInfo &RI, const CXXRecordDecl *D)
static void parseFullComment(const FullComment *C, CommentInfo &CI)
static void getTemplateParameters(const TemplateParameterList *TemplateParams, llvm::raw_ostream &Stream)
static std::string serialize(T &I)
static void parseParameters(FunctionInfo &I, const FunctionDecl *D)
static void populateMemberTypeInfo(MemberTypeInfo &I, const Decl *D)
static SymbolID getUSRForDecl(const Decl *D)
static AccessSpecifier getFinalAccessSpecifier(AccessSpecifier FirstAS, AccessSpecifier SecondAS)
static llvm::SmallString< 128 > getInfoRelativePath(const llvm::SmallVectorImpl< doc::Reference > &Namespaces)
static void populateFunctionInfo(FunctionInfo &I, const FunctionDecl *D, const FullComment *FC, Location Loc, bool &IsInAnonymousNamespace)
static TemplateParamInfo convertTemplateArgToInfo(const clang::Decl *D, const TemplateArgument &Arg)
static void populateTemplateParameters(std::optional< TemplateInfo > &TemplateInfo, const clang::Decl *D)
static void InsertChild(ScopeChildren &Scope, const NamespaceInfo &Info)
static llvm::SmallString< 16 > getRecordPrototype(const CXXRecordDecl *CXXRD)
static TypeInfo getTypeInfoForType(const QualType &T, const PrintingPolicy &Policy)
static llvm::SmallString< 16 > getTypeAlias(const TypeAliasDecl *Alias)
static void populateParentNamespaces(llvm::SmallVector< Reference, 4 > &Namespaces, const T *D, bool &IsAnonymousNamespace)
static std::string getSourceCode(const Decl *D, const SourceRange &R)
static void populateSymbolInfo(SymbolInfo &I, const T *D, const FullComment *C, Location Loc, bool &IsInAnonymousNamespace)
static void parseEnumerators(EnumInfo &I, const EnumDecl *D)
static TagDecl * getTagDeclForType(const QualType &T)
static void parseBases(RecordInfo &I, const CXXRecordDecl *D)
static llvm::SmallString< 256 > getFunctionPrototype(const FunctionDecl *FuncDecl)
SymbolID hashUSR(llvm::StringRef USR)
static void handleCompoundConstraints(const Expr *Constraint, std::vector< ConstraintInfo > &ConstraintInfos)
static void populateInfo(Info &I, const T *D, const FullComment *C, bool &IsInAnonymousNamespace)
static GeneratorRegistry::Add< MDGenerator > MD(MDGenerator::Format, "Generator for MD output.")
CommentKind stringToCommentKind(llvm::StringRef KindStr)
std::array< uint8_t, 20 > SymbolID
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
SmallString< 16 > ConstraintExpr
llvm::SmallVector< EnumValueInfo, 4 > Members
std::vector< CommentInfo > Description
Comment description of this field.
SmallString< 16 > DefaultValue
std::optional< TypeInfo > ReturnType
std::optional< SmallVector< FieldTypeInfo, 4 > > Params
std::optional< TemplateInfo > Template
llvm::SmallVector< FieldTypeInfo, 4 > Params
std::optional< TemplateInfo > Template
SmallString< 256 > Prototype
std::vector< CommentInfo > Description
llvm::SmallVector< Reference, 4 > Namespace
std::vector< CommentInfo > Description
llvm::SmallVector< MemberTypeInfo, 4 > Members
std::vector< FriendInfo > Friends
llvm::SmallVector< Reference, 4 > VirtualParents
llvm::SmallVector< Reference, 4 > Parents
std::vector< BaseRecordInfo > Bases
std::vector< Reference > Records
std::vector< TypedefInfo > Typedefs
std::vector< FunctionInfo > Functions
std::vector< Reference > Namespaces
std::vector< VarInfo > Variables
std::vector< EnumInfo > Enums
std::vector< ConceptInfo > Concepts
llvm::SmallVector< Location, 2 > Loc
std::optional< Location > DefLoc
SmallString< 16 > MangledName
std::vector< ConstraintInfo > Constraints
std::vector< TemplateParamInfo > Params
static constexpr const char FuncDecl[]