Skip to content

Commit

Permalink
[dcl.type.simple] Factor out decltype(e) wording into its own subclause.
Browse files Browse the repository at this point in the history
  • Loading branch information
zygoloid committed Nov 25, 2018
1 parent 4cc61d4 commit 9b52553
Showing 1 changed file with 108 additions and 107 deletions.
215 changes: 108 additions & 107 deletions source/declarations.tex
Original file line number Diff line number Diff line change
Expand Up @@ -1258,6 +1258,8 @@
\nontermdef{simple-type-specifier}\br
\opt{nested-name-specifier} type-name\br
nested-name-specifier \terminal{template} simple-template-id\br
decltype-specifier\br
placeholder-type-specifier\br
\opt{nested-name-specifier} template-name\br
\terminal{char}\br
\terminal{char8_t}\br
Expand All @@ -1272,27 +1274,14 @@
\terminal{unsigned}\br
\terminal{float}\br
\terminal{double}\br
\terminal{void}\br
decltype-specifier\br
placeholder-type-specifier
\terminal{void}
\end{bnf}

\begin{bnf}
\nontermdef{type-name}\br
class-name\br
enum-name\br
typedef-name\br
\end{bnf}

\begin{bnf}
\nontermdef{decltype-specifier}\br
\terminal{decltype} \terminal{(} expression \terminal{)}
\end{bnf}

\begin{bnf}
\nontermdef{placeholder-type-specifier}\br
\opt{type-constraint} \terminal{auto}\br
\opt{type-constraint} \terminal{decltype} \terminal{(} \terminal{auto} \terminal{)}
typedef-name
\end{bnf}

\pnum
Expand All @@ -1310,8 +1299,6 @@
\indextext{type specifier!\idxcode{float}}%
\indextext{type specifier!\idxcode{double}}%
\indextext{type specifier!\idxcode{void}}%
\indextext{type specifier!\idxcode{auto}}%
\indextext{type specifier!\idxcode{decltype}}%
\indextext{\idxgram{type-name}}%
\indextext{\idxgram{lambda-introducer}}%
A \grammarterm{placeholder-type-specifier}
Expand Down Expand Up @@ -1342,7 +1329,10 @@
\hdstyle{Specifier(s)} & \hdstyle{Type} \\ \capsep
\grammarterm{type-name} & the type named \\
\grammarterm{simple-template-id} & the type as defined in~\ref{temp.names}\\
\grammarterm{template-name} & placeholder for a type to be deduced\\
\grammarterm{decltype-specifier} & the type as defined in~\ref{dcl.type.decltype}\\
\grammarterm{placeholder-type-specifier}
& the type as defined in~\ref{dcl.spec.auto}\\
\grammarterm{template-name} & the type as defined in~\ref{dcl.type.class.deduct}\\
\tcode{char} & ``\tcode{char}'' \\
\tcode{unsigned char} & ``\tcode{unsigned char}'' \\
\tcode{signed char} & ``\tcode{signed char}'' \\
Expand Down Expand Up @@ -1378,10 +1368,6 @@
\tcode{double} & ``\tcode{double}'' \\
\tcode{long double} & ``\tcode{long double}'' \\
\tcode{void} & ``\tcode{void}'' \\
\tcode{decltype(}\grammarterm{expression}\tcode{)}
& the type as defined below\\
\grammarterm{placeholder-type-specifier}
& placeholder for a type to be deduced\\
\end{simpletypetable}

\pnum
Expand All @@ -1393,6 +1379,100 @@
forces \tcode{char} objects to be signed; it is redundant in other contexts.
\end{note}

\rSec3[dcl.type.elab]{Elaborated type specifiers}%
\indextext{type specifier!elaborated}%
\indextext{\idxcode{typename}}%
\indextext{type specifier!\idxcode{enum}}

\begin{bnf}
\nontermdef{elaborated-type-specifier}\br
class-key \opt{attribute-specifier-seq} \opt{nested-name-specifier} identifier\br
class-key simple-template-id\br
class-key nested-name-specifier \opt{\terminal{template}} simple-template-id\br
\terminal{enum} \opt{nested-name-specifier} identifier
\end{bnf}

