diff options
author | Kevin Enderby <enderby@apple.com> | 2011-10-12 21:38:39 +0000 |
---|---|---|
committer | Kevin Enderby <enderby@apple.com> | 2011-10-12 21:38:39 +0000 |
commit | acbaecd4c8e4d19207e63624dcd9e01947b51757 (patch) | |
tree | e993557087dba178c23b400fcce5dd8128e6d314 /lib/MC/MCParser/AsmParser.cpp | |
parent | 7007e4c5564f32fe4f06765a9740218039e7b492 (diff) |
Finish supporting cpp #file/line comments in assembler for error messages. So
for cpp pre-processed assembly we give correct filename and line numbers when
reporting errors in assembly files when using clang and -integrated-as on .s
files. rdar://8998895
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141814 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC/MCParser/AsmParser.cpp')
-rw-r--r-- | lib/MC/MCParser/AsmParser.cpp | 69 |
1 files changed, 64 insertions, 5 deletions
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index 9113dd7c31..311c3347a5 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -115,6 +115,11 @@ private: /// Flag tracking whether any errors have been encountered. unsigned HadError : 1; + /// The values from the last parsed cpp hash file line comment if any. + StringRef CppHashFilename; + int64_t CppHashLineNumber; + SMLoc CppHashLoc; + public: AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out, const MCAsmInfo &MAI); @@ -168,6 +173,7 @@ private: bool ShowLine = true) const { SrcMgr.PrintMessage(Loc, Msg, Type, ShowLine); } + static void DiagHandler(const SMDiagnostic &Diag, void *Context); /// EnterIncludeFile - Enter the specified file. This returns true on failure. bool EnterIncludeFile(const std::string &Filename); @@ -344,7 +350,8 @@ AsmParser::AsmParser(SourceMgr &_SM, MCContext &_Ctx, MCStreamer &_Out, const MCAsmInfo &_MAI) : Lexer(_MAI), Ctx(_Ctx), Out(_Out), MAI(_MAI), SrcMgr(_SM), GenericParser(new GenericAsmParser), PlatformParser(0), - CurBuffer(0), MacrosEnabled(true) { + CurBuffer(0), MacrosEnabled(true), CppHashLineNumber(0) { + SrcMgr.setDiagHandler(DiagHandler, this); Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer)); // Initialize the generic parser. @@ -1231,8 +1238,6 @@ bool AsmParser::ParseCppHashLineFilenameComment(const SMLoc &L) { } int64_t LineNumber = getTok().getIntVal(); - // FIXME: remember to remove this line that is silencing a warning for now. - (void) LineNumber; Lex(); if (getLexer().isNot(AsmToken::String)) { @@ -1244,14 +1249,68 @@ bool AsmParser::ParseCppHashLineFilenameComment(const SMLoc &L) { // Get rid of the enclosing quotes. Filename = Filename.substr(1, Filename.size()-2); - // TODO: Now with the Filename, LineNumber set up a mapping to the SMLoc for - // later use by diagnostics. + // Save the SMLoc, Filename and LineNumber for later use by diagnostics. + CppHashLoc = L; + CppHashFilename = Filename; + CppHashLineNumber = LineNumber; // Ignore any trailing characters, they're just comment. EatToEndOfLine(); return false; } +/// DiagHandler - will use the the last parsed cpp hash line filename comment +/// for the Filename and LineNo if any in the diagnostic. +void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) { + const AsmParser *Parser = static_cast<const AsmParser*>(Context); + raw_ostream &OS = errs(); + + const SourceMgr &DiagSrcMgr = *Diag.getSourceMgr(); + const SMLoc &DiagLoc = Diag.getLoc(); + int DiagBuf = DiagSrcMgr.FindBufferContainingLoc(DiagLoc); + int CppHashBuf = Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashLoc); + + // Like SourceMgr::PrintMessage() we need to print the include stack if any + // before printing the message. + int DiagCurBuffer = DiagSrcMgr.FindBufferContainingLoc(DiagLoc); + if (DiagCurBuffer > 0) { + SMLoc ParentIncludeLoc = DiagSrcMgr.getParentIncludeLoc(DiagCurBuffer); + DiagSrcMgr.PrintIncludeStack(ParentIncludeLoc, OS); + } + + // If we have not parsed a cpp hash line filename comment or the source + // manager changed or buffer changed (like in a nested include) then just + // print the normal diagnostic using its Filename and LineNo. + if (!Parser->CppHashLineNumber || + &DiagSrcMgr != &Parser->SrcMgr || + DiagBuf != CppHashBuf) { + Diag.Print(0, OS); + return; + } + + // Use the CppHashFilename and calculate a line number based on the + // CppHashLoc and CppHashLineNumber relative to this Diag's SMLoc for + // the diagnostic. + const std::string Filename = Parser->CppHashFilename; + + int DiagLocLineNo = DiagSrcMgr.FindLineNumber(DiagLoc, DiagBuf); + int CppHashLocLineNo = + Parser->SrcMgr.FindLineNumber(Parser->CppHashLoc, CppHashBuf); + int LineNo = Parser->CppHashLineNumber - 1 + + (DiagLocLineNo - CppHashLocLineNo); + + SMDiagnostic NewDiag(*Diag.getSourceMgr(), + Diag.getLoc(), + Filename, + LineNo, + Diag.getColumnNo(), + Diag.getMessage(), + Diag.getLineContents(), + Diag.getShowLine()); + + NewDiag.Print(0, OS); +} + bool AsmParser::expandMacro(SmallString<256> &Buf, StringRef Body, const std::vector<StringRef> &Parameters, const std::vector<std::vector<AsmToken> > &A, |