23 #include "llvm/Support/Error.h" 24 #include "llvm/Support/Path.h" 34 llvm::Expected<std::unique_ptr<Info>>
35 reduce(std::vector<std::unique_ptr<Info>> &Values) {
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);
49 int getChildIndexIfExists(std::vector<T> &Children, T &ChildToMerge) {
50 for (
unsigned long I = 0; I < Children.size(); I++) {
51 if (ChildToMerge.USR == Children[I].USR)
57 void reduceChildren(std::vector<Reference> &Children,
58 std::vector<Reference> &&ChildrenToMerge) {
59 for (
auto &ChildToMerge : ChildrenToMerge) {
60 int mergeIdx = getChildIndexIfExists(Children, ChildToMerge);
62 Children.push_back(std::move(ChildToMerge));
65 Children[mergeIdx].merge(std::move(ChildToMerge));
69 void reduceChildren(std::vector<FunctionInfo> &Children,
70 std::vector<FunctionInfo> &&ChildrenToMerge) {
71 for (
auto &ChildToMerge : ChildrenToMerge) {
72 int mergeIdx = getChildIndexIfExists(Children, ChildToMerge);
74 Children.push_back(std::move(ChildToMerge));
77 Children[mergeIdx].merge(std::move(ChildToMerge));
81 void reduceChildren(std::vector<EnumInfo> &Children,
82 std::vector<EnumInfo> &&ChildrenToMerge) {
83 for (
auto &ChildToMerge : ChildrenToMerge) {
84 int mergeIdx = getChildIndexIfExists(Children, ChildToMerge);
86 Children.push_back(std::move(ChildToMerge));
89 Children[mergeIdx].merge(std::move(ChildToMerge));
96 llvm::Expected<std::unique_ptr<Info>>
99 return llvm::createStringError(llvm::inconvertibleErrorCode(),
100 "no info values to merge");
102 switch (Values[0]->IT) {
104 return reduce<NamespaceInfo>(Values);
106 return reduce<RecordInfo>(Values);
108 return reduce<EnumInfo>(Values);
110 return reduce<FunctionInfo>(Values);
112 return llvm::createStringError(llvm::inconvertibleErrorCode(),
113 "unexpected info type");
139 if (Namespace.empty())
140 Namespace = std::move(Other.Namespace);
142 std::move(Other.Description.begin(), Other.Description.end(),
150 return IT == Other.
IT &&
USR == Other.
USR;
156 DefLoc = std::move(Other.DefLoc);
158 std::move(Other.Loc.begin(), Other.Loc.end(), std::back_inserter(
Loc));
159 std::sort(
Loc.begin(),
Loc.end());
160 auto Last = std::unique(
Loc.begin(),
Loc.end());
161 Loc.erase(Last,
Loc.end());
162 mergeBase(std::move(Other));
168 reduceChildren(ChildNamespaces, std::move(Other.ChildNamespaces));
169 reduceChildren(ChildRecords, std::move(Other.ChildRecords));
170 reduceChildren(ChildFunctions, std::move(Other.ChildFunctions));
171 reduceChildren(ChildEnums, std::move(Other.ChildEnums));
172 mergeBase(std::move(Other));
178 TagType = Other.TagType;
180 Members = std::move(Other.Members);
182 Bases = std::move(Other.Bases);
184 Parents = std::move(Other.Parents);
185 if (VirtualParents.empty())
186 VirtualParents = std::move(Other.VirtualParents);
188 reduceChildren(ChildRecords, std::move(Other.ChildRecords));
189 reduceChildren(ChildFunctions, std::move(Other.ChildFunctions));
190 reduceChildren(ChildEnums, std::move(Other.ChildEnums));
197 Scoped = Other.Scoped;
199 Members = std::move(Other.Members);
206 IsMethod = Other.IsMethod;
208 Access = Other.Access;
212 Parent = std::move(Other.Parent);
214 Params = std::move(Other.Params);
228 if (
Name ==
"GlobalNamespace" && Namespace.empty())
229 return llvm::SmallString<16>(
"@GlobalNamespace");
233 return llvm::SmallString<16>(
"GlobalNamespace");
235 return llvm::SmallString<16>(
"@nonymous_record_" +
236 toHex(llvm::toStringRef(
USR)));
238 return llvm::SmallString<16>(
"@nonymous_enum_" +
239 toHex(llvm::toStringRef(
USR)));
241 return llvm::SmallString<16>(
"@nonymous_function_" +
242 toHex(llvm::toStringRef(
USR)));
244 return llvm::SmallString<16>(
"@nonymous_" + toHex(llvm::toStringRef(
USR)));
246 llvm_unreachable(
"Invalid InfoType.");
247 return llvm::SmallString<16>(
"");
253 for (
unsigned I = 0; I <
Name.size() && I < Other.
Name.size(); ++I) {
255 int D = tolower(
Name[I]) - tolower(Other.
Name[I]);
264 if (
Name.size() == Other.
Name.size())
267 return Name.size() < Other.
Name.size();
271 std::sort(Children.begin(), Children.end());
272 for (
auto &C : Children)
281 std::vector<std::string> JsScripts)
282 : ECtx(ECtx), ProjectName(ProjectName), PublicOnly(PublicOnly),
283 OutDirectory(OutDirectory), UserStylesheets(UserStylesheets),
284 JsScripts(JsScripts) {
285 llvm::SmallString<128> SourceRootDir(SourceRoot);
286 if (SourceRoot.empty())
288 llvm::sys::fs::current_path(SourceRootDir);
289 this->SourceRoot = SourceRootDir.str();
290 if (!RepositoryUrl.empty()) {
292 if (!RepositoryUrl.empty() && RepositoryUrl.find(
"http://") != 0 &&
293 RepositoryUrl.find(
"https://") != 0)
294 this->RepositoryUrl->insert(0,
"https://");
SourceLocation Loc
'#' location in the include directive
static const SymbolID EmptySID
llvm::Optional< std::string > RepositoryUrl
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 > RepositoryUrl("repository", llvm::cl::desc(R"(
URL of repository that hosts code.
Used for links to definition locations.)"), llvm::cl::cat(ClangDocCategory))
llvm::SmallString< 16 > extractName() const
ClangDocContext()=default
void merge(NamespaceInfo &&I)
static llvm::cl::opt< bool > PublicOnly("public", llvm::cl::desc("Document only public declarations."), llvm::cl::init(false), llvm::cl::cat(ClangDocCategory))
void merge(Reference &&I)
static llvm::cl::opt< std::string > ProjectName("project-name", llvm::cl::desc("Name of project."), llvm::cl::cat(ClangDocCategory))
bool mergeable(const Info &Other)
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::list< std::string > UserStylesheets("stylesheets", llvm::cl::CommaSeparated, llvm::cl::desc("CSS stylesheets to extend the default styles."), llvm::cl::cat(ClangDocCategory))
bool operator<(const Index &Other) const
bool mergeable(const Reference &Other)
llvm::Expected< std::unique_ptr< Info > > mergeInfos(std::vector< std::unique_ptr< Info >> &Values)
void merge(SymbolInfo &&I)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
void merge(FunctionInfo &&I)
std::array< uint8_t, 20 > SymbolID
void merge(RecordInfo &&I)
llvm::SmallString< 128 > Path