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