An identifier belongs to one of four different name spaces. Section 22.214.171.124 of the standard points out that the syntactic context determines the name space to which a particular identifier occurrence belongs. These contexts are distinguished in the abstract syntax tree by distinct names.
Each of the four name spaces has at least one defining occurrence and one applied occurrence. If an identifier in the label name space happens to also be declared as a typedef_name in the name space of ordinary identifiers, the scanner will classify it as a typedef_name instead of an identifier because the : that distinguishes the label context follows the identifier. Thus the identifier that is the defining occurrence of a label may have been classified as either a typedef_name or an identifier. (See Section 1.3 for the details of the classification task.)
Identifiers in the tag name space have more complex semantics, discussed in Section 126.96.36.199 of the standard. Some of the occurrences are always defining, others are always applied, but the characteristics of some may be influenced by constructs remotefrom their position. Further information can be found in Section 2.4.1.
Ordinary identifiers may denote objects or functions on the one hand, and types on the other. The semantics of objects and functions are quite different from the semantics of types, and therefore it is useful to separate object and function identifier occurrences from type identifier occurrences in the tree. Both defining and applied occurrences of type identifiers can be distinguished during scanning, so this is just a matter of assigning them distinct tree nodes.
A parameter_id is a defining ocurrence of an ordinary identifier in the parameter list of a function definition. This is a very special context present only to enable compilation of legacy programs.