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())
340template <
typename T>
static std::string
serialize(T &I) {
341 SmallString<2048> Buffer;
342 llvm::BitstreamWriter Stream(Buffer);
345 return Buffer.str().str();
367 llvm_unreachable(
"unhandled enumerator");
376 llvm::SmallString<128> USR;
377 if (index::generateUSRForDecl(D, USR))
383 if (
const TagDecl *D = T->getAsTagDecl())
384 return D->getDefinition();
389 if (
const RecordDecl *D = T->getAsRecordDecl())
390 return D->getDefinition();
395 const PrintingPolicy &Policy) {
404 if (isa<EnumDecl>(TD)) {
406 }
else if (isa<RecordDecl>(TD)) {
419static bool isPublic(
const clang::AccessSpecifier AS,
420 const clang::Linkage Link) {
421 if (AS == clang::AccessSpecifier::AS_private)
423 if ((Link == clang::Linkage::Module) || (Link == clang::Linkage::External))
429 const NamedDecl *D) {
430 bool IsAnonymousNamespace =
false;
431 if (
const auto *N = dyn_cast<NamespaceDecl>(D))
432 IsAnonymousNamespace = N->isAnonymousNamespace();
434 (!IsInAnonymousNamespace && !IsAnonymousNamespace &&
435 isPublic(D->getAccessUnsafe(), D->getLinkageInternal()));
489template <
typename ChildType>
491 if (Child.Namespace.empty()) {
493 auto ParentNS = std::make_unique<NamespaceInfo>();
494 InsertChild(ParentNS->Children, std::forward<ChildType>(Child));
498 switch (Child.Namespace[0].RefType) {
500 auto ParentNS = std::make_unique<NamespaceInfo>();
501 ParentNS->USR = Child.Namespace[0].USR;
502 InsertChild(ParentNS->Children, std::forward<ChildType>(Child));
506 auto ParentRec = std::make_unique<RecordInfo>();
507 ParentRec->USR = Child.Namespace[0].USR;
508 InsertChild(ParentRec->Children, std::forward<ChildType>(Child));
520 llvm_unreachable(
"Invalid reference type for parent namespace");
539 AccessSpecifier SecondAS) {
540 if (FirstAS == AccessSpecifier::AS_none ||
541 SecondAS == AccessSpecifier::AS_none)
542 return AccessSpecifier::AS_none;
543 if (FirstAS == AccessSpecifier::AS_private ||
544 SecondAS == AccessSpecifier::AS_private)
545 return AccessSpecifier::AS_private;
546 if (FirstAS == AccessSpecifier::AS_protected ||
547 SecondAS == AccessSpecifier::AS_protected)
548 return AccessSpecifier::AS_protected;
549 return AccessSpecifier::AS_public;
555 AccessSpecifier Access = AccessSpecifier::AS_public) {
556 for (
const FieldDecl *F : D->fields()) {
561 const auto *CxxRD = dyn_cast<CXXRecordDecl>(D);
564 for (Decl *CxxDecl : CxxRD->decls()) {
565 auto *VD = dyn_cast<VarDecl>(CxxDecl);
570 if (VD->isStaticDataMember())
576 for (
const EnumConstantDecl *E : D->enumerators()) {
577 std::string ValueExpr;
578 if (
const Expr *InitExpr = E->getInitExpr())
580 SmallString<16> ValueStr;
581 E->getInitVal().toString(ValueStr);
582 I.
Members.emplace_back(E->getNameAsString(), ValueStr.str(), ValueExpr);
583 ASTContext &Context = E->getASTContext();
584 if (RawComment *Comment =
585 E->getASTContext().getRawCommentForDeclNoCache(E)) {
586 Comment->setAttached();
587 if (comments::FullComment *Fc = Comment->parse(Context,
nullptr, E)) {
597 auto &LO = D->getLangOpts();
598 for (
const ParmVarDecl *P : D->parameters()) {
609 if (!D->isThisDeclarationADefinition())
612 for (
const CXXBaseSpecifier &B : D->bases()) {
615 if (
const auto *Ty = B.getType()->getAs<TemplateSpecializationType>()) {
616 const TemplateDecl *D = Ty->getTemplateName().getAsTemplateDecl();
626 for (
const CXXBaseSpecifier &B : D->vbases()) {
639 const T *D,
bool &IsInAnonymousNamespace) {
640 const DeclContext *DC = D->getDeclContext();
642 if (
const auto *N = dyn_cast<NamespaceDecl>(DC)) {
643 std::string Namespace;
644 if (N->isAnonymousNamespace()) {
645 Namespace =
"@nonymous_namespace";
646 IsInAnonymousNamespace =
true;
648 Namespace = N->getNameAsString();
651 N->getQualifiedNameAsString());
652 }
else if (
const auto *N = dyn_cast<RecordDecl>(DC))
653 Namespaces.emplace_back(
getUSRForDecl(N), N->getNameAsString(),
655 N->getQualifiedNameAsString());
656 else if (
const auto *N = dyn_cast<FunctionDecl>(DC))
657 Namespaces.emplace_back(
getUSRForDecl(N), N->getNameAsString(),
659 N->getQualifiedNameAsString());
660 else if (
const auto *N = dyn_cast<EnumDecl>(DC))
661 Namespaces.emplace_back(
getUSRForDecl(N), N->getNameAsString(),
663 }
while ((DC = DC->getParent()));
668 if ((Namespaces.empty() && isa<RecordDecl>(D)) ||
670 Namespaces.emplace_back(
SymbolID(),
"GlobalNamespace",
676 const clang::Decl *D) {
677 if (
const TemplateParameterList *ParamList =
678 D->getDescribedTemplateParams()) {
682 for (
const NamedDecl *ND : *ParamList) {
690 const TemplateArgument &Arg) {
694 llvm::raw_string_ostream Stream(Str);
695 Arg.print(PrintingPolicy(D->getLangOpts()), Stream,
false);
701 bool &IsInAnonymousNamespace) {
703 if (
auto ConversionDecl = dyn_cast_or_null<CXXConversionDecl>(D);
704 ConversionDecl && ConversionDecl->getConversionType()
706 ->isTemplateTypeParmType())
707 I.
Name =
"operator " + ConversionDecl->getConversionType().getAsString();
709 I.
Name = D->getNameAsString();
719 Location Loc,
bool &IsInAnonymousNamespace) {
721 if (D->isThisDeclarationADefinition())
724 I.
Loc.emplace_back(Loc);
726 auto *Mangler = ItaniumMangleContext::create(
727 D->getASTContext(), D->getASTContext().getDiagnostics());
728 std::string MangledName;
729 llvm::raw_string_ostream MangledStream(MangledName);
730 if (
auto *CXXD = dyn_cast<CXXRecordDecl>(D))
731 Mangler->mangleCXXVTable(CXXD, MangledStream);
733 MangledStream << D->getNameAsString();
736 if (MangledName.size() > 250) {
737 auto SymbolID = llvm::toStringRef(llvm::toHex(I.
USR)).str();
746 std::vector<ConstraintInfo> &ConstraintInfos) {
747 if (Constraint->getStmtClass() == Stmt::ParenExprClass) {
750 }
else if (Constraint->getStmtClass() == Stmt::BinaryOperatorClass) {
751 auto *BinaryOpExpr = dyn_cast<BinaryOperator>(Constraint);
754 }
else if (Constraint->getStmtClass() ==
755 Stmt::ConceptSpecializationExprClass) {
756 auto *Concept = dyn_cast<ConceptSpecializationExpr>(Constraint);
758 Concept->getNamedConcept()->getNameAsString());
760 ConstraintInfos.push_back(CI);
765 if (!D || !D->hasAssociatedConstraints())
768 SmallVector<AssociatedConstraint> AssociatedConstraints;
769 D->getAssociatedConstraints(AssociatedConstraints);
770 for (
const auto &Constraint : AssociatedConstraints) {
775 if (
const auto *ConstraintExpr =
776 dyn_cast_or_null<ConceptSpecializationExpr>(
777 Constraint.ConstraintExpr)) {
779 ConstraintExpr->getNamedConcept()->getNameAsString());
789 const FullComment *FC,
Location Loc,
790 bool &IsInAnonymousNamespace) {
792 auto &LO = D->getLangOpts();
803 if (
const FunctionTemplateSpecializationInfo *FTSI =
804 D->getTemplateSpecializationInfo()) {
807 I.
Template->Specialization.emplace();
808 auto &Specialization = *I.
Template->Specialization;
810 Specialization.SpecializationOf =
getUSRForDecl(FTSI->getTemplate());
813 if (FTSI->TemplateArguments) {
814 for (
const TemplateArgument &Arg : FTSI->TemplateArguments->asArray()) {
822 assert(D &&
"Expect non-null FieldDecl in populateMemberTypeInfo");
824 ASTContext &Context = D->getASTContext();
827 RawComment *Comment = Context.getRawCommentForDeclNoCache(D);
831 Comment->setAttached();
832 if (comments::FullComment *Fc = Comment->parse(Context,
nullptr, D)) {
839 const DeclaratorDecl *D,
bool IsStatic) {
844 D->getNameAsString(),
852 AccessSpecifier ParentAccess = AccessSpecifier::AS_public) {
854 if (!D->isThisDeclarationADefinition())
856 for (
const CXXBaseSpecifier &B : D->bases()) {
857 if (
const auto *Base = B.getType()->getAsCXXRecordDecl()) {
858 if (Base->isCompleteDefinition()) {
865 if (
const auto *Ty = B.getType()->getAs<TemplateSpecializationType>()) {
866 const TemplateDecl *D = Ty->getTemplateName().getAsTemplateDecl();
868 BI.Name = B.getType().getAsString();
871 BI.Name = Base->getNameAsString();
874 for (
const auto &Decl : Base->decls())
875 if (
const auto *
MD = dyn_cast<CXXMethodDecl>(Decl)) {
877 if (
MD->getAccessUnsafe() == AccessSpecifier::AS_private ||
878 !
MD->isUserProvided())
886 bool IsInAnonymousNamespace;
888 IsInAnonymousNamespace);
891 BI.Children.Functions.emplace_back(std::move(FI));
893 I.
Bases.emplace_back(std::move(BI));
898 I.
Bases.back().Access);
904std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
907 auto NSI = std::make_unique<NamespaceInfo>();
908 bool IsInAnonymousNamespace =
false;
913 NSI->Name = D->isAnonymousNamespace()
914 ? llvm::SmallString<16>(
"@nonymous_namespace")
917 if (NSI->Namespace.empty() && NSI->USR ==
SymbolID())
918 return {std::unique_ptr<Info>{std::move(NSI)},
nullptr};
926 if (!D->hasDefinition() || !D->hasFriends())
929 for (
const FriendDecl *FD : D->friends()) {
930 if (FD->isUnsupportedFriend())
934 const auto *ActualDecl = FD->getFriendDecl();
936 const auto *FriendTypeInfo = FD->getFriendType();
939 ActualDecl = FriendTypeInfo->getType()->getAsCXXRecordDecl();
946 if (
const auto *ActualTD = dyn_cast_or_null<TemplateDecl>(ActualDecl)) {
947 if (isa<RecordDecl>(ActualTD->getTemplatedDecl()))
950 for (
const auto *Param : ActualTD->getTemplateParameters()->asArray())
953 ActualDecl = ActualTD->getTemplatedDecl();
956 if (
auto *
FuncDecl = dyn_cast_or_null<FunctionDecl>(ActualDecl)) {
970 RI.
Friends.push_back(std::move(F));
974std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
978 auto RI = std::make_unique<RecordInfo>();
979 bool IsInAnonymousNamespace =
false;
985 RI->TagType = D->getTagKind();
988 if (
const auto *C = dyn_cast<CXXRecordDecl>(D)) {
989 if (
const TypedefNameDecl *TD = C->getTypedefNameForAnonDecl()) {
990 RI->Name = TD->getNameAsString();
991 RI->IsTypeDef =
true;
1005 if (
auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1007 RI->Template.emplace();
1008 RI->Template->Specialization.emplace();
1009 auto &Specialization = *RI->Template->Specialization;
1012 auto SpecOf = CTSD->getSpecializedTemplateOrPartial();
1013 if (
auto *SpecTD = dyn_cast<ClassTemplateDecl *>(SpecOf))
1015 else if (
auto *SpecTD =
1016 dyn_cast<ClassTemplatePartialSpecializationDecl *>(SpecOf))
1024 if (
const ClassTemplatePartialSpecializationDecl *CTPSD =
1025 dyn_cast<ClassTemplatePartialSpecializationDecl>(D)) {
1026 if (
const ASTTemplateArgumentListInfo *AsWritten =
1027 CTPSD->getTemplateArgsAsWritten()) {
1028 for (
unsigned Idx = 0; Idx < AsWritten->getNumTemplateArgs(); Idx++) {
1029 Specialization.Params.emplace_back(
1034 for (
const TemplateArgument &Arg : CTSD->getTemplateArgs().asArray()) {
1043 return {std::move(RI), std::move(Parent)};
1046std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
1050 bool IsInAnonymousNamespace =
false;
1052 Func.
Access = clang::AccessSpecifier::AS_none;
1060std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
1064 bool IsInAnonymousNamespace =
false;
1072 const NamedDecl *Parent =
nullptr;
1073 if (
const auto *SD =
1074 dyn_cast<ClassTemplateSpecializationDecl>(D->getParent()))
1075 Parent = SD->getSpecializedTemplate();
1077 Parent = D->getParent();
1082 Parent->getQualifiedNameAsString()};
1083 Func.
Access = D->getAccess();
1090 assert(D &&
"Invalid Decl when extracting comment");
1091 ASTContext &Context = D->getASTContext();
1092 RawComment *Comment = Context.getRawCommentForDeclNoCache(D);
1096 Comment->setAttached();
1097 if (comments::FullComment *Fc = Comment->parse(Context,
nullptr, D)) {
1103std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
1107 bool IsInAnonymousNamespace =
false;
1114 auto &LO = D->getLangOpts();
1117 if (
Info.Underlying.Type.
Name.empty()) {
1123 Info.IsUsing =
false;
1132std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
1136 bool IsInAnonymousNamespace =
false;
1142 const LangOptions &LO = D->getLangOpts();
1145 Info.IsUsing =
true;
1153std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
1157 bool IsInAnonymousNamespace =
false;
1163 Enum.Scoped = D->isScoped();
1165 auto Name = D->getIntegerType().getAsString();
1166 Enum.BaseType =
TypeInfo(Name, Name);
1174std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
1179 bool IsInAnonymousNamespace =
false;
1181 Concept.IsType = D->isTypeConcept();
1182 Concept.DefLoc = Loc;
1183 Concept.ConstraintExpression = exprToString(D->getConstraintExpr());
1185 if (
auto *ConceptParams = D->getTemplateParameters()) {
1186 for (
const auto *Param : ConceptParams->asArray()) {
1187 Concept.Template.Params.emplace_back(
1198std::pair<std::unique_ptr<Info>, std::unique_ptr<Info>>
1202 bool IsInAnonymousNamespace =
false;
1207 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[]