<br><div class="gmail_quote"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div class="im">
> Since I noticed Doug commit PCH support for NamespaceDecl's the other day (week?), I thought I'd send an update to my last PCH patch. I've been sitting on this work for quite some time while I've been busy with other things.<br>

><br>
<br>
</div>Nifty.<br></blockquote><div><br>I've spent the morning addressing issues in the patch and had some questions, comments. I'm not sending up a new patch just yet, though.<br> </div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
I think we really need better tests. Due to PCH's laziness, it is extremely annoying to debug when it breaks, so small tests for each kind of declaration/statement/expression are important for catching problems quickly.<br>
</blockquote><div><br>Yes... it is very annoying to debug :)<br> </div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
We should keep the existing DECL_* constants in order, since each reshuffle is (unnecessary) breakage in backward-compatibility for the PCH format.<br></blockquote><div><br>I moved all of the constants down to the bottom (and reorganized a couple). <br>
 </div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">

I don't see why we should need this. We already have startDefinition()/completeDefinition(), which takes care of allocating the DefinitionData and linking it in.<br></blockquote><div><br>Removed. I was concerned about side effects, but after looking I don't think there are any. I'm still having problems understanding which classes should be serialized. More below.<br>
 <br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">

Please store/load fields in the PCH record in the same order as they occur in the corresponding AST; it makes it easier to verify that everything is there. In this case, BaseOfClass and Virtual should be swapped (the same goes for the reader).<br>
</blockquote><div><br>I think I've addressed all instances that you've pointed out, but haven't checked every decl yet. I wish there was an easier way to do this. Maybe I could use clang to dump the order of members...<br>
 </div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">

Why const-qualify the NestedNameSpecifier? You're just const_cast'ing it away anyway.<br></blockquote><div><br>It's a non-modifying operation. I was only const-casting it away because getPrefix() returns a non-const ptr. It's probably easier just to remove the const in the function that try to make NNS more const-friendly.<br>
 </div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Why not push all of the NestedNameSpecifiers onto a stack and then emit them in reverse order? That would make it far easier for the reader to reconstruct them properly, since the prefix will come before the nested-name-specifier itself.<br>


<br>
This won't work with nested-name-specifiers that have prefixes, because we see the nested-name-specifier before its prefix, and end up trying to build the nested-name-specifier backwards. Use the stack I mentioned previously to address this problem, and you can then get rid of the NNS/P dance, since the last nested-name-specifier you build will be the complete one.<br>
</blockquote><div><br>For some reason, I thought that trying to write this without a stack would be a better solution. Other than that no real reason. I'll rewrite this in the next day or two.<br> </div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">


FWIW, I've typically been ordering the Visit functions the same way as the Decl nodes are ordered in DeclNodes.def.<br></blockquote><div><br>Fair enough. Would it be worthwhile reordering all of the ObjC visitors too?<br>
 <br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Aside: anonymous namespaces are somewhat interesting for PCH, because we need to make sure that an anonymous namespace defined in the source file gets linked to an anonymous namespace defined in the PCH file, since they are effectively the same anonymous namespace. One fun way to test this is:<br>

<br>
  // In PCH:<br>
  namespace {<br>
    class X;<br>
  }<br>
<br>
  // In source file (that includes PCH):<br>
  namespace {<br>
    class X;<br>
  }<br></blockquote><div><br>I'll add this to the test tomorrow.<br> </div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">

+void PCHDeclReader::VisitCXXRecordDecl(CXXRecordDecl *D) {<br>
+  VisitRecordDecl(D);<br>
+  // Injected class names are, I think, actually empty.<br>
<br>
Yes, they are. Aside from making sure to get them into the right declaration context and link up their previous declaration chains, there shouldn't be much to serialize for them.<br>

<br>
isInjectedClassName() is the wrong check for this. Instead, PCHDeclWriter::VisitCXXRecordDecl should serialize all of the bits in the definition when D->getDefinition() == D, i.e., the declaration you're serializing is the definition.<br>
</blockquote><div><br>This is where I'm a little lost w.r.t. class decls, defs, and injected names... Here's my current understanding.<br><br>class C;    // call this CXXRecordDecl* decl;<br>class C { };  // call this CXXRecordDecl* def;<br>
// call C::C (the injected name) CXXRecordDecl *inj;<br><br>decl->getDefinition() == def<br>def->getDefinition() == def<br>decl in def->redeclarations() // pseduo python-ese<br>inj->getDefinition() == def // ???<br>
decl->DefinitionData == def->DefinitionData == inj->DefinitionData // ???<br>decl->DefiniotinData->Definition == def // ???<br><br>And then for a slightly different case, if C isn't defined (so def == inj == 0), then:<br>
decl->getDefinition() == 0?<br><br>Is this about right or is there something I might be missing?<br><br>Also, w.r.t. class serialization. Should virtual bases be serialized the same way that regular bases are serialized? What b<br>
<br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">

+void PCHDeclReader::VisitCXXConstructorDecl(CXXConstructorDecl *D) {<br>
+  VisitCXXMethodDecl(D);<br>
+  D->setExplicitSpecified(Record[Idx++]);<br>
+  if (D->isThisDeclarationADefinition())<br>
+    D->setImplicitlyDefined(Record[Idx++]);<br>
+  // FIXME: Serialize member initializers?<br>
+}<br>
<br>
I suggest that the PCH reader/writer avoid cleverness, and serialize exactly what is in the AST (rather than doing the isThisDeclarationADefinition() check).<br></blockquote><div><br>This is a problem since isImplicitlyDefined and setImplicitlyDefined will assert if isThisDeclarationADefintion returns false. Would it be an acceptable workaround to add non-asserting accessors? </div>
<br>Back to work...<br></div><br>Andrew Sutton<br><a href="mailto:andrew.n.sutton@gmail.com">andrew.n.sutton@gmail.com</a><br>