<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">I think I took care of all your feedback in <b><a href="http://llvm.org/viewvc/llvm-project?view=rev&revision=75849">http://llvm.org/viewvc/llvm-project?view=rev&revision=75849</a></b><div><b><br></b><div><b>Let me know if I missed something.</b></div><div><b><br class="webkit-block-placeholder"></b></div><div><b>- Thanks, Fariborz</b></div><div><b><br></b><div><div>On Jul 20, 2009, at 5:29 PM, Douglas Gregor wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><br>On Jul 15, 2009, at 3:34 PM, Fariborz Jahanian wrote:<br><br><blockquote type="cite">Author: fjahanian<br></blockquote><blockquote type="cite">Date: Wed Jul 15 17:34:08 2009<br></blockquote><blockquote type="cite">New Revision: 75849<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">URL: <a href="http://llvm.org/viewvc/llvm-project?rev=75849&view=rev">http://llvm.org/viewvc/llvm-project?rev=75849&view=rev</a><br></blockquote><blockquote type="cite">Log:<br></blockquote><blockquote type="cite">Added ASTs to destructor decl AST for default destruction of object's<br></blockquote><blockquote type="cite">base/members.<br></blockquote><br>Okay, some comments below.<br><br><blockquote type="cite">Modified:<br></blockquote><blockquote type="cite">   cfe/trunk/include/clang/AST/DeclCXX.h<br></blockquote><blockquote type="cite">   cfe/trunk/include/clang/Parse/Action.h<br></blockquote><blockquote type="cite">   cfe/trunk/lib/AST/DeclCXX.cpp<br></blockquote><blockquote type="cite">   cfe/trunk/lib/AST/DeclPrinter.cpp<br></blockquote><blockquote type="cite">   cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp<br></blockquote><blockquote type="cite">   cfe/trunk/lib/Parse/Parser.cpp<br></blockquote><blockquote type="cite">   cfe/trunk/lib/Sema/Sema.h<br></blockquote><blockquote type="cite">   cfe/trunk/lib/Sema/SemaDeclCXX.cpp<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Modified: cfe/trunk/include/clang/AST/DeclCXX.h<br></blockquote><blockquote type="cite">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=75849&r1=75848&r2=75849&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=75849&r1=75848&r2=75849&view=diff</a><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">=<br></blockquote><blockquote type="cite">=<br></blockquote><blockquote type="cite">=<br></blockquote><blockquote type="cite">=<br></blockquote><blockquote type="cite">=<br></blockquote><blockquote type="cite">=<br></blockquote><blockquote type="cite">=<br></blockquote><blockquote type="cite">=<br></blockquote><blockquote type="cite">======================================================================<br></blockquote><blockquote type="cite">--- cfe/trunk/include/clang/AST/DeclCXX.h (original)<br></blockquote><blockquote type="cite">+++ cfe/trunk/include/clang/AST/DeclCXX.h Wed Jul 15 17:34:08 2009<br></blockquote><blockquote type="cite">@@ -895,7 +895,16 @@<br></blockquote><blockquote type="cite">  /// explicitly defaulted (i.e., defined with " = default") will have<br></blockquote><blockquote type="cite">  /// @c !Implicit && ImplicitlyDefined.<br></blockquote><blockquote type="cite">  bool ImplicitlyDefined : 1;<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+  /// Support for base and member destruction.<br></blockquote><blockquote type="cite">+  /// BaseOrMemberDestructions - The arguments used to destruct the base<br></blockquote><blockquote type="cite">+  /// or member.<br></blockquote><blockquote type="cite">+  // FIXME. May want to use a new class as CXXBaseOrMemberInitializer has<br></blockquote><blockquote type="cite">+  // more info. than is needed. At the least, CXXBaseOrMemberInitializer need<br></blockquote><blockquote type="cite">+  // be renamed to something neutral.<br></blockquote><blockquote type="cite">+  CXXBaseOrMemberInitializer **BaseOrMemberDestructions;<br></blockquote><blockquote type="cite">+  unsigned NumBaseOrMemberDestructions;<br></blockquote><br>CXXBaseOrMemberInitializer is the wrong abstraction for this, especially because it contains the Args, NumArgs, and IdLoc fields that we don't need. I'd suggest storing a uintptr_t that stores either a RecordDecl* or a FieldDecl* (for bases and members, respectively), and use the lower two bits to encode one of the three options: it's a virtual base (stored as a RecordDecl*), it's a direct non-virtual base (stored as a RecordDecl*), or it's a non-static data members (stored as a FieldDecl*). That should be all of the information that clients (such as CodeGen) need to perform destruction properly.<br><br>Also, I think it's important for the comment to note that we're storing the destructions in the order they should occur (which is the reverse of construction order).<br><br><blockquote type="cite">  CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation L,<br></blockquote><blockquote type="cite">                    DeclarationName N, QualType T,<br></blockquote><blockquote type="cite">                    bool isInline, bool isImplicitlyDeclared)<br></blockquote><blockquote type="cite">@@ -928,6 +937,34 @@<br></blockquote><blockquote type="cite">    ImplicitlyDefined = ID;<br></blockquote><blockquote type="cite">  }<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">+  /// destr_iterator - Iterates through the member/base destruction list.<br></blockquote><blockquote type="cite">+  typedef CXXBaseOrMemberInitializer **destr_iterator;<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+  /// destr_const_iterator - Iterates through the member/base destruction list.<br></blockquote><blockquote type="cite">+  typedef CXXBaseOrMemberInitializer * const * destr_const_iterator;<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+  /// destr_begin() - Retrieve an iterator to the first destructed member/base.<br></blockquote><blockquote type="cite">+  destr_iterator       destr_begin()       { return BaseOrMemberDestructions; }<br></blockquote><blockquote type="cite">+  /// destr_begin() - Retrieve an iterator to the first destructed member/base.<br></blockquote><blockquote type="cite">+  destr_const_iterator destr_begin() const { return BaseOrMemberDestructions; }<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+  /// destr_end() - Retrieve an iterator past the last destructed member/base.<br></blockquote><blockquote type="cite">+  destr_iterator       destr_end()       {<br></blockquote><blockquote type="cite">+    return BaseOrMemberDestructions + NumBaseOrMemberDestructions;<br></blockquote><blockquote type="cite">+  }<br></blockquote><blockquote type="cite">+  /// destr_end() - Retrieve an iterator past the last destructed member/base.<br></blockquote><blockquote type="cite">+  destr_const_iterator destr_end() const {<br></blockquote><blockquote type="cite">+    return BaseOrMemberDestructions + NumBaseOrMemberDestructions;<br></blockquote><blockquote type="cite">+  }<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+  /// getNumArgs - Determine the number of arguments used to<br></blockquote><blockquote type="cite">+  /// destruct the member or base.<br></blockquote><blockquote type="cite">+  unsigned getNumBaseOrMemberDestructions() const {<br></blockquote><blockquote type="cite">+    return NumBaseOrMemberDestructions;<br></blockquote><blockquote type="cite">+  }<br></blockquote><br>The comment for getNumBaseOrMemberDestructions() is wrong.<br><br><blockquote type="cite"><br></blockquote><blockquote type="cite">+  void setBaseOrMemberDestructions(ASTContext &C);<br></blockquote><blockquote type="cite">+<br></blockquote><br>The name of this method is confusing: we're not really "setting" the base or member destructions, we're "computing" the bases and members that will be implicitly destroyed. A comment would also help!<br><br><blockquote type="cite"><br></blockquote><blockquote type="cite">  // Implement isa/cast/dyncast/etc.<br></blockquote><blockquote type="cite">  static bool classof(const Decl *D) {<br></blockquote><blockquote type="cite">    return D->getKind() == CXXDestructor;<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Modified: cfe/trunk/include/clang/Parse/Action.h<br></blockquote><blockquote type="cite">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=75849&r1=75848&r2=75849&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=75849&r1=75848&r2=75849&view=diff</a><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">==============================================================================<br></blockquote><blockquote type="cite">--- cfe/trunk/include/clang/Parse/Action.h (original)<br></blockquote><blockquote type="cite">+++ cfe/trunk/include/clang/Parse/Action.h Wed Jul 15 17:34:08 2009<br></blockquote><blockquote type="cite">@@ -1233,7 +1233,7 @@<br></blockquote><blockquote type="cite">                                    MemInitTy **MemInits, unsigned NumMemInits){<br></blockquote><blockquote type="cite">  }<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">- virtual void ActOnDefaultInitializers(DeclPtrTy ConstructorDecl) {}<br></blockquote><blockquote type="cite">+ virtual void ActOnDefaultCDtorInitializers(DeclPtrTy CDtorDecl) {}<br></blockquote><br><blockquote type="cite">  /// ActOnFinishCXXMemberSpecification - Invoked after all member declarators<br></blockquote><blockquote type="cite">  /// are parsed but *before* parsing of inline method definitions.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Modified: cfe/trunk/lib/AST/DeclCXX.cpp<br></blockquote><blockquote type="cite">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=75849&r1=75848&r2=75849&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=75849&r1=75848&r2=75849&view=diff</a><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">==============================================================================<br></blockquote><blockquote type="cite">--- cfe/trunk/lib/AST/DeclCXX.cpp (original)<br></blockquote><blockquote type="cite">+++ cfe/trunk/lib/AST/DeclCXX.cpp Wed Jul 15 17:34:08 2009<br></blockquote><blockquote type="cite">@@ -478,6 +478,50 @@<br></blockquote><blockquote type="cite">}<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">void<br></blockquote><blockquote type="cite">+CXXDestructorDecl::setBaseOrMemberDestructions(ASTContext &C) {<br></blockquote><blockquote type="cite">+  CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(getDeclContext());<br></blockquote><blockquote type="cite">+  llvm::SmallVector<CXXBaseOrMemberInitializer*, 32> AllToDestruct;<br></blockquote><blockquote type="cite">+  for (CXXRecordDecl::base_class_iterator VBase = ClassDecl->vbases_begin(),<br></blockquote><blockquote type="cite">+       E = ClassDecl->vbases_end(); VBase != E; ++VBase) {<br></blockquote><blockquote type="cite">+    CXXBaseOrMemberInitializer *Member =<br></blockquote><blockquote type="cite">+      new CXXBaseOrMemberInitializer(VBase->getType(), 0, 0,SourceLocation());<br></blockquote><blockquote type="cite">+    AllToDestruct.push_back(Member);<br></blockquote><blockquote type="cite">+  }<br></blockquote><br>If the virtual base class has a trivial destructor, it shouldn't be in the list, right?<br><br><blockquote type="cite">+  for (CXXRecordDecl::base_class_iterator Base =<br></blockquote><blockquote type="cite">+       ClassDecl->bases_begin(),<br></blockquote><blockquote type="cite">+       E = ClassDecl->bases_end(); Base != E; ++Base) {<br></blockquote><blockquote type="cite">+    if (Base->isVirtual())<br></blockquote><blockquote type="cite">+      continue;<br></blockquote><blockquote type="cite">+    CXXBaseOrMemberInitializer *Member =<br></blockquote><blockquote type="cite">+      new CXXBaseOrMemberInitializer(Base->getType(), 0, 0, SourceLocation());<br></blockquote><blockquote type="cite">+    AllToDestruct.push_back(Member);<br></blockquote><blockquote type="cite">+  }<br></blockquote><br>Same question: if the direct non-virtual base has a trivial destructor, it shouldn't be in the list.<br><br><blockquote type="cite">+  // non-static data members.<br></blockquote><blockquote type="cite">+  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(),<br></blockquote><blockquote type="cite">+       E = ClassDecl->field_end(); Field != E; ++Field) {<br></blockquote><blockquote type="cite">+    QualType FieldType = C.getCanonicalType((*Field)->getType());<br></blockquote><blockquote type="cite">+    while (const ArrayType *AT = C.getAsArrayType(FieldType))<br></blockquote><blockquote type="cite">+      FieldType = AT->getElementType();<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+    if (FieldType->getAsRecordType()) {<br></blockquote><blockquote type="cite">+      CXXBaseOrMemberInitializer *Member =<br></blockquote><blockquote type="cite">+        new CXXBaseOrMemberInitializer((*Field), 0, 0, SourceLocation());<br></blockquote><blockquote type="cite">+      AllToDestruct.push_back(Member);<br></blockquote><blockquote type="cite">+    }<br></blockquote><br>Same question, but also: if the field is not of class type, then it shouldn't be in the list of destructions.<br><br><blockquote type="cite">+  }<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+  unsigned NumDestructions = AllToDestruct.size();<br></blockquote><blockquote type="cite">+  if (NumDestructions > 0) {<br></blockquote><blockquote type="cite">+    NumBaseOrMemberDestructions = NumDestructions;<br></blockquote><blockquote type="cite">+    BaseOrMemberDestructions =<br></blockquote><blockquote type="cite">+      new (C) CXXBaseOrMemberInitializer*[NumDestructions];<br></blockquote><blockquote type="cite">+    // Insert in reverse order.<br></blockquote><blockquote type="cite">+    for (int Idx = NumDestructions-1, i=0 ; Idx >= 0; --Idx)<br></blockquote><blockquote type="cite">+      BaseOrMemberDestructions[i++] = AllToDestruct[Idx];<br></blockquote><blockquote type="cite">+  }<br></blockquote><blockquote type="cite">+}<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+void<br></blockquote><blockquote type="cite">CXXConstructorDecl::setBaseOrMemberInitializers(<br></blockquote><blockquote type="cite">                                    ASTContext &C,<br></blockquote><blockquote type="cite">                                    CXXBaseOrMemberInitializer **Initializers,<br></blockquote><br><br>CXXDestructorDecl should have a Destroy method that deallocates the BaseOrMemberDestructions pointer.<br><br><blockquote type="cite">Modified: cfe/trunk/lib/AST/DeclPrinter.cpp<br></blockquote><blockquote type="cite">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclPrinter.cpp?rev=75849&r1=75848&r2=75849&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclPrinter.cpp?rev=75849&r1=75848&r2=75849&view=diff</a><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">==============================================================================<br></blockquote><blockquote type="cite">--- cfe/trunk/lib/AST/DeclPrinter.cpp (original)<br></blockquote><blockquote type="cite">+++ cfe/trunk/lib/AST/DeclPrinter.cpp Wed Jul 15 17:34:08 2009<br></blockquote><blockquote type="cite">@@ -374,6 +374,36 @@<br></blockquote><blockquote type="cite">        }<br></blockquote><blockquote type="cite">      }<br></blockquote><blockquote type="cite">    }<br></blockquote><blockquote type="cite">+    else if (CXXDestructorDecl *DDecl = dyn_cast<CXXDestructorDecl>(D)) {<br></blockquote><blockquote type="cite">+      if (DDecl->getNumBaseOrMemberDestructions() > 0) {<br></blockquote><blockquote type="cite">+        // FIXME. This is strictly for visualization of destructor's AST for<br></blockquote><blockquote type="cite">+        // how base/members are destructed. It has no other validity.<br></blockquote><blockquote type="cite">+        assert (D->isThisDeclarationADefinition() && "Destructor with dtor-list");<br></blockquote><blockquote type="cite">+        Proto += " : ";<br></blockquote><blockquote type="cite">+        for (CXXDestructorDecl::destr_const_iterator B = DDecl->destr_begin(),<br></blockquote><blockquote type="cite">+             E = DDecl->destr_end();<br></blockquote><blockquote type="cite">+             B != E; ++B) {<br></blockquote><blockquote type="cite">+          CXXBaseOrMemberInitializer * BMInitializer = (*B);<br></blockquote><blockquote type="cite">+          if (B != DDecl->destr_begin())<br></blockquote><blockquote type="cite">+            Proto += ", ";<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">+          if (BMInitializer->isMemberInitializer()) {<br></blockquote><blockquote type="cite">+            FieldDecl *FD = BMInitializer->getMember();<br></blockquote><blockquote type="cite">+            Proto += "~";<br></blockquote><blockquote type="cite">+            Proto += FD->getNameAsString();<br></blockquote><blockquote type="cite">+          }<br></blockquote><blockquote type="cite">+          else // FIXME. skip dependent types for now.<br></blockquote><blockquote type="cite">+            if (const RecordType *RT =<br></blockquote><blockquote type="cite">+                BMInitializer->getBaseClass()->getAsRecordType()) {<br></blockquote><blockquote type="cite">+              const CXXRecordDecl *BaseDecl =<br></blockquote><blockquote type="cite">+                cast<CXXRecordDecl>(RT->getDecl());<br></blockquote><blockquote type="cite">+              Proto += "~";<br></blockquote><blockquote type="cite">+              Proto += BaseDecl->getNameAsString();<br></blockquote><blockquote type="cite">+            }<br></blockquote><blockquote type="cite">+          Proto += "()";<br></blockquote><blockquote type="cite">+        }<br></blockquote><blockquote type="cite">+      }<br></blockquote><blockquote type="cite">+    }<br></blockquote><br>It's unfortunate that this unnecessarily breaks round-tripping of C++ code with -ast-print. Could you wrap the output of this in "/*" and "*/"?<br><br><blockquote type="cite">    else<br></blockquote><blockquote type="cite">      AFT->getResultType().getAsStringInternal(Proto, Policy);<br></blockquote><blockquote type="cite">  } else {<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Modified: cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp<br></blockquote><blockquote type="cite">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp?rev=75849&r1=75848&r2=75849&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp?rev=75849&r1=75848&r2=75849&view=diff</a><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">==============================================================================<br></blockquote><blockquote type="cite">--- cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp (original)<br></blockquote><blockquote type="cite">+++ cfe/trunk/lib/Parse/ParseCXXInlineMethods.cpp Wed Jul 15 17:34:08 2009<br></blockquote><blockquote type="cite">@@ -172,7 +172,7 @@<br></blockquote><blockquote type="cite">    if (Tok.is(tok::colon))<br></blockquote><blockquote type="cite">      ParseConstructorInitializer(LM.D);<br></blockquote><blockquote type="cite">    else<br></blockquote><blockquote type="cite">-      Actions.ActOnDefaultInitializers(LM.D);<br></blockquote><blockquote type="cite">+      Actions.ActOnDefaultCDtorInitializers(LM.D);<br></blockquote><br>I find it a bit strange that ActOnDefaultCDtorInitializers gets called for all member function definitions, not just constructors and (with this change) destructors. More comments on this action below...<br><br><blockquote type="cite">    // FIXME: What if ParseConstructorInitializer doesn't leave us with a '{'??<br></blockquote><blockquote type="cite">    ParseFunctionStatementBody(LM.D);<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Modified: cfe/trunk/lib/Parse/Parser.cpp<br></blockquote><blockquote type="cite">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=75849&r1=75848&r2=75849&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=75849&r1=75848&r2=75849&view=diff</a><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">==============================================================================<br></blockquote><blockquote type="cite">--- cfe/trunk/lib/Parse/Parser.cpp (original)<br></blockquote><blockquote type="cite">+++ cfe/trunk/lib/Parse/Parser.cpp Wed Jul 15 17:34:08 2009<br></blockquote><blockquote type="cite">@@ -666,7 +666,7 @@<br></blockquote><blockquote type="cite">  if (Tok.is(tok::colon))<br></blockquote><blockquote type="cite">    ParseConstructorInitializer(Res);<br></blockquote><blockquote type="cite">  else<br></blockquote><blockquote type="cite">-    Actions.ActOnDefaultInitializers(Res);<br></blockquote><blockquote type="cite">+    Actions.ActOnDefaultCDtorInitializers(Res);<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">  return ParseFunctionStatementBody(Res);<br></blockquote><blockquote type="cite">}<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Modified: cfe/trunk/lib/Sema/Sema.h<br></blockquote><blockquote type="cite">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=75849&r1=75848&r2=75849&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=75849&r1=75848&r2=75849&view=diff</a><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">==============================================================================<br></blockquote><blockquote type="cite">--- cfe/trunk/lib/Sema/Sema.h (original)<br></blockquote><blockquote type="cite">+++ cfe/trunk/lib/Sema/Sema.h Wed Jul 15 17:34:08 2009<br></blockquote><blockquote type="cite">@@ -1468,7 +1468,7 @@<br></blockquote><blockquote type="cite">                                                    SourceLocation MemberLoc,<br></blockquote><blockquote type="cite">                                                    IdentifierInfo &Member,<br></blockquote><blockquote type="cite">                                                    DeclPtrTy ImplDecl);<br></blockquote><blockquote type="cite">-  virtual void ActOnDefaultInitializers(DeclPtrTy ConstructorDecl);<br></blockquote><blockquote type="cite">+  virtual void ActOnDefaultCDtorInitializers(DeclPtrTy CDtorDecl);<br></blockquote><blockquote type="cite">  bool ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,<br></blockquote><blockquote type="cite">                               FunctionDecl *FDecl,<br></blockquote><blockquote type="cite">                               const FunctionProtoType *Proto,<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp<br></blockquote><blockquote type="cite">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=75849&r1=75848&r2=75849&view=diff">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=75849&r1=75848&r2=75849&view=diff</a><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">==============================================================================<br></blockquote><blockquote type="cite">--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)<br></blockquote><blockquote type="cite">+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Jul 15 17:34:08 2009<br></blockquote><blockquote type="cite">@@ -902,15 +902,18 @@<br></blockquote><blockquote type="cite">  }<br></blockquote><blockquote type="cite">}<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">-void Sema::ActOnDefaultInitializers(DeclPtrTy ConstructorDecl) {<br></blockquote><blockquote type="cite">-  if (!ConstructorDecl)<br></blockquote><blockquote type="cite">+void Sema::ActOnDefaultCDtorInitializers(DeclPtrTy CDtorDecl) {<br></blockquote><blockquote type="cite">+  if (!CDtorDecl)<br></blockquote><blockquote type="cite">    return;<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">  if (CXXConstructorDecl *Constructor<br></blockquote><blockquote type="cite">-      = dyn_cast<CXXConstructorDecl>(ConstructorDecl.getAs<Decl>()))<br></blockquote><blockquote type="cite">+      = dyn_cast<CXXConstructorDecl>(CDtorDecl.getAs<Decl>()))<br></blockquote><blockquote type="cite">    Constructor->setBaseOrMemberInitializers(Context,<br></blockquote><blockquote type="cite">                                           (CXXBaseOrMemberInitializer **)0, 0);<br></blockquote><blockquote type="cite">-<br></blockquote><blockquote type="cite">+  else<br></blockquote><blockquote type="cite">+    if (CXXDestructorDecl *Destructor<br></blockquote><blockquote type="cite">+        = dyn_cast<CXXDestructorDecl>(CDtorDecl.getAs<Decl>()))<br></blockquote><blockquote type="cite">+      Destructor->setBaseOrMemberDestructions(Context);<br></blockquote><blockquote type="cite">}<br></blockquote><br><br>I don't think that setBaseOrMemberDestructions should be called here. Instead, setBaseOrMemberDestructions (with whatever new name it gets) should be called from Sema::ActOnFinishFunctionBody, because *semantically* these destructions occur at the end of the destructor, and we don't need the parser to tell us when they happen. Another side benefit of this behavior is that it will make sure that these destructions are computed for destructors of class template specializations, which isn't happening now.<br><br>  - Doug<br></blockquote></div><br></div></div></body></html>