@@ -145,9 +145,8 @@ void Prescanner::Statement() {
145145 if (inFixedForm_) {
146146 CHECK (IsFixedFormCommentChar (*at_));
147147 } else {
148- while (int n{IsSpaceOrTab (at_)}) {
149- at_ += n, ++column_;
150- }
148+ at_ += line.payloadOffset ;
149+ column_ += line.payloadOffset ;
151150 CHECK (*at_ == ' !' );
152151 }
153152 std::optional<int > condOffset;
@@ -597,6 +596,30 @@ const char *Prescanner::SkipWhiteSpace(const char *p) {
597596 return p;
598597}
599598
599+ const char *Prescanner::SkipWhiteSpaceIncludingEmptyMacros (
600+ const char *p) const {
601+ while (true ) {
602+ if (int n{IsSpaceOrTab (p)}) {
603+ p += n;
604+ } else if (preprocessor_.AnyDefinitions () && IsLegalIdentifierStart (*p)) {
605+ // Skip keyword macros with empty definitions
606+ const char *q{p + 1 };
607+ while (IsLegalInIdentifier (*q)) {
608+ ++q;
609+ }
610+ if (preprocessor_.IsNameDefinedEmpty (
611+ CharBlock{p, static_cast <std::size_t >(q - p)})) {
612+ p = q;
613+ } else {
614+ break ;
615+ }
616+ } else {
617+ break ;
618+ }
619+ }
620+ return p;
621+ }
622+
600623const char *Prescanner::SkipWhiteSpaceAndCComments (const char *p) const {
601624 while (true ) {
602625 if (int n{IsSpaceOrTab (p)}) {
@@ -1463,18 +1486,18 @@ Prescanner::IsFixedFormCompilerDirectiveLine(const char *start) const {
14631486 *sp = ' \0 ' ;
14641487 if (const char *ss{IsCompilerDirectiveSentinel (
14651488 sentinel, static_cast <std::size_t >(sp - sentinel))}) {
1466- std::size_t payloadOffset = p - start;
1467- return {LineClassification{
1468- LineClassification::Kind::CompilerDirective, payloadOffset, ss}};
1489+ return {
1490+ LineClassification{LineClassification::Kind::CompilerDirective, 0 , ss}};
14691491 }
14701492 return std::nullopt ;
14711493}
14721494
14731495std::optional<Prescanner::LineClassification>
14741496Prescanner::IsFreeFormCompilerDirectiveLine (const char *start) const {
1475- if (const char *p{SkipWhiteSpace (start)}; p && *p++ == ' !' ) {
1497+ if (const char *p{SkipWhiteSpaceIncludingEmptyMacros (start)};
1498+ p && *p++ == ' !' ) {
14761499 if (auto maybePair{IsCompilerDirectiveSentinel (p)}) {
1477- auto offset{static_cast <std::size_t >(maybePair-> second - start)};
1500+ auto offset{static_cast <std::size_t >(p - start - 1 )};
14781501 return {LineClassification{LineClassification::Kind::CompilerDirective,
14791502 offset, maybePair->first }};
14801503 }
@@ -1529,7 +1552,7 @@ Prescanner::IsCompilerDirectiveSentinel(const char *p) const {
15291552 if (int n{*p == ' &' ? 1 : IsSpaceOrTab (p)}) {
15301553 if (j > 0 ) {
15311554 sentinel[j] = ' \0 ' ;
1532- p = SkipWhiteSpace (p + n);
1555+ p = SkipWhiteSpaceIncludingEmptyMacros (p + n);
15331556 if (*p != ' !' ) {
15341557 if (const char *sp{IsCompilerDirectiveSentinel (sentinel, j)}) {
15351558 return std::make_pair (sp, p);
0 commit comments