//===--- SourceManager.cpp - Track and cache source files -----------------===////// The LLVM Compiler Infrastructure//// This file is distributed under the University of Illinois Open Source// License. See LICENSE.TXT for details.////===----------------------------------------------------------------------===////// This file implements the SourceManager interface.////===----------------------------------------------------------------------===//#include"clang/Basic/SourceManager.h"#include"clang/Basic/SourceManagerInternals.h"#include"clang/Basic/Diagnostic.h"#include"clang/Basic/FileManager.h"#include"llvm/Support/Compiler.h"#include"llvm/Support/MemoryBuffer.h"#include"llvm/Support/raw_ostream.h"#include"llvm/System/Path.h"#include<algorithm>#include<string>#include<cstdio>usingnamespaceclang;usingnamespaceSrcMgr;usingllvm::MemoryBuffer;//===----------------------------------------------------------------------===//// SourceManager Helper Classes//===----------------------------------------------------------------------===//structBufferResult::FailureData{constllvm::MemoryBuffer*Buffer;constchar*FileName;std::stringErrorStr;};BufferResult::BufferResult(constBufferResult&Other){if(constllvm::MemoryBuffer*Buffer=Other.Data.dyn_cast<constllvm::MemoryBuffer*>()){Data=Buffer;return;}Data=newFailureData(*Other.Data.get<FailureData*>());}BufferResult::BufferResult(constchar*FileName,llvm::StringRefErrorStr,constllvm::MemoryBuffer*Buffer){FailureData*FD=newFailureData;FD->FileName=FileName;FD->ErrorStr=ErrorStr;FD->Buffer=Buffer;Data=FD;}BufferResult::~BufferResult(){if(FailureData*FD=Data.dyn_cast<FailureData*>())deleteFD;}boolBufferResult::isInvalid()const{returnData.is<FailureData*>();}constllvm::MemoryBuffer*BufferResult::getBuffer(Diagnostic&Diags)const{llvm::StringRefFileName;std::stringErrorMsg;constllvm::MemoryBuffer*Result=getBuffer(FileName,ErrorMsg);if(!ErrorMsg.empty()){Diags.Report(diag::err_cannot_open_file)<<FileName<<ErrorMsg;}returnResult;}constllvm::MemoryBuffer*BufferResult::getBuffer(llvm::StringRef&FileName,std::string&Error)const{if(constllvm::MemoryBuffer*Buffer=Data.dyn_cast<constllvm::MemoryBuffer*>())returnBuffer;FailureData*Fail=Data.get<FailureData*>();FileName=Fail->FileName;Error=Fail->ErrorStr;