Originally, `extern(C++, ident)` was implemented as introducing a scope,
importing C++ semantics into D, and was made a `ScopeDsymbol`.
Introducing a scope turned out to be a behavior that was problematic,
and users of `extern(C++)` just wanted to use D semantics and have the correct mangling.
Later on, `extern(C++, "namespace")` was implemented, which removed the introduction of a scope.
However, it was implemented within the existing `Nspace`,
basically hacking around the fact that `ScopeDsymbol` introduces a scope
and injecting the symbols in the parent scope.
This commit implements a new AST node, `CPPNamespaceDeclaration`, which is an `AttributeDeclaration`.
`AttributeDeclaration` are the way storage classes (e.g. `extern(C)` and `extern(C++, class|struct)` are implemented,
as well as declarations that apply to a scope without introducing one, such as `DeprecatedDeclaration`.
Since mangling is part of the function's external interface,
CTFE on the message is run during the first semantic pass.
Since `_scope` is set earlier than `semantic` is done on the attribute,
the full `CPPNamespaceDeclaration` needs to be stored in the `Scope`,
not just the resolved `Identifiers`.
Moreover, a few tweaks are required to `cppmangle` to make it work with the new AST structure.
Once the scoped version of `extern(C++, namespace)` is deprecated, the code can be greatly simplified.