Author: Erick Velez Date: 2026-07-13T22:22:53-07:00 New Revision: 1bd46015ea4e842091109cd2a491c55c0b455330
URL: https://github.com/llvm/llvm-project/commit/1bd46015ea4e842091109cd2a491c55c0b455330 DIFF: https://github.com/llvm/llvm-project/commit/1bd46015ea4e842091109cd2a491c55c0b455330.diff LOG: [clang-doc] Remove the YAML generator (#209350) The original intent of the YAML generator was to package the documentation information in a structured and reusable way. It has been superseded by the JSON generator. Added: Modified: clang-tools-extra/clang-doc/CMakeLists.txt clang-tools-extra/clang-doc/Generators.cpp clang-tools-extra/clang-doc/Generators.h clang-tools-extra/clang-doc/Representation.h clang-tools-extra/clang-doc/tool/ClangDocMain.cpp clang-tools-extra/docs/ReleaseNotes.rst clang-tools-extra/unittests/clang-doc/CMakeLists.txt Removed: clang-tools-extra/clang-doc/YAMLGenerator.cpp clang-tools-extra/test/clang-doc/yaml/builtin_types.cpp clang-tools-extra/test/clang-doc/yaml/conversion_function.cpp clang-tools-extra/test/clang-doc/yaml/single-file-public.cpp clang-tools-extra/test/clang-doc/yaml/single-file.cpp clang-tools-extra/test/clang-doc/yaml/templates.cpp clang-tools-extra/unittests/clang-doc/YAMLGeneratorTest.cpp ################################################################################ diff --git a/clang-tools-extra/clang-doc/CMakeLists.txt b/clang-tools-extra/clang-doc/CMakeLists.txt index 76d3c98d3299e..1a3e62742e956 100644 --- a/clang-tools-extra/clang-doc/CMakeLists.txt +++ b/clang-tools-extra/clang-doc/CMakeLists.txt @@ -15,7 +15,6 @@ add_clang_library(clangDoc STATIC MDGenerator.cpp Representation.cpp Serialize.cpp - YAMLGenerator.cpp JSONGenerator.cpp DEPENDS diff --git a/clang-tools-extra/clang-doc/Generators.cpp b/clang-tools-extra/clang-doc/Generators.cpp index c0933f06c1789..fa4af5344d262 100644 --- a/clang-tools-extra/clang-doc/Generators.cpp +++ b/clang-tools-extra/clang-doc/Generators.cpp @@ -248,7 +248,6 @@ void Generator::addInfoToIndex(Index &Idx, const doc::Info *Info) { // This anchor is used to force the linker to link in the generated object file // and thus register the generators. -[[maybe_unused]] static int YAMLGeneratorAnchorDest = YAMLGeneratorAnchorSource; [[maybe_unused]] static int MDGeneratorAnchorDest = MDGeneratorAnchorSource; [[maybe_unused]] static int HTMLGeneratorAnchorDest = HTMLGeneratorAnchorSource; [[maybe_unused]] static int JSONGeneratorAnchorDest = JSONGeneratorAnchorSource; diff --git a/clang-tools-extra/clang-doc/Generators.h b/clang-tools-extra/clang-doc/Generators.h index 7b2d5c7f97f5e..674f98108507f 100644 --- a/clang-tools-extra/clang-doc/Generators.h +++ b/clang-tools-extra/clang-doc/Generators.h @@ -140,7 +140,6 @@ struct MustacheGenerator : public Generator { // This anchor is used to force the linker to link in the generated object file // and thus register the generators. -extern volatile int YAMLGeneratorAnchorSource; extern volatile int MDGeneratorAnchorSource; extern volatile int HTMLGeneratorAnchorSource; extern volatile int JSONGeneratorAnchorSource; diff --git a/clang-tools-extra/clang-doc/Representation.h b/clang-tools-extra/clang-doc/Representation.h index 3a7a6deb3d0a3..74ac26442018f 100644 --- a/clang-tools-extra/clang-doc/Representation.h +++ b/clang-tools-extra/clang-doc/Representation.h @@ -225,7 +225,7 @@ enum class CommentKind { CK_Unknown }; -enum OutputFormatTy { md, yaml, html, json }; +enum OutputFormatTy { md, html, json }; CommentKind stringToCommentKind(llvm::StringRef KindStr); llvm::StringRef commentKindToString(CommentKind Kind); diff --git a/clang-tools-extra/clang-doc/YAMLGenerator.cpp b/clang-tools-extra/clang-doc/YAMLGenerator.cpp deleted file mode 100644 index 7ccf526c59e22..0000000000000 --- a/clang-tools-extra/clang-doc/YAMLGenerator.cpp +++ /dev/null @@ -1,585 +0,0 @@ -//===-- YAMLGenerator.cpp - ClangDoc YAML -----------------------*- C++ -*-===// -// -// 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 -// -//===----------------------------------------------------------------------===// -// Implementation of the YAML generator, converting decl info into YAML output. -//===----------------------------------------------------------------------===// - -#include "Generators.h" -#include "Representation.h" -#include "llvm/ADT/STLExtras.h" -#include "llvm/Support/YAMLTraits.h" -#include "llvm/Support/raw_ostream.h" -#include <optional> - -using namespace clang::doc; - -// These define YAML traits for decoding the listed values within a vector. -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(FunctionInfo) -LLVM_YAML_IS_SEQUENCE_VECTOR(EnumInfo) -LLVM_YAML_IS_SEQUENCE_VECTOR(EnumValueInfo) -LLVM_YAML_IS_SEQUENCE_VECTOR(TemplateParamInfo) -LLVM_YAML_IS_SEQUENCE_VECTOR(TypedefInfo) -LLVM_YAML_IS_SEQUENCE_VECTOR(BaseRecordInfo) - -namespace llvm { - -namespace yaml { - -// Provide SequenceTraits for ArrayRef<T*> since YAMLTraits only provides it for -// MutableArrayRef -template <typename T> struct SequenceTraits<ArrayRef<T *>> { - static size_t size(IO &io, ArrayRef<T *> &seq) { return seq.size(); } - static T *&element(IO &io, ArrayRef<T *> &seq, size_t index) { - // ArrayRef is not mutable, but YAML output only reads the value. - return const_cast<T *&>(seq[index]); - } -}; - -template <typename T> struct SequenceTraits<llvm::simple_ilist<T>> { - static size_t size(IO &io, llvm::simple_ilist<T> &seq) { return seq.size(); } - static T &element(IO &io, llvm::simple_ilist<T> &seq, size_t index) { - return *std::next(seq.begin(), index); - } -}; - -template <typename T> struct SequenceTraits<clang::doc::DocList<T>> { - static size_t size(IO &io, clang::doc::DocList<T> &seq) { return seq.size(); } - static T &element(IO &io, clang::doc::DocList<T> &seq, size_t index) { - return *(std::next(seq.begin(), index)); - } -}; - -// Map pointers to the value mappings as clang-doc only does output -// serialization. -template <typename T> struct PointerMappingTraits { - static void mapping(IO &IO, T *&Val) { - if (Val) - MappingTraits<T>::mapping(IO, *Val); - } -}; - -template <> -struct MappingTraits<clang::doc::Reference *> - : PointerMappingTraits<clang::doc::Reference> {}; -template <> -struct MappingTraits<clang::doc::CommentInfo *> - : PointerMappingTraits<clang::doc::CommentInfo> {}; -template <> -struct MappingTraits<clang::doc::FunctionInfo *> - : PointerMappingTraits<clang::doc::FunctionInfo> {}; -template <> -struct MappingTraits<clang::doc::EnumInfo *> - : PointerMappingTraits<clang::doc::EnumInfo> {}; -template <> -struct MappingTraits<clang::doc::TemplateParamInfo *> - : PointerMappingTraits<clang::doc::TemplateParamInfo> {}; - -template <typename T> struct SequenceTraits<ArrayRef<T>> { - static size_t size(IO &io, llvm::ArrayRef<T> &seq) { return seq.size(); } - static T &element(IO &io, llvm::ArrayRef<T> &seq, size_t index) { - return const_cast<T &>(seq[index]); - } -}; - -// 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::Struct); - IO.enumCase(Value, "Interface", clang::TagTypeKind::Interface); - IO.enumCase(Value, "Union", clang::TagTypeKind::Union); - IO.enumCase(Value, "Class", clang::TagTypeKind::Class); - IO.enumCase(Value, "Enum", clang::TagTypeKind::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); - } -}; - -template <> struct ScalarEnumerationTraits<clang::doc::CommentKind> { - static void enumeration(IO &IO, clang::doc::CommentKind &Value) { - IO.enumCase(Value, "FullComment", clang::doc::CommentKind::CK_FullComment); - IO.enumCase(Value, "ParagraphComment", - clang::doc::CommentKind::CK_ParagraphComment); - IO.enumCase(Value, "TextComment", clang::doc::CommentKind::CK_TextComment); - IO.enumCase(Value, "InlineCommandComment", - clang::doc::CommentKind::CK_InlineCommandComment); - IO.enumCase(Value, "HTMLStartTagComment", - clang::doc::CommentKind::CK_HTMLStartTagComment); - IO.enumCase(Value, "HTMLEndTagComment", - clang::doc::CommentKind::CK_HTMLEndTagComment); - IO.enumCase(Value, "BlockCommandComment", - clang::doc::CommentKind::CK_BlockCommandComment); - IO.enumCase(Value, "ParamCommandComment", - clang::doc::CommentKind::CK_ParamCommandComment); - IO.enumCase(Value, "TParamCommandComment", - clang::doc::CommentKind::CK_TParamCommandComment); - IO.enumCase(Value, "VerbatimBlockComment", - clang::doc::CommentKind::CK_VerbatimBlockComment); - IO.enumCase(Value, "VerbatimBlockLineComment", - clang::doc::CommentKind::CK_VerbatimBlockLineComment); - IO.enumCase(Value, "VerbatimLineComment", - clang::doc::CommentKind::CK_VerbatimLineComment); - IO.enumCase(Value, "Unknown", clang::doc::CommentKind::CK_Unknown); - } -}; - -// Scalars to YAML output. - -template <> struct ScalarTraits<SymbolID> { - - static void output(const SymbolID &S, void *, llvm::raw_ostream &OS) { - OS << toHex(toStringRef(S)); - } - - static StringRef input(StringRef Scalar, void *, SymbolID &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); - llvm::copy(HexString, USR.begin()); - return SymbolID(USR); - } - - static QuotingType mustQuote(StringRef) { return QuotingType::Single; } -}; - -/// A wrapper for StringRef to force YAML traits to single-quote the string. -struct QuotedString { - StringRef Ref; - QuotedString() = default; - explicit QuotedString(StringRef R) : Ref(R) {} - explicit operator StringRef() const { return Ref; } - bool operator==(const QuotedString &Other) const { return Ref == Other.Ref; } -}; - -template <> struct ScalarTraits<QuotedString> { - static void output(const QuotedString &S, void *, llvm::raw_ostream &OS) { - OS << S.Ref; - } - static StringRef input(StringRef Scalar, void *, QuotedString &Value) { - Value.Ref = Scalar; - return StringRef(); - } - static QuotingType mustQuote(StringRef) { return QuotingType::Single; } -}; -} // end namespace yaml -} // end namespace llvm - -LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::QuotedString) - -namespace llvm { -namespace yaml { - -// 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); - - QuotedString QName(I.Name); - IO.mapOptional("Name", QName, QuotedString(StringRef())); - if (!IO.outputting()) - I.Name = QName.Ref; - - QuotedString QDefault(I.DefaultValue); - IO.mapOptional("DefaultValue", QDefault, QuotedString(StringRef())); - if (!IO.outputting()) - I.DefaultValue = QDefault.Ref; -} - -static void infoMapping(IO &IO, Info &I) { - IO.mapRequired("USR", I.USR); - - QuotedString QName(I.Name); - IO.mapOptional("Name", QName, QuotedString(StringRef())); - if (!IO.outputting()) - I.Name = QName.Ref; - - QuotedString QPath(I.Path); - IO.mapOptional("Path", QPath, QuotedString(StringRef())); - if (!IO.outputting()) - I.Path = QPath.Ref; - - 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, std::optional<Location>()); - IO.mapOptional("Location", I.Loc); -} - -static void recordInfoMapping(IO &IO, RecordInfo &I) { - symbolInfoMapping(IO, I); - IO.mapOptional("TagType", I.TagType); - IO.mapOptional("IsTypeDef", I.IsTypeDef, false); - IO.mapOptional("Members", I.Members); - IO.mapOptional("Bases", I.Bases); - IO.mapOptional("Parents", I.Parents, SmallVector<Reference, 4>()); - IO.mapOptional("VirtualParents", I.VirtualParents, - llvm::SmallVector<Reference, 4>()); - IO.mapOptional("ChildRecords", I.Children.Records); - IO.mapOptional("ChildFunctions", I.Children.Functions); - IO.mapOptional("ChildEnums", I.Children.Enums); - IO.mapOptional("ChildTypedefs", I.Children.Typedefs); - IO.mapOptional("Template", I.Template); -} - -static void commentInfoMapping(IO &IO, CommentInfo &I) { - IO.mapOptional("Kind", I.Kind, CommentKind::CK_Unknown); - - QuotedString QText(I.Text); - IO.mapOptional("Text", QText, QuotedString(StringRef())); - if (!IO.outputting()) - I.Text = QText.Ref; - - QuotedString QName(I.Name); - IO.mapOptional("Name", QName, QuotedString(StringRef())); - if (!IO.outputting()) - I.Name = QName.Ref; - - QuotedString QDirection(I.Direction); - IO.mapOptional("Direction", QDirection, QuotedString(StringRef())); - if (!IO.outputting()) - I.Direction = QDirection.Ref; - - QuotedString QParamName(I.ParamName); - IO.mapOptional("ParamName", QParamName, QuotedString(StringRef())); - if (!IO.outputting()) - I.ParamName = QParamName.Ref; - - QuotedString QCloseName(I.CloseName); - IO.mapOptional("CloseName", QCloseName, QuotedString(StringRef())); - if (!IO.outputting()) - I.CloseName = QCloseName.Ref; - - IO.mapOptional("SelfClosing", I.SelfClosing, false); - IO.mapOptional("Explicit", I.Explicit, false); - - std::vector<QuotedString> QArgs; - if (IO.outputting()) { - for (auto &S : I.Args) - QArgs.push_back(QuotedString(S)); - } - IO.mapOptional("Args", QArgs, std::vector<QuotedString>()); - - std::vector<QuotedString> QAttrKeys; - if (IO.outputting()) { - for (auto &S : I.AttrKeys) - QAttrKeys.push_back(QuotedString(S)); - } - IO.mapOptional("AttrKeys", QAttrKeys, std::vector<QuotedString>()); - - std::vector<QuotedString> QAttrValues; - if (IO.outputting()) { - for (auto &S : I.AttrValues) - QAttrValues.push_back(QuotedString(S)); - } - IO.mapOptional("AttrValues", QAttrValues, std::vector<QuotedString>()); - - 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.StartLineNumber, 0); - - QuotedString QFilename(Loc.Filename); - IO.mapOptional("Filename", QFilename, QuotedString(StringRef())); - if (!IO.outputting()) - Loc.Filename = QFilename.Ref; - } -}; - -template <> struct MappingTraits<Reference> { - static void mapping(IO &IO, Reference &Ref) { - IO.mapOptional("Type", Ref.RefType, InfoType::IT_default); - - QuotedString QName(Ref.Name); - IO.mapOptional("Name", QName, QuotedString(StringRef())); - if (!IO.outputting()) - Ref.Name = QName.Ref; - - QuotedString QQualName(Ref.QualName); - IO.mapOptional("QualName", QQualName, QuotedString(StringRef())); - if (!IO.outputting()) - Ref.QualName = QQualName.Ref; - - IO.mapOptional("USR", Ref.USR, SymbolID()); - - QuotedString QPath(Ref.Path); - IO.mapOptional("Path", QPath, QuotedString(StringRef())); - if (!IO.outputting()) - Ref.Path = QPath.Ref; - } -}; - -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); - - QuotedString QName(I.Name); - IO.mapOptional("Name", QName, QuotedString(StringRef())); - if (!IO.outputting()) - I.Name = QName.Ref; - - QuotedString QDefault(I.DefaultValue); - IO.mapOptional("DefaultValue", QDefault, QuotedString(StringRef())); - if (!IO.outputting()) - I.DefaultValue = QDefault.Ref; - } -}; - -template <> struct MappingTraits<MemberTypeInfo> { - static void mapping(IO &IO, MemberTypeInfo &I) { - fieldTypeInfoMapping(IO, I); - // clang::AccessSpecifier::AS_none is used as the default here because it's - // the AS that shouldn't be part of the output. Even though AS_public is the - // default in the struct, it should be displayed in the YAML output. - IO.mapOptional("Access", I.Access, clang::AccessSpecifier::AS_none); - IO.mapOptional("Description", I.Description); - } -}; - -template <> struct MappingTraits<NamespaceInfo> { - static void mapping(IO &IO, NamespaceInfo &I) { - infoMapping(IO, I); - std::vector<Reference> TempNamespaces; - for (const auto &N : I.Children.Namespaces) - TempNamespaces.push_back(N); - IO.mapOptional("ChildNamespaces", TempNamespaces, std::vector<Reference>()); - IO.mapOptional("ChildRecords", I.Children.Records); - IO.mapOptional("ChildFunctions", I.Children.Functions); - IO.mapOptional("ChildEnums", I.Children.Enums); - IO.mapOptional("ChildTypedefs", I.Children.Typedefs); - } -}; - -template <> struct MappingTraits<RecordInfo> { - static void mapping(IO &IO, RecordInfo &I) { recordInfoMapping(IO, I); } -}; - -template <> struct MappingTraits<BaseRecordInfo> { - static void mapping(IO &IO, BaseRecordInfo &I) { - recordInfoMapping(IO, I); - IO.mapOptional("IsVirtual", I.IsVirtual, false); - // clang::AccessSpecifier::AS_none is used as the default here because it's - // the AS that shouldn't be part of the output. Even though AS_public is the - // default in the struct, it should be displayed in the YAML output. - IO.mapOptional("Access", I.Access, clang::AccessSpecifier::AS_none); - IO.mapOptional("IsParent", I.IsParent, false); - } -}; - -template <> struct MappingTraits<EnumValueInfo> { - static void mapping(IO &IO, EnumValueInfo &I) { - QuotedString QName(I.Name); - IO.mapOptional("Name", QName, QuotedString(StringRef())); - if (!IO.outputting()) - I.Name = QName.Ref; - - QuotedString QValue(I.Value); - IO.mapOptional("Value", QValue, QuotedString(StringRef())); - if (!IO.outputting()) - I.Value = QValue.Ref; - - QuotedString QExpr(I.ValueExpr); - IO.mapOptional("Expr", QExpr, QuotedString(StringRef())); - if (!IO.outputting()) - I.ValueExpr = QExpr.Ref; - } -}; - -template <> struct MappingTraits<EnumInfo> { - static void mapping(IO &IO, EnumInfo &I) { - symbolInfoMapping(IO, I); - IO.mapOptional("Scoped", I.Scoped, false); - IO.mapOptional("BaseType", I.BaseType); - IO.mapOptional("Members", I.Members); - } -}; - -template <> struct MappingTraits<TypedefInfo> { - static void mapping(IO &IO, TypedefInfo &I) { - symbolInfoMapping(IO, I); - IO.mapOptional("Underlying", I.Underlying.Type); - IO.mapOptional("IsUsing", I.IsUsing, false); - } -}; - -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); - // clang::AccessSpecifier::AS_none is used as the default here because it's - // the AS that shouldn't be part of the output. Even though AS_public is the - // default in the struct, it should be displayed in the YAML output. - IO.mapOptional("Access", I.Access, clang::AccessSpecifier::AS_none); - IO.mapOptional("Template", I.Template); - } -}; - -template <> struct MappingTraits<TemplateParamInfo> { - static void mapping(IO &IO, TemplateParamInfo &I) { - QuotedString QContents(I.Contents); - IO.mapOptional("Contents", QContents, QuotedString(StringRef())); - if (!IO.outputting()) - I.Contents = QContents.Ref; - } -}; - -template <> struct MappingTraits<TemplateSpecializationInfo> { - static void mapping(IO &IO, TemplateSpecializationInfo &I) { - IO.mapOptional("SpecializationOf", I.SpecializationOf); - IO.mapOptional("Params", I.Params); - } -}; - -template <> struct MappingTraits<TemplateInfo> { - static void mapping(IO &IO, TemplateInfo &I) { - IO.mapOptional("Params", I.Params); - IO.mapOptional("Specialization", I.Specialization, - std::optional<TemplateSpecializationInfo>()); - } -}; - -template <> struct MappingTraits<CommentInfo> { - static void mapping(IO &IO, CommentInfo &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; - - llvm::Error generateDocumentation(StringRef RootDir, - llvm::StringMap<doc::Info *> Infos, - const ClangDocContext &CDCtx, - std::string DirName) override; - llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS, - const ClangDocContext &CDCtx) override; -}; - -const char *YAMLGenerator::Format = "yaml"; - -llvm::Error YAMLGenerator::generateDocumentation( - StringRef RootDir, llvm::StringMap<doc::Info *> Infos, - const ClangDocContext &CDCtx, std::string DirName) { - for (const auto &Group : Infos) { - doc::Info *Info = Group.getValue(); - - // Output file names according to the USR except the global namesapce. - // Anonymous namespaces are taken care of in serialization, so here we can - // safely assume an unnamed namespace is the global one. - llvm::SmallString<128> Path; - llvm::sys::path::native(RootDir, Path); - if (Info->IT == InfoType::IT_namespace && Info->Name.empty()) { - llvm::sys::path::append(Path, "index.yaml"); - } else { - llvm::sys::path::append(Path, Group.getKey() + ".yaml"); - } - - std::error_code FileErr; - llvm::raw_fd_ostream InfoOS(Path, FileErr, llvm::sys::fs::OF_Text); - if (FileErr) { - return llvm::createStringError(FileErr, "Error opening file '%s'", - Path.c_str()); - } - - if (llvm::Error Err = generateDocForInfo(Info, InfoOS, CDCtx)) { - return Err; - } - } - - return llvm::Error::success(); -} - -llvm::Error YAMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS, - const ClangDocContext &CDCtx) { - llvm::yaml::Output InfoYAML(OS); - switch (I->IT) { - case InfoType::IT_namespace: - InfoYAML << *cast<NamespaceInfo>(I); - break; - case InfoType::IT_record: - InfoYAML << *cast<RecordInfo>(I); - break; - case InfoType::IT_enum: - InfoYAML << *cast<EnumInfo>(I); - break; - case InfoType::IT_function: - InfoYAML << *cast<FunctionInfo>(I); - break; - case InfoType::IT_typedef: - InfoYAML << *cast<TypedefInfo>(I); - break; - case InfoType::IT_concept: - case InfoType::IT_variable: - case InfoType::IT_friend: - break; - case InfoType::IT_default: - return llvm::createStringError(llvm::inconvertibleErrorCode(), - "unexpected InfoType"); - } - return llvm::Error::success(); -} - -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 diff --git a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp index c3e61e26612aa..00290d7cdc74b 100644 --- a/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp +++ b/clang-tools-extra/clang-doc/tool/ClangDocMain.cpp @@ -119,23 +119,19 @@ static llvm::cl::opt<bool> static llvm::cl::opt<OutputFormatTy> FormatEnum("format", llvm::cl::desc("Format for outputted docs."), - llvm::cl::values(clEnumValN(OutputFormatTy::yaml, "yaml", - "Documentation in YAML format."), - clEnumValN(OutputFormatTy::md, "md", + llvm::cl::values(clEnumValN(OutputFormatTy::md, "md", "Documentation in MD format."), clEnumValN(OutputFormatTy::html, "html", "Documentation in HTML format."), clEnumValN(OutputFormatTy::json, "json", "Documentation in JSON format")), - llvm::cl::init(OutputFormatTy::yaml), + llvm::cl::init(OutputFormatTy::json), llvm::cl::cat(ClangDocCategory)); static llvm::ExitOnError ExitOnErr; static llvm::StringRef getFormatString() { switch (FormatEnum) { - case OutputFormatTy::yaml: - return "yaml"; case OutputFormatTy::md: return "md"; case OutputFormatTy::html: diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index cd568efb274ff..beb29752c7863 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -135,6 +135,9 @@ Potentially Breaking Changes now uses the new Mustache-backed MD generator. It is possible that there are some regressions in MD output. +- Removed the :program:`clang-doc` YAML generator. Prefer the JSON generator to + get documentation information in a reusable format. + Improvements to clangd ---------------------- diff --git a/clang-tools-extra/test/clang-doc/yaml/builtin_types.cpp b/clang-tools-extra/test/clang-doc/yaml/builtin_types.cpp deleted file mode 100644 index 7a0defb165194..0000000000000 --- a/clang-tools-extra/test/clang-doc/yaml/builtin_types.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// RUN: rm -rf %t -// RUN: mkdir -p %t/yaml %t/md %t/md_mustache -// RUN: clang-doc --doxygen --executor=standalone %S/../Inputs/builtin_types.cpp -output=%t/yaml -// RUN: FileCheck %s < %t/yaml/index.yaml --check-prefix=YAML - -// YAML: --- -// YAML-NEXT: USR: '0000000000000000000000000000000000000000' -// YAML-NEXT: ChildFunctions: - -// YAML-NEXT: - USR: '88A104C263241E354ECF5B55B04AE8CEAD625B71' -// YAML-NEXT: Name: 'b' -// YAML-NEXT: Location: -// YAML-NEXT: - LineNumber: 1 -// YAML-NEXT: Filename: '{{.*}}' -// YAML-NEXT: ReturnType: -// YAML-NEXT: Type: -// YAML-NEXT: Name: 'bool' -// YAML-NEXT: QualName: 'bool' - -// YAML-NEXT: - USR: 'EA3287837B3F175C8DB154406B4DAD2924F479B5' -// YAML-NEXT: Name: 'c' -// YAML-NEXT: Location: -// YAML-NEXT: - LineNumber: 2 -// YAML-NEXT: Filename: '{{.*}}' -// YAML-NEXT: ReturnType: -// YAML-NEXT: Type: -// YAML-NEXT: Name: 'char' -// YAML-NEXT: QualName: 'char' - -// YAML-NEXT: - USR: '60A47E4696CEFC411AB2E1EEFA2DD914E2A7E450' -// YAML-NEXT: Name: 'd' -// YAML-NEXT: Location: -// YAML-NEXT: - LineNumber: 3 -// YAML-NEXT: Filename: '{{.*}}' -// YAML-NEXT: ReturnType: -// YAML-NEXT: Type: -// YAML-NEXT: Name: 'double' -// YAML-NEXT: QualName: 'double' - -// YAML-NEXT: - USR: 'B3A9EC6BECD5869CF3ACDFB25153CFE6BBDD5EAB' -// YAML-NEXT: Name: 'f' -// YAML-NEXT: Location: -// YAML-NEXT: - LineNumber: 4 -// YAML-NEXT: Filename: '{{.*}}' -// YAML-NEXT: ReturnType: -// YAML-NEXT: Type: -// YAML-NEXT: Name: 'float' -// YAML-NEXT: QualName: 'float' - -// YAML-NEXT: - USR: '307041280A81EB46F949A94AD52587C659FD801C' -// YAML-NEXT: Name: 'i' -// YAML-NEXT: Location: -// YAML-NEXT: - LineNumber: 5 -// YAML-NEXT: Filename: '{{.*}}' -// YAML-NEXT: ReturnType: -// YAML-NEXT: Type: -// YAML-NEXT: Name: 'int' -// YAML-NEXT: QualName: 'int' - -// YAML-NEXT: - USR: 'A1CE9AB0064C412F857592E01332C641C1A06F37' -// YAML-NEXT: Name: 'l' -// YAML-NEXT: Location: -// YAML-NEXT: - LineNumber: 6 -// YAML-NEXT: Filename: '{{.*}}' -// YAML-NEXT: ReturnType: -// YAML-NEXT: Type: -// YAML-NEXT: Name: 'long' -// YAML-NEXT: QualName: 'long' - -// YAML-NEXT: - USR: '5C2C44ED4825C066EF6ED796863586F343C8BCA9' -// YAML-NEXT: Name: 'll' -// YAML-NEXT: Location: -// YAML-NEXT: - LineNumber: 7 -// YAML-NEXT: Filename: '{{.*}}' -// YAML-NEXT: ReturnType: -// YAML-NEXT: Type: -// YAML-NEXT: Name: 'long long' -// YAML-NEXT: QualName: 'long long' - -// YAML-NEXT: - USR: '412341570FD3AD2C3A1E9A1DE7B3C01C07BEACFE' -// YAML-NEXT: Name: 's' -// YAML-NEXT: Location: -// YAML-NEXT: - LineNumber: 8 -// YAML-NEXT: Filename: '{{.*}}' -// YAML-NEXT: ReturnType: -// YAML-NEXT: Type: -// YAML-NEXT: Name: 'short' -// YAML-NEXT: QualName: 'short' -// YAML-NEXT: ... diff --git a/clang-tools-extra/test/clang-doc/yaml/conversion_function.cpp b/clang-tools-extra/test/clang-doc/yaml/conversion_function.cpp deleted file mode 100644 index 47305e4a7c8d7..0000000000000 --- a/clang-tools-extra/test/clang-doc/yaml/conversion_function.cpp +++ /dev/null @@ -1,6 +0,0 @@ -// RUN: rm -rf %t && mkdir -p %t -// RUN: clang-doc --output=%t --executor=standalone %S/../Inputs/conversion_function.cpp -// RUN: find %t/ -regex ".*/[0-9A-F]*.yaml" -exec cat {} ";" | FileCheck %s --check-prefix=CHECK-YAML - -// Output correct conversion names. -// CHECK-YAML: Name: 'operator T' diff --git a/clang-tools-extra/test/clang-doc/yaml/single-file-public.cpp b/clang-tools-extra/test/clang-doc/yaml/single-file-public.cpp deleted file mode 100644 index 29ef67e61ca63..0000000000000 --- a/clang-tools-extra/test/clang-doc/yaml/single-file-public.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// RUN: rm -rf %t && mkdir -p %t -// RUN: echo "" > %t/compile_flags.txt -// RUN: cp "%S/../Inputs/single-file-public.cpp" "%t/test.cpp" -// RUN: clang-doc --doxygen --public --executor=standalone -p %t %t/test.cpp -output=%t/docs -// This produces two files, index.yaml and one for the record named by its USR diff --git a/clang-tools-extra/test/clang-doc/yaml/single-file.cpp b/clang-tools-extra/test/clang-doc/yaml/single-file.cpp deleted file mode 100644 index 2b7650ca2ffa1..0000000000000 --- a/clang-tools-extra/test/clang-doc/yaml/single-file.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// RUN: rm -rf %t && mkdir -p %t -// RUN: echo "" > %t/compile_flags.txt -// RUN: cp "%S/../Inputs/single-file.cpp" "%t/test.cpp" -// RUN: clang-doc --doxygen --executor=standalone -p %t %t/test.cpp -output=%t/docs -// RUN: FileCheck %s -input-file=%t/docs/index.yaml --check-prefix=CHECK - -// CHECK: --- -// CHECK-NEXT: USR: '{{([0-9A-F]{40})}}' -// CHECK-NEXT: ChildFunctions: -// CHECK-NEXT: - USR: '{{([0-9A-F]{40})}}' -// CHECK-NEXT: Name: 'function' -// CHECK-NEXT: DefLocation: -// CHECK-NEXT: LineNumber: 3 -// CHECK-NEXT: Filename: '{{.*}} -// CHECK-NEXT: Location: -// CHECK-NEXT: - LineNumber: 1 -// CHECK-NEXT: Filename: '{{.*}}' -// CHECK-NEXT: Params: -// CHECK-NEXT: - Type: -// CHECK-NEXT: Name: 'int' -// CHECK-NEXT: QualName: 'int' -// CHECK-NEXT: Name: 'x' -// CHECK-NEXT: ReturnType: -// CHECK-NEXT: Type: -// CHECK-NEXT: Name: 'void' -// CHECK-NEXT: QualName: 'void' -// CHECK-NEXT:... diff --git a/clang-tools-extra/test/clang-doc/yaml/templates.cpp b/clang-tools-extra/test/clang-doc/yaml/templates.cpp deleted file mode 100644 index 21b7085ef39dd..0000000000000 --- a/clang-tools-extra/test/clang-doc/yaml/templates.cpp +++ /dev/null @@ -1,148 +0,0 @@ -// RUN: rm -rf %t && mkdir -p %t -// RUN: clang-doc --doxygen --executor=standalone %S/../Inputs/templates.cpp -output=%t/docs -// RUN: cat %t/docs/index.yaml | FileCheck %s --check-prefix=YAML - -// YAML: --- -// YAML-NEXT: USR: '{{([0-9A-F]{40})}}' -// YAML-NEXT: ChildRecords: -// YAML-NEXT: - Type: Record -// YAML-NEXT: Name: 'tuple' -// YAML-NEXT: QualName: 'tuple' -// YAML-NEXT: USR: '{{([0-9A-F]{40})}}' -// YAML-NEXT: Path: 'GlobalNamespace' -// YAML-NEXT: ChildFunctions: -// YAML-NEXT: - USR: '{{([0-9A-F]{40})}}' -// YAML-NEXT: Name: 'ParamPackFunction' -// YAML-NEXT: Location: -// YAML-NEXT: - LineNumber: 1 -// YAML-NEXT: Filename: '{{.*}}' -// YAML-NEXT: Params: -// YAML-NEXT: - Type: -// YAML-NEXT: Name: 'T...' -// YAML-NEXT: QualName: 'T...' -// YAML-NEXT: Name: 'args' -// YAML-NEXT: ReturnType: -// YAML-NEXT: Type: -// YAML-NEXT: Name: 'void' -// YAML-NEXT: QualName: 'void' -// YAML-NEXT: Template: -// YAML-NEXT: Params: -// YAML-NEXT: - Contents: 'class... T' - -// YAML-NEXT: - USR: '{{([0-9A-F]{40})}}' -// YAML-NEXT: Name: 'function' -// YAML-NEXT: DefLocation: -// YAML-NEXT: LineNumber: 3 -// YAML-NEXT: Filename: '{{.*}}' -// YAML-NEXT: Params: -// YAML-NEXT: - Type: -// YAML-NEXT: Name: 'T' -// YAML-NEXT: QualName: 'T' -// YAML-NEXT: Name: 'x' -// YAML-NEXT: ReturnType: -// YAML-NEXT: Type: -// YAML-NEXT: Name: 'void' -// YAML-NEXT: QualName: 'void' -// YAML-NEXT: Template: -// YAML-NEXT: Params: -// YAML-NEXT: - Contents: 'typename T' -// YAML-NEXT: - Contents: 'int U = 1' - -// YAML-NEXT: - USR: '{{([0-9A-F]{40})}}' -// YAML-NEXT: Name: 'longFunction' -// YAML-NEXT: DefLocation: -// YAML-NEXT: LineNumber: 6 -// YAML-NEXT: Filename: '{{.*}}' -// YAML-NEXT: Params: -// YAML-NEXT: - Type: -// YAML-NEXT: Name: 'A' -// YAML-NEXT: QualName: 'A' -// YAML-NEXT: Name: 'a' -// YAML-NEXT: - Type: -// YAML-NEXT: Name: 'B' -// YAML-NEXT: QualName: 'B' -// YAML-NEXT: Name: 'b' -// YAML-NEXT: - Type: -// YAML-NEXT: Name: 'C' -// YAML-NEXT: QualName: 'C' -// YAML-NEXT: Name: 'c' -// YAML-NEXT: - Type: -// YAML-NEXT: Name: 'D' -// YAML-NEXT: QualName: 'D' -// YAML-NEXT: Name: 'd' -// YAML-NEXT: - Type: -// YAML-NEXT: Name: 'E' -// YAML-NEXT: QualName: 'E' -// YAML-NEXT: Name: 'e' -// YAML-NEXT: ReturnType: -// YAML-NEXT: Type: -// YAML-NEXT: Name: 'void' -// YAML-NEXT: QualName: 'void' -// YAML-NEXT: Template: -// YAML-NEXT: Params: -// YAML-NEXT: - Contents: 'typename A' -// YAML-NEXT: - Contents: 'typename B' -// YAML-NEXT: - Contents: 'typename C' -// YAML-NEXT: - Contents: 'typename D' -// YAML-NEXT: - Contents: 'typename E' - -// YAML-NEXT: - USR: '{{([0-9A-F]{40})}}' -// YAML-NEXT: Name: 'function' -// YAML-NEXT: DefLocation: -// YAML-NEXT: LineNumber: 8 -// YAML-NEXT: Filename: '{{.*}}' -// YAML-NEXT: Params: -// YAML-NEXT: - Type: -// YAML-NEXT: Name: 'bool' -// YAML-NEXT: QualName: 'bool' -// YAML-NEXT: Name: 'x' -// YAML-NEXT: ReturnType: -// YAML-NEXT: Type: -// YAML-NEXT: Name: 'void' -// YAML-NEXT: QualName: 'void' -// YAML-NEXT: Template: -// YAML-NEXT: Specialization: -// YAML-NEXT: SpecializationOf: '{{([0-9A-F]{40})}}' -// YAML-NEXT: Params: -// YAML-NEXT: - Contents: 'bool' -// YAML-NEXT: - Contents: '0' - -// YAML-NEXT: - USR: '{{([0-9A-F]{40})}}' -// YAML-NEXT: Name: 'func_with_tuple_param' -// YAML-NEXT: Description: -// YAML-NEXT: - Kind: FullComment -// YAML-NEXT: Children: -// YAML-NEXT: - Kind: ParagraphComment -// YAML-NEXT: Children: -// YAML-NEXT: - Kind: TextComment -// YAML-NEXT: Text: 'A function with a tuple parameter' -// YAML-NEXT: - Kind: ParagraphComment -// YAML-NEXT: Children: -// YAML-NEXT: - Kind: TextComment -// YAML-NEXT: - Kind: ParamCommandComment -// YAML-NEXT: Direction: '[in]' -// YAML-NEXT: ParamName: 't' -// YAML-NEXT: Children: -// YAML-NEXT: - Kind: ParagraphComment -// YAML-NEXT: Children: -// YAML-NEXT: - Kind: TextComment -// YAML-NEXT: Text: 'The input to func_with_tuple_param' -// YAML-NEXT: DefLocation: -// YAML-NEXT: LineNumber: 18 -// YAML-NEXT: Filename: -// YAML-NEXT: Params: -// YAML-NEXT: - Type: -// YAML-NEXT: Type: Record -// YAML-NEXT: Name: 'tuple' -// YAML-NEXT: QualName: 'tuple<int, int, bool>' -// YAML-NEXT: USR: '{{([0-9A-F]{40})}}' -// YAML-NEXT: Path: 'GlobalNamespace' -// YAML-NEXT: Name: 't' -// YAML-NEXT: ReturnType: -// YAML-NEXT: Type: -// YAML-NEXT: Type: Record -// YAML-NEXT: Name: 'tuple' -// YAML-NEXT: QualName: 'tuple<int, int, bool>' -// YAML-NEXT: USR: '{{([0-9A-F]{40})}}' -// YAML-NEXT: Path: 'GlobalNamespace' -// YAML-NEXT: ... diff --git a/clang-tools-extra/unittests/clang-doc/CMakeLists.txt b/clang-tools-extra/unittests/clang-doc/CMakeLists.txt index ed95c3d39698a..dc5110bffb9ae 100644 --- a/clang-tools-extra/unittests/clang-doc/CMakeLists.txt +++ b/clang-tools-extra/unittests/clang-doc/CMakeLists.txt @@ -28,7 +28,6 @@ add_extra_unittest(ClangDocTests HTMLGeneratorTest.cpp MergeTest.cpp SerializeTest.cpp - YAMLGeneratorTest.cpp JSONGeneratorTest.cpp ) diff --git a/clang-tools-extra/unittests/clang-doc/YAMLGeneratorTest.cpp b/clang-tools-extra/unittests/clang-doc/YAMLGeneratorTest.cpp deleted file mode 100644 index 7a1126f1035ee..0000000000000 --- a/clang-tools-extra/unittests/clang-doc/YAMLGeneratorTest.cpp +++ /dev/null @@ -1,593 +0,0 @@ -//===-- clang-doc/YAMLGeneratorTest.cpp -//------------------------------------===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#include "ClangDocTest.h" -#include "Generators.h" -#include "Representation.h" -#include "gtest/gtest.h" - -namespace clang { -namespace doc { - -static std::unique_ptr<Generator> getYAMLGenerator() { - auto G = doc::findGeneratorByName("yaml"); - if (!G) - return nullptr; - return std::move(G.get()); -} - -class YAMLGeneratorTest : public ClangDocContextTest {}; - -TEST_F(YAMLGeneratorTest, emitNamespaceYAML) { - NamespaceInfo I; - I.Name = "Namespace"; - I.Path = "path/to/A"; - Reference Ns[] = {Reference(EmptySID, "A", InfoType::IT_namespace)}; - I.Namespace = llvm::ArrayRef(Ns); - - Reference NewNamespace(EmptySID, "ChildNamespace", InfoType::IT_namespace, - "path::to::A::Namespace::ChildNamespace", - "path/to/A/Namespace"); - InfoNode<Reference> NewNamespaceNode(&NewNamespace); - I.Children.Namespaces.push_back(NewNamespaceNode); - - Reference ChildStruct(EmptySID, "ChildStruct", InfoType::IT_record, - "path::to::A::Namespace::ChildStruct", - "path/to/A/Namespace"); - InfoNode<Reference> ChildStructNode(&ChildStruct); - I.Children.Records.push_back(ChildStructNode); - - FunctionInfo F; - F.Name = "OneFunction"; - F.Access = AccessSpecifier::AS_none; - InfoNode<FunctionInfo> FNode(&F); - I.Children.Functions.push_back(FNode); - - EnumInfo E; - E.Name = "OneEnum"; - InfoNode<EnumInfo> ENode(&E); - I.Children.Enums.push_back(ENode); - - auto G = getYAMLGenerator(); - assert(G); - std::string Buffer; - llvm::raw_string_ostream Actual(Buffer); - auto Err = G->generateDocForInfo(&I, Actual, getClangDocContext()); - assert(!Err); - std::string Expected = - R"raw(--- -USR: '0000000000000000000000000000000000000000' -Name: 'Namespace' -Path: 'path/to/A' -Namespace: - - Type: Namespace - Name: 'A' - QualName: 'A' -ChildNamespaces: - - Type: Namespace - Name: 'ChildNamespace' - QualName: 'path::to::A::Namespace::ChildNamespace' - Path: 'path/to/A/Namespace' -ChildRecords: - - Type: Record - Name: 'ChildStruct' - QualName: 'path::to::A::Namespace::ChildStruct' - Path: 'path/to/A/Namespace' -ChildFunctions: - - USR: '0000000000000000000000000000000000000000' - Name: 'OneFunction' - ReturnType: {} -ChildEnums: - - USR: '0000000000000000000000000000000000000000' - Name: 'OneEnum' -... -)raw"; - EXPECT_EQ(Expected, Actual.str()); -} - -TEST_F(YAMLGeneratorTest, emitRecordYAML) { - RecordInfo I; - I.Name = "r"; - I.Path = "path/to/A"; - I.IsTypeDef = true; - Reference Ns[] = {Reference(EmptySID, "A", InfoType::IT_namespace)}; - I.Namespace = llvm::ArrayRef(Ns); - - I.DefLoc = Location(10, 10, "test.cpp"); - Location Loc1(12, 12, "test.cpp"); - InfoNode<Location> Loc1Node(&Loc1); - I.Loc.push_back(Loc1Node); - - MemberTypeInfo M(TypeInfo("int"), "X", AccessSpecifier::AS_private); - - // Member documentation. - CommentInfo BriefChildren[] = {CommentInfo(CommentKind::CK_TextComment, {}, - "Value of the thing.", - "ParagraphComment")}; - CommentInfo TopCommentChildren[] = { - CommentInfo(CommentKind::CK_ParagraphComment, BriefChildren)}; - CommentInfo TopComment(CommentKind::CK_FullComment, TopCommentChildren); - InfoNode<CommentInfo> TopCommentNode(&TopComment); - M.Description.push_back(TopCommentNode); - MemberTypeInfo MemArr[] = {std::move(M)}; - I.Members = llvm::ArrayRef(MemArr); - - I.TagType = TagTypeKind::Class; - BaseRecordInfo B(EmptySID, "F", "path/to/F", true, AccessSpecifier::AS_public, - true); - FunctionInfo F; - F.Name = "InheritedFunctionOne"; - InfoNode<FunctionInfo> FNode(&F); - B.Children.Functions.push_back(FNode); - MemberTypeInfo BMem[] = { - MemberTypeInfo(TypeInfo("int"), "N", AccessSpecifier::AS_private)}; - B.Members = llvm::ArrayRef(BMem); - BaseRecordInfo Bases[] = {std::move(B)}; - I.Bases = llvm::ArrayRef(Bases); - - // F is in the global namespace - Reference Parents[] = {Reference(EmptySID, "F", InfoType::IT_record, "")}; - I.Parents = llvm::ArrayRef(Parents); - Reference VParents[] = {Reference(EmptySID, "G", InfoType::IT_record, - "path::to::G::G", "path/to/G")}; - I.VirtualParents = llvm::ArrayRef(VParents); - - Reference ChildStruct(EmptySID, "ChildStruct", InfoType::IT_record, - "path::to::A::r::ChildStruct", "path/to/A/r"); - InfoNode<Reference> ChildStructNode(&ChildStruct); - I.Children.Records.push_back(ChildStructNode); - - FunctionInfo F2; - F2.Name = "OneFunction"; - InfoNode<FunctionInfo> F2Node(&F2); - I.Children.Functions.push_back(F2Node); - - EnumInfo E; - E.Name = "OneEnum"; - InfoNode<EnumInfo> ENode(&E); - I.Children.Enums.push_back(ENode); - - auto G = getYAMLGenerator(); - assert(G); - std::string Buffer; - llvm::raw_string_ostream Actual(Buffer); - auto Err = G->generateDocForInfo(&I, Actual, getClangDocContext()); - assert(!Err); - std::string Expected = - R"raw(--- -USR: '0000000000000000000000000000000000000000' -Name: 'r' -Path: 'path/to/A' -Namespace: - - Type: Namespace - Name: 'A' - QualName: 'A' -DefLocation: - LineNumber: 10 - Filename: 'test.cpp' -Location: - - LineNumber: 12 - Filename: 'test.cpp' -TagType: Class -IsTypeDef: true -Members: - - Type: - Name: 'int' - QualName: 'int' - Name: 'X' - Access: Private - Description: - - Kind: FullComment - Children: - - Kind: ParagraphComment - Children: - - Kind: TextComment - Text: 'Value of the thing.' - Name: 'ParagraphComment' -Bases: - - USR: '0000000000000000000000000000000000000000' - Name: 'F' - Path: 'path/to/F' - TagType: Struct - Members: - - Type: - Name: 'int' - QualName: 'int' - Name: 'N' - Access: Private - ChildFunctions: - - USR: '0000000000000000000000000000000000000000' - Name: 'InheritedFunctionOne' - ReturnType: {} - Access: Public - IsVirtual: true - Access: Public - IsParent: true -Parents: - - Type: Record - Name: 'F' -VirtualParents: - - Type: Record - Name: 'G' - QualName: 'path::to::G::G' - Path: 'path/to/G' -ChildRecords: - - Type: Record - Name: 'ChildStruct' - QualName: 'path::to::A::r::ChildStruct' - Path: 'path/to/A/r' -ChildFunctions: - - USR: '0000000000000000000000000000000000000000' - Name: 'OneFunction' - ReturnType: {} - Access: Public -ChildEnums: - - USR: '0000000000000000000000000000000000000000' - Name: 'OneEnum' -... -)raw"; - EXPECT_EQ(Expected, Actual.str()); -} - -TEST_F(YAMLGeneratorTest, emitFunctionYAML) { - FunctionInfo I; - I.Name = "f"; - Reference Ns[] = {Reference(EmptySID, "A", InfoType::IT_namespace)}; - I.Namespace = llvm::ArrayRef(Ns); - - I.DefLoc = Location(10, 10, "test.cpp"); - Location Loc1(12, 12, "test.cpp"); - InfoNode<Location> Loc1Node(&Loc1); - I.Loc.push_back(Loc1Node); - - I.Access = AccessSpecifier::AS_none; - - I.ReturnType = TypeInfo(Reference(EmptySID, "void", InfoType::IT_default)); - - FieldTypeInfo P1(TypeInfo("int"), "P"); - FieldTypeInfo D(TypeInfo("double"), "D"); - D.DefaultValue = "2.0 * M_PI"; - FieldTypeInfo Params[] = {std::move(P1), std::move(D)}; - I.Params = llvm::ArrayRef(Params); - I.IsMethod = true; - I.Parent = Reference(EmptySID, "Parent", InfoType::IT_record); - - auto G = getYAMLGenerator(); - assert(G); - std::string Buffer; - llvm::raw_string_ostream Actual(Buffer); - auto Err = G->generateDocForInfo(&I, Actual, getClangDocContext()); - assert(!Err); - std::string Expected = - R"raw(--- -USR: '0000000000000000000000000000000000000000' -Name: 'f' -Namespace: - - Type: Namespace - Name: 'A' - QualName: 'A' -DefLocation: - LineNumber: 10 - Filename: 'test.cpp' -Location: - - LineNumber: 12 - Filename: 'test.cpp' -IsMethod: true -Parent: - Type: Record - Name: 'Parent' - QualName: 'Parent' -Params: - - Type: - Name: 'int' - QualName: 'int' - Name: 'P' - - Type: - Name: 'double' - QualName: 'double' - Name: 'D' - DefaultValue: '2.0 * M_PI' -ReturnType: - Type: - Name: 'void' - QualName: 'void' -... -)raw"; - EXPECT_EQ(Expected, Actual.str()); -} - -// Tests the equivalent of: -// namespace A { -// enum e { X }; -// } -TEST_F(YAMLGeneratorTest, emitSimpleEnumYAML) { - EnumInfo I; - I.Name = "e"; - Reference Ns[] = {Reference(EmptySID, "A", InfoType::IT_namespace)}; - I.Namespace = llvm::ArrayRef(Ns); - - I.DefLoc = Location(10, 10, "test.cpp"); - Location Loc1(12, 12, "test.cpp"); - InfoNode<Location> Loc1Node(&Loc1); - I.Loc.push_back(Loc1Node); - - EnumValueInfo EV[] = {EnumValueInfo("X")}; - I.Members = llvm::ArrayRef(EV); - I.Scoped = false; - - auto G = getYAMLGenerator(); - assert(G); - std::string Buffer; - llvm::raw_string_ostream Actual(Buffer); - auto Err = G->generateDocForInfo(&I, Actual, getClangDocContext()); - assert(!Err); - std::string Expected = - R"raw(--- -USR: '0000000000000000000000000000000000000000' -Name: 'e' -Namespace: - - Type: Namespace - Name: 'A' - QualName: 'A' -DefLocation: - LineNumber: 10 - Filename: 'test.cpp' -Location: - - LineNumber: 12 - Filename: 'test.cpp' -Members: - - Name: 'X' - Value: '0' -... -)raw"; - EXPECT_EQ(Expected, Actual.str()); -} - -// Tests the equivalent of: -// enum class e : short { X = FOO_BAR + 2 }; -TEST_F(YAMLGeneratorTest, enumTypedScopedEnumYAML) { - EnumInfo I; - I.Name = "e"; - - EnumValueInfo EV[] = {EnumValueInfo("X", "-9876", "FOO_BAR + 2")}; - I.Members = llvm::ArrayRef(EV); - I.Scoped = true; - I.BaseType = TypeInfo("short"); - - auto G = getYAMLGenerator(); - assert(G); - std::string Buffer; - llvm::raw_string_ostream Actual(Buffer); - auto Err = G->generateDocForInfo(&I, Actual, getClangDocContext()); - assert(!Err); - std::string Expected = - R"raw(--- -USR: '0000000000000000000000000000000000000000' -Name: 'e' -Scoped: true -BaseType: - Type: - Name: 'short' - QualName: 'short' -Members: - - Name: 'X' - Value: '-9876' - Expr: 'FOO_BAR + 2' -... -)raw"; - EXPECT_EQ(Expected, Actual.str()); -} - -TEST_F(YAMLGeneratorTest, enumTypedefYAML) { - TypedefInfo I; - I.Name = "MyUsing"; - I.Underlying = TypeInfo("int"); - I.IsUsing = true; - - auto G = getYAMLGenerator(); - assert(G); - std::string Buffer; - llvm::raw_string_ostream Actual(Buffer); - auto Err = G->generateDocForInfo(&I, Actual, getClangDocContext()); - assert(!Err); - std::string Expected = - R"raw(--- -USR: '0000000000000000000000000000000000000000' -Name: 'MyUsing' -Underlying: - Name: 'int' - QualName: 'int' -IsUsing: true -... -)raw"; - EXPECT_EQ(Expected, Actual.str()); -} - -TEST_F(YAMLGeneratorTest, emitCommentYAML) { - FunctionInfo I; - I.Name = "f"; - I.DefLoc = Location(10, 10, "test.cpp"); - I.ReturnType = TypeInfo("void"); - FieldTypeInfo Params[] = {FieldTypeInfo(TypeInfo("int"), "I"), - FieldTypeInfo(TypeInfo("int"), "J")}; - I.Params = llvm::ArrayRef(Params); - I.Access = AccessSpecifier::AS_none; - - // BlankLine - CommentInfo BlankChildren[] = {CommentInfo(CommentKind::CK_TextComment)}; - CommentInfo BlankLine(CommentKind::CK_ParagraphComment, BlankChildren); - - // Brief - CommentInfo BriefChildren[] = {CommentInfo(CommentKind::CK_TextComment, {}, - " Brief description.", - "ParagraphComment")}; - CommentInfo Brief(CommentKind::CK_ParagraphComment, BriefChildren); - - // Extended - CommentInfo ExtChildren[] = {CommentInfo(CommentKind::CK_TextComment, {}, - " Extended description that"), - CommentInfo(CommentKind::CK_TextComment, {}, - " continues onto the next line.")}; - CommentInfo Extended(CommentKind::CK_ParagraphComment, ExtChildren); - - // HTML - StringRef HtmlKeys[] = {"class"}; - StringRef HtmlValues[] = {"test"}; - CommentInfo HtmlStart(CommentKind::CK_HTMLStartTagComment, {}, "", "ul", "", - "", "", false, false, HtmlKeys, HtmlValues); - CommentInfo HtmlStartLi(CommentKind::CK_HTMLStartTagComment, {}, "", "li"); - CommentInfo HtmlEnd(CommentKind::CK_HTMLEndTagComment, {}, "", "ul", "", "", - "", false, true); - - CommentInfo HtmlChildren[] = { - CommentInfo(CommentKind::CK_TextComment), HtmlStart, HtmlStartLi, - CommentInfo(CommentKind::CK_TextComment, {}, " Testing."), HtmlEnd}; - CommentInfo HTML(CommentKind::CK_ParagraphComment, HtmlChildren); - - // Verbatim - CommentInfo VerbLine(CommentKind::CK_VerbatimBlockLineComment, {}, - " The description continues."); - CommentInfo VerbChildren[] = {VerbLine}; - CommentInfo Verbatim(CommentKind::CK_VerbatimBlockComment, VerbChildren, "", - "verbatim", "endverbatim"); - - // ParamOut - CommentInfo ParamOutParaChildren[] = { - CommentInfo(CommentKind::CK_TextComment), - CommentInfo(CommentKind::CK_TextComment, {}, " is a parameter.")}; - CommentInfo ParamOutPara(CommentKind::CK_ParagraphComment, - ParamOutParaChildren); - CommentInfo ParamOutChildren[] = {ParamOutPara}; - CommentInfo ParamOut(CommentKind::CK_ParamCommandComment, ParamOutChildren, - "", "", "", "[out]", "I", true); - - // ParamIn - CommentInfo ParamInParaChildren[] = { - CommentInfo(CommentKind::CK_TextComment, {}, " is a parameter."), - CommentInfo(CommentKind::CK_TextComment)}; - CommentInfo ParamInPara(CommentKind::CK_ParagraphComment, - ParamInParaChildren); - CommentInfo ParamInChildren[] = {ParamInPara}; - CommentInfo ParamIn(CommentKind::CK_ParamCommandComment, ParamInChildren, "", - "", "", "[in]", "J"); - - // Return - CommentInfo ReturnParaChildren[] = { - CommentInfo(CommentKind::CK_TextComment, {}, "void")}; - CommentInfo ReturnPara(CommentKind::CK_ParagraphComment, ReturnParaChildren); - CommentInfo ReturnChildren[] = {ReturnPara}; - CommentInfo Return(CommentKind::CK_BlockCommandComment, ReturnChildren, "", - "return", "", "", "", true); - - CommentInfo TopChildren[] = {BlankLine, Brief, Extended, HTML, - Verbatim, ParamOut, ParamIn, Return}; - CommentInfo Top(CommentKind::CK_FullComment, TopChildren); - InfoNode<CommentInfo> TopNode(&Top); - I.Description.push_back(TopNode); - - auto G = getYAMLGenerator(); - assert(G); - std::string Buffer; - llvm::raw_string_ostream Actual(Buffer); - auto Err = G->generateDocForInfo(&I, Actual, getClangDocContext()); - assert(!Err); - std::string Expected = - R"raw(--- -USR: '0000000000000000000000000000000000000000' -Name: 'f' -Description: - - Kind: FullComment - Children: - - Kind: ParagraphComment - Children: - - Kind: TextComment - - Kind: ParagraphComment - Children: - - Kind: TextComment - Text: ' Brief description.' - Name: 'ParagraphComment' - - Kind: ParagraphComment - Children: - - Kind: TextComment - Text: ' Extended description that' - - Kind: TextComment - Text: ' continues onto the next line.' - - Kind: ParagraphComment - Children: - - Kind: TextComment - - Kind: HTMLStartTagComment - Name: 'ul' - AttrKeys: - - 'class' - AttrValues: - - 'test' - - Kind: HTMLStartTagComment - Name: 'li' - - Kind: TextComment - Text: ' Testing.' - - Kind: HTMLEndTagComment - Name: 'ul' - SelfClosing: true - - Kind: VerbatimBlockComment - Name: 'verbatim' - CloseName: 'endverbatim' - Children: - - Kind: VerbatimBlockLineComment - Text: ' The description continues.' - - Kind: ParamCommandComment - Direction: '[out]' - ParamName: 'I' - Explicit: true - Children: - - Kind: ParagraphComment - Children: - - Kind: TextComment - - Kind: TextComment - Text: ' is a parameter.' - - Kind: ParamCommandComment - Direction: '[in]' - ParamName: 'J' - Children: - - Kind: ParagraphComment - Children: - - Kind: TextComment - Text: ' is a parameter.' - - Kind: TextComment - - Kind: BlockCommandComment - Name: 'return' - Explicit: true - Children: - - Kind: ParagraphComment - Children: - - Kind: TextComment - Text: 'void' -DefLocation: - LineNumber: 10 - Filename: 'test.cpp' -Params: - - Type: - Name: 'int' - QualName: 'int' - Name: 'I' - - Type: - Name: 'int' - QualName: 'int' - Name: 'J' -ReturnType: - Type: - Name: 'void' - QualName: 'void' -... -)raw"; - - EXPECT_EQ(Expected, Actual.str()); -} - -} // namespace doc -} // namespace clang _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
