summaryrefslogtreecommitdiffstats
path: root/clang/lib
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
commit11feaf5921cfc0afeb207cfed6a186c948ad66bc (patch)
treeee0af4ff80fceaf85d190796420fe6af6c722852 /clang/lib
parent79ffdc7581f6d6296f37857e483a524f22b6c9e7 (diff)
downloadbcm5719-llvm-11feaf5921cfc0afeb207cfed6a186c948ad66bc.tar.gz
bcm5719-llvm-11feaf5921cfc0afeb207cfed6a186c948ad66bc.zip
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. llvm-svn: 119489
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CGStmt.cpp28
1 files changed, 24 insertions, 4 deletions
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index d8a16fc7d7d..c5102133139 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/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) {
OpenPOWER on IntegriCloud