@@ -145,10 +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- }
151- CHECK (*at_ == ' !' );
148+ at_ += line.payloadOffset ;
149+ column_ += line.payloadOffset ;
152150 }
153151 std::optional<int > condOffset;
154152 if (directiveSentinel_[0 ] == ' $' && directiveSentinel_[1 ] == ' \0 ' ) {
@@ -597,6 +595,30 @@ const char *Prescanner::SkipWhiteSpace(const char *p) {
597595 return p;
598596}
599597
598+ const char *Prescanner::SkipWhiteSpaceIncludingEmptyMacros (
599+ const char *p) const {
600+ while (true ) {
601+ if (int n{IsSpaceOrTab (p)}) {
602+ p += n;
603+ } else if (preprocessor_.AnyDefinitions () && IsLegalIdentifierStart (*p)) {
604+ // Skip keyword macros with empty definitions
605+ const char *q{p + 1 };
606+ while (IsLegalInIdentifier (*q)) {
607+ ++q;
608+ }
609+ if (preprocessor_.IsNameDefinedEmpty (
610+ CharBlock{p, static_cast <std::size_t >(q - p)})) {
611+ p = q;
612+ } else {
613+ break ;
614+ }
615+ } else {
616+ break ;
617+ }
618+ }
619+ return p;
620+ }
621+
600622const char *Prescanner::SkipWhiteSpaceAndCComments (const char *p) const {
601623 while (true ) {
602624 if (int n{IsSpaceOrTab (p)}) {
@@ -1463,18 +1485,18 @@ Prescanner::IsFixedFormCompilerDirectiveLine(const char *start) const {
14631485 *sp = ' \0 ' ;
14641486 if (const char *ss{IsCompilerDirectiveSentinel (
14651487 sentinel, static_cast <std::size_t >(sp - sentinel))}) {
1466- std::size_t payloadOffset = p - start;
1467- return {LineClassification{
1468- LineClassification::Kind::CompilerDirective, payloadOffset, ss}};
1488+ return {
1489+ LineClassification{LineClassification::Kind::CompilerDirective, 0 , ss}};
14691490 }
14701491 return std::nullopt ;
14711492}
14721493
14731494std::optional<Prescanner::LineClassification>
14741495Prescanner::IsFreeFormCompilerDirectiveLine (const char *start) const {
1475- if (const char *p{SkipWhiteSpace (start)}; p && *p++ == ' !' ) {
1496+ if (const char *p{SkipWhiteSpaceIncludingEmptyMacros (start)};
1497+ p && *p++ == ' !' ) {
14761498 if (auto maybePair{IsCompilerDirectiveSentinel (p)}) {
1477- auto offset{static_cast <std::size_t >(maybePair-> second - start)};
1499+ auto offset{static_cast <std::size_t >(p - start - 1 )};
14781500 return {LineClassification{LineClassification::Kind::CompilerDirective,
14791501 offset, maybePair->first }};
14801502 }
@@ -1529,7 +1551,7 @@ Prescanner::IsCompilerDirectiveSentinel(const char *p) const {
15291551 if (int n{*p == ' &' ? 1 : IsSpaceOrTab (p)}) {
15301552 if (j > 0 ) {
15311553 sentinel[j] = ' \0 ' ;
1532- p = SkipWhiteSpace (p + n);
1554+ p = SkipWhiteSpaceIncludingEmptyMacros (p + n);
15331555 if (*p != ' !' ) {
15341556 if (const char *sp{IsCompilerDirectiveSentinel (sentinel, j)}) {
15351557 return std::make_pair (sp, p);
0 commit comments