diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2012-10-23 02:43:30 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2012-10-23 02:43:30 +0000 |
commit | 5f1385b81b0a6c6878ff1e35118a5b0bf52ca930 (patch) | |
tree | 35d72be2e239ff535cbe6e3a59507dbbf486fa86 /lib/Sema/SemaStmtAsm.cpp | |
parent | 5f14fcbd45870585a136ae735d29d0e085c0d7f8 (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.cpp | 51 |
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; |