Addressed the review comments.

http://reviews.llvm.org/D4589

Files:
  include/clang/Sema/Sema.h
  lib/Parse/ParseStmtAsm.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaStmtAsm.cpp
  test/CodeGen/mozilla-ms-inline-asm.c
  test/CodeGen/ms-inline-asm.c
  test/Parser/ms-inline-asm.c
  test/Sema/ms-inline-asm.c
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -46,6 +46,7 @@
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/TinyPtrVector.h"
 #include <deque>
@@ -3124,6 +3125,16 @@
                             ArrayRef<StringRef> Clobbers,
                             ArrayRef<Expr*> Exprs,
                             SourceLocation EndLoc);
+  struct MSAsmLabelEntry {
+    MSAsmLabelEntry() : InternalName(), Location(), Resolved(false) {}
+    llvm::SmallString<32> InternalName;
+    SourceLocation Location;
+    bool Resolved;
+  };
+  const MSAsmLabelEntry &GetMSAsmLabel(StringRef ExternalLabelName,
+                                       SourceLocation Location,
+                                       bool AlwaysCreate);
+  void HandleMSAsmLabelsOnScopePop();
 
   VarDecl *BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType ExceptionType,
                                   SourceLocation StartLoc,
@@ -8385,6 +8396,8 @@
   mutable IdentifierInfo *Ident_super;
   mutable IdentifierInfo *Ident___float128;
 
+  llvm::StringMap<MSAsmLabelEntry> MSAsmLabelMap;
+
 protected:
   friend class Parser;
   friend class InitializationSequence;
Index: lib/Parse/ParseStmtAsm.cpp
===================================================================
--- lib/Parse/ParseStmtAsm.cpp
+++ lib/Parse/ParseStmtAsm.cpp
@@ -93,6 +93,17 @@
     return Info.OpDecl;
   }
 
+  void LookupInlineAsmLabel(StringRef &Identifier, llvm::SourceMgr &LSM,
+                            llvm::SMLoc Location, bool Create) {
+    const llvm::MemoryBuffer *LBuf =
+      LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(Location));
+    unsigned Offset = Location.getPointer() - LBuf->getBufferStart();
+    SourceLocation Loc = translateLocation(Offset);
+    const Sema::MSAsmLabelEntry &Entry =
+      TheParser.getActions().GetMSAsmLabel(Identifier, Loc, Create);
+    Identifier = Entry.InternalName;
+  }
+
   bool LookupInlineAsmField(StringRef Base, StringRef Member,
                             unsigned &Offset) override {
     return TheParser.getActions().LookupInlineAsmField(Base, Member, Offset,
@@ -133,15 +144,7 @@
     }
   }
 
-  void handleDiagnostic(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();
-
+  SourceLocation translateLocation(unsigned Offset) {
     // Figure out which token that offset points into.
     const unsigned *TokOffsetPtr =
         std::lower_bound(AsmTokOffsets.begin(), AsmTokOffsets.end(), Offset);
@@ -157,6 +160,19 @@
       Loc = Tok.getLocation();
       Loc = Loc.getLocWithOffset(Offset - TokOffset);
     }
+    return Loc;
+  }
+
+  void handleDiagnostic(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();
+
+    SourceLocation Loc = translateLocation(Offset);
     TheParser.Diag(Loc, diag::err_inline_ms_asm_parsing) << D.getMessage();
   }
 };
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -1489,6 +1489,8 @@
 void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
   S->mergeNRVOIntoParent();
 
+  HandleMSAsmLabelsOnScopePop();
+
   if (S->decl_empty()) return;
   assert((S->getFlags() & (Scope::DeclScope | Scope::TemplateParamScope)) &&
          "Scope shouldn't contain decls!");
Index: lib/Sema/SemaStmtAsm.cpp
===================================================================
--- lib/Sema/SemaStmtAsm.cpp
+++ lib/Sema/SemaStmtAsm.cpp
@@ -22,6 +22,7 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/BitVector.h"
 #include "llvm/MC/MCParser/MCAsmParser.h"
