[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