12#include "clang/AST/Attr.h"
13#include "clang/AST/Comment.h"
14#include "clang/AST/CommentVisitor.h"
15#include "clang/AST/DeclFriend.h"
16#include "clang/AST/ExprConcepts.h"
17#include "clang/AST/Mangle.h"
18#include "clang/Index/USRGeneration.h"
19#include "clang/Lex/Lexer.h"
20#include "llvm/ADT/StringExtras.h"
21#include "llvm/Support/SHA1.h"
23using clang::comments::FullComment;
30static SmallString<16> exprToString(
const clang::Expr *E) {
31 clang::LangOptions Opts;
32 clang::PrintingPolicy Policy(Opts);
33 SmallString<16> Result;
34 llvm::raw_svector_ostream OS(Result);
35 E->printPretty(OS,
nullptr, Policy);
41 return llvm::SHA1::hash(arrayRefFromStringRef(USR));
47 const T *D,
bool &IsAnonymousNamespace);
51 const DeclaratorDecl *D,
52 bool IsStatic =
false);
55 llvm::raw_ostream &Stream) {
56 Stream <<
"template <";
58 for (
unsigned i = 0; i < TemplateParams->size(); ++i) {
62 const NamedDecl *Param = TemplateParams->getParam(i);
63 if (
const auto *TTP = llvm::dyn_cast<TemplateTypeParmDecl>(Param)) {
64 if (TTP->wasDeclaredWithTypename())
68 if (TTP->isParameterPack())
70 Stream <<
" " << TTP->getNameAsString();
75 if (TTP->hasTypeConstraint()) {
77 TTP->getTypeConstraint()->print(
78 Stream, TTP->getASTContext().getPrintingPolicy());
80 }
else if (
const auto *NTTP =
81 llvm::dyn_cast<NonTypeTemplateParmDecl>(Param)) {
82 NTTP->getType().print(Stream, NTTP->getASTContext().getPrintingPolicy());
83 if (NTTP->isParameterPack())
85 Stream <<
" " << NTTP->getNameAsString();
86 }
else if (
const auto *TTPD =
87 llvm::dyn_cast<TemplateTemplateParmDecl>(Param)) {
88 Stream <<
"template <";
90 Stream <<
"> class " << TTPD->getNameAsString();
99static llvm::SmallString<256>
101 llvm::SmallString<256> Result;
102 llvm::raw_svector_ostream Stream(Result);
103 const ASTContext &Ctx =
FuncDecl->getASTContext();
104 const auto *Method = llvm::dyn_cast<CXXMethodDecl>(
FuncDecl);
106 if (
const auto *TmplDecl =
FuncDecl->getDescribedTemplate())
110 if (Method && Method->isVirtual())
111 Stream <<
"virtual ";
114 FuncDecl->getReturnType().print(Stream, Ctx.getPrintingPolicy());
117 Stream <<
" " <<
FuncDecl->getNameAsString() <<
"(";
120 for (
unsigned I = 0; I <
FuncDecl->getNumParams(); ++I) {
123 const ParmVarDecl *ParamDecl =
FuncDecl->getParamDecl(I);
124 QualType ParamType = ParamDecl->getType();
125 ParamType.print(Stream, Ctx.getPrintingPolicy());
128 if (!ParamDecl->getName().empty())
129 Stream <<
" " << ParamDecl->getNameAsString();
132 if (ParamDecl->hasDefaultArg() &&
133 !ParamDecl->hasUninstantiatedDefaultArg()) {
134 if (
const Expr *DefaultArg = ParamDecl->getDefaultArg()) {
136 DefaultArg->printPretty(Stream,
nullptr, Ctx.getPrintingPolicy());
152 if (Method->isDeleted())
153 Stream <<
" = delete";
154 if (Method->size_overridden_methods())
155 Stream <<
" override";
156 if (Method->hasAttr<clang::FinalAttr>())
158 if (Method->isConst())
160 if (Method->isPureVirtual())
164 if (
auto ExceptionSpecType =
FuncDecl->getExceptionSpecType())
165 Stream <<
" " << ExceptionSpecType;
171 llvm::SmallString<16> Result;
172 llvm::raw_svector_ostream Stream(Result);
173 const ASTContext &Ctx = Alias->getASTContext();
174 if (
const auto *TmplDecl = Alias->getDescribedTemplate())
176 Stream <<
"using " << Alias->getNameAsString() <<
" = ";
177 QualType Q = Alias->getUnderlyingType();
178 Q.print(Stream, Ctx.getPrintingPolicy());
196static llvm::SmallString<128>
198 llvm::SmallString<128> Path;
199 for (
auto R = Namespaces.rbegin(), E = Namespaces.rend(); R != E; ++R)
200 llvm::sys::path::append(Path, R->Name);
205 llvm::SmallVector<Reference, 4> Namespaces;
233 std::string getCommandName(
unsigned CommandID)
const;
234 bool isWhitespaceOnly(StringRef S)
const;
242 for (comments::Comment *Child :
243 llvm::make_range(C->child_begin(), C->child_end())) {
244 CurrentCI.Children.emplace_back(std::make_unique<CommentInfo>());
251 if (!isWhitespaceOnly(C->getText()))
252 CurrentCI.Text = C->getText();
256 const InlineCommandComment *C) {
257 CurrentCI.Name = getCommandName(C->getCommandID());
258 for (
unsigned I = 0, E = C->getNumArgs(); I != E; ++I)
259 CurrentCI.Args.push_back(C->getArgText(I));
263 const HTMLStartTagComment *C) {
264 CurrentCI.Name = C->getTagName();
265 CurrentCI.SelfClosing = C->isSelfClosing();
266 for (
unsigned I = 0, E = C->getNumAttrs(); I < E; ++I) {
267 const HTMLStartTagComment::Attribute &Attr = C->getAttr(I);
268 CurrentCI.AttrKeys.push_back(Attr.Name);
269 CurrentCI.AttrValues.push_back(Attr.Value);
274 const HTMLEndTagComment *C) {
275 CurrentCI.Name = C->getTagName();
276 CurrentCI.SelfClosing =
true;
280 const BlockCommandComment *C) {
281 CurrentCI.Name = getCommandName(C->getCommandID());
282 for (
unsigned I = 0, E = C->getNumArgs(); I < E; ++I)
283 CurrentCI.Args.push_back(C->getArgText(I));
287 const ParamCommandComment *C) {
288 CurrentCI.Direction =
289 ParamCommandComment::getDirectionAsString(C->getDirection());
290 CurrentCI.Explicit = C->isDirectionExplicit();
291 if (C->hasParamName())
292 CurrentCI.ParamName = C->getParamNameAsWritten();
296 const TParamCommandComment *C) {
297 if (C->hasParamName())
298 CurrentCI.ParamName = C->getParamNameAsWritten();
302 const VerbatimBlockComment *C) {
303 CurrentCI.Name = getCommandName(C->getCommandID());
304 CurrentCI.CloseName = C->getCloseName();
308 const VerbatimBlockLineComment *C) {
309 if (!isWhitespaceOnly(C->getText()))
310 CurrentCI.Text = C->getText();
314 const VerbatimLineComment *C) {
315 if (!isWhitespaceOnly(C->getText()))
316 CurrentCI.Text = C->getText();
319bool ClangDocCommentVisitor::isWhitespaceOnly(llvm::StringRef S)
const {
320 return llvm::all_of(S, isspace);
323std::string ClangDocCommentVisitor::getCommandName(
unsigned CommandID)
const {
324 const CommandInfo *
Info = CommandTraits::getBuiltinCommandInfo(CommandID);
328 return "<not a builtin command>";
334 return Lexer::getSourceText(CharSourceRange::getTokenRange(R),
335 D->getASTContext().getSourceManager(),
336 D->getASTContext().getLangOpts())
341static std::string
serialize(T &I, DiagnosticsEngine &Diags) {
342 SmallString<2048> Buffer;
343 llvm::BitstreamWriter Stream(Buffer);
346 return Buffer.str().str();
349std::string
serialize(std::unique_ptr<Info> &I, DiagnosticsEngine &Diags) {
368 llvm_unreachable(
"unhandled enumerator");
377 llvm::SmallString<128> USR;
378 if (index::generateUSRForDecl(D, USR))
384 if (
const TagDecl *D = T->getAsTagDecl())
385 return D->getDefinition();
390 if (
const RecordDecl *D = T->getAsRecordDecl())
391 return D->getDefinition();
396 const PrintingPolicy &Policy) {
405 if (isa<EnumDecl>(TD)) {
407 }
else if (isa<RecordDecl>(TD)) {
420static bool isPublic(
const clang::AccessSpecifier AS,
421 const clang::Linkage Link) {
422 if (AS == clang::AccessSpecifier::AS_private)
424 if ((Link == clang::Linkage::Module) || (Link == clang::Linkage::External))
430 const NamedDecl *D) {
431 bool IsAnonymousNamespace =
false;
432 if (
const auto *N = dyn_cast<NamespaceDecl>(D))
433 IsAnonymousNamespace = N->isAnonymousNamespace();
435 (!IsInAnonymousNamespace && !IsAnonymousNamespace &&
436 isPublic(D->getAccessUnsafe(), D->getLinkageInternal()));
490template <
typename ChildType>
492 if (Child.Namespace.empty()) {
494 auto ParentNS = std::make_unique<NamespaceInfo>();
495 InsertChild(ParentNS->Children, std::forward<ChildType>(Child));
499 switch (Child.Namespace[0].RefType) {
501 auto ParentNS = std::make_unique<NamespaceInfo>();
502 ParentNS->USR = Child.Namespace[0].USR;
503 InsertChild(ParentNS->Children, std::forward<ChildType>(Child));
507 auto ParentRec = std::make_unique<RecordInfo>();
508 ParentRec->USR = Child.Namespace[0].USR;
509 InsertChild(ParentRec->Children, std::forward<ChildType>(Child));
521 llvm_unreachable(
"Invalid reference type for parent namespace");
540 AccessSpecifier SecondAS) {
541 if (FirstAS == AccessSpecifier::AS_none ||
542 SecondAS == AccessSpecifier::AS_none)
543 return AccessSpecifier::AS_none;
544 if (FirstAS == AccessSpecifier::AS_private ||
545 SecondAS == AccessSpecifier::AS_private)
546 return AccessSpecifier::AS_private;
547 if (FirstAS == AccessSpecifier::AS_protected ||
548 SecondAS == AccessSpecifier::AS_protected)
549 return AccessSpecifier::AS_protected;
550 return AccessSpecifier::AS_public;
556 AccessSpecifier Access = AccessSpecifier::AS_public) {
557 for (
const FieldDecl *F : D->fields()) {
562 const auto *CxxRD = dyn_cast<CXXRecordDecl>(D);
565 for (Decl *CxxDecl : CxxRD->decls()) {
566 auto *VD = dyn_cast<VarDecl>(CxxDecl);
571 if (VD->isStaticDataMember())
577 for (
const EnumConstantDecl *E : D->enumerators()) {
578 std::string ValueExpr;
579 if (
const Expr *InitExpr = E->getInitExpr())
581 SmallString<16> ValueStr;
582 E->getInitVal().toString(ValueStr);
583 I.
Members.emplace_back(E->getNameAsString(), ValueStr.str(), ValueExpr);
584 ASTContext &Context = E->getASTContext();
585 if (RawComment *Comment =
586 E->getASTContext().getRawCommentForDeclNoCache(E)) {
587 Comment->setAttached();
588 if (comments::FullComment *Fc = Comment->parse(Context,
nullptr, E)) {
598 auto &LO = D->getLangOpts();
599 for (
const ParmVarDecl *P : D->parameters()) {
610 if (!D->isThisDeclarationADefinition())
613 for (
const CXXBaseSpecifier &B : D->bases()) {
616 if (
const auto *Ty = B.getType()->getAs<TemplateSpecializationType>()) {
617 const TemplateDecl *D = Ty->getTemplateName().getAsTemplateDecl();
627 for (
const CXXBaseSpecifier &B : D->vbases()) {
640 const T *D,
bool &IsInAnonymousNamespace) {
641 const DeclContext *DC = D->getDeclContext();
643 if (
const auto *N = dyn_cast<NamespaceDecl>(DC)) {
644 std::string Namespace;
645 if (N->isAnonymousNamespace()) {
646 Namespace =
"@nonymous_namespace";
647 IsInAnonymousNamespace =
true;
649 Namespace = N->getNameAsString();
652 N->getQualifiedNameAsString());
653 }
else if (
const auto *N = dyn_cast<RecordDecl>(DC))
654 Namespaces.emplace_back(
getUSRForDecl(N), N->getNameAsString(),
656 N->getQualifiedNameAsString());
657 else if (
const auto *N = dyn_cast<FunctionDecl>(DC))
658 Namespaces.emplace_back(
getUSRForDecl(N), N->getNameAsString(),
660 N->getQualifiedNameAsString());
661 else if (
const auto *N = dyn_cast<EnumDecl>(DC))
662 Namespaces.emplace_back(
getUSRForDecl(N), N->getNameAsString(),
664 }
while ((DC = DC->getParent()));
669 if ((Namespaces.empty() && isa<RecordDecl>(D)) ||
671 Namespaces.emplace_back(
SymbolID(),
"GlobalNamespace",
677 const clang::Decl *D) {
678 if (
const TemplateParameterList *ParamList =
679 D->getDescribedTemplateParams()) {
683 for (
const NamedDecl *ND : *ParamList) {
691 const TemplateArgument &Arg) {
695 llvm::raw_string_ostream Stream(Str);
696 Arg.print(PrintingPolicy(D->getLangOpts()), Stream,
false);
702 bool &IsInAnonymousNamespace) {
704 if (
auto ConversionDecl = dyn_cast_or_null<CXXConversionDecl>(D);
705 ConversionDecl && ConversionDecl->getConversionType()
707 ->isTemplateTypeParmType())
708 I.
Name =
"operator " + ConversionDecl->getConversionType().getAsString();
710 I.
Name = D->getNameAsString();
720 Location Loc,
bool &IsInAnonymousNamespace) {
722 if (D->isThisDeclarationADefinition())
725 I.
Loc.emplace_back(Loc);
727 auto *Mangler = ItaniumMangleContext::create(
728 D->getASTContext(), D->getASTContext().getDiagnostics());
729 std::string MangledName;
730 llvm::raw_string_ostream MangledStream(MangledName);
731 if (
auto *CXXD = dyn_cast<CXXRecordDecl>(D))
732 Mangler->mangleCXXVTable(CXXD, MangledStream);
734 MangledStream << D->getNameAsString();
737 if (MangledName.size() > 250) {
738 auto SymbolID = llvm::toStringRef(llvm::toHex(I.
USR)).str();
747 std::vector<ConstraintInfo> &ConstraintInfos) {
748 if (Constraint->getStmtClass() == Stmt::ParenExprClass) {
751 }
else if (Constraint->getStmtClass() == Stmt::BinaryOperatorClass) {
752 auto *BinaryOpExpr = dyn_cast<BinaryOperator>(Constraint);
755 }
else if (Constraint->getStmtClass() ==
756 Stmt::ConceptSpecializationExprClass) {
757 auto *Concept = dyn_cast<ConceptSpecializationExpr>(Constraint);
759 Concept->getNamedConcept()->getNameAsString());
761 ConstraintInfos.push_back(CI);
766 if (!D || !D->hasAssociatedConstraints())
769 SmallVector<AssociatedConstraint> AssociatedConstraints;
770 D->getAssociatedConstraints(AssociatedConstraints);
771 for (
const auto &Constraint : AssociatedConstraints) {
776 if (
const auto *ConstraintExpr =
777 dyn_cast_or_null<ConceptSpecializationExpr>(
778 Constraint.ConstraintExpr)) {
780 ConstraintExpr->getNamedConcept()->getNameAsString());
790 const FullComment *FC,
Location Loc,
791 bool &IsInAnonymousNamespace) {
793 auto &LO = D->getLangOpts();
804 if (
const FunctionTemplateSpecializationInfo *FTSI =
805 D->getTemplateSpecializationInfo()) {
808 I.
Template->Specialization.emplace();
809 auto &Specialization = *I.
Template->Specialization;
811 Specialization.SpecializationOf =
getUSRForDecl(FTSI->getTemplate());
814 if (FTSI->TemplateArguments) {
815 for (
const TemplateArgument &Arg : FTSI->TemplateArguments->asArray()) {
823 assert(D &&
"Expect non-null FieldDecl in populateMemberTypeInfo");
825 ASTContext &Context = D->getASTContext();
828 RawComment *Comment = Context.getRawCommentForDeclNoCache(D);
832 Comment->setAttached();
833 if (comments::FullComment *Fc = Comment->parse(Context,
nullptr, D)) {
840 const DeclaratorDecl *D,
bool IsStatic) {
845 D->getNameAsString(),
853 AccessSpecifier ParentAccess = AccessSpecifier::AS_public) {
855 if (!D->isThisDeclarationADefinition())
857 for (
const CXXBaseSpecifier &B : D->bases()) {
858 if (
const auto *Base = B.getType()->getAsCXXRecordDecl()) {
859 if (Base->isCompleteDefinition()) {
866 if (
const auto *Ty = B.getType()->getAs<TemplateSpecializationType>()) {
867 const TemplateDecl *D = Ty->getTemplateName().getAsTemplateDecl();
869 BI.Name = B.getType().getAsString();
872 BI.Name = Base->getNameAsString();
875 for (
const auto &Decl : Base->decls())
876 if (
const auto *
MD = dyn_cast<CXXMethodDecl>(Decl)) {
878 if (
MD->getAccessUnsafe() == AccessSpecifier::AS_private ||
879 !
MD->isUserProvided())
887 bool IsInAnonymousNamespace;
889 IsInAnonymousNamespace);
892 BI.Children.Functions.emplace_back(std::move(FI));
894 I.
Bases.emplace_back(std::move(BI));
899 I.
Bases.back().Access);
905std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
908 auto NSI = std::make_unique<NamespaceInfo>();
909 bool IsInAnonymousNamespace =
false;
914 NSI->Name = D->isAnonymousNamespace()
915 ? llvm::SmallString<16>(
"@nonymous_namespace")
918 if (NSI->Namespace.empty() && NSI->USR ==
SymbolID())
919 return {std::unique_ptr<Info>{std::move(NSI)},
nullptr};
927 if (!D->hasDefinition() || !D->hasFriends())
930 for (
const FriendDecl *FD : D->friends()) {
931 if (FD->isUnsupportedFriend())
935 const auto *ActualDecl = FD->getFriendDecl();
937 const auto *FriendTypeInfo = FD->getFriendType();
940 ActualDecl = FriendTypeInfo->getType()->getAsCXXRecordDecl();
947 if (
const auto *ActualTD = dyn_cast_or_null<TemplateDecl>(ActualDecl)) {
948 if (isa<RecordDecl>(ActualTD->getTemplatedDecl()))
951 for (
const auto *Param : ActualTD->getTemplateParameters()->asArray())
954 ActualDecl = ActualTD->getTemplatedDecl();
957 if (
auto *
FuncDecl = dyn_cast_or_null<FunctionDecl>(ActualDecl)) {
971 RI.
Friends.push_back(std::move(F));
975std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
979 auto RI = std::make_unique<RecordInfo>();
980 bool IsInAnonymousNamespace =
false;
986 RI->TagType = D->getTagKind();
989 if (
const auto *C = dyn_cast<CXXRecordDecl>(D)) {
990 if (
const TypedefNameDecl *TD = C->getTypedefNameForAnonDecl()) {
991 RI->Name = TD->getNameAsString();
992 RI->IsTypeDef =
true;
1006 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1008 RI->Template.emplace();
1009 RI->Template->Specialization.emplace();
1010 auto &Specialization = *RI->Template->Specialization;
1013 auto SpecOf = CTSD->getSpecializedTemplateOrPartial();
1014 if (
auto *SpecTD = dyn_cast<ClassTemplateDecl *>(SpecOf))
1016 else if (
auto *SpecTD =
1017 dyn_cast<ClassTemplatePartialSpecializationDecl *>(SpecOf))
1025 if (
const ClassTemplatePartialSpecializationDecl *CTPSD =
1026 dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) {
1027 if (
const ASTTemplateArgumentListInfo *AsWritten =
1028 CTPSD->getTemplateArgsAsWritten()) {
1029 for (
unsigned Idx = 0; Idx < AsWritten->getNumTemplateArgs(); Idx++) {
1030 Specialization.Params.emplace_back(
1035 for (
const TemplateArgument &Arg : CTSD->getTemplateArgs().asArray()) {
1044 return {std::move(RI), std::move(Parent)};
1047std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
1051 bool IsInAnonymousNamespace =
false;
1053 Func.
Access = clang::AccessSpecifier::AS_none;
1061std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
1065 bool IsInAnonymousNamespace =
false;
1073 const NamedDecl *Parent =
nullptr;
1074 if (
const auto *SD =
1075 dyn_cast<ClassTemplateSpecializationDecl>(D->getParent()))
1076 Parent = SD->getSpecializedTemplate();
1078 Parent = D->getParent();
1083 Parent->getQualifiedNameAsString()};
1084 Func.
Access = D->getAccess();
1091 assert(D &&
"Invalid Decl when extracting comment");
1092 ASTContext &Context = D->getASTContext();
1093 RawComment *Comment = Context.getRawCommentForDeclNoCache(D);
1097 Comment->setAttached();
1098 if (comments::FullComment *Fc = Comment->parse(Context,
nullptr, D)) {
1104std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
1108 bool IsInAnonymousNamespace =
false;
1115 auto &LO = D->getLangOpts();
1118 if (
Info.Underlying.Type.
Name.empty()) {
1124 Info.IsUsing =
false;
1133std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
1137 bool IsInAnonymousNamespace =
false;
1143 const LangOptions &LO = D->getLangOpts();
1146 Info.IsUsing =
true;
1154std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
1158 bool IsInAnonymousNamespace =
false;
1164 Enum.Scoped = D->isScoped();
1166 auto Name = D->getIntegerType().getAsString();
1167 Enum.BaseType =
TypeInfo(Name, Name);
1175std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
1180 bool IsInAnonymousNamespace =
false;
1182 Concept.IsType = D->isTypeConcept();
1183 Concept.DefLoc = Loc;
1184 Concept.ConstraintExpression = exprToString(D->getConstraintExpr());
1186 if (
auto *ConceptParams = D->getTemplateParameters()) {
1187 for (
const auto *Param : ConceptParams->asArray()) {
1188 Concept.Template.Params.emplace_back(
1199std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
1203 bool IsInAnonymousNamespace =
false;
1208 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 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 std::string serialize(T &I, DiagnosticsEngine &Diags)
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[]