diff options
author | Tim Northover <tnorthover@apple.com> | 2016-04-13 19:46:54 +0000 |
---|---|---|
committer | Tim Northover <tnorthover@apple.com> | 2016-04-13 19:46:54 +0000 |
commit | c0bef99bb03cbcef5e0700bfdbed6e82970c8416 (patch) | |
tree | c20731cf874216d7034bf71e42c8606f11bd7ef2 | |
parent | cbd39897422bf686076e153b088670bab7aeb112 (diff) | |
download | bcm5719-llvm-c0bef99bb03cbcef5e0700bfdbed6e82970c8416.tar.gz bcm5719-llvm-c0bef99bb03cbcef5e0700bfdbed6e82970c8416.zip |
AsmParser: record "# line file" context to calculate location for diag
Since we can't emit diagnostics for missing "jmp 1f" labels until the end of
the file, we need to be able to restore the context used to calculate
file/line. This is basically the "# line file" directive that's being used at
the time the expression is seen.
rdar://25706972
llvm-svn: 266238
-rw-r--r-- | llvm/lib/MC/MCParser/AsmParser.cpp | 70 | ||||
-rw-r--r-- | llvm/test/MC/ELF/undefined-directional.s | 5 | ||||
-rw-r--r-- | llvm/test/MC/MachO/undefined-directional.s | 4 |
3 files changed, 47 insertions, 32 deletions
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index 700461576cb..e20e176ea44 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -146,9 +146,6 @@ private: /// \brief List of bodies of anonymous macros. std::deque<MCAsmMacro> MacroLikeBodies; - /// \brief List of forward directional labels for diagnosis at the end. - SmallVector<std::pair<SMLoc, MCSymbol *>, 4> DirectionalLabels; - /// Boolean tracking whether macro substitution is enabled. unsigned MacrosEnabledFlag : 1; @@ -159,10 +156,17 @@ private: unsigned HadError : 1; /// The values from the last parsed cpp hash file line comment if any. - StringRef CppHashFilename; - int64_t CppHashLineNumber; - SMLoc CppHashLoc; - unsigned CppHashBuf; + struct CppHashInfoTy { + StringRef Filename; + int64_t LineNumber; + SMLoc Loc; + unsigned Buf; + }; + CppHashInfoTy CppHashInfo; + + /// \brief List of forward directional labels for diagnosis at the end. + SmallVector<std::tuple<SMLoc, CppHashInfoTy, MCSymbol *>, 4> DirLabels; + /// When generating dwarf for assembly source files we need to calculate the /// logical line number based on the last parsed cpp hash file line comment /// and current line. Since this is slow and messes up the SourceMgr's @@ -522,7 +526,7 @@ AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out, const MCAsmInfo &MAI) : Lexer(MAI), Ctx(Ctx), Out(Out), MAI(MAI), SrcMgr(SM), PlatformParser(nullptr), CurBuffer(SM.getMainFileID()), - MacrosEnabledFlag(true), HadError(false), CppHashLineNumber(0), + MacrosEnabledFlag(true), HadError(false), CppHashInfo(), AssemblerDialect(~0U), IsDarwin(false), ParsingInlineAsm(false) { // Save the old handler. SavedDiagHandler = SrcMgr.getDiagHandler(); @@ -718,9 +722,13 @@ bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { // Temporary symbols like the ones for directional jumps don't go in the // symbol table. They also need to be diagnosed in all (final) cases. - for (std::pair<SMLoc, MCSymbol *> &LocSym : DirectionalLabels) { - if (LocSym.second->isUndefined()) - HadError |= Error(LocSym.first, "directional label undefined"); + for (std::tuple<SMLoc, CppHashInfoTy, MCSymbol *> &LocSym : DirLabels) { + if (std::get<2>(LocSym)->isUndefined()) { + // Reset the state of any "# line file" directives we've seen to the + // context as it was at the diagnostic site. + CppHashInfo = std::get<1>(LocSym); + HadError |= Error(std::get<0>(LocSym), "directional label undefined"); + } } } @@ -931,7 +939,7 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { Res = MCSymbolRefExpr::create(Sym, Variant, getContext()); if (IDVal == "b" && Sym->isUndefined()) return Error(Loc, "directional label undefined"); - DirectionalLabels.push_back(std::make_pair(Loc, Sym)); + DirLabels.push_back(std::make_tuple(Loc, CppHashInfo, Sym)); EndLoc = Lexer.getTok().getEndLoc(); Lex(); // Eat identifier. } @@ -1796,24 +1804,26 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info, // If we previously parsed a cpp hash file line comment then make sure the // current Dwarf File is for the CppHashFilename if not then emit the // Dwarf File table for it and adjust the line number for the .loc. - if (CppHashFilename.size()) { + if (CppHashInfo.Filename.size()) { unsigned FileNumber = getStreamer().EmitDwarfFileDirective( - 0, StringRef(), CppHashFilename); + 0, StringRef(), CppHashInfo.Filename); getContext().setGenDwarfFileNumber(FileNumber); // Since SrcMgr.FindLineNumber() is slow and messes up the SourceMgr's // cache with the different Loc from the call above we save the last // info we queried here with SrcMgr.FindLineNumber(). unsigned CppHashLocLineNo; - if (LastQueryIDLoc == CppHashLoc && LastQueryBuffer == CppHashBuf) + if (LastQueryIDLoc == CppHashInfo.Loc && + LastQueryBuffer == CppHashInfo.Buf) CppHashLocLineNo = LastQueryLine; else { - CppHashLocLineNo = SrcMgr.FindLineNumber(CppHashLoc, CppHashBuf); + CppHashLocLineNo = + SrcMgr.FindLineNumber(CppHashInfo.Loc, CppHashInfo.Buf); LastQueryLine = CppHashLocLineNo; - LastQueryIDLoc = CppHashLoc; - LastQueryBuffer = CppHashBuf; + LastQueryIDLoc = CppHashInfo.Loc; + LastQueryBuffer = CppHashInfo.Buf; } - Line = CppHashLineNumber - 1 + (Line - CppHashLocLineNo); + Line = CppHashInfo.LineNumber - 1 + (Line - CppHashLocLineNo); } getStreamer().EmitDwarfLocDirective( @@ -1888,10 +1898,10 @@ bool AsmParser::parseCppHashLineFilenameComment(SMLoc L) { Filename = Filename.substr(1, Filename.size() - 2); // Save the SMLoc, Filename and LineNumber for later use by diagnostics. - CppHashLoc = L; - CppHashFilename = Filename; - CppHashLineNumber = LineNumber; - CppHashBuf = CurBuffer; + CppHashInfo.Loc = L; + CppHashInfo.Filename = Filename; + CppHashInfo.LineNumber = LineNumber; + CppHashInfo.Buf = CurBuffer; // Ignore any trailing characters, they're just comment. eatToEndOfLine(); @@ -1908,7 +1918,7 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) { SMLoc DiagLoc = Diag.getLoc(); unsigned DiagBuf = DiagSrcMgr.FindBufferContainingLoc(DiagLoc); unsigned CppHashBuf = - Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashLoc); + Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashInfo.Loc); // Like SourceMgr::printMessage() we need to print the include stack if any // before printing the message. @@ -1922,7 +1932,7 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) { // 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 || + if (!Parser->CppHashInfo.LineNumber || &DiagSrcMgr != &Parser->SrcMgr || DiagBuf != CppHashBuf) { if (Parser->SavedDiagHandler) Parser->SavedDiagHandler(Diag, Parser->SavedDiagContext); @@ -1932,15 +1942,15 @@ void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) { } // 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; + // CppHashInfo.Loc and CppHashInfo.LineNumber relative to this Diag's SMLoc + // for the diagnostic. + const std::string &Filename = Parser->CppHashInfo.Filename; int DiagLocLineNo = DiagSrcMgr.FindLineNumber(DiagLoc, DiagBuf); int CppHashLocLineNo = - Parser->SrcMgr.FindLineNumber(Parser->CppHashLoc, CppHashBuf); + Parser->SrcMgr.FindLineNumber(Parser->CppHashInfo.Loc, CppHashBuf); int LineNo = - Parser->CppHashLineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo); + Parser->CppHashInfo.LineNumber - 1 + (DiagLocLineNo - CppHashLocLineNo); SMDiagnostic NewDiag(*Diag.getSourceMgr(), Diag.getLoc(), Filename, LineNo, Diag.getColumnNo(), Diag.getKind(), Diag.getMessage(), diff --git a/llvm/test/MC/ELF/undefined-directional.s b/llvm/test/MC/ELF/undefined-directional.s index 74449d4e4f6..e09acd73111 100644 --- a/llvm/test/MC/ELF/undefined-directional.s +++ b/llvm/test/MC/ELF/undefined-directional.s @@ -4,6 +4,9 @@ jmp 1b // CHECK: [[@LINE+1]]:{{[0-9]+}}: error: directional label undefined jmp 1f -// CHECK: [[@LINE+1]]:{{[0-9]+}}: error: directional label undefined +# 10 "wibble.s" +// CHECK: wibble.s:11:{{[0-9]+}}: error: directional label undefined jmp 2f +# 42 "invalid.s" + diff --git a/llvm/test/MC/MachO/undefined-directional.s b/llvm/test/MC/MachO/undefined-directional.s index 8d75228f835..80af9caf68c 100644 --- a/llvm/test/MC/MachO/undefined-directional.s +++ b/llvm/test/MC/MachO/undefined-directional.s @@ -4,6 +4,8 @@ jmp 1b // CHECK: [[@LINE+1]]:{{[0-9]+}}: error: directional label undefined jmp 1f -// CHECK: [[@LINE+1]]:{{[0-9]+}}: error: directional label undefined +# 10 "wibble.s" +// CHECK: wibble.s:11:{{[0-9]+}}: error: directional label undefined jmp 2f +# 42 "invalid.s" |