[cfe-commits] r166463 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaStmtAsm.cpp test/Sema/ms-inline-asm.c

Eli Friedman eli.friedman at gmail.com
Mon Oct 22 19:43:30 PDT 2012


Author: efriedma
Date: Mon Oct 22 21:43:30 2012
New Revision: 166463

URL: http://llvm.org/viewvc/llvm-project?rev=166463&view=rev
Log:
[ms-inline-asm] Add handling for errors coming out of the backend.


Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/SemaStmtAsm.cpp
    cfe/trunk/test/Sema/ms-inline-asm.c

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=166463&r1=166462&r2=166463&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Oct 22 21:43:30 2012
@@ -5143,6 +5143,8 @@
     "invalid use of a cast in a inline asm context requiring an l-value: "
     "accepted due to -fheinous-gnu-extensions, but clang may remove support "
     "for this in the future">;
+
+  def err_inline_ms_asm_parsing : Error<"%0">;
 }
 
 let CategoryName = "Semantic Issue" in {

Modified: cfe/trunk/lib/Sema/SemaStmtAsm.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmtAsm.cpp?rev=166463&r1=166462&r2=166463&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmtAsm.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmtAsm.cpp Mon Oct 22 21:43:30 2012
@@ -328,6 +328,7 @@
 static bool buildMSAsmString(Sema &SemaRef,
                              SourceLocation AsmLoc,
                              ArrayRef<Token> AsmToks,
+                             llvm::SmallVectorImpl<unsigned> &TokOffsets,
                              std::string &AsmString) {
   assert (!AsmToks.empty() && "Didn't expect an empty AsmToks!");
 
@@ -355,6 +356,7 @@
 
     StringRef Spelling = getSpelling(SemaRef, AsmToks[i]);
     Asm += Spelling;
+    TokOffsets.push_back(Asm.size());
   }
   AsmString = Asm.str();
   return false;
@@ -363,17 +365,53 @@
 namespace {
 
 class MCAsmParserSemaCallbackImpl : public llvm::MCAsmParserSemaCallback {
-  Sema *SemaRef;
+  Sema &SemaRef;
+  SourceLocation AsmLoc;
+  ArrayRef<Token> AsmToks;
+  ArrayRef<unsigned> TokOffsets;
 
 public:
-  MCAsmParserSemaCallbackImpl(class Sema *Ref) { SemaRef = Ref; }
+  MCAsmParserSemaCallbackImpl(Sema &Ref, SourceLocation Loc,
+                              ArrayRef<Token> Toks,
+                              ArrayRef<unsigned> Offsets)
+    : SemaRef(Ref), AsmLoc(Loc), AsmToks(Toks), TokOffsets(Offsets) { }
   ~MCAsmParserSemaCallbackImpl() {}
 
   void *LookupInlineAsmIdentifier(StringRef Name, void *SrcLoc, unsigned &Size){
     SourceLocation Loc = SourceLocation::getFromPtrEncoding(SrcLoc);
-    NamedDecl *OpDecl = SemaRef->LookupInlineAsmIdentifier(Name, Loc, Size);
+    NamedDecl *OpDecl = SemaRef.LookupInlineAsmIdentifier(Name, Loc, Size);
     return static_cast<void *>(OpDecl);
   }
+
+  static void MSAsmDiagHandlerCallback(const llvm::SMDiagnostic &D,
+                                       void *Context) {
+    ((MCAsmParserSemaCallbackImpl*)Context)->MSAsmDiagHandler(D);
+  }
+  void MSAsmDiagHandler(const llvm::SMDiagnostic &D) {
+    // Compute an offset into the inline asm buffer.
+    // FIXME: This isn't right if .macro is involved (but hopefully, no
+    // real-world code does that).
+    const llvm::SourceMgr &LSM = *D.getSourceMgr();
+    const llvm::MemoryBuffer *LBuf =
+    LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(D.getLoc()));
+    unsigned Offset = D.getLoc().getPointer()  - LBuf->getBufferStart();
+
+    // Figure out which token that offset points into.
+    const unsigned *OffsetPtr =
+        std::lower_bound(TokOffsets.begin(), TokOffsets.end(), Offset);
+    unsigned TokIndex = OffsetPtr - TokOffsets.begin();
+
+    // If we come up with an answer which seems sane, use it; otherwise,
+    // just point at the __asm keyword.
+    // FIXME: Assert the answer is sane once we handle .macro correctly.
+    SourceLocation Loc = AsmLoc;
+    if (TokIndex < AsmToks.size()) {
+      const Token *Tok = &AsmToks[TokIndex];
+      Loc = Tok->getLocation();
+      Loc = Loc.getLocWithOffset(Offset - (*OffsetPtr - Tok->getLength()));
+    }
+    SemaRef.Diag(Loc, diag::err_inline_ms_asm_parsing) << D.getMessage();
+  }
 };
 
 }
@@ -427,7 +465,8 @@
   }
 
   std::string AsmString;
-  if (buildMSAsmString(*this, AsmLoc, AsmToks, AsmString))
+  llvm::SmallVector<unsigned, 8> TokOffsets;
+  if (buildMSAsmString(*this, AsmLoc, AsmToks, TokOffsets, AsmString))
     return StmtError();
 
   // Get the target specific parser.
@@ -466,8 +505,10 @@
   Parser->setParsingInlineAsm(true);
   TargetParser->setParsingInlineAsm(true);
 
-  MCAsmParserSemaCallbackImpl MCAPSI(this);
+  MCAsmParserSemaCallbackImpl MCAPSI(*this, AsmLoc, AsmToks, TokOffsets);
   TargetParser->setSemaCallback(&MCAPSI);
+  SrcMgr.setDiagHandler(MCAsmParserSemaCallbackImpl::MSAsmDiagHandlerCallback,
+                        &MCAPSI);
 
   unsigned NumOutputs;
   unsigned NumInputs;

Modified: cfe/trunk/test/Sema/ms-inline-asm.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/ms-inline-asm.c?rev=166463&r1=166462&r2=166463&view=diff
==============================================================================
--- cfe/trunk/test/Sema/ms-inline-asm.c (original)
+++ cfe/trunk/test/Sema/ms-inline-asm.c Mon Oct 22 21:43:30 2012
@@ -1,5 +1,20 @@
-// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -fms-extensions -fenable-experimental-ms-inline-asm -verify -fsyntax-only
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -fms-extensions -fenable-experimental-ms-inline-asm -Wno-microsoft -verify -fsyntax-only
 
 void t1(void) { 
- __asm __asm // expected-warning {{MS-style inline assembly is not supported}} expected-error {{__asm used with no assembly instructions}}
+ __asm __asm // expected-error {{__asm used with no assembly instructions}}
+}
+
+void f() {
+  __asm { 
+    mov eax, eax
+    .unknowndirective // expected-error {{unknown directive}}
+  }
+  f();
+  __asm {
+    mov eax, 1+=2 // expected-error 2 {{unknown token in expression}}
+  }
+  f();
+  __asm {
+    mov eax, 1+++ // expected-error 2 {{unknown token in expression}}
+  }
 }





More information about the cfe-commits mailing list