summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaStmtAsm.cpp
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2012-10-23 02:43:30 +0000
committerEli Friedman <eli.friedman@gmail.com>2012-10-23 02:43:30 +0000
commit5f1385b81b0a6c6878ff1e35118a5b0bf52ca930 (patch)
tree35d72be2e239ff535cbe6e3a59507dbbf486fa86 /lib/Sema/SemaStmtAsm.cpp
parent5f14fcbd45870585a136ae735d29d0e085c0d7f8 (diff)
[ms-inline-asm] Add handling for errors coming out of the backend.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@166463 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaStmtAsm.cpp')
-rw-r--r--lib/Sema/SemaStmtAsm.cpp51
1 files changed, 46 insertions, 5 deletions
diff --git a/lib/Sema/SemaStmtAsm.cpp b/lib/Sema/SemaStmtAsm.cpp
index 616dcfcd83..f33b87cebc 100644
--- a/lib/Sema/SemaStmtAsm.cpp
+++ b/lib/Sema/SemaStmtAsm.cpp
@@ -328,6 +328,7 @@ static StringRef getSpelling(Sema &SemaRef, Token AsmTok) {
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 @@ static bool buildMSAsmString(Sema &SemaRef,
StringRef Spelling = getSpelling(SemaRef, AsmToks[i]);
Asm += Spelling;
+ TokOffsets.push_back(Asm.size());
}
AsmString = Asm.str();
return false;
@@ -363,17 +365,53 @@ static bool buildMSAsmString(Sema &SemaRef,
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 @@ StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
}
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 @@ StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
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;