unsigned SDiagsWriter::getEmitDiagnosticFlag(DiagnosticsEngine::Level DiagLevel, unsigned DiagID) { if (DiagLevel == DiagnosticsEngine::Note) return 0; // No flag for notes. StringRef FlagName = DiagnosticIDs::getWarningOptionForDiag(DiagID); if (FlagName.empty()) return 0; // Here we assume that FlagName points to static data whose pointer // value is fixed. This allows us to unique by diagnostic groups. const void *data = FlagName.data(); std::pair<unsigned, StringRef> &entry = DiagFlags[data]; if (entry.first == 0) { entry.first = DiagFlags.size(); entry.second = FlagName; // Lazily emit the string in a separate record. RecordData Record; Record.push_back(RECORD_DIAG_FLAG); Record.push_back(entry.first); Record.push_back(FlagName.size()); Stream.EmitRecordWithBlob(Abbrevs.get(RECORD_DIAG_FLAG), Record, FlagName); } return entry.first; }
unsigned SDiagsWriter::getEmitFile(SourceLocation Loc) { SourceManager &SM = Diags.getSourceManager(); assert(Loc.isValid()); const std::pair<FileID, unsigned> &LocInfo = SM.getDecomposedLoc(Loc); const FileEntry *FE = SM.getFileEntryForID(LocInfo.first); if (!FE) return 0; unsigned &entry = Files[FE]; if (entry) return entry; // Lazily generate the record for the file. entry = Files.size(); RecordData Record; Record.push_back(RECORD_FILENAME); Record.push_back(entry); Record.push_back(FE->getSize()); Record.push_back(FE->getModificationTime()); StringRef Name = FE->getName(); Record.push_back(Name.size()); Stream.EmitRecordWithBlob(Abbrevs.get(RECORD_FILENAME), Record, Name); return entry; }
void SDiagsRenderer::emitNote(SourceLocation Loc, StringRef Message) { Writer.Stream.EnterSubblock(BLOCK_DIAG, 4); RecordData Record; Record.push_back(RECORD_DIAG); Record.push_back(DiagnosticsEngine::Note); Writer.AddLocToRecord(Loc, Record, SM); Record.push_back(Writer.getEmitCategory()); Record.push_back(Writer.getEmitDiagnosticFlag(DiagnosticsEngine::Note)); Record.push_back(Message.size()); Writer.Stream.EmitRecordWithBlob(Writer.Abbrevs.get(RECORD_DIAG), Record, Message); Writer.Stream.ExitBlock(); }
unsigned SDiagsWriter::getEmitCategory(unsigned int category) { if (Categories.count(category)) return category; Categories.insert(category); // We use a local version of 'Record' so that we can be generating // another record when we lazily generate one for the category entry. RecordData Record; Record.push_back(RECORD_CATEGORY); Record.push_back(category); StringRef catName = DiagnosticIDs::getCategoryNameFromID(category); Record.push_back(catName.size()); Stream.EmitRecordWithBlob(Abbrevs.get(RECORD_CATEGORY), Record, catName); return category; }
unsigned SDiagsWriter::getEmitFile(const char *FileName){ if (!FileName) return 0; unsigned &entry = Files[FileName]; if (entry) return entry; // Lazily generate the record for the file. entry = Files.size(); RecordData Record; Record.push_back(RECORD_FILENAME); Record.push_back(entry); Record.push_back(0); // For legacy. Record.push_back(0); // For legacy. StringRef Name(FileName); Record.push_back(Name.size()); Stream.EmitRecordWithBlob(Abbrevs.get(RECORD_FILENAME), Record, Name); return entry; }
unsigned SerializedDiagnosticConsumer::getEmitFile(StringRef Filename) { // NOTE: Using Filename.data() here relies on SourceMgr using // const char* as buffer identifiers. This is fast, but may // be brittle. We can always switch over to using a StringMap. unsigned &entry = State->Files[Filename.data()]; if (entry) return entry; // Lazily generate the record for the file. Note that in // practice we only expect there to be one file, but this is // general and is what the diagnostic file expects. entry = State->Files.size(); RecordData Record; Record.push_back(RECORD_FILENAME); Record.push_back(entry); Record.push_back(0); // For legacy. Record.push_back(0); // For legacy. Record.push_back(Filename.size()); State->Stream.EmitRecordWithBlob(State->Abbrevs.get(RECORD_FILENAME), Record, Filename.data()); return entry; }