diff options
| author | Douglas Gregor <dgregor@apple.com> | 2010-09-27 23:16:44 +0000 | 
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2010-09-27 23:16:44 +0000 | 
| commit | 1be93f5143afb06d5e380a6fadb41fabc40794ab (patch) | |
| tree | 07e2c6cf3cbc42d9d4aea3633d20bcd36b30d43a | |
| parent | 185051cb8e69e5cb17a82c9c0591afecf0bcadf8 (diff) | |
| download | bcm5719-llvm-1be93f5143afb06d5e380a6fadb41fabc40794ab.tar.gz bcm5719-llvm-1be93f5143afb06d5e380a6fadb41fabc40794ab.zip  | |
Centralize the management of CXXRecordDecl::DefinitionData's Aggregate
and PlainOldData bits in CXXRecordDecl itself. Another milepost on the
road toward <rdar://problem/8459981>.
llvm-svn: 114921
| -rw-r--r-- | clang/include/clang/AST/DeclCXX.h | 7 | ||||
| -rw-r--r-- | clang/lib/AST/DeclCXX.cpp | 50 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 18 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 8 | 
4 files changed, 48 insertions, 35 deletions
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index 975659b1e50..aa2ff3c43df 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -688,10 +688,6 @@ public:    /// no base classes, and no virtual functions (C++ [dcl.init.aggr]p1).    bool isAggregate() const { return data().Aggregate; } -  /// setAggregate - Set whether this class is an aggregate (C++ -  /// [dcl.init.aggr]). -  void setAggregate(bool Agg) { data().Aggregate = Agg; } -    /// setMethodAsVirtual - Make input method virtual and set the necesssary     /// special function bits and other bits accordingly.    void setMethodAsVirtual(FunctionDecl *Method); @@ -702,9 +698,6 @@ public:    /// user-defined destructor.    bool isPOD() const { return data().PlainOldData; } -  /// setPOD - Set whether this class is a POD-type (C++ [class]p4). -  void setPOD(bool POD) { data().PlainOldData = POD; } -    /// isEmpty - Whether this class is empty (C++0x [meta.unary.prop]), which    /// means it has a virtual function, virtual base, data member (other than    /// 0-width bit-field) or inherits from a non-empty class. Does NOT include diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 5d9a09da702..440eaddb7c1 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -97,6 +97,14 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,      CXXRecordDecl *BaseClassDecl        = cast<CXXRecordDecl>(BaseType->getAs<RecordType>()->getDecl()); +    // C++ [dcl.init.aggr]p1: +    //   An aggregate is [...] a class with [...] no base classes [...]. +    data().Aggregate = false;     +     +    // C++ [class]p4: +    //   A POD-struct is an aggregate class... +    data().PlainOldData = false; +          // Now go through all virtual bases of this base and add them.      for (CXXRecordDecl::base_class_iterator VBase =            BaseClassDecl->vbases_begin(), @@ -268,6 +276,18 @@ CXXRecordDecl::addedMember(Decl *D) {    if (FunTmpl)      D = FunTmpl->getTemplatedDecl(); +  if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) { +    if (Method->isVirtual()) { +      // C++ [dcl.init.aggr]p1: +      //   An aggregate is an array or a class with [...] no virtual functions. +      data().Aggregate = false; +       +      // C++ [class]p4: +      //   A POD-struct is an aggregate class... +      data().PlainOldData = false; +    } +  } +      if (D->isImplicit()) {      if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) {        // If this is the implicit default constructor, note that we have now @@ -334,6 +354,12 @@ CXXRecordDecl::addedMember(Decl *D) {    if (isa<CXXDestructorDecl>(D)) {      data().DeclaredDestructor = true;      data().UserDeclaredDestructor = true; +     +    // C++ [class]p4:  +    //   A POD-struct is an aggregate class that has [...] no user-defined  +    //   destructor. +    data().PlainOldData = false; +          return;    } @@ -382,6 +408,28 @@ CXXRecordDecl::addedMember(Decl *D) {      return;    } +   +  // Handle non-static data members. +  if (FieldDecl *Field = dyn_cast<FieldDecl>(D)) { +    // C++ [dcl.init.aggr]p1: +    //   An aggregate is an array or a class (clause 9) with [...] no +    //   private or protected non-static data members (clause 11). +    // +    // A POD must be an aggregate.     +    if (D->getAccess() == AS_private || D->getAccess() == AS_protected) { +      data().Aggregate = false; +      data().PlainOldData = false; +    } +     +    // C++ [class]p9: +    //   A POD struct is a class that is both a trivial class and a  +    //   standard-layout class, and has no non-static data members of type  +    //   non-POD struct, non-POD union (or array of such types). +    ASTContext &Context = getASTContext(); +    QualType T = Context.getBaseElementType(Field->getType()); +    if (!T->isPODType()) +      data().PlainOldData = false; +  }  }  static CanQualType GetConversionType(ASTContext &Context, NamedDecl *Conv) { @@ -566,8 +614,6 @@ void CXXRecordDecl::removeConversion(const NamedDecl *ConvDecl) {  void CXXRecordDecl::setMethodAsVirtual(FunctionDecl *Method) {    Method->setVirtualAsWritten(true); -  setAggregate(false); -  setPOD(false);    setEmpty(false);    setPolymorphic(true);    setHasTrivialConstructor(false); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 68cdc556e8d..5ac6f618d30 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -3931,10 +3931,6 @@ void Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,          }        } -      // C++ [class]p4: A POD-struct is an aggregate class that has [...] no -      // user-defined destructor. -      Record->setPOD(false); -        // C++ [class.dtor]p3: A destructor is trivial if it is an implicitly-        // declared destructor.        // FIXME: C++0x: don't do this for "= default" destructors @@ -6194,8 +6190,6 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,    if (!InvalidDecl && getLangOptions().CPlusPlus) {      CXXRecordDecl* CXXRecord = cast<CXXRecordDecl>(Record); -    if (!T->isPODType()) -      CXXRecord->setPOD(false);      if (!ZeroWidth)        CXXRecord->setEmpty(false);      if (T->isReferenceType()) @@ -6235,18 +6229,6 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,      Diag(Loc, diag::warn_attribute_weak_on_field);    NewFD->setAccess(AS); - -  // C++ [dcl.init.aggr]p1: -  //   An aggregate is an array or a class (clause 9) with [...] no -  //   private or protected non-static data members (clause 11). -  // A POD must be an aggregate. -  if (getLangOptions().CPlusPlus && -      (AS == AS_private || AS == AS_protected)) { -    CXXRecordDecl *CXXRecord = cast<CXXRecordDecl>(Record); -    CXXRecord->setAggregate(false); -    CXXRecord->setPOD(false); -  } -    return NewFD;  } diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 473247139e6..8ecf047a670 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -527,14 +527,6 @@ void Sema::SetClassDeclAttributesFromBase(CXXRecordDecl *Class,    if (BaseClass->isPolymorphic())      Class->setPolymorphic(true); -  // C++ [dcl.init.aggr]p1: -  //   An aggregate is [...] a class with [...] no base classes [...]. -  Class->setAggregate(false); - -  // C++ [class]p4: -  //   A POD-struct is an aggregate class... -  Class->setPOD(false); -    if (BaseIsVirtual) {      // C++ [class.ctor]p5:      //   A constructor is trivial if its class has no virtual base classes.  | 

