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());
194static llvm::SmallString<128>
196 llvm::SmallString<128> Path;
197 for (
auto R = Namespaces.rbegin(), E = Namespaces.rend(); R != E; ++R)
198 llvm::sys::path::append(Path, R->Name);
203 llvm::SmallVector<Reference, 4> Namespaces;
231 std::string getCommandName(
unsigned CommandID)
const;
232 bool isWhitespaceOnly(StringRef S)
const;
240 for (comments::Comment *Child :
241 llvm::make_range(C->child_begin(), C->child_end())) {
242 CurrentCI.Children.emplace_back(std::make_unique<CommentInfo>());
249 if (!isWhitespaceOnly(C->getText()))
250 CurrentCI.Text = C->getText();
254 const InlineCommandComment *C) {
255 CurrentCI.Name = getCommandName(C->getCommandID());
256 for (
unsigned I = 0, E = C->getNumArgs(); I != E; ++I)
257 CurrentCI.Args.push_back(C->getArgText(I));
261 const HTMLStartTagComment *C) {
262 CurrentCI.Name = C->getTagName();
263 CurrentCI.SelfClosing = C->isSelfClosing();
264 for (
unsigned I = 0, E = C->getNumAttrs(); I < E; ++I) {
265 const HTMLStartTagComment::Attribute &Attr = C->getAttr(I);
266 CurrentCI.AttrKeys.push_back(Attr.Name);
267 CurrentCI.AttrValues.push_back(Attr.Value);
272 const HTMLEndTagComment *C) {
273 CurrentCI.Name = C->getTagName();
274 CurrentCI.SelfClosing =
true;
278 const BlockCommandComment *C) {
279 CurrentCI.Name = getCommandName(C->getCommandID());
280 for (
unsigned I = 0, E = C->getNumArgs(); I < E; ++I)
281 CurrentCI.Args.push_back(C->getArgText(I));
285 const ParamCommandComment *C) {
286 CurrentCI.Direction =
287 ParamCommandComment::getDirectionAsString(C->getDirection());
288 CurrentCI.Explicit = C->isDirectionExplicit();
289 if (C->hasParamName())
290 CurrentCI.ParamName = C->getParamNameAsWritten();
294 const TParamCommandComment *C) {
295 if (C->hasParamName())
296 CurrentCI.ParamName = C->getParamNameAsWritten();
300 const VerbatimBlockComment *C) {
301 CurrentCI.Name = getCommandName(C->getCommandID());
302 CurrentCI.CloseName = C->getCloseName();
306 const VerbatimBlockLineComment *C) {
307 if (!isWhitespaceOnly(C->getText()))
308 CurrentCI.Text = C->getText();
312 const VerbatimLineComment *C) {
313 if (!isWhitespaceOnly(C->getText()))
314 CurrentCI.Text = C->getText();
317bool ClangDocCommentVisitor::isWhitespaceOnly(llvm::StringRef S)
const {
318 return llvm::all_of(S, isspace);
321std::string ClangDocCommentVisitor::getCommandName(
unsigned CommandID)
const {
322 const CommandInfo *
Info = CommandTraits::getBuiltinCommandInfo(CommandID);
326 return "<not a builtin command>";
332 return Lexer::getSourceText(CharSourceRange::getTokenRange(R),
333 D->getASTContext().getSourceManager(),
334 D->getASTContext().getLangOpts())
338template <
typename T>
static std::string
serialize(T &I) {
339 SmallString<2048> Buffer;
340 llvm::BitstreamWriter Stream(Buffer);
343 return Buffer.str().str();
365 llvm_unreachable(
"unhandled enumerator");
374 llvm::SmallString<128> USR;
375 if (index::generateUSRForDecl(D, USR))
381 if (
const TagDecl *D = T->getAsTagDecl())
382 return D->getDefinition();
387 if (
const RecordDecl *D = T->getAsRecordDecl())
388 return D->getDefinition();
393 const PrintingPolicy &Policy) {
402 if (isa<EnumDecl>(TD)) {
404 }
else if (isa<RecordDecl>(TD)) {
417static bool isPublic(
const clang::AccessSpecifier AS,
418 const clang::Linkage Link) {
419 if (AS == clang::AccessSpecifier::AS_private)
421 if ((Link == clang::Linkage::Module) || (Link == clang::Linkage::External))
427 const NamedDecl *D) {
428 bool IsAnonymousNamespace =
false;
429 if (
const auto *N = dyn_cast<NamespaceDecl>(D))
430 IsAnonymousNamespace = N->isAnonymousNamespace();
432 (!IsInAnonymousNamespace && !IsAnonymousNamespace &&
433 isPublic(D->getAccessUnsafe(), D->getLinkageInternal()));
487template <
typename ChildType>
489 if (Child.Namespace.empty()) {
491 auto ParentNS = std::make_unique<NamespaceInfo>();
492 InsertChild(ParentNS->Children, std::forward<ChildType>(Child));
496 switch (Child.Namespace[0].RefType) {
498 auto ParentNS = std::make_unique<NamespaceInfo>();
499 ParentNS->USR = Child.Namespace[0].USR;
500 InsertChild(ParentNS->Children, std::forward<ChildType>(Child));
504 auto ParentRec = std::make_unique<RecordInfo>();
505 ParentRec->USR = Child.Namespace[0].USR;
506 InsertChild(ParentRec->Children, std::forward<ChildType>(Child));
518 llvm_unreachable(
"Invalid reference type for parent namespace");
537 AccessSpecifier SecondAS) {
538 if (FirstAS == AccessSpecifier::AS_none ||
539 SecondAS == AccessSpecifier::AS_none)
540 return AccessSpecifier::AS_none;
541 if (FirstAS == AccessSpecifier::AS_private ||
542 SecondAS == AccessSpecifier::AS_private)
543 return AccessSpecifier::AS_private;
544 if (FirstAS == AccessSpecifier::AS_protected ||
545 SecondAS == AccessSpecifier::AS_protected)
546 return AccessSpecifier::AS_protected;
547 return AccessSpecifier::AS_public;
553 AccessSpecifier Access = AccessSpecifier::AS_public) {
554 for (
const FieldDecl *F : D->fields()) {
559 const auto *CxxRD = dyn_cast<CXXRecordDecl>(D);
562 for (Decl *CxxDecl : CxxRD->decls()) {
563 auto *VD = dyn_cast<VarDecl>(CxxDecl);
568 if (VD->isStaticDataMember())
574 for (
const EnumConstantDecl *E : D->enumerators()) {
575 std::string ValueExpr;
576 if (
const Expr *InitExpr = E->getInitExpr())
578 SmallString<16> ValueStr;
579 E->getInitVal().toString(ValueStr);
580 I.
Members.emplace_back(E->getNameAsString(), ValueStr.str(), ValueExpr);
581 ASTContext &Context = E->getASTContext();
582 if (RawComment *Comment =
583 E->getASTContext().getRawCommentForDeclNoCache(E)) {
584 Comment->setAttached();
585 if (comments::FullComment *Fc = Comment->parse(Context,
nullptr, E)) {
595 auto &LO = D->getLangOpts();
596 for (
const ParmVarDecl *P : D->parameters()) {
607 if (!D->isThisDeclarationADefinition())
610 for (
const CXXBaseSpecifier &B : D->bases()) {
613 if (
const auto *Ty = B.getType()->getAs<TemplateSpecializationType>()) {
614 const TemplateDecl *D = Ty->getTemplateName().getAsTemplateDecl();
624 for (
const CXXBaseSpecifier &B : D->vbases()) {
637 const T *D,
bool &IsInAnonymousNamespace) {
638 const DeclContext *DC = D->getDeclContext();
640 if (
const auto *N = dyn_cast<NamespaceDecl>(DC)) {
641 std::string Namespace;
642 if (N->isAnonymousNamespace()) {
643 Namespace =
"@nonymous_namespace";
644 IsInAnonymousNamespace =
true;
646 Namespace = N->getNameAsString();
649 N->getQualifiedNameAsString());
650 }
else if (
const auto *N = dyn_cast<RecordDecl>(DC))
651 Namespaces.emplace_back(
getUSRForDecl(N), N->getNameAsString(),
653 N->getQualifiedNameAsString());
654 else if (
const auto *N = dyn_cast<FunctionDecl>(DC))
655 Namespaces.emplace_back(
getUSRForDecl(N), N->getNameAsString(),
657 N->getQualifiedNameAsString());
658 else if (
const auto *N = dyn_cast<EnumDecl>(DC))
659 Namespaces.emplace_back(
getUSRForDecl(N), N->getNameAsString(),
661 }
while ((DC = DC->getParent()));
666 if ((Namespaces.empty() && isa<RecordDecl>(D)) ||
668 Namespaces.emplace_back(
SymbolID(),
"GlobalNamespace",
674 const clang::Decl *D) {
675 if (
const TemplateParameterList *ParamList =
676 D->getDescribedTemplateParams()) {
680 for (
const NamedDecl *ND : *ParamList) {
688 const TemplateArgument &Arg) {
692 llvm::raw_string_ostream Stream(Str);
693 Arg.print(PrintingPolicy(D->getLangOpts()), Stream,
false);
699 bool &IsInAnonymousNamespace) {
701 if (
auto ConversionDecl = dyn_cast_or_null<CXXConversionDecl>(D);
702 ConversionDecl && ConversionDecl->getConversionType()
704 ->isTemplateTypeParmType())
705 I.
Name =
"operator " + ConversionDecl->getConversionType().getAsString();
707 I.
Name = D->getNameAsString();
717 Location Loc,
bool &IsInAnonymousNamespace) {
719 if (D->isThisDeclarationADefinition())
722 I.
Loc.emplace_back(Loc);
724 auto *Mangler = ItaniumMangleContext::create(
725 D->getASTContext(), D->getASTContext().getDiagnostics());
726 std::string MangledName;
727 llvm::raw_string_ostream MangledStream(MangledName);
728 if (
auto *CXXD = dyn_cast<CXXRecordDecl>(D))
729 Mangler->mangleCXXVTable(CXXD, MangledStream);
731 MangledStream << D->getNameAsString();
734 if (MangledName.size() > 250) {
735 auto SymbolID = llvm::toStringRef(llvm::toHex(I.
USR)).str();
744 std::vector<ConstraintInfo> &ConstraintInfos) {
745 if (Constraint->getStmtClass() == Stmt::ParenExprClass) {
748 }
else if (Constraint->getStmtClass() == Stmt::BinaryOperatorClass) {
749 auto *BinaryOpExpr = dyn_cast<BinaryOperator>(Constraint);
752 }
else if (Constraint->getStmtClass() ==
753 Stmt::ConceptSpecializationExprClass) {
754 auto *Concept = dyn_cast<ConceptSpecializationExpr>(Constraint);
756 Concept->getNamedConcept()->getNameAsString());
758 ConstraintInfos.push_back(CI);
763 if (!D || !D->hasAssociatedConstraints())
766 SmallVector<AssociatedConstraint> AssociatedConstraints;
767 D->getAssociatedConstraints(AssociatedConstraints);
768 for (
const auto &Constraint : AssociatedConstraints) {
773 if (
const auto *ConstraintExpr =
774 dyn_cast_or_null<ConceptSpecializationExpr>(
775 Constraint.ConstraintExpr)) {
777 ConstraintExpr->getNamedConcept()->getNameAsString());
787 const FullComment *FC,
Location Loc,
788 bool &IsInAnonymousNamespace) {
790 auto &LO = D->getLangOpts();
801 if (
const FunctionTemplateSpecializationInfo *FTSI =
802 D->getTemplateSpecializationInfo()) {
805 I.
Template->Specialization.emplace();
806 auto &Specialization = *I.
Template->Specialization;
808 Specialization.SpecializationOf =
getUSRForDecl(FTSI->getTemplate());
811 if (FTSI->TemplateArguments) {
812 for (
const TemplateArgument &Arg : FTSI->TemplateArguments->asArray()) {
820 assert(D &&
"Expect non-null FieldDecl in populateMemberTypeInfo");
822 ASTContext &Context = D->getASTContext();
825 RawComment *Comment = Context.getRawCommentForDeclNoCache(D);
829 Comment->setAttached();
830 if (comments::FullComment *Fc = Comment->parse(Context,
nullptr, D)) {
837 const DeclaratorDecl *D,
bool IsStatic) {
842 D->getNameAsString(),
850 AccessSpecifier ParentAccess = AccessSpecifier::AS_public) {
852 if (!D->isThisDeclarationADefinition())
854 for (
const CXXBaseSpecifier &B : D->bases()) {
855 if (
const auto *Base = B.getType()->getAsCXXRecordDecl()) {
856 if (Base->isCompleteDefinition()) {
863 if (
const auto *Ty = B.getType()->getAs<TemplateSpecializationType>()) {
864 const TemplateDecl *D = Ty->getTemplateName().getAsTemplateDecl();
866 BI.Name = B.getType().getAsString();
869 BI.Name = Base->getNameAsString();
872 for (
const auto &Decl : Base->decls())
873 if (
const auto *
MD = dyn_cast<CXXMethodDecl>(Decl)) {
875 if (
MD->getAccessUnsafe() == AccessSpecifier::AS_private ||
876 !
MD->isUserProvided())
884 bool IsInAnonymousNamespace;
886 IsInAnonymousNamespace);
889 BI.Children.Functions.emplace_back(std::move(FI));
891 I.
Bases.emplace_back(std::move(BI));
896 I.
Bases.back().Access);
902std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
905 auto NSI = std::make_unique<NamespaceInfo>();
906 bool IsInAnonymousNamespace =
false;
911 NSI->Name = D->isAnonymousNamespace()
912 ? llvm::SmallString<16>(
"@nonymous_namespace")
915 if (NSI->Namespace.empty() && NSI->USR ==
SymbolID())
916 return {std::unique_ptr<Info>{std::move(NSI)},
nullptr};
924 if (!D->hasDefinition() || !D->hasFriends())
927 for (
const FriendDecl *FD : D->friends()) {
928 if (FD->isUnsupportedFriend())
932 const auto *ActualDecl = FD->getFriendDecl();
934 const auto *FriendTypeInfo = FD->getFriendType();
937 ActualDecl = FriendTypeInfo->getType()->getAsCXXRecordDecl();
944 if (
const auto *ActualTD = dyn_cast_or_null<TemplateDecl>(ActualDecl)) {
945 if (isa<RecordDecl>(ActualTD->getTemplatedDecl()))
948 for (
const auto *Param : ActualTD->getTemplateParameters()->asArray())
951 ActualDecl = ActualTD->getTemplatedDecl();
954 if (
auto *
FuncDecl = dyn_cast_or_null<FunctionDecl>(ActualDecl)) {
968 RI.
Friends.push_back(std::move(F));
972std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
976 auto RI = std::make_unique<RecordInfo>();
977 bool IsInAnonymousNamespace =
false;
983 RI->TagType = D->getTagKind();
986 if (
const auto *C = dyn_cast<CXXRecordDecl>(D)) {
987 if (
const TypedefNameDecl *TD = C->getTypedefNameForAnonDecl()) {
988 RI->Name = TD->getNameAsString();
989 RI->IsTypeDef =
true;
1003 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1005 RI->Template.emplace();
1006 RI->Template->Specialization.emplace();
1007 auto &Specialization = *RI->Template->Specialization;
1010 auto SpecOf = CTSD->getSpecializedTemplateOrPartial();
1011 if (
auto *SpecTD = dyn_cast<ClassTemplateDecl *>(SpecOf))
1013 else if (
auto *SpecTD =
1014 dyn_cast<ClassTemplatePartialSpecializationDecl *>(SpecOf))
1022 if (
const ClassTemplatePartialSpecializationDecl *CTPSD =
1023 dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) {
1024 if (
const ASTTemplateArgumentListInfo *AsWritten =
1025 CTPSD->getTemplateArgsAsWritten()) {
1026 for (
unsigned Idx = 0; Idx < AsWritten->getNumTemplateArgs(); Idx++) {
1027 Specialization.Params.emplace_back(
1032 for (
const TemplateArgument &Arg : CTSD->getTemplateArgs().asArray()) {
1041 return {std::move(RI), std::move(Parent)};
1044std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
1048 bool IsInAnonymousNamespace =
false;
1050 Func.
Access = clang::AccessSpecifier::AS_none;
1058std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
1062 bool IsInAnonymousNamespace =
false;
1070 const NamedDecl *Parent =
nullptr;
1071 if (
const auto *SD =
1072 dyn_cast<ClassTemplateSpecializationDecl>(D->getParent()))
1073 Parent = SD->getSpecializedTemplate();
1075 Parent = D->getParent();
1080 Parent->getQualifiedNameAsString()};
1081 Func.
Access = D->getAccess();
1088 assert(D &&
"Invalid Decl when extracting comment");
1089 ASTContext &Context = D->getASTContext();
1090 RawComment *Comment = Context.getRawCommentForDeclNoCache(D);
1094 Comment->setAttached();
1095 if (comments::FullComment *Fc = Comment->parse(Context,
nullptr, D)) {
1101std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
1105 bool IsInAnonymousNamespace =
false;
1112 auto &LO = D->getLangOpts();
1115 if (
Info.Underlying.Type.
Name.empty()) {
1121 Info.IsUsing =
false;
1130std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
1134 bool IsInAnonymousNamespace =
false;
1140 const LangOptions &LO = D->getLangOpts();
1143 Info.IsUsing =
true;
1151std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
1155 bool IsInAnonymousNamespace =
false;
1161 Enum.Scoped = D->isScoped();
1163 auto Name = D->getIntegerType().getAsString();
1164 Enum.BaseType =
TypeInfo(Name, Name);
1172std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
1177 bool IsInAnonymousNamespace =
false;
1179 Concept.IsType = D->isTypeConcept();
1180 Concept.DefLoc = Loc;
1181 Concept.ConstraintExpression = exprToString(D->getConstraintExpr());
1183 if (
auto *ConceptParams = D->getTemplateParameters()) {
1184 for (
const auto *Param : ConceptParams->asArray()) {
1185 Concept.Template.Params.emplace_back(
1196std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
1200 bool IsInAnonymousNamespace =
false;
1205 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 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[]