Skip to content
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