18#include "llvm/ADT/StringExtras.h"
19#include "llvm/MC/MCAsmInfo.h"
20#include "llvm/MC/MCContext.h"
21#include "llvm/MC/MCInstPrinter.h"
22#include "llvm/MC/MCInstrInfo.h"
23#include "llvm/MC/MCObjectFileInfo.h"
24#include "llvm/MC/MCParser/MCAsmParser.h"
25#include "llvm/MC/MCParser/MCTargetAsmParser.h"
26#include "llvm/MC/MCRegisterInfo.h"
27#include "llvm/MC/MCStreamer.h"
28#include "llvm/MC/MCSubtargetInfo.h"
29#include "llvm/MC/MCTargetOptions.h"
30#include "llvm/MC/TargetRegistry.h"
31#include "llvm/Support/SourceMgr.h"
35class ClangAsmParserCallback :
public llvm::MCAsmParserSemaCallback {
37 SourceLocation AsmLoc;
41 ArrayRef<Token> AsmToks;
44 ArrayRef<unsigned> AsmTokOffsets;
47 ClangAsmParserCallback(Parser &P, SourceLocation Loc, StringRef AsmString,
48 ArrayRef<Token> Toks, ArrayRef<unsigned> Offsets)
49 : TheParser(P), AsmLoc(Loc), AsmString(AsmString), AsmToks(Toks),
50 AsmTokOffsets(Offsets) {
51 assert(AsmToks.size() == AsmTokOffsets.size());
54 void LookupInlineAsmIdentifier(StringRef &LineBuf,
55 llvm::InlineAsmIdentifierInfo &Info,
56 bool IsUnevaluatedContext)
override;
58 StringRef LookupInlineAsmLabel(StringRef Identifier, llvm::SourceMgr &LSM,
62 bool LookupInlineAsmField(StringRef Base, StringRef
Member,
63 unsigned &Offset)
override {
64 return TheParser.getActions().LookupInlineAsmField(Base,
Member, Offset,
68 static void DiagHandlerCallback(
const llvm::SMDiagnostic &D,
void *Context) {
69 ((ClangAsmParserCallback *)Context)->handleDiagnostic(D);
74 void findTokensForString(StringRef Str, SmallVectorImpl<Token> &TempToks,
75 const Token *&FirstOrigToken)
const;
77 SourceLocation translateLocation(
const llvm::SourceMgr &LSM,
80 void handleDiagnostic(
const llvm::SMDiagnostic &D);
84void ClangAsmParserCallback::LookupInlineAsmIdentifier(
85 StringRef &LineBuf, llvm::InlineAsmIdentifierInfo &Info,
86 bool IsUnevaluatedContext) {
88 SmallVector<Token, 16> LineToks;
89 const Token *FirstOrigToken =
nullptr;
90 findTokensForString(LineBuf, LineToks, FirstOrigToken);
92 unsigned NumConsumedToks;
94 IsUnevaluatedContext);
98 if (NumConsumedToks == 0 || NumConsumedToks == LineToks.size()) {
103 assert(FirstOrigToken &&
"not using original tokens?");
106 assert(FirstOrigToken[NumConsumedToks].getLocation() ==
107 LineToks[NumConsumedToks].getLocation());
108 unsigned FirstIndex = FirstOrigToken - AsmToks.begin();
109 unsigned LastIndex = FirstIndex + NumConsumedToks - 1;
113 unsigned TotalOffset =
114 (AsmTokOffsets[LastIndex] + AsmToks[LastIndex].getLength() -
115 AsmTokOffsets[FirstIndex]);
116 LineBuf = LineBuf.substr(0, TotalOffset);
125StringRef ClangAsmParserCallback::LookupInlineAsmLabel(StringRef Identifier,
126 llvm::SourceMgr &LSM,
127 llvm::SMLoc Location,
129 SourceLocation Loc = translateLocation(LSM, Location);
135void ClangAsmParserCallback::findTokensForString(
136 StringRef Str, SmallVectorImpl<Token> &TempToks,
137 const Token *&FirstOrigToken)
const {
140 assert(!std::less<const char *>()(Str.begin(), AsmString.begin()) &&
141 !std::less<const char *>()(AsmString.end(), Str.end()));
144 unsigned FirstCharOffset = Str.begin() - AsmString.begin();
145 const unsigned *FirstTokOffset =
146 llvm::lower_bound(AsmTokOffsets, FirstCharOffset);
150 assert(*FirstTokOffset == FirstCharOffset);
154 unsigned FirstTokIndex = FirstTokOffset - AsmTokOffsets.begin();
155 FirstOrigToken = &AsmToks[FirstTokIndex];
156 unsigned LastCharOffset = Str.end() - AsmString.begin();
157 for (
unsigned i = FirstTokIndex, e = AsmTokOffsets.size(); i != e; ++i) {
158 if (AsmTokOffsets[i] >= LastCharOffset)
160 TempToks.push_back(AsmToks[i]);
165ClangAsmParserCallback::translateLocation(
const llvm::SourceMgr &LSM,
170 const llvm::MemoryBuffer *LBuf =
171 LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(SMLoc));
172 unsigned Offset = SMLoc.getPointer() - LBuf->getBufferStart();
175 const unsigned *TokOffsetPtr = llvm::lower_bound(AsmTokOffsets, Offset);
176 unsigned TokIndex = TokOffsetPtr - AsmTokOffsets.begin();
177 unsigned TokOffset = *TokOffsetPtr;
182 SourceLocation Loc = AsmLoc;
183 if (TokIndex < AsmToks.size()) {
184 const Token &
Tok = AsmToks[TokIndex];
191void ClangAsmParserCallback::handleDiagnostic(
const llvm::SMDiagnostic &D) {
192 const llvm::SourceMgr &LSM = *D.getSourceMgr();
193 SourceLocation Loc = translateLocation(LSM, D.getLoc());
194 TheParser.
Diag(Loc, diag::err_inline_ms_asm_parsing) << D.getMessage();
198 unsigned &NumLineToksConsumed,
199 bool IsUnevaluatedContext) {
204 Token EndOfStreamTok;
206 EndOfStreamTok.
setKind(EndOfStream);
207 LineToks.push_back(EndOfStreamTok);
210 LineToks.push_back(Tok);
212 PP.EnterTokenStream(LineToks,
true,
221 ParseOptionalCXXScopeSpecifier(SS,
nullptr,
230 if (Tok.is(tok::kw_this)) {
240 false, &TemplateKWLoc, Id);
242 Result = Actions.LookupInlineAsmIdentifier(SS, TemplateKWLoc, Id,
243 IsUnevaluatedContext);
248 while (
Result.isUsable() && Tok.is(tok::period)) {
249 Token IdTok = PP.LookAhead(0);
250 if (IdTok.
isNot(tok::identifier))
260 unsigned LineIndex = 0;
261 if (Tok.is(EndOfStream)) {
262 LineIndex = LineToks.size() - 2;
264 while (LineToks[LineIndex].getLocation() != Tok.getLocation()) {
266 assert(LineIndex < LineToks.size() - 2);
272 if (Invalid || Tok.is(EndOfStream)) {
273 NumLineToksConsumed = LineToks.size() - 2;
276 NumLineToksConsumed = LineIndex;
281 for (
unsigned i = 0, e = LineToks.size() - LineIndex - 2; i != e; ++i) {
284 assert(Tok.is(EndOfStream));
300 assert(!AsmToks.empty() &&
"Didn't expect an empty AsmToks!");
303 bool isNewStatement =
true;
305 for (
unsigned i = 0, e = AsmToks.size(); i < e; ++i) {
309 if (!isNewStatement && (
Tok.is(tok::kw_asm) ||
Tok.isAtStartOfLine())) {
311 isNewStatement =
true;
316 if (!isNewStatement &&
Tok.hasLeadingSpace())
320 TokOffsets.push_back(
Asm.size());
323 if (
Tok.is(tok::kw_asm)) {
326 PP.
Diag(AsmLoc, diag::err_asm_empty);
335 bool SpellingInvalid =
false;
337 assert(!SpellingInvalid &&
"spelling was invalid after correct parse?");
340 isNewStatement =
false;
347 assert(TokOffsets.size() == AsmToks.size());
351bool Parser::isGCCAsmStatement(
const Token &TokAfterAsm)
const {
352 return TokAfterAsm.
is(tok::l_paren) || isGNUAsmQualifier(TokAfterAsm);
355bool Parser::isGNUAsmQualifier(
const Token &TokAfterAsm)
const {
356 return getGNUAsmQualifier(TokAfterAsm) != GNUAsmQualifiers::AQ_unspecified;
359StmtResult Parser::ParseMicrosoftAsmStatement(SourceLocation AsmLoc) {
360 SourceManager &SrcMgr = PP.getSourceManager();
361 SourceLocation EndLoc = AsmLoc;
362 SmallVector<Token, 4> AsmToks;
364 bool SingleLineMode =
true;
365 unsigned BraceNesting = 0;
367 bool InAsmComment =
false;
370 unsigned NumTokensRead = 0;
371 SmallVector<SourceLocation, 4> LBraceLocs;
372 bool SkippedStartOfLine =
false;
374 if (
Tok.
is(tok::l_brace)) {
376 SingleLineMode =
false;
378 EndLoc = ConsumeBrace();
379 LBraceLocs.push_back(EndLoc);
384 FID = ExpAsmLoc.first;
386 LBraceLocs.push_back(SourceLocation());
395 if (!InAsmComment &&
Tok.
is(tok::l_brace)) {
398 AsmToks.push_back(
Tok);
399 EndLoc = ConsumeBrace();
401 LBraceLocs.push_back(EndLoc);
405 }
else if (!InAsmComment &&
Tok.
is(tok::semi)) {
408 if (!SingleLineMode) {
411 FID = ExpSemiLoc.first;
414 }
else if (SingleLineMode || InAsmComment) {
418 if (ExpLoc.first != FID ||
419 SrcMgr.
getLineNumber(ExpLoc.first, ExpLoc.second) != LineNo) {
424 bool isAsm =
Tok.
is(tok::kw_asm);
425 if (SingleLineMode && (!isAsm || isGCCAsmStatement(NextToken())))
428 InAsmComment =
false;
432 if (PP.LookAhead(0).is(tok::l_brace))
436 }
else if (
Tok.
is(tok::semi)) {
442 }
else if (!InAsmComment &&
Tok.
is(tok::r_brace)) {
450 if (!InAsmComment && BraceNesting &&
Tok.
is(tok::r_brace) &&
451 BraceCount == (savedBraceCount + BraceNesting)) {
455 if (SingleLineMode || BraceNesting > 1) {
457 AsmToks.push_back(
Tok);
459 EndLoc = ConsumeBrace();
463 if (BraceNesting == 0 && !SingleLineMode)
466 LBraceLocs.pop_back();
481 if (SkippedStartOfLine)
483 AsmToks.push_back(
Tok);
488 SkippedStartOfLine =
false;
491 if (BraceNesting &&
BraceCount != savedBraceCount) {
493 for (
unsigned i = 0; i < BraceNesting; ++i) {
494 Diag(
Tok, diag::err_expected) << tok::r_brace;
495 Diag(LBraceLocs.back(), diag::note_matching) << tok::l_brace;
496 LBraceLocs.pop_back();
499 }
else if (NumTokensRead == 0) {
501 Diag(
Tok, diag::err_expected) << tok::l_brace;
506 SmallVector<StringRef, 4> ConstraintRefs;
507 SmallVector<Expr *, 4> Exprs;
508 SmallVector<StringRef, 4> ClobberRefs;
511 const llvm::Triple &TheTriple = Actions.Context.getTargetInfo().getTriple();
512 const llvm::Target *TheTarget =
nullptr;
513 if (!TheTriple.isX86()) {
514 Diag(AsmLoc, diag::err_msasm_unsupported_arch) << TheTriple.getArchName();
517 TheTarget = llvm::TargetRegistry::lookupTarget(TheTriple,
Error);
519 Diag(AsmLoc, diag::err_msasm_unable_to_create_target) <<
Error;
522 assert(!LBraceLocs.empty() &&
"Should have at least one location here");
524 SmallString<512> AsmString;
525 auto EmptyStmt = [&] {
526 return Actions.ActOnMSAsmStmt(AsmLoc, LBraceLocs[0], AsmToks, AsmString,
528 ConstraintRefs, ClobberRefs, Exprs, EndLoc);
532 if (!TheTarget || AsmToks.empty()) {
537 SmallVector<unsigned, 8> TokOffsets;
541 const TargetOptions &TO = Actions.Context.getTargetInfo().getTargetOpts();
542 std::string FeaturesStr =
545 std::unique_ptr<llvm::MCRegisterInfo> MRI(
546 TheTarget->createMCRegInfo(TheTriple));
548 Diag(AsmLoc, diag::err_msasm_unable_to_create_target)
549 <<
"target MC unavailable";
553 llvm::MCTargetOptions MCOptions;
554 std::unique_ptr<llvm::MCAsmInfo> MAI(
555 TheTarget->createMCAsmInfo(*MRI, TheTriple, MCOptions));
557 std::unique_ptr<llvm::MCInstrInfo> MII(TheTarget->createMCInstrInfo());
558 std::unique_ptr<llvm::MCSubtargetInfo> STI(
559 TheTarget->createMCSubtargetInfo(TheTriple, TO.
CPU, FeaturesStr));
562 if (!MAI || !MII || !STI) {
563 Diag(AsmLoc, diag::err_msasm_unable_to_create_target)
564 <<
"target MC unavailable";
568 llvm::SourceMgr TempSrcMgr;
569 llvm::MCContext Ctx(TheTriple, MAI.get(), MRI.get(), STI.get(), &TempSrcMgr);
570 std::unique_ptr<llvm::MCObjectFileInfo> MOFI(
571 TheTarget->createMCObjectFileInfo(Ctx,
false));
572 Ctx.setObjectFileInfo(MOFI.get());
574 std::unique_ptr<llvm::MemoryBuffer> Buffer =
575 llvm::MemoryBuffer::getMemBuffer(AsmString,
"<MS inline asm>");
578 TempSrcMgr.AddNewSourceBuffer(std::move(Buffer), llvm::SMLoc());
580 std::unique_ptr<llvm::MCStreamer> Str(createNullStreamer(Ctx));
581 std::unique_ptr<llvm::MCAsmParser> Parser(
582 createMCAsmParser(TempSrcMgr, Ctx, *Str, *MAI));
584 std::unique_ptr<llvm::MCTargetAsmParser> TargetParser(
585 TheTarget->createMCAsmParser(*STI, *Parser, *MII, MCOptions));
588 Diag(AsmLoc, diag::err_msasm_unable_to_create_target)
589 <<
"target ASM parser unavailable";
593 std::unique_ptr<llvm::MCInstPrinter> IP(
594 TheTarget->createMCInstPrinter(TheTriple, 1, *MAI, *MII, *MRI));
597 Parser->setAssemblerDialect(1);
598 Parser->setTargetParser(*TargetParser);
599 Parser->setParsingMSInlineAsm(
true);
600 TargetParser->setParsingMSInlineAsm(
true);
602 ClangAsmParserCallback Callback(*
this, AsmLoc, AsmString, AsmToks,
604 TargetParser->setSemaCallback(&Callback);
605 TempSrcMgr.setDiagHandler(ClangAsmParserCallback::DiagHandlerCallback,
610 std::string AsmStringIR;
611 SmallVector<std::pair<void *, bool>, 4> OpExprs;
612 SmallVector<std::string, 4> Constraints;
613 SmallVector<std::string, 4> Clobbers;
614 if (Parser->parseMSInlineAsm(AsmStringIR, NumOutputs, NumInputs, OpExprs,
615 Constraints, Clobbers, MII.get(), IP.get(),
621 llvm::erase_if(Clobbers, [](
const std::string &
C) {
622 return C ==
"fpsr" ||
C ==
"mxcsr";
626 llvm::append_range(ClobberRefs, Clobbers);
629 unsigned NumExprs = NumOutputs + NumInputs;
630 ConstraintRefs.resize(NumExprs);
631 Exprs.resize(NumExprs);
632 for (
unsigned i = 0, e = NumExprs; i != e; ++i) {
633 Expr *OpExpr =
static_cast<Expr *
>(OpExprs[i].first);
638 if (OpExprs[i].second)
640 Actions.BuildUnaryOp(getCurScope(), AsmLoc, UO_AddrOf, OpExpr).get();
642 ConstraintRefs[i] = StringRef(Constraints[i]);
647 return Actions.ActOnMSAsmStmt(AsmLoc, LBraceLocs[0], AsmToks, AsmStringIR,
648 NumOutputs, NumInputs, ConstraintRefs,
649 ClobberRefs, Exprs, EndLoc);
652bool Parser::parseGNUAsmQualifierListOpt(GNUAsmQualifiers &AQ) {
654 const GNUAsmQualifiers::AQ A = getGNUAsmQualifier(
Tok);
655 if (A == GNUAsmQualifiers::AQ_unspecified) {
658 SkipUntil(tok::r_paren, StopAtSemi);
663 if (AQ.setAsmQualifier(A))
665 << GNUAsmQualifiers::getQualifierName(A);
671StmtResult Parser::ParseAsmStatement(
bool &msAsm) {
672 assert(
Tok.
is(tok::kw_asm) &&
"Not an asm stmt");
673 SourceLocation AsmLoc = ConsumeToken();
675 if (getLangOpts().AsmBlocks && !isGCCAsmStatement(
Tok)) {
677 return ParseMicrosoftAsmStatement(AsmLoc);
681 GNUAsmQualifiers GAQ;
682 if (parseGNUAsmQualifierListOpt(GAQ))
685 if (GAQ.isGoto() && getLangOpts().SpeculativeLoadHardening)
686 Diag(Loc, diag::warn_slh_does_not_support_asm_goto);
688 BalancedDelimiterTracker
T(*
this, tok::l_paren);
691 ExprResult AsmString(ParseAsmStringLiteral(
false));
695 if (!(getLangOpts().GNUAsm || AsmString.isInvalid())) {
697 if (!SL->getString().trim().empty())
698 Diag(Loc, diag::err_gnu_inline_asm_disabled);
701 if (AsmString.isInvalid()) {
707 SmallVector<IdentifierInfo *, 4> Names;
708 ExprVector Constraints;
712 if (
Tok.
is(tok::r_paren)) {
715 return Actions.ActOnGCCAsmStmt(
716 AsmLoc,
true, GAQ.isVolatile(),
717 0, 0,
nullptr, Constraints, Exprs,
718 AsmString.get(), Clobbers, 0,
T.getCloseLocation());
722 bool AteExtraColon =
false;
723 if (
Tok.
is(tok::colon) ||
Tok.
is(tok::coloncolon)) {
725 AteExtraColon =
Tok.
is(tok::coloncolon);
728 if (!AteExtraColon && ParseAsmOperandsOpt(Names, Constraints, Exprs))
732 unsigned NumOutputs = Names.size();
735 if (AteExtraColon ||
Tok.
is(tok::colon) ||
Tok.
is(tok::coloncolon)) {
738 AteExtraColon =
false;
740 AteExtraColon =
Tok.
is(tok::coloncolon);
744 if (!AteExtraColon && ParseAsmOperandsOpt(Names, Constraints, Exprs))
748 assert(Names.size() == Constraints.size() &&
749 Constraints.size() == Exprs.size() &&
"Input operand size mismatch!");
751 unsigned NumInputs = Names.size() - NumOutputs;
754 if (AteExtraColon ||
Tok.
is(tok::colon) ||
Tok.
is(tok::coloncolon)) {
756 AteExtraColon =
false;
758 AteExtraColon =
Tok.
is(tok::coloncolon);
762 if (!AteExtraColon && (isTokenStringLiteral() ||
Tok.
is(tok::l_paren))) {
764 ExprResult Clobber(ParseAsmStringLiteral(
false));
766 if (Clobber.isInvalid())
769 Clobbers.push_back(Clobber.get());
771 if (!TryConsumeToken(tok::comma))
776 if (!GAQ.isGoto() && (
Tok.
isNot(tok::r_paren) || AteExtraColon)) {
777 Diag(
Tok, diag::err_expected) << tok::r_paren;
778 SkipUntil(tok::r_paren, StopAtSemi);
783 unsigned NumLabels = 0;
784 if (AteExtraColon ||
Tok.
is(tok::colon)) {
790 Diag(
Tok, diag::err_expected) << tok::identifier;
791 SkipUntil(tok::r_paren, StopAtSemi);
798 SkipUntil(tok::r_paren, StopAtSemi);
803 Exprs.push_back(Res.
get());
806 if (!TryConsumeToken(tok::comma))
809 }
else if (GAQ.isGoto()) {
810 Diag(
Tok, diag::err_expected) << tok::colon;
811 SkipUntil(tok::r_paren, StopAtSemi);
815 return Actions.ActOnGCCAsmStmt(AsmLoc,
false, GAQ.isVolatile(), NumOutputs,
816 NumInputs, Names.data(), Constraints, Exprs,
817 AsmString.get(), Clobbers, NumLabels,
818 T.getCloseLocation());
821bool Parser::ParseAsmOperandsOpt(SmallVectorImpl<IdentifierInfo *> &Names,
822 SmallVectorImpl<Expr *> &Constraints,
823 SmallVectorImpl<Expr *> &Exprs) {
825 if (
Tok.
isOneOf(tok::colon, tok::coloncolon, tok::r_paren))
830 if (
Tok.
is(tok::l_square)) {
831 BalancedDelimiterTracker
T(*
this, tok::l_square);
835 Diag(
Tok, diag::err_expected) << tok::identifier;
836 SkipUntil(tok::r_paren, StopAtSemi);
846 Names.push_back(
nullptr);
848 ExprResult Constraint(ParseAsmStringLiteral(
false));
849 if (Constraint.isInvalid()) {
850 SkipUntil(tok::r_paren, StopAtSemi);
853 Constraints.push_back(Constraint.get());
856 Diag(
Tok, diag::err_expected_lparen_after) <<
"asm operand";
857 SkipUntil(tok::r_paren, StopAtSemi);
862 BalancedDelimiterTracker
T(*
this, tok::l_paren);
867 SkipUntil(tok::r_paren, StopAtSemi);
870 Exprs.push_back(Res.
get());
872 if (!TryConsumeToken(tok::comma))
877const char *Parser::GNUAsmQualifiers::getQualifierName(AQ Qualifier) {
879 case AQ_volatile:
return "volatile";
880 case AQ_inline:
return "inline";
881 case AQ_goto:
return "goto";
882 case AQ_unspecified:
return "unspecified";
884 llvm_unreachable(
"Unknown GNUAsmQualifier");
887Parser::GNUAsmQualifiers::AQ
888Parser::getGNUAsmQualifier(
const Token &
Tok)
const {
890 case tok::kw_volatile:
return GNUAsmQualifiers::AQ_volatile;
891 case tok::kw_inline:
return GNUAsmQualifiers::AQ_inline;
892 case tok::kw_goto:
return GNUAsmQualifiers::AQ_goto;
893 default:
return GNUAsmQualifiers::AQ_unspecified;
896bool Parser::GNUAsmQualifiers::setAsmQualifier(AQ Qualifier) {
897 bool IsDuplicate = Qualifiers &
Qualifier;
Defines the clang::ASTContext interface.
Defines the Diagnostic-related interfaces.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
static bool buildMSAsmString(Preprocessor &PP, SourceLocation AsmLoc, ArrayRef< Token > AsmToks, SmallVectorImpl< unsigned > &TokOffsets, SmallString< 512 > &Asm)
Turn a sequence of our tokens back into a string that we can hand to the MC asm parser.
Represents a C++ nested-name-specifier or a global scope specifier.
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
StringRef getMSAsmLabel() const
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
SourceLocation ConsumeToken()
ConsumeToken - Consume the current 'peek token' and lex the next one.
Sema & getActions() const
ExprResult ParseMSAsmIdentifier(llvm::SmallVectorImpl< Token > &LineToks, unsigned &NumLineToksConsumed, bool IsUnevaluated)
Parse an identifier in an MS-style inline assembly block.
bool ParseUnqualifiedId(CXXScopeSpec &SS, ParsedType ObjectType, bool ObjectHadErrors, bool EnteringContext, bool AllowDestructorName, bool AllowConstructorName, bool AllowDeductionGuide, SourceLocation *TemplateKWLoc, UnqualifiedId &Result)
Parse a C++ unqualified-id (or a C identifier), which describes the name of an entity.
SourceLocation ConsumeAnyToken(bool ConsumeCodeCompletionTok=false)
ConsumeAnyToken - Dispatch to the right Consume* method based on the current token type.
const LangOptions & getLangOpts() const
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the 'spelling' of the token at the given location; does not go up to the spelling location or ...
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const
Forwarding function for diagnostics.
void FillInlineAsmIdentifierInfo(Expr *Res, llvm::InlineAsmIdentifierInfo &Info)
LabelDecl * GetOrCreateMSAsmLabel(StringRef ExternalLabelName, SourceLocation Location, bool AlwaysCreate)
Encodes a location in the source.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
FileIDAndOffset getDecomposedExpansionLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
unsigned getLineNumber(FileID FID, unsigned FilePos, bool *Invalid=nullptr) const
Given a SourceLocation, return the spelling line number for the position indicated.
std::vector< std::string > Features
The list of target specific features to enable or disable – this should be a list of strings starting...
std::string CPU
If given, the name of the target CPU to generate code for.
Token - This structure provides full information about a lexed token.
IdentifierInfo * getIdentifierInfo() const
void clearFlag(TokenFlags Flag)
Unset the specified flag.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
void setKind(tok::TokenKind K)
bool is(tok::TokenKind K) const
is/isNot - Predicates to check if this token is a specific kind, as in "if (Tok.is(tok::l_brace)) {....
tok::TokenKind getKind() const
bool isAtStartOfLine() const
isAtStartOfLine - Return true if this token is at the start of a line.
bool isOneOf(Ts... Ks) const
bool isNot(tok::TokenKind K) const
void startToken()
Reset all flags to cleared.
void setFlag(TokenFlags Flag)
Set the specified flag.
Represents a C++ unqualified-id that has been parsed.
Defines the clang::TargetInfo interface.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
The JSON file list parser is used to communicate input to InstallAPI.
std::pair< FileID, unsigned > FileIDAndOffset
@ Create
'create' clause, allowed on Compute and Combined constructs, plus 'data', 'enter data',...
@ Asm
Assembly: we accept this only so that we can preprocess it.
@ Result
The result type of a method or function.
const FunctionProtoType * T
U cast(CodeGen::Address addr)
ActionResult< Expr * > ExprResult
ActionResult< Stmt * > StmtResult