1 | //===-- Generators.cpp - Generator Registry ----------------------*- C++-*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "Generators.h" |
10 | |
11 | LLVM_INSTANTIATE_REGISTRY(clang::doc::GeneratorRegistry) |
12 | |
13 | namespace clang { |
14 | namespace doc { |
15 | |
16 | llvm::Expected<std::unique_ptr<Generator>> |
17 | findGeneratorByName(llvm::StringRef Format) { |
18 | for (const auto &Generator : GeneratorRegistry::entries()) { |
19 | if (Generator.getName() != Format) |
20 | continue; |
21 | return Generator.instantiate(); |
22 | } |
23 | return createStringError(EC: llvm::inconvertibleErrorCode(), |
24 | S: "can't find generator: " + Format); |
25 | } |
26 | |
27 | // Enum conversion |
28 | |
29 | std::string getTagType(TagTypeKind AS) { |
30 | switch (AS) { |
31 | case TagTypeKind::Class: |
32 | return "class" ; |
33 | case TagTypeKind::Union: |
34 | return "union" ; |
35 | case TagTypeKind::Interface: |
36 | return "interface" ; |
37 | case TagTypeKind::Struct: |
38 | return "struct" ; |
39 | case TagTypeKind::Enum: |
40 | return "enum" ; |
41 | } |
42 | llvm_unreachable("Unknown TagTypeKind" ); |
43 | } |
44 | |
45 | llvm::Error Generator::createResources(ClangDocContext &CDCtx) { |
46 | return llvm::Error::success(); |
47 | } |
48 | |
49 | // A function to add a reference to Info in Idx. |
50 | // Given an Info X with the following namespaces: [B,A]; a reference to X will |
51 | // be added in the children of a reference to B, which should be also a child of |
52 | // a reference to A, where A is a child of Idx. |
53 | // Idx |
54 | // |-- A |
55 | // |--B |
56 | // |--X |
57 | // If the references to the namespaces do not exist, they will be created. If |
58 | // the references already exist, the same one will be used. |
59 | void Generator::addInfoToIndex(Index &Idx, const doc::Info *Info) { |
60 | // Index pointer that will be moving through Idx until the first parent |
61 | // namespace of Info (where the reference has to be inserted) is found. |
62 | Index *I = &Idx; |
63 | // The Namespace vector includes the upper-most namespace at the end so the |
64 | // loop will start from the end to find each of the namespaces. |
65 | for (const auto &R : llvm::reverse(C: Info->Namespace)) { |
66 | // Look for the current namespace in the children of the index I is |
67 | // pointing. |
68 | auto It = llvm::find(Range&: I->Children, Val: R.USR); |
69 | if (It != I->Children.end()) { |
70 | // If it is found, just change I to point the namespace reference found. |
71 | I = &*It; |
72 | } else { |
73 | // If it is not found a new reference is created |
74 | I->Children.emplace_back(args: R.USR, args: R.Name, args: R.RefType, args: R.Path); |
75 | // I is updated with the reference of the new namespace reference |
76 | I = &I->Children.back(); |
77 | } |
78 | } |
79 | // Look for Info in the vector where it is supposed to be; it could already |
80 | // exist if it is a parent namespace of an Info already passed to this |
81 | // function. |
82 | auto It = llvm::find(Range&: I->Children, Val: Info->USR); |
83 | if (It == I->Children.end()) { |
84 | // If it is not in the vector it is inserted |
85 | I->Children.emplace_back(args: Info->USR, args: Info->extractName(), args: Info->IT, |
86 | args: Info->Path); |
87 | } else { |
88 | // If it not in the vector we only check if Path and Name are not empty |
89 | // because if the Info was included by a namespace it may not have those |
90 | // values. |
91 | if (It->Path.empty()) |
92 | It->Path = Info->Path; |
93 | if (It->Name.empty()) |
94 | It->Name = Info->extractName(); |
95 | } |
96 | } |
97 | |
98 | // This anchor is used to force the linker to link in the generated object file |
99 | // and thus register the generators. |
100 | extern volatile int YAMLGeneratorAnchorSource; |
101 | extern volatile int MDGeneratorAnchorSource; |
102 | extern volatile int HTMLGeneratorAnchorSource; |
103 | static int LLVM_ATTRIBUTE_UNUSED YAMLGeneratorAnchorDest = |
104 | YAMLGeneratorAnchorSource; |
105 | static int LLVM_ATTRIBUTE_UNUSED MDGeneratorAnchorDest = |
106 | MDGeneratorAnchorSource; |
107 | static int LLVM_ATTRIBUTE_UNUSED HTMLGeneratorAnchorDest = |
108 | HTMLGeneratorAnchorSource; |
109 | |
110 | } // namespace doc |
111 | } // namespace clang |
112 | |