Lines Matching full:first
87 /// Lexes next token and advances \p First and the \p Lexer.
89 lexToken(const char *&First, const char *const End);
92 lexIncludeFilename(const char *&First, const char *const End);
94 void skipLine(const char *&First, const char *const End);
95 void skipDirective(StringRef Name, const char *&First, const char *const End);
104 /// In any case (whatever the token kind) \p First and the \p Lexer will
107 tryLexIdentifierOrSkipLine(const char *&First, const char *const End);
110 [[nodiscard]] StringRef lexIdentifier(const char *&First,
116 /// In any case (whatever the token kind) \p First and the \p Lexer will
119 const char *&First,
125 /// In any case (whatever the token kind) \p First and the \p Lexer will
127 [[nodiscard]] bool isNextTokenOrSkipLine(tok::TokenKind K, const char *&First,
133 /// In any case (whatever the token kind) \p First and the \p Lexer will
136 tryLexStringLiteralOrSkipLine(const char *&First, const char *const End);
138 [[nodiscard]] bool scanImpl(const char *First, const char *const End);
139 [[nodiscard]] bool lexPPLine(const char *&First, const char *const End);
140 [[nodiscard]] bool lexAt(const char *&First, const char *const End);
141 [[nodiscard]] bool lexModule(const char *&First, const char *const End);
142 [[nodiscard]] bool lexDefine(const char *HashLoc, const char *&First,
144 [[nodiscard]] bool lexPragma(const char *&First, const char *const End);
145 [[nodiscard]] bool lex_Pragma(const char *&First, const char *const End);
146 [[nodiscard]] bool lexEndif(const char *&First, const char *const End);
147 [[nodiscard]] bool lexDefault(DirectiveKind Kind, const char *&First,
150 const char *&First,
152 void lexPPDirectiveBody(const char *&First, const char *const End);
204 static void skipOverSpaces(const char *&First, const char *const End) {
205 while (First != End && isHorizontalWhitespace(*First))
206 ++First;
209 [[nodiscard]] static bool isRawStringLiteral(const char *First,
211 assert(First <= Current);
214 if (*Current != '"' || First == Current)
221 if (First == Current || !isAsciiIdentifierContinue(*--Current))
226 return First == Current || !isAsciiIdentifierContinue(*--Current);
229 if (*Current != '8' || First == Current || *Current-- != 'u')
231 return First == Current || !isAsciiIdentifierContinue(*--Current);
234 static void skipRawString(const char *&First, const char *const End) {
235 assert(First[0] == '"');
236 assert(First[-1] == 'R');
238 const char *Last = ++First;
242 First = Last; // Hit the end... just give up.
246 StringRef Terminator(First, Last - First);
248 // Move First to just past the next ")".
249 First = Last;
250 while (First != End && *First != ')')
251 ++First;
252 if (First == End)
254 ++First;
257 Last = First;
258 while (Last != End && size_t(Last - First) < Terminator.size() &&
259 Terminator[Last - First] == *Last)
264 First = Last;
267 if (size_t(Last - First) < Terminator.size())
271 First = Last + 1;
277 static unsigned isEOL(const char *First, const char *const End) {
278 if (First == End)
280 if (End - First > 1 && isVerticalWhitespace(First[0]) &&
281 isVerticalWhitespace(First[1]) && First[0] != First[1])
283 return !!isVerticalWhitespace(First[0]);
286 static void skipString(const char *&First, const char *const End) {
287 assert(*First == '\'' || *First == '"' || *First == '<');
288 const char Terminator = *First == '<' ? '>' : *First;
289 for (++First; First != End && *First != Terminator; ++First) {
291 if (isVerticalWhitespace(*First))
293 if (*First != '\\')
298 if (++First == End)
300 if (!isWhitespace(*First))
303 const char *FirstAfterBackslashPastSpace = First;
308 First = FirstAfterBackslashPastSpace + NLSize - 1;
311 if (First != End)
312 ++First; // Finish off the string.
316 static unsigned skipNewline(const char *&First, const char *End) {
317 if (First == End)
319 assert(isVerticalWhitespace(*First));
320 unsigned Len = isEOL(First, End);
322 First += Len;
326 static bool wasLineContinuation(const char *First, unsigned EOLLen) {
327 return *(First - (int)EOLLen - 1) == '\\';
330 static void skipToNewlineRaw(const char *&First, const char *const End) {
332 if (First == End)
335 unsigned Len = isEOL(First, End);
340 if (++First == End)
342 Len = isEOL(First, End);
345 if (First[-1] != '\\')
348 First += Len;
353 static void skipLineComment(const char *&First, const char *const End) {
354 assert(First[0] == '/' && First[1] == '/');
355 First += 2;
356 skipToNewlineRaw(First, End);
359 static void skipBlockComment(const char *&First, const char *const End) {
360 assert(First[0] == '/' && First[1] == '*');
361 if (End - First < 4) {
362 First = End;
365 for (First += 3; First != End; ++First)
366 if (First[-1] == '*' && First[0] == '/') {
367 ++First;
396 void Scanner::skipLine(const char *&First, const char *const End) {
398 assert(First <= End);
399 if (First == End)
402 if (isVerticalWhitespace(*First)) {
403 skipNewline(First, End);
406 const char *Start = First;
407 while (First != End && !isVerticalWhitespace(*First)) {
409 if (*First == '"' ||
410 (*First == '\'' && !isQuoteCppDigitSeparator(Start, First, End))) {
411 LastTokenPtr = First;
412 if (isRawStringLiteral(Start, First))
413 skipRawString(First, End);
415 skipString(First, End);
420 if (*First != '/' || End - First < 2) {
421 LastTokenPtr = First;
422 ++First;
426 if (First[1] == '/') {
428 skipLineComment(First, End);
432 if (First[1] != '*') {
433 LastTokenPtr = First;
434 ++First;
439 skipBlockComment(First, End);
441 if (First == End)
445 unsigned Len = skipNewline(First, End);
446 if (!wasLineContinuation(First, Len)) // Continue past line-continuations.
451 void Scanner::skipDirective(StringRef Name, const char *&First,
458 skipToNewlineRaw(First, End);
460 skipLine(First, End);
463 static void skipWhitespace(const char *&First, const char *const End) {
465 assert(First <= End);
466 skipOverSpaces(First, End);
468 if (End - First < 2)
471 if (First[0] == '\\' && isVerticalWhitespace(First[1])) {
472 skipNewline(++First, End);
477 if (First[0] != '/')
481 if (First[1] == '/') {
482 skipLineComment(First, End);
487 if (First[1] != '*')
491 skipBlockComment(First, End);
495 bool Scanner::lexModuleDirectiveBody(DirectiveKind Kind, const char *&First,
499 const dependency_directives_scan::Token &Tok = lexToken(First, End);
508 skipWhitespace(First, End);
509 if (First == End)
511 if (!isVerticalWhitespace(*First))
514 skipNewline(First, End);
518 dependency_directives_scan::Token &Scanner::lexToken(const char *&First,
522 First = Input.data() + TheLexer.getCurrentBufferOffset();
523 assert(First <= End);
532 Scanner::lexIncludeFilename(const char *&First, const char *const End) {
535 First = Input.data() + TheLexer.getCurrentBufferOffset();
536 assert(First <= End);
544 void Scanner::lexPPDirectiveBody(const char *&First, const char *const End) {
546 const dependency_directives_scan::Token &Tok = lexToken(First, End);
574 .first->first();
578 Scanner::tryLexIdentifierOrSkipLine(const char *&First, const char *const End) {
579 const dependency_directives_scan::Token &Tok = lexToken(First, End);
582 skipLine(First, End);
589 StringRef Scanner::lexIdentifier(const char *&First, const char *const End) {
590 std::optional<StringRef> Id = tryLexIdentifierOrSkipLine(First, End);
595 bool Scanner::isNextIdentifierOrSkipLine(StringRef Id, const char *&First,
598 tryLexIdentifierOrSkipLine(First, End)) {
601 skipLine(First, End);
606 bool Scanner::isNextTokenOrSkipLine(tok::TokenKind K, const char *&First,
608 const dependency_directives_scan::Token &Tok = lexToken(First, End);
611 skipLine(First, End);
616 Scanner::tryLexStringLiteralOrSkipLine(const char *&First,
618 const dependency_directives_scan::Token &Tok = lexToken(First, End);
621 skipLine(First, End);
628 bool Scanner::lexAt(const char *&First, const char *const End) {
632 const dependency_directives_scan::Token &AtTok = lexToken(First, End);
636 if (!isNextIdentifierOrSkipLine("import", First, End))
638 return lexModuleDirectiveBody(decl_at_import, First, End);
641 bool Scanner::lexModule(const char *&First, const char *const End) {
642 StringRef Id = lexIdentifier(First, End);
646 std::optional<StringRef> NextId = tryLexIdentifierOrSkipLine(First, End);
653 skipLine(First, End);
657 skipWhitespace(First, End);
662 switch (*First) {
666 skipLine(First, End);
670 (void)lexToken(First, End);
671 if (!tryLexIdentifierOrSkipLine(First, End))
679 if (!isAsciiIdentifierContinue(*First)) {
680 skipLine(First, End);
685 TheLexer.seek(getOffsetAt(First), /*IsAtStartOfLine*/ false);
693 return lexModuleDirectiveBody(Kind, First, End);
696 bool Scanner::lex_Pragma(const char *&First, const char *const End) {
697 if (!isNextTokenOrSkipLine(tok::l_paren, First, End))
700 std::optional<StringRef> Str = tryLexStringLiteralOrSkipLine(First, End);
702 if (!Str || !isNextTokenOrSkipLine(tok::r_paren, First, End))
722 skipLine(First, End);
731 bool Scanner::lexPragma(const char *&First, const char *const End) {
732 std::optional<StringRef> FoundId = tryLexIdentifierOrSkipLine(First, End);
744 lexPPDirectiveBody(First, End);
750 skipLine(First, End);
754 FoundId = tryLexIdentifierOrSkipLine(First, End);
761 lexPPDirectiveBody(First, End);
767 skipLine(First, End);
772 if (!isNextIdentifierOrSkipLine("import", First, End))
776 lexPPDirectiveBody(First, End);
781 bool Scanner::lexEndif(const char *&First, const char *const End) {
794 skipLine(First, End);
798 return lexDefault(pp_endif, First, End);
801 bool Scanner::lexDefault(DirectiveKind Kind, const char *&First,
803 lexPPDirectiveBody(First, End);
808 static bool isStartOfRelevantLine(char First) {
809 switch (First) {
821 bool Scanner::lexPPLine(const char *&First, const char *const End) {
822 assert(First != End);
824 skipWhitespace(First, End);
825 assert(First <= End);
826 if (First == End)
829 if (!isStartOfRelevantLine(*First)) {
830 skipLine(First, End);
831 assert(First <= End);
835 LastTokenPtr = First;
837 TheLexer.seek(getOffsetAt(First), /*IsAtStartOfLine*/ true);
846 if (*First == '@')
847 return lexAt(First, End);
849 if (*First == 'i' || *First == 'e' || *First == 'm')
850 return lexModule(First, End);
852 if (*First == '_') {
853 if (isNextIdentifierOrSkipLine("_Pragma", First, End))
854 return lex_Pragma(First, End);
865 const dependency_directives_scan::Token &HashTok = lexToken(First, End);
870 skipLine(First, End);
871 assert(First <= End);
877 std::optional<StringRef> FoundId = tryLexIdentifierOrSkipLine(First, End);
884 return lexPragma(First, End);
903 skipDirective(Id, First, End);
908 return lexEndif(First, End);
916 if (lexIncludeFilename(First, End).is(tok::eod)) {
917 skipDirective(Id, First, End);
926 return lexDefault(Kind, First, End);
929 static void skipUTF8ByteOrderMark(const char *&First, const char *const End) {
930 if ((End - First) >= 3 && First[0] == '\xef' && First[1] == '\xbb' &&
931 First[2] == '\xbf')
932 First += 3;
935 bool Scanner::scanImpl(const char *First, const char *const End) {
936 skipUTF8ByteOrderMark(First, End);
937 while (First != End)
938 if (lexPPLine(First, End))