[cfe-dev] Variable declaration/definition

Douglas Gregor dgregor at apple.com
Thu Jan 28 10:10:50 PST 2010


On Jan 27, 2010, at 6:48 AM, Sebastian Redl wrote:

> Hi,
> 
> I'm trying to clean up variable definition code. I've given VarDecl a
> new method, isThisDeclarationADefinition(), and have implemented it thus:
> 
> VarDecl::DefinitionKind VarDecl::isThisDeclarationADefinition() const {
>  // C++ [basic.def]p2:
>  //   A declaration is a definition unless [...] it contains the 'extern'
>  //   specifier or a linkage-specification and neither an initializer
> [...],
>  //   it declares a static data member in a class declaration [...].
>  // C++ [temp.expl.spec]p15:
>  //   An explicit specialization of a static data member of a template is a
>  //   definition if the declaration includes an initializer; otherwise,
> it is
>  //   a declaration.
>  // FIXME: Exact C rules?
>  if (isStaticDataMember()) {
>    if (isOutOfLine() && (hasInit() ||
>          getTemplateSpecializationKind() != TSK_ExplicitSpecialization))
>      return Definition;
>    else
>      return DeclarationOnly;
>  }
>  if (hasInit())
>    return Definition;
>  // AST for 'extern "C" int foo;' is annotated with 'extern'.
>  if (hasExternalStorage())
>    return DeclarationOnly;
> 
>  // Now, in C++, everything left is a definition, but in C, if this
> variable
>  // is global, it is a tentative definition.
>  // FIXME: It's not a tentative definition if there's a known definite
>  // definition.
>  if (!getASTContext().getLang().CPlusPlus && isFileVarDecl())
>    return TentativeDefinition;
> 
>  return Definition;
> }
> 
> Are these semantics correct for C?

They look correct to me, although (as you say below) you should double-check the tentative-definition semantics against isTentativeDefinition.

> Can I have a standard quote?

C99 6.9.2 sayeth:

1	If the declaration of an identifier for an object has file scope and an initializer, the declaration is an external definition for the identifier.
2	A declaration of an identifier for an object that has file scope without an initializer, and without a storage-class specifier or with the storage-class specifier static, constitutes a tentative definition.

> Are
> global variables marked with __thread ever tentative definitions?

I think they can be... they would just get a definition of 0 in each thread.

> The current isTentativeDefinition() will return false if there is a
> definite definition elsewhere in the file; I will fix this in my
> implementation. Any other problems?


I don't see any other issues. Thanks for working on this!

	- Doug
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20100128/0173bf7d/attachment.html>


More information about the cfe-dev mailing list