[cfe-dev] Variable declaration/definition

Sebastian Redl sebastian.redl at getdesigned.at
Wed Jan 27 08:48:30 CST 2010


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? Can I have a standard quote? Are
global variables marked with __thread ever tentative definitions?
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?

Sebastian


More information about the cfe-dev mailing list