diff options
Diffstat (limited to 'include/clang/AST/DeclCXX.h')
-rw-r--r-- | include/clang/AST/DeclCXX.h | 184 |
1 files changed, 155 insertions, 29 deletions
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 8c819e3..42a12eb 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -278,10 +278,18 @@ class CXXRecordDecl : public RecordDecl { /// user-declared copy constructor. bool UserDeclaredCopyConstructor : 1; + /// UserDeclareMoveConstructor - True when this class has a + /// user-declared move constructor. + bool UserDeclaredMoveConstructor : 1; + /// UserDeclaredCopyAssignment - True when this class has a /// user-declared copy assignment operator. bool UserDeclaredCopyAssignment : 1; + /// UserDeclareMoveAssignment - True when this class has a + /// user-declared move assignment. + bool UserDeclaredMoveAssignment : 1; + /// UserDeclaredDestructor - True when this class has a /// user-declared destructor. bool UserDeclaredDestructor : 1; @@ -337,15 +345,24 @@ class CXXRecordDecl : public RecordDecl { /// HasPublicFields - True when there are private non-static data members. bool HasPublicFields : 1; - /// HasTrivialConstructor - True when this class has a trivial constructor. + /// \brief True if this class (or any subobject) has mutable fields. + bool HasMutableFields : 1; + + /// HasTrivialDefaultConstructor - True when, if this class has a default + /// constructor, this default constructor is trivial. /// - /// 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; + /// C++0x [class.ctor]p5 + /// A default constructor is trivial if it is not user-provided and if + /// -- its class has no virtual functions and no virtual base classes, + /// and + /// -- no non-static data member of its class has a + /// brace-or-equal-initializer, and + /// -- all the direct base classes of its class have trivial + /// default 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 + /// default constructor. + bool HasTrivialDefaultConstructor : 1; /// HasConstExprNonCopyMoveConstructor - True when this class has at least /// one constexpr constructor which is neither the copy nor move @@ -357,7 +374,7 @@ class CXXRecordDecl : public RecordDecl { /// /// C++0x [class.copy]p13: /// A copy/move constructor for class X is trivial if it is neither - /// user-provided nor deleted and if + /// user-provided and if /// -- class X has no virtual functions and no virtual base classes, and /// -- the constructor selected to copy/move each direct base class /// subobject is trivial, and @@ -372,7 +389,7 @@ class CXXRecordDecl : public RecordDecl { /// /// C++0x [class.copy]p13: /// A copy/move constructor for class X is trivial if it is neither - /// user-provided nor deleted and if + /// user-provided and if /// -- class X has no virtual functions and no virtual base classes, and /// -- the constructor selected to copy/move each direct base class /// subobject is trivial, and @@ -430,15 +447,24 @@ class CXXRecordDecl : public RecordDecl { /// already computed and are available. bool ComputedVisibleConversions : 1; - /// \brief Whether we have already declared the default constructor or - /// do not need to have one declared. + /// \brief Whether we have a C++0x user-provided default constructor (not + /// explicitly deleted or defaulted). + bool UserProvidedDefaultConstructor : 1; + + /// \brief Whether we have already declared the default constructor. bool DeclaredDefaultConstructor : 1; /// \brief Whether we have already declared the copy constructor. bool DeclaredCopyConstructor : 1; + + /// \brief Whether we have already declared the move constructor. + bool DeclaredMoveConstructor : 1; /// \brief Whether we have already declared the copy-assignment operator. bool DeclaredCopyAssignment : 1; + + /// \brief Whether we have already declared the move-assignment operator. + bool DeclaredMoveAssignment : 1; /// \brief Whether we have already declared a destructor within the class. bool DeclaredDestructor : 1; @@ -666,21 +692,30 @@ public: return data().FirstFriend != 0; } - /// \brief Determine whether this class has had its default constructor - /// declared implicitly or does not need one declared implicitly. + /// \brief Determine if we need to declare a default constructor for + /// this class. /// /// This value is used for lazy creation of default constructors. + bool needsImplicitDefaultConstructor() const { + return !data().UserDeclaredConstructor && + !data().DeclaredDefaultConstructor; + } + + /// hasDeclaredDefaultConstructor - Whether this class's default constructor + /// has been declared (either explicitly or implicitly). bool hasDeclaredDefaultConstructor() const { return data().DeclaredDefaultConstructor; } - + /// hasConstCopyConstructor - Determines whether this class has a /// copy constructor that accepts a const-qualified argument. - bool hasConstCopyConstructor(const ASTContext &Context) const; + bool hasConstCopyConstructor() const; /// getCopyConstructor - Returns the copy constructor for this class - CXXConstructorDecl *getCopyConstructor(const ASTContext &Context, - unsigned TypeQuals) const; + CXXConstructorDecl *getCopyConstructor(unsigned TypeQuals) const; + + /// getMoveConstructor - Returns the move constructor for this class + CXXConstructorDecl *getMoveConstructor() const; /// \brief Retrieve the copy-assignment operator for this class, if available. /// @@ -693,6 +728,10 @@ public: /// \returns The copy-assignment operator that can be invoked, or NULL if /// a unique copy-assignment operator could not be found. CXXMethodDecl *getCopyAssignmentOperator(bool ArgIsConst) const; + + /// getMoveAssignmentOperator - Returns the move assignment operator for this + /// class + CXXMethodDecl *getMoveAssignmentOperator() const; /// hasUserDeclaredConstructor - Whether this class has any /// user-declared constructors. When true, a default constructor @@ -701,6 +740,12 @@ public: return data().UserDeclaredConstructor; } + /// hasUserProvidedDefaultconstructor - Whether this class has a + /// user-provided default constructor per C++0x. + bool hasUserProvidedDefaultConstructor() const { + return data().UserProvidedDefaultConstructor; + } + /// hasUserDeclaredCopyConstructor - Whether this class has a /// user-declared copy constructor. When false, a copy constructor /// will be implicitly declared. @@ -715,7 +760,27 @@ public: bool hasDeclaredCopyConstructor() const { return data().DeclaredCopyConstructor; } - + + /// hasUserDeclaredMoveOperation - Whether this class has a user- + /// declared move constructor or assignment operator. When false, a + /// move constructor and assignment operator may be implicitly declared. + bool hasUserDeclaredMoveOperation() const { + return data().UserDeclaredMoveConstructor || + data().UserDeclaredMoveAssignment; + } + + /// \brief Determine whether this class has had a move constructor + /// declared by the user. + bool hasUserDeclaredMoveConstructor() const { + return data().UserDeclaredMoveConstructor; + } + + /// \brief Determine whether this class has had a move constructor + /// declared. + bool hasDeclaredMoveConstructor() const { + return data().DeclaredMoveConstructor; + } + /// hasUserDeclaredCopyAssignment - Whether this class has a /// user-declared copy assignment operator. When false, a copy /// assigment operator will be implicitly declared. @@ -730,7 +795,19 @@ public: bool hasDeclaredCopyAssignment() const { return data().DeclaredCopyAssignment; } - + + /// \brief Determine whether this class has had a move assignment + /// declared by the user. + bool hasUserDeclaredMoveAssignment() const { + return data().UserDeclaredMoveAssignment; + } + + /// hasDeclaredMoveAssignment - Whether this class has a + /// declared move assignment operator. + bool hasDeclaredMoveAssignment() const { + return data().DeclaredMoveAssignment; + } + /// hasUserDeclaredDestructor - Whether this class has a /// user-declared destructor. When false, a destructor will be /// implicitly declared. @@ -800,9 +877,18 @@ public: /// (C++ [class]p7) bool isStandardLayout() const { return data().IsStandardLayout; } - // hasTrivialConstructor - Whether this class has a trivial constructor - // (C++ [class.ctor]p5) - bool hasTrivialConstructor() const { return data().HasTrivialConstructor; } + /// \brief Whether this class, or any of its class subobjects, contains a + /// mutable field. + bool hasMutableFields() const { return data().HasMutableFields; } + + // hasTrivialDefaultConstructor - Whether this class has a trivial default + // constructor + // (C++0x [class.ctor]p5) + bool hasTrivialDefaultConstructor() const { + return data().HasTrivialDefaultConstructor && + (!data().UserDeclaredConstructor || + data().DeclaredDefaultConstructor); + } // hasConstExprNonCopyMoveConstructor - Whether this class has at least one // constexpr constructor other than the copy or move constructors @@ -845,9 +931,18 @@ public: } // isTriviallyCopyable - Whether this class is considered trivially copyable - // (C++0x [class]p5). + // (C++0x [class]p6). bool isTriviallyCopyable() const; + // isTrivial - Whether this class is considered trivial + // + // C++0x [class]p6 + // A trivial class is a class that has a trivial default constructor and + // is trivially copiable. + bool isTrivial() const { + return isTriviallyCopyable() && hasTrivialDefaultConstructor(); + } + /// \brief If this record is an instantiation of a member class, /// retrieves the member class from which it was instantiated. /// @@ -1182,6 +1277,9 @@ public: /// \brief Determine whether this is a copy-assignment operator, regardless /// of whether it was declared implicitly or explicitly. bool isCopyAssignmentOperator() const; + + /// \brief Determine whether this is a move assignment operator. + bool isMoveAssignmentOperator() const; const CXXMethodDecl *getCanonicalDecl() const { return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl()); @@ -1189,6 +1287,12 @@ public: CXXMethodDecl *getCanonicalDecl() { return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl()); } + + /// isUserProvided - True if it is either an implicit constructor or + /// if it was defaulted or deleted on first declaration. + bool isUserProvided() const { + return !(isDeleted() || getCanonicalDecl()->isDefaulted()); + } /// void addOverriddenMethod(const CXXMethodDecl *MD); @@ -1274,6 +1378,8 @@ class CXXCtorInitializer { /// \brief The argument used to initialize the base or member, which may /// end up constructing an object (when multiple arguments are involved). + /// If 0, this is a field initializer, and the in-class member initializer + /// will be used. Stmt *Init; /// LParenLoc - Location of the left paren of the ctor-initializer. @@ -1348,6 +1454,13 @@ public: return Initializee.is<IndirectFieldDecl*>(); } + /// isInClassMemberInitializer - Returns true when this initializer is an + /// implicit ctor initializer generated for a field with an initializer + /// defined on the member declaration. + bool isInClassMemberInitializer() const { + return !Init; + } + /// isDelegatingInitializer - Returns true when this initializer is creating /// a delegating constructor. bool isDelegatingInitializer() const { @@ -1476,7 +1589,14 @@ public: reinterpret_cast<VarDecl **>(this + 1)[I] = Index; } - Expr *getInit() const { return static_cast<Expr *>(Init); } + /// \brief Get the initializer. This is 0 if this is an in-class initializer + /// for a non-static data member which has not yet been parsed. + Expr *getInit() const { + if (!Init) + return getAnyMember()->getInClassInitializer(); + + return static_cast<Expr*>(Init); + } }; /// CXXConstructorDecl - Represents a C++ constructor within a @@ -1619,10 +1739,9 @@ public: /// getTargetConstructor - When this constructor delegates to /// another, retrieve the target CXXConstructorDecl *getTargetConstructor() const { - if (isDelegatingConstructor()) - return CtorInitializers[0]->getTargetConstructor(); - else - return 0; + assert(isDelegatingConstructor() && + "A non-delegating constructor has no target"); + return CtorInitializers[0]->getTargetConstructor(); } /// isDefaultConstructor - Whether this constructor is a default @@ -1693,6 +1812,13 @@ public: /// \brief Set the constructor that this inheriting constructor is based on. void setInheritedConstructor(const CXXConstructorDecl *BaseCtor); + + const CXXConstructorDecl *getCanonicalDecl() const { + return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl()); + } + CXXConstructorDecl *getCanonicalDecl() { + return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl()); + } // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } |