;
37classClangAsmParserCallback :
publicllvm::MCAsmParserSemaCallback {
51: TheParser(
P), AsmLoc(
Loc), AsmString(AsmString), AsmToks(Toks),
52AsmTokOffsets(Offsets) {
53assert(AsmToks.size() == AsmTokOffsets.size());
56 voidLookupInlineAsmIdentifier(StringRef &LineBuf,
57llvm::InlineAsmIdentifierInfo &Info,
58 boolIsUnevaluatedContext)
override;
60StringRef LookupInlineAsmLabel(StringRef
Identifier, llvm::SourceMgr &LSM,
64 boolLookupInlineAsmField(StringRef
Base, StringRef
Member,
65 unsigned&Offset)
override{
70 static voidDiagHandlerCallback(
constllvm::SMDiagnostic &
D,
void*Context) {
71((ClangAsmParserCallback *)Context)->handleDiagnostic(
D);
77 const Token*&FirstOrigToken)
const;
82 voidhandleDiagnostic(
constllvm::SMDiagnostic &
D);
86voidClangAsmParserCallback::LookupInlineAsmIdentifier(
87StringRef &LineBuf, llvm::InlineAsmIdentifierInfo &Info,
88 boolIsUnevaluatedContext) {
91 const Token*FirstOrigToken =
nullptr;
92findTokensForString(LineBuf, LineToks, FirstOrigToken);
94 unsignedNumConsumedToks;
96IsUnevaluatedContext);
100 if(NumConsumedToks == 0 || NumConsumedToks == LineToks.size()) {
105assert(FirstOrigToken &&
"not using original tokens?");
108assert(FirstOrigToken[NumConsumedToks].getLocation() ==
109LineToks[NumConsumedToks].getLocation());
110 unsignedFirstIndex = FirstOrigToken - AsmToks.begin();
111 unsignedLastIndex = FirstIndex + NumConsumedToks - 1;
115 unsignedTotalOffset =
116(AsmTokOffsets[LastIndex] + AsmToks[LastIndex].getLength() -
117AsmTokOffsets[FirstIndex]);
118LineBuf = LineBuf.substr(0, TotalOffset);
122 if(!Result.isUsable())
127StringRef ClangAsmParserCallback::LookupInlineAsmLabel(StringRef
Identifier,
128llvm::SourceMgr &LSM,
129llvm::SMLoc Location,
134 return Label->getMSAsmLabel();
137voidClangAsmParserCallback::findTokensForString(
139 const Token*&FirstOrigToken)
const{
142assert(!std::less<const char *>()(Str.begin(), AsmString.begin()) &&
143!std::less<const char *>()(AsmString.end(), Str.end()));
146 unsignedFirstCharOffset = Str.begin() - AsmString.begin();
147 const unsigned*FirstTokOffset =
148llvm::lower_bound(AsmTokOffsets, FirstCharOffset);
152assert(*FirstTokOffset == FirstCharOffset);
156 unsignedFirstTokIndex = FirstTokOffset - AsmTokOffsets.begin();
157FirstOrigToken = &AsmToks[FirstTokIndex];
158 unsignedLastCharOffset = Str.end() - AsmString.begin();
159 for(
unsignedi = FirstTokIndex, e = AsmTokOffsets.size(); i != e; ++i) {
160 if(AsmTokOffsets[i] >= LastCharOffset)
162TempToks.push_back(AsmToks[i]);
167ClangAsmParserCallback::translateLocation(
constllvm::SourceMgr &LSM,
172 constllvm::MemoryBuffer *LBuf =
173LSM.getMemoryBuffer(LSM.FindBufferContainingLoc(SMLoc));
174 unsignedOffset = SMLoc.getPointer() - LBuf->getBufferStart();
177 const unsigned*TokOffsetPtr = llvm::lower_bound(AsmTokOffsets, Offset);
178 unsignedTokIndex = TokOffsetPtr - AsmTokOffsets.begin();
179 unsignedTokOffset = *TokOffsetPtr;
185 if(TokIndex < AsmToks.size()) {
186 const Token&Tok = AsmToks[TokIndex];
193voidClangAsmParserCallback::handleDiagnostic(
constllvm::SMDiagnostic &
D) {
194 constllvm::SourceMgr &LSM = *
D.getSourceMgr();
196TheParser.
Diag(
Loc, diag::err_inline_ms_asm_parsing) <<
D.getMessage();
201 unsigned&NumLineToksConsumed,
202 boolIsUnevaluatedContext) {
207 TokenEndOfStreamTok;
209EndOfStreamTok.
setKind(EndOfStream);
210LineToks.push_back(EndOfStreamTok);
213LineToks.push_back(Tok);
215PP.EnterTokenStream(LineToks,
true,
224ParseOptionalCXXScopeSpecifier(SS,
nullptr,
231 boolInvalid =
true;
233 if(Tok.
is(tok::kw_this)) {
243 false, &TemplateKWLoc,
Id);
246IsUnevaluatedContext);
251 while(
Result.isUsable() && Tok.
is(tok::period)) {
253 if(IdTok.
isNot(tok::identifier))
263 unsignedLineIndex = 0;
264 if(Tok.
is(EndOfStream)) {
265LineIndex = LineToks.size() - 2;
267 while(LineToks[LineIndex].getLocation() != Tok.
getLocation()) {
269assert(LineIndex < LineToks.size() - 2);
275 if(Invalid || Tok.
is(EndOfStream)) {
276NumLineToksConsumed = LineToks.size() - 2;
279NumLineToksConsumed = LineIndex;
284 for(
unsignedi = 0, e = LineToks.size() - LineIndex - 2; i != e; ++i) {
287assert(Tok.
is(EndOfStream));
303assert(!AsmToks.empty() &&
"Didn't expect an empty AsmToks!");
306 boolisNewStatement =
true;
308 for(
unsignedi = 0, e = AsmToks.size(); i < e; ++i) {
309 const Token&Tok = AsmToks[i];
314isNewStatement =
true;
323TokOffsets.push_back(
Asm.size());
326 if(Tok.
is(tok::kw_asm)) {
329PP.
Diag(AsmLoc, diag::err_asm_empty);
338 boolSpellingInvalid =
false;
340assert(!SpellingInvalid &&
"spelling was invalid after correct parse?");
343isNewStatement =
false;
347 Asm.push_back(
'\0');
350assert(TokOffsets.size() == AsmToks.size());
355boolParser::isGCCAsmStatement(
const Token&TokAfterAsm)
const{
356 returnTokAfterAsm.
is(tok::l_paren) || isGNUAsmQualifier(TokAfterAsm);
359boolParser::isGNUAsmQualifier(
const Token&TokAfterAsm)
const{
360 returngetGNUAsmQualifier(TokAfterAsm) != GNUAsmQualifiers::AQ_unspecified;
383 boolSingleLineMode =
true;
384 unsignedBraceNesting = 0;
385 unsigned shortsavedBraceCount = BraceCount;
386 boolInAsmComment =
false;
389 unsignedNumTokensRead = 0;
391 boolSkippedStartOfLine =
false;
393 if(Tok.
is(tok::l_brace)) {
395SingleLineMode =
false;
397EndLoc = ConsumeBrace();
398LBraceLocs.push_back(EndLoc);
402std::pair<FileID, unsigned> ExpAsmLoc =
404FID = ExpAsmLoc.first;
415 if(!InAsmComment && Tok.
is(tok::l_brace)) {
418AsmToks.push_back(Tok);
419EndLoc = ConsumeBrace();
421LBraceLocs.push_back(EndLoc);
425}
else if(!InAsmComment && Tok.
is(tok::semi)) {
427InAsmComment =
true;
428 if(!SingleLineMode) {
430std::pair<FileID, unsigned> ExpSemiLoc =
432FID = ExpSemiLoc.first;
435}
else if(SingleLineMode || InAsmComment) {
438std::pair<FileID, unsigned> ExpLoc =
440 if(ExpLoc.first != FID ||
441SrcMgr.
getLineNumber(ExpLoc.first, ExpLoc.second) != LineNo) {
446 boolisAsm = Tok.
is(tok::kw_asm);
447 if(SingleLineMode && (!isAsm || isGCCAsmStatement(
NextToken())))
450InAsmComment =
false;
456LineNo = SrcMgr.
getLineNumber(ExpLoc.first, ExpLoc.second);
458}
else if(Tok.
is(tok::semi)) {
460InAsmComment =
true;
464}
else if(!InAsmComment && Tok.
is(tok::r_brace)) {
472 if(!InAsmComment && BraceNesting && Tok.
is(tok::r_brace) &&
473BraceCount == (savedBraceCount + BraceNesting)) {
477 if(SingleLineMode || BraceNesting > 1) {
479AsmToks.push_back(Tok);
481EndLoc = ConsumeBrace();
485 if(BraceNesting == 0 && !SingleLineMode)
488LBraceLocs.pop_back();
503 if(SkippedStartOfLine)
505AsmToks.push_back(Tok);
510SkippedStartOfLine =
false;
513 if(BraceNesting && BraceCount != savedBraceCount) {
515 for(
unsignedi = 0; i < BraceNesting; ++i) {
516 Diag(Tok, diag::err_expected) << tok::r_brace;
517 Diag(LBraceLocs.back(), diag::note_matching) << tok::l_brace;
518LBraceLocs.pop_back();
521}
else if(NumTokensRead == 0) {
523 Diag(Tok, diag::err_expected) << tok::l_brace;
534 conststd::string &TT = TheTriple.getTriple();
535 constllvm::Target *TheTarget =
nullptr;
536 if(!TheTriple.isX86()) {
537 Diag(AsmLoc, diag::err_msasm_unsupported_arch) << TheTriple.getArchName();
540TheTarget = llvm::TargetRegistry::lookupTarget(TT, Error);
542 Diag(AsmLoc, diag::err_msasm_unable_to_create_target) <<
Error;
545assert(!LBraceLocs.empty() &&
"Should have at least one location here");
548 autoEmptyStmt = [&] {
549 returnActions.
ActOnMSAsmStmt(AsmLoc, LBraceLocs[0], AsmToks, AsmString,
551ConstraintRefs, ClobberRefs, Exprs, EndLoc);
555 if(!TheTarget || AsmToks.empty()) {
565std::string FeaturesStr =
568std::unique_ptr<llvm::MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TT));
570 Diag(AsmLoc, diag::err_msasm_unable_to_create_target)
571<<
"target MC unavailable";
575llvm::MCTargetOptions MCOptions;
576std::unique_ptr<llvm::MCAsmInfo> MAI(
577TheTarget->createMCAsmInfo(*MRI, TT, MCOptions));
579std::unique_ptr<llvm::MCInstrInfo> MII(TheTarget->createMCInstrInfo());
580std::unique_ptr<llvm::MCSubtargetInfo> STI(
581TheTarget->createMCSubtargetInfo(TT, TO.
CPU, FeaturesStr));
584 if(!MAI || !MII || !STI) {
585 Diag(AsmLoc, diag::err_msasm_unable_to_create_target)
586<<
"target MC unavailable";
590llvm::SourceMgr TempSrcMgr;
591llvm::MCContext Ctx(TheTriple, MAI.get(), MRI.get(), STI.get(), &TempSrcMgr);
592std::unique_ptr<llvm::MCObjectFileInfo> MOFI(
593TheTarget->createMCObjectFileInfo(Ctx,
false));
594Ctx.setObjectFileInfo(MOFI.get());
596std::unique_ptr<llvm::MemoryBuffer> Buffer =
597llvm::MemoryBuffer::getMemBuffer(AsmString,
"<MS inline asm>");
600TempSrcMgr.AddNewSourceBuffer(std::move(Buffer), llvm::SMLoc());
602std::unique_ptr<llvm::MCStreamer> Str(createNullStreamer(Ctx));
603std::unique_ptr<llvm::MCAsmParser>
Parser(
604createMCAsmParser(TempSrcMgr, Ctx, *Str.get(), *MAI));
606std::unique_ptr<llvm::MCTargetAsmParser> TargetParser(
607TheTarget->createMCAsmParser(*STI, *
Parser, *MII, MCOptions));
610 Diag(AsmLoc, diag::err_msasm_unable_to_create_target)
611<<
"target ASM parser unavailable";
615std::unique_ptr<llvm::MCInstPrinter> IP(
616TheTarget->createMCInstPrinter(llvm::Triple(TT), 1, *MAI, *MII, *MRI));
619 Parser->setAssemblerDialect(1);
620 Parser->setTargetParser(*TargetParser.get());
621 Parser->setParsingMSInlineAsm(
true);
622TargetParser->setParsingMSInlineAsm(
true);
624ClangAsmParserCallback Callback(*
this, AsmLoc, AsmString, AsmToks,
626TargetParser->setSemaCallback(&Callback);
627TempSrcMgr.setDiagHandler(ClangAsmParserCallback::DiagHandlerCallback,
632std::string AsmStringIR;
636 if(
Parser->parseMSInlineAsm(AsmStringIR, NumOutputs, NumInputs, OpExprs,
637Constraints, Clobbers, MII.get(), IP.get(),
643llvm::erase_if(Clobbers, [](
conststd::string &
C) {
644 return C==
"fpsr"||
C==
"mxcsr";
648ClobberRefs.insert(ClobberRefs.end(), Clobbers.begin(), Clobbers.end());
651 unsignedNumExprs = NumOutputs + NumInputs;
652ConstraintRefs.resize(NumExprs);
653Exprs.resize(NumExprs);
654 for(
unsignedi = 0, e = NumExprs; i != e; ++i) {
655 Expr*OpExpr =
static_cast<Expr*
>(OpExprs[i].first);
660 if(OpExprs[i].second)
664ConstraintRefs[i] = StringRef(Constraints[i]);
669 returnActions.
ActOnMSAsmStmt(AsmLoc, LBraceLocs[0], AsmToks, AsmStringIR,
670NumOutputs, NumInputs, ConstraintRefs,
671ClobberRefs, Exprs, EndLoc);
683boolParser::parseGNUAsmQualifierListOpt(GNUAsmQualifiers &AQ) {
685 constGNUAsmQualifiers::AQ A = getGNUAsmQualifier(Tok);
686 if(A == GNUAsmQualifiers::AQ_unspecified) {
687 if(Tok.
isNot(tok::l_paren)) {
694 if(AQ.setAsmQualifier(A))
696<< GNUAsmQualifiers::getQualifierName(A);
721StmtResultParser::ParseAsmStatement(
bool&msAsm) {
722assert(Tok.
is(tok::kw_asm) &&
"Not an asm stmt");
725 if(
getLangOpts().AsmBlocks && !isGCCAsmStatement(Tok)) {
727 returnParseMicrosoftAsmStatement(AsmLoc);
731GNUAsmQualifiers GAQ;
732 if(parseGNUAsmQualifierListOpt(GAQ))
735 if(GAQ.isGoto() &&
getLangOpts().SpeculativeLoadHardening)
736 Diag(
Loc, diag::warn_slh_does_not_support_asm_goto);
741 ExprResultAsmString(ParseAsmStringLiteral(
false));
745 if(!(
getLangOpts().GNUAsm || AsmString.isInvalid())) {
746 const auto*SL = cast<StringLiteral>(AsmString.get());
747 if(!SL->getString().trim().empty())
748 Diag(
Loc, diag::err_gnu_inline_asm_disabled);
751 if(AsmString.isInvalid()) {
758ExprVector Constraints;
762 if(Tok.
is(tok::r_paren)) {
766AsmLoc,
true, GAQ.isVolatile(),
7670,
0,
nullptr, Constraints, Exprs,
768AsmString.get(), Clobbers,
0,
T.getCloseLocation());
772 boolAteExtraColon =
false;
773 if(Tok.
is(tok::colon) || Tok.
is(tok::coloncolon)) {
775AteExtraColon = Tok.
is(tok::coloncolon);
778 if(!AteExtraColon && ParseAsmOperandsOpt(Names, Constraints, Exprs))
782 unsignedNumOutputs = Names.size();
785 if(AteExtraColon || Tok.
is(tok::colon) || Tok.
is(tok::coloncolon)) {
788AteExtraColon =
false;
790AteExtraColon = Tok.
is(tok::coloncolon);
794 if(!AteExtraColon && ParseAsmOperandsOpt(Names, Constraints, Exprs))
798assert(Names.size() == Constraints.size() &&
799Constraints.size() == Exprs.size() &&
"Input operand size mismatch!");
801 unsignedNumInputs = Names.size() - NumOutputs;
804 if(AteExtraColon || Tok.
is(tok::colon) || Tok.
is(tok::coloncolon)) {
806AteExtraColon =
false;
808AteExtraColon = Tok.
is(tok::coloncolon);
812 if(!AteExtraColon && isTokenStringLiteral()) {
814 ExprResultClobber(ParseAsmStringLiteral(
false));
816 if(Clobber.isInvalid())
819Clobbers.push_back(Clobber.get());
826 if(!GAQ.isGoto() && (Tok.
isNot(tok::r_paren) || AteExtraColon)) {
827 Diag(Tok, diag::err_expected) << tok::r_paren;
833 unsignedNumLabels = 0;
834 if(AteExtraColon || Tok.
is(tok::colon)) {
839 if(Tok.
isNot(tok::identifier)) {
840 Diag(Tok, diag::err_expected) << tok::identifier;
853Exprs.push_back(Res.
get());
859}
else if(GAQ.isGoto()) {
860 Diag(Tok, diag::err_expected) << tok::colon;
865 returnActions.
ActOnGCCAsmStmt(AsmLoc,
false, GAQ.isVolatile(), NumOutputs,
866NumInputs, Names.data(), Constraints, Exprs,
867AsmString.get(), Clobbers, NumLabels,
868 T.getCloseLocation());
888 if(!isTokenStringLiteral() && Tok.
isNot(tok::l_square))
893 if(Tok.
is(tok::l_square)) {
897 if(Tok.
isNot(tok::identifier)) {
898 Diag(Tok, diag::err_expected) << tok::identifier;
909Names.push_back(
nullptr);
911 ExprResultConstraint(ParseAsmStringLiteral(
false));
912 if(Constraint.isInvalid()) {
916Constraints.push_back(Constraint.get());
918 if(Tok.
isNot(tok::l_paren)) {
919 Diag(Tok, diag::err_expected_lparen_after) <<
"asm operand";
933Exprs.push_back(Res.
get());
940const char*Parser::GNUAsmQualifiers::getQualifierName(AQ Qualifier) {
942 caseAQ_volatile:
return "volatile";
943 caseAQ_inline:
return "inline";
944 caseAQ_goto:
return "goto";
945 caseAQ_unspecified:
return "unspecified";
947llvm_unreachable(
"Unknown GNUAsmQualifier");
950Parser::GNUAsmQualifiers::AQ
951Parser::getGNUAsmQualifier(
const Token&Tok)
const{
953 casetok::kw_volatile:
returnGNUAsmQualifiers::AQ_volatile;
954 casetok::kw_inline:
returnGNUAsmQualifiers::AQ_inline;
955 casetok::kw_goto:
returnGNUAsmQualifiers::AQ_goto;
956 default:
returnGNUAsmQualifiers::AQ_unspecified;
959boolParser::GNUAsmQualifiers::setAsmQualifier(AQ Qualifier) {
Defines the clang::ASTContext interface.
Defines the Diagnostic-related interfaces.
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.
const TargetInfo & getTargetInfo() const
RAII class that helps handle the parsing of an open/close delimiter pair, such as braces { ....
Represents a C++ nested-name-specifier or a global scope specifier.
This represents one expression.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
One of these records is kept for each identifier that is lexed.
Represents the declaration of a label.
Parser - This implements a parser for the C family of languages.
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.
bool TryConsumeToken(tok::TokenKind Expected)
Scope * getCurScope() const
bool SkipUntil(tok::TokenKind T, SkipUntilFlags Flags=static_cast< SkipUntilFlags >(0))
SkipUntil - Read tokens until we get to the specified token, then consume it (unless StopBeforeMatch ...
const LangOptions & getLangOpts() const
ExprResult ParseExpression(TypeCastState isTypeCast=NotTypeCast)
Simple precedence-based parser for binary/ternary operators.
@ StopAtSemi
Stop skipping at semicolon.
const Token & NextToken()
NextToken - This peeks ahead one token and returns it without consuming it.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
void Lex(Token &Result)
Lex the next token for this preprocessor.
const Token & LookAhead(unsigned N)
Peeks ahead N tokens and returns that token without consuming any tokens.
SourceManager & getSourceManager() const
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.
The collection of all-type qualifiers we support.
StmtResult ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc, ArrayRef< Token > AsmToks, StringRef AsmString, unsigned NumOutputs, unsigned NumInputs, ArrayRef< StringRef > Constraints, ArrayRef< StringRef > Clobbers, ArrayRef< Expr * > Exprs, SourceLocation EndLoc)
ExprResult LookupInlineAsmIdentifier(CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Id, bool IsUnevaluatedContext)
ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *Input, bool IsAfterAmp=false)
ExprResult ActOnAddrLabel(SourceLocation OpLoc, SourceLocation LabLoc, LabelDecl *TheDecl)
ActOnAddrLabel - Parse the GNU address of label extension: "&&foo".
void FillInlineAsmIdentifierInfo(Expr *Res, llvm::InlineAsmIdentifierInfo &Info)
bool LookupInlineAsmField(StringRef Base, StringRef Member, unsigned &Offset, SourceLocation AsmLoc)
LabelDecl * LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc, SourceLocation GnuLabelLoc=SourceLocation())
LookupOrCreateLabel - Do a name lookup of a label with the specified name.
ExprResult LookupInlineAsmVarDeclField(Expr *RefExpr, StringRef Member, SourceLocation AsmLoc)
LabelDecl * GetOrCreateMSAsmLabel(StringRef ExternalLabelName, SourceLocation Location, bool AlwaysCreate)
ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, bool RecoverUncorrectedTypos=false, llvm::function_ref< ExprResult(Expr *)> Filter=[](Expr *E) -> ExprResult { return E;})
Process any TypoExprs in the given Expr and its children, generating diagnostics as appropriate and r...
StmtResult ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, bool IsVolatile, unsigned NumOutputs, unsigned NumInputs, IdentifierInfo **Names, MultiExprArg Constraints, MultiExprArg Exprs, Expr *AsmString, MultiExprArg Clobbers, unsigned NumLabels, SourceLocation RParenLoc)
Encodes a location in the source.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
unsigned getLineNumber(FileID FID, unsigned FilePos, bool *Invalid=nullptr) const
Given a SourceLocation, return the spelling line number for the position indicated.
std::pair< FileID, unsigned > getDecomposedExpansionLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
TargetOptions & getTargetOpts() const
Retrieve the target options.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Options for controlling the target.
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 hasLeadingSpace() const
Return true if this token has whitespace before it.
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.
@ 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
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4