__declspec(selectany): adding an attribute to a declvar

Hi. I'm trying to add support for Microsoft's __declspec(selectany) to
the frontend. (Backend stuff will come later.)

I've added the attribute to the AST, but I'm tightening up the checking.
The attribute should only be added to global data initializations that
have external visibility. So this is ok:

  __declspec(selectany) int t1 = 4; // OK

But this is not:

  __declspec(selectany) int t2; // ERROR, not initializer

I add the attribute to the decl in Sema::ProcessDeclAttributeList, where
I can check that the decl is global && (non-const || external). But
checking for an initializer is a problem because the initializer doesn't
get added to the decl until Sema::AddInitializerToDecl, which is called
later.

Any ideas how I should handle this?

Thanks,

I think you're looking for Sema::ActOnUninitializedDecl.

-Eli

So this is ok:

__declspec(selectany) int t1 = 4; // OK

But this is not:

__declspec(selectany) int t2; // ERROR, not initializer

<snip>

Any ideas how I should handle this?

I think you're looking for Sema::ActOnUninitializedDecl.

Thanks, Eli. That's worked like a charm. But no good deed goes
unpunished, so here's my next question.

I need to be able to handle cases where the "extern" appears on a
forward declaration, like this:

extern const int x4;
const __declspec(selectany) int x4=4;

If I check the storage class in Sema::ProcessDeclAttributeList, it
doesn't show up as extern in this case. I need to check the storage
class somewhere else. Any ideas where?

If you are looking for the presence of the "extern" keyword specifically, you can walk the chain of previous declarations with getPreviousDeclaration() and check for the "extern" storage class.

Or, more likely, it's a question of external linkage, in which case you'll want to use NamedDecl::getLinkage() to check for external linkage.

  - Doug

I need to be able to handle cases where the "extern" appears on a
forward declaration, like this:

extern const int x4;
const __declspec(selectany) int x4=4;

If I check the storage class in Sema::ProcessDeclAttributeList, it
doesn't show up as extern in this case. I need to check the storage
class somewhere else. Any ideas where?

If you are looking for the presence of the "extern" keyword specifically, you can walk the chain of previous declarations with getPreviousDeclaration() and check for the "extern" storage class.

Tried that. It doesn't work because the declaration chain isn't set up
until MergeVarDecl gets called, which is later. Blech.

Or, more likely, it's a question of external linkage, in which case you'll want to use NamedDecl::getLinkage() to check for external linkage.

Yeah, prolly.

Yeah, some attributes will have to have their well-formedness checked after declaration merging.

  - Doug