23#include "llvm/ADT/StringMap.h"
24#include "llvm/Support/Error.h"
25#include "llvm/Support/Path.h"
31 static const llvm::StringMap<CommentKind> KindMap = {
46 auto It = KindMap.find(KindStr);
47 if (It != KindMap.end()) {
58 return "ParagraphComment";
62 return "InlineCommandComment";
64 return "HTMLStartTagComment";
66 return "HTMLEndTagComment";
68 return "BlockCommandComment";
70 return "ParamCommandComment";
72 return "TParamCommandComment";
74 return "VerbatimBlockComment";
76 return "VerbatimBlockLineComment";
78 return "VerbatimLineComment";
82 llvm_unreachable(
"Unhandled CommentKind");
90llvm::Expected<std::unique_ptr<Info>>
91reduce(std::vector<std::unique_ptr<Info>> &Values) {
92 if (Values.empty() || !Values[0])
93 return llvm::createStringError(llvm::inconvertibleErrorCode(),
94 "no value to reduce");
95 std::unique_ptr<Info> Merged = std::make_unique<T>(Values[0]->USR);
96 T *Tmp =
static_cast<T *
>(Merged.get());
97 for (
auto &I : Values)
98 Tmp->merge(std::move(*
static_cast<T *
>(I.get())));
99 return std::move(Merged);
105int getChildIndexIfExists(std::vector<T> &Children, T &ChildToMerge) {
106 for (
unsigned long I = 0; I < Children.size(); I++) {
107 if (ChildToMerge.USR == Children[I].USR)
114void reduceChildren(std::vector<T> &Children,
115 std::vector<T> &&ChildrenToMerge) {
116 for (
auto &ChildToMerge : ChildrenToMerge) {
117 int MergeIdx = getChildIndexIfExists(Children, ChildToMerge);
118 if (MergeIdx == -1) {
119 Children.push_back(std::move(ChildToMerge));
122 Children[MergeIdx].merge(std::move(ChildToMerge));
129llvm::Expected<std::unique_ptr<Info>>
131 if (Values.empty() || !Values[0])
132 return llvm::createStringError(llvm::inconvertibleErrorCode(),
133 "no info values to merge");
135 switch (Values[0]->IT) {
137 return reduce<NamespaceInfo>(Values);
139 return reduce<RecordInfo>(Values);
141 return reduce<EnumInfo>(Values);
143 return reduce<FunctionInfo>(Values);
145 return reduce<TypedefInfo>(Values);
147 return reduce<ConceptInfo>(Values);
149 return reduce<VarInfo>(Values);
151 return reduce<FriendInfo>(Values);
153 return llvm::createStringError(llvm::inconvertibleErrorCode(),
154 "unexpected info type");
156 llvm_unreachable(
"unhandled enumerator");
171 llvm::deref<std::equal_to<>>{});
182 if (FirstCI < SecondCI)
185 if (FirstCI == SecondCI) {
186 return std::lexicographical_compare(
188 Other.
Children.end(), llvm::deref<std::less<>>());
194static llvm::SmallString<64>
196 const StringRef &Name,
const StringRef &CurrentPath) {
197 llvm::SmallString<64> FilePath;
199 if (CurrentPath != Path) {
201 for (llvm::sys::path::const_iterator I =
202 llvm::sys::path::begin(CurrentPath);
203 I != llvm::sys::path::end(CurrentPath); ++I)
204 llvm::sys::path::append(FilePath,
"..");
205 llvm::sys::path::append(FilePath, Path);
211 llvm::sys::path::append(FilePath, Name);
213 return llvm::sys::path::relative_path(FilePath);
223 return llvm::SmallString<16>(
"index");
235 return llvm::SmallString<16>(
"index");
260 Ref.merge(std::move(Other.Ref));
274 std::move(Other.Description.begin(), Other.Description.end(),
288 DefLoc = std::move(Other.DefLoc);
290 std::move(Other.Loc.begin(), Other.Loc.end(), std::back_inserter(
Loc));
292 auto *Last = llvm::unique(
Loc);
293 Loc.erase(Last,
Loc.end());
305 reduceChildren(
Children.Namespaces, std::move(Other.Children.Namespaces));
306 reduceChildren(
Children.Records, std::move(Other.Children.Records));
307 reduceChildren(
Children.Functions, std::move(Other.Children.Functions));
308 reduceChildren(
Children.Enums, std::move(Other.Children.Enums));
309 reduceChildren(
Children.Typedefs, std::move(Other.Children.Typedefs));
310 reduceChildren(
Children.Concepts, std::move(Other.Children.Concepts));
311 reduceChildren(
Children.Variables, std::move(Other.Children.Variables));
320 if (!llvm::to_underlying(
TagType))
324 Members = std::move(Other.Members);
326 Bases = std::move(Other.Bases);
328 Parents = std::move(Other.Parents);
332 Friends = std::move(Other.Friends);
334 reduceChildren(
Children.Records, std::move(Other.Children.Records));
335 reduceChildren(
Children.Functions, std::move(Other.Children.Functions));
336 reduceChildren(
Children.Enums, std::move(Other.Children.Enums));
337 reduceChildren(
Children.Typedefs, std::move(Other.Children.Typedefs));
338 SymbolInfo::merge(std::move(Other));
348 Members = std::move(Other.Members);
349 SymbolInfo::merge(std::move(Other));
361 Parent = std::move(Other.Parent);
363 Params = std::move(Other.Params);
364 SymbolInfo::merge(std::move(Other));
375 SymbolInfo::merge(std::move(Other));
385 Template.Constraints = std::move(Other.Template.Constraints);
387 Template.Params = std::move(Other.Template.Params);
388 SymbolInfo::merge(std::move(Other));
396 Type = std::move(Other.Type);
397 SymbolInfo::merge(std::move(Other));
419 return llvm::SmallString<16>(
"@GlobalNamespace");
423 return llvm::SmallString<16>(
"GlobalNamespace");
425 return llvm::SmallString<16>(
"@nonymous_record_" +
426 toHex(llvm::toStringRef(
USR)));
428 return llvm::SmallString<16>(
"@nonymous_enum_" +
429 toHex(llvm::toStringRef(
USR)));
431 return llvm::SmallString<16>(
"@nonymous_typedef_" +
432 toHex(llvm::toStringRef(
USR)));
434 return llvm::SmallString<16>(
"@nonymous_function_" +
435 toHex(llvm::toStringRef(
USR)));
437 return llvm::SmallString<16>(
"@nonymous_concept_" +
438 toHex(llvm::toStringRef(
USR)));
440 return llvm::SmallString<16>(
"@nonymous_variable_" +
441 toHex(llvm::toStringRef(
USR)));
443 return llvm::SmallString<16>(
"@nonymous_friend_" +
444 toHex(llvm::toStringRef(
USR)));
446 return llvm::SmallString<16>(
"@nonymous_" + toHex(llvm::toStringRef(
USR)));
448 llvm_unreachable(
"Invalid InfoType.");
449 return llvm::SmallString<16>(
"");
455 for (
unsigned I = 0; I <
Name.size() && I < Other.
Name.size(); ++I) {
457 int D = tolower(
Name[I]) - tolower(Other.
Name[I]);
466 if (
Name.size() == Other.
Name.size())
469 return Name.size() < Other.
Name.size();
488 llvm::SmallString<128> SourceRootDir(
SourceRoot);
491 llvm::sys::fs::current_path(SourceRootDir);
492 this->SourceRoot = std::string(SourceRootDir);
497 this->RepositoryUrl->insert(0,
"https://");
llvm::Expected< std::unique_ptr< Info > > mergeInfos(std::vector< std::unique_ptr< Info > > &Values)
@ CK_InlineCommandComment
@ CK_VerbatimBlockLineComment
@ CK_VerbatimBlockComment
@ CK_TParamCommandComment
static llvm::SmallString< 64 > calculateRelativeFilePath(const InfoType &Type, const StringRef &Path, const StringRef &Name, const StringRef &CurrentPath)
CommentKind stringToCommentKind(llvm::StringRef KindStr)
std::array< uint8_t, 20 > SymbolID
llvm::StringRef commentKindToString(CommentKind Kind)
static const SymbolID EmptySID
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
std::optional< std::string > RepositoryUrl
ClangDocContext()=default
std::vector< std::string > UserStylesheets
tooling::ExecutionContext * ECtx
std::optional< std::string > RepositoryLinePrefix
void merge(ConceptInfo &&I)
SmallString< 16 > ConstraintExpression
llvm::SmallVector< EnumValueInfo, 4 > Members
void merge(FriendInfo &&Other)
bool mergeable(const FriendInfo &Other)
FunctionInfo(SymbolID USR=SymbolID())
llvm::SmallVector< FieldTypeInfo, 4 > Params
void merge(FunctionInfo &&I)
std::optional< TemplateInfo > Template
std::vector< Index > Children
bool operator<(const Index &Other) const
Info(InfoType IT=InfoType::IT_default, SymbolID USR=SymbolID(), StringRef Name=StringRef(), StringRef Path=StringRef())
bool mergeable(const Info &Other)
llvm::SmallString< 16 > getFileBaseName() const
Returns the basename that should be used for this Info.
std::vector< CommentInfo > Description
llvm::SmallString< 128 > Path
llvm::SmallString< 16 > extractName() const
llvm::SmallString< 64 > getRelativeFilePath(const StringRef &CurrentPath) const
Returns the file path for this Info relative to CurrentPath.
llvm::SmallVector< Reference, 4 > Namespace
NamespaceInfo(SymbolID USR=SymbolID(), StringRef Name=StringRef(), StringRef Path=StringRef())
void merge(NamespaceInfo &&I)
llvm::SmallVector< MemberTypeInfo, 4 > Members
RecordInfo(SymbolID USR=SymbolID(), StringRef Name=StringRef(), StringRef Path=StringRef())
std::optional< TemplateInfo > Template
std::vector< FriendInfo > Friends
llvm::SmallVector< Reference, 4 > VirtualParents
llvm::SmallVector< Reference, 4 > Parents
void merge(RecordInfo &&I)
std::vector< BaseRecordInfo > Bases
void merge(Reference &&I)
Reference(SymbolID USR=SymbolID(), StringRef Name=StringRef(), InfoType IT=InfoType::IT_default)
bool mergeable(const Reference &Other)
llvm::SmallString< 128 > Path
llvm::SmallString< 64 > getRelativeFilePath(const StringRef &CurrentPath) const
Returns the path for this Reference relative to CurrentPath.
llvm::SmallString< 16 > getFileBaseName() const
Returns the basename that should be used for this Reference.
SmallString< 16 > DocumentationFileName
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
SymbolInfo(InfoType IT, SymbolID USR=SymbolID(), StringRef Name=StringRef(), StringRef Path=StringRef())
llvm::SmallVector< Location, 2 > Loc
std::optional< Location > DefLoc
SmallString< 16 > MangledName
void merge(TypedefInfo &&I)
TypedefInfo(SymbolID USR=SymbolID())