]> granicus.if.org Git - clang/commitdiff
When forming the !srcloc mdnode for an inline asm, add the SourceLocations
authorChris Lattner <sabre@nondot.org>
Wed, 17 Nov 2010 08:25:26 +0000 (08:25 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 17 Nov 2010 08:25:26 +0000 (08:25 +0000)
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

lib/CodeGen/CGStmt.cpp

index d8a16fc7d7d299a0b5bddd82af3ff8dc97b0d6c1..c51021331394af72b98ef57091bab0fb66f136be 100644 (file)
@@ -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) {