aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGStmt.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-11-17 08:25:26 +0000
committerChris Lattner <sabre@nondot.org>2010-11-17 08:25:26 +0000
commit5d93653247eeedaff5f0712178953b63d71a0b3b (patch)
tree4076073337446e6be51ad714213c6e08e07c749f /lib/CodeGen/CGStmt.cpp
parent063e47667c583433548e3c40a3003bc1aac8cf78 (diff)
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" ^ <inline asm>:2:1: note: instantiated into assembly here .code32 ^ now we get: t.c:5:8: error: warning: ignoring directive for now ".code32\n" ^ <inline asm>: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
Diffstat (limited to 'lib/CodeGen/CGStmt.cpp')
-rw-r--r--lib/CodeGen/CGStmt.cpp28
1 files changed, 24 insertions, 4 deletions
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<llvm::Value *, 8> 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) {