aboutsummaryrefslogtreecommitdiff
path: root/include/clang
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-07-22 18:25:24 +0000
committerDouglas Gregor <dgregor@apple.com>2009-07-22 18:25:24 +0000
commit1f2023ab8b35e0f665eb6c0f11dd6d9b9bca12b8 (patch)
tree3a574978b5e87d08d62da2dd674e1e73b7da6c8b /include/clang
parent5350066e7b19d17a5b137caa6c039ab9626dbfa5 (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.h12
-rw-r--r--include/clang/AST/DeclCXX.h87
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td12
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)">;