clang-tools  9.0.0
BitcodeWriter.cpp
Go to the documentation of this file.
1 //===-- BitcodeWriter.cpp - ClangDoc Bitcode Writer ------------*- 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 
9 #include "BitcodeWriter.h"
10 #include "llvm/ADT/IndexedMap.h"
11 #include <initializer_list>
12 
13 namespace clang {
14 namespace doc {
15 
16 // Empty SymbolID for comparison, so we don't have to construct one every time.
17 static const SymbolID EmptySID = SymbolID();
18 
19 // Since id enums are not zero-indexed, we need to transform the given id into
20 // its associated index.
22  using argument_type = unsigned;
23  unsigned operator()(unsigned ID) const { return ID - BI_FIRST; }
24 };
25 
27  using argument_type = unsigned;
28  unsigned operator()(unsigned ID) const { return ID - RI_FIRST; }
29 };
30 
31 using AbbrevDsc = void (*)(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev);
32 
33 static void AbbrevGen(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev,
34  const std::initializer_list<llvm::BitCodeAbbrevOp> Ops) {
35  for (const auto &Op : Ops)
36  Abbrev->Add(Op);
37 }
38 
39 static void BoolAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev) {
40  AbbrevGen(Abbrev,
41  {// 0. Boolean
42  llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
44 }
45 
46 static void IntAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev) {
47  AbbrevGen(Abbrev,
48  {// 0. Fixed-size integer
49  llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
51 }
52 
53 static void SymbolIDAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev) {
54  AbbrevGen(Abbrev,
55  {// 0. Fixed-size integer (length of the sha1'd USR)
56  llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
58  // 1. Fixed-size array of Char6 (USR)
59  llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Array),
60  llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
62 }
63 
64 static void StringAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev) {
65  AbbrevGen(Abbrev,
66  {// 0. Fixed-size integer (length of the following string)
67  llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
69  // 1. The string blob
70  llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)});
71 }
72 
73 // Assumes that the file will not have more than 65535 lines.
74 static void LocationAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev) {
75  AbbrevGen(
76  Abbrev,
77  {// 0. Fixed-size integer (line number)
78  llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
80  // 1. Fixed-size integer (length of the following string (filename))
81  llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
83  // 2. The string blob
84  llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)});
85 }
86 
87 struct RecordIdDsc {
88  llvm::StringRef Name;
89  AbbrevDsc Abbrev = nullptr;
90 
91  RecordIdDsc() = default;
92  RecordIdDsc(llvm::StringRef Name, AbbrevDsc Abbrev)
93  : Name(Name), Abbrev(Abbrev) {}
94 
95  // Is this 'description' valid?
96  operator bool() const {
97  return Abbrev != nullptr && Name.data() != nullptr && !Name.empty();
98  }
99 };
100 
101 static const llvm::IndexedMap<llvm::StringRef, BlockIdToIndexFunctor>
102  BlockIdNameMap = []() {
103  llvm::IndexedMap<llvm::StringRef, BlockIdToIndexFunctor> BlockIdNameMap;
104  BlockIdNameMap.resize(BlockIdCount);
105 
106  // There is no init-list constructor for the IndexedMap, so have to
107  // improvise
108  static const std::vector<std::pair<BlockId, const char *const>> Inits = {
109  {BI_VERSION_BLOCK_ID, "VersionBlock"},
110  {BI_NAMESPACE_BLOCK_ID, "NamespaceBlock"},
111  {BI_ENUM_BLOCK_ID, "EnumBlock"},
112  {BI_TYPE_BLOCK_ID, "TypeBlock"},
113  {BI_FIELD_TYPE_BLOCK_ID, "FieldTypeBlock"},
114  {BI_MEMBER_TYPE_BLOCK_ID, "MemberTypeBlock"},
115  {BI_RECORD_BLOCK_ID, "RecordBlock"},
116  {BI_FUNCTION_BLOCK_ID, "FunctionBlock"},
117  {BI_COMMENT_BLOCK_ID, "CommentBlock"},
118  {BI_REFERENCE_BLOCK_ID, "ReferenceBlock"}};
119  assert(Inits.size() == BlockIdCount);
120  for (const auto &Init : Inits)
121  BlockIdNameMap[Init.first] = Init.second;
122  assert(BlockIdNameMap.size() == BlockIdCount);
123  return BlockIdNameMap;
124  }();
125 
126 static const llvm::IndexedMap<RecordIdDsc, RecordIdToIndexFunctor>
128  llvm::IndexedMap<RecordIdDsc, RecordIdToIndexFunctor> RecordIdNameMap;
129  RecordIdNameMap.resize(RecordIdCount);
130 
131  // There is no init-list constructor for the IndexedMap, so have to
132  // improvise
133  static const std::vector<std::pair<RecordId, RecordIdDsc>> Inits = {
134  {VERSION, {"Version", &IntAbbrev}},
135  {COMMENT_KIND, {"Kind", &StringAbbrev}},
136  {COMMENT_TEXT, {"Text", &StringAbbrev}},
137  {COMMENT_NAME, {"Name", &StringAbbrev}},
138  {COMMENT_DIRECTION, {"Direction", &StringAbbrev}},
139  {COMMENT_PARAMNAME, {"ParamName", &StringAbbrev}},
140  {COMMENT_CLOSENAME, {"CloseName", &StringAbbrev}},
141  {COMMENT_SELFCLOSING, {"SelfClosing", &BoolAbbrev}},
142  {COMMENT_EXPLICIT, {"Explicit", &BoolAbbrev}},
143  {COMMENT_ATTRKEY, {"AttrKey", &StringAbbrev}},
144  {COMMENT_ATTRVAL, {"AttrVal", &StringAbbrev}},
145  {COMMENT_ARG, {"Arg", &StringAbbrev}},
146  {FIELD_TYPE_NAME, {"Name", &StringAbbrev}},
147  {MEMBER_TYPE_NAME, {"Name", &StringAbbrev}},
148  {MEMBER_TYPE_ACCESS, {"Access", &IntAbbrev}},
149  {NAMESPACE_USR, {"USR", &SymbolIDAbbrev}},
150  {NAMESPACE_NAME, {"Name", &StringAbbrev}},
151  {NAMESPACE_PATH, {"Path", &StringAbbrev}},
152  {ENUM_USR, {"USR", &SymbolIDAbbrev}},
153  {ENUM_NAME, {"Name", &StringAbbrev}},
154  {ENUM_DEFLOCATION, {"DefLocation", &LocationAbbrev}},
155  {ENUM_LOCATION, {"Location", &LocationAbbrev}},
156  {ENUM_MEMBER, {"Member", &StringAbbrev}},
157  {ENUM_SCOPED, {"Scoped", &BoolAbbrev}},
158  {RECORD_USR, {"USR", &SymbolIDAbbrev}},
159  {RECORD_NAME, {"Name", &StringAbbrev}},
160  {RECORD_PATH, {"Path", &StringAbbrev}},
161  {RECORD_DEFLOCATION, {"DefLocation", &LocationAbbrev}},
162  {RECORD_LOCATION, {"Location", &LocationAbbrev}},
163  {RECORD_TAG_TYPE, {"TagType", &IntAbbrev}},
164  {RECORD_IS_TYPE_DEF, {"IsTypeDef", &BoolAbbrev}},
165  {FUNCTION_USR, {"USR", &SymbolIDAbbrev}},
166  {FUNCTION_NAME, {"Name", &StringAbbrev}},
167  {FUNCTION_DEFLOCATION, {"DefLocation", &LocationAbbrev}},
168  {FUNCTION_LOCATION, {"Location", &LocationAbbrev}},
169  {FUNCTION_ACCESS, {"Access", &IntAbbrev}},
170  {FUNCTION_IS_METHOD, {"IsMethod", &BoolAbbrev}},
171  {REFERENCE_USR, {"USR", &SymbolIDAbbrev}},
172  {REFERENCE_NAME, {"Name", &StringAbbrev}},
173  {REFERENCE_TYPE, {"RefType", &IntAbbrev}},
174  {REFERENCE_PATH, {"Path", &StringAbbrev}},
175  {REFERENCE_FIELD, {"Field", &IntAbbrev}}};
176  assert(Inits.size() == RecordIdCount);
177  for (const auto &Init : Inits) {
178  RecordIdNameMap[Init.first] = Init.second;
179  assert((Init.second.Name.size() + 1) <= BitCodeConstants::RecordSize);
180  }
181  assert(RecordIdNameMap.size() == RecordIdCount);
182  return RecordIdNameMap;
183  }();
184 
185 static const std::vector<std::pair<BlockId, std::vector<RecordId>>>
187  // Version Block
189  // Comment Block
194  // Type Block
195  {BI_TYPE_BLOCK_ID, {}},
196  // FieldType Block
198  // MemberType Block
200  // Enum Block
203  ENUM_SCOPED}},
204  // Namespace Block
207  // Record Block
211  // Function Block
215  // Reference Block
218  REFERENCE_FIELD}}};
219 
220 // AbbreviationMap
221 
222 constexpr unsigned char BitCodeConstants::Signature[];
223 
224 void ClangDocBitcodeWriter::AbbreviationMap::add(RecordId RID,
225  unsigned AbbrevID) {
226  assert(RecordIdNameMap[RID] && "Unknown RecordId.");
227  assert(Abbrevs.find(RID) == Abbrevs.end() && "Abbreviation already added.");
228  Abbrevs[RID] = AbbrevID;
229 }
230 
231 unsigned ClangDocBitcodeWriter::AbbreviationMap::get(RecordId RID) const {
232  assert(RecordIdNameMap[RID] && "Unknown RecordId.");
233  assert(Abbrevs.find(RID) != Abbrevs.end() && "Unknown abbreviation.");
234  return Abbrevs.lookup(RID);
235 }
236 
237 // Validation and Overview Blocks
238 
239 /// \brief Emits the magic number header to check that its the right format,
240 /// in this case, 'DOCS'.
241 void ClangDocBitcodeWriter::emitHeader() {
242  for (char C : BitCodeConstants::Signature)
243  Stream.Emit((unsigned)C, BitCodeConstants::SignatureBitSize);
244 }
245 
246 void ClangDocBitcodeWriter::emitVersionBlock() {
247  StreamSubBlockGuard Block(Stream, BI_VERSION_BLOCK_ID);
248  emitRecord(VersionNumber, VERSION);
249 }
250 
251 /// \brief Emits a block ID and the block name to the BLOCKINFO block.
252 void ClangDocBitcodeWriter::emitBlockID(BlockId BID) {
253  const auto &BlockIdName = BlockIdNameMap[BID];
254  assert(BlockIdName.data() && BlockIdName.size() && "Unknown BlockId.");
255 
256  Record.clear();
257  Record.push_back(BID);
258  Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETBID, Record);
259  Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_BLOCKNAME,
260  ArrayRef<unsigned char>(BlockIdName.bytes_begin(),
261  BlockIdName.bytes_end()));
262 }
263 
264 /// \brief Emits a record name to the BLOCKINFO block.
265 void ClangDocBitcodeWriter::emitRecordID(RecordId ID) {
266  assert(RecordIdNameMap[ID] && "Unknown RecordId.");
267  prepRecordData(ID);
268  Record.append(RecordIdNameMap[ID].Name.begin(),
269  RecordIdNameMap[ID].Name.end());
270  Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETRECORDNAME, Record);
271 }
272 
273 // Abbreviations
274 
275 void ClangDocBitcodeWriter::emitAbbrev(RecordId ID, BlockId Block) {
276  assert(RecordIdNameMap[ID] && "Unknown abbreviation.");
277  auto Abbrev = std::make_shared<llvm::BitCodeAbbrev>();
278  Abbrev->Add(llvm::BitCodeAbbrevOp(ID));
279  RecordIdNameMap[ID].Abbrev(Abbrev);
280  Abbrevs.add(ID, Stream.EmitBlockInfoAbbrev(Block, std::move(Abbrev)));
281 }
282 
283 // Records
284 
285 void ClangDocBitcodeWriter::emitRecord(const SymbolID &Sym, RecordId ID) {
286  assert(RecordIdNameMap[ID] && "Unknown RecordId.");
287  assert(RecordIdNameMap[ID].Abbrev == &SymbolIDAbbrev &&
288  "Abbrev type mismatch.");
289  if (!prepRecordData(ID, Sym != EmptySID))
290  return;
291  assert(Sym.size() == 20);
292  Record.push_back(Sym.size());
293  Record.append(Sym.begin(), Sym.end());
294  Stream.EmitRecordWithAbbrev(Abbrevs.get(ID), Record);
295 }
296 
297 void ClangDocBitcodeWriter::emitRecord(llvm::StringRef Str, RecordId ID) {
298  assert(RecordIdNameMap[ID] && "Unknown RecordId.");
299  assert(RecordIdNameMap[ID].Abbrev == &StringAbbrev &&
300  "Abbrev type mismatch.");
301  if (!prepRecordData(ID, !Str.empty()))
302  return;
303  assert(Str.size() < (1U << BitCodeConstants::StringLengthSize));
304  Record.push_back(Str.size());
305  Stream.EmitRecordWithBlob(Abbrevs.get(ID), Record, Str);
306 }
307 
308 void ClangDocBitcodeWriter::emitRecord(const Location &Loc, RecordId ID) {
309  assert(RecordIdNameMap[ID] && "Unknown RecordId.");
310  assert(RecordIdNameMap[ID].Abbrev == &LocationAbbrev &&
311  "Abbrev type mismatch.");
312  if (!prepRecordData(ID, true))
313  return;
314  // FIXME: Assert that the line number is of the appropriate size.
315  Record.push_back(Loc.LineNumber);
316  assert(Loc.Filename.size() < (1U << BitCodeConstants::StringLengthSize));
317  Record.push_back(Loc.Filename.size());
318  Stream.EmitRecordWithBlob(Abbrevs.get(ID), Record, Loc.Filename);
319 }
320 
321 void ClangDocBitcodeWriter::emitRecord(bool Val, RecordId ID) {
322  assert(RecordIdNameMap[ID] && "Unknown RecordId.");
323  assert(RecordIdNameMap[ID].Abbrev == &BoolAbbrev && "Abbrev type mismatch.");
324  if (!prepRecordData(ID, Val))
325  return;
326  Record.push_back(Val);
327  Stream.EmitRecordWithAbbrev(Abbrevs.get(ID), Record);
328 }
329 
330 void ClangDocBitcodeWriter::emitRecord(int Val, RecordId ID) {
331  assert(RecordIdNameMap[ID] && "Unknown RecordId.");
332  assert(RecordIdNameMap[ID].Abbrev == &IntAbbrev && "Abbrev type mismatch.");
333  if (!prepRecordData(ID, Val))
334  return;
335  // FIXME: Assert that the integer is of the appropriate size.
336  Record.push_back(Val);
337  Stream.EmitRecordWithAbbrev(Abbrevs.get(ID), Record);
338 }
339 
340 void ClangDocBitcodeWriter::emitRecord(unsigned Val, RecordId ID) {
341  assert(RecordIdNameMap[ID] && "Unknown RecordId.");
342  assert(RecordIdNameMap[ID].Abbrev == &IntAbbrev && "Abbrev type mismatch.");
343  if (!prepRecordData(ID, Val))
344  return;
345  assert(Val < (1U << BitCodeConstants::IntSize));
346  Record.push_back(Val);
347  Stream.EmitRecordWithAbbrev(Abbrevs.get(ID), Record);
348 }
349 
350 bool ClangDocBitcodeWriter::prepRecordData(RecordId ID, bool ShouldEmit) {
351  assert(RecordIdNameMap[ID] && "Unknown RecordId.");
352  if (!ShouldEmit)
353  return false;
354  Record.clear();
355  Record.push_back(ID);
356  return true;
357 }
358 
359 // BlockInfo Block
360 
361 void ClangDocBitcodeWriter::emitBlockInfoBlock() {
362  Stream.EnterBlockInfoBlock();
363  for (const auto &Block : RecordsByBlock) {
364  assert(Block.second.size() < (1U << BitCodeConstants::SubblockIDSize));
365  emitBlockInfo(Block.first, Block.second);
366  }
367  Stream.ExitBlock();
368 }
369 
370 void ClangDocBitcodeWriter::emitBlockInfo(BlockId BID,
371  const std::vector<RecordId> &RIDs) {
372  assert(RIDs.size() < (1U << BitCodeConstants::SubblockIDSize));
373  emitBlockID(BID);
374  for (RecordId RID : RIDs) {
375  emitRecordID(RID);
376  emitAbbrev(RID, BID);
377  }
378 }
379 
380 // Block emission
381 
383  if (R.USR == EmptySID && R.Name.empty())
384  return;
385  StreamSubBlockGuard Block(Stream, BI_REFERENCE_BLOCK_ID);
386  emitRecord(R.USR, REFERENCE_USR);
387  emitRecord(R.Name, REFERENCE_NAME);
388  emitRecord((unsigned)R.RefType, REFERENCE_TYPE);
389  emitRecord(R.Path, REFERENCE_PATH);
390  emitRecord((unsigned)Field, REFERENCE_FIELD);
391 }
392 
394  StreamSubBlockGuard Block(Stream, BI_TYPE_BLOCK_ID);
395  emitBlock(T.Type, FieldId::F_type);
396 }
397 
399  StreamSubBlockGuard Block(Stream, BI_FIELD_TYPE_BLOCK_ID);
400  emitBlock(T.Type, FieldId::F_type);
401  emitRecord(T.Name, FIELD_TYPE_NAME);
402 }
403 
405  StreamSubBlockGuard Block(Stream, BI_MEMBER_TYPE_BLOCK_ID);
406  emitBlock(T.Type, FieldId::F_type);
407  emitRecord(T.Name, MEMBER_TYPE_NAME);
408  emitRecord(T.Access, MEMBER_TYPE_ACCESS);
409 }
410 
412  StreamSubBlockGuard Block(Stream, BI_COMMENT_BLOCK_ID);
413  for (const auto &L : std::vector<std::pair<llvm::StringRef, RecordId>>{
414  {I.Kind, COMMENT_KIND},
415  {I.Text, COMMENT_TEXT},
416  {I.Name, COMMENT_NAME},
420  emitRecord(L.first, L.second);
421  emitRecord(I.SelfClosing, COMMENT_SELFCLOSING);
422  emitRecord(I.Explicit, COMMENT_EXPLICIT);
423  for (const auto &A : I.AttrKeys)
424  emitRecord(A, COMMENT_ATTRKEY);
425  for (const auto &A : I.AttrValues)
426  emitRecord(A, COMMENT_ATTRVAL);
427  for (const auto &A : I.Args)
428  emitRecord(A, COMMENT_ARG);
429  for (const auto &C : I.Children)
430  emitBlock(*C);
431 }
432 
434  StreamSubBlockGuard Block(Stream, BI_NAMESPACE_BLOCK_ID);
435  emitRecord(I.USR, NAMESPACE_USR);
436  emitRecord(I.Name, NAMESPACE_NAME);
437  emitRecord(I.Path, NAMESPACE_PATH);
438  for (const auto &N : I.Namespace)
439  emitBlock(N, FieldId::F_namespace);
440  for (const auto &CI : I.Description)
441  emitBlock(CI);
442  for (const auto &C : I.ChildNamespaces)
443  emitBlock(C, FieldId::F_child_namespace);
444  for (const auto &C : I.ChildRecords)
445  emitBlock(C, FieldId::F_child_record);
446  for (const auto &C : I.ChildFunctions)
447  emitBlock(C);
448  for (const auto &C : I.ChildEnums)
449  emitBlock(C);
450 }
451 
453  StreamSubBlockGuard Block(Stream, BI_ENUM_BLOCK_ID);
454  emitRecord(I.USR, ENUM_USR);
455  emitRecord(I.Name, ENUM_NAME);
456  for (const auto &N : I.Namespace)
457  emitBlock(N, FieldId::F_namespace);
458  for (const auto &CI : I.Description)
459  emitBlock(CI);
460  if (I.DefLoc)
461  emitRecord(I.DefLoc.getValue(), ENUM_DEFLOCATION);
462  for (const auto &L : I.Loc)
463  emitRecord(L, ENUM_LOCATION);
464  emitRecord(I.Scoped, ENUM_SCOPED);
465  for (const auto &N : I.Members)
466  emitRecord(N, ENUM_MEMBER);
467 }
468 
470  StreamSubBlockGuard Block(Stream, BI_RECORD_BLOCK_ID);
471  emitRecord(I.USR, RECORD_USR);
472  emitRecord(I.Name, RECORD_NAME);
473  emitRecord(I.Path, RECORD_PATH);
474  for (const auto &N : I.Namespace)
475  emitBlock(N, FieldId::F_namespace);
476  for (const auto &CI : I.Description)
477  emitBlock(CI);
478  if (I.DefLoc)
479  emitRecord(I.DefLoc.getValue(), RECORD_DEFLOCATION);
480  for (const auto &L : I.Loc)
481  emitRecord(L, RECORD_LOCATION);
482  emitRecord(I.TagType, RECORD_TAG_TYPE);
483  emitRecord(I.IsTypeDef, RECORD_IS_TYPE_DEF);
484  for (const auto &N : I.Members)
485  emitBlock(N);
486  for (const auto &P : I.Parents)
487  emitBlock(P, FieldId::F_parent);
488  for (const auto &P : I.VirtualParents)
489  emitBlock(P, FieldId::F_vparent);
490  for (const auto &C : I.ChildRecords)
491  emitBlock(C, FieldId::F_child_record);
492  for (const auto &C : I.ChildFunctions)
493  emitBlock(C);
494  for (const auto &C : I.ChildEnums)
495  emitBlock(C);
496 }
497 
499  StreamSubBlockGuard Block(Stream, BI_FUNCTION_BLOCK_ID);
500  emitRecord(I.USR, FUNCTION_USR);
501  emitRecord(I.Name, FUNCTION_NAME);
502  for (const auto &N : I.Namespace)
503  emitBlock(N, FieldId::F_namespace);
504  for (const auto &CI : I.Description)
505  emitBlock(CI);
506  emitRecord(I.IsMethod, FUNCTION_IS_METHOD);
507  if (I.DefLoc)
508  emitRecord(I.DefLoc.getValue(), FUNCTION_DEFLOCATION);
509  for (const auto &L : I.Loc)
510  emitRecord(L, FUNCTION_LOCATION);
511  emitBlock(I.Parent, FieldId::F_parent);
512  emitBlock(I.ReturnType);
513  for (const auto &N : I.Params)
514  emitBlock(N);
515 }
516 
518  switch (I->IT) {
520  emitBlock(*static_cast<clang::doc::NamespaceInfo *>(I));
521  break;
522  case InfoType::IT_record:
523  emitBlock(*static_cast<clang::doc::RecordInfo *>(I));
524  break;
525  case InfoType::IT_enum:
526  emitBlock(*static_cast<clang::doc::EnumInfo *>(I));
527  break;
529  emitBlock(*static_cast<clang::doc::FunctionInfo *>(I));
530  break;
531  default:
532  llvm::errs() << "Unexpected info, unable to write.\n";
533  return true;
534  }
535  return false;
536 }
537 
538 } // namespace doc
539 } // namespace clang
SourceLocation Loc
&#39;#&#39; location in the include directive
static void StringAbbrev(std::shared_ptr< llvm::BitCodeAbbrev > &Abbrev)
llvm::SmallVector< Reference, 4 > Namespace
static const SymbolID EmptySID
static void AbbrevGen(std::shared_ptr< llvm::BitCodeAbbrev > &Abbrev, const std::initializer_list< llvm::BitCodeAbbrevOp > Ops)
static constexpr unsigned SignatureBitSize
Definition: BitcodeWriter.h:37
static const std::vector< std::pair< BlockId, std::vector< RecordId > > > RecordsByBlock
static const unsigned VersionNumber
Definition: BitcodeWriter.h:33
static constexpr unsigned SubblockIDSize
Definition: BitcodeWriter.h:38
static constexpr unsigned BlockIdCount
static constexpr unsigned char Signature[4]
Definition: BitcodeWriter.h:47
llvm::SmallVector< uint64_t, 1024 > Record
void emitBlock(const NamespaceInfo &I)
SmallString< 16 > Name
llvm::Optional< Location > DefLoc
RecordIdDsc(llvm::StringRef Name, AbbrevDsc Abbrev)
std::vector< FunctionInfo > ChildFunctions
static constexpr unsigned BoolSize
Definition: BitcodeWriter.h:39
llvm::SmallVector< Location, 2 > Loc
static void BoolAbbrev(std::shared_ptr< llvm::BitCodeAbbrev > &Abbrev)
static const llvm::IndexedMap< RecordIdDsc, RecordIdToIndexFunctor > RecordIdNameMap
std::vector< FunctionInfo > ChildFunctions
unsigned operator()(unsigned ID) const
std::vector< EnumInfo > ChildEnums
unsigned operator()(unsigned ID) const
static constexpr unsigned LineNumberSize
Definition: BitcodeWriter.h:43
std::vector< Reference > ChildRecords
static void SymbolIDAbbrev(std::shared_ptr< llvm::BitCodeAbbrev > &Abbrev)
llvm::SmallVector< Reference, 4 > VirtualParents
llvm::SmallVector< FieldTypeInfo, 4 > Params
llvm::SmallVector< SmallString< 16 >, 4 > Members
static void IntAbbrev(std::shared_ptr< llvm::BitCodeAbbrev > &Abbrev)
llvm::SmallVector< SmallString< 16 >, 4 > AttrValues
static constexpr unsigned RecordSize
Definition: BitcodeWriter.h:36
std::vector< CommentInfo > Description
llvm::SmallVector< SmallString< 16 >, 4 > Args
void(*)(std::shared_ptr< llvm::BitCodeAbbrev > &Abbrev) AbbrevDsc
SmallString< 16 > Name
static constexpr llvm::StringLiteral Name
A base struct for Infos.
llvm::SmallString< 128 > Path
llvm::SmallVector< Reference, 4 > Parents
SmallString< 16 > ParamName
static const llvm::IndexedMap< llvm::StringRef, BlockIdToIndexFunctor > BlockIdNameMap
llvm::SmallVector< SmallString< 16 >, 4 > AttrKeys
SmallString< 16 > Name
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
SmallString< 16 > Name
std::vector< Reference > ChildNamespaces
static constexpr unsigned IntSize
Definition: BitcodeWriter.h:40
SmallString< 16 > CloseName
static constexpr unsigned USRBitLengthSize
Definition: BitcodeWriter.h:46
std::vector< Reference > ChildRecords
SmallString< 32 > Filename
SmallString< 8 > Direction
const InfoType IT
std::vector< EnumInfo > ChildEnums
static constexpr unsigned USRLengthSize
Definition: BitcodeWriter.h:45
static void LocationAbbrev(std::shared_ptr< llvm::BitCodeAbbrev > &Abbrev)
llvm::SmallVector< MemberTypeInfo, 4 > Members
SmallString< 16 > Kind
std::vector< std::unique_ptr< CommentInfo > > Children
SmallString< 64 > Text
static constexpr unsigned StringLengthSize
Definition: BitcodeWriter.h:41
std::array< uint8_t, 20 > SymbolID
llvm::SmallString< 128 > Path
static constexpr unsigned RecordIdCount