\pnum
\indextext{class name!elaborated}%
\indextext{name!elaborated!\idxcode{enum}}%
An \grammarterm{attribute-specifier-seq} shall not appear in an \grammarterm{elaborated-type-specifier}
unless the latter is the sole constituent of a declaration.
If an \grammarterm{elaborated-type-specifier} is the sole constituent of a
declaration, the declaration is ill-formed unless it is an explicit
specialization\iref{temp.expl.spec}, an explicit
instantiation\iref{temp.explicit} or it has one of the following
forms:

\begin{ncsimplebnf}
class-key \opt{attribute-specifier-seq} identifier \terminal{;}\br
\terminal{friend} class-key \terminal{\opt{::}} identifier \terminal{;}\br
\terminal{friend} class-key \terminal{\opt{::}} simple-template-id \terminal{;}\br
\terminal{friend} class-key nested-name-specifier identifier \terminal{;}\br
\terminal{friend} class-key nested-name-specifier \terminal{\opt{template}} simple-template-id \terminal{;}
\end{ncsimplebnf}

In the first case, the \grammarterm{attribute-specifier-seq}, if any, appertains
to the class being declared; the attributes in the
\grammarterm{attribute-specifier-seq} are thereafter considered attributes of
the class whenever it is named.

\pnum
\begin{note}
\ref{basic.lookup.elab} describes how name lookup proceeds for the
\grammarterm{identifier} in an \grammarterm{elaborated-type-specifier}.
\end{note}
If the \grammarterm{identifier} or \grammarterm{simple-template-id}
resolves to a \grammarterm{class-name} or
\grammarterm{enum-name}, the \grammarterm{elaborated-type-specifier}
introduces it into the declaration the same way a
\grammarterm{simple-type-specifier} introduces
its \grammarterm{type-name}\iref{dcl.type.simple}.
If the \grammarterm{identifier} or \grammarterm{simple-template-id} resolves to a
\grammarterm{typedef-name} (\ref{dcl.typedef}, \ref{temp.names}),
the \grammarterm{elaborated-type-specifier} is ill-formed.
\begin{note}
This implies that, within a class template with a template
\grammarterm{type-parameter} \tcode{T}, the declaration

\begin{codeblock}
friend class T;
\end{codeblock}

is ill-formed. However, the similar declaration \tcode{friend T;} is allowed\iref{class.friend}.
\end{note}

\pnum
The \grammarterm{class-key} or \tcode{enum} keyword
present in the
\grammarterm{elaborated-type-specifier} shall agree in kind with the
declaration to which the name in the
\grammarterm{elaborated-type-specifier} refers. This rule also applies to
the form of \grammarterm{elaborated-type-specifier} that declares a
\grammarterm{class-name} or friend class since it can be construed
as referring to the definition of the class. Thus, in any
\grammarterm{elaborated-type-specifier}, the \tcode{enum} keyword
shall be
used to refer to an enumeration\iref{dcl.enum}, the \tcode{union}
\grammarterm{class-key} shall be used to refer to a union\iref{class},
and either the \tcode{class} or \tcode{struct}
\grammarterm{class-key} shall be used to refer to a class\iref{class}
declared using the \tcode{class} or \tcode{struct}
\grammarterm{class-key}. \begin{example}

\begin{codeblock}
enum class E { a, b };
enum E x = E::a; // OK
\end{codeblock}
\end{example}

\rSec3[dcl.type.decltype]{Decltype specifiers}%
\indextext{type specifier!\idxcode{decltype}}%

\begin{bnf}
\nontermdef{decltype-specifier}\br
\terminal{decltype} \terminal{(} expression \terminal{)}
\end{bnf}

\pnum
\indextext{type specifier!\idxcode{decltype}}%
For an expression \tcode{e}, the type denoted by \tcode{decltype(e)} is defined as follows:
Expand Down Expand Up @@ -1497,95 +1577,16 @@
\end{codeblock}
\end{example}

\rSec3[dcl.type.elab]{Elaborated type specifiers}%
\indextext{type specifier!elaborated}%
\indextext{\idxcode{typename}}%
\indextext{type specifier!\idxcode{enum}}
\rSec3[dcl.spec.auto]{Placeholder type specifiers}%
\indextext{type specifier!\idxcode{auto}}
\indextext{type specifier!\idxcode{decltype(auto)}}%

