diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md --- a/flang/docs/Extensions.md +++ b/flang/docs/Extensions.md @@ -82,13 +82,14 @@ * `$` and `@` as legal characters in names * Initialization in type declaration statements using `/values/` * Kind specification with `*`, e.g. `REAL*4` -* `DOUBLE COMPLEX` +* `DOUBLE COMPLEX` as a synonym for `COMPLEX(KIND(0.D0))` -- + but not when spelled `TYPE(DOUBLECOMPLEX)`. * Signed complex literal constants * DEC `STRUCTURE`, `RECORD`, with '%FILL'; but `UNION`, and `MAP` are not yet supported throughout compilation, and elicit a "not yet implemented" message. * Structure field access with `.field` -* `BYTE` as synonym for `INTEGER(KIND=1)` +* `BYTE` as synonym for `INTEGER(KIND=1)`; but not when spelled `TYPE(BYTE)`. * Quad precision REAL literals with `Q` * `X` prefix/suffix as synonym for `Z` on hexadecimal literals * `B`, `O`, `Z`, and `X` accepted as suffixes as well as prefixes diff --git a/flang/lib/Parser/Fortran-parsers.cpp b/flang/lib/Parser/Fortran-parsers.cpp --- a/flang/lib/Parser/Fortran-parsers.cpp +++ b/flang/lib/Parser/Fortran-parsers.cpp @@ -168,10 +168,13 @@ // for TYPE (...), rather than putting the alternatives within it, which // would fail on "TYPE(real_derived)" with a misrecognition of "real" as an // intrinsic-type-spec. +// N.B. TYPE(x) is a derived type if x is a one-word extension intrinsic +// type (BYTE or DOUBLECOMPLEX), not the extension intrinsic type. TYPE_CONTEXT_PARSER("declaration type spec"_en_US, construct(intrinsicTypeSpec) || "TYPE" >> - (parenthesized(construct(intrinsicTypeSpec)) || + (parenthesized(construct( + !"DOUBLECOMPLEX"_tok >> !"BYTE"_tok >> intrinsicTypeSpec)) || parenthesized(construct( construct(derivedTypeSpec))) || construct( @@ -209,7 +212,7 @@ "LOGICAL" >> maybe(kindSelector))), extension( "nonstandard usage: DOUBLE COMPLEX"_port_en_US, - construct("DOUBLE COMPLEX" >> + construct("DOUBLE COMPLEX"_sptok >> construct())), extension("nonstandard usage: BYTE"_port_en_US, construct(construct(