diff options
Diffstat (limited to 'lib/Parse/ParseStmtAsm.cpp')
-rw-r--r-- | lib/Parse/ParseStmtAsm.cpp | 235 |
1 files changed, 124 insertions, 111 deletions
diff --git a/lib/Parse/ParseStmtAsm.cpp b/lib/Parse/ParseStmtAsm.cpp index d6f16bb0cb79e..d81029e279740 100644 --- a/lib/Parse/ParseStmtAsm.cpp +++ b/lib/Parse/ParseStmtAsm.cpp @@ -54,54 +54,13 @@ public: assert(AsmToks.size() == AsmTokOffsets.size()); } - void *LookupInlineAsmIdentifier(StringRef &LineBuf, - llvm::InlineAsmIdentifierInfo &Info, - bool IsUnevaluatedContext) override { - // Collect the desired tokens. - SmallVector<Token, 16> LineToks; - const Token *FirstOrigToken = nullptr; - findTokensForString(LineBuf, LineToks, FirstOrigToken); - - unsigned NumConsumedToks; - ExprResult Result = TheParser.ParseMSAsmIdentifier( - LineToks, NumConsumedToks, &Info, IsUnevaluatedContext); - - // If we consumed the entire line, tell MC that. - // Also do this if we consumed nothing as a way of reporting failure. - if (NumConsumedToks == 0 || NumConsumedToks == LineToks.size()) { - // By not modifying LineBuf, we're implicitly consuming it all. - - // Otherwise, consume up to the original tokens. - } else { - assert(FirstOrigToken && "not using original tokens?"); - - // Since we're using original tokens, apply that offset. - assert(FirstOrigToken[NumConsumedToks].getLocation() == - LineToks[NumConsumedToks].getLocation()); - unsigned FirstIndex = FirstOrigToken - AsmToks.begin(); - unsigned LastIndex = FirstIndex + NumConsumedToks - 1; - - // The total length we've consumed is the relative offset - // of the last token we consumed plus its length. - unsigned TotalOffset = - (AsmTokOffsets[LastIndex] + AsmToks[LastIndex].getLength() - - AsmTokOffsets[FirstIndex]); - LineBuf = LineBuf.substr(0, TotalOffset); - } - - // Initialize the "decl" with the lookup result. - Info.OpDecl = static_cast<void *>(Result.get()); - return Info.OpDecl; - } + void LookupInlineAsmIdentifier(StringRef &LineBuf, + llvm::InlineAsmIdentifierInfo &Info, + bool IsUnevaluatedContext) override; StringRef LookupInlineAsmLabel(StringRef Identifier, llvm::SourceMgr &LSM, llvm::SMLoc Location, - bool Create) override { - SourceLocation Loc = translateLocation(LSM, Location); - LabelDecl *Label = - TheParser.getActions().GetOrCreateMSAsmLabel(Identifier, Loc, Create); - return Label->getMSAsmLabel(); - } + bool Create) override; bool LookupInlineAsmField(StringRef Base, StringRef Member, unsigned &Offset) override { @@ -116,78 +75,133 @@ public: private: /// Collect the appropriate tokens for the given string. void findTokensForString(StringRef Str, SmallVectorImpl<Token> &TempToks, - const Token *&FirstOrigToken) const { - // For now, assert that the string we're working with is a substring - // of what we gave to MC. This lets us use the original tokens. - assert(!std::less<const char *>()(Str.begin(), AsmString.begin()) && - !std::less<const char *>()(AsmString.end(), Str.end())); - - // Try to find a token whose offset matches the first token. - unsigned FirstCharOffset = Str.begin() - AsmString.begin(); - const unsigned *FirstTokOffset = std::lower_bound( - AsmTokOffsets.begin(), AsmTokOffsets.end(), FirstCharOffset); - - // For now, assert that the start of the string exactly - // corresponds to the start of a token. - assert(*FirstTokOffset == FirstCharOffset); - - // Use all the original tokens for this line. (We assume the - // end of the line corresponds cleanly to a token break.) - unsigned FirstTokIndex = FirstTokOffset - AsmTokOffsets.begin(); - FirstOrigToken = &AsmToks[FirstTokIndex]; - unsigned LastCharOffset = Str.end() - AsmString.begin(); - for (unsigned i = FirstTokIndex, e = AsmTokOffsets.size(); i != e; ++i) { - if (AsmTokOffsets[i] >= LastCharOffset) - break; - TempToks.push_back(AsmToks[i]); - } + const Token *&FirstOrigToken) const; + + SourceLocation translateLocation(const llvm::SourceMgr &LSM, + llvm::SMLoc SMLoc); + + void handleDiagnostic(const llvm::SMDiagnostic &D); +}; +} + +void ClangAsmParserCallback::LookupInlineAsmIdentifier( + StringRef &LineBuf, llvm::InlineAsmIdentifierInfo &Info, + bool IsUnevaluatedContext) { + // Collect the desired tokens. + SmallVector<Token, 16> LineToks; + const Token *FirstOrigToken = nullptr; + findTokensForString(LineBuf, LineToks, FirstOrigToken); + + unsigned NumConsumedToks; + ExprResult Result = TheParser.ParseMSAsmIdentifier(LineToks, NumConsumedToks, + IsUnevaluatedContext); + + // If we consumed the entire line, tell MC that. + // Also do this if we consumed nothing as a way of reporting failure. + if (NumConsumedToks == 0 || NumConsumedToks == LineToks.size()) { + // By not modifying LineBuf, we're implicitly consuming it all. + + // Otherwise, consume up to the original tokens. + } else { + assert(FirstOrigToken && "not using original tokens?"); + + // Since we're using original tokens, apply that offset. + assert(FirstOrigToken[NumConsumedToks].getLocation() == + LineToks[NumConsumedToks].getLocation()); + unsigned FirstIndex = FirstOrigToken - AsmToks.begin(); + unsigned LastIndex = FirstIndex + NumConsumedToks - 1; + + // The total length we've consumed is the relative offset + // of the last token we consumed plus its length. + unsigned TotalOffset = + (AsmTokOffsets[LastIndex] + AsmToks[LastIndex].getLength() - + AsmTokOffsets[FirstIndex]); + LineBuf = LineBuf.substr(0, TotalOffset); } - SourceLocation translateLocation(const llvm::SourceMgr &LSM, llvm::SMLoc SMLoc) { - // 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::MemoryBuffer *LBuf = - LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(SMLoc)); - unsigned Offset = SMLoc.getPointer() - LBuf->getBufferStart(); - - // Figure out which token that offset points into. - const unsigned *TokOffsetPtr = - std::lower_bound(AsmTokOffsets.begin(), AsmTokOffsets.end(), Offset); - unsigned TokIndex = TokOffsetPtr - AsmTokOffsets.begin(); - unsigned TokOffset = *TokOffsetPtr; - - // 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 - TokOffset); - } - return Loc; + // Initialize Info with the lookup result. + if (!Result.isUsable()) + return; + TheParser.getActions().FillInlineAsmIdentifierInfo(Result.get(), Info); +} + +StringRef ClangAsmParserCallback::LookupInlineAsmLabel(StringRef Identifier, + llvm::SourceMgr &LSM, + llvm::SMLoc Location, + bool Create) { + SourceLocation Loc = translateLocation(LSM, Location); + LabelDecl *Label = + TheParser.getActions().GetOrCreateMSAsmLabel(Identifier, Loc, Create); + return Label->getMSAsmLabel(); +} + +void ClangAsmParserCallback::findTokensForString( + StringRef Str, SmallVectorImpl<Token> &TempToks, + const Token *&FirstOrigToken) const { + // For now, assert that the string we're working with is a substring + // of what we gave to MC. This lets us use the original tokens. + assert(!std::less<const char *>()(Str.begin(), AsmString.begin()) && + !std::less<const char *>()(AsmString.end(), Str.end())); + + // Try to find a token whose offset matches the first token. + unsigned FirstCharOffset = Str.begin() - AsmString.begin(); + const unsigned *FirstTokOffset = std::lower_bound( + AsmTokOffsets.begin(), AsmTokOffsets.end(), FirstCharOffset); + + // For now, assert that the start of the string exactly + // corresponds to the start of a token. + assert(*FirstTokOffset == FirstCharOffset); + + // Use all the original tokens for this line. (We assume the + // end of the line corresponds cleanly to a token break.) + unsigned FirstTokIndex = FirstTokOffset - AsmTokOffsets.begin(); + FirstOrigToken = &AsmToks[FirstTokIndex]; + unsigned LastCharOffset = Str.end() - AsmString.begin(); + for (unsigned i = FirstTokIndex, e = AsmTokOffsets.size(); i != e; ++i) { + if (AsmTokOffsets[i] >= LastCharOffset) + break; + TempToks.push_back(AsmToks[i]); } +} - void handleDiagnostic(const llvm::SMDiagnostic &D) { - const llvm::SourceMgr &LSM = *D.getSourceMgr(); - SourceLocation Loc = translateLocation(LSM, D.getLoc()); - TheParser.Diag(Loc, diag::err_inline_ms_asm_parsing) << D.getMessage(); +SourceLocation +ClangAsmParserCallback::translateLocation(const llvm::SourceMgr &LSM, + llvm::SMLoc SMLoc) { + // 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::MemoryBuffer *LBuf = + LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(SMLoc)); + unsigned Offset = SMLoc.getPointer() - LBuf->getBufferStart(); + + // Figure out which token that offset points into. + const unsigned *TokOffsetPtr = + std::lower_bound(AsmTokOffsets.begin(), AsmTokOffsets.end(), Offset); + unsigned TokIndex = TokOffsetPtr - AsmTokOffsets.begin(); + unsigned TokOffset = *TokOffsetPtr; + + // 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 - TokOffset); } -}; + return Loc; +} + +void ClangAsmParserCallback::handleDiagnostic(const llvm::SMDiagnostic &D) { + const llvm::SourceMgr &LSM = *D.getSourceMgr(); + SourceLocation Loc = translateLocation(LSM, D.getLoc()); + TheParser.Diag(Loc, diag::err_inline_ms_asm_parsing) << D.getMessage(); } /// Parse an identifier in an MS-style inline assembly block. -/// -/// \param CastInfo - a void* so that we don't have to teach Parser.h -/// about the actual type. ExprResult Parser::ParseMSAsmIdentifier(llvm::SmallVectorImpl<Token> &LineToks, unsigned &NumLineToksConsumed, - void *CastInfo, bool IsUnevaluatedContext) { - llvm::InlineAsmIdentifierInfo &Info = - *(llvm::InlineAsmIdentifierInfo *)CastInfo; - // Push a fake token on the end so that we don't overrun the token // stream. We use ';' because it expression-parsing should never // overrun it. @@ -227,7 +241,7 @@ ExprResult Parser::ParseMSAsmIdentifier(llvm::SmallVectorImpl<Token> &LineToks, /*AllowDeductionGuide=*/false, /*ObjectType=*/nullptr, TemplateKWLoc, Id); // Perform the lookup. - Result = Actions.LookupInlineAsmIdentifier(SS, TemplateKWLoc, Id, Info, + Result = Actions.LookupInlineAsmIdentifier(SS, TemplateKWLoc, Id, IsUnevaluatedContext); } // While the next two tokens are 'period' 'identifier', repeatedly parse it as @@ -241,7 +255,7 @@ ExprResult Parser::ParseMSAsmIdentifier(llvm::SmallVectorImpl<Token> &LineToks, IdentifierInfo *Id = Tok.getIdentifierInfo(); ConsumeToken(); // Consume the identifier. Result = Actions.LookupInlineAsmVarDeclField(Result.get(), Id->getName(), - Info, Tok.getLocation()); + Tok.getLocation()); } // Figure out how many tokens we are into LineToks. @@ -564,7 +578,7 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) { if (buildMSAsmString(PP, AsmLoc, AsmToks, TokOffsets, AsmString)) return StmtError(); - TargetOptions TO = Actions.Context.getTargetInfo().getTargetOpts(); + const TargetOptions &TO = Actions.Context.getTargetInfo().getTargetOpts(); std::string FeaturesStr = llvm::join(TO.Features.begin(), TO.Features.end(), ","); @@ -578,8 +592,7 @@ StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) { llvm::SourceMgr TempSrcMgr; llvm::MCContext Ctx(MAI.get(), MRI.get(), MOFI.get(), &TempSrcMgr); - MOFI->InitMCObjectFileInfo(TheTriple, /*PIC*/ false, llvm::CodeModel::Default, - Ctx); + MOFI->InitMCObjectFileInfo(TheTriple, /*PIC*/ false, Ctx); std::unique_ptr<llvm::MemoryBuffer> Buffer = llvm::MemoryBuffer::getMemBuffer(AsmString, "<MS inline asm>"); |