\begin{bnf}
\nontermdef{elaborated-type-specifier}\br
class-key \opt{attribute-specifier-seq} \opt{nested-name-specifier} identifier\br
class-key simple-template-id\br
class-key nested-name-specifier \opt{\terminal{template}} simple-template-id\br
\terminal{enum} \opt{nested-name-specifier} identifier
\nontermdef{placeholder-type-specifier}\br
\opt{type-constraint} \terminal{auto}\br
\opt{type-constraint} \terminal{decltype} \terminal{(} \terminal{auto} \terminal{)}
\end{bnf}

\pnum
\indextext{class name!elaborated}%
\indextext{name!elaborated!\idxcode{enum}}%
An \grammarterm{attribute-specifier-seq} shall not appear in an \grammarterm{elaborated-type-specifier}
unless the latter is the sole constituent of a declaration.
If an \grammarterm{elaborated-type-specifier} is the sole constituent of a
declaration, the declaration is ill-formed unless it is an explicit
specialization\iref{temp.expl.spec}, an explicit
instantiation\iref{temp.explicit} or it has one of the following
forms:

\begin{ncsimplebnf}
class-key \opt{attribute-specifier-seq} identifier \terminal{;}\br
\terminal{friend} class-key \terminal{\opt{::}} identifier \terminal{;}\br
\terminal{friend} class-key \terminal{\opt{::}} simple-template-id \terminal{;}\br
\terminal{friend} class-key nested-name-specifier identifier \terminal{;}\br
\terminal{friend} class-key nested-name-specifier \terminal{\opt{template}} simple-template-id \terminal{;}
\end{ncsimplebnf}

In the first case, the \grammarterm{attribute-specifier-seq}, if any, appertains
to the class being declared; the attributes in the
\grammarterm{attribute-specifier-seq} are thereafter considered attributes of
the class whenever it is named.

\pnum
\begin{note}
\ref{basic.lookup.elab} describes how name lookup proceeds for the
\grammarterm{identifier} in an \grammarterm{elaborated-type-specifier}.
\end{note}
If the \grammarterm{identifier} or \grammarterm{simple-template-id}
resolves to a \grammarterm{class-name} or
\grammarterm{enum-name}, the \grammarterm{elaborated-type-specifier}
introduces it into the declaration the same way a
\grammarterm{simple-type-specifier} introduces
its \grammarterm{type-name}\iref{dcl.type.simple}.
If the \grammarterm{identifier} or \grammarterm{simple-template-id} resolves to a
\grammarterm{typedef-name} (\ref{dcl.typedef}, \ref{temp.names}),
the \grammarterm{elaborated-type-specifier} is ill-formed.
\begin{note}
This implies that, within a class template with a template
\grammarterm{type-parameter} \tcode{T}, the declaration

\begin{codeblock}
friend class T;
\end{codeblock}

is ill-formed. However, the similar declaration \tcode{friend T;} is allowed\iref{class.friend}.
\end{note}

\pnum
The \grammarterm{class-key} or \tcode{enum} keyword
present in the
\grammarterm{elaborated-type-specifier} shall agree in kind with the
declaration to which the name in the
\grammarterm{elaborated-type-specifier} refers. This rule also applies to
the form of \grammarterm{elaborated-type-specifier} that declares a
\grammarterm{class-name} or friend class since it can be construed
as referring to the definition of the class. Thus, in any
\grammarterm{elaborated-type-specifier}, the \tcode{enum} keyword
shall be
used to refer to an enumeration\iref{dcl.enum}, the \tcode{union}
\grammarterm{class-key} shall be used to refer to a union\iref{class},
and either the \tcode{class} or \tcode{struct}
\grammarterm{class-key} shall be used to refer to a class\iref{class}
declared using the \tcode{class} or \tcode{struct}
\grammarterm{class-key}. \begin{example}

\begin{codeblock}
enum class E { a, b };
enum E x = E::a; // OK
\end{codeblock}
\end{example}

\rSec3[dcl.spec.auto]{The \tcode{auto} specifier}%
\indextext{type specifier!\idxcode{auto}}

\pnum
A \grammarterm{placeholder-type-specifier}
designates a placeholder type that will be replaced later by deduction
Expand Down

0 comments on commit 9b52553

Please sign in to comment.