Skip to content

Commit e94755f

Browse files
committed
[flang] Allow macro replacement in numeric kind suffix
When a numeric value has a kind suffix containing an identifier, allow macro replacement for that identifier by treating it as its own token. Fixes #131548.
1 parent 6aeae62 commit e94755f

File tree

3 files changed

+48
-28
lines changed

3 files changed

+48
-28
lines changed

flang/lib/Parser/prescan.cpp

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -720,8 +720,8 @@ bool Prescanner::NextToken(TokenSequence &tokens) {
720720
} else if (*at_ == '.') {
721721
while (IsDecimalDigit(EmitCharAndAdvance(tokens, *at_))) {
722722
}
723-
ExponentAndKind(tokens);
724-
} else if (ExponentAndKind(tokens)) {
723+
HandleExponentAndOrKindSuffix(tokens);
724+
} else if (HandleExponentAndOrKindSuffix(tokens)) {
725725
} else if (digits == 1 && n == 0 && (*at_ == 'x' || *at_ == 'X') &&
726726
inPreprocessorDirective_) {
727727
do {
@@ -743,7 +743,7 @@ bool Prescanner::NextToken(TokenSequence &tokens) {
743743
if (!inPreprocessorDirective_ && IsDecimalDigit(nch)) {
744744
while (IsDecimalDigit(EmitCharAndAdvance(tokens, *at_))) {
745745
}
746-
ExponentAndKind(tokens);
746+
HandleExponentAndOrKindSuffix(tokens);
747747
} else if (nch == '.' && EmitCharAndAdvance(tokens, '.') == '.') {
748748
EmitCharAndAdvance(tokens, '.'); // variadic macro definition ellipsis
749749
}
@@ -839,40 +839,52 @@ bool Prescanner::NextToken(TokenSequence &tokens) {
839839
return true;
840840
}
841841

842-
bool Prescanner::ExponentAndKind(TokenSequence &tokens) {
843-
char ed{ToLowerCaseLetter(*at_)};
844-
if (ed != 'e' && ed != 'd') {
845-
return false;
846-
}
847-
// Do some look-ahead to ensure that this 'e'/'d' is an exponent,
848-
// not the start of an identifier that could be a macro.
849-
const char *p{at_};
850-
if (int n{IsSpace(++p)}) {
851-
p += n;
852-
}
853-
if (*p == '+' || *p == '-') {
854-
if (int n{IsSpace(++p)}) {
855-
p += n;
842+
bool Prescanner::HandleExponent(TokenSequence &tokens) {
843+
if (char ed{ToLowerCaseLetter(*at_)}; ed == 'e' || ed == 'd') {
844+
// Do some look-ahead to ensure that this 'e'/'d' is an exponent,
845+
// not the start of an identifier that could be a macro.
846+
const char *p{SkipWhiteSpace(at_ + 1)};
847+
if (*p == '+' || *p == '-') {
848+
p = SkipWhiteSpace(p + 1);
849+
}
850+
if (IsDecimalDigit(*p)) { // it's an exponent
851+
EmitCharAndAdvance(tokens, ed);
852+
if (*at_ == '+' || *at_ == '-') {
853+
EmitCharAndAdvance(tokens, *at_);
854+
}
855+
while (IsDecimalDigit(*at_)) {
856+
EmitCharAndAdvance(tokens, *at_);
857+
}
858+
return true;
856859
}
857860
}
858-
if (IsDecimalDigit(*p)) { // it's an exponent
859-
EmitCharAndAdvance(tokens, ed);
860-
if (*at_ == '+' || *at_ == '-') {
861-
EmitCharAndAdvance(tokens, *at_);
862-
}
863-
while (IsDecimalDigit(*at_)) {
864-
EmitCharAndAdvance(tokens, *at_);
861+
return false;
862+
}
863+
864+
bool Prescanner::HandleKindSuffix(TokenSequence &tokens) {
865+
if (*at_ == '_' && IsLegalInIdentifier(*SkipWhiteSpace(at_ + 1))) {
866+
EmitCharAndAdvance(tokens, *at_);
867+
if (IsLegalIdentifierStart(*at_)) {
868+
// The kind specifier might be a macro, so put it into its own token.
869+
tokens.CloseToken();
865870
}
866-
if (*at_ == '_') {
867-
while (IsLegalInIdentifier(EmitCharAndAdvance(tokens, *at_))) {
868-
}
871+
while (IsLegalInIdentifier(EmitCharAndAdvance(tokens, *at_))) {
869872
}
870873
return true;
871874
} else {
872875
return false;
873876
}
874877
}
875878

879+
bool Prescanner::HandleExponentAndOrKindSuffix(TokenSequence &tokens) {
880+
bool hadExponent{HandleExponent(tokens)};
881+
if (HandleKindSuffix(tokens)) {
882+
return true;
883+
} else {
884+
return hadExponent;
885+
}
886+
}
887+
876888
void Prescanner::QuotedCharacterLiteral(
877889
TokenSequence &tokens, const char *start) {
878890
char quote{*at_};

flang/lib/Parser/prescan.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,9 @@ class Prescanner {
186186
const char *SkipWhiteSpaceAndCComments(const char *) const;
187187
const char *SkipCComment(const char *) const;
188188
bool NextToken(TokenSequence &);
189-
bool ExponentAndKind(TokenSequence &);
189+
bool HandleExponent(TokenSequence &);
190+
bool HandleKindSuffix(TokenSequence &);
191+
bool HandleExponentAndOrKindSuffix(TokenSequence &);
190192
void QuotedCharacterLiteral(TokenSequence &, const char *start);
191193
void Hollerith(TokenSequence &, int count, const char *start);
192194
bool PadOutCharacterLiteral(TokenSequence &);
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
! RUN: %flang -E %s 2>&1 | FileCheck %s
2+
#define n k
3+
parameter(n=4)
4+
!CHECK: print *,1_k
5+
print *,1_n
6+
end

0 commit comments

Comments
 (0)