From: Chris Lattner Date: Wed, 17 Nov 2010 08:25:26 +0000 (+0000) Subject: When forming the !srcloc mdnode for an inline asm, add the SourceLocations X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5d93653247eeedaff5f0712178953b63d71a0b3b;p=clang When forming the !srcloc mdnode for an inline asm, add the SourceLocations of all the lines of the inline asm. With the refactoring and enhancement of the backend, we can now reports errors on the correct source line when an asm contains multiple lines of text. For something like this: void foo() { asm("push %rax\n" ".code32\n"); } we used to get this: (note that the line 4 in t.c isn't helpful) t.c:4:7: error: warning: ignoring directive for now asm("push %rax\n" ^ :2:1: note: instantiated into assembly here .code32 ^ now we get: t.c:5:8: error: warning: ignoring directive for now ".code32\n" ^ :2:1: note: instantiated into assembly here .code32 ^ Note that we're pointing to line 5 properly now. This implements rdar://7839391 - inline asm errors should point to the right line in the asm and makes the error message in PR8595 much less confusing. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@119489 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp index d8a16fc7d7..c510213313 100644 --- a/lib/CodeGen/CGStmt.cpp +++ b/lib/CodeGen/CGStmt.cpp @@ -949,12 +949,32 @@ llvm::Value* CodeGenFunction::EmitAsmInput(const AsmStmt &S, } /// getAsmSrcLocInfo - Return the !srcloc metadata node to attach to an inline -/// asm call instruction. +/// asm call instruction. The !srcloc MDNode contains a list of constant +/// integers which are the source locations of the start of each line in the +/// asm. static llvm::MDNode *getAsmSrcLocInfo(const StringLiteral *Str, CodeGenFunction &CGF) { - unsigned LocID = Str->getLocStart().getRawEncoding(); - llvm::Value *LocIDC = llvm::ConstantInt::get(CGF.Int32Ty, LocID); - return llvm::MDNode::get(LocIDC->getContext(), &LocIDC, 1); + llvm::SmallVector Locs; + // Add the location of the first line to the MDNode. + Locs.push_back(llvm::ConstantInt::get(CGF.Int32Ty, + Str->getLocStart().getRawEncoding())); + llvm::StringRef StrVal = Str->getString(); + if (!StrVal.empty()) { + const SourceManager &SM = CGF.CGM.getContext().getSourceManager(); + const LangOptions &LangOpts = CGF.CGM.getLangOptions(); + + // Add the location of the start of each subsequent line of the asm to the + // MDNode. + for (unsigned i = 0, e = StrVal.size()-1; i != e; ++i) { + if (StrVal[i] != '\n') continue; + SourceLocation LineLoc = Str->getLocationOfByte(i+1, SM, LangOpts, + CGF.Target); + Locs.push_back(llvm::ConstantInt::get(CGF.Int32Ty, + LineLoc.getRawEncoding())); + } + } + + return llvm::MDNode::get(CGF.getLLVMContext(), Locs.data(), Locs.size()); } void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {