clang-tools  9.0.0
YAMLGenerator.cpp
Go to the documentation of this file.
1 //===-- YAMLGenerator.cpp - ClangDoc YAML -----------------------*- 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 // Implementation of the YAML generator, converting decl info into YAML output.
9 //===----------------------------------------------------------------------===//
10 
11 #include "Generators.h"
12 #include "llvm/Support/YAMLTraits.h"
13 #include "llvm/Support/raw_ostream.h"
14 
15 using namespace clang::doc;
16 
17 LLVM_YAML_IS_SEQUENCE_VECTOR(FieldTypeInfo)
18 LLVM_YAML_IS_SEQUENCE_VECTOR(MemberTypeInfo)
19 LLVM_YAML_IS_SEQUENCE_VECTOR(Reference)
20 LLVM_YAML_IS_SEQUENCE_VECTOR(Location)
21 LLVM_YAML_IS_SEQUENCE_VECTOR(CommentInfo)
22 LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionInfo)
23 LLVM_YAML_IS_SEQUENCE_VECTOR(EnumInfo)
24 LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<CommentInfo>)
25 LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::SmallString<16>)
26 
27 namespace llvm {
28 namespace yaml {
29 
30 // Enumerations to YAML output.
31 
32 template <> struct ScalarEnumerationTraits<clang::AccessSpecifier> {
33  static void enumeration(IO &IO, clang::AccessSpecifier &Value) {
34  IO.enumCase(Value, "Public", clang::AccessSpecifier::AS_public);
35  IO.enumCase(Value, "Protected", clang::AccessSpecifier::AS_protected);
36  IO.enumCase(Value, "Private", clang::AccessSpecifier::AS_private);
37  IO.enumCase(Value, "None", clang::AccessSpecifier::AS_none);
38  }
39 };
40 
41 template <> struct ScalarEnumerationTraits<clang::TagTypeKind> {
42  static void enumeration(IO &IO, clang::TagTypeKind &Value) {
43  IO.enumCase(Value, "Struct", clang::TagTypeKind::TTK_Struct);
44  IO.enumCase(Value, "Interface", clang::TagTypeKind::TTK_Interface);
45  IO.enumCase(Value, "Union", clang::TagTypeKind::TTK_Union);
46  IO.enumCase(Value, "Class", clang::TagTypeKind::TTK_Class);
47  IO.enumCase(Value, "Enum", clang::TagTypeKind::TTK_Enum);
48  }
49 };
50 
51 template <> struct ScalarEnumerationTraits<InfoType> {
52  static void enumeration(IO &IO, InfoType &Value) {
53  IO.enumCase(Value, "Namespace", InfoType::IT_namespace);
54  IO.enumCase(Value, "Record", InfoType::IT_record);
55  IO.enumCase(Value, "Function", InfoType::IT_function);
56  IO.enumCase(Value, "Enum", InfoType::IT_enum);
57  IO.enumCase(Value, "Default", InfoType::IT_default);
58  }
59 };
60 
61 // Scalars to YAML output.
62 template <unsigned U> struct ScalarTraits<SmallString<U>> {
63 
64  static void output(const SmallString<U> &S, void *, llvm::raw_ostream &OS) {
65  for (const auto &C : S)
66  OS << C;
67  }
68 
69  static StringRef input(StringRef Scalar, void *, SmallString<U> &Value) {
70  Value.assign(Scalar.begin(), Scalar.end());
71  return StringRef();
72  }
73 
74  static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
75 };
76 
77 template <> struct ScalarTraits<std::array<unsigned char, 20>> {
78 
79  static void output(const std::array<unsigned char, 20> &S, void *,
80  llvm::raw_ostream &OS) {
81  OS << toHex(toStringRef(S));
82  }
83 
84  static StringRef input(StringRef Scalar, void *,
85  std::array<unsigned char, 20> &Value) {
86  if (Scalar.size() != 40)
87  return "Error: Incorrect scalar size for USR.";
88  Value = StringToSymbol(Scalar);
89  return StringRef();
90  }
91 
92  static SymbolID StringToSymbol(llvm::StringRef Value) {
93  SymbolID USR;
94  std::string HexString = fromHex(Value);
95  std::copy(HexString.begin(), HexString.end(), USR.begin());
96  return SymbolID(USR);
97  }
98 
99  static QuotingType mustQuote(StringRef) { return QuotingType::Single; }
100 };
101 
102 // Helper functions to map infos to YAML.
103 
104 static void TypeInfoMapping(IO &IO, TypeInfo &I) {
105  IO.mapOptional("Type", I.Type, Reference());
106 }
107 
108 static void FieldTypeInfoMapping(IO &IO, FieldTypeInfo &I) {
109  TypeInfoMapping(IO, I);
110  IO.mapOptional("Name", I.Name, SmallString<16>());
111 }
112 
113 static void InfoMapping(IO &IO, Info &I) {
114  IO.mapRequired("USR", I.USR);
115  IO.mapOptional("Name", I.Name, SmallString<16>());
116  IO.mapOptional("Path", I.Path, SmallString<128>());
117  IO.mapOptional("Namespace", I.Namespace, llvm::SmallVector<Reference, 4>());
118  IO.mapOptional("Description", I.Description);
119 }
120 
121 static void SymbolInfoMapping(IO &IO, SymbolInfo &I) {
122  InfoMapping(IO, I);
123  IO.mapOptional("DefLocation", I.DefLoc, Optional<Location>());
124  IO.mapOptional("Location", I.Loc, llvm::SmallVector<Location, 2>());
125 }
126 
127 static void CommentInfoMapping(IO &IO, CommentInfo &I) {
128  IO.mapOptional("Kind", I.Kind, SmallString<16>());
129  IO.mapOptional("Text", I.Text, SmallString<64>());
130  IO.mapOptional("Name", I.Name, SmallString<16>());
131  IO.mapOptional("Direction", I.Direction, SmallString<8>());
132  IO.mapOptional("ParamName", I.ParamName, SmallString<16>());
133  IO.mapOptional("CloseName", I.CloseName, SmallString<16>());
134  IO.mapOptional("SelfClosing", I.SelfClosing, false);
135  IO.mapOptional("Explicit", I.Explicit, false);
136  IO.mapOptional("Args", I.Args, llvm::SmallVector<SmallString<16>, 4>());
137  IO.mapOptional("AttrKeys", I.AttrKeys,
138  llvm::SmallVector<SmallString<16>, 4>());
139  IO.mapOptional("AttrValues", I.AttrValues,
140  llvm::SmallVector<SmallString<16>, 4>());
141  IO.mapOptional("Children", I.Children);
142 }
143 
144 // Template specialization to YAML traits for Infos.
145 
146 template <> struct MappingTraits<Location> {
147  static void mapping(IO &IO, Location &Loc) {
148  IO.mapOptional("LineNumber", Loc.LineNumber, 0);
149  IO.mapOptional("Filename", Loc.Filename, SmallString<32>());
150  }
151 };
152 
153 template <> struct MappingTraits<Reference> {
154  static void mapping(IO &IO, Reference &Ref) {
155  IO.mapOptional("Type", Ref.RefType, InfoType::IT_default);
156  IO.mapOptional("Name", Ref.Name, SmallString<16>());
157  IO.mapOptional("USR", Ref.USR, SymbolID());
158  IO.mapOptional("Path", Ref.Path, SmallString<128>());
159  }
160 };
161 
162 template <> struct MappingTraits<TypeInfo> {
163  static void mapping(IO &IO, TypeInfo &I) { TypeInfoMapping(IO, I); }
164 };
165 
166 template <> struct MappingTraits<FieldTypeInfo> {
167  static void mapping(IO &IO, FieldTypeInfo &I) {
168  TypeInfoMapping(IO, I);
169  IO.mapOptional("Name", I.Name, SmallString<16>());
170  }
171 };
172 
173 template <> struct MappingTraits<MemberTypeInfo> {
174  static void mapping(IO &IO, MemberTypeInfo &I) {
175  FieldTypeInfoMapping(IO, I);
176  IO.mapOptional("Access", I.Access, clang::AccessSpecifier::AS_none);
177  }
178 };
179 
180 template <> struct MappingTraits<NamespaceInfo> {
181  static void mapping(IO &IO, NamespaceInfo &I) {
182  InfoMapping(IO, I);
183  IO.mapOptional("ChildNamespaces", I.ChildNamespaces,
184  std::vector<Reference>());
185  IO.mapOptional("ChildRecords", I.ChildRecords, std::vector<Reference>());
186  IO.mapOptional("ChildFunctions", I.ChildFunctions);
187  IO.mapOptional("ChildEnums", I.ChildEnums);
188  }
189 };
190 
191 template <> struct MappingTraits<RecordInfo> {
192  static void mapping(IO &IO, RecordInfo &I) {
193  SymbolInfoMapping(IO, I);
194  IO.mapOptional("TagType", I.TagType, clang::TagTypeKind::TTK_Struct);
195  IO.mapOptional("Members", I.Members);
196  IO.mapOptional("Parents", I.Parents, llvm::SmallVector<Reference, 4>());
197  IO.mapOptional("VirtualParents", I.VirtualParents,
198  llvm::SmallVector<Reference, 4>());
199  IO.mapOptional("ChildRecords", I.ChildRecords, std::vector<Reference>());
200  IO.mapOptional("ChildFunctions", I.ChildFunctions);
201  IO.mapOptional("ChildEnums", I.ChildEnums);
202  }
203 };
204 
205 template <> struct MappingTraits<EnumInfo> {
206  static void mapping(IO &IO, EnumInfo &I) {
207  SymbolInfoMapping(IO, I);
208  IO.mapOptional("Scoped", I.Scoped, false);
209  IO.mapOptional("Members", I.Members);
210  }
211 };
212 
213 template <> struct MappingTraits<FunctionInfo> {
214  static void mapping(IO &IO, FunctionInfo &I) {
215  SymbolInfoMapping(IO, I);
216  IO.mapOptional("IsMethod", I.IsMethod, false);
217  IO.mapOptional("Parent", I.Parent, Reference());
218  IO.mapOptional("Params", I.Params);
219  IO.mapOptional("ReturnType", I.ReturnType);
220  IO.mapOptional("Access", I.Access, clang::AccessSpecifier::AS_none);
221  }
222 };
223 
224 template <> struct MappingTraits<CommentInfo> {
225  static void mapping(IO &IO, CommentInfo &I) { CommentInfoMapping(IO, I); }
226 };
227 
228 template <> struct MappingTraits<std::unique_ptr<CommentInfo>> {
229  static void mapping(IO &IO, std::unique_ptr<CommentInfo> &I) {
230  if (I)
231  CommentInfoMapping(IO, *I);
232  }
233 };
234 
235 } // end namespace yaml
236 } // end namespace llvm
237 
238 namespace clang {
239 namespace doc {
240 
241 /// Generator for YAML documentation.
242 class YAMLGenerator : public Generator {
243 public:
244  static const char *Format;
245 
246  llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS) override;
247 };
248 
249 const char *YAMLGenerator::Format = "yaml";
250 
251 llvm::Error YAMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS) {
252  llvm::yaml::Output InfoYAML(OS);
253  switch (I->IT) {
255  InfoYAML << *static_cast<clang::doc::NamespaceInfo *>(I);
256  break;
257  case InfoType::IT_record:
258  InfoYAML << *static_cast<clang::doc::RecordInfo *>(I);
259  break;
260  case InfoType::IT_enum:
261  InfoYAML << *static_cast<clang::doc::EnumInfo *>(I);
262  break;
264  InfoYAML << *static_cast<clang::doc::FunctionInfo *>(I);
265  break;
267  return llvm::make_error<llvm::StringError>("Unexpected info type.\n",
268  llvm::inconvertibleErrorCode());
269  }
270  return llvm::Error::success();
271 }
272 
273 static GeneratorRegistry::Add<YAMLGenerator> YAML(YAMLGenerator::Format,
274  "Generator for YAML output.");
275 
276 // This anchor is used to force the linker to link in the generated object file
277 // and thus register the generator.
278 volatile int YAMLGeneratorAnchorSource = 0;
279 
280 } // namespace doc
281 } // namespace clang
static void mapping(IO &IO, std::unique_ptr< CommentInfo > &I)
SourceLocation Loc
&#39;#&#39; location in the include directive
llvm::SmallVector< Reference, 4 > Namespace
Some operations such as code completion produce a set of candidates.
static void mapping(IO &IO, MemberTypeInfo &I)
static void mapping(IO &IO, Location &Loc)
Generator for YAML documentation.
SmallString< 16 > Name
static StringRef input(StringRef Scalar, void *, std::array< unsigned char, 20 > &Value)
std::vector< FunctionInfo > ChildFunctions
Represents a symbol occurrence in the source file.
Definition: Ref.h:52
static void SymbolInfoMapping(IO &IO, SymbolInfo &I)
static void enumeration(IO &IO, clang::TagTypeKind &Value)
static void InfoMapping(IO &IO, Info &I)
static void mapping(IO &IO, TypeInfo &I)
std::vector< FunctionInfo > ChildFunctions
llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS) override
static void TypeInfoMapping(IO &IO, TypeInfo &I)
std::vector< EnumInfo > ChildEnums
std::vector< Reference > ChildRecords
llvm::SmallVector< Reference, 4 > VirtualParents
static QuotingType mustQuote(StringRef)
llvm::SmallVector< FieldTypeInfo, 4 > Params
clang::find_all_symbols::SymbolInfo SymbolInfo
llvm::SmallVector< SmallString< 16 >, 4 > Members
static void mapping(IO &IO, Reference &Ref)
llvm::SmallVector< SmallString< 16 >, 4 > AttrValues
std::vector< CommentInfo > Description
static void enumeration(IO &IO, InfoType &Value)
volatile int YAMLGeneratorAnchorSource
static void mapping(IO &IO, CommentInfo &I)
llvm::SmallVector< SmallString< 16 >, 4 > Args
SmallString< 16 > Name
static void output(const SmallString< U > &S, void *, llvm::raw_ostream &OS)
A base struct for Infos.
static void mapping(IO &IO, FunctionInfo &I)
llvm::SmallString< 128 > Path
static void mapping(IO &IO, NamespaceInfo &I)
llvm::SmallVector< Reference, 4 > Parents
static void enumeration(IO &IO, clang::AccessSpecifier &Value)
static StringRef input(StringRef Scalar, void *, SmallString< U > &Value)
static GeneratorRegistry::Add< YAMLGenerator > YAML(YAMLGenerator::Format, "Generator for YAML output.")
SmallString< 16 > ParamName
llvm::SmallVector< SmallString< 16 >, 4 > AttrKeys
SmallString< 16 > Name
static void mapping(IO &IO, RecordInfo &I)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
static SymbolID StringToSymbol(llvm::StringRef Value)
SmallString< 16 > Name
std::vector< Reference > ChildNamespaces
SmallString< 16 > CloseName
std::vector< Reference > ChildRecords
static const char * Format
SmallString< 32 > Filename
SmallString< 8 > Direction
const InfoType IT
std::vector< EnumInfo > ChildEnums
static void mapping(IO &IO, FieldTypeInfo &I)
static void FieldTypeInfoMapping(IO &IO, FieldTypeInfo &I)
llvm::SmallVector< MemberTypeInfo, 4 > Members
static void CommentInfoMapping(IO &IO, CommentInfo &I)
SmallString< 16 > Kind
std::vector< std::unique_ptr< CommentInfo > > Children
SmallString< 64 > Text
std::array< uint8_t, 20 > SymbolID
llvm::SmallString< 128 > Path
static void output(const std::array< unsigned char, 20 > &S, void *, llvm::raw_ostream &OS)
static void mapping(IO &IO, EnumInfo &I)