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(llvm::inconvertibleErrorCode(), 24 "can't find generator: " + Format); 25 } 26 27 // Enum conversion 28 29 std::string getTagType(TagTypeKind AS) { 30 switch (AS) { 31 case TagTypeKind::TTK_Class: 32 return "class"; 33 case TagTypeKind::TTK_Union: 34 return "union"; 35 case TagTypeKind::TTK_Interface: 36 return "interface"; 37 case TagTypeKind::TTK_Struct: 38 return "struct"; 39 case TagTypeKind::TTK_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(Info->Namespace)) { 66 // Look for the current namespace in the children of the index I is 67 // pointing. 68 auto It = std::find(I->Children.begin(), I->Children.end(), 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(R.USR, R.Name, R.RefType, 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 = std::find(I->Children.begin(), I->Children.end(), Info->USR); 83 if (It == I->Children.end()) { 84 // If it is not in the vector it is inserted 85 I->Children.emplace_back(Info->USR, Info->extractName(), Info->IT, 86 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