summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/MC/MCParser/AsmParser.cpp70
-rw-r--r--llvm/test/MC/ELF/undefined-directional.s5
-rw-r--r--llvm/test/MC/MachO/undefined-directional.s4
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"
OpenPOWER on IntegriCloud