1ffe9f00cSFangrui Song //===-- Generators.cpp - Generator Registry ----------------------*- C++-*-===//
2e78f3018SJulie Hockett //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e78f3018SJulie Hockett //
7e78f3018SJulie Hockett //===----------------------------------------------------------------------===//
8e78f3018SJulie Hockett
9e78f3018SJulie Hockett #include "Generators.h"
10e78f3018SJulie Hockett
11e78f3018SJulie Hockett LLVM_INSTANTIATE_REGISTRY(clang::doc::GeneratorRegistry)
12e78f3018SJulie Hockett
13e78f3018SJulie Hockett namespace clang {
14e78f3018SJulie Hockett namespace doc {
15e78f3018SJulie Hockett
16e78f3018SJulie Hockett llvm::Expected<std::unique_ptr<Generator>>
findGeneratorByName(llvm::StringRef Format)17e78f3018SJulie Hockett findGeneratorByName(llvm::StringRef Format) {
188b0df1c1SNathan James for (const auto &Generator : GeneratorRegistry::entries()) {
198b0df1c1SNathan James if (Generator.getName() != Format)
20e78f3018SJulie Hockett continue;
218b0df1c1SNathan James return Generator.instantiate();
22e78f3018SJulie Hockett }
2318038065SFangrui Song return createStringError(llvm::inconvertibleErrorCode(),
2418038065SFangrui Song "can't find generator: " + Format);
25e78f3018SJulie Hockett }
26e78f3018SJulie Hockett
27671bac74SJulie Hockett // Enum conversion
28671bac74SJulie Hockett
getTagType(TagTypeKind AS)29671bac74SJulie Hockett std::string getTagType(TagTypeKind AS) {
30671bac74SJulie Hockett switch (AS) {
31*edd690b0SVlad Serebrennikov case TagTypeKind::Class:
32671bac74SJulie Hockett return "class";
33*edd690b0SVlad Serebrennikov case TagTypeKind::Union:
34671bac74SJulie Hockett return "union";
35*edd690b0SVlad Serebrennikov case TagTypeKind::Interface:
36671bac74SJulie Hockett return "interface";
37*edd690b0SVlad Serebrennikov case TagTypeKind::Struct:
38671bac74SJulie Hockett return "struct";
39*edd690b0SVlad Serebrennikov case TagTypeKind::Enum:
40671bac74SJulie Hockett return "enum";
41671bac74SJulie Hockett }
42671bac74SJulie Hockett llvm_unreachable("Unknown TagTypeKind");
43671bac74SJulie Hockett }
44671bac74SJulie Hockett
createResources(ClangDocContext & CDCtx)4572e1f7f9SJulie Hockett llvm::Error Generator::createResources(ClangDocContext &CDCtx) {
4672e1f7f9SJulie Hockett return llvm::Error::success();
4772e1f7f9SJulie Hockett }
487dfe0bc3SDiego Astiazaran
497dfe0bc3SDiego Astiazaran // A function to add a reference to Info in Idx.
507dfe0bc3SDiego Astiazaran // Given an Info X with the following namespaces: [B,A]; a reference to X will
517dfe0bc3SDiego Astiazaran // be added in the children of a reference to B, which should be also a child of
527dfe0bc3SDiego Astiazaran // a reference to A, where A is a child of Idx.
537dfe0bc3SDiego Astiazaran // Idx
547dfe0bc3SDiego Astiazaran // |-- A
557dfe0bc3SDiego Astiazaran // |--B
567dfe0bc3SDiego Astiazaran // |--X
577dfe0bc3SDiego Astiazaran // If the references to the namespaces do not exist, they will be created. If
587dfe0bc3SDiego Astiazaran // the references already exist, the same one will be used.
addInfoToIndex(Index & Idx,const doc::Info * Info)597dfe0bc3SDiego Astiazaran void Generator::addInfoToIndex(Index &Idx, const doc::Info *Info) {
607dfe0bc3SDiego Astiazaran // Index pointer that will be moving through Idx until the first parent
617dfe0bc3SDiego Astiazaran // namespace of Info (where the reference has to be inserted) is found.
627dfe0bc3SDiego Astiazaran Index *I = &Idx;
637dfe0bc3SDiego Astiazaran // The Namespace vector includes the upper-most namespace at the end so the
647dfe0bc3SDiego Astiazaran // loop will start from the end to find each of the namespaces.
657dfe0bc3SDiego Astiazaran for (const auto &R : llvm::reverse(Info->Namespace)) {
667dfe0bc3SDiego Astiazaran // Look for the current namespace in the children of the index I is
677dfe0bc3SDiego Astiazaran // pointing.
68e125e6c4SKazu Hirata auto It = llvm::find(I->Children, R.USR);
697dfe0bc3SDiego Astiazaran if (It != I->Children.end()) {
70dd5571d5SKazuaki Ishizaki // If it is found, just change I to point the namespace reference found.
717dfe0bc3SDiego Astiazaran I = &*It;
727dfe0bc3SDiego Astiazaran } else {
737dfe0bc3SDiego Astiazaran // If it is not found a new reference is created
747dfe0bc3SDiego Astiazaran I->Children.emplace_back(R.USR, R.Name, R.RefType, R.Path);
757dfe0bc3SDiego Astiazaran // I is updated with the reference of the new namespace reference
767dfe0bc3SDiego Astiazaran I = &I->Children.back();
777dfe0bc3SDiego Astiazaran }
787dfe0bc3SDiego Astiazaran }
797dfe0bc3SDiego Astiazaran // Look for Info in the vector where it is supposed to be; it could already
807dfe0bc3SDiego Astiazaran // exist if it is a parent namespace of an Info already passed to this
817dfe0bc3SDiego Astiazaran // function.
82e125e6c4SKazu Hirata auto It = llvm::find(I->Children, Info->USR);
837dfe0bc3SDiego Astiazaran if (It == I->Children.end()) {
847dfe0bc3SDiego Astiazaran // If it is not in the vector it is inserted
857dfe0bc3SDiego Astiazaran I->Children.emplace_back(Info->USR, Info->extractName(), Info->IT,
867dfe0bc3SDiego Astiazaran Info->Path);
877dfe0bc3SDiego Astiazaran } else {
887dfe0bc3SDiego Astiazaran // If it not in the vector we only check if Path and Name are not empty
897dfe0bc3SDiego Astiazaran // because if the Info was included by a namespace it may not have those
907dfe0bc3SDiego Astiazaran // values.
917dfe0bc3SDiego Astiazaran if (It->Path.empty())
927dfe0bc3SDiego Astiazaran It->Path = Info->Path;
937dfe0bc3SDiego Astiazaran if (It->Name.empty())
947dfe0bc3SDiego Astiazaran It->Name = Info->extractName();
957dfe0bc3SDiego Astiazaran }
967dfe0bc3SDiego Astiazaran }
977dfe0bc3SDiego Astiazaran
98e78f3018SJulie Hockett // This anchor is used to force the linker to link in the generated object file
99e78f3018SJulie Hockett // and thus register the generators.
100e78f3018SJulie Hockett extern volatile int YAMLGeneratorAnchorSource;
101ac68cab9SJulie Hockett extern volatile int MDGeneratorAnchorSource;
102671bac74SJulie Hockett extern volatile int HTMLGeneratorAnchorSource;
103e78f3018SJulie Hockett static int LLVM_ATTRIBUTE_UNUSED YAMLGeneratorAnchorDest =
104e78f3018SJulie Hockett YAMLGeneratorAnchorSource;
105ac68cab9SJulie Hockett static int LLVM_ATTRIBUTE_UNUSED MDGeneratorAnchorDest =
106ac68cab9SJulie Hockett MDGeneratorAnchorSource;
107671bac74SJulie Hockett static int LLVM_ATTRIBUTE_UNUSED HTMLGeneratorAnchorDest =
108671bac74SJulie Hockett HTMLGeneratorAnchorSource;
109e78f3018SJulie Hockett
110e78f3018SJulie Hockett } // namespace doc
111e78f3018SJulie Hockett } // namespace clang
112