Consider:
```
version (A)
enum NS = "something";
else
enum NS = "something_else";
extern(C++, NS):
//...
```
In this example, the parser sees an identifier and assumes that to be the name for the namespace, rather than check if it's an expression that evaluates to a string.
I think it should attempt to evaluate the expression as a string.
It could be argued that may be ambiguous, but this isn't:
```
string GetNs() { version (A) { return "A"; } else { return "B"; } }
extern(C++, GetNs()):
```
There's also this:
```
alias NS = AliasSeq!("A", "B");
extern(C++, NS):
```
That is, do want `extern(C++, "A", "B")` in this case, but again, it looks like an identifier to the parser.
Various work-around constructions don't work:
```
version (A)
extern(C++, "A"):
else
extern(C++, "B"):
void f(); // <- f is not in any namespace, the externs are scoped inside the version cases
```
```
mixin(`extern(C++, "NS"):`);
void f(); // <- f is not namespaced; it seems the mixin statement has some sort of scope which the extern doesn't escape
```
One of the goals of the string namespace was that you could synthesise the name, so it really just needs to work with expressions.