llvm.org GIT mirror llvm / acbaecd
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 Kevin Enderby 9 years ago
3 changed file(s) with 75 addition(s) and 7 deletion(s). Raw diff Collapse all Expand all
137137 const Twine &Msg, const char *Type,
138138 bool ShowLine = true) const;
139139
140
141 private:
140 /// PrintIncludeStack - Prints the names of included files and the line of the
141 /// file they were included from. A diagnostic handler can use this before
142 /// printing its custom formatted message.
143 ///
144 /// @param IncludeLoc - The line of the include.
145 /// @param OS the raw_ostream to print on.
142146 void PrintIncludeStack(SMLoc IncludeLoc, raw_ostream &OS) const;
143147 };
144148
114114 /// Flag tracking whether any errors have been encountered.
115115 unsigned HadError : 1;
116116
117 /// The values from the last parsed cpp hash file line comment if any.
118 StringRef CppHashFilename;
119 int64_t CppHashLineNumber;
120 SMLoc CppHashLoc;
121
117122 public:
118123 AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out,
119124 const MCAsmInfo &MAI);
167172 bool ShowLine = true) const {
168173 SrcMgr.PrintMessage(Loc, Msg, Type, ShowLine);
169174 }
175 static void DiagHandler(const SMDiagnostic &Diag, void *Context);
170176
171177 /// EnterIncludeFile - Enter the specified file. This returns true on failure.
172178 bool EnterIncludeFile(const std::string &Filename);
343349 MCStreamer &_Out, const MCAsmInfo &_MAI)
344350 : Lexer(_MAI), Ctx(_Ctx), Out(_Out), MAI(_MAI), SrcMgr(_SM),
345351 GenericParser(new GenericAsmParser), PlatformParser(0),
346 CurBuffer(0), MacrosEnabled(true) {
352 CurBuffer(0), MacrosEnabled(true), CppHashLineNumber(0) {
353 SrcMgr.setDiagHandler(DiagHandler, this);
347354 Lexer.setBuffer(SrcMgr.getMemoryBuffer(CurBuffer));
348355
349356 // Initialize the generic parser.
12301237 }
12311238
12321239 int64_t LineNumber = getTok().getIntVal();
1233 // FIXME: remember to remove this line that is silencing a warning for now.
1234 (void) LineNumber;
12351240 Lex();
12361241
12371242 if (getLexer().isNot(AsmToken::String)) {
12431248 // Get rid of the enclosing quotes.
12441249 Filename = Filename.substr(1, Filename.size()-2);
12451250
1246 // TODO: Now with the Filename, LineNumber set up a mapping to the SMLoc for
1247 // later use by diagnostics.
1251 // Save the SMLoc, Filename and LineNumber for later use by diagnostics.
1252 CppHashLoc = L;
1253 CppHashFilename = Filename;
1254 CppHashLineNumber = LineNumber;
12481255
12491256 // Ignore any trailing characters, they're just comment.
12501257 EatToEndOfLine();
12511258 return false;
1259 }
1260
1261 /// DiagHandler - will use the the last parsed cpp hash line filename comment
1262 /// for the Filename and LineNo if any in the diagnostic.
1263 void AsmParser::DiagHandler(const SMDiagnostic &Diag, void *Context) {
1264 const AsmParser *Parser = static_cast(Context);
1265 raw_ostream &OS = errs();
1266
1267 const SourceMgr &DiagSrcMgr = *Diag.getSourceMgr();
1268 const SMLoc &DiagLoc = Diag.getLoc();
1269 int DiagBuf = DiagSrcMgr.FindBufferContainingLoc(DiagLoc);
1270 int CppHashBuf = Parser->SrcMgr.FindBufferContainingLoc(Parser->CppHashLoc);
1271
1272 // Like SourceMgr::PrintMessage() we need to print the include stack if any
1273 // before printing the message.
1274 int DiagCurBuffer = DiagSrcMgr.FindBufferContainingLoc(DiagLoc);
1275 if (DiagCurBuffer > 0) {
1276 SMLoc ParentIncludeLoc = DiagSrcMgr.getParentIncludeLoc(DiagCurBuffer);
1277 DiagSrcMgr.PrintIncludeStack(ParentIncludeLoc, OS);
1278 }
1279
1280 // If we have not parsed a cpp hash line filename comment or the source
1281 // manager changed or buffer changed (like in a nested include) then just
1282 // print the normal diagnostic using its Filename and LineNo.
1283 if (!Parser->CppHashLineNumber ||
1284 &DiagSrcMgr != &Parser->SrcMgr ||
1285 DiagBuf != CppHashBuf) {
1286 Diag.Print(0, OS);
1287 return;
1288 }
1289
1290 // Use the CppHashFilename and calculate a line number based on the
1291 // CppHashLoc and CppHashLineNumber relative to this Diag's SMLoc for
1292 // the diagnostic.
1293 const std::string Filename = Parser->CppHashFilename;
1294
1295 int DiagLocLineNo = DiagSrcMgr.FindLineNumber(DiagLoc, DiagBuf);
1296 int CppHashLocLineNo =
1297 Parser->SrcMgr.FindLineNumber(Parser->CppHashLoc, CppHashBuf);
1298 int LineNo = Parser->CppHashLineNumber - 1 +
1299 (DiagLocLineNo - CppHashLocLineNo);
1300
1301 SMDiagnostic NewDiag(*Diag.getSourceMgr(),
1302 Diag.getLoc(),
1303 Filename,
1304 LineNo,
1305 Diag.getColumnNo(),
1306 Diag.getMessage(),
1307 Diag.getLineContents(),
1308 Diag.getShowLine());
1309
1310 NewDiag.Print(0, OS);
12521311 }
12531312
12541313 bool AsmParser::expandMacro(SmallString<256> &Buf, StringRef Body,
99
1010 // 32: error: register %rax is only available in 64-bit mode
1111 addl $0, 0(%rax)
12
13 // 32: test.s:8:2: error: invalid instruction mnemonic 'movi'
14
15 # 8 "test.s"
16 movi $8,%eax