libclang: don't store nul-terminated strings as StringRefs,

if the nul-terminatedness property is important for clients.

Also, don't return the same CXString multiple times.  This did not create a
correctness issue in practice because the CXString was of an CXS_Unmanaged
kind, and destruction was a no-op.

llvm-svn: 175455
This commit is contained in:
Dmitri Gribenko 2013-02-18 19:50:38 +00:00
parent b61d087d40
commit 7d09808818
2 changed files with 15 additions and 16 deletions

View File

@ -29,7 +29,7 @@ using namespace clang;
// Extend CXDiagnosticSetImpl which contains strings for diagnostics. // Extend CXDiagnosticSetImpl which contains strings for diagnostics.
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
typedef llvm::DenseMap<unsigned, llvm::StringRef> Strings; typedef llvm::DenseMap<unsigned, const char *> Strings;
namespace { namespace {
class CXLoadedDiagnosticSetImpl : public CXDiagnosticSetImpl { class CXLoadedDiagnosticSetImpl : public CXDiagnosticSetImpl {
@ -45,14 +45,13 @@ public:
FileSystemOptions FO; FileSystemOptions FO;
FileManager FakeFiles; FileManager FakeFiles;
llvm::DenseMap<unsigned, const FileEntry *> Files; llvm::DenseMap<unsigned, const FileEntry *> Files;
llvm::StringRef makeString(StringRef Blob) { /// \brief Copy the string into our own allocator.
const char *copyString(StringRef Blob) {
char *mem = Alloc.Allocate<char>(Blob.size() + 1); char *mem = Alloc.Allocate<char>(Blob.size() + 1);
memcpy(mem, Blob.data(), Blob.size()); memcpy(mem, Blob.data(), Blob.size());
// Add a null terminator for those clients accessing the buffer
// like a c-string.
mem[Blob.size()] = '\0'; mem[Blob.size()] = '\0';
return llvm::StringRef(mem, Blob.size()); return mem;
} }
}; };
} }
@ -135,7 +134,7 @@ CXString CXLoadedDiagnostic::getFixIt(unsigned FixIt,
assert(FixIt < FixIts.size()); assert(FixIt < FixIts.size());
if (ReplacementRange) if (ReplacementRange)
*ReplacementRange = FixIts[FixIt].first; *ReplacementRange = FixIts[FixIt].first;
return FixIts[FixIt].second; return cxstring::createRef(FixIts[FixIt].second);
} }
void CXLoadedDiagnostic::decodeLocation(CXSourceLocation location, void CXLoadedDiagnostic::decodeLocation(CXSourceLocation location,
@ -220,7 +219,7 @@ class DiagLoader {
bool allowEmptyString = false); bool allowEmptyString = false);
LoadResult readString(CXLoadedDiagnosticSetImpl &TopDiags, LoadResult readString(CXLoadedDiagnosticSetImpl &TopDiags,
llvm::StringRef &RetStr, const char *&RetStr,
llvm::StringRef errorContext, llvm::StringRef errorContext,
RecordData &Record, RecordData &Record,
StringRef Blob, StringRef Blob,
@ -434,7 +433,7 @@ LoadResult DiagLoader::readMetaBlock(llvm::BitstreamCursor &Stream) {
} }
LoadResult DiagLoader::readString(CXLoadedDiagnosticSetImpl &TopDiags, LoadResult DiagLoader::readString(CXLoadedDiagnosticSetImpl &TopDiags,
llvm::StringRef &RetStr, const char *&RetStr,
llvm::StringRef errorContext, llvm::StringRef errorContext,
RecordData &Record, RecordData &Record,
StringRef Blob, StringRef Blob,
@ -458,7 +457,7 @@ LoadResult DiagLoader::readString(CXLoadedDiagnosticSetImpl &TopDiags,
return Failure; return Failure;
} }
RetStr = TopDiags.makeString(Blob); RetStr = TopDiags.copyString(Blob);
return Success; return Success;
} }
@ -468,7 +467,7 @@ LoadResult DiagLoader::readString(CXLoadedDiagnosticSetImpl &TopDiags,
RecordData &Record, RecordData &Record,
StringRef Blob, StringRef Blob,
bool allowEmptyString) { bool allowEmptyString) {
llvm::StringRef RetStr; const char *RetStr;
if (readString(TopDiags, RetStr, errorContext, Record, Blob, if (readString(TopDiags, RetStr, errorContext, Record, Blob,
allowEmptyString)) allowEmptyString))
return Failure; return Failure;
@ -622,11 +621,11 @@ LoadResult DiagLoader::readDiagnosticBlock(llvm::BitstreamCursor &Stream,
CXSourceRange SR; CXSourceRange SR;
if (readRange(TopDiags, Record, 0, SR)) if (readRange(TopDiags, Record, 0, SR))
return Failure; return Failure;
llvm::StringRef RetStr; const char *RetStr;
if (readString(TopDiags, RetStr, "FIXIT", Record, Blob, if (readString(TopDiags, RetStr, "FIXIT", Record, Blob,
/* allowEmptyString */ true)) /* allowEmptyString */ true))
return Failure; return Failure;
D->FixIts.push_back(std::make_pair(SR, cxstring::createRef(RetStr))); D->FixIts.push_back(std::make_pair(SR, RetStr));
continue; continue;
} }
@ -639,7 +638,7 @@ LoadResult DiagLoader::readDiagnosticBlock(llvm::BitstreamCursor &Stream,
unsigned diagFlag = Record[offset++]; unsigned diagFlag = Record[offset++];
D->DiagOption = diagFlag ? TopDiags.WarningFlags[diagFlag] : ""; D->DiagOption = diagFlag ? TopDiags.WarningFlags[diagFlag] : "";
D->CategoryText = D->category ? TopDiags.Categories[D->category] : ""; D->CategoryText = D->category ? TopDiags.Categories[D->category] : "";
D->Spelling = TopDiags.makeString(Blob); D->Spelling = TopDiags.copyString(Blob);
continue; continue;
} }
} }

View File

@ -82,8 +82,8 @@ public:
Location DiagLoc; Location DiagLoc;
std::vector<CXSourceRange> Ranges; std::vector<CXSourceRange> Ranges;
std::vector<std::pair<CXSourceRange, CXString> > FixIts; std::vector<std::pair<CXSourceRange, const char *> > FixIts;
llvm::StringRef Spelling; const char *Spelling;
llvm::StringRef DiagOption; llvm::StringRef DiagOption;
llvm::StringRef CategoryText; llvm::StringRef CategoryText;
unsigned severity; unsigned severity;