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