diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-07-22 18:25:24 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-07-22 18:25:24 +0000 |
commit | 1f2023ab8b35e0f665eb6c0f11dd6d9b9bca12b8 (patch) | |
tree | 3a574978b5e87d08d62da2dd674e1e73b7da6c8b /include/clang | |
parent | 5350066e7b19d17a5b137caa6c039ab9626dbfa5 (diff) |
"This patch implements the restrictions on union members detailed in
[class.union]p1", from John McCall!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76766 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang')
-rw-r--r-- | include/clang/AST/Decl.h | 12 | ||||
-rw-r--r-- | include/clang/AST/DeclCXX.h | 87 | ||||
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 12 |
3 files changed, 104 insertions, 7 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 48b14a96a7..d99873823c 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -673,6 +673,7 @@ private: bool HasInheritedPrototype : 1; bool HasWrittenPrototype : 1; bool IsDeleted : 1; + bool IsTrivial : 1; // sunk from CXXMethodDecl // Move to DeclGroup when it is implemented. SourceLocation TypeSpecStartLoc; @@ -712,8 +713,8 @@ protected: ParamInfo(0), Body(), SClass(S), IsInline(isInline), C99InlineDefinition(false), IsVirtualAsWritten(false), IsPure(false), HasInheritedPrototype(false), - HasWrittenPrototype(true), IsDeleted(false), TypeSpecStartLoc(TSSL), - EndRangeLoc(L), TemplateOrSpecialization() {} + HasWrittenPrototype(true), IsDeleted(false), IsTrivial(false), + TypeSpecStartLoc(TSSL), EndRangeLoc(L), TemplateOrSpecialization() {} virtual ~FunctionDecl() {} virtual void Destroy(ASTContext& C); @@ -782,6 +783,13 @@ public: bool isPure() const { return IsPure; } void setPure(bool P = true) { IsPure = P; } + /// Whether this function is "trivial" in some specialized C++ senses. + /// Can only be true for default constructors, copy constructors, + /// copy assignment operators, and destructors. Not meaningful until + /// the class has been fully built by Sema. + bool isTrivial() const { return IsTrivial; } + void setTrivial(bool IT) { IsTrivial = IT; } + /// \brief Whether this function has a prototype, either because one /// was explicitly written or because it was "inherited" by merging /// a declaration without a prototype with a declaration that has a diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index ffacc0e1f3..6f9eee74d5 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -297,12 +297,51 @@ class CXXRecordDecl : public RecordDecl { /// pure virtual function, (that can come from a base class). bool Abstract : 1; - /// HasTrivialConstructor - True when this class has a trivial constructor + /// HasTrivialConstructor - True when this class has a trivial constructor. + /// + /// C++ [class.ctor]p5. A constructor is trivial if it is an + /// implicitly-declared default constructor and if: + /// * its class has no virtual functions and no virtual base classes, and + /// * all the direct base classes of its class have trivial constructors, and + /// * for all the nonstatic data members of its class that are of class type + /// (or array thereof), each such class has a trivial constructor. bool HasTrivialConstructor : 1; - /// HasTrivialDestructor - True when this class has a trivial destructor + /// HasTrivialCopyConstructor - True when this class has a trivial copy + /// constructor. + /// + /// C++ [class.copy]p6. A copy constructor for class X is trivial + /// if it is implicitly declared and if + /// * class X has no virtual functions and no virtual base classes, and + /// * each direct base class of X has a trivial copy constructor, and + /// * for all the nonstatic data members of X that are of class type (or + /// array thereof), each such class type has a trivial copy constructor; + /// otherwise the copy constructor is non-trivial. + bool HasTrivialCopyConstructor : 1; + + /// HasTrivialCopyAssignment - True when this class has a trivial copy + /// assignment operator. + /// + /// C++ [class.copy]p11. A copy assignment operator for class X is + /// trivial if it is implicitly declared and if + /// * class X has no virtual functions and no virtual base classes, and + /// * each direct base class of X has a trivial copy assignment operator, and + /// * for all the nonstatic data members of X that are of class type (or + /// array thereof), each such class type has a trivial copy assignment + /// operator; + /// otherwise the copy assignment operator is non-trivial. + bool HasTrivialCopyAssignment : 1; + + /// HasTrivialDestructor - True when this class has a trivial destructor. + /// + /// C++ [class.dtor]p3. A destructor is trivial if it is an + /// implicitly-declared destructor and if: + /// * all of the direct base classes of its class have trivial destructors + /// and + /// * for all of the non-static data members of its class that are of class + /// type (or array thereof), each such class has a trivial destructor. bool HasTrivialDestructor : 1; - + /// Bases - Base classes of this class. /// FIXME: This is wasted space for a union. CXXBaseSpecifier *Bases; @@ -342,11 +381,11 @@ protected: public: /// base_class_iterator - Iterator that traverses the base classes - /// of a clas. + /// of a class. typedef CXXBaseSpecifier* base_class_iterator; /// base_class_const_iterator - Iterator that traverses the base - /// classes of a clas. + /// classes of a class. typedef const CXXBaseSpecifier* base_class_const_iterator; static CXXRecordDecl *Create(ASTContext &C, TagKind TK, DeclContext *DC, @@ -379,6 +418,28 @@ public: base_class_iterator vbases_end() { return VBases + NumVBases; } base_class_const_iterator vbases_end() const { return VBases + NumVBases; } + /// Iterator access to method members. The method iterator visits + /// all method members of the class, including non-instance methods, + /// special methods, etc. + typedef specific_decl_iterator<CXXMethodDecl> method_iterator; + + method_iterator method_begin() const { + return method_iterator(decls_begin()); + } + method_iterator method_end() const { + return method_iterator(decls_end()); + } + + /// Iterator access to constructor members. + typedef specific_decl_iterator<CXXConstructorDecl> ctor_iterator; + + ctor_iterator ctor_begin() const { + return ctor_iterator(decls_begin()); + } + ctor_iterator ctor_end() const { + return ctor_iterator(decls_end()); + } + /// hasConstCopyConstructor - Determines whether this class has a /// copy constructor that accepts a const-qualified argument. bool hasConstCopyConstructor(ASTContext &Context) const; @@ -487,6 +548,22 @@ public: // (C++ [class.ctor]p5) void setHasTrivialConstructor(bool TC) { HasTrivialConstructor = TC; } + // hasTrivialCopyConstructor - Whether this class has a trivial copy + // constructor (C++ [class.copy]p6) + bool hasTrivialCopyConstructor() const { return HasTrivialCopyConstructor; } + + // setHasTrivialCopyConstructor - Set whether this class has a trivial + // copy constructor (C++ [class.copy]p6) + void setHasTrivialCopyConstructor(bool TC) { HasTrivialCopyConstructor = TC; } + + // hasTrivialCopyAssignment - Whether this class has a trivial copy + // assignment operator (C++ [class.copy]p11) + bool hasTrivialCopyAssignment() const { return HasTrivialCopyAssignment; } + + // setHasTrivialCopyAssignment - Set whether this class has a + // trivial copy assignment operator (C++ [class.copy]p11) + void setHasTrivialCopyAssignment(bool TC) { HasTrivialCopyAssignment = TC; } + // hasTrivialDestructor - Whether this class has a trivial destructor // (C++ [class.dtor]p3) bool hasTrivialDestructor() const { return HasTrivialDestructor; } diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 4cd1dca9a6..df62573e8c 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -339,6 +339,18 @@ def err_implicit_object_parameter_init : Error< "cannot initialize object parameter of type %0 with an expression " "of type %1">; +def err_illegal_union_member : Error< + "union member %0 has a non-trivial %select{constructor|" + "copy constructor|copy assignment operator|destructor}1">; +def note_nontrivial_has_virtual : Note< + "because type %0 has a virtual %select{member function|base class}1">; +def note_nontrivial_has_nontrivial : Note< + "because type %0 has a %select{member|base class}1 with a non-trivial " + "%select{constructor|copy constructor|copy assignment operator|destructor}2">; +def note_nontrivial_user_defined : Note< + "because type %0 has a user-declared %select{constructor|copy constructor|" + "copy assignment operator|destructor}1">; + def err_different_return_type_for_overriding_virtual_function : Error< "virtual function %0 has a different return type (%1) than the " "function it overrides (which has return type %2)">; |