10 #include "llvm/ADT/IndexedMap.h"
11 #include <initializer_list>
31 using AbbrevDsc = void (*)(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev);
33 static void AbbrevGen(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev,
34 const std::initializer_list<llvm::BitCodeAbbrevOp> Ops) {
35 for (
const auto &Op : Ops)
39 static void BoolAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev) {
42 llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
46 static void IntAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev) {
49 llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
56 llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
59 llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Array),
60 llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
64 static void StringAbbrev(std::shared_ptr<llvm::BitCodeAbbrev> &Abbrev) {
67 llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
70 llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)});
78 llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
81 llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
84 llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Fixed,
87 llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)});
99 operator bool()
const {
100 return Abbrev !=
nullptr &&
Name.data() !=
nullptr && !
Name.empty();
104 static const llvm::IndexedMap<llvm::StringRef, BlockIdToIndexFunctor>
106 llvm::IndexedMap<llvm::StringRef, BlockIdToIndexFunctor>
BlockIdNameMap;
111 static const std::vector<std::pair<BlockId, const char *const>> Inits = {
124 for (
const auto &Init : Inits)
130 static const llvm::IndexedMap<RecordIdDsc, RecordIdToIndexFunctor>
137 static const std::vector<std::pair<RecordId, RecordIdDsc>> Inits = {
190 for (
const auto &Init : Inits) {
198 static const std::vector<std::pair<BlockId, std::vector<RecordId>>>
242 void ClangDocBitcodeWriter::AbbreviationMap::add(
RecordId RID,
245 assert(Abbrevs.find(RID) == Abbrevs.end() &&
"Abbreviation already added.");
246 Abbrevs[RID] = AbbrevID;
249 unsigned ClangDocBitcodeWriter::AbbreviationMap::get(
RecordId RID)
const {
251 assert(Abbrevs.find(RID) != Abbrevs.end() &&
"Unknown abbreviation.");
252 return Abbrevs.lookup(RID);
259 void ClangDocBitcodeWriter::emitHeader() {
264 void ClangDocBitcodeWriter::emitVersionBlock() {
270 void ClangDocBitcodeWriter::emitBlockID(
BlockId BID) {
272 assert(BlockIdName.data() && BlockIdName.size() &&
"Unknown BlockId.");
275 Record.push_back(BID);
276 Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETBID, Record);
277 Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_BLOCKNAME,
278 ArrayRef<unsigned char>(BlockIdName.bytes_begin(),
279 BlockIdName.bytes_end()));
283 void ClangDocBitcodeWriter::emitRecordID(
RecordId ID) {
288 Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_SETRECORDNAME, Record);
295 auto Abbrev = std::make_shared<llvm::BitCodeAbbrev>();
296 Abbrev->Add(llvm::BitCodeAbbrevOp(ID));
298 Abbrevs.add(ID, Stream.EmitBlockInfoAbbrev(Block, std::move(Abbrev)));
306 "Abbrev type mismatch.");
307 if (!prepRecordData(ID, Sym !=
EmptySID))
309 assert(Sym.size() == 20);
310 Record.push_back(Sym.size());
311 Record.append(Sym.begin(), Sym.end());
312 Stream.EmitRecordWithAbbrev(Abbrevs.get(ID), Record);
315 void ClangDocBitcodeWriter::emitRecord(llvm::StringRef Str,
RecordId ID) {
318 "Abbrev type mismatch.");
319 if (!prepRecordData(ID, !Str.empty()))
322 Record.push_back(Str.size());
323 Stream.EmitRecordWithBlob(Abbrevs.get(ID), Record, Str);
329 "Abbrev type mismatch.");
330 if (!prepRecordData(ID,
true))
333 Record.push_back(
Loc.LineNumber);
335 Record.push_back(
Loc.IsFileInRootDir);
336 Record.push_back(
Loc.Filename.size());
337 Stream.EmitRecordWithBlob(Abbrevs.get(ID), Record,
Loc.Filename);
340 void ClangDocBitcodeWriter::emitRecord(
bool Val,
RecordId ID) {
343 if (!prepRecordData(ID, Val))
345 Record.push_back(Val);
346 Stream.EmitRecordWithAbbrev(Abbrevs.get(ID), Record);
349 void ClangDocBitcodeWriter::emitRecord(
int Val,
RecordId ID) {
352 if (!prepRecordData(ID, Val))
355 Record.push_back(Val);
356 Stream.EmitRecordWithAbbrev(Abbrevs.get(ID), Record);
359 void ClangDocBitcodeWriter::emitRecord(
unsigned Val,
RecordId ID) {
362 if (!prepRecordData(ID, Val))
365 Record.push_back(Val);
366 Stream.EmitRecordWithAbbrev(Abbrevs.get(ID), Record);
369 bool ClangDocBitcodeWriter::prepRecordData(
RecordId ID,
bool ShouldEmit) {
374 Record.push_back(ID);
380 void ClangDocBitcodeWriter::emitBlockInfoBlock() {
381 Stream.EnterBlockInfoBlock();
384 emitBlockInfo(Block.first, Block.second);
389 void ClangDocBitcodeWriter::emitBlockInfo(
BlockId BID,
390 const std::vector<RecordId> &RIDs) {
395 emitAbbrev(RID, BID);
433 for (
const auto &L : std::vector<std::pair<llvm::StringRef, RecordId>>{
440 emitRecord(L.first, L.second);
447 for (
const auto &A : I.
Args)
482 for (
const auto &L : I.
Loc)
485 for (
const auto &N : I.
Members)
500 for (
const auto &L : I.
Loc)
504 for (
const auto &N : I.
Members)
506 for (
const auto &P : I.
Parents)
510 for (
const auto &PB : I.
Bases)
529 for (
const auto &M : I.
Members)
547 for (
const auto &L : I.
Loc)
551 for (
const auto &N : I.
Params)
558 emitBlock(*static_cast<clang::doc::NamespaceInfo *>(I));
561 emitBlock(*static_cast<clang::doc::RecordInfo *>(I));
564 emitBlock(*static_cast<clang::doc::EnumInfo *>(I));
567 emitBlock(*static_cast<clang::doc::FunctionInfo *>(I));
570 llvm::errs() <<
"Unexpected info, unable to write.\n";