23#include "llvm/Support/Error.h"
24#include "llvm/Support/Path.h"
34llvm::Expected<std::unique_ptr<Info>>
35reduce(std::vector<std::unique_ptr<Info>> &Values) {
36 if (Values.empty() || !Values[0])
37 return llvm::createStringError(llvm::inconvertibleErrorCode(),
38 "no value to reduce");
39 std::unique_ptr<Info> Merged = std::make_unique<T>(Values[0]->
USR);
40 T *Tmp =
static_cast<T *
>(Merged.get());
41 for (
auto &I : Values)
42 Tmp->merge(std::move(*
static_cast<T *
>(I.get())));
43 return std::move(Merged);
49int getChildIndexIfExists(std::vector<T> &
Children, T &ChildToMerge) {
50 for (
unsigned long I = 0; I <
Children.size(); I++) {
51 if (ChildToMerge.USR ==
Children[I].USR)
58void reduceChildren(std::vector<T> &
Children,
59 std::vector<T> &&ChildrenToMerge) {
60 for (
auto &ChildToMerge : ChildrenToMerge) {
61 int MergeIdx = getChildIndexIfExists(
Children, ChildToMerge);
63 Children.push_back(std::move(ChildToMerge));
66 Children[MergeIdx].merge(std::move(ChildToMerge));
73llvm::Expected<std::unique_ptr<Info>>
75 if (Values.empty() || !Values[0])
76 return llvm::createStringError(llvm::inconvertibleErrorCode(),
77 "no info values to merge");
79 switch (Values[0]->IT) {
81 return reduce<NamespaceInfo>(Values);
83 return reduce<RecordInfo>(Values);
85 return reduce<EnumInfo>(Values);
87 return reduce<FunctionInfo>(Values);
89 return reduce<TypedefInfo>(Values);
91 return llvm::createStringError(llvm::inconvertibleErrorCode(),
92 "unexpected info type");
108 llvm::deref<std::equal_to<>>{});
119 if (FirstCI < SecondCI)
122 if (FirstCI == SecondCI) {
123 return std::lexicographical_compare(
125 Other.
Children.end(), llvm::deref<std::less<>>());
131static llvm::SmallString<64>
133 const StringRef &
Name,
const StringRef &CurrentPath) {
134 llvm::SmallString<64> FilePath;
136 if (CurrentPath !=
Path) {
138 for (llvm::sys::path::const_iterator I =
139 llvm::sys::path::begin(CurrentPath);
140 I != llvm::sys::path::end(CurrentPath); ++I)
141 llvm::sys::path::append(FilePath,
"..");
142 llvm::sys::path::append(FilePath,
Path);
148 llvm::sys::path::append(FilePath,
Name);
150 return llvm::sys::path::relative_path(FilePath);
160 return llvm::SmallString<16>(
"index");
172 return llvm::SmallString<16>(
"index");
200 std::move(Other.Description.begin(), Other.Description.end(),
214 DefLoc = std::move(Other.DefLoc);
216 std::move(Other.Loc.begin(), Other.Loc.end(), std::back_inserter(
Loc));
218 auto Last = std::unique(
Loc.begin(),
Loc.end());
219 Loc.erase(Last,
Loc.end());
232 reduceChildren(
Children.
Enums, std::move(Other.Children.Enums));
242 if (!llvm::to_underlying(
TagType))
246 Members = std::move(Other.Members);
248 Bases = std::move(Other.Bases);
250 Parents = std::move(Other.Parents);
256 reduceChildren(
Children.
Enums, std::move(Other.Children.Enums));
258 SymbolInfo::merge(std::move(Other));
268 Members = std::move(Other.Members);
269 SymbolInfo::merge(std::move(Other));
281 Parent = std::move(Other.Parent);
283 Params = std::move(Other.Params);
284 SymbolInfo::merge(std::move(Other));
295 SymbolInfo::merge(std::move(Other));
301 bool IsVirtual, AccessSpecifier Access,
304 IsParent(IsParent) {}
317 return llvm::SmallString<16>(
"@GlobalNamespace");
321 return llvm::SmallString<16>(
"GlobalNamespace");
323 return llvm::SmallString<16>(
"@nonymous_record_" +
324 toHex(llvm::toStringRef(
USR)));
326 return llvm::SmallString<16>(
"@nonymous_enum_" +
327 toHex(llvm::toStringRef(
USR)));
329 return llvm::SmallString<16>(
"@nonymous_typedef_" +
330 toHex(llvm::toStringRef(
USR)));
332 return llvm::SmallString<16>(
"@nonymous_function_" +
333 toHex(llvm::toStringRef(
USR)));
335 return llvm::SmallString<16>(
"@nonymous_" + toHex(llvm::toStringRef(
USR)));
337 llvm_unreachable(
"Invalid InfoType.");
338 return llvm::SmallString<16>(
"");
344 for (
unsigned I = 0; I <
Name.size() && I < Other.
Name.size(); ++I) {
346 int D = tolower(
Name[I]) - tolower(Other.
Name[I]);
355 if (
Name.size() == Other.
Name.size())
358 return Name.size() < Other.
Name.size();
374 llvm::SmallString<128> SourceRootDir(
SourceRoot);
377 llvm::sys::fs::current_path(SourceRootDir);
378 this->SourceRoot = std::string(SourceRootDir);
383 this->RepositoryUrl->insert(0,
"https://");
llvm::SmallString< 256U > Name
static llvm::cl::opt< bool > PublicOnly("public", llvm::cl::desc("Document only public declarations."), llvm::cl::init(false), llvm::cl::cat(ClangDocCategory))
static llvm::cl::opt< std::string > ProjectName("project-name", llvm::cl::desc("Name of project."), llvm::cl::cat(ClangDocCategory))
static llvm::cl::list< std::string > UserStylesheets("stylesheets", llvm::cl::CommaSeparated, llvm::cl::desc("CSS stylesheets to extend the default styles."), llvm::cl::cat(ClangDocCategory))
static llvm::cl::opt< std::string > SourceRoot("source-root", llvm::cl::desc(R"(
Directory where processed files are stored.
Links to definition locations will only be
generated if the file is in this dir.)"), llvm::cl::cat(ClangDocCategory))
static llvm::cl::opt< std::string > OutDirectory("output", llvm::cl::desc("Directory for outputting generated files."), llvm::cl::init("docs"), llvm::cl::cat(ClangDocCategory))
static llvm::cl::opt< std::string > RepositoryUrl("repository", llvm::cl::desc(R"(
URL of repository that hosts code.
Used for links to definition locations.)"), llvm::cl::cat(ClangDocCategory))
std::vector< std::unique_ptr< HTMLNode > > Children
std::vector< HeaderHandle > Path
llvm::Expected< std::unique_ptr< Info > > mergeInfos(std::vector< std::unique_ptr< Info > > &Values)
static llvm::SmallString< 64 > calculateRelativeFilePath(const InfoType &Type, const StringRef &Path, const StringRef &Name, const StringRef &CurrentPath)
std::array< uint8_t, 20 > SymbolID
static const SymbolID EmptySID
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
std::optional< std::string > RepositoryUrl
ClangDocContext()=default
llvm::SmallVector< EnumValueInfo, 4 > Members
llvm::SmallVector< FieldTypeInfo, 4 > Params
void merge(FunctionInfo &&I)
std::optional< TemplateInfo > Template
std::vector< Index > Children
bool operator<(const Index &Other) const
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
llvm::SmallVector< Reference, 4 > VirtualParents
llvm::SmallVector< Reference, 4 > Parents
void merge(RecordInfo &&I)
std::vector< BaseRecordInfo > Bases
void merge(Reference &&I)
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.
std::vector< Reference > Records
std::vector< TypedefInfo > Typedefs
std::vector< FunctionInfo > Functions
std::vector< Reference > Namespaces
std::vector< EnumInfo > Enums
llvm::SmallVector< Location, 2 > Loc
std::optional< Location > DefLoc
void merge(TypedefInfo &&I)