xref: /llvm-project/clang-tools-extra/clang-doc/Generators.cpp (revision edd690b02e16e991393bf7f67631196942369aed)
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