1153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek/*===-- CXLoadedDiagnostic.cpp - Handling of persisent diags -*- C++ -*-===*\ 2153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek|* *| 3153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek|* The LLVM Compiler Infrastructure *| 4153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek|* *| 5153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek|* This file is distributed under the University of Illinois Open Source *| 6153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek|* License. See LICENSE.TXT for details. *| 7153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek|* *| 8153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek|*===----------------------------------------------------------------------===*| 9153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek|* *| 10153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek|* Implements handling of persisent diagnostics. *| 11153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek|* *| 12153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek\*===----------------------------------------------------------------------===*/ 13153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 14153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek#include "CXLoadedDiagnostic.h" 15153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek#include "CXString.h" 16153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek#include "clang/Basic/Diagnostic.h" 17153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek#include "clang/Basic/FileManager.h" 18153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek#include "clang/Frontend/SerializedDiagnosticPrinter.h" 19153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek#include "llvm/ADT/StringRef.h" 20153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek#include "llvm/ADT/Twine.h" 21153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek#include "llvm/ADT/Optional.h" 22153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek#include "clang/Basic/LLVM.h" 23153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek#include "llvm/Support/ErrorHandling.h" 24153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek#include "llvm/Bitcode/BitstreamReader.h" 25153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek#include "llvm/Support/MemoryBuffer.h" 26153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek#include <assert.h> 27153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 28153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenekusing namespace clang; 29153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenekusing namespace clang::cxstring; 30153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 31153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek//===----------------------------------------------------------------------===// 32153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek// Extend CXDiagnosticSetImpl which contains strings for diagnostics. 33153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek//===----------------------------------------------------------------------===// 34153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 35153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenektypedef llvm::DenseMap<unsigned, llvm::StringRef> Strings; 36153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 37153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremeneknamespace { 38153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenekclass CXLoadedDiagnosticSetImpl : public CXDiagnosticSetImpl { 39153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenekpublic: 40153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek CXLoadedDiagnosticSetImpl() : CXDiagnosticSetImpl(true), FakeFiles(FO) {} 41153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek virtual ~CXLoadedDiagnosticSetImpl() {} 42153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 43153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek llvm::StringRef makeString(const char *blob, unsigned blobLen); 44153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 45153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek llvm::BumpPtrAllocator Alloc; 46153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek Strings Categories; 47153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek Strings WarningFlags; 48153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek Strings FileNames; 49153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 50153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek FileSystemOptions FO; 51153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek FileManager FakeFiles; 52153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek llvm::DenseMap<unsigned, const FileEntry *> Files; 53153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek}; 54153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek} 55153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 56153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenekllvm::StringRef CXLoadedDiagnosticSetImpl::makeString(const char *blob, 57153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek unsigned bloblen) { 58e97ac9e684aecb5fc3fb9f86da09b8bb9dc31ff4Ted Kremenek char *mem = Alloc.Allocate<char>(bloblen + 1); 59153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek memcpy(mem, blob, bloblen); 60e97ac9e684aecb5fc3fb9f86da09b8bb9dc31ff4Ted Kremenek // Add a null terminator for those clients accessing the buffer 61e97ac9e684aecb5fc3fb9f86da09b8bb9dc31ff4Ted Kremenek // like a c-string. 62e97ac9e684aecb5fc3fb9f86da09b8bb9dc31ff4Ted Kremenek mem[bloblen] = '\0'; 63153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return llvm::StringRef(mem, bloblen); 64153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek} 65153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 66153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek//===----------------------------------------------------------------------===// 67153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek// Cleanup. 68153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek//===----------------------------------------------------------------------===// 69153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 70153221717e39ce41323d5bc6b8b8bf130923c1bdTed KremenekCXLoadedDiagnostic::~CXLoadedDiagnostic() {} 71153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 72153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek//===----------------------------------------------------------------------===// 73153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek// Public CXLoadedDiagnostic methods. 74153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek//===----------------------------------------------------------------------===// 75153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 76153221717e39ce41323d5bc6b8b8bf130923c1bdTed KremenekCXDiagnosticSeverity CXLoadedDiagnostic::getSeverity() const { 77153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek // FIXME: possibly refactor with logic in CXStoredDiagnostic. 78153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek switch (severity) { 79153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case DiagnosticsEngine::Ignored: return CXDiagnostic_Ignored; 80153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case DiagnosticsEngine::Note: return CXDiagnostic_Note; 81153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case DiagnosticsEngine::Warning: return CXDiagnostic_Warning; 82153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case DiagnosticsEngine::Error: return CXDiagnostic_Error; 83153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case DiagnosticsEngine::Fatal: return CXDiagnostic_Fatal; 84153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 85153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 86153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek llvm_unreachable("Invalid diagnostic level"); 87153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek} 88153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 89153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenekstatic CXSourceLocation makeLocation(const CXLoadedDiagnostic::Location *DLoc) { 90153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek // The lowest bit of ptr_data[0] is always set to 1 to indicate this 91153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek // is a persistent diagnostic. 92153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek uintptr_t V = (uintptr_t) DLoc; 93153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek V |= 0x1; 94153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek CXSourceLocation Loc = { { (void*) V, 0 }, 0 }; 95153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Loc; 96153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek} 97153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 98153221717e39ce41323d5bc6b8b8bf130923c1bdTed KremenekCXSourceLocation CXLoadedDiagnostic::getLocation() const { 99153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek // The lowest bit of ptr_data[0] is always set to 1 to indicate this 100153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek // is a persistent diagnostic. 101153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return makeLocation(&DiagLoc); 102153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek} 103153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 104153221717e39ce41323d5bc6b8b8bf130923c1bdTed KremenekCXString CXLoadedDiagnostic::getSpelling() const { 105e97ac9e684aecb5fc3fb9f86da09b8bb9dc31ff4Ted Kremenek return cxstring::createCXString(Spelling, false); 106153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek} 107153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 108153221717e39ce41323d5bc6b8b8bf130923c1bdTed KremenekCXString CXLoadedDiagnostic::getDiagnosticOption(CXString *Disable) const { 109153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (DiagOption.empty()) 110153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return createCXString(""); 111153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 112153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek // FIXME: possibly refactor with logic in CXStoredDiagnostic. 113153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (Disable) 114153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek *Disable = createCXString((Twine("-Wno-") + DiagOption).str()); 115153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return createCXString((Twine("-W") + DiagOption).str()); 116153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek} 117153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 118153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenekunsigned CXLoadedDiagnostic::getCategory() const { 119153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return category; 120153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek} 121153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 12278d5d3bb9386a5aa31d19445eb8f81bf2652acb4Ted KremenekCXString CXLoadedDiagnostic::getCategoryText() const { 12378d5d3bb9386a5aa31d19445eb8f81bf2652acb4Ted Kremenek return cxstring::createCXString(CategoryText); 12478d5d3bb9386a5aa31d19445eb8f81bf2652acb4Ted Kremenek} 12578d5d3bb9386a5aa31d19445eb8f81bf2652acb4Ted Kremenek 126153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenekunsigned CXLoadedDiagnostic::getNumRanges() const { 127153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Ranges.size(); 128153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek} 129153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 130153221717e39ce41323d5bc6b8b8bf130923c1bdTed KremenekCXSourceRange CXLoadedDiagnostic::getRange(unsigned Range) const { 131153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek assert(Range < Ranges.size()); 132153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Ranges[Range]; 133153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek} 134153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 135153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenekunsigned CXLoadedDiagnostic::getNumFixIts() const { 136153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return FixIts.size(); 137153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek} 138153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 139153221717e39ce41323d5bc6b8b8bf130923c1bdTed KremenekCXString CXLoadedDiagnostic::getFixIt(unsigned FixIt, 140153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek CXSourceRange *ReplacementRange) const { 141153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek assert(FixIt < FixIts.size()); 142153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (ReplacementRange) 143153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek *ReplacementRange = FixIts[FixIt].first; 144153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return FixIts[FixIt].second; 145153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek} 146153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 147153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenekvoid CXLoadedDiagnostic::decodeLocation(CXSourceLocation location, 148153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek CXFile *file, 149153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek unsigned int *line, 150153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek unsigned int *column, 151153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek unsigned int *offset) { 152153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 153153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 154153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek // CXSourceLocation consists of the following fields: 155153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek // 156153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek // void *ptr_data[2]; 157153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek // unsigned int_data; 158153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek // 159153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek // The lowest bit of ptr_data[0] is always set to 1 to indicate this 160153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek // is a persistent diagnostic. 161153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek // 162153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek // For now, do the unoptimized approach and store the data in a side 163153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek // data structure. We can optimize this case later. 164153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 165153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek uintptr_t V = (uintptr_t) location.ptr_data[0]; 166153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek assert((V & 0x1) == 1); 167153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek V &= ~(uintptr_t)1; 168153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 169153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek const Location &Loc = *((Location*)V); 170153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 171153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (file) 172153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek *file = Loc.file; 173153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (line) 174153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek *line = Loc.line; 175153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (column) 176153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek *column = Loc.column; 177153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (offset) 178153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek *offset = Loc.offset; 179153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek} 180153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 181153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek//===----------------------------------------------------------------------===// 182153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek// Deserialize diagnostics. 183153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek//===----------------------------------------------------------------------===// 184153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 185153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenekenum { MaxSupportedVersion = 1 }; 186153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenektypedef SmallVector<uint64_t, 64> RecordData; 187153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenekenum LoadResult { Failure = 1, Success = 0 }; 188153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenekenum StreamResult { Read_EndOfStream, 189153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek Read_BlockBegin, 190153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek Read_Failure, 191153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek Read_Record, 192153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek Read_BlockEnd }; 193153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 194153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremeneknamespace { 195153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenekclass DiagLoader { 196153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek enum CXLoadDiag_Error *error; 197153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek CXString *errorString; 198153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 199153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek void reportBad(enum CXLoadDiag_Error code, llvm::StringRef err) { 200153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (error) 201153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek *error = code; 202153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (errorString) 203153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek *errorString = createCXString(err); 204153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 205153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 206153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek void reportInvalidFile(llvm::StringRef err) { 207153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return reportBad(CXLoadDiag_InvalidFile, err); 208153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 209153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 210153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek LoadResult readMetaBlock(llvm::BitstreamCursor &Stream); 211153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 212153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek LoadResult readDiagnosticBlock(llvm::BitstreamCursor &Stream, 213153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek CXDiagnosticSetImpl &Diags, 214153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek CXLoadedDiagnosticSetImpl &TopDiags); 215153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 216153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek StreamResult readToNextRecordOrBlock(llvm::BitstreamCursor &Stream, 217153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek llvm::StringRef errorContext, 218153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek unsigned &BlockOrRecordID, 219153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek const bool atTopLevel = false); 220153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 221153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 222153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek LoadResult readString(CXLoadedDiagnosticSetImpl &TopDiags, 223153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek Strings &strings, llvm::StringRef errorContext, 224153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek RecordData &Record, 225153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek const char *BlobStart, 226952538d48d75b2c01d98002a46691638f9f9a4acTed Kremenek unsigned BlobLen, 227952538d48d75b2c01d98002a46691638f9f9a4acTed Kremenek bool allowEmptyString = false); 228153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 229153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek LoadResult readString(CXLoadedDiagnosticSetImpl &TopDiags, 230153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek llvm::StringRef &RetStr, 231153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek llvm::StringRef errorContext, 232153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek RecordData &Record, 233153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek const char *BlobStart, 234952538d48d75b2c01d98002a46691638f9f9a4acTed Kremenek unsigned BlobLen, 235952538d48d75b2c01d98002a46691638f9f9a4acTed Kremenek bool allowEmptyString = false); 236153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 237153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek LoadResult readRange(CXLoadedDiagnosticSetImpl &TopDiags, 238153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek RecordData &Record, unsigned RecStartIdx, 239153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek CXSourceRange &SR); 240153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 241153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek LoadResult readLocation(CXLoadedDiagnosticSetImpl &TopDiags, 242153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek RecordData &Record, unsigned &offset, 243153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek CXLoadedDiagnostic::Location &Loc); 244153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 245153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenekpublic: 246153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek DiagLoader(enum CXLoadDiag_Error *e, CXString *es) 247153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek : error(e), errorString(es) { 248153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (error) 249153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek *error = CXLoadDiag_None; 250153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (errorString) 251153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek *errorString = createCXString(""); 252153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 253e97ac9e684aecb5fc3fb9f86da09b8bb9dc31ff4Ted Kremenek 254153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek CXDiagnosticSet load(const char *file); 255153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek}; 256153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek} 257153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 258153221717e39ce41323d5bc6b8b8bf130923c1bdTed KremenekCXDiagnosticSet DiagLoader::load(const char *file) { 259153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek // Open the diagnostics file. 260153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek std::string ErrStr; 261153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek FileSystemOptions FO; 262153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek FileManager FileMgr(FO); 263153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 2641e4c01b79273b9cd4e9e9ecfd3422df3900b8356Dylan Noblesmith OwningPtr<llvm::MemoryBuffer> Buffer; 265153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek Buffer.reset(FileMgr.getBufferForFile(file)); 266153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 267153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (!Buffer) { 268153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek reportBad(CXLoadDiag_CannotLoad, ErrStr); 269153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return 0; 270153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 271153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 272153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek llvm::BitstreamReader StreamFile; 273153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek StreamFile.init((const unsigned char *)Buffer->getBufferStart(), 274153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek (const unsigned char *)Buffer->getBufferEnd()); 275153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 276153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek llvm::BitstreamCursor Stream; 277153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek Stream.init(StreamFile); 278153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 279153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek // Sniff for the signature. 280153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (Stream.Read(8) != 'D' || 281153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek Stream.Read(8) != 'I' || 282153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek Stream.Read(8) != 'A' || 283153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek Stream.Read(8) != 'G') { 284153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek reportBad(CXLoadDiag_InvalidFile, 285153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek "Bad header in diagnostics file"); 286153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return 0; 287153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 288153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 2891e4c01b79273b9cd4e9e9ecfd3422df3900b8356Dylan Noblesmith OwningPtr<CXLoadedDiagnosticSetImpl> 290153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek Diags(new CXLoadedDiagnosticSetImpl()); 291153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 292153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek while (true) { 293153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek unsigned BlockID = 0; 294153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek StreamResult Res = readToNextRecordOrBlock(Stream, "Top-level", 295153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek BlockID, true); 296153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek switch (Res) { 297153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case Read_EndOfStream: 298153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return (CXDiagnosticSet) Diags.take(); 299153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case Read_Failure: 300153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return 0; 301153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case Read_Record: 302153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek llvm_unreachable("Top-level does not have records"); 303153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case Read_BlockEnd: 304153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek continue; 305153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case Read_BlockBegin: 306153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek break; 307153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 308153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 309153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek switch (BlockID) { 310153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case serialized_diags::BLOCK_META: 311153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (readMetaBlock(Stream)) 312153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return 0; 313153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek break; 314153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case serialized_diags::BLOCK_DIAG: 315153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (readDiagnosticBlock(Stream, *Diags.get(), *Diags.get())) 316153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return 0; 317153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek break; 318153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek default: 319153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (!Stream.SkipBlock()) { 320153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek reportInvalidFile("Malformed block at top-level of diagnostics file"); 321153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return 0; 322153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 323153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek break; 324153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 325153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 326153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek} 327153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 328153221717e39ce41323d5bc6b8b8bf130923c1bdTed KremenekStreamResult DiagLoader::readToNextRecordOrBlock(llvm::BitstreamCursor &Stream, 329153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek llvm::StringRef errorContext, 330153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek unsigned &blockOrRecordID, 331153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek const bool atTopLevel) { 332153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 333153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek blockOrRecordID = 0; 334153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 335153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek while (!Stream.AtEndOfStream()) { 336153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek unsigned Code = Stream.ReadCode(); 337153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 338153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek // Handle the top-level specially. 339153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (atTopLevel) { 340153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (Code == llvm::bitc::ENTER_SUBBLOCK) { 341153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek unsigned BlockID = Stream.ReadSubBlockID(); 342153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (BlockID == llvm::bitc::BLOCKINFO_BLOCK_ID) { 343153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (Stream.ReadBlockInfoBlock()) { 344153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek reportInvalidFile("Malformed BlockInfoBlock in diagnostics file"); 345153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Read_Failure; 346153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 347153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek continue; 348153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 349153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek blockOrRecordID = BlockID; 350153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Read_BlockBegin; 351153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 352153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek reportInvalidFile("Only blocks can appear at the top of a " 353153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek "diagnostic file"); 354153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Read_Failure; 355153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 356153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 357153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek switch ((llvm::bitc::FixedAbbrevIDs)Code) { 358153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case llvm::bitc::ENTER_SUBBLOCK: 359153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek blockOrRecordID = Stream.ReadSubBlockID(); 360153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Read_BlockBegin; 361153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 362153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case llvm::bitc::END_BLOCK: 363153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (Stream.ReadBlockEnd()) { 364153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek reportInvalidFile("Cannot read end of block"); 365153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Read_Failure; 366153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 367153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Read_BlockEnd; 368153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 369153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case llvm::bitc::DEFINE_ABBREV: 370153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek Stream.ReadAbbrevRecord(); 371153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek continue; 372153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 373153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case llvm::bitc::UNABBREV_RECORD: 374153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek reportInvalidFile("Diagnostics file should have no unabbreviated " 375153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek "records"); 376153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Read_Failure; 377153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 378153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek default: 379153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek // We found a record. 380153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek blockOrRecordID = Code; 381153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Read_Record; 382153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 383153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 384153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 385153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (atTopLevel) 386153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Read_EndOfStream; 387153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 388153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek reportInvalidFile(Twine("Premature end of diagnostics file within ").str() + 389153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek errorContext.str()); 390153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Read_Failure; 391153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek} 392153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 393153221717e39ce41323d5bc6b8b8bf130923c1bdTed KremenekLoadResult DiagLoader::readMetaBlock(llvm::BitstreamCursor &Stream) { 394153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (Stream.EnterSubBlock(clang::serialized_diags::BLOCK_META)) { 395153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek reportInvalidFile("Malformed metadata block"); 396153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Failure; 397153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 398153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 399153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek bool versionChecked = false; 400153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 401153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek while (true) { 402153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek unsigned blockOrCode = 0; 403153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek StreamResult Res = readToNextRecordOrBlock(Stream, "Metadata Block", 404153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek blockOrCode); 405153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 406153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek switch(Res) { 407153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case Read_EndOfStream: 408153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek llvm_unreachable("EndOfStream handled by readToNextRecordOrBlock"); 409153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case Read_Failure: 410153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Failure; 411153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case Read_Record: 412153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek break; 413153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case Read_BlockBegin: 414153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (Stream.SkipBlock()) { 415153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek reportInvalidFile("Malformed metadata block"); 416153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Failure; 417153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 418153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case Read_BlockEnd: 419153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (!versionChecked) { 420153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek reportInvalidFile("Diagnostics file does not contain version" 421153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek " information"); 422153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Failure; 423153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 424153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Success; 425153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 426153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 427153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek RecordData Record; 428153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek const char *Blob; 429153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek unsigned BlobLen; 430153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek unsigned recordID = Stream.ReadRecord(blockOrCode, Record, &Blob, &BlobLen); 431153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 432153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (recordID == serialized_diags::RECORD_VERSION) { 433153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (Record.size() < 1) { 434153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek reportInvalidFile("malformed VERSION identifier in diagnostics file"); 435153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Failure; 436153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 437153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (Record[0] > MaxSupportedVersion) { 438153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek reportInvalidFile("diagnosics file is a newer version than the one " 439153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek "supported"); 440153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Failure; 441153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 442153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek versionChecked = true; 443153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 444153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 445153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek} 446153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 447153221717e39ce41323d5bc6b8b8bf130923c1bdTed KremenekLoadResult DiagLoader::readString(CXLoadedDiagnosticSetImpl &TopDiags, 448153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek llvm::StringRef &RetStr, 449153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek llvm::StringRef errorContext, 450153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek RecordData &Record, 451153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek const char *BlobStart, 452952538d48d75b2c01d98002a46691638f9f9a4acTed Kremenek unsigned BlobLen, 453952538d48d75b2c01d98002a46691638f9f9a4acTed Kremenek bool allowEmptyString) { 454153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 455153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek // Basic buffer overflow check. 456153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (BlobLen > 65536) { 457153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek reportInvalidFile(std::string("Out-of-bounds string in ") + 458153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek std::string(errorContext)); 459153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Failure; 460153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 461952538d48d75b2c01d98002a46691638f9f9a4acTed Kremenek 462952538d48d75b2c01d98002a46691638f9f9a4acTed Kremenek if (allowEmptyString && Record.size() >= 1 && BlobLen == 0) { 463952538d48d75b2c01d98002a46691638f9f9a4acTed Kremenek RetStr = ""; 464952538d48d75b2c01d98002a46691638f9f9a4acTed Kremenek return Success; 465952538d48d75b2c01d98002a46691638f9f9a4acTed Kremenek } 466153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 467153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (Record.size() < 1 || BlobLen == 0) { 468153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek reportInvalidFile(std::string("Corrupted ") + std::string(errorContext) 469153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek + std::string(" entry")); 470153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Failure; 471153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 472153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 473153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek RetStr = TopDiags.makeString(BlobStart, BlobLen); 474153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Success; 475153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek} 476153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 477153221717e39ce41323d5bc6b8b8bf130923c1bdTed KremenekLoadResult DiagLoader::readString(CXLoadedDiagnosticSetImpl &TopDiags, 478153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek Strings &strings, 479153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek llvm::StringRef errorContext, 480153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek RecordData &Record, 481153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek const char *BlobStart, 482952538d48d75b2c01d98002a46691638f9f9a4acTed Kremenek unsigned BlobLen, 483952538d48d75b2c01d98002a46691638f9f9a4acTed Kremenek bool allowEmptyString) { 484153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek llvm::StringRef RetStr; 485952538d48d75b2c01d98002a46691638f9f9a4acTed Kremenek if (readString(TopDiags, RetStr, errorContext, Record, BlobStart, BlobLen, 486952538d48d75b2c01d98002a46691638f9f9a4acTed Kremenek allowEmptyString)) 487153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Failure; 488153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek strings[Record[0]] = RetStr; 489153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Success; 490153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek} 491153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 492153221717e39ce41323d5bc6b8b8bf130923c1bdTed KremenekLoadResult DiagLoader::readLocation(CXLoadedDiagnosticSetImpl &TopDiags, 493153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek RecordData &Record, unsigned &offset, 494153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek CXLoadedDiagnostic::Location &Loc) { 495153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (Record.size() < offset + 3) { 496153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek reportInvalidFile("Corrupted source location"); 497153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Failure; 498153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 499153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 500153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek unsigned fileID = Record[offset++]; 501153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (fileID == 0) { 502153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek // Sentinel value. 503153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek Loc.file = 0; 504153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek Loc.line = 0; 505153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek Loc.column = 0; 506153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek Loc.offset = 0; 507153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Success; 508153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 509153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 510153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek const FileEntry *FE = TopDiags.Files[fileID]; 511153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (!FE) { 512153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek reportInvalidFile("Corrupted file entry in source location"); 513153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Failure; 514153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 515153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek Loc.file = (void*) FE; 516153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek Loc.line = Record[offset++]; 517153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek Loc.column = Record[offset++]; 518153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek Loc.offset = Record[offset++]; 519153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Success; 520153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek} 521153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 522153221717e39ce41323d5bc6b8b8bf130923c1bdTed KremenekLoadResult DiagLoader::readRange(CXLoadedDiagnosticSetImpl &TopDiags, 523153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek RecordData &Record, 524153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek unsigned int RecStartIdx, 525153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek CXSourceRange &SR) { 526153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek CXLoadedDiagnostic::Location *Start, *End; 527153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek Start = TopDiags.Alloc.Allocate<CXLoadedDiagnostic::Location>(); 528153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek End = TopDiags.Alloc.Allocate<CXLoadedDiagnostic::Location>(); 529153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 530153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (readLocation(TopDiags, Record, RecStartIdx, *Start)) 531153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Failure; 532153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (readLocation(TopDiags, Record, RecStartIdx, *End)) 533153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Failure; 534153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 535153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek CXSourceLocation startLoc = makeLocation(Start); 536153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek CXSourceLocation endLoc = makeLocation(End); 537153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek SR = clang_getRange(startLoc, endLoc); 538153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Success; 539153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek} 540153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 541153221717e39ce41323d5bc6b8b8bf130923c1bdTed KremenekLoadResult DiagLoader::readDiagnosticBlock(llvm::BitstreamCursor &Stream, 542153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek CXDiagnosticSetImpl &Diags, 543153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek CXLoadedDiagnosticSetImpl &TopDiags){ 544153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 545153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (Stream.EnterSubBlock(clang::serialized_diags::BLOCK_DIAG)) { 546153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek reportInvalidFile("malformed diagnostic block"); 547153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Failure; 548153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 549153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 5501e4c01b79273b9cd4e9e9ecfd3422df3900b8356Dylan Noblesmith OwningPtr<CXLoadedDiagnostic> D(new CXLoadedDiagnostic()); 551153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek RecordData Record; 552153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 553153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek while (true) { 554153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek unsigned blockOrCode = 0; 555153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek StreamResult Res = readToNextRecordOrBlock(Stream, "Diagnostic Block", 556153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek blockOrCode); 557153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek switch (Res) { 558153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case Read_EndOfStream: 559153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek llvm_unreachable("EndOfStream handled in readToNextRecordOrBlock"); 560153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case Read_Failure: 561153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Failure; 562153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case Read_BlockBegin: { 563153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek // The only blocks we care about are subdiagnostics. 564153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (blockOrCode != serialized_diags::BLOCK_DIAG) { 565153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (!Stream.SkipBlock()) { 566153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek reportInvalidFile("Invalid subblock in Diagnostics block"); 567153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Failure; 568153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 569153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } else if (readDiagnosticBlock(Stream, D->getChildDiagnostics(), 570153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek TopDiags)) { 571153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Failure; 572153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 573153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 574153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek continue; 575153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 576153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case Read_BlockEnd: 577153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek Diags.appendDiagnostic(D.take()); 578153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Success; 579153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case Read_Record: 580153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek break; 581153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 582153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 583153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek // Read the record. 584153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek Record.clear(); 585153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek const char *BlobStart = 0; 586153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek unsigned BlobLen = 0; 587153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek unsigned recID = Stream.ReadRecord(blockOrCode, Record, 588153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek BlobStart, BlobLen); 589153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 590153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (recID < serialized_diags::RECORD_FIRST || 591153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek recID > serialized_diags::RECORD_LAST) 592153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek continue; 593153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 594153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek switch ((serialized_diags::RecordIDs)recID) { 595153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case serialized_diags::RECORD_VERSION: 596153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek continue; 597153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case serialized_diags::RECORD_CATEGORY: 598153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (readString(TopDiags, TopDiags.Categories, "category", Record, 59913eee196469596a107762606e5cea6511368a54cTed Kremenek BlobStart, BlobLen, 60013eee196469596a107762606e5cea6511368a54cTed Kremenek /* allowEmptyString */ true)) 601153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Failure; 602153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek continue; 603153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 604153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case serialized_diags::RECORD_DIAG_FLAG: 605153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (readString(TopDiags, TopDiags.WarningFlags, "warning flag", Record, 606153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek BlobStart, BlobLen)) 607153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Failure; 608153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek continue; 609153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 610153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case serialized_diags::RECORD_FILENAME: { 611153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (readString(TopDiags, TopDiags.FileNames, "filename", Record, 612153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek BlobStart, BlobLen)) 613153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Failure; 614153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 615153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (Record.size() < 3) { 616153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek reportInvalidFile("Invalid file entry"); 617153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Failure; 618153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 619153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 620153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek const FileEntry *FE = 621153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek TopDiags.FakeFiles.getVirtualFile(TopDiags.FileNames[Record[0]], 622153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek /* size */ Record[1], 623153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek /* time */ Record[2]); 624153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 625153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek TopDiags.Files[Record[0]] = FE; 626153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek continue; 627153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 628153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 629153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case serialized_diags::RECORD_SOURCE_RANGE: { 630153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek CXSourceRange SR; 631153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (readRange(TopDiags, Record, 0, SR)) 632153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Failure; 633153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek D->Ranges.push_back(SR); 634153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek continue; 635153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 636153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 637153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case serialized_diags::RECORD_FIXIT: { 638153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek CXSourceRange SR; 639153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (readRange(TopDiags, Record, 0, SR)) 640153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Failure; 641153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek llvm::StringRef RetStr; 642952538d48d75b2c01d98002a46691638f9f9a4acTed Kremenek if (readString(TopDiags, RetStr, "FIXIT", Record, BlobStart, BlobLen, 643952538d48d75b2c01d98002a46691638f9f9a4acTed Kremenek /* allowEmptyString */ true)) 644153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Failure; 645e97ac9e684aecb5fc3fb9f86da09b8bb9dc31ff4Ted Kremenek D->FixIts.push_back(std::make_pair(SR, createCXString(RetStr, false))); 646e97ac9e684aecb5fc3fb9f86da09b8bb9dc31ff4Ted Kremenek continue; 647153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 648153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 649153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek case serialized_diags::RECORD_DIAG: { 650153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek D->severity = Record[0]; 651153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek unsigned offset = 1; 652153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek if (readLocation(TopDiags, Record, offset, D->DiagLoc)) 653153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return Failure; 654153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek D->category = Record[offset++]; 655153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek unsigned diagFlag = Record[offset++]; 656153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek D->DiagOption = diagFlag ? TopDiags.WarningFlags[diagFlag] : ""; 65778d5d3bb9386a5aa31d19445eb8f81bf2652acb4Ted Kremenek D->CategoryText = D->category ? TopDiags.Categories[D->category] : ""; 658153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek D->Spelling = TopDiags.makeString(BlobStart, BlobLen); 659153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek continue; 660153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 661153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 662153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek } 663153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek} 664153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek 665153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenekextern "C" { 666153221717e39ce41323d5bc6b8b8bf130923c1bdTed KremenekCXDiagnosticSet clang_loadDiagnostics(const char *file, 667153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek enum CXLoadDiag_Error *error, 668153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek CXString *errorString) { 669153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek DiagLoader L(error, errorString); 670153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek return L.load(file); 671153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek} 672153221717e39ce41323d5bc6b8b8bf130923c1bdTed Kremenek} // end extern 'C'. 673