forked from OSchip/llvm-project
Give SourceManager a Diagnostic object with which to report errors,
and start simplifying the interfaces in SourceManager that can fail. llvm-svn: 98594
This commit is contained in:
parent
5599256415
commit
e0fbb83b8b
|
@ -357,7 +357,7 @@ public:
|
|||
TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; }
|
||||
|
||||
|
||||
const char *getCommentForDecl(const Decl *D, Diagnostic &Diags);
|
||||
const char *getCommentForDecl(const Decl *D);
|
||||
|
||||
// Builtin Types.
|
||||
CanQualType VoidTy;
|
||||
|
|
|
@ -321,6 +321,9 @@ public:
|
|||
/// location indicates where the expanded token came from and the instantiation
|
||||
/// location specifies where it was expanded.
|
||||
class SourceManager {
|
||||
/// \brief Diagnostic object.
|
||||
Diagnostic &Diag;
|
||||
|
||||
mutable llvm::BumpPtrAllocator ContentCacheAlloc;
|
||||
|
||||
/// FileInfos - Memoized information about all of the files tracked by this
|
||||
|
@ -380,8 +383,8 @@ class SourceManager {
|
|||
explicit SourceManager(const SourceManager&);
|
||||
void operator=(const SourceManager&);
|
||||
public:
|
||||
SourceManager()
|
||||
: ExternalSLocEntries(0), LineTable(0), NumLinearScans(0),
|
||||
SourceManager(Diagnostic &Diag)
|
||||
: Diag(Diag), ExternalSLocEntries(0), LineTable(0), NumLinearScans(0),
|
||||
NumBinaryProbes(0) {
|
||||
clearIDTables();
|
||||
}
|
||||
|
@ -482,22 +485,13 @@ public:
|
|||
return getSLocEntry(FID).getFile().getContentCache()->Entry;
|
||||
}
|
||||
|
||||
/// getBufferData - Return a pointer to the start and end of the source buffer
|
||||
/// data for the specified FileID.
|
||||
///
|
||||
/// If an error occurs while reading in the file, provides the file name
|
||||
/// and a non-empty error string and returns a pair of NULL pointers.
|
||||
std::pair<const char*, const char*> getBufferData(FileID FID,
|
||||
llvm::StringRef &FileName,
|
||||
std::string &Error) const;
|
||||
|
||||
/// getBufferData - Return a pointer to the start and end of the source buffer
|
||||
/// data for the specified FileID.
|
||||
///
|
||||
/// If an error occurs while reading in the file, emits a diagnostic to the
|
||||
/// given \c Diagnostic object and returns a pair of NULL pointers.
|
||||
std::pair<const char*, const char*> getBufferData(FileID FID,
|
||||
Diagnostic &Diags) const;
|
||||
/// \param FID The file ID whose contents will be returned.
|
||||
/// \param Invalid If non-NULL, will be set true if an error occurred.
|
||||
std::pair<const char*, const char*> getBufferData(FileID FID,
|
||||
bool *Invalid = 0) const;
|
||||
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
|
|
@ -121,7 +121,7 @@ public:
|
|||
};
|
||||
friend class ConcurrencyCheck;
|
||||
|
||||
ASTUnit(bool MainFileIsAST);
|
||||
ASTUnit(Diagnostic &Diag, bool MainFileIsAST);
|
||||
~ASTUnit();
|
||||
|
||||
bool isMainFileAST() const { return MainFileIsAST; }
|
||||
|
|
|
@ -423,12 +423,13 @@ namespace {
|
|||
/// (which requires a < after the Doxygen-comment delimiter). Otherwise,
|
||||
/// we only return true when we find a non-member comment.
|
||||
static bool
|
||||
isDoxygenComment(SourceManager &SourceMgr, Diagnostic &Diags,
|
||||
SourceRange Comment, bool Member = false) {
|
||||
isDoxygenComment(SourceManager &SourceMgr, SourceRange Comment,
|
||||
bool Member = false) {
|
||||
bool Invalid = false;
|
||||
const char *BufferStart
|
||||
= SourceMgr.getBufferData(SourceMgr.getFileID(Comment.getBegin()),
|
||||
Diags).first;
|
||||
if (!BufferStart)
|
||||
&Invalid).first;
|
||||
if (Invalid)
|
||||
return false;
|
||||
|
||||
const char *Start = BufferStart + SourceMgr.getFileOffset(Comment.getBegin());
|
||||
|
@ -448,7 +449,7 @@ isDoxygenComment(SourceManager &SourceMgr, Diagnostic &Diags,
|
|||
|
||||
/// \brief Retrieve the comment associated with the given declaration, if
|
||||
/// it has one.
|
||||
const char *ASTContext::getCommentForDecl(const Decl *D, Diagnostic &Diags) {
|
||||
const char *ASTContext::getCommentForDecl(const Decl *D) {
|
||||
if (!D)
|
||||
return 0;
|
||||
|
||||
|
@ -492,15 +493,16 @@ const char *ASTContext::getCommentForDecl(const Decl *D, Diagnostic &Diags) {
|
|||
// beginning of the file buffer.
|
||||
std::pair<FileID, unsigned> DeclStartDecomp
|
||||
= SourceMgr.getDecomposedLoc(DeclStartLoc);
|
||||
bool Invalid = false;
|
||||
const char *FileBufferStart
|
||||
= SourceMgr.getBufferData(DeclStartDecomp.first, Diags).first;
|
||||
if (!FileBufferStart)
|
||||
= SourceMgr.getBufferData(DeclStartDecomp.first, &Invalid).first;
|
||||
if (Invalid)
|
||||
return 0;
|
||||
|
||||
// First check whether we have a comment for a member.
|
||||
if (LastComment != Comments.end() &&
|
||||
!isa<TagDecl>(D) && !isa<NamespaceDecl>(D) &&
|
||||
isDoxygenComment(SourceMgr, Diags, *LastComment, true)) {
|
||||
isDoxygenComment(SourceMgr, *LastComment, true)) {
|
||||
std::pair<FileID, unsigned> LastCommentEndDecomp
|
||||
= SourceMgr.getDecomposedLoc(LastComment->getEnd());
|
||||
if (DeclStartDecomp.first == LastCommentEndDecomp.first &&
|
||||
|
@ -532,7 +534,7 @@ const char *ASTContext::getCommentForDecl(const Decl *D, Diagnostic &Diags) {
|
|||
return 0;
|
||||
|
||||
// Check that we actually have a Doxygen comment.
|
||||
if (!isDoxygenComment(SourceMgr, Diags, *LastComment))
|
||||
if (!isDoxygenComment(SourceMgr, *LastComment))
|
||||
return 0;
|
||||
|
||||
// Compute the starting line for the declaration and for the end of the
|
||||
|
@ -567,7 +569,7 @@ const char *ASTContext::getCommentForDecl(const Decl *D, Diagnostic &Diags) {
|
|||
}
|
||||
|
||||
// If this comment is not a Doxygen comment, we're done.
|
||||
if (!isDoxygenComment(SourceMgr, Diags, *FirstComment)) {
|
||||
if (!isDoxygenComment(SourceMgr, *FirstComment)) {
|
||||
++FirstComment;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "llvm/System/Path.h"
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <cstdio>
|
||||
|
||||
using namespace clang;
|
||||
|
@ -532,19 +533,17 @@ bool SourceManager::overrideFileContents(const FileEntry *SourceFile,
|
|||
}
|
||||
|
||||
std::pair<const char*, const char*>
|
||||
SourceManager::getBufferData(FileID FID, llvm::StringRef &FileName,
|
||||
std::string &Error) const {
|
||||
const llvm::MemoryBuffer *Buf = getBuffer(FID).getBuffer(FileName, Error);
|
||||
if (!Error.empty())
|
||||
return std::make_pair((const char *)0, (const char *)0);
|
||||
return std::make_pair(Buf->getBufferStart(), Buf->getBufferEnd());
|
||||
}
|
||||
|
||||
std::pair<const char*, const char*>
|
||||
SourceManager::getBufferData(FileID FID, Diagnostic &Diags) const {
|
||||
const llvm::MemoryBuffer *Buf = getBuffer(FID).getBuffer(Diags);
|
||||
if (!Buf)
|
||||
return std::make_pair((const char *)0, (const char *)0);
|
||||
SourceManager::getBufferData(FileID FID, bool *Invalid) const {
|
||||
if (Invalid)
|
||||
*Invalid = false;
|
||||
|
||||
const llvm::MemoryBuffer *Buf = getBuffer(FID).getBuffer(Diag);
|
||||
if (!Buf) {
|
||||
if (*Invalid)
|
||||
*Invalid = true;
|
||||
const char *FakeText = "";
|
||||
return std::make_pair(FakeText, FakeText + strlen(FakeText));
|
||||
}
|
||||
return std::make_pair(Buf->getBufferStart(), Buf->getBufferEnd());
|
||||
}
|
||||
|
||||
|
|
|
@ -35,8 +35,9 @@
|
|||
#include "llvm/System/Path.h"
|
||||
using namespace clang;
|
||||
|
||||
ASTUnit::ASTUnit(bool _MainFileIsAST)
|
||||
: MainFileIsAST(_MainFileIsAST), ConcurrencyCheckValue(CheckUnlocked) {
|
||||
ASTUnit::ASTUnit(Diagnostic &Diag, bool _MainFileIsAST)
|
||||
: SourceMgr(Diag), MainFileIsAST(_MainFileIsAST),
|
||||
ConcurrencyCheckValue(CheckUnlocked) {
|
||||
}
|
||||
ASTUnit::~ASTUnit() {
|
||||
ConcurrencyCheckValue = CheckLocked;
|
||||
|
@ -146,7 +147,7 @@ ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename,
|
|||
RemappedFile *RemappedFiles,
|
||||
unsigned NumRemappedFiles,
|
||||
bool CaptureDiagnostics) {
|
||||
llvm::OwningPtr<ASTUnit> AST(new ASTUnit(true));
|
||||
llvm::OwningPtr<ASTUnit> AST(new ASTUnit(Diags, true));
|
||||
AST->OnlyLocalDecls = OnlyLocalDecls;
|
||||
AST->HeaderInfo.reset(new HeaderSearch(AST->getFileManager()));
|
||||
|
||||
|
@ -311,7 +312,7 @@ ASTUnit *ASTUnit::LoadFromCompilerInvocation(CompilerInvocation *CI,
|
|||
"FIXME: AST inputs not yet supported here!");
|
||||
|
||||
// Create the AST unit.
|
||||
AST.reset(new ASTUnit(false));
|
||||
AST.reset(new ASTUnit(Diags, false));
|
||||
AST->OnlyLocalDecls = OnlyLocalDecls;
|
||||
AST->OriginalSourceFile = Clang.getFrontendOpts().Inputs[0].second;
|
||||
|
||||
|
|
|
@ -185,7 +185,7 @@ void CompilerInstance::createFileManager() {
|
|||
// Source Manager
|
||||
|
||||
void CompilerInstance::createSourceManager() {
|
||||
SourceMgr.reset(new SourceManager());
|
||||
SourceMgr.reset(new SourceManager(getDiagnostics()));
|
||||
}
|
||||
|
||||
// Preprocessor
|
||||
|
|
|
@ -706,11 +706,7 @@ void RewriteObjC::HandleTopLevelSingleDecl(Decl *D) {
|
|||
|
||||
void RewriteObjC::RewriteInclude() {
|
||||
SourceLocation LocStart = SM->getLocForStartOfFile(MainFileID);
|
||||
std::pair<const char*, const char*> MainBuf = SM->getBufferData(MainFileID,
|
||||
Diags);
|
||||
if (!MainBuf.first)
|
||||
return;
|
||||
|
||||
std::pair<const char*, const char*> MainBuf = SM->getBufferData(MainFileID);
|
||||
const char *MainBufStart = MainBuf.first;
|
||||
const char *MainBufEnd = MainBuf.second;
|
||||
size_t ImportLen = strlen("import");
|
||||
|
@ -735,11 +731,7 @@ void RewriteObjC::RewriteInclude() {
|
|||
}
|
||||
|
||||
void RewriteObjC::RewriteTabs() {
|
||||
std::pair<const char*, const char*> MainBuf = SM->getBufferData(MainFileID,
|
||||
Diags);
|
||||
if (!MainBuf.first)
|
||||
return;
|
||||
|
||||
std::pair<const char*, const char*> MainBuf = SM->getBufferData(MainFileID);
|
||||
const char *MainBufStart = MainBuf.first;
|
||||
const char *MainBufEnd = MainBuf.second;
|
||||
|
||||
|
@ -981,11 +973,7 @@ void RewriteObjC::RewriteCategoryDecl(ObjCCategoryDecl *CatDecl) {
|
|||
}
|
||||
|
||||
void RewriteObjC::RewriteProtocolDecl(ObjCProtocolDecl *PDecl) {
|
||||
std::pair<const char*, const char*> MainBuf = SM->getBufferData(MainFileID,
|
||||
Diags);
|
||||
if (!MainBuf.first)
|
||||
return;
|
||||
|
||||
std::pair<const char*, const char*> MainBuf = SM->getBufferData(MainFileID);
|
||||
SourceLocation LocStart = PDecl->getLocStart();
|
||||
|
||||
// FIXME: handle protocol headers that are declared across multiple lines.
|
||||
|
|
|
@ -330,15 +330,14 @@ void TextDiagnosticPrinter::EmitCaretDiagnostic(SourceLocation Loc,
|
|||
unsigned FileOffset = LocInfo.second;
|
||||
|
||||
// Get information about the buffer it points into.
|
||||
llvm::StringRef ErrorFileName;
|
||||
std::string ErrorStr;
|
||||
bool Invalid = false;
|
||||
std::pair<const char*, const char*> BufferInfo = SM.getBufferData(FID,
|
||||
ErrorFileName,
|
||||
ErrorStr);
|
||||
const char *BufStart = BufferInfo.first;
|
||||
if (!BufStart)
|
||||
&Invalid);
|
||||
if (Invalid)
|
||||
return;
|
||||
|
||||
const char *BufStart = BufferInfo.first;
|
||||
|
||||
unsigned ColNo = SM.getColumnNumber(FID, FileOffset);
|
||||
unsigned CaretEndColNo
|
||||
= ColNo + Lexer::MeasureTokenLength(Loc, SM, *LangOpts);
|
||||
|
|
|
@ -229,12 +229,10 @@ unsigned Lexer::MeasureTokenLength(SourceLocation Loc,
|
|||
// the token this macro expanded to.
|
||||
Loc = SM.getInstantiationLoc(Loc);
|
||||
std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
|
||||
llvm::StringRef FileName;
|
||||
std::string ErrorStr;
|
||||
bool Invalid = false;
|
||||
std::pair<const char *,const char *> Buffer = SM.getBufferData(LocInfo.first,
|
||||
FileName,
|
||||
ErrorStr);
|
||||
if (!Buffer.first)
|
||||
&Invalid);
|
||||
if (Invalid)
|
||||
return 0;
|
||||
|
||||
const char *StrData = Buffer.first+LocInfo.second;
|
||||
|
|
|
@ -439,9 +439,10 @@ bool TokenLexer::PasteTokens(Token &Tok) {
|
|||
SourceManager &SourceMgr = PP.getSourceManager();
|
||||
FileID LocFileID = SourceMgr.getFileID(ResultTokLoc);
|
||||
|
||||
bool Invalid = false;
|
||||
const char *ScratchBufStart
|
||||
= SourceMgr.getBufferData(LocFileID, PP.getDiagnostics()).first;
|
||||
if (!ScratchBufStart)
|
||||
= SourceMgr.getBufferData(LocFileID, &Invalid).first;
|
||||
if (Invalid)
|
||||
return false;
|
||||
|
||||
// Make a lexer to lex this string from. Lex just this one token.
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include "llvm/ADT/OwningPtr.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cstdio>
|
||||
using namespace clang;
|
||||
|
||||
|
||||
|
@ -44,15 +43,10 @@ void html::HighlightRange(Rewriter &R, SourceLocation B, SourceLocation E,
|
|||
// Include the whole end token in the range.
|
||||
EOffset += Lexer::MeasureTokenLength(E, R.getSourceMgr(), R.getLangOpts());
|
||||
|
||||
llvm::StringRef FileName;
|
||||
std::string ErrorStr;
|
||||
const char *BufferStart = SM.getBufferData(FID, FileName, ErrorStr).first;
|
||||
if (!BufferStart) {
|
||||
// FIXME: Add a diagnostic object somewhere?
|
||||
fprintf(stderr, "error: cannot open file '%s': %s\n",
|
||||
FileName.str().c_str(), ErrorStr.c_str());
|
||||
bool Invalid = false;
|
||||
const char *BufferStart = SM.getBufferData(FID, &Invalid).first;
|
||||
if (Invalid)
|
||||
return;
|
||||
}
|
||||
|
||||
HighlightRange(R.getEditBuffer(FID), BOffset, EOffset,
|
||||
BufferStart, StartTag, EndTag);
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include "clang/Lex/Lexer.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cstdio>
|
||||
using namespace clang;
|
||||
|
||||
void RewriteBuffer::RemoveText(unsigned OrigOffset, unsigned Size) {
|
||||
|
@ -166,17 +165,7 @@ RewriteBuffer &Rewriter::getEditBuffer(FileID FID) {
|
|||
return I->second;
|
||||
I = RewriteBuffers.insert(I, std::make_pair(FID, RewriteBuffer()));
|
||||
|
||||
llvm::StringRef FileName;
|
||||
std::string ErrorStr;
|
||||
|
||||
std::pair<const char*, const char*> MB
|
||||
= SourceMgr->getBufferData(FID, FileName, ErrorStr);
|
||||
if (!MB.first) {
|
||||
// FIXME: Add a diagnostic object somewhere?
|
||||
fprintf(stderr, "error: cannot open file '%s': %s\n",
|
||||
FileName.str().c_str(), ErrorStr.c_str());
|
||||
}
|
||||
|
||||
std::pair<const char*, const char*> MB = SourceMgr->getBufferData(FID);
|
||||
I->second.Initialize(MB.first, MB.second);
|
||||
|
||||
return I->second;
|
||||
|
|
|
@ -59,9 +59,10 @@ SourceLocation Sema::getLocationOfStringLiteralByte(const StringLiteral *SL,
|
|||
// Re-lex the token to get its length and original spelling.
|
||||
std::pair<FileID, unsigned> LocInfo =
|
||||
SourceMgr.getDecomposedLoc(StrTokSpellingLoc);
|
||||
bool Invalid = false;
|
||||
std::pair<const char *,const char *> Buffer =
|
||||
SourceMgr.getBufferData(LocInfo.first, Diags);
|
||||
if (!Buffer.first)
|
||||
SourceMgr.getBufferData(LocInfo.first, &Invalid);
|
||||
if (Invalid)
|
||||
return StrTokSpellingLoc;
|
||||
|
||||
const char *StrData = Buffer.first+LocInfo.second;
|
||||
|
|
|
@ -1133,7 +1133,8 @@ clang_createTranslationUnitFromSourceFile(CXIndex CIdx,
|
|||
// We failed to load the ASTUnit, but we can still deserialize the
|
||||
// diagnostics and emit them.
|
||||
FileManager FileMgr;
|
||||
SourceManager SourceMgr;
|
||||
Diagnostic Diag;
|
||||
SourceManager SourceMgr(Diag);
|
||||
// FIXME: Faked LangOpts!
|
||||
LangOptions LangOpts;
|
||||
llvm::SmallVector<StoredDiagnostic, 4> Diags;
|
||||
|
@ -2042,10 +2043,10 @@ CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
|
|||
SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
|
||||
std::pair<FileID, unsigned> LocInfo
|
||||
= CXXUnit->getSourceManager().getDecomposedLoc(Loc);
|
||||
bool Invalid = false;
|
||||
std::pair<const char *,const char *> Buffer
|
||||
= CXXUnit->getSourceManager().getBufferData(LocInfo.first,
|
||||
CXXUnit->getPreprocessor().getDiagnostics());
|
||||
if (!Buffer.first)
|
||||
= CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
|
||||
if (Invalid)
|
||||
return createCXString("");
|
||||
|
||||
return createCXString(llvm::StringRef(Buffer.first+LocInfo.second,
|
||||
|
@ -2098,11 +2099,9 @@ void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
|
|||
return;
|
||||
|
||||
// Create a lexer
|
||||
bool Invalid = false;
|
||||
std::pair<const char *,const char *> Buffer
|
||||
= SourceMgr.getBufferData(BeginLocInfo.first,
|
||||
CXXUnit->getPreprocessor().getDiagnostics());
|
||||
if (!Buffer.first)
|
||||
return;
|
||||
= SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
|
||||
|
||||
Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
|
||||
CXXUnit->getASTContext().getLangOptions(),
|
||||
|
@ -2135,10 +2134,10 @@ void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range,
|
|||
// Lookup the identifier to determine whether we have a keyword.
|
||||
std::pair<FileID, unsigned> LocInfo
|
||||
= SourceMgr.getDecomposedLoc(Tok.getLocation());
|
||||
bool Invalid = false;
|
||||
std::pair<const char *, const char *> Buf
|
||||
= CXXUnit->getSourceManager().getBufferData(LocInfo.first,
|
||||
CXXUnit->getPreprocessor().getDiagnostics());
|
||||
if (!Buf.first)
|
||||
= CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
|
||||
if (Invalid)
|
||||
return;
|
||||
|
||||
const char *StartPos= Buf.first + LocInfo.second;
|
||||
|
|
|
@ -187,6 +187,9 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
|
|||
/// \brief Diagnostics produced while performing code completion.
|
||||
llvm::SmallVector<StoredDiagnostic, 8> Diagnostics;
|
||||
|
||||
/// \brief Diag object
|
||||
Diagnostic Diag;
|
||||
|
||||
/// \brief Language options used to adjust source locations.
|
||||
LangOptions LangOpts;
|
||||
|
||||
|
@ -202,7 +205,7 @@ struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
|
|||
};
|
||||
|
||||
AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults()
|
||||
: CXCodeCompleteResults(), Buffer(0) { }
|
||||
: CXCodeCompleteResults(), Buffer(0), SourceMgr(Diag) { }
|
||||
|
||||
AllocatedCXCodeCompleteResults::~AllocatedCXCodeCompleteResults() {
|
||||
for (unsigned I = 0, N = NumResults; I != N; ++I)
|
||||
|
|
Loading…
Reference in New Issue