2019-03-01 17:52:53 +08:00
|
|
|
//===-- Generators.cpp - Generator Registry ----------------------*- C++-*-===//
|
2018-06-07 00:13:17 +08:00
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2018-06-07 00:13:17 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "Generators.h"
|
|
|
|
|
|
|
|
LLVM_INSTANTIATE_REGISTRY(clang::doc::GeneratorRegistry)
|
|
|
|
|
|
|
|
namespace clang {
|
|
|
|
namespace doc {
|
|
|
|
|
|
|
|
llvm::Expected<std::unique_ptr<Generator>>
|
|
|
|
findGeneratorByName(llvm::StringRef Format) {
|
2020-06-19 07:40:00 +08:00
|
|
|
for (const auto &Generator : GeneratorRegistry::entries()) {
|
|
|
|
if (Generator.getName() != Format)
|
2018-06-07 00:13:17 +08:00
|
|
|
continue;
|
2020-06-19 07:40:00 +08:00
|
|
|
return Generator.instantiate();
|
2018-06-07 00:13:17 +08:00
|
|
|
}
|
2019-08-28 10:56:03 +08:00
|
|
|
return createStringError(llvm::inconvertibleErrorCode(),
|
|
|
|
"can't find generator: " + Format);
|
2018-06-07 00:13:17 +08:00
|
|
|
}
|
|
|
|
|
2019-07-11 03:03:25 +08:00
|
|
|
// Enum conversion
|
|
|
|
|
|
|
|
std::string getTagType(TagTypeKind AS) {
|
|
|
|
switch (AS) {
|
|
|
|
case TagTypeKind::TTK_Class:
|
|
|
|
return "class";
|
|
|
|
case TagTypeKind::TTK_Union:
|
|
|
|
return "union";
|
|
|
|
case TagTypeKind::TTK_Interface:
|
|
|
|
return "interface";
|
|
|
|
case TagTypeKind::TTK_Struct:
|
|
|
|
return "struct";
|
|
|
|
case TagTypeKind::TTK_Enum:
|
|
|
|
return "enum";
|
|
|
|
}
|
|
|
|
llvm_unreachable("Unknown TagTypeKind");
|
|
|
|
}
|
|
|
|
|
2019-08-27 00:39:48 +08:00
|
|
|
llvm::Error Generator::createResources(ClangDocContext &CDCtx) {
|
|
|
|
return llvm::Error::success();
|
|
|
|
}
|
2019-08-07 02:31:46 +08:00
|
|
|
|
|
|
|
// A function to add a reference to Info in Idx.
|
|
|
|
// Given an Info X with the following namespaces: [B,A]; a reference to X will
|
|
|
|
// be added in the children of a reference to B, which should be also a child of
|
|
|
|
// a reference to A, where A is a child of Idx.
|
|
|
|
// Idx
|
|
|
|
// |-- A
|
|
|
|
// |--B
|
|
|
|
// |--X
|
|
|
|
// If the references to the namespaces do not exist, they will be created. If
|
|
|
|
// the references already exist, the same one will be used.
|
|
|
|
void Generator::addInfoToIndex(Index &Idx, const doc::Info *Info) {
|
|
|
|
// Index pointer that will be moving through Idx until the first parent
|
|
|
|
// namespace of Info (where the reference has to be inserted) is found.
|
|
|
|
Index *I = &Idx;
|
|
|
|
// The Namespace vector includes the upper-most namespace at the end so the
|
|
|
|
// loop will start from the end to find each of the namespaces.
|
|
|
|
for (const auto &R : llvm::reverse(Info->Namespace)) {
|
|
|
|
// Look for the current namespace in the children of the index I is
|
|
|
|
// pointing.
|
|
|
|
auto It = std::find(I->Children.begin(), I->Children.end(), R.USR);
|
|
|
|
if (It != I->Children.end()) {
|
2020-04-05 14:28:11 +08:00
|
|
|
// If it is found, just change I to point the namespace reference found.
|
2019-08-07 02:31:46 +08:00
|
|
|
I = &*It;
|
|
|
|
} else {
|
|
|
|
// If it is not found a new reference is created
|
|
|
|
I->Children.emplace_back(R.USR, R.Name, R.RefType, R.Path);
|
|
|
|
// I is updated with the reference of the new namespace reference
|
|
|
|
I = &I->Children.back();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Look for Info in the vector where it is supposed to be; it could already
|
|
|
|
// exist if it is a parent namespace of an Info already passed to this
|
|
|
|
// function.
|
|
|
|
auto It = std::find(I->Children.begin(), I->Children.end(), Info->USR);
|
|
|
|
if (It == I->Children.end()) {
|
|
|
|
// If it is not in the vector it is inserted
|
|
|
|
I->Children.emplace_back(Info->USR, Info->extractName(), Info->IT,
|
|
|
|
Info->Path);
|
|
|
|
} else {
|
|
|
|
// If it not in the vector we only check if Path and Name are not empty
|
|
|
|
// because if the Info was included by a namespace it may not have those
|
|
|
|
// values.
|
|
|
|
if (It->Path.empty())
|
|
|
|
It->Path = Info->Path;
|
|
|
|
if (It->Name.empty())
|
|
|
|
It->Name = Info->extractName();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-07 00:13:17 +08:00
|
|
|
// This anchor is used to force the linker to link in the generated object file
|
|
|
|
// and thus register the generators.
|
|
|
|
extern volatile int YAMLGeneratorAnchorSource;
|
2018-09-11 23:56:55 +08:00
|
|
|
extern volatile int MDGeneratorAnchorSource;
|
2019-07-11 03:03:25 +08:00
|
|
|
extern volatile int HTMLGeneratorAnchorSource;
|
2018-06-07 00:13:17 +08:00
|
|
|
static int LLVM_ATTRIBUTE_UNUSED YAMLGeneratorAnchorDest =
|
|
|
|
YAMLGeneratorAnchorSource;
|
2018-09-11 23:56:55 +08:00
|
|
|
static int LLVM_ATTRIBUTE_UNUSED MDGeneratorAnchorDest =
|
|
|
|
MDGeneratorAnchorSource;
|
2019-07-11 03:03:25 +08:00
|
|
|
static int LLVM_ATTRIBUTE_UNUSED HTMLGeneratorAnchorDest =
|
|
|
|
HTMLGeneratorAnchorSource;
|
2018-06-07 00:13:17 +08:00
|
|
|
|
|
|
|
} // namespace doc
|
|
|
|
} // namespace clang
|