summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clang-doc/YAMLGenerator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra/clang-doc/YAMLGenerator.cpp')
-rw-r--r--clang-tools-extra/clang-doc/YAMLGenerator.cpp268
1 files changed, 268 insertions, 0 deletions
diff --git a/clang-tools-extra/clang-doc/YAMLGenerator.cpp b/clang-tools-extra/clang-doc/YAMLGenerator.cpp
new file mode 100644
index 00000000000..f29b4787dbd
--- /dev/null
+++ b/clang-tools-extra/clang-doc/YAMLGenerator.cpp
@@ -0,0 +1,268 @@
+//===-- ClangDocYAML.cpp - ClangDoc YAML -----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Implementation of the YAML generator, converting decl info into YAML output.
+//===----------------------------------------------------------------------===//
+
+#include "Generators.h"
+#include "llvm/Support/YAMLTraits.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace clang::doc;
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(FieldTypeInfo)
+LLVM_YAML_IS_SEQUENCE_VECTOR(MemberTypeInfo)
+LLVM_YAML_IS_SEQUENCE_VECTOR(Reference)
+LLVM_YAML_IS_SEQUENCE_VECTOR(Location)
+LLVM_YAML_IS_SEQUENCE_VECTOR(CommentInfo)
+LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<CommentInfo>)
+LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::SmallString<16>)
+
+namespace llvm {
+namespace yaml {
+
+// Enumerations to YAML output.
+
+template <> struct ScalarEnumerationTraits<clang::AccessSpecifier> {
+ static void enumeration(IO &IO, clang::AccessSpecifier &Value) {
+ IO.enumCase(Value, "Public", clang::AccessSpecifier::AS_public);
+ IO.enumCase(Value, "Protected", clang::AccessSpecifier::AS_protected);
+ IO.enumCase(Value, "Private", clang::AccessSpecifier::AS_private);
+ IO.enumCase(Value, "None", clang::AccessSpecifier::AS_none);
+ }
+};
+
+template <> struct ScalarEnumerationTraits<clang::TagTypeKind> {
+ static void enumeration(IO &IO, clang::TagTypeKind &Value) {
+ IO.enumCase(Value, "Struct", clang::TagTypeKind::TTK_Struct);
+ IO.enumCase(Value, "Interface", clang::TagTypeKind::TTK_Interface);
+ IO.enumCase(Value, "Union", clang::TagTypeKind::TTK_Union);
+ IO.enumCase(Value, "Class", clang::TagTypeKind::TTK_Class);
+ IO.enumCase(Value, "Enum", clang::TagTypeKind::TTK_Enum);
+ }
+};
+
+template <> struct ScalarEnumerationTraits<InfoType> {
+ static void enumeration(IO &IO, InfoType &Value) {
+ IO.enumCase(Value, "Namespace", InfoType::IT_namespace);
+ IO.enumCase(Value, "Record", InfoType::IT_record);
+ IO.enumCase(Value, "Function", InfoType::IT_function);
+ IO.enumCase(Value, "Enum", InfoType::IT_enum);
+ IO.enumCase(Value, "Default", InfoType::IT_default);
+ }
+};
+
+// Scalars to YAML output.
+template <unsigned U> struct ScalarTraits<SmallString<U>> {
+
+ static void output(const SmallString<U> &S, void *, llvm::raw_ostream &OS) {
+ for (const auto &C : S)
+ OS << C;
+ }
+
+ static StringRef input(StringRef Scalar, void *, SmallString<U> &Value) {
+ Value.assign(Scalar.begin(), Scalar.end());
+ return StringRef();
+ }
+
+ static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
+};
+
+template <> struct ScalarTraits<std::array<unsigned char, 20>> {
+
+ static void output(const std::array<unsigned char, 20> &S, void *,
+ llvm::raw_ostream &OS) {
+ OS << toHex(toStringRef(S));
+ }
+
+ static StringRef input(StringRef Scalar, void *,
+ std::array<unsigned char, 20> &Value) {
+ if (Scalar.size() != 40)
+ return "Error: Incorrect scalar size for USR.";
+ Value = StringToSymbol(Scalar);
+ return StringRef();
+ }
+
+ static SymbolID StringToSymbol(llvm::StringRef Value) {
+ SymbolID USR;
+ std::string HexString = fromHex(Value);
+ std::copy(HexString.begin(), HexString.end(), USR.begin());
+ return SymbolID(USR);
+ }
+
+ static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
+};
+
+// Helper functions to map infos to YAML.
+
+static void TypeInfoMapping(IO &IO, TypeInfo &I) {
+ IO.mapOptional("Type", I.Type, Reference());
+}
+
+static void FieldTypeInfoMapping(IO &IO, FieldTypeInfo &I) {
+ TypeInfoMapping(IO, I);
+ IO.mapOptional("Name", I.Name, SmallString<16>());
+}
+
+static void InfoMapping(IO &IO, Info &I) {
+ IO.mapRequired("USR", I.USR);
+ IO.mapOptional("Name", I.Name, SmallString<16>());
+ IO.mapOptional("Namespace", I.Namespace, llvm::SmallVector<Reference, 4>());
+ IO.mapOptional("Description", I.Description);
+}
+
+static void SymbolInfoMapping(IO &IO, SymbolInfo &I) {
+ InfoMapping(IO, I);
+ IO.mapOptional("DefLocation", I.DefLoc, Optional<Location>());
+ IO.mapOptional("Location", I.Loc, llvm::SmallVector<Location, 2>());
+}
+
+static void CommentInfoMapping(IO &IO, CommentInfo &I) {
+ IO.mapOptional("Kind", I.Kind, SmallString<16>());
+ IO.mapOptional("Text", I.Text, SmallString<64>());
+ IO.mapOptional("Name", I.Name, SmallString<16>());
+ IO.mapOptional("Direction", I.Direction, SmallString<8>());
+ IO.mapOptional("ParamName", I.ParamName, SmallString<16>());
+ IO.mapOptional("CloseName", I.CloseName, SmallString<16>());
+ IO.mapOptional("SelfClosing", I.SelfClosing, false);
+ IO.mapOptional("Explicit", I.Explicit, false);
+ IO.mapOptional("Args", I.Args, llvm::SmallVector<SmallString<16>, 4>());
+ IO.mapOptional("AttrKeys", I.AttrKeys,
+ llvm::SmallVector<SmallString<16>, 4>());
+ IO.mapOptional("AttrValues", I.AttrValues,
+ llvm::SmallVector<SmallString<16>, 4>());
+ IO.mapOptional("Children", I.Children);
+}
+
+// Template specialization to YAML traits for Infos.
+
+template <> struct MappingTraits<Location> {
+ static void mapping(IO &IO, Location &Loc) {
+ IO.mapOptional("LineNumber", Loc.LineNumber, 0);
+ IO.mapOptional("Filename", Loc.Filename, SmallString<32>());
+ }
+};
+
+template <> struct MappingTraits<Reference> {
+ static void mapping(IO &IO, Reference &Ref) {
+ IO.mapOptional("Type", Ref.RefType, InfoType::IT_default);
+ IO.mapOptional("Name", Ref.Name, SmallString<16>());
+ IO.mapOptional("USR", Ref.USR, SymbolID());
+ }
+};
+
+template <> struct MappingTraits<TypeInfo> {
+ static void mapping(IO &IO, TypeInfo &I) { TypeInfoMapping(IO, I); }
+};
+
+template <> struct MappingTraits<FieldTypeInfo> {
+ static void mapping(IO &IO, FieldTypeInfo &I) {
+ TypeInfoMapping(IO, I);
+ IO.mapOptional("Name", I.Name, SmallString<16>());
+ }
+};
+
+template <> struct MappingTraits<MemberTypeInfo> {
+ static void mapping(IO &IO, MemberTypeInfo &I) {
+ FieldTypeInfoMapping(IO, I);
+ IO.mapOptional("Access", I.Access, clang::AccessSpecifier::AS_none);
+ }
+};
+
+template <> struct MappingTraits<NamespaceInfo> {
+ static void mapping(IO &IO, NamespaceInfo &I) { InfoMapping(IO, I); }
+};
+
+template <> struct MappingTraits<RecordInfo> {
+ static void mapping(IO &IO, RecordInfo &I) {
+ SymbolInfoMapping(IO, I);
+ IO.mapOptional("TagType", I.TagType, clang::TagTypeKind::TTK_Struct);
+ IO.mapOptional("Members", I.Members);
+ IO.mapOptional("Parents", I.Parents, llvm::SmallVector<Reference, 4>());
+ IO.mapOptional("VirtualParents", I.VirtualParents,
+ llvm::SmallVector<Reference, 4>());
+ }
+};
+
+template <> struct MappingTraits<EnumInfo> {
+ static void mapping(IO &IO, EnumInfo &I) {
+ SymbolInfoMapping(IO, I);
+ IO.mapOptional("Scoped", I.Scoped, false);
+ IO.mapOptional("Members", I.Members);
+ }
+};
+
+template <> struct MappingTraits<FunctionInfo> {
+ static void mapping(IO &IO, FunctionInfo &I) {
+ SymbolInfoMapping(IO, I);
+ IO.mapOptional("IsMethod", I.IsMethod, false);
+ IO.mapOptional("Parent", I.Parent, Reference());
+ IO.mapOptional("Params", I.Params);
+ IO.mapOptional("ReturnType", I.ReturnType);
+ IO.mapOptional("Access", I.Access, clang::AccessSpecifier::AS_none);
+ }
+};
+
+template <> struct MappingTraits<CommentInfo> {
+ static void mapping(IO &IO, CommentInfo &I) { CommentInfoMapping(IO, I); }
+};
+
+template <> struct MappingTraits<std::unique_ptr<CommentInfo>> {
+ static void mapping(IO &IO, std::unique_ptr<CommentInfo> &I) {
+ if (I)
+ CommentInfoMapping(IO, *I);
+ }
+};
+
+} // end namespace yaml
+} // end namespace llvm
+
+namespace clang {
+namespace doc {
+
+/// Generator for YAML documentation.
+class YAMLGenerator : public Generator {
+public:
+ static const char *Format;
+
+ bool generateDocForInfo(Info *I, llvm::raw_ostream &OS) override;
+};
+
+const char *YAMLGenerator::Format = "yaml";
+
+bool YAMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS) {
+ llvm::yaml::Output InfoYAML(OS);
+ switch (I->IT) {
+ case InfoType::IT_namespace:
+ InfoYAML << *static_cast<clang::doc::NamespaceInfo *>(I);
+ break;
+ case InfoType::IT_record:
+ InfoYAML << *static_cast<clang::doc::RecordInfo *>(I);
+ break;
+ case InfoType::IT_enum:
+ InfoYAML << *static_cast<clang::doc::EnumInfo *>(I);
+ break;
+ case InfoType::IT_function:
+ InfoYAML << *static_cast<clang::doc::FunctionInfo *>(I);
+ break;
+ case InfoType::IT_default:
+ llvm::errs() << "Unexpected info type in index.\n";
+ return true;
+ }
+ return false;
+}
+
+static GeneratorRegistry::Add<YAMLGenerator> YAML(YAMLGenerator::Format,
+ "Generator for YAML output.");
+
+// This anchor is used to force the linker to link in the generated object file
+// and thus register the generator.
+volatile int YAMLGeneratorAnchorSource = 0;
+
+} // namespace doc
+} // namespace clang
OpenPOWER on IntegriCloud