diff options
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/include/clang/AST/DeclCXX.h | 39 | ||||
| -rw-r--r-- | clang/include/clang/Parse/Action.h | 2 | ||||
| -rw-r--r-- | clang/lib/AST/DeclCXX.cpp | 44 | ||||
| -rw-r--r-- | clang/lib/AST/DeclPrinter.cpp | 30 | ||||
| -rw-r--r-- | clang/lib/Parse/ParseCXXInlineMethods.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/Parse/Parser.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/Sema.h | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 11 | 
8 files changed, 123 insertions, 9 deletions
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index ff0dd676aa7..af4976df762 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -895,7 +895,16 @@ class CXXDestructorDecl : public CXXMethodDecl {    /// explicitly defaulted (i.e., defined with " = default") will have    /// @c !Implicit && ImplicitlyDefined.    bool ImplicitlyDefined : 1; - +   +  /// Support for base and member destruction. +  /// BaseOrMemberDestructions - The arguments used to destruct the base  +  /// or member. +  // FIXME. May want to use a new class as CXXBaseOrMemberInitializer has +  // more info. than is needed. At the least, CXXBaseOrMemberInitializer need +  // be renamed to something neutral. +  CXXBaseOrMemberInitializer **BaseOrMemberDestructions; +  unsigned NumBaseOrMemberDestructions; +      CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation L,                      DeclarationName N, QualType T,                      bool isInline, bool isImplicitlyDeclared) @@ -928,6 +937,34 @@ public:      ImplicitlyDefined = ID;     } +  /// destr_iterator - Iterates through the member/base destruction list. +  typedef CXXBaseOrMemberInitializer **destr_iterator; +   +  /// destr_const_iterator - Iterates through the member/base destruction list. +  typedef CXXBaseOrMemberInitializer * const * destr_const_iterator; +   +  /// destr_begin() - Retrieve an iterator to the first destructed member/base. +  destr_iterator       destr_begin()       { return BaseOrMemberDestructions; } +  /// destr_begin() - Retrieve an iterator to the first destructed member/base. +  destr_const_iterator destr_begin() const { return BaseOrMemberDestructions; } +   +  /// destr_end() - Retrieve an iterator past the last destructed member/base. +  destr_iterator       destr_end()       {  +    return BaseOrMemberDestructions + NumBaseOrMemberDestructions;  +  } +  /// destr_end() - Retrieve an iterator past the last destructed member/base. +  destr_const_iterator destr_end() const {  +    return BaseOrMemberDestructions + NumBaseOrMemberDestructions;  +  } +   +  /// getNumArgs - Determine the number of arguments used to +  /// destruct the member or base. +  unsigned getNumBaseOrMemberDestructions() const {  +    return NumBaseOrMemberDestructions;  +  } +   +  void setBaseOrMemberDestructions(ASTContext &C); +                            // Implement isa/cast/dyncast/etc.    static bool classof(const Decl *D) {       return D->getKind() == CXXDestructor; diff --git a/clang/include/clang/Parse/Action.h b/clang/include/clang/Parse/Action.h index b88ea17a675..1f6780e1fe2 100644 --- a/clang/include/clang/Parse/Action.h +++ b/clang/include/clang/Parse/Action.h @@ -1233,7 +1233,7 @@ public:                                      MemInitTy **MemInits, unsigned NumMemInits){    } - virtual void ActOnDefaultInitializers(DeclPtrTy ConstructorDecl) {} + virtual void ActOnDefaultCDtorInitializers(DeclPtrTy CDtorDecl) {}    /// ActOnFinishCXXMemberSpecification - Invoked after all member declarators    /// are parsed but *before* parsing of inline method definitions. diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 674e98a2657..57ac611b2ca 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -478,6 +478,50 @@ CXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,  }  void +CXXDestructorDecl::setBaseOrMemberDestructions(ASTContext &C) { +  CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(getDeclContext()); +  llvm::SmallVector<CXXBaseOrMemberInitializer*, 32> AllToDestruct; +  for (CXXRecordDecl::base_class_iterator VBase = ClassDecl->vbases_begin(), +       E = ClassDecl->vbases_end(); VBase != E; ++VBase) { +    CXXBaseOrMemberInitializer *Member =  +      new CXXBaseOrMemberInitializer(VBase->getType(), 0, 0,SourceLocation()); +    AllToDestruct.push_back(Member); +  } +  for (CXXRecordDecl::base_class_iterator Base = +       ClassDecl->bases_begin(), +       E = ClassDecl->bases_end(); Base != E; ++Base) { +    if (Base->isVirtual()) +      continue; +    CXXBaseOrMemberInitializer *Member =  +      new CXXBaseOrMemberInitializer(Base->getType(), 0, 0, SourceLocation()); +    AllToDestruct.push_back(Member); +  } +  // non-static data members. +  for (CXXRecordDecl::field_iterator Field = ClassDecl->field_begin(), +       E = ClassDecl->field_end(); Field != E; ++Field) { +    QualType FieldType = C.getCanonicalType((*Field)->getType()); +    while (const ArrayType *AT = C.getAsArrayType(FieldType)) +      FieldType = AT->getElementType(); +     +    if (FieldType->getAsRecordType()) { +      CXXBaseOrMemberInitializer *Member =  +        new CXXBaseOrMemberInitializer((*Field), 0, 0, SourceLocation()); +      AllToDestruct.push_back(Member); +    } +  } +   +  unsigned NumDestructions = AllToDestruct.size(); +  if (NumDestructions > 0) { +    NumBaseOrMemberDestructions = NumDestructions; +    BaseOrMemberDestructions =  +      new (C) CXXBaseOrMemberInitializer*[NumDestructions]; +    // Insert in reverse order. +    for (int Idx = NumDestructions-1, i=0 ; Idx >= 0; --Idx) +      BaseOrMemberDestructions[i++] = AllToDestruct[Idx]; +  } +} + +void  CXXConstructorDecl::setBaseOrMemberInitializers(                                      ASTContext &C,                                      CXXBaseOrMemberInitializer **Initializers, diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp index c7ad8d0a711..84ae72977e6 100644 --- a/clang/lib/AST/DeclPrinter.cpp +++ b/clang/lib/AST/DeclPrinter.cpp @@ -374,6 +374,36 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {          }        }      } +    else if (CXXDestructorDecl *DDecl = dyn_cast<CXXDestructorDecl>(D)) { +      if (DDecl->getNumBaseOrMemberDestructions() > 0) { +        // FIXME. This is strictly for visualization of destructor's AST for +        // how base/members are destructed. It has no other validity. +        assert (D->isThisDeclarationADefinition() && "Destructor with dtor-list"); +        Proto += " : "; +        for (CXXDestructorDecl::destr_const_iterator B = DDecl->destr_begin(),  +             E = DDecl->destr_end(); +             B != E; ++B) { +          CXXBaseOrMemberInitializer * BMInitializer = (*B); +          if (B != DDecl->destr_begin()) +            Proto += ", "; + +          if (BMInitializer->isMemberInitializer()) { +            FieldDecl *FD = BMInitializer->getMember(); +            Proto += "~"; +            Proto += FD->getNameAsString(); +          } +          else // FIXME. skip dependent types for now. +            if (const RecordType *RT =  +                BMInitializer->getBaseClass()->getAsRecordType()) { +              const CXXRecordDecl *BaseDecl =  +                cast<CXXRecordDecl>(RT->getDecl()); +              Proto += "~"; +              Proto += BaseDecl->getNameAsString(); +            } +          Proto += "()"; +        } +      } +    }      else        AFT->getResultType().getAsStringInternal(Proto, Policy);    } else { diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index 8dcf24f86a5..3bb9c3eb9c2 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -172,7 +172,7 @@ void Parser::ParseLexedMethodDefs(ParsingClass &Class) {      if (Tok.is(tok::colon))        ParseConstructorInitializer(LM.D);      else -      Actions.ActOnDefaultInitializers(LM.D); +      Actions.ActOnDefaultCDtorInitializers(LM.D);      // FIXME: What if ParseConstructorInitializer doesn't leave us with a '{'??      ParseFunctionStatementBody(LM.D); diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index bac3a86dc47..e7b0f337320 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -666,7 +666,7 @@ Parser::DeclPtrTy Parser::ParseFunctionDefinition(Declarator &D,    if (Tok.is(tok::colon))      ParseConstructorInitializer(Res);    else -    Actions.ActOnDefaultInitializers(Res); +    Actions.ActOnDefaultCDtorInitializers(Res);    return ParseFunctionStatementBody(Res);  } diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index e01bf23ce6a..f17b77baaa7 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -1468,7 +1468,7 @@ public:                                                      SourceLocation MemberLoc,                                                      IdentifierInfo &Member,                                                      DeclPtrTy ImplDecl); -  virtual void ActOnDefaultInitializers(DeclPtrTy ConstructorDecl); +  virtual void ActOnDefaultCDtorInitializers(DeclPtrTy CDtorDecl);    bool ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,                                 FunctionDecl *FDecl,                                 const FunctionProtoType *Proto, diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 7d039dc2d67..c62858ac730 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -902,15 +902,18 @@ void Sema::ActOnMemInitializers(DeclPtrTy ConstructorDecl,    }  } -void Sema::ActOnDefaultInitializers(DeclPtrTy ConstructorDecl) { -  if (!ConstructorDecl) +void Sema::ActOnDefaultCDtorInitializers(DeclPtrTy CDtorDecl) { +  if (!CDtorDecl)      return;    if (CXXConstructorDecl *Constructor  -      = dyn_cast<CXXConstructorDecl>(ConstructorDecl.getAs<Decl>())) +      = dyn_cast<CXXConstructorDecl>(CDtorDecl.getAs<Decl>()))      Constructor->setBaseOrMemberInitializers(Context,                                              (CXXBaseOrMemberInitializer **)0, 0); -                                            +  else  +    if (CXXDestructorDecl *Destructor  +        = dyn_cast<CXXDestructorDecl>(CDtorDecl.getAs<Decl>())) +      Destructor->setBaseOrMemberDestructions(Context);  }  namespace {  | 

