forked from OSchip/llvm-project
* Remove isInSystemHeader() from DiagClient, move it to SourceManager
* Move FormatError() from TextDiagnostic up to DiagClient, remove now empty class TextDiagnostic * Make DiagClient optional for Diagnostic This fixes the following problems: * -html-diags (and probably others) does now output the same set of warnings as console clang does * nothing crashes if one forgets to call setHeaderSearch() on TextDiagnostic * some code duplication is removed llvm-svn: 54620
This commit is contained in:
parent
cb1e06e8fd
commit
4c3116437c
|
@ -183,8 +183,11 @@ static bool CompareDiagLists(SourceManager &SourceMgr,
|
|||
static bool CheckResults(Preprocessor &PP,
|
||||
const DiagList &ExpectedErrors,
|
||||
const DiagList &ExpectedWarnings) {
|
||||
const DiagnosticClient *DiagClient = PP.getDiagnostics().getClient();
|
||||
assert(DiagClient != 0 &&
|
||||
"DiagChecker requires a valid TextDiagnosticBuffer");
|
||||
const TextDiagnosticBuffer &Diags =
|
||||
static_cast<const TextDiagnosticBuffer&>(PP.getDiagnostics().getClient());
|
||||
static_cast<const TextDiagnosticBuffer&>(*DiagClient);
|
||||
SourceManager &SourceMgr = PP.getSourceManager();
|
||||
|
||||
// We want to capture the delta between what was expected and what was
|
||||
|
|
|
@ -1387,7 +1387,7 @@ int main(int argc, char **argv) {
|
|||
|
||||
// Create the diagnostic client for reporting errors or for
|
||||
// implementing -verify.
|
||||
TextDiagnostics* TextDiagClient = 0;
|
||||
DiagnosticClient* TextDiagClient = 0;
|
||||
|
||||
if (!VerifyDiagnostics) {
|
||||
// Print diagnostics to stderr by default.
|
||||
|
@ -1460,7 +1460,6 @@ int main(int argc, char **argv) {
|
|||
|
||||
// Process the -I options and set them in the HeaderInfo.
|
||||
HeaderSearch HeaderInfo(FileMgr);
|
||||
if (TextDiagClient) TextDiagClient->setHeaderSearch(HeaderInfo);
|
||||
|
||||
// FIXME: Sink IncludeGroup into this loop.
|
||||
IncludeGroup[0].clear();
|
||||
|
|
|
@ -76,16 +76,17 @@ private:
|
|||
|
||||
/// CustomDiagInfo - Information for uniquing and looking up custom diags.
|
||||
diag::CustomDiagInfo *CustomDiagInfo;
|
||||
|
||||
public:
|
||||
explicit Diagnostic(DiagnosticClient *client);
|
||||
explicit Diagnostic(DiagnosticClient *client = 0);
|
||||
~Diagnostic();
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Diagnostic characterization methods, used by a client to customize how
|
||||
//
|
||||
|
||||
DiagnosticClient &getClient() { return *Client; };
|
||||
const DiagnosticClient &getClient() const { return *Client; };
|
||||
DiagnosticClient *getClient() { return Client; };
|
||||
const DiagnosticClient *getClient() const { return Client; };
|
||||
|
||||
void setClient(DiagnosticClient* client) { Client = client; }
|
||||
|
||||
|
@ -181,13 +182,14 @@ public:
|
|||
/// DiagnosticClient - This is an abstract interface implemented by clients of
|
||||
/// the front-end, which formats and prints fully processed diagnostics.
|
||||
class DiagnosticClient {
|
||||
protected:
|
||||
std::string FormatDiagnostic(Diagnostic &Diags, Diagnostic::Level Level,
|
||||
diag::kind ID,
|
||||
const std::string *Strs,
|
||||
unsigned NumStrs);
|
||||
public:
|
||||
virtual ~DiagnosticClient();
|
||||
|
||||
/// isInSystemHeader - If the client can tell that this is a system header,
|
||||
/// return true.
|
||||
virtual bool isInSystemHeader(FullSourceLoc Pos) const { return false; }
|
||||
|
||||
/// HandleDiagnostic - Handle this diagnostic, reporting it to the user or
|
||||
/// capturing it to a log as needed.
|
||||
virtual void HandleDiagnostic(Diagnostic &Diags,
|
||||
|
|
|
@ -247,6 +247,8 @@ public:
|
|||
const char* getSourceName() const;
|
||||
const FileEntry* getFileEntryForLoc() const;
|
||||
|
||||
bool isInSystemHeader() const;
|
||||
|
||||
bool isFileID() const { return Loc.isFileID(); }
|
||||
|
||||
unsigned getCanonicalFileID() const;
|
||||
|
|
|
@ -112,7 +112,10 @@ namespace SrcMgr {
|
|||
/// ChunkNo - Really large buffers are broken up into chunks that are
|
||||
/// each (1 << SourceLocation::FilePosBits) in size. This specifies the
|
||||
/// chunk number of this FileID.
|
||||
unsigned ChunkNo;
|
||||
unsigned ChunkNo:30;
|
||||
|
||||
/// isSystemHeader - Set for system header files.
|
||||
bool isSysHeader:1;
|
||||
|
||||
/// Content - Information about the source buffer itself.
|
||||
const ContentCache* Content;
|
||||
|
@ -120,17 +123,19 @@ namespace SrcMgr {
|
|||
public:
|
||||
/// get - Return a FileIDInfo object.
|
||||
static FileIDInfo get(SourceLocation IL, unsigned CN,
|
||||
const ContentCache *Con) {
|
||||
const ContentCache *Con, bool SysHeader) {
|
||||
FileIDInfo X;
|
||||
X.IncludeLoc = IL;
|
||||
X.ChunkNo = CN;
|
||||
X.Content = Con;
|
||||
X.isSysHeader = SysHeader;
|
||||
return X;
|
||||
}
|
||||
|
||||
SourceLocation getIncludeLoc() const { return IncludeLoc; }
|
||||
unsigned getChunkNo() const { return ChunkNo; }
|
||||
const ContentCache* getContentCache() const { return Content; }
|
||||
bool isSystemHeader() const { return isSysHeader; }
|
||||
|
||||
/// Emit - Emit this FileIDInfo to Bitcode.
|
||||
void Emit(llvm::Serializer& S) const;
|
||||
|
@ -244,10 +249,11 @@ public:
|
|||
/// createFileID - Create a new FileID that represents the specified file
|
||||
/// being #included from the specified IncludePosition. This returns 0 on
|
||||
/// error and translates NULL into standard input.
|
||||
unsigned createFileID(const FileEntry *SourceFile, SourceLocation IncludePos){
|
||||
unsigned createFileID(const FileEntry *SourceFile, SourceLocation IncludePos,
|
||||
bool isSysHeader = false) {
|
||||
const SrcMgr::ContentCache *IR = getContentCache(SourceFile);
|
||||
if (IR == 0) return 0; // Error opening file?
|
||||
return createFileID(IR, IncludePos);
|
||||
return createFileID(IR, IncludePos, isSysHeader);
|
||||
}
|
||||
|
||||
/// createMainFileID - Create the FileID for the main source file.
|
||||
|
@ -262,8 +268,10 @@ public:
|
|||
/// createFileIDForMemBuffer - Create a new FileID that represents the
|
||||
/// specified memory buffer. This does no caching of the buffer and takes
|
||||
/// ownership of the MemoryBuffer, so only pass a MemoryBuffer to this once.
|
||||
unsigned createFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer) {
|
||||
return createFileID(createMemBufferContentCache(Buffer), SourceLocation());
|
||||
unsigned createFileIDForMemBuffer(const llvm::MemoryBuffer *Buffer,
|
||||
bool isSysHeader = false) {
|
||||
return createFileID(createMemBufferContentCache(Buffer), SourceLocation(),
|
||||
isSysHeader);
|
||||
}
|
||||
|
||||
/// createMainFileIDForMembuffer - Create the FileID for a memory buffer
|
||||
|
@ -422,6 +430,12 @@ public:
|
|||
return getCanonicalFileID(Loc) == getMainFileID();
|
||||
}
|
||||
|
||||
/// isInSystemHeader - Returns if a SourceLocation is in a system header.
|
||||
bool isInSystemHeader(SourceLocation Loc) const {
|
||||
assert (Loc.isFileID() && "method only valid for file ids");
|
||||
return getFIDInfo(Loc.getFileID())->isSystemHeader();
|
||||
}
|
||||
|
||||
/// PrintStats - Print statistics to stderr.
|
||||
///
|
||||
void PrintStats() const;
|
||||
|
@ -440,7 +454,7 @@ private:
|
|||
/// include position. This works regardless of whether the ContentCache
|
||||
/// corresponds to a file or some other input source.
|
||||
unsigned createFileID(const SrcMgr::ContentCache* File,
|
||||
SourceLocation IncludePos);
|
||||
SourceLocation IncludePos, bool isSysHeader = false);
|
||||
|
||||
/// getContentCache - Create or return a cached ContentCache for the specified
|
||||
/// file. This returns null on failure.
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#ifndef DRIVER_TEXT_DIAGNOSTIC_BUFFER_H_
|
||||
#define DRIVER_TEXT_DIAGNOSTIC_BUFFER_H_
|
||||
|
||||
#include "clang/Driver/TextDiagnostics.h"
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include <vector>
|
||||
|
||||
namespace clang {
|
||||
|
@ -22,7 +22,7 @@ namespace clang {
|
|||
class Preprocessor;
|
||||
class SourceManager;
|
||||
|
||||
class TextDiagnosticBuffer : public TextDiagnostics {
|
||||
class TextDiagnosticBuffer : public DiagnosticClient {
|
||||
public:
|
||||
typedef std::vector<std::pair<SourceLocation, std::string> > DiagList;
|
||||
typedef DiagList::iterator iterator;
|
||||
|
@ -30,8 +30,6 @@ public:
|
|||
private:
|
||||
DiagList Errors, Warnings;
|
||||
public:
|
||||
TextDiagnosticBuffer() {}
|
||||
|
||||
const_iterator err_begin() const { return Errors.begin(); }
|
||||
const_iterator err_end() const { return Errors.end(); }
|
||||
|
||||
|
|
|
@ -15,14 +15,14 @@
|
|||
#ifndef TEXT_DIAGNOSTIC_PRINTER_H_
|
||||
#define TEXT_DIAGNOSTIC_PRINTER_H_
|
||||
|
||||
#include "clang/Driver/TextDiagnostics.h"
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "llvm/Support/Streams.h"
|
||||
|
||||
namespace clang {
|
||||
class SourceManager;
|
||||
|
||||
class TextDiagnosticPrinter : public TextDiagnostics {
|
||||
class TextDiagnosticPrinter : public DiagnosticClient {
|
||||
FullSourceLoc LastWarningLoc;
|
||||
FullSourceLoc LastLoc;
|
||||
llvm::OStream OS;
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
//===--- TextDiagnostics.h - Text Diagnostics Checkers ----------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This is the parent class for all text diagnostics.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef TEXT_DIAGNOSTICS_H_
|
||||
#define TEXT_DIAGNOSTICS_H_
|
||||
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
|
||||
namespace clang {
|
||||
class SourceManager;
|
||||
class HeaderSearch;
|
||||
class Preprocessor;
|
||||
|
||||
class TextDiagnostics : public DiagnosticClient {
|
||||
HeaderSearch *TheHeaderSearch;
|
||||
protected:
|
||||
std::string FormatDiagnostic(Diagnostic &Diags, Diagnostic::Level Level,
|
||||
diag::kind ID,
|
||||
const std::string *Strs,
|
||||
unsigned NumStrs);
|
||||
public:
|
||||
TextDiagnostics() {}
|
||||
virtual ~TextDiagnostics();
|
||||
|
||||
void setHeaderSearch(HeaderSearch &HS) { TheHeaderSearch = &HS; }
|
||||
|
||||
virtual bool isInSystemHeader(FullSourceLoc Pos) const;
|
||||
|
||||
virtual void HandleDiagnostic(Diagnostic &Diags, Diagnostic::Level DiagLevel,
|
||||
FullSourceLoc Pos,
|
||||
diag::kind ID,
|
||||
const std::string *Strs,
|
||||
unsigned NumStrs,
|
||||
const SourceRange *Ranges,
|
||||
unsigned NumRanges) = 0;
|
||||
};
|
||||
|
||||
} // end namspace clang
|
||||
|
||||
#endif
|
|
@ -470,6 +470,9 @@ private:
|
|||
/// #include.
|
||||
bool isInPrimaryFile() const;
|
||||
|
||||
/// isSystemHeader - Return true if F is a system header.
|
||||
bool isSystemHeader(const FileEntry* F) const;
|
||||
|
||||
/// DiscardUntilEndOfDirective - Read and discard all tokens remaining on the
|
||||
/// current line until the tok::eom token is found.
|
||||
void DiscardUntilEndOfDirective();
|
||||
|
|
|
@ -33,9 +33,6 @@ void PathDiagnosticClient::HandleDiagnostic(Diagnostic &Diags,
|
|||
|
||||
PathDiagnostic* D = new PathDiagnostic();
|
||||
|
||||
// Ripped from TextDiagnostics::FormatDiagnostic. Perhaps we should
|
||||
// centralize it somewhere?
|
||||
|
||||
std::ostringstream os;
|
||||
|
||||
switch (DiagLevel) {
|
||||
|
@ -47,16 +44,7 @@ void PathDiagnosticClient::HandleDiagnostic(Diagnostic &Diags,
|
|||
break;
|
||||
}
|
||||
|
||||
std::string Msg = Diags.getDescription(ID);
|
||||
|
||||
for (unsigned i = 0; i < Msg.size() - 1; ++i) {
|
||||
if (Msg[i] == '%' && isdigit(Msg[i + 1])) {
|
||||
unsigned StrNo = Msg[i + 1] - '0';
|
||||
Msg = std::string(Msg.begin(), Msg.begin() + i) +
|
||||
(StrNo < NumStrs ? Strs[StrNo] : "<<<INTERNAL ERROR>>>") +
|
||||
std::string(Msg.begin() + i + 2, Msg.end());
|
||||
}
|
||||
}
|
||||
std::string Msg = FormatDiagnostic(Diags, DiagLevel, ID, Strs, NumStrs);
|
||||
|
||||
os << Msg;
|
||||
|
||||
|
|
|
@ -203,11 +203,10 @@ Diagnostic::Level Diagnostic::getDiagnosticLevel(unsigned DiagID) const {
|
|||
}
|
||||
}
|
||||
|
||||
/// Report - Issue the message to the client. If the client wants us to stop
|
||||
/// compilation, return true, otherwise return false. DiagID is a member of
|
||||
/// the diag::kind enum.
|
||||
/// Report - Issue the message to the client.
|
||||
/// DiagID is a member of the diag::kind enum.
|
||||
void Diagnostic::Report(DiagnosticClient* C,
|
||||
FullSourceLoc Pos, unsigned DiagID,
|
||||
FullSourceLoc Loc, unsigned DiagID,
|
||||
const std::string *Strs, unsigned NumStrs,
|
||||
const SourceRange *Ranges, unsigned NumRanges) {
|
||||
|
||||
|
@ -221,29 +220,51 @@ void Diagnostic::Report(DiagnosticClient* C,
|
|||
// Set the diagnostic client if it isn't set already.
|
||||
if (!C) C = Client;
|
||||
|
||||
// If this is not an error and we are in a system header, ignore it. We have
|
||||
// to check on the original class here, because we also want to ignore
|
||||
// extensions and warnings in -Werror and -pedantic-errors modes, which *map*
|
||||
// warnings/extensions to errors.
|
||||
// If this is not an error and we are in a system header, ignore it. We
|
||||
// have to check on the original DiagID here, because we also want to
|
||||
// ignore extensions and warnings in -Werror and -pedantic-errors modes,
|
||||
// which *map* warnings/extensions to errors.
|
||||
if (DiagID < diag::NUM_BUILTIN_DIAGNOSTICS &&
|
||||
getBuiltinDiagClass(DiagID) != ERROR &&
|
||||
Client->isInSystemHeader(Pos))
|
||||
Loc.isValid() && Loc.isFileID() && Loc.isInSystemHeader())
|
||||
return;
|
||||
|
||||
if (DiagLevel >= Diagnostic::Error) {
|
||||
ErrorOccurred = true;
|
||||
|
||||
if (C == Client)
|
||||
if (C != 0 && C == Client)
|
||||
++NumErrors;
|
||||
}
|
||||
|
||||
// Finally, report it.
|
||||
|
||||
C->HandleDiagnostic(*this, DiagLevel, Pos, (diag::kind)DiagID,
|
||||
if (C != 0)
|
||||
C->HandleDiagnostic(*this, DiagLevel, Loc, (diag::kind)DiagID,
|
||||
Strs, NumStrs, Ranges, NumRanges);
|
||||
|
||||
if (C == Client)
|
||||
if (C != 0 && C == Client)
|
||||
++NumDiagnostics;
|
||||
}
|
||||
|
||||
|
||||
DiagnosticClient::~DiagnosticClient() {}
|
||||
|
||||
std::string DiagnosticClient::FormatDiagnostic(Diagnostic &Diags,
|
||||
Diagnostic::Level Level,
|
||||
diag::kind ID,
|
||||
const std::string *Strs,
|
||||
unsigned NumStrs) {
|
||||
std::string Msg = Diags.getDescription(ID);
|
||||
|
||||
// Replace all instances of %0 in Msg with 'Extra'.
|
||||
for (unsigned i = 0; i < Msg.size() - 1; ++i) {
|
||||
if (Msg[i] == '%' && isdigit(Msg[i + 1])) {
|
||||
unsigned StrNo = Msg[i + 1] - '0';
|
||||
Msg = std::string(Msg.begin(), Msg.begin() + i) +
|
||||
(StrNo < NumStrs ? Strs[StrNo] : "<<<INTERNAL ERROR>>>") +
|
||||
std::string(Msg.begin() + i + 2, Msg.end());
|
||||
}
|
||||
}
|
||||
|
||||
return Msg;
|
||||
}
|
||||
|
|
|
@ -79,6 +79,12 @@ const FileEntry* FullSourceLoc::getFileEntryForLoc() const {
|
|||
return SrcMgr->getFileEntryForLoc(Loc);
|
||||
}
|
||||
|
||||
bool FullSourceLoc::isInSystemHeader() const {
|
||||
assert (isValid());
|
||||
return SrcMgr->isInSystemHeader(Loc);
|
||||
}
|
||||
|
||||
|
||||
const char * FullSourceLoc::getCharacterData() const {
|
||||
assert (isValid());
|
||||
return SrcMgr->getCharacterData(Loc);
|
||||
|
|
|
@ -75,14 +75,15 @@ SourceManager::createMemBufferContentCache(const MemoryBuffer *Buffer) {
|
|||
/// include position. This works regardless of whether the ContentCache
|
||||
/// corresponds to a file or some other input source.
|
||||
unsigned SourceManager::createFileID(const ContentCache *File,
|
||||
SourceLocation IncludePos) {
|
||||
SourceLocation IncludePos,
|
||||
bool isSysHeader) {
|
||||
// If FileEnt is really large (e.g. it's a large .i file), we may not be able
|
||||
// to fit an arbitrary position in the file in the FilePos field. To handle
|
||||
// this, we create one FileID for each chunk of the file that fits in a
|
||||
// FilePos field.
|
||||
unsigned FileSize = File->Buffer->getBufferSize();
|
||||
if (FileSize+1 < (1 << SourceLocation::FilePosBits)) {
|
||||
FileIDs.push_back(FileIDInfo::get(IncludePos, 0, File));
|
||||
FileIDs.push_back(FileIDInfo::get(IncludePos, 0, File, isSysHeader));
|
||||
assert(FileIDs.size() < (1 << SourceLocation::FileIDBits) &&
|
||||
"Ran out of file ID's!");
|
||||
return FileIDs.size();
|
||||
|
@ -93,7 +94,8 @@ unsigned SourceManager::createFileID(const ContentCache *File,
|
|||
|
||||
unsigned ChunkNo = 0;
|
||||
while (1) {
|
||||
FileIDs.push_back(FileIDInfo::get(IncludePos, ChunkNo++, File));
|
||||
FileIDs.push_back(FileIDInfo::get(IncludePos, ChunkNo++, File,
|
||||
isSysHeader));
|
||||
|
||||
if (FileSize+1 < (1 << SourceLocation::FilePosBits)) break;
|
||||
FileSize -= (1 << SourceLocation::FilePosBits);
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#include "clang/Driver/TextDiagnosticPrinter.h"
|
||||
#include "clang/Basic/FileManager.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "clang/Lex/HeaderSearch.h"
|
||||
#include "clang/Lex/Lexer.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include <string>
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
//===--- TextDiagnostics.cpp - Text Diagnostics Parent Class --------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This is the parent class for all text diagnostics.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/Driver/TextDiagnostics.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "clang/Basic/SourceManager.h"
|
||||
#include "clang/Lex/HeaderSearch.h"
|
||||
using namespace clang;
|
||||
|
||||
TextDiagnostics:: ~TextDiagnostics() {}
|
||||
|
||||
std::string TextDiagnostics::FormatDiagnostic(Diagnostic &Diags,
|
||||
Diagnostic::Level Level,
|
||||
diag::kind ID,
|
||||
const std::string *Strs,
|
||||
unsigned NumStrs) {
|
||||
std::string Msg = Diags.getDescription(ID);
|
||||
|
||||
// Replace all instances of %0 in Msg with 'Extra'.
|
||||
for (unsigned i = 0; i < Msg.size() - 1; ++i) {
|
||||
if (Msg[i] == '%' && isdigit(Msg[i + 1])) {
|
||||
unsigned StrNo = Msg[i + 1] - '0';
|
||||
Msg = std::string(Msg.begin(), Msg.begin() + i) +
|
||||
(StrNo < NumStrs ? Strs[StrNo] : "<<<INTERNAL ERROR>>>") +
|
||||
std::string(Msg.begin() + i + 2, Msg.end());
|
||||
}
|
||||
}
|
||||
|
||||
return Msg;
|
||||
}
|
||||
|
||||
bool TextDiagnostics::isInSystemHeader(FullSourceLoc Pos) const {
|
||||
if (!Pos.isValid()) return false;
|
||||
|
||||
if (const FileEntry *F = Pos.getFileEntryForLoc()) {
|
||||
DirectoryLookup::DirType DirInfo = TheHeaderSearch->getFileDirFlavor(F);
|
||||
if (DirInfo == DirectoryLookup::SystemHeaderDir ||
|
||||
DirInfo == DirectoryLookup::ExternCSystemHeaderDir)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
|
@ -674,7 +674,8 @@ void Preprocessor::HandleIncludeDirective(Token &IncludeTok,
|
|||
}
|
||||
|
||||
// Look up the file, create a File ID for it.
|
||||
unsigned FileID = SourceMgr.createFileID(File, FilenameTok.getLocation());
|
||||
unsigned FileID = SourceMgr.createFileID(File, FilenameTok.getLocation(),
|
||||
isSystemHeader(File));
|
||||
if (FileID == 0)
|
||||
return Diag(FilenameTok, diag::err_pp_file_not_found,
|
||||
std::string(FilenameStart, FilenameEnd));
|
||||
|
|
|
@ -115,6 +115,17 @@ Preprocessor::~Preprocessor() {
|
|||
delete Callbacks;
|
||||
}
|
||||
|
||||
bool Preprocessor::isSystemHeader(const FileEntry* F) const {
|
||||
if (F) {
|
||||
DirectoryLookup::DirType DirInfo = HeaderInfo.getFileDirFlavor(F);
|
||||
if (DirInfo == DirectoryLookup::SystemHeaderDir ||
|
||||
DirInfo == DirectoryLookup::ExternCSystemHeaderDir)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// Diag - Forwarding function for diagnostics. This emits a diagnostic at
|
||||
/// the specified Token's location, translating the token's start
|
||||
/// position in the current buffer into a SourcePosition object for rendering.
|
||||
|
|
Loading…
Reference in New Issue