summaryrefslogtreecommitdiffstats
path: root/include/clang/AST/DeclCXX.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST/DeclCXX.h')
-rw-r--r--include/clang/AST/DeclCXX.h563
1 files changed, 315 insertions, 248 deletions
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index a9802bf..d11ee8f 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -35,6 +35,7 @@ class CXXMethodDecl;
class CXXRecordDecl;
class CXXMemberLookupCriteria;
class CXXFinalOverriderMap;
+class CXXIndirectPrimaryBaseSet;
class FriendDecl;
/// \brief Represents any kind of function declaration, whether it is a
@@ -112,6 +113,8 @@ class AccessSpecDecl : public Decl {
: Decl(AccessSpec, DC, ASLoc), ColonLoc(ColonLoc) {
setAccess(AS);
}
+ AccessSpecDecl(EmptyShell Empty)
+ : Decl(AccessSpec, Empty) { }
public:
/// getAccessSpecifierLoc - The location of the access specifier.
SourceLocation getAccessSpecifierLoc() const { return getLocation(); }
@@ -132,6 +135,9 @@ public:
SourceLocation ColonLoc) {
return new (C) AccessSpecDecl(AS, DC, ASLoc, ColonLoc);
}
+ static AccessSpecDecl *Create(ASTContext &C, EmptyShell Empty) {
+ return new (C) AccessSpecDecl(Empty);
+ }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -162,6 +168,10 @@ class CXXBaseSpecifier {
/// specifier (if present).
SourceRange Range;
+ /// \brief The source location of the ellipsis, if this is a pack
+ /// expansion.
+ SourceLocation EllipsisLoc;
+
/// Virtual - Whether this is a virtual base class or not.
bool Virtual : 1;
@@ -177,6 +187,10 @@ class CXXBaseSpecifier {
/// VC++ bug.
unsigned Access : 2;
+ /// InheritConstructors - Whether the class contains a using declaration
+ /// to inherit the named class's constructors.
+ bool InheritConstructors : 1;
+
/// BaseTypeInfo - The type of the base class. This will be a class or struct
/// (or a typedef of such). The source code range does not include the
/// "virtual" or access specifier.
@@ -186,8 +200,9 @@ public:
CXXBaseSpecifier() { }
CXXBaseSpecifier(SourceRange R, bool V, bool BC, AccessSpecifier A,
- TypeSourceInfo *TInfo)
- : Range(R), Virtual(V), BaseOfClass(BC), Access(A), BaseTypeInfo(TInfo) { }
+ TypeSourceInfo *TInfo, SourceLocation EllipsisLoc)
+ : Range(R), EllipsisLoc(EllipsisLoc), Virtual(V), BaseOfClass(BC),
+ Access(A), InheritConstructors(false), BaseTypeInfo(TInfo) { }
/// getSourceRange - Retrieves the source range that contains the
/// entire base specifier.
@@ -201,6 +216,22 @@ public:
/// with the 'class' keyword (vs. one declared with the 'struct' keyword).
bool isBaseOfClass() const { return BaseOfClass; }
+ /// \brief Determine whether this base specifier is a pack expansion.
+ bool isPackExpansion() const { return EllipsisLoc.isValid(); }
+
+ /// \brief Determine whether this base class's constructors get inherited.
+ bool getInheritConstructors() const { return InheritConstructors; }
+
+ /// \brief Set that this base class's constructors should be inherited.
+ void setInheritConstructors(bool Inherit = true) {
+ InheritConstructors = Inherit;
+ }
+
+ /// \brief For a pack expansion, determine the location of the ellipsis.
+ SourceLocation getEllipsisLoc() const {
+ return EllipsisLoc;
+ }
+
/// getAccessSpecifier - Returns the access specifier for this base
/// specifier. This is the actual base specifier as used for
/// semantic analysis, so the result can never be AS_none. To
@@ -336,20 +367,20 @@ class CXXRecordDecl : public RecordDecl {
/// \brief Whether we have already declared a destructor within the class.
bool DeclaredDestructor : 1;
-
- /// Bases - Base classes of this class.
- /// FIXME: This is wasted space for a union.
- CXXBaseSpecifier *Bases;
/// NumBases - The number of base class specifiers in Bases.
unsigned NumBases;
-
- /// VBases - direct and indirect virtual base classes of this class.
- CXXBaseSpecifier *VBases;
-
+
/// NumVBases - The number of virtual base class specifiers in VBases.
unsigned NumVBases;
+ /// Bases - Base classes of this class.
+ /// FIXME: This is wasted space for a union.
+ LazyCXXBaseSpecifiersPtr Bases;
+
+ /// VBases - direct and indirect virtual base classes of this class.
+ LazyCXXBaseSpecifiersPtr VBases;
+
/// Conversions - Overload set containing the conversion functions
/// of this C++ class (but not its inherited conversion
/// functions). Each of the entries in this overload set is a
@@ -371,6 +402,15 @@ class CXXRecordDecl : public RecordDecl {
/// in reverse order.
FriendDecl *FirstFriend;
+ /// \brief Retrieve the set of direct base classes.
+ CXXBaseSpecifier *getBases() const {
+ return Bases.get(Definition->getASTContext().getExternalSource());
+ }
+
+ /// \brief Retrieve the set of virtual base classes.
+ CXXBaseSpecifier *getVBases() const {
+ return VBases.get(Definition->getASTContext().getExternalSource());
+ }
} *DefinitionData;
struct DefinitionData &data() {
@@ -395,9 +435,17 @@ class CXXRecordDecl : public RecordDecl {
llvm::PointerUnion<ClassTemplateDecl*, MemberSpecializationInfo*>
TemplateOrInstantiation;
-#ifndef NDEBUG
- void CheckConversionFunction(NamedDecl *D);
-#endif
+ friend class DeclContext;
+
+ /// \brief Notify the class that member has been added.
+ ///
+ /// This routine helps maintain information about the class based on which
+ /// members have been added. It will be invoked by DeclContext::addDecl()
+ /// whenever a member is added to this record.
+ void addedMember(Decl *D);
+
+ void markedVirtualFunctionPure();
+ friend void FunctionDecl::setPure(bool);
protected:
CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
@@ -445,12 +493,12 @@ public:
bool hasDefinition() const { return DefinitionData != 0; }
- static CXXRecordDecl *Create(ASTContext &C, TagKind TK, DeclContext *DC,
+ static CXXRecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
SourceLocation TKL = SourceLocation(),
CXXRecordDecl* PrevDecl=0,
bool DelayTypeCreation = false);
- static CXXRecordDecl *Create(ASTContext &C, EmptyShell Empty);
+ static CXXRecordDecl *Create(const ASTContext &C, EmptyShell Empty);
bool isDynamicClass() const {
return data().Polymorphic || data().NumVBases != 0;
@@ -463,8 +511,8 @@ public:
/// class.
unsigned getNumBases() const { return data().NumBases; }
- base_class_iterator bases_begin() { return data().Bases; }
- base_class_const_iterator bases_begin() const { return data().Bases; }
+ base_class_iterator bases_begin() { return data().getBases(); }
+ base_class_const_iterator bases_begin() const { return data().getBases(); }
base_class_iterator bases_end() { return bases_begin() + data().NumBases; }
base_class_const_iterator bases_end() const {
return bases_begin() + data().NumBases;
@@ -486,8 +534,8 @@ public:
/// class.
unsigned getNumVBases() const { return data().NumVBases; }
- base_class_iterator vbases_begin() { return data().VBases; }
- base_class_const_iterator vbases_begin() const { return data().VBases; }
+ base_class_iterator vbases_begin() { return data().getVBases(); }
+ base_class_const_iterator vbases_begin() const { return data().getVBases(); }
base_class_iterator vbases_end() { return vbases_begin() + data().NumVBases; }
base_class_const_iterator vbases_end() const {
return vbases_begin() + data().NumVBases;
@@ -553,18 +601,12 @@ public:
return data().DeclaredDefaultConstructor;
}
- /// \brief Note whether this class has already had its default constructor
- /// implicitly declared or doesn't need one.
- void setDeclaredDefaultConstructor(bool DDC) {
- data().DeclaredDefaultConstructor = DDC;
- }
-
/// hasConstCopyConstructor - Determines whether this class has a
/// copy constructor that accepts a const-qualified argument.
- bool hasConstCopyConstructor(ASTContext &Context) const;
+ bool hasConstCopyConstructor(const ASTContext &Context) const;
/// getCopyConstructor - Returns the copy constructor for this class
- CXXConstructorDecl *getCopyConstructor(ASTContext &Context,
+ CXXConstructorDecl *getCopyConstructor(const ASTContext &Context,
unsigned TypeQuals) const;
/// \brief Retrieve the copy-assignment operator for this class, if available.
@@ -579,11 +621,6 @@ public:
/// a unique copy-assignment operator could not be found.
CXXMethodDecl *getCopyAssignmentOperator(bool ArgIsConst) const;
- /// addedConstructor - Notify the class that another constructor has
- /// been added. This routine helps maintain information about the
- /// class based on which constructors have been added.
- void addedConstructor(ASTContext &Context, CXXConstructorDecl *ConDecl);
-
/// hasUserDeclaredConstructor - Whether this class has any
/// user-declared constructors. When true, a default constructor
/// will not be implicitly declared.
@@ -606,17 +643,6 @@ public:
return data().DeclaredCopyConstructor;
}
- /// \brief Note whether this class has already had its copy constructor
- /// declared.
- void setDeclaredCopyConstructor(bool DCC) {
- data().DeclaredCopyConstructor = DCC;
- }
-
- /// addedAssignmentOperator - Notify the class that another assignment
- /// operator has been added. This routine helps maintain information about the
- /// class based on which operators have been added.
- void addedAssignmentOperator(ASTContext &Context, CXXMethodDecl *OpDecl);
-
/// hasUserDeclaredCopyAssignment - Whether this class has a
/// user-declared copy assignment operator. When false, a copy
/// assigment operator will be implicitly declared.
@@ -632,12 +658,6 @@ public:
return data().DeclaredCopyAssignment;
}
- /// \brief Note whether this class has already had its copy assignment
- /// operator declared.
- void setDeclaredCopyAssignment(bool DCA) {
- data().DeclaredCopyAssignment = DCA;
- }
-
/// hasUserDeclaredDestructor - Whether this class has a
/// user-declared destructor. When false, a destructor will be
/// implicitly declared.
@@ -645,26 +665,12 @@ public:
return data().UserDeclaredDestructor;
}
- /// setUserDeclaredDestructor - Set whether this class has a
- /// user-declared destructor. If not set by the time the class is
- /// fully defined, a destructor will be implicitly declared.
- void setUserDeclaredDestructor(bool UCD) {
- data().UserDeclaredDestructor = UCD;
- if (UCD)
- data().DeclaredDestructor = true;
- }
-
/// \brief Determine whether this class has had its destructor declared,
/// either via the user or via an implicit declaration.
///
/// This value is used for lazy creation of destructors.
bool hasDeclaredDestructor() const { return data().DeclaredDestructor; }
-
- /// \brief Note whether this class has already had its destructor declared.
- void setDeclaredDestructor(bool DD) {
- data().DeclaredDestructor = DD;
- }
-
+
/// getConversions - Retrieve the overload set containing all of the
/// conversion functions in this class.
UnresolvedSetImpl *getConversionFunctions() {
@@ -682,13 +688,6 @@ public:
return getConversionFunctions()->end();
}
- /// Replaces a conversion function with a new declaration.
- ///
- /// Returns true if the old conversion was found.
- bool replaceConversion(const NamedDecl* Old, NamedDecl *New) {
- return getConversionFunctions()->replace(Old, New);
- }
-
/// Removes a conversion function from this class. The conversion
/// function must currently be a member of this class. Furthermore,
/// this class must currently be in the process of being defined.
@@ -698,105 +697,52 @@ public:
/// in current class; including conversion function templates.
const UnresolvedSetImpl *getVisibleConversionFunctions();
- /// addConversionFunction - Registers a conversion function which
- /// this class declares directly.
- void addConversionFunction(NamedDecl *Decl) {
-#ifndef NDEBUG
- CheckConversionFunction(Decl);
-#endif
-
- // We intentionally don't use the decl's access here because it
- // hasn't been set yet. That's really just a misdesign in Sema.
- data().Conversions.addDecl(Decl);
- }
-
/// isAggregate - Whether this class is an aggregate (C++
/// [dcl.init.aggr]), which is a class with no user-declared
/// constructors, no private or protected non-static data members,
/// 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);
-
/// isPOD - Whether this class is a POD-type (C++ [class]p4), which is a class
/// that is an aggregate that has no non-static non-POD data members, no
/// reference data members, no user-defined copy assignment operator and no
/// 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
/// a check for union-ness.
bool isEmpty() const { return data().Empty; }
- /// Set whether this class is empty (C++0x [meta.unary.prop])
- void setEmpty(bool Emp) { data().Empty = Emp; }
-
/// isPolymorphic - Whether this class is polymorphic (C++ [class.virtual]),
/// which means that the class contains or inherits a virtual function.
bool isPolymorphic() const { return data().Polymorphic; }
- /// setPolymorphic - Set whether this class is polymorphic (C++
- /// [class.virtual]).
- void setPolymorphic(bool Poly) { data().Polymorphic = Poly; }
-
/// isAbstract - Whether this class is abstract (C++ [class.abstract]),
/// which means that the class contains or inherits a pure virtual function.
bool isAbstract() const { return data().Abstract; }
- /// setAbstract - Set whether this class is abstract (C++ [class.abstract])
- void setAbstract(bool Abs) { data().Abstract = Abs; }
-
// hasTrivialConstructor - Whether this class has a trivial constructor
// (C++ [class.ctor]p5)
bool hasTrivialConstructor() const { return data().HasTrivialConstructor; }
- // setHasTrivialConstructor - Set whether this class has a trivial constructor
- // (C++ [class.ctor]p5)
- void setHasTrivialConstructor(bool TC) { data().HasTrivialConstructor = TC; }
-
// hasTrivialCopyConstructor - Whether this class has a trivial copy
// constructor (C++ [class.copy]p6)
bool hasTrivialCopyConstructor() const {
return data().HasTrivialCopyConstructor;
}
- // setHasTrivialCopyConstructor - Set whether this class has a trivial
- // copy constructor (C++ [class.copy]p6)
- void setHasTrivialCopyConstructor(bool TC) {
- data().HasTrivialCopyConstructor = TC;
- }
-
// hasTrivialCopyAssignment - Whether this class has a trivial copy
// assignment operator (C++ [class.copy]p11)
bool hasTrivialCopyAssignment() const {
return data().HasTrivialCopyAssignment;
}
- // setHasTrivialCopyAssignment - Set whether this class has a
- // trivial copy assignment operator (C++ [class.copy]p11)
- void setHasTrivialCopyAssignment(bool TC) {
- data().HasTrivialCopyAssignment = TC;
- }
-
// hasTrivialDestructor - Whether this class has a trivial destructor
// (C++ [class.dtor]p3)
bool hasTrivialDestructor() const { return data().HasTrivialDestructor; }
- // setHasTrivialDestructor - Set whether this class has a trivial destructor
- // (C++ [class.dtor]p3)
- void setHasTrivialDestructor(bool TC) { data().HasTrivialDestructor = TC; }
-
/// \brief If this record is an instantiation of a member class,
/// retrieves the member class from which it was instantiated.
///
@@ -854,9 +800,6 @@ public:
/// \brief Set the kind of specialization or template instantiation this is.
void setTemplateSpecializationKind(TemplateSpecializationKind TSK);
-
- /// getDefaultConstructor - Returns the default constructor for this class
- CXXConstructorDecl *getDefaultConstructor();
/// getDestructor - Returns the destructor decl for this class.
CXXDestructorDecl *getDestructor() const;
@@ -880,7 +823,7 @@ public:
/// \param Base the base class we are searching for.
///
/// \returns true if this class is derived from Base, false otherwise.
- bool isDerivedFrom(CXXRecordDecl *Base) const;
+ bool isDerivedFrom(const CXXRecordDecl *Base) const;
/// \brief Determine whether this class is derived from the type \p Base.
///
@@ -898,7 +841,7 @@ public:
///
/// \todo add a separate paramaeter to configure IsDerivedFrom, rather than
/// tangling input and output in \p Paths
- bool isDerivedFrom(CXXRecordDecl *Base, CXXBasePaths &Paths) const;
+ bool isDerivedFrom(const CXXRecordDecl *Base, CXXBasePaths &Paths) const;
/// \brief Determine whether this class is virtually derived from
/// the class \p Base.
@@ -1034,6 +977,9 @@ public:
/// most-derived class in the class hierarchy.
void getFinalOverriders(CXXFinalOverriderMap &FinaOverriders) const;
+ /// \brief Get the indirect primary bases for this class.
+ void getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet& Bases) const;
+
/// viewInheritance - Renders and displays an inheritance diagram
/// for this C++ class and all of its base classes (transitively) using
/// GraphViz.
@@ -1048,6 +994,27 @@ public:
return (PathAccess > DeclAccess ? PathAccess : DeclAccess);
}
+ /// \brief Indicates that the definition of this class is now complete.
+ virtual void completeDefinition();
+
+ /// \brief Indicates that the definition of this class is now complete,
+ /// and provides a final overrider map to help determine
+ ///
+ /// \param FinalOverriders The final overrider map for this class, which can
+ /// be provided as an optimization for abstract-class checking. If NULL,
+ /// final overriders will be computed if they are needed to complete the
+ /// definition.
+ void completeDefinition(CXXFinalOverriderMap *FinalOverriders);
+
+ /// \brief Determine whether this class may end up being abstract, even though
+ /// it is not yet known to be abstract.
+ ///
+ /// \returns true if this class is not known to be abstract but has any
+ /// base classes that are abstract. In this case, \c completeDefinition()
+ /// will need to compute final overriders to determine whether the class is
+ /// actually abstract.
+ bool mayBeAbstract() const;
+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) {
return K >= firstCXXRecord && K <= lastCXXRecord;
@@ -1059,6 +1026,8 @@ public:
friend class ASTDeclReader;
friend class ASTDeclWriter;
+ friend class ASTReader;
+ friend class ASTWriter;
};
/// CXXMethodDecl - Represents a static or instance method of a
@@ -1139,6 +1108,20 @@ public:
return getType()->getAs<FunctionProtoType>()->getTypeQuals();
}
+ /// \brief Retrieve the ref-qualifier associated with this method.
+ ///
+ /// In the following example, \c f() has an lvalue ref-qualifier, \c g()
+ /// has an rvalue ref-qualifier, and \c h() has no ref-qualifier.
+ /// \code
+ /// struct X {
+ /// void f() &;
+ /// void g() &&;
+ /// void h();
+ /// };
+ RefQualifierKind getRefQualifier() const {
+ return getType()->getAs<FunctionProtoType>()->getRefQualifier();
+ }
+
bool hasInlineBody() const;
// Implement isa/cast/dyncast/etc.
@@ -1149,7 +1132,7 @@ public:
}
};
-/// CXXBaseOrMemberInitializer - Represents a C++ base or member
+/// CXXCtorInitializer - Represents a C++ base or member
/// initializer, which is part of a constructor initializer that
/// initializes one non-static member variable or one base class. For
/// example, in the following, both 'A(a)' and 'f(3.14159)' are member
@@ -1163,37 +1146,20 @@ public:
/// B(A& a) : A(a), f(3.14159) { }
/// };
/// @endcode
-class CXXBaseOrMemberInitializer {
- /// \brief Either the base class name (stored as a TypeSourceInfo*) or the
- /// field being initialized.
- llvm::PointerUnion<TypeSourceInfo *, FieldDecl *> BaseOrMember;
+class CXXCtorInitializer {
+ /// \brief Either the base class name (stored as a TypeSourceInfo*), an normal
+ /// field (FieldDecl) or an anonymous field (IndirectFieldDecl*) being
+ /// initialized.
+ llvm::PointerUnion3<TypeSourceInfo *, FieldDecl *, IndirectFieldDecl *>
+ Initializee;
- /// \brief The source location for the field name.
- SourceLocation MemberLocation;
+ /// \brief The source location for the field name or, for a base initializer
+ /// pack expansion, the location of the ellipsis.
+ SourceLocation MemberOrEllipsisLocation;
/// \brief The argument used to initialize the base or member, which may
/// end up constructing an object (when multiple arguments are involved).
Stmt *Init;
-
- /// \brief Stores either the constructor to call to initialize this base or
- /// member (a CXXConstructorDecl pointer), or stores the anonymous union of
- /// which the initialized value is a member.
- ///
- /// When the value is a FieldDecl pointer, 'BaseOrMember' is class's
- /// anonymous union data member, this field holds the FieldDecl for the
- /// member of the anonymous union being initialized.
- /// @code
- /// struct X {
- /// X() : au_i1(123) {}
- /// union {
- /// int au_i1;
- /// float au_f1;
- /// };
- /// };
- /// @endcode
- /// In above example, BaseOrMember holds the field decl. for anonymous union
- /// and AnonUnionMember holds field decl for au_i1.
- FieldDecl *AnonUnionMember;
/// LParenLoc - Location of the left paren of the ctor-initializer.
SourceLocation LParenLoc;
@@ -1208,6 +1174,7 @@ class CXXBaseOrMemberInitializer {
/// IsWritten - Whether or not the initializer is explicitly written
/// in the sources.
bool IsWritten : 1;
+
/// SourceOrderOrNumArrayIndices - If IsWritten is true, then this
/// number keeps track of the textual order of this initializer in the
/// original sources, counting from 0; otherwise, if IsWritten is false,
@@ -1215,50 +1182,62 @@ class CXXBaseOrMemberInitializer {
/// object in memory.
unsigned SourceOrderOrNumArrayIndices : 14;
- CXXBaseOrMemberInitializer(ASTContext &Context,
- FieldDecl *Member, SourceLocation MemberLoc,
- SourceLocation L,
- Expr *Init,
- SourceLocation R,
- VarDecl **Indices,
- unsigned NumIndices);
+ CXXCtorInitializer(ASTContext &Context, FieldDecl *Member,
+ SourceLocation MemberLoc, SourceLocation L, Expr *Init,
+ SourceLocation R, VarDecl **Indices, unsigned NumIndices);
public:
- /// CXXBaseOrMemberInitializer - Creates a new base-class initializer.
+ /// CXXCtorInitializer - Creates a new base-class initializer.
explicit
- CXXBaseOrMemberInitializer(ASTContext &Context,
- TypeSourceInfo *TInfo, bool IsVirtual,
- SourceLocation L,
- Expr *Init,
- SourceLocation R);
+ CXXCtorInitializer(ASTContext &Context, TypeSourceInfo *TInfo, bool IsVirtual,
+ SourceLocation L, Expr *Init, SourceLocation R,
+ SourceLocation EllipsisLoc);
- /// CXXBaseOrMemberInitializer - Creates a new member initializer.
+ /// CXXCtorInitializer - Creates a new member initializer.
explicit
- CXXBaseOrMemberInitializer(ASTContext &Context,
- FieldDecl *Member, SourceLocation MemberLoc,
- SourceLocation L,
- Expr *Init,
- SourceLocation R);
+ CXXCtorInitializer(ASTContext &Context, FieldDecl *Member,
+ SourceLocation MemberLoc, SourceLocation L, Expr *Init,
+ SourceLocation R);
+
+ explicit
+ CXXCtorInitializer(ASTContext &Context, IndirectFieldDecl *Member,
+ SourceLocation MemberLoc, SourceLocation L, Expr *Init,
+ SourceLocation R);
/// \brief Creates a new member initializer that optionally contains
/// array indices used to describe an elementwise initialization.
- static CXXBaseOrMemberInitializer *Create(ASTContext &Context,
- FieldDecl *Member,
- SourceLocation MemberLoc,
- SourceLocation L,
- Expr *Init,
- SourceLocation R,
- VarDecl **Indices,
- unsigned NumIndices);
+ static CXXCtorInitializer *Create(ASTContext &Context, FieldDecl *Member,
+ SourceLocation MemberLoc, SourceLocation L,
+ Expr *Init, SourceLocation R,
+ VarDecl **Indices, unsigned NumIndices);
/// isBaseInitializer - Returns true when this initializer is
/// initializing a base class.
- bool isBaseInitializer() const { return BaseOrMember.is<TypeSourceInfo*>(); }
+ bool isBaseInitializer() const { return Initializee.is<TypeSourceInfo*>(); }
/// isMemberInitializer - Returns true when this initializer is
/// initializing a non-static data member.
- bool isMemberInitializer() const { return BaseOrMember.is<FieldDecl*>(); }
+ bool isMemberInitializer() const { return Initializee.is<FieldDecl*>(); }
+
+ bool isAnyMemberInitializer() const {
+ return isMemberInitializer() || isIndirectMemberInitializer();
+ }
+ bool isIndirectMemberInitializer() const {
+ return Initializee.is<IndirectFieldDecl*>();
+ }
+
+ /// \brief Determine whether this initializer is a pack expansion.
+ bool isPackExpansion() const {
+ return isBaseInitializer() && MemberOrEllipsisLocation.isValid();
+ }
+
+ // \brief For a pack expansion, returns the location of the ellipsis.
+ SourceLocation getEllipsisLoc() const {
+ assert(isPackExpansion() && "Initializer is not a pack expansion");
+ return MemberOrEllipsisLocation;
+ }
+
/// If this is a base class initializer, returns the type of the
/// base class with location information. Otherwise, returns an NULL
/// type location.
@@ -1267,7 +1246,6 @@ public:
/// If this is a base class initializer, returns the type of the base class.
/// Otherwise, returns NULL.
const Type *getBaseClass() const;
- Type *getBaseClass();
/// Returns whether the base is virtual or not.
bool isBaseVirtual() const {
@@ -1278,7 +1256,7 @@ public:
/// \brief Returns the declarator information for a base class initializer.
TypeSourceInfo *getBaseClassInfo() const {
- return BaseOrMember.dyn_cast<TypeSourceInfo *>();
+ return Initializee.dyn_cast<TypeSourceInfo *>();
}
/// getMember - If this is a member initializer, returns the
@@ -1286,18 +1264,28 @@ public:
/// initialized. Otherwise, returns NULL.
FieldDecl *getMember() const {
if (isMemberInitializer())
- return BaseOrMember.get<FieldDecl*>();
+ return Initializee.get<FieldDecl*>();
+ else
+ return 0;
+ }
+ FieldDecl *getAnyMember() const {
+ if (isMemberInitializer())
+ return Initializee.get<FieldDecl*>();
+ else if (isIndirectMemberInitializer())
+ return Initializee.get<IndirectFieldDecl*>()->getAnonField();
else
return 0;
}
- SourceLocation getMemberLocation() const {
- return MemberLocation;
+ IndirectFieldDecl *getIndirectMember() const {
+ if (isIndirectMemberInitializer())
+ return Initializee.get<IndirectFieldDecl*>();
+ else
+ return 0;
}
- void setMember(FieldDecl *Member) {
- assert(isMemberInitializer());
- BaseOrMember = Member;
+ SourceLocation getMemberLocation() const {
+ return MemberOrEllipsisLocation;
}
/// \brief Determine the source location of the initializer.
@@ -1329,15 +1317,7 @@ public:
IsWritten = true;
SourceOrderOrNumArrayIndices = static_cast<unsigned>(pos);
}
-
- FieldDecl *getAnonUnionMember() const {
- return AnonUnionMember;
- }
- void setAnonUnionMember(FieldDecl *anonMember) {
- AnonUnionMember = anonMember;
- }
-
SourceLocation getLParenLoc() const { return LParenLoc; }
SourceLocation getRParenLoc() const { return RParenLoc; }
@@ -1388,10 +1368,10 @@ class CXXConstructorDecl : public CXXMethodDecl {
bool ImplicitlyDefined : 1;
/// Support for base and member initializers.
- /// BaseOrMemberInitializers - The arguments used to initialize the base
+ /// CtorInitializers - The arguments used to initialize the base
/// or member.
- CXXBaseOrMemberInitializer **BaseOrMemberInitializers;
- unsigned NumBaseOrMemberInitializers;
+ CXXCtorInitializer **CtorInitializers;
+ unsigned NumCtorInitializers;
CXXConstructorDecl(CXXRecordDecl *RD, const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
@@ -1400,7 +1380,7 @@ class CXXConstructorDecl : public CXXMethodDecl {
: CXXMethodDecl(CXXConstructor, RD, NameInfo, T, TInfo, false,
SC_None, isInline),
IsExplicitSpecified(isExplicitSpecified), ImplicitlyDefined(false),
- BaseOrMemberInitializers(0), NumBaseOrMemberInitializers(0) {
+ CtorInitializers(0), NumCtorInitializers(0) {
setImplicit(isImplicitlyDeclared);
}
@@ -1443,37 +1423,54 @@ public:
}
/// init_iterator - Iterates through the member/base initializer list.
- typedef CXXBaseOrMemberInitializer **init_iterator;
+ typedef CXXCtorInitializer **init_iterator;
/// init_const_iterator - Iterates through the memberbase initializer list.
- typedef CXXBaseOrMemberInitializer * const * init_const_iterator;
+ typedef CXXCtorInitializer * const * init_const_iterator;
/// init_begin() - Retrieve an iterator to the first initializer.
- init_iterator init_begin() { return BaseOrMemberInitializers; }
+ init_iterator init_begin() { return CtorInitializers; }
/// begin() - Retrieve an iterator to the first initializer.
- init_const_iterator init_begin() const { return BaseOrMemberInitializers; }
+ init_const_iterator init_begin() const { return CtorInitializers; }
/// init_end() - Retrieve an iterator past the last initializer.
init_iterator init_end() {
- return BaseOrMemberInitializers + NumBaseOrMemberInitializers;
+ return CtorInitializers + NumCtorInitializers;
}
/// end() - Retrieve an iterator past the last initializer.
init_const_iterator init_end() const {
- return BaseOrMemberInitializers + NumBaseOrMemberInitializers;
+ return CtorInitializers + NumCtorInitializers;
+ }
+
+ typedef std::reverse_iterator<init_iterator> init_reverse_iterator;
+ typedef std::reverse_iterator<init_const_iterator> init_const_reverse_iterator;
+
+ init_reverse_iterator init_rbegin() {
+ return init_reverse_iterator(init_end());
+ }
+ init_const_reverse_iterator init_rbegin() const {
+ return init_const_reverse_iterator(init_end());
+ }
+
+ init_reverse_iterator init_rend() {
+ return init_reverse_iterator(init_begin());
+ }
+ init_const_reverse_iterator init_rend() const {
+ return init_const_reverse_iterator(init_begin());
}
/// getNumArgs - Determine the number of arguments used to
/// initialize the member or base.
- unsigned getNumBaseOrMemberInitializers() const {
- return NumBaseOrMemberInitializers;
+ unsigned getNumCtorInitializers() const {
+ return NumCtorInitializers;
}
- void setNumBaseOrMemberInitializers(unsigned numBaseOrMemberInitializers) {
- NumBaseOrMemberInitializers = numBaseOrMemberInitializers;
+ void setNumCtorInitializers(unsigned numCtorInitializers) {
+ NumCtorInitializers = numCtorInitializers;
}
- void setBaseOrMemberInitializers(CXXBaseOrMemberInitializer ** initializers) {
- BaseOrMemberInitializers = initializers;
+ void setCtorInitializers(CXXCtorInitializer ** initializers) {
+ CtorInitializers = initializers;
}
/// isDefaultConstructor - Whether this constructor is a default
/// constructor (C++ [class.ctor]p5), which can be used to
@@ -1502,15 +1499,44 @@ public:
return isCopyConstructor(TypeQuals);
}
+ /// \brief Determine whether this constructor is a move constructor
+ /// (C++0x [class.copy]p3), which can be used to move values of the class.
+ ///
+ /// \param TypeQuals If this constructor is a move constructor, will be set
+ /// to the type qualifiers on the referent of the first parameter's type.
+ bool isMoveConstructor(unsigned &TypeQuals) const;
+
+ /// \brief Determine whether this constructor is a move constructor
+ /// (C++0x [class.copy]p3), which can be used to move values of the class.
+ bool isMoveConstructor() const;
+
+ /// \brief Determine whether this is a copy or move constructor.
+ ///
+ /// \param TypeQuals Will be set to the type qualifiers on the reference
+ /// parameter, if in fact this is a copy or move constructor.
+ bool isCopyOrMoveConstructor(unsigned &TypeQuals) const;
+
+ /// \brief Determine whether this a copy or move constructor.
+ bool isCopyOrMoveConstructor() const {
+ unsigned Quals;
+ return isCopyOrMoveConstructor(Quals);
+ }
+
/// isConvertingConstructor - Whether this constructor is a
/// converting constructor (C++ [class.conv.ctor]), which can be
/// used for user-defined conversions.
bool isConvertingConstructor(bool AllowExplicit) const;
/// \brief Determine whether this is a member template specialization that
- /// looks like a copy constructor. Such constructors are never used to copy
+ /// would copy the object to itself. Such constructors are never used to copy
/// an object.
- bool isCopyConstructorLikeSpecialization() const;
+ bool isSpecializationCopyingObject() const;
+
+ /// \brief Get the constructor that this inheriting constructor is based on.
+ const CXXConstructorDecl *getInheritedConstructor() const;
+
+ /// \brief Set the constructor that this inheriting constructor is based on.
+ void setInheritedConstructor(const CXXConstructorDecl *BaseCtor);
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -1542,8 +1568,9 @@ class CXXDestructorDecl : public CXXMethodDecl {
FunctionDecl *OperatorDelete;
CXXDestructorDecl(CXXRecordDecl *RD, const DeclarationNameInfo &NameInfo,
- QualType T, bool isInline, bool isImplicitlyDeclared)
- : CXXMethodDecl(CXXDestructor, RD, NameInfo, T, /*TInfo=*/0, false,
+ QualType T, TypeSourceInfo *TInfo,
+ bool isInline, bool isImplicitlyDeclared)
+ : CXXMethodDecl(CXXDestructor, RD, NameInfo, T, TInfo, false,
SC_None, isInline),
ImplicitlyDefined(false), OperatorDelete(0) {
setImplicit(isImplicitlyDeclared);
@@ -1553,7 +1580,8 @@ public:
static CXXDestructorDecl *Create(ASTContext& C, EmptyShell Empty);
static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
const DeclarationNameInfo &NameInfo,
- QualType T, bool isInline,
+ QualType T, TypeSourceInfo* TInfo,
+ bool isInline,
bool isImplicitlyDeclared);
/// isImplicitlyDefined - Whether this destructor was implicitly
@@ -1918,13 +1946,16 @@ class UsingShadowDecl : public NamedDecl {
/// The referenced declaration.
NamedDecl *Underlying;
- /// The using declaration which introduced this decl.
- UsingDecl *Using;
+ /// \brief The using declaration which introduced this decl or the next using
+ /// shadow declaration contained in the aforementioned using declaration.
+ NamedDecl *UsingOrNextShadow;
+ friend class UsingDecl;
UsingShadowDecl(DeclContext *DC, SourceLocation Loc, UsingDecl *Using,
NamedDecl *Target)
: NamedDecl(UsingShadow, DC, Loc, DeclarationName()),
- Underlying(Target), Using(Using) {
+ Underlying(Target),
+ UsingOrNextShadow(reinterpret_cast<NamedDecl *>(Using)) {
if (Target) {
setDeclName(Target->getDeclName());
IdentifierNamespace = Target->getIdentifierNamespace();
@@ -1952,15 +1983,20 @@ public:
}
/// \brief Gets the using declaration to which this declaration is tied.
- UsingDecl *getUsingDecl() const { return Using; }
+ UsingDecl *getUsingDecl() const;
- /// \brief Sets the using declaration that introduces this target
- /// declaration.
- void setUsingDecl(UsingDecl* UD) { Using = UD; }
+ /// \brief The next using shadow declaration contained in the shadow decl
+ /// chain of the using declaration which introduced this decl.
+ UsingShadowDecl *getNextUsingShadowDecl() const {
+ return dyn_cast_or_null<UsingShadowDecl>(UsingOrNextShadow);
+ }
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UsingShadowDecl *D) { return true; }
static bool classofKind(Kind K) { return K == Decl::UsingShadow; }
+
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
};
/// UsingDecl - Represents a C++ using-declaration. For example:
@@ -1980,10 +2016,9 @@ class UsingDecl : public NamedDecl {
/// declaration name embedded in the ValueDecl base class.
DeclarationNameLoc DNLoc;
- /// \brief The collection of shadow declarations associated with
- /// this using declaration. This set can change as a class is
- /// processed.
- llvm::SmallPtrSet<UsingShadowDecl*, 8> Shadows;
+ /// \brief The first shadow declaration of the shadow decl chain associated
+ /// with this using declaration.
+ UsingShadowDecl *FirstUsingShadow;
// \brief Has 'typename' keyword.
bool IsTypeName;
@@ -1993,7 +2028,7 @@ class UsingDecl : public NamedDecl {
const DeclarationNameInfo &NameInfo, bool IsTypeNameArg)
: NamedDecl(Using, DC, NameInfo.getLoc(), NameInfo.getName()),
NestedNameRange(NNR), UsingLocation(UL), TargetNestedName(TargetNNS),
- DNLoc(NameInfo.getInfo()), IsTypeName(IsTypeNameArg) {
+ DNLoc(NameInfo.getInfo()), FirstUsingShadow(0),IsTypeName(IsTypeNameArg) {
}
public:
@@ -2031,29 +2066,58 @@ public:
/// \brief Sets whether the using declaration has 'typename'.
void setTypeName(bool TN) { IsTypeName = TN; }
- typedef llvm::SmallPtrSet<UsingShadowDecl*,8>::const_iterator shadow_iterator;
- shadow_iterator shadow_begin() const { return Shadows.begin(); }
- shadow_iterator shadow_end() const { return Shadows.end(); }
+ /// \brief Iterates through the using shadow declarations assosiated with
+ /// this using declaration.
+ class shadow_iterator {
+ /// \brief The current using shadow declaration.
+ UsingShadowDecl *Current;
+
+ public:
+ typedef UsingShadowDecl* value_type;
+ typedef UsingShadowDecl* reference;
+ typedef UsingShadowDecl* pointer;
+ typedef std::forward_iterator_tag iterator_category;
+ typedef std::ptrdiff_t difference_type;
+
+ shadow_iterator() : Current(0) { }
+ explicit shadow_iterator(UsingShadowDecl *C) : Current(C) { }
- void addShadowDecl(UsingShadowDecl *S) {
- assert(S->getUsingDecl() == this);
- if (!Shadows.insert(S)) {
- assert(false && "declaration already in set");
+ reference operator*() const { return Current; }
+ pointer operator->() const { return Current; }
+
+ shadow_iterator& operator++() {
+ Current = Current->getNextUsingShadowDecl();
+ return *this;
}
- }
- void removeShadowDecl(UsingShadowDecl *S) {
- assert(S->getUsingDecl() == this);
- if (!Shadows.erase(S)) {
- assert(false && "declaration not in set");
+
+ shadow_iterator operator++(int) {
+ shadow_iterator tmp(*this);
+ ++(*this);
+ return tmp;
}
+
+ friend bool operator==(shadow_iterator x, shadow_iterator y) {
+ return x.Current == y.Current;
+ }
+ friend bool operator!=(shadow_iterator x, shadow_iterator y) {
+ return x.Current != y.Current;
+ }
+ };
+
+ shadow_iterator shadow_begin() const {
+ return shadow_iterator(FirstUsingShadow);
}
+ shadow_iterator shadow_end() const { return shadow_iterator(); }
/// \brief Return the number of shadowed declarations associated with this
/// using declaration.
- unsigned getNumShadowDecls() const {
- return Shadows.size();
+ unsigned shadow_size() const {
+ return std::distance(shadow_begin(), shadow_end());
}
+ void addShadowDecl(UsingShadowDecl *S);
+ void removeShadowDecl(UsingShadowDecl *S);
+
static UsingDecl *Create(ASTContext &C, DeclContext *DC,
SourceRange NNR, SourceLocation UsingL,
NestedNameSpecifier* TargetNNS,
@@ -2145,6 +2209,9 @@ public:
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const UnresolvedUsingValueDecl *D) { return true; }
static bool classofKind(Kind K) { return K == UnresolvedUsingValue; }
+
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
};
/// UnresolvedUsingTypenameDecl - Represents a dependent using
OpenPOWER on IntegriCloud