+#include "llvm/Support/Format.h"
 using namespace clang;
 using namespace sema;
 
@@ -488,3 +489,49 @@
                             Clobbers, EndLoc);
   return NS;
 }
+
+const Sema::MSAsmLabelEntry& Sema::GetMSAsmLabel(StringRef ExternalLabelName,
+                                                 SourceLocation Location,
+                                                 bool AlwaysCreate) {
+  static uint32_t counter = 0;
+
+  // First, see if this is a label that we already know about.
+  llvm::StringMap<MSAsmLabelEntry>::iterator it =
+    MSAsmLabelMap.find(ExternalLabelName);
+  if (it != MSAsmLabelMap.end()) {
+    if (AlwaysCreate) {
+      // Resolve the label if it was previously referenced.
+      it->getValue().Resolved = true;
+      it->getValue().Location = Location;
+    }
+    return it->getValue();
+  }
+
+  // Otherwise, insert it, but only resolve it if we have seen the label itself.
+  std::string InternalName;
+  llvm::raw_string_ostream OS(InternalName);
+  // Create an internal name for the label.  The name should not be a valid mangled
+  // name, and should be unique.  We use a dot to make the name an invalid mangled
+  // name.
+  OS << llvm::format("__MSASMLABEL_.%" PRIu32 "__", counter++);
+  MSAsmLabelEntry Entry;
+  Entry.InternalName = OS.str();
+  Entry.Location = Location;
+  if (AlwaysCreate) {
+    Entry.Resolved = true;
+  }
+  MSAsmLabelMap.insert(std::make_pair(ExternalLabelName, Entry));
+  return GetMSAsmLabel(ExternalLabelName, Location, false);
+}
+
+void Sema::HandleMSAsmLabelsOnScopePop() {
+  for (const auto& Entry : MSAsmLabelMap) {
+    if (!Entry.getValue().Resolved) {
+      Diag(Entry.getValue().Location, diag::err_undeclared_label_use)
+        << Entry.getKey();
+    }
+  }
+
+  // Clear the map as we're leaving the function scope.
+  MSAsmLabelMap.clear();
+}
Index: test/CodeGen/mozilla-ms-inline-asm.c
===================================================================
--- test/CodeGen/mozilla-ms-inline-asm.c
+++ test/CodeGen/mozilla-ms-inline-asm.c
@@ -3,6 +3,8 @@
 
 // Some test cases for MS inline asm support from Mozilla code base.
 
+void invoke_copy_to_stack() {}
+
 void invoke(void* that, unsigned methodIndex,
             unsigned paramCount, void* params)
 {
@@ -18,24 +20,25 @@
 // CHECK: call void asm sideeffect inteldialect
 // CHECK: mov edx,dword ptr $1
 // CHECK: test edx,edx
-// CHECK: jz noparams
+// CHECK: jz {{[^_]*}}__MSASMLABEL_.0__
+//             ^ Can't use {{.*}} here because the matching is greedy.
 // CHECK: mov eax,edx
 // CHECK: shl eax,$$3
 // CHECK: sub esp,eax
 // CHECK: mov ecx,esp
 // CHECK: push dword ptr $0
-// CHECK: call invoke_copy_to_stack
-// CHECK: noparams:
-// CHECK: mov ecx,dword ptr $2
+// CHECK: call $2
+// CHECK: {{.*}}__MSASMLABEL_.0__:
+// CHECK: mov ecx,dword ptr $3
 // CHECK: push ecx
 // CHECK: mov edx,[ecx]
-// CHECK: mov eax,dword ptr $3
+// CHECK: mov eax,dword ptr $4
 // CHECK: call dword ptr[edx+eax*$$4]
 // CHECK: mov esp,ebp
 // CHECK: pop ebp
 // CHECK: ret
-// CHECK: "=*m,*m,*m,*m,~{eax},~{ebp},~{ecx},~{edx},~{flags},~{esp},~{dirflag},~{fpsr},~{flags}"
-// CHECK: (i8** %8, i32* %7, i8** %5, i32* %6)
+// CHECK: "=*m,*m,r,*m,*m,~{eax},~{ebp},~{ecx},~{edx},~{flags},~{esp},~{dirflag},~{fpsr},~{flags}"
+// CHECK: (i8** %8, i32* %7, void (...)* bitcast (void ()* @invoke_copy_to_stack to void (...)*), i8** %5, i32* %6)
 // CHECK: ret void
     __asm {
         mov     edx,paramCount
Index: test/CodeGen/ms-inline-asm.c
===================================================================
--- test/CodeGen/ms-inline-asm.c
+++ test/CodeGen/ms-inline-asm.c
@@ -242,7 +242,7 @@
   the_label:
   }
 // CHECK: t23
-// CHECK: call void asm sideeffect inteldialect "the_label:", "~{dirflag},~{fpsr},~{flags}"()
+// CHECK: call void asm sideeffect inteldialect "{{.*}}__MSASMLABEL_.0__:", "~{dirflag},~{fpsr},~{flags}"()
 }
 
 void t24_helper(void) {}
