Skip to content

[flang] Allow macro replacement in numeric kind suffix #132120

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 26, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 39 additions & 26 deletions flang/lib/Parser/prescan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -720,8 +720,8 @@ bool Prescanner::NextToken(TokenSequence &tokens) {
} else if (*at_ == '.') {
while (IsDecimalDigit(EmitCharAndAdvance(tokens, *at_))) {
}
ExponentAndKind(tokens);
} else if (ExponentAndKind(tokens)) {
HandleExponentAndOrKindSuffix(tokens);
} else if (HandleExponentAndOrKindSuffix(tokens)) {
} else if (digits == 1 && n == 0 && (*at_ == 'x' || *at_ == 'X') &&
inPreprocessorDirective_) {
do {
Expand All @@ -743,7 +743,7 @@ bool Prescanner::NextToken(TokenSequence &tokens) {
if (!inPreprocessorDirective_ && IsDecimalDigit(nch)) {
while (IsDecimalDigit(EmitCharAndAdvance(tokens, *at_))) {
}
ExponentAndKind(tokens);
HandleExponentAndOrKindSuffix(tokens);
} else if (nch == '.' && EmitCharAndAdvance(tokens, '.') == '.') {
EmitCharAndAdvance(tokens, '.'); // variadic macro definition ellipsis
}
Expand Down Expand Up @@ -839,40 +839,53 @@ bool Prescanner::NextToken(TokenSequence &tokens) {
return true;
}

bool Prescanner::ExponentAndKind(TokenSequence &tokens) {
char ed{ToLowerCaseLetter(*at_)};
if (ed != 'e' && ed != 'd') {
return false;
}
// Do some look-ahead to ensure that this 'e'/'d' is an exponent,
// not the start of an identifier that could be a macro.
const char *p{at_};
if (int n{IsSpace(++p)}) {
p += n;
}
if (*p == '+' || *p == '-') {
if (int n{IsSpace(++p)}) {
p += n;
bool Prescanner::HandleExponent(TokenSequence &tokens) {
if (char ed{ToLowerCaseLetter(*at_)}; ed == 'e' || ed == 'd') {
// Do some look-ahead to ensure that this 'e'/'d' is an exponent,
// not the start of an identifier that could be a macro.
const char *p{SkipWhiteSpace(at_ + 1)};
if (*p == '+' || *p == '-') {
p = SkipWhiteSpace(p + 1);
}
if (IsDecimalDigit(*p)) { // it's an exponent
EmitCharAndAdvance(tokens, ed);
if (*at_ == '+' || *at_ == '-') {
EmitCharAndAdvance(tokens, *at_);
}
while (IsDecimalDigit(*at_)) {
EmitCharAndAdvance(tokens, *at_);
}
return true;
}
}
if (IsDecimalDigit(*p)) { // it's an exponent
EmitCharAndAdvance(tokens, ed);
if (*at_ == '+' || *at_ == '-') {
EmitCharAndAdvance(tokens, *at_);
return false;
}

bool Prescanner::HandleKindSuffix(TokenSequence &tokens) {
if (*at_ == '_' && IsLegalInIdentifier(*SkipWhiteSpace(at_ + 1))) {
EmitCharAndAdvance(tokens, *at_);
if (IsLegalIdentifierStart(*at_)) {
// The kind specifier might be a macro, so put it into its own token.
tokens.CloseToken();
}
while (IsDecimalDigit(*at_)) {
while (IsLegalInIdentifier(*at_)) {
EmitCharAndAdvance(tokens, *at_);
}
if (*at_ == '_') {
while (IsLegalInIdentifier(EmitCharAndAdvance(tokens, *at_))) {
}
}
return true;
} else {
return false;
}
}

bool Prescanner::HandleExponentAndOrKindSuffix(TokenSequence &tokens) {
bool hadExponent{HandleExponent(tokens)};
if (HandleKindSuffix(tokens)) {
return true;
} else {
return hadExponent;
}
}

void Prescanner::QuotedCharacterLiteral(
TokenSequence &tokens, const char *start) {
char quote{*at_};
Expand Down
4 changes: 3 additions & 1 deletion flang/lib/Parser/prescan.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,9 @@ class Prescanner {
const char *SkipWhiteSpaceAndCComments(const char *) const;
const char *SkipCComment(const char *) const;
bool NextToken(TokenSequence &);
bool ExponentAndKind(TokenSequence &);
bool HandleExponent(TokenSequence &);
bool HandleKindSuffix(TokenSequence &);
bool HandleExponentAndOrKindSuffix(TokenSequence &);
void QuotedCharacterLiteral(TokenSequence &, const char *start);
void Hollerith(TokenSequence &, int count, const char *start);
bool PadOutCharacterLiteral(TokenSequence &);
Expand Down
6 changes: 6 additions & 0 deletions flang/test/Preprocessing/kind-suffix.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
! RUN: %flang -E %s 2>&1 | FileCheck %s
#define n k
parameter(n=4)
!CHECK: print *,1_k
print *,1_n
end