<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Jan 27, 2010, at 6:48 AM, Sebastian Redl wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div>Hi,<br><br>I'm trying to clean up variable definition code. I've given VarDecl a<br>new method, isThisDeclarationADefinition(), and have implemented it thus:<br><br>VarDecl::DefinitionKind VarDecl::isThisDeclarationADefinition() const {<br> // C++ [basic.def]p2:<br> // A declaration is a definition unless [...] it contains the 'extern'<br> // specifier or a linkage-specification and neither an initializer<br>[...],<br> // it declares a static data member in a class declaration [...].<br> // C++ [temp.expl.spec]p15:<br> // An explicit specialization of a static data member of a template is a<br> // definition if the declaration includes an initializer; otherwise,<br>it is<br> // a declaration.<br> // FIXME: Exact C rules?<br> if (isStaticDataMember()) {<br> if (isOutOfLine() && (hasInit() ||<br> getTemplateSpecializationKind() != TSK_ExplicitSpecialization))<br> return Definition;<br> else<br> return DeclarationOnly;<br> }<br> if (hasInit())<br> return Definition;<br> // AST for 'extern "C" int foo;' is annotated with 'extern'.<br> if (hasExternalStorage())<br> return DeclarationOnly;<br><br> // Now, in C++, everything left is a definition, but in C, if this<br>variable<br> // is global, it is a tentative definition.<br> // FIXME: It's not a tentative definition if there's a known definite<br> // definition.<br> if (!getASTContext().getLang().CPlusPlus && isFileVarDecl())<br> return TentativeDefinition;<br><br> return Definition;<br>}<br><br>Are these semantics correct for C? </div></blockquote><div><br></div><div>They look correct to me, although (as you say below) you should double-check the tentative-definition semantics against isTentativeDefinition.</div><br><blockquote type="cite"><div>Can I have a standard quote? </div></blockquote><div><br></div><div>C99 6.9.2 sayeth:</div><div><br></div><div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 12px/normal Times; ">1<span class="Apple-tab-span" style="white-space:pre"> </span>If the declaration of an identifier for an object has file scope and an initializer, the declaration is an external definition for the identifier.</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 12px/normal Times; ">2<span class="Apple-tab-span" style="white-space:pre"> </span>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 <span style="font: 12.0px Courier"><b>static</b></span>, constitutes a <i>tentative definition</i>.</div></div><br><blockquote type="cite"><div>Are<br>global variables marked with __thread ever tentative definitions?<br></div></blockquote><div><br></div>I think they can be... they would just get a definition of 0 in each thread.</div><div><br><blockquote type="cite"><div>The current isTentativeDefinition() will return false if there is a<br>definite definition elsewhere in the file; I will fix this in my<br>implementation. Any other problems?<br></div></blockquote></div><div><br></div>I don't see any other issues. Thanks for working on this!<div><br><div><span class="Apple-tab-span" style="white-space:pre"> </span>- Doug</div></div></body></html>