@@ -494,3 +494,30 @@
   // CHECK: call void asm sideeffect inteldialect "mov gs, word ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(i16* [[T41_A_ADDR]])
   // CHECK: call void asm sideeffect inteldialect "mov ss, word ptr $0", "*m,~{dirflag},~{fpsr},~{flags}"(i16* [[T41_A_ADDR]])
 }
+
+void label1() {
+  __asm {
+    label:
+    jmp label
+  }
+  // CHECK-LABEL: define void @label1
+  // CHECK: call void asm sideeffect inteldialect "{{.*}}__MSASMLABEL_.1__:\0A\09jmp {{.*}}__MSASMLABEL_.1__", "~{dirflag},~{fpsr},~{flags}"()
+}
+
+void label2() {
+  __asm {
+    jmp label
+    label:
+  }
+  // CHECK-LABEL: define void @label2
+  // CHECK: call void asm sideeffect inteldialect "jmp {{.*}}__MSASMLABEL_.2__\0A\09{{.*}}__MSASMLABEL_.2__:", "~{dirflag},~{fpsr},~{flags}"()
+}
+
+void label3() {
+  __asm {
+    label:
+    mov eax, label
+  }
+  // CHECK-LABEL: define void @label3
+  // CHECK: call void asm sideeffect inteldialect "{{.*}}__MSASMLABEL_.3__:\0A\09mov eax, {{.*}}__MSASMLABEL_.3__", "~{eax},~{dirflag},~{fpsr},~{flags}"()
+}
Index: test/Parser/ms-inline-asm.c
===================================================================
--- test/Parser/ms-inline-asm.c
+++ test/Parser/ms-inline-asm.c
@@ -48,6 +48,9 @@
 void t11() {
   do { __asm mov eax, 0 __asm { __asm mov edx, 1 } } while(0);
 }
+void t12() {
+  __asm jmp label // expected-error {{use of undeclared label label}}
+}
 int t_fail() { // expected-note {{to match this}}
   __asm 
   __asm { // expected-error 3 {{expected}} expected-note {{to match this}}
Index: test/Sema/ms-inline-asm.c
===================================================================
--- test/Sema/ms-inline-asm.c
+++ test/Sema/ms-inline-asm.c
@@ -21,7 +21,7 @@
   }
   f();
   __asm {
-    mov eax, LENGTH bar // expected-error {{unable to lookup expression}}
+    mov eax, LENGTH bar // expected-error {{unable to lookup expression}} expected-error {{use of undeclared label bar}}
   }
   f();
   __asm {
@@ -80,9 +80,10 @@
 } A;
 
 void t3() {
-  __asm mov eax, [eax] UndeclaredId // expected-error {{unknown token in expression}}
+  __asm mov eax, [eax] UndeclaredId // expected-error {{unknown token in expression}} expected-error {{use of undeclared label UndeclaredId}}
 
   // FIXME: Only emit one diagnostic here.
+  // expected-error@+3 {{use of undeclared label A}}
   // expected-error@+2 {{unexpected type name 'A': expected expression}}
   // expected-error@+1 {{unknown token in expression}}
   __asm mov eax, [eax] A
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to