llvm.org GIT mirror llvm / 3f2d5f6
Make SMDiagnostic a little more sane. Instead of passing around note/warning/error as a string, pass it around as an enum. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@142107 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 8 years ago
11 changed file(s) with 107 addition(s) and 88 deletion(s). Raw diff Collapse all Expand all
3939 std::string ErrMsg;
4040 Module *M = getLazyBitcodeModule(Buffer, Context, &ErrMsg);
4141 if (M == 0) {
42 Err = SMDiagnostic(Buffer->getBufferIdentifier(), ErrMsg);
42 Err = SMDiagnostic(Buffer->getBufferIdentifier(), SourceMgr::DK_Error,
43 ErrMsg);
4344 // ParseBitcodeFile does not take ownership of the Buffer in the
4445 // case of an error.
4546 delete Buffer;
5960 LLVMContext &Context) {
6061 OwningPtr File;
6162 if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), File)) {
62 Err = SMDiagnostic(Filename,
63 Err = SMDiagnostic(Filename, SourceMgr::DK_Error,
6364 "Could not open input file: " + ec.message());
6465 return 0;
6566 }
7980 std::string ErrMsg;
8081 Module *M = ParseBitcodeFile(Buffer, Context, &ErrMsg);
8182 if (M == 0)
82 Err = SMDiagnostic(Buffer->getBufferIdentifier(), ErrMsg);
83 Err = SMDiagnostic(Buffer->getBufferIdentifier(), SourceMgr::DK_Error,
84 ErrMsg);
8385 // ParseBitcodeFile does not take ownership of the Buffer.
8486 delete Buffer;
8587 return M;
9698 LLVMContext &Context) {
9799 OwningPtr File;
98100 if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), File)) {
99 Err = SMDiagnostic(Filename,
101 Err = SMDiagnostic(Filename, SourceMgr::DK_Error,
100102 "Could not open input file: " + ec.message());
101103 return 0;
102104 }
3030 /// and handles diagnostic wrangling.
3131 class SourceMgr {
3232 public:
33 enum DiagKind {
34 DK_Error,
35 DK_Warning,
36 DK_Note
37 };
38
3339 /// DiagHandlerTy - Clients that want to handle their own diagnostics in a
3440 /// custom way can register a function pointer+context as a diagnostic
3541 /// handler. It gets called each time PrintMessage is invoked.
36 typedef void (*DiagHandlerTy)(const SMDiagnostic&, void *Context);
42 typedef void (*DiagHandlerTy)(const SMDiagnostic &, void *Context);
3743 private:
3844 struct SrcBuffer {
3945 /// Buffer - The memory buffer for the file.
118124 /// PrintMessage - Emit a message about the specified location with the
119125 /// specified string.
120126 ///
121 /// @param Type - If non-null, the kind of message (e.g., "error") which is
122 /// prefixed to the message.
123 /// @param ShowLine - Should the diagnostic show the source line.
124 void PrintMessage(SMLoc Loc, const Twine &Msg, const char *Type,
127 void PrintMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg,
125128 ArrayRef Ranges = ArrayRef(),
126129 bool ShowLine = true) const;
127130
132135 /// @param Type - If non-null, the kind of message (e.g., "error") which is
133136 /// prefixed to the message.
134137 /// @param ShowLine - Should the diagnostic show the source line.
135 SMDiagnostic GetMessage(SMLoc Loc,
136 const Twine &Msg, const char *Type,
138 SMDiagnostic GetMessage(SMLoc Loc, DiagKind Kind, const Twine &Msg,
137139 ArrayRef Ranges = ArrayRef(),
138140 bool ShowLine = true) const;
139141
154156 SMLoc Loc;
155157 std::string Filename;
156158 int LineNo, ColumnNo;
159 SourceMgr::DiagKind Kind;
157160 std::string Message, LineContents;
158161 unsigned ShowLine : 1;
159162 std::vector > Ranges;
160163
161164 public:
162165 // Null diagnostic.
163 SMDiagnostic() : SM(0), LineNo(0), ColumnNo(0), ShowLine(0) {}
166 SMDiagnostic()
167 : SM(0), LineNo(0), ColumnNo(0), Kind(SourceMgr::DK_Error), ShowLine(0) {}
164168 // Diagnostic with no location (e.g. file not found, command line arg error).
165 SMDiagnostic(const std::string &filename, const std::string &Msg)
166 : SM(0), Filename(filename), LineNo(-1), ColumnNo(-1),
169 SMDiagnostic(const std::string &filename, SourceMgr::DiagKind Kind,
170 const std::string &Msg)
171 : SM(0), Filename(filename), LineNo(-1), ColumnNo(-1), Kind(Kind),
167172 Message(Msg), ShowLine(false) {}
168173
169174 // Diagnostic with a location.
170175 SMDiagnostic(const SourceMgr &sm, SMLoc L, const std::string &FN,
171 int Line, int Col,
176 int Line, int Col, SourceMgr::DiagKind Kind,
172177 const std::string &Msg, const std::string &LineStr,
173178 ArrayRef > Ranges, bool showline);
174179
177182 const std::string &getFilename() const { return Filename; }
178183 int getLineNo() const { return LineNo; }
179184 int getColumnNo() const { return ColumnNo; }
185 SourceMgr::DiagKind getKind() const { return Kind; }
180186 const std::string &getMessage() const { return Message; }
181187 const std::string &getLineContents() const { return LineContents; }
182188 bool getShowLine() const { return ShowLine; }
2828 using namespace llvm;
2929
3030 bool LLLexer::Error(LocTy ErrorLoc, const Twine &Msg) const {
31 ErrorInfo = SM.GetMessage(ErrorLoc, Msg, "error");
31 ErrorInfo = SM.GetMessage(ErrorLoc, SourceMgr::DK_Error, Msg);
3232 return true;
3333 }
3434
4343 LLVMContext &Context) {
4444 OwningPtr File;
4545 if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), File)) {
46 Err = SMDiagnostic(Filename,
46 Err = SMDiagnostic(Filename, SourceMgr::DK_Error,
4747 "Could not open input file: " + ec.message());
4848 return 0;
4949 }
170170 void HandleMacroExit();
171171
172172 void PrintMacroInstantiations();
173 void PrintMessage(SMLoc Loc, const Twine &Msg, const char *Type,
173 void PrintMessage(SMLoc Loc, SourceMgr::DiagKind Kind, const Twine &Msg,
174174 ArrayRef Ranges = ArrayRef(),
175175 bool ShowLine = true) const {
176 SrcMgr.PrintMessage(Loc, Msg, Type, Ranges, ShowLine);
176 SrcMgr.PrintMessage(Loc, Kind, Msg, Ranges, ShowLine);
177177 }
178178 static void DiagHandler(const SMDiagnostic &Diag, void *Context);
179179
391391 // Print the active macro instantiation stack.
392392 for (std::vector::const_reverse_iterator
393393 it = ActiveMacros.rbegin(), ie = ActiveMacros.rend(); it != ie; ++it)
394 PrintMessage((*it)->InstantiationLoc, "while in macro instantiation",
395 "note");
394 PrintMessage((*it)->InstantiationLoc, SourceMgr::DK_Note,
395 "while in macro instantiation");
396396 }
397397
398398 bool AsmParser::Warning(SMLoc L, const Twine &Msg, ArrayRef Ranges) {
399399 if (FatalAssemblerWarnings)
400400 return Error(L, Msg, Ranges);
401 PrintMessage(L, Msg, "warning", Ranges);
401 PrintMessage(L, SourceMgr::DK_Warning, Msg, Ranges);
402402 PrintMacroInstantiations();
403403 return false;
404404 }
405405
406406 bool AsmParser::Error(SMLoc L, const Twine &Msg, ArrayRef Ranges) {
407407 HadError = true;
408 PrintMessage(L, Msg, "error", Ranges);
408 PrintMessage(L, SourceMgr::DK_Error, Msg, Ranges);
409409 PrintMacroInstantiations();
410410 return true;
411411 }
497497 // FIXME: We would really like to refer back to where the symbol was
498498 // first referenced for a source location. We need to add something
499499 // to track that. Currently, we just point to the end of the file.
500 PrintMessage(getLexer().getLoc(), "assembler local symbol '" +
501 Sym->getName() + "' not defined", "error",
502 ArrayRef(), false);
500 PrintMessage(getLexer().getLoc(), SourceMgr::DK_Error,
501 "assembler local symbol '" + Sym->getName() +
502 "' not defined");
503503 }
504504 }
505505
12021202 }
12031203 OS << "]";
12041204
1205 PrintMessage(IDLoc, OS.str(), "note");
1205 PrintMessage(IDLoc, SourceMgr::DK_Note, OS.str());
12061206 }
12071207
12081208 // If parsing succeeded, match the instruction.
13041304
13051305 SMDiagnostic NewDiag(*Diag.getSourceMgr(), Diag.getLoc(),
13061306 Filename, LineNo, Diag.getColumnNo(),
1307 Diag.getMessage(), Diag.getLineContents(),
1307 Diag.getKind(), Diag.getMessage(),
1308 Diag.getLineContents(),
13081309 Diag.getRanges(), Diag.getShowLine());
13091310
13101311 NewDiag.print(0, OS);
139139 ///
140140 /// @param Type - If non-null, the kind of message (e.g., "error") which is
141141 /// prefixed to the message.
142 SMDiagnostic SourceMgr::GetMessage(SMLoc Loc, const Twine &Msg,
143 const char *Type, ArrayRef Ranges,
142 SMDiagnostic SourceMgr::GetMessage(SMLoc Loc, SourceMgr::DiagKind Kind,
143 const Twine &Msg, ArrayRef Ranges,
144144 bool ShowLine) const {
145145
146146 // First thing to do: find the current buffer containing the specified
162162 LineEnd[0] != '\n' && LineEnd[0] != '\r')
163163 ++LineEnd;
164164 std::string LineStr(LineStart, LineEnd);
165
166 std::string PrintedMsg;
167 raw_string_ostream OS(PrintedMsg);
168 if (Type)
169 OS << Type << ": ";
170 OS << Msg;
171165
172166 // Convert any ranges to column ranges that only intersect the line of the
173167 // location.
193187
194188 return SMDiagnostic(*this, Loc,
195189 CurMB->getBufferIdentifier(), FindLineNumber(Loc, CurBuf),
196 Loc.getPointer()-LineStart, OS.str(),
190 Loc.getPointer()-LineStart, Kind, Msg.str(),
197191 LineStr, ColRanges, ShowLine);
198192 }
199193
200 void SourceMgr::PrintMessage(SMLoc Loc, const Twine &Msg,
201 const char *Type, ArrayRef Ranges,
194 void SourceMgr::PrintMessage(SMLoc Loc, SourceMgr::DiagKind Kind,
195 const Twine &Msg, ArrayRef Ranges,
202196 bool ShowLine) const {
197 SMDiagnostic Diagnostic = GetMessage(Loc, Kind, Msg, Ranges, ShowLine);
198
203199 // Report the message with the diagnostic handler if present.
204200 if (DiagHandler) {
205 DiagHandler(GetMessage(Loc, Msg, Type, Ranges, ShowLine), DiagContext);
201 DiagHandler(Diagnostic, DiagContext);
206202 return;
207203 }
208204
212208 assert(CurBuf != -1 && "Invalid or unspecified location!");
213209 PrintIncludeStack(getBufferInfo(CurBuf).IncludeLoc, OS);
214210
215 GetMessage(Loc, Msg, Type, Ranges, ShowLine).print(0, OS);
211 Diagnostic.print(0, OS);
216212 }
217213
218214 //===----------------------------------------------------------------------===//
220216 //===----------------------------------------------------------------------===//
221217
222218 SMDiagnostic::SMDiagnostic(const SourceMgr &sm, SMLoc L, const std::string &FN,
223 int Line, int Col, const std::string &Msg,
219 int Line, int Col, SourceMgr::DiagKind Kind,
220 const std::string &Msg,
224221 const std::string &LineStr,
225222 ArrayRef > Ranges,
226223 bool showline)
227 : SM(&sm), Loc(L), Filename(FN), LineNo(Line), ColumnNo(Col), Message(Msg),
228 LineContents(LineStr), ShowLine(showline), Ranges(Ranges.vec()) {}
224 : SM(&sm), Loc(L), Filename(FN), LineNo(Line), ColumnNo(Col), Kind(Kind),
225 Message(Msg), LineContents(LineStr), ShowLine(showline),
226 Ranges(Ranges.vec()) {
227 }
229228
230229
231230 void SMDiagnostic::print(const char *ProgName, raw_ostream &S) const {
246245 S << ": ";
247246 }
248247
248 switch (Kind) {
249 default: assert(0 && "Unknown diagnostic kind");
250 case SourceMgr::DK_Error: S << "error: "; break;
251 case SourceMgr::DK_Warning: S << "warning: "; break;
252 case SourceMgr::DK_Note: S << "note: "; break;
253 }
254
249255 S << Message << '\n';
250256
251257 if (LineNo == -1 || ColumnNo == -1 || !ShowLine)
2020 SourceMgr SrcMgr;
2121
2222 void PrintError(SMLoc ErrorLoc, const Twine &Msg) {
23 SrcMgr.PrintMessage(ErrorLoc, Msg, "error");
23 SrcMgr.PrintMessage(ErrorLoc, SourceMgr::DK_Error, Msg);
2424 }
2525
2626 void PrintError(const char *Loc, const Twine &Msg) {
27 SrcMgr.PrintMessage(SMLoc::getFromPointer(Loc), Msg, "error");
27 SrcMgr.PrintMessage(SMLoc::getFromPointer(Loc), SourceMgr::DK_Error, Msg);
2828 }
2929
3030 void PrintError(const Twine &Msg) {
9999 }
100100
101101 // If we do have an error handler, we can report the error and keep going.
102 SMDiagnostic Diag("", "error: " + ErrorStr.str());
102 SMDiagnostic Diag("", SourceMgr::DK_Error, ErrorStr.str());
103103
104104 pImpl->InlineAsmDiagHandler(Diag, pImpl->InlineAsmDiagContext, LocCookie);
105105 }
7171 switch (S) {
7272 case MCDisassembler::Fail:
7373 SM.PrintMessage(SMLoc::getFromPointer(Bytes[Index].second),
74 "invalid instruction encoding", "warning");
74 SourceMgr::DK_Warning,
75 "invalid instruction encoding");
7576 if (Size == 0)
7677 Size = 1; // skip illegible bytes
7778 break;
7879
7980 case MCDisassembler::SoftFail:
8081 SM.PrintMessage(SMLoc::getFromPointer(Bytes[Index].second),
81 "potentially undefined instruction encoding", "warning");
82 SourceMgr::DK_Warning,
83 "potentially undefined instruction encoding");
8284 // Fall through
8385
8486 case MCDisassembler::Success:
124126 unsigned ByteVal;
125127 if (Value.getAsInteger(0, ByteVal) || ByteVal > 255) {
126128 // If we have an error, print it and skip to the end of line.
127 SM.PrintMessage(SMLoc::getFromPointer(Value.data()),
128 "invalid input token", "error");
129 SM.PrintMessage(SMLoc::getFromPointer(Value.data()), SourceMgr::DK_Error,
130 "invalid input token");
129131 Str = Str.substr(Str.find('\n'));
130132 ByteArray.clear();
131133 continue;
266266
267267 switch (Tok.getKind()) {
268268 default:
269 SrcMgr.PrintMessage(Lexer.getLoc(), "unknown token", "warning");
269 SrcMgr.PrintMessage(Lexer.getLoc(), SourceMgr::DK_Warning,
270 "unknown token");
270271 Error = true;
271272 break;
272273 case AsmToken::Error:
116116
117117 // Check that there is something on the line.
118118 if (PatternStr.empty()) {
119 SM.PrintMessage(PatternLoc, "found empty check string with prefix '" +
120 CheckPrefix+":'", "error");
119 SM.PrintMessage(PatternLoc, SourceMgr::DK_Error,
120 "found empty check string with prefix '" +
121 CheckPrefix+":'");
121122 return true;
122123 }
123124
143144 size_t End = PatternStr.find("}}");
144145 if (End == StringRef::npos) {
145146 SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
146 "found start of regex string with no end '}}'","error");
147 SourceMgr::DK_Error,
148 "found start of regex string with no end '}}'");
147149 return true;
148150 }
149151
172174 size_t End = PatternStr.find("]]");
173175 if (End == StringRef::npos) {
174176 SM.PrintMessage(SMLoc::getFromPointer(PatternStr.data()),
175 "invalid named regex reference, no ]] found", "error");
177 SourceMgr::DK_Error,
178 "invalid named regex reference, no ]] found");
176179 return true;
177180 }
178181
184187 StringRef Name = MatchStr.substr(0, NameEnd);
185188
186189 if (Name.empty()) {
187 SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
188 "invalid name in named regex: empty name", "error");
190 SM.PrintMessage(SMLoc::getFromPointer(Name.data()), SourceMgr::DK_Error,
191 "invalid name in named regex: empty name");
189192 return true;
190193 }
191194
193196 for (unsigned i = 0, e = Name.size(); i != e; ++i)
194197 if (Name[i] != '_' && !isalnum(Name[i])) {
195198 SM.PrintMessage(SMLoc::getFromPointer(Name.data()+i),
196 "invalid name in named regex", "error");
199 SourceMgr::DK_Error, "invalid name in named regex");
197200 return true;
198201 }
199202
200203 // Name can't start with a digit.
201204 if (isdigit(Name[0])) {
202 SM.PrintMessage(SMLoc::getFromPointer(Name.data()),
203 "invalid name in named regex", "error");
205 SM.PrintMessage(SMLoc::getFromPointer(Name.data()), SourceMgr::DK_Error,
206 "invalid name in named regex");
204207 return true;
205208 }
206209
265268 Regex R(RegexStr);
266269 std::string Error;
267270 if (!R.isValid(Error)) {
268 SM.PrintMessage(SMLoc::getFromPointer(RegexStr.data()),
269 "invalid regex: " + Error, "error");
271 SM.PrintMessage(SMLoc::getFromPointer(RegexStr.data()), SourceMgr::DK_Error,
272 "invalid regex: " + Error);
270273 return true;
271274 }
272275
382385 OS.write_escaped(it->second) << "\"";
383386 }
384387
385 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), OS.str(), "note",
386 ArrayRef(), /*ShowLine=*/false);
388 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
389 OS.str());
387390 }
388391 }
389392
421424 // line.
422425 if (Best && Best != StringRef::npos && BestQuality < 50) {
423426 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + Best),
424 "possible intended match here", "note");
427 SourceMgr::DK_Note, "possible intended match here");
425428
426429 // FIXME: If we wanted to be really friendly we would show why the match
427430 // failed, as it can be hard to spot simple one character differences.
565568 // Verify that CHECK-NEXT lines have at least one CHECK line before them.
566569 if (IsCheckNext && CheckStrings.empty()) {
567570 SM.PrintMessage(SMLoc::getFromPointer(CheckPrefixStart),
571 SourceMgr::DK_Error,
568572 "found '"+CheckPrefix+"-NEXT:' without previous '"+
569 CheckPrefix+ ": line", "error");
573 CheckPrefix+ ": line");
570574 return true;
571575 }
572576
606610 StringRef Buffer,
607611 StringMap &VariableTable) {
608612 // Otherwise, we have an error, emit an error message.
609 SM.PrintMessage(CheckStr.Loc, "expected string not found in input",
610 "error");
613 SM.PrintMessage(CheckStr.Loc, SourceMgr::DK_Error,
614 "expected string not found in input");
611615
612616 // Print the "scanning from here" line. If the current position is at the
613617 // end of a line, advance to the start of the next line.
614618 Buffer = Buffer.substr(Buffer.find_first_not_of(" \t\n\r"));
615619
616 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), "scanning from here",
617 "note");
620 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note,
621 "scanning from here");
618622
619623 // Allow the pattern to print additional information if desired.
620624 CheckStr.Pat.PrintFailureInfo(SM, Buffer, VariableTable);
709713
710714 unsigned NumNewLines = CountNumNewlinesBetween(SkippedRegion);
711715 if (NumNewLines == 0) {
712 SM.PrintMessage(CheckStr.Loc,
713 CheckPrefix+"-NEXT: is on the same line as previous match",
714 "error");
716 SM.PrintMessage(CheckStr.Loc, SourceMgr::DK_Error,
717 CheckPrefix+"-NEXT: is on the same line as previous match");
715718 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()),
716 "'next' match was here", "note");
717 SM.PrintMessage(SMLoc::getFromPointer(LastMatch),
718 "previous match was here", "note");
719 SourceMgr::DK_Note, "'next' match was here");
720 SM.PrintMessage(SMLoc::getFromPointer(LastMatch), SourceMgr::DK_Note,
721 "previous match was here");
719722 return 1;
720723 }
721724
722725 if (NumNewLines != 1) {
723 SM.PrintMessage(CheckStr.Loc,
724 CheckPrefix+
725 "-NEXT: is not on the line after the previous match",
726 "error");
726 SM.PrintMessage(CheckStr.Loc, SourceMgr::DK_Error, CheckPrefix+
727 "-NEXT: is not on the line after the previous match");
727728 SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()),
728 "'next' match was here", "note");
729 SM.PrintMessage(SMLoc::getFromPointer(LastMatch),
730 "previous match was here", "note");
729 SourceMgr::DK_Note, "'next' match was here");
730 SM.PrintMessage(SMLoc::getFromPointer(LastMatch), SourceMgr::DK_Note,
731 "previous match was here");
731732 return 1;
732733 }
733734 }
742743 VariableTable);
743744 if (Pos == StringRef::npos) continue;
744745
745 SM.PrintMessage(SMLoc::getFromPointer(LastMatch+Pos),
746 CheckPrefix+"-NOT: string occurred!", "error");
747 SM.PrintMessage(CheckStr.NotStrings[ChunkNo].first,
748 CheckPrefix+"-NOT: pattern specified here", "note");
746 SM.PrintMessage(SMLoc::getFromPointer(LastMatch+Pos), SourceMgr::DK_Error,
747 CheckPrefix+"-NOT: string occurred!");
748 SM.PrintMessage(CheckStr.NotStrings[ChunkNo].first, SourceMgr::DK_Note,
749 CheckPrefix+"-NOT: pattern specified here");
749750 return 1;
750751 }
751752