diff options
Diffstat (limited to 'contrib/llvm-project/clang/lib/Lex/PPLexerChange.cpp')
-rw-r--r-- | contrib/llvm-project/clang/lib/Lex/PPLexerChange.cpp | 45 |
1 files changed, 43 insertions, 2 deletions
diff --git a/contrib/llvm-project/clang/lib/Lex/PPLexerChange.cpp b/contrib/llvm-project/clang/lib/Lex/PPLexerChange.cpp index b979b965f46a..16170969a322 100644 --- a/contrib/llvm-project/clang/lib/Lex/PPLexerChange.cpp +++ b/contrib/llvm-project/clang/lib/Lex/PPLexerChange.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "clang/Basic/FileManager.h" +#include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/LexDiagnostic.h" @@ -22,6 +23,7 @@ #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBufferRef.h" #include "llvm/Support/Path.h" + using namespace clang; //===----------------------------------------------------------------------===// @@ -299,10 +301,46 @@ void Preprocessor::diagnoseMissingHeaderInUmbrellaDir(const Module &Mod) { } } +void Preprocessor::ResolvePragmaIncludeInstead( + const SourceLocation Location) const { + assert(Location.isValid()); + if (CurLexer == nullptr) + return; + + if (SourceMgr.isInSystemHeader(Location)) + return; + + for (const auto &Include : CurLexer->getIncludeHistory()) { + StringRef Filename = Include.getKey(); + const PreprocessorLexer::IncludeInfo &Info = Include.getValue(); + ArrayRef<SmallString<32>> Aliases = + HeaderInfo.getFileInfo(Info.File).Aliases.getArrayRef(); + + if (Aliases.empty()) + continue; + + switch (Aliases.size()) { + case 1: + Diag(Info.Location, diag::err_pragma_include_instead_system_reserved) + << Filename << 0 << Aliases[0]; + continue; + case 2: + Diag(Info.Location, diag::err_pragma_include_instead_system_reserved) + << Filename << 1 << Aliases[0] << Aliases[1]; + continue; + default: { + Diag(Info.Location, diag::err_pragma_include_instead_system_reserved) + << Filename << 2 << ("{'" + llvm::join(Aliases, "', '") + "'}"); + } + } + } +} + /// HandleEndOfFile - This callback is invoked when the lexer hits the end of /// the current file. This either returns the EOF token or pops a level off /// the include stack and keeps going. -bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) { +bool Preprocessor::HandleEndOfFile(Token &Result, SourceLocation EndLoc, + bool isEndOfMacro) { assert(!CurTokenLexer && "Ending a file when currently in a macro!"); @@ -372,6 +410,9 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) { } } + if (EndLoc.isValid()) + ResolvePragmaIncludeInstead(EndLoc); + // Complain about reaching a true EOF within arc_cf_code_audited. // We don't want to complain about reaching the end of a macro // instantiation or a _Pragma. @@ -560,7 +601,7 @@ bool Preprocessor::HandleEndOfTokenLexer(Token &Result) { TokenLexerCache[NumCachedTokenLexers++] = std::move(CurTokenLexer); // Handle this like a #include file being popped off the stack. - return HandleEndOfFile(Result, true); + return HandleEndOfFile(Result, {}, true); } /// RemoveTopOfLexerStack - Pop the current lexer/macro exp off the top of the |