aboutsummaryrefslogtreecommitdiff
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.h383
1 files changed, 231 insertions, 152 deletions
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index dbc41320bd72..72fad7c28e49 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -17,13 +17,12 @@
#define LLVM_CLANG_AST_DECLCXX_H
#include "clang/AST/ASTUnresolvedSet.h"
+#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
-#include "clang/AST/ExprCXX.h"
-#include "clang/AST/TypeLoc.h"
+#include "clang/AST/LambdaCapture.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/Compiler.h"
namespace clang {
@@ -122,14 +121,14 @@ public:
/// \brief Sets the location of the colon.
void setColonLoc(SourceLocation CLoc) { ColonLoc = CLoc; }
- SourceRange getSourceRange() const LLVM_READONLY {
+ SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(getAccessSpecifierLoc(), getColonLoc());
}
static AccessSpecDecl *Create(ASTContext &C, AccessSpecifier AS,
DeclContext *DC, SourceLocation ASLoc,
SourceLocation ColonLoc) {
- return new (C) AccessSpecDecl(AS, DC, ASLoc, ColonLoc);
+ return new (C, DC) AccessSpecDecl(AS, DC, ASLoc, ColonLoc);
}
static AccessSpecDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -258,20 +257,31 @@ public:
TypeSourceInfo *getTypeSourceInfo() const { return BaseTypeInfo; }
};
-/// The inheritance model to use for member pointers of a given CXXRecordDecl.
-enum MSInheritanceModel {
- MSIM_Single,
- MSIM_SinglePolymorphic,
- MSIM_Multiple,
- MSIM_MultiplePolymorphic,
- MSIM_Virtual,
- MSIM_Unspecified
+/// \brief A lazy pointer to the definition data for a declaration.
+/// FIXME: This is a little CXXRecordDecl-specific that the moment.
+template<typename Decl, typename T> class LazyDefinitionDataPtr {
+ llvm::PointerUnion<T *, Decl *> DataOrCanonicalDecl;
+
+ LazyDefinitionDataPtr update() {
+ if (Decl *Canon = DataOrCanonicalDecl.template dyn_cast<Decl*>()) {
+ if (Canon->isCanonicalDecl())
+ Canon->getMostRecentDecl();
+ else
+ // Declaration isn't canonical any more;
+ // update it and perform path compression.
+ *this = Canon->getPreviousDecl()->DefinitionData.update();
+ }
+ return *this;
+ }
+
+public:
+ LazyDefinitionDataPtr(Decl *Canon) : DataOrCanonicalDecl(Canon) {}
+ LazyDefinitionDataPtr(T *Data) : DataOrCanonicalDecl(Data) {}
+ T *getNotUpdated() { return DataOrCanonicalDecl.template dyn_cast<T*>(); }
+ T *get() { return update().getNotUpdated(); }
};
/// \brief Represents a C++ struct/union/class.
-///
-/// FIXME: This class will disappear once we've properly taught RecordDecl
-/// to deal with C++-specific things.
class CXXRecordDecl : public RecordDecl {
friend void TagDecl::startDefinition();
@@ -350,10 +360,15 @@ class CXXRecordDecl : public RecordDecl {
/// \brief True if this class (or any subobject) has mutable fields.
bool HasMutableFields : 1;
+ /// \brief True if this class (or any nested anonymous struct or union)
+ /// has variant members.
+ bool HasVariantMembers : 1;
+
/// \brief True if there no non-field members declared by the user.
bool HasOnlyCMembers : 1;
- /// \brief True if any field has an in-class initializer.
+ /// \brief True if any field has an in-class initializer, including those
+ /// within anonymous unions or structs.
bool HasInClassInitializer : 1;
/// \brief True if any field is of reference type, and does not have an
@@ -409,7 +424,7 @@ class CXXRecordDecl : public RecordDecl {
/// \brief True if this class has a constexpr default constructor.
///
/// This is true for either a user-declared constexpr default constructor
- /// or an implicitly declared constexpr default constructor..
+ /// or an implicitly declared constexpr default constructor.
bool HasConstexprDefaultConstructor : 1;
/// \brief True when this class contains at least one non-static data
@@ -447,6 +462,9 @@ class CXXRecordDecl : public RecordDecl {
/// \brief Whether this class describes a C++ lambda.
bool IsLambda : 1;
+ /// \brief Whether we are currently parsing base specifiers.
+ bool IsParsingBaseSpecifiers : 1;
+
/// \brief The number of base class specifiers in Bases.
unsigned NumBases;
@@ -486,33 +504,39 @@ class CXXRecordDecl : public RecordDecl {
/// \brief Retrieve the set of direct base classes.
CXXBaseSpecifier *getBases() const {
if (!Bases.isOffset())
- return Bases.get(0);
+ return Bases.get(nullptr);
return getBasesSlowCase();
}
/// \brief Retrieve the set of virtual base classes.
CXXBaseSpecifier *getVBases() const {
if (!VBases.isOffset())
- return VBases.get(0);
+ return VBases.get(nullptr);
return getVBasesSlowCase();
}
private:
CXXBaseSpecifier *getBasesSlowCase() const;
CXXBaseSpecifier *getVBasesSlowCase() const;
- } *DefinitionData;
+ };
+
+ typedef LazyDefinitionDataPtr<CXXRecordDecl, struct DefinitionData>
+ DefinitionDataPtr;
+ friend class LazyDefinitionDataPtr<CXXRecordDecl, struct DefinitionData>;
+
+ mutable DefinitionDataPtr DefinitionData;
/// \brief Describes a C++ closure type (generated by a lambda expression).
struct LambdaDefinitionData : public DefinitionData {
- typedef LambdaExpr::Capture Capture;
-
- LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info,
+ typedef LambdaCapture Capture;
+
+ LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info,
bool Dependent, bool IsGeneric,
LambdaCaptureDefault CaptureDefault)
: DefinitionData(D), Dependent(Dependent), IsGenericLambda(IsGeneric),
CaptureDefault(CaptureDefault), NumCaptures(0), NumExplicitCaptures(0),
- ManglingNumber(0), ContextDecl(0), Captures(0), MethodTyInfo(Info)
- {
+ ManglingNumber(0), ContextDecl(nullptr), Captures(nullptr),
+ MethodTyInfo(Info) {
IsLambda = true;
}
@@ -557,23 +581,20 @@ class CXXRecordDecl : public RecordDecl {
};
- struct DefinitionData &data() {
- assert(DefinitionData && "queried property of class with no definition");
- return *DefinitionData;
- }
-
- const struct DefinitionData &data() const {
- assert(DefinitionData && "queried property of class with no definition");
- return *DefinitionData;
+ struct DefinitionData &data() const {
+ auto *DD = DefinitionData.get();
+ assert(DD && "queried property of class with no definition");
+ return *DD;
}
struct LambdaDefinitionData &getLambdaData() const {
- assert(DefinitionData && "queried property of lambda with no definition");
- assert(DefinitionData->IsLambda &&
- "queried lambda property of non-lambda class");
- return static_cast<LambdaDefinitionData &>(*DefinitionData);
+ // No update required: a merged definition cannot change any lambda
+ // properties.
+ auto *DD = DefinitionData.getNotUpdated();
+ assert(DD && DD->IsLambda && "queried lambda property of non-lambda class");
+ return static_cast<LambdaDefinitionData&>(*DD);
}
-
+
/// \brief The template or declaration that this declaration
/// describes or was instantiated from, respectively.
///
@@ -610,7 +631,7 @@ class CXXRecordDecl : public RecordDecl {
FriendDecl *getFirstFriend() const;
protected:
- CXXRecordDecl(Kind K, TagKind TK, DeclContext *DC,
+ CXXRecordDecl(Kind K, TagKind TK, const ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, CXXRecordDecl *PrevDecl);
@@ -621,17 +642,7 @@ public:
/// \brief Iterator that traverses the base classes of a class.
typedef const CXXBaseSpecifier* base_class_const_iterator;
- /// \brief Iterator that traverses the base classes of a class in reverse
- /// order.
- typedef std::reverse_iterator<base_class_iterator>
- reverse_base_class_iterator;
-
- /// \brief Iterator that traverses the base classes of a class in reverse
- /// order.
- typedef std::reverse_iterator<base_class_const_iterator>
- reverse_base_class_const_iterator;
-
- virtual CXXRecordDecl *getCanonicalDecl() {
+ CXXRecordDecl *getCanonicalDecl() override {
return cast<CXXRecordDecl>(RecordDecl::getCanonicalDecl());
}
virtual const CXXRecordDecl *getCanonicalDecl() const {
@@ -656,19 +667,20 @@ public:
}
CXXRecordDecl *getDefinition() const {
- if (!DefinitionData) return 0;
- return data().Definition;
+ auto *DD = DefinitionData.get();
+ return DD ? DD->Definition : nullptr;
}
- bool hasDefinition() const { return DefinitionData != 0; }
+ bool hasDefinition() const { return DefinitionData.get(); }
static CXXRecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
- IdentifierInfo *Id, CXXRecordDecl* PrevDecl=0,
+ IdentifierInfo *Id,
+ CXXRecordDecl *PrevDecl = nullptr,
bool DelayTypeCreation = false);
static CXXRecordDecl *CreateLambda(const ASTContext &C, DeclContext *DC,
TypeSourceInfo *Info, SourceLocation Loc,
- bool DependentLambda, bool IsGeneric,
+ bool DependentLambda, bool IsGeneric,
LambdaCaptureDefault CaptureDefault);
static CXXRecordDecl *CreateDeserialized(const ASTContext &C, unsigned ID);
@@ -676,52 +688,52 @@ public:
return data().Polymorphic || data().NumVBases != 0;
}
+ void setIsParsingBaseSpecifiers() { data().IsParsingBaseSpecifiers = true; }
+
+ bool isParsingBaseSpecifiers() const {
+ return data().IsParsingBaseSpecifiers;
+ }
+
/// \brief Sets the base classes of this struct or class.
void setBases(CXXBaseSpecifier const * const *Bases, unsigned NumBases);
/// \brief Retrieves the number of base classes of this class.
unsigned getNumBases() const { return data().NumBases; }
+ typedef llvm::iterator_range<base_class_iterator> base_class_range;
+ typedef llvm::iterator_range<base_class_const_iterator>
+ base_class_const_range;
+
+ base_class_range bases() {
+ return base_class_range(bases_begin(), bases_end());
+ }
+ base_class_const_range bases() const {
+ return base_class_const_range(bases_begin(), bases_end());
+ }
+
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;
}
- reverse_base_class_iterator bases_rbegin() {
- return reverse_base_class_iterator(bases_end());
- }
- reverse_base_class_const_iterator bases_rbegin() const {
- return reverse_base_class_const_iterator(bases_end());
- }
- reverse_base_class_iterator bases_rend() {
- return reverse_base_class_iterator(bases_begin());
- }
- reverse_base_class_const_iterator bases_rend() const {
- return reverse_base_class_const_iterator(bases_begin());
- }
/// \brief Retrieves the number of virtual base classes of this class.
unsigned getNumVBases() const { return data().NumVBases; }
+ base_class_range vbases() {
+ return base_class_range(vbases_begin(), vbases_end());
+ }
+ base_class_const_range vbases() const {
+ return base_class_const_range(vbases_begin(), vbases_end());
+ }
+
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;
}
- reverse_base_class_iterator vbases_rbegin() {
- return reverse_base_class_iterator(vbases_end());
- }
- reverse_base_class_const_iterator vbases_rbegin() const {
- return reverse_base_class_const_iterator(vbases_end());
- }
- reverse_base_class_iterator vbases_rend() {
- return reverse_base_class_iterator(vbases_begin());
- }
- reverse_base_class_const_iterator vbases_rend() const {
- return reverse_base_class_const_iterator(vbases_begin());
- }
/// \brief Determine whether this class has any dependent base classes which
/// are not the current instantiation.
@@ -731,6 +743,12 @@ public:
/// all method members of the class, including non-instance methods,
/// special methods, etc.
typedef specific_decl_iterator<CXXMethodDecl> method_iterator;
+ typedef llvm::iterator_range<specific_decl_iterator<CXXMethodDecl>>
+ method_range;
+
+ method_range methods() const {
+ return method_range(method_begin(), method_end());
+ }
/// \brief Method begin iterator. Iterates in the order the methods
/// were declared.
@@ -744,6 +762,10 @@ public:
/// Iterator access to constructor members.
typedef specific_decl_iterator<CXXConstructorDecl> ctor_iterator;
+ typedef llvm::iterator_range<specific_decl_iterator<CXXConstructorDecl>>
+ ctor_range;
+
+ ctor_range ctors() const { return ctor_range(ctor_begin(), ctor_end()); }
ctor_iterator ctor_begin() const {
return ctor_iterator(decls_begin());
@@ -755,6 +777,9 @@ public:
/// An iterator over friend declarations. All of these are defined
/// in DeclFriend.h.
class friend_iterator;
+ typedef llvm::iterator_range<friend_iterator> friend_range;
+
+ friend_range friends() const;
friend_iterator friend_begin() const;
friend_iterator friend_end() const;
void pushFriendDecl(FriendDecl *FD);
@@ -984,7 +1009,11 @@ public:
}
/// \brief Determine whether this class describes a lambda function object.
- bool isLambda() const { return hasDefinition() && data().IsLambda; }
+ bool isLambda() const {
+ // An update record can't turn a non-lambda into a lambda.
+ auto *DD = DefinitionData.getNotUpdated();
+ return DD && DD->IsLambda;
+ }
/// \brief Determine whether this class describes a generic
/// lambda function object (i.e. function call operator is
@@ -1025,12 +1054,18 @@ public:
void getCaptureFields(llvm::DenseMap<const VarDecl *, FieldDecl *> &Captures,
FieldDecl *&ThisCapture) const;
- typedef const LambdaExpr::Capture* capture_const_iterator;
+ typedef const LambdaCapture *capture_const_iterator;
+ typedef llvm::iterator_range<capture_const_iterator> capture_const_range;
+
+ capture_const_range captures() const {
+ return capture_const_range(captures_begin(), captures_end());
+ }
capture_const_iterator captures_begin() const {
- return isLambda() ? getLambdaData().Captures : NULL;
+ return isLambda() ? getLambdaData().Captures : nullptr;
}
capture_const_iterator captures_end() const {
- return isLambda() ? captures_begin() + getLambdaData().NumCaptures : NULL;
+ return isLambda() ? captures_begin() + getLambdaData().NumCaptures
+ : nullptr;
}
typedef UnresolvedSetIterator conversion_iterator;
@@ -1058,7 +1093,8 @@ public:
bool isAggregate() const { return data().Aggregate; }
/// \brief Whether this class has any in-class initializers
- /// for non-static data members.
+ /// for non-static data members (including those in anonymous unions or
+ /// structs).
bool hasInClassInitializer() const { return data().HasInClassInitializer; }
/// \brief Whether this class or any of its subobjects has any members of
@@ -1117,6 +1153,9 @@ public:
/// contains a mutable field.
bool hasMutableFields() const { return data().HasMutableFields; }
+ /// \brief Determine whether this class has any variant members.
+ bool hasVariantMembers() const { return data().HasVariantMembers; }
+
/// \brief Determine whether this class has a trivial default constructor
/// (C++11 [class.ctor]p5).
bool hasTrivialDefaultConstructor() const {
@@ -1144,7 +1183,7 @@ public:
/// would be constexpr.
bool defaultedDefaultConstructorIsConstexpr() const {
return data().DefaultedDefaultConstructorIsConstexpr &&
- (!isUnion() || hasInClassInitializer());
+ (!isUnion() || hasInClassInitializer() || !hasVariantMembers());
}
/// \brief Determine whether this class has a constexpr default constructor.
@@ -1546,7 +1585,7 @@ public:
void finishedDefaultedOrDeletedMember(CXXMethodDecl *MD);
/// \brief Indicates that the definition of this class is now complete.
- virtual void completeDefinition();
+ void completeDefinition() override;
/// \brief Indicates that the definition of this class is now complete,
/// and provides a final overrider map to help determine
@@ -1599,7 +1638,25 @@ public:
}
/// \brief Returns the inheritance model used for this record.
- MSInheritanceModel getMSInheritanceModel() const;
+ MSInheritanceAttr::Spelling getMSInheritanceModel() const;
+ /// \brief Calculate what the inheritance model would be for this class.
+ MSInheritanceAttr::Spelling calculateInheritanceModel() const;
+
+ /// In the Microsoft C++ ABI, use zero for the field offset of a null data
+ /// member pointer if we can guarantee that zero is not a valid field offset,
+ /// or if the member pointer has multiple fields. Polymorphic classes have a
+ /// vfptr at offset zero, so we can use zero for null. If there are multiple
+ /// fields, we can use zero even if it is a valid field offset because
+ /// null-ness testing will check the other fields.
+ bool nullFieldOffsetIsZero() const {
+ return !MSInheritanceAttr::hasOnlyOneField(/*IsMemberFunction=*/false,
+ getMSInheritanceModel()) ||
+ (hasDefinition() && isPolymorphic());
+ }
+
+ /// \brief Controls when vtordisps will be emitted if this record is used as a
+ /// virtual base.
+ MSVtorDispAttr::Mode getMSVtorDispMode() const;
/// \brief Determine whether this lambda expression was known to be dependent
/// at the time it was created, even if its context does not appear to be
@@ -1636,14 +1693,14 @@ public:
/// In the terminology of the C++ Standard, these are the (static and
/// non-static) member functions, whether virtual or not.
class CXXMethodDecl : public FunctionDecl {
- virtual void anchor();
+ void anchor() override;
protected:
- CXXMethodDecl(Kind DK, CXXRecordDecl *RD, SourceLocation StartLoc,
- const DeclarationNameInfo &NameInfo,
+ CXXMethodDecl(Kind DK, ASTContext &C, CXXRecordDecl *RD,
+ SourceLocation StartLoc, const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
StorageClass SC, bool isInline,
bool isConstexpr, SourceLocation EndLocation)
- : FunctionDecl(DK, RD, StartLoc, NameInfo, T, TInfo,
+ : FunctionDecl(DK, C, RD, StartLoc, NameInfo, T, TInfo,
SC, isInline, isConstexpr) {
if (EndLocation.isValid())
setRangeEnd(EndLocation);
@@ -1683,9 +1740,9 @@ public:
CXXMethodDecl *CD =
cast<CXXMethodDecl>(const_cast<CXXMethodDecl*>(this)->getCanonicalDecl());
- // Methods declared in interfaces are automatically (pure) virtual.
- if (CD->isVirtualAsWritten() ||
- (CD->getParent()->isInterface() && CD->isUserProvided()))
+ // Member function is virtual if it is marked explicitly so, or if it is
+ // declared in __interface -- then it is automatically pure virtual.
+ if (CD->isVirtualAsWritten() || CD->isPure())
return true;
return (CD->begin_overridden_methods() != CD->end_overridden_methods());
@@ -1703,10 +1760,10 @@ public:
/// \brief Determine whether this is a move assignment operator.
bool isMoveAssignmentOperator() const;
- CXXMethodDecl *getCanonicalDecl() {
+ CXXMethodDecl *getCanonicalDecl() override {
return cast<CXXMethodDecl>(FunctionDecl::getCanonicalDecl());
}
- const CXXMethodDecl *getCanonicalDecl() const {
+ const CXXMethodDecl *getCanonicalDecl() const override {
return const_cast<CXXMethodDecl*>(this)->getCanonicalDecl();
}
@@ -1921,7 +1978,7 @@ public:
/// In-class member initializers (also known as "non-static data member
/// initializations", NSDMIs) were introduced in C++11.
bool isInClassMemberInitializer() const {
- return isa<CXXDefaultInitExpr>(Init);
+ return Init->getStmtClass() == Stmt::CXXDefaultInitExprClass;
}
/// \brief Determine whether this initializer is creating a delegating
@@ -1968,20 +2025,20 @@ public:
FieldDecl *getMember() const {
if (isMemberInitializer())
return Initializee.get<FieldDecl*>();
- return 0;
+ return nullptr;
}
FieldDecl *getAnyMember() const {
if (isMemberInitializer())
return Initializee.get<FieldDecl*>();
if (isIndirectMemberInitializer())
return Initializee.get<IndirectFieldDecl*>()->getAnonField();
- return 0;
+ return nullptr;
}
IndirectFieldDecl *getIndirectMember() const {
if (isIndirectMemberInitializer())
return Initializee.get<IndirectFieldDecl*>();
- return 0;
+ return nullptr;
}
SourceLocation getMemberLocation() const {
@@ -2066,7 +2123,7 @@ public:
/// };
/// \endcode
class CXXConstructorDecl : public CXXMethodDecl {
- virtual void anchor();
+ void anchor() override;
/// \brief Whether this constructor declaration has the \c explicit keyword
/// specified.
bool IsExplicitSpecified : 1;
@@ -2078,14 +2135,14 @@ class CXXConstructorDecl : public CXXMethodDecl {
unsigned NumCtorInitializers;
/// \}
- CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation StartLoc,
+ CXXConstructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
bool isExplicitSpecified, bool isInline,
bool isImplicitlyDeclared, bool isConstexpr)
- : CXXMethodDecl(CXXConstructor, RD, StartLoc, NameInfo, T, TInfo,
+ : CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo,
SC_None, isInline, isConstexpr, SourceLocation()),
- IsExplicitSpecified(isExplicitSpecified), CtorInitializers(0),
+ IsExplicitSpecified(isExplicitSpecified), CtorInitializers(nullptr),
NumCtorInitializers(0) {
setImplicit(isImplicitlyDeclared);
}
@@ -2115,6 +2172,14 @@ public:
/// \brief Iterates through the member/base initializer list.
typedef CXXCtorInitializer * const * init_const_iterator;
+ typedef llvm::iterator_range<init_iterator> init_range;
+ typedef llvm::iterator_range<init_const_iterator> init_const_range;
+
+ init_range inits() { return init_range(init_begin(), init_end()); }
+ init_const_range inits() const {
+ return init_const_range(init_begin(), init_end());
+ }
+
/// \brief Retrieve an iterator to the first initializer.
init_iterator init_begin() { return CtorInitializers; }
/// \brief Retrieve an iterator to the first initializer.
@@ -2240,10 +2305,10 @@ public:
/// \brief Set the constructor that this inheriting constructor is based on.
void setInheritedConstructor(const CXXConstructorDecl *BaseCtor);
- const CXXConstructorDecl *getCanonicalDecl() const {
+ const CXXConstructorDecl *getCanonicalDecl() const override {
return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl());
}
- CXXConstructorDecl *getCanonicalDecl() {
+ CXXConstructorDecl *getCanonicalDecl() override {
return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl());
}
@@ -2266,17 +2331,17 @@ public:
/// };
/// \endcode
class CXXDestructorDecl : public CXXMethodDecl {
- virtual void anchor();
+ void anchor() override;
FunctionDecl *OperatorDelete;
- CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation StartLoc,
+ CXXDestructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
bool isInline, bool isImplicitlyDeclared)
- : CXXMethodDecl(CXXDestructor, RD, StartLoc, NameInfo, T, TInfo,
+ : CXXMethodDecl(CXXDestructor, C, RD, StartLoc, NameInfo, T, TInfo,
SC_None, isInline, /*isConstexpr=*/false, SourceLocation()),
- OperatorDelete(0) {
+ OperatorDelete(nullptr) {
setImplicit(isImplicitlyDeclared);
}
@@ -2289,8 +2354,12 @@ public:
bool isImplicitlyDeclared);
static CXXDestructorDecl *CreateDeserialized(ASTContext & C, unsigned ID);
- void setOperatorDelete(FunctionDecl *OD) { OperatorDelete = OD; }
- const FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
+ void setOperatorDelete(FunctionDecl *OD) {
+ cast<CXXDestructorDecl>(getFirstDecl())->OperatorDelete = OD;
+ }
+ const FunctionDecl *getOperatorDelete() const {
+ return cast<CXXDestructorDecl>(getFirstDecl())->OperatorDelete;
+ }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
@@ -2311,18 +2380,18 @@ public:
/// };
/// \endcode
class CXXConversionDecl : public CXXMethodDecl {
- virtual void anchor();
+ void anchor() override;
/// Whether this conversion function declaration is marked
/// "explicit", meaning that it can only be applied when the user
/// explicitly wrote a cast. This is a C++0x feature.
bool IsExplicitSpecified : 1;
- CXXConversionDecl(CXXRecordDecl *RD, SourceLocation StartLoc,
+ CXXConversionDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
const DeclarationNameInfo &NameInfo,
QualType T, TypeSourceInfo *TInfo,
bool isInline, bool isExplicitSpecified,
bool isConstexpr, SourceLocation EndLocation)
- : CXXMethodDecl(CXXConversion, RD, StartLoc, NameInfo, T, TInfo,
+ : CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo,
SC_None, isInline, isConstexpr, EndLocation),
IsExplicitSpecified(isExplicitSpecified) { }
@@ -2351,7 +2420,7 @@ public:
/// \brief Returns the type that this conversion function is converting to.
QualType getConversionType() const {
- return getType()->getAs<FunctionType>()->getResultType();
+ return getType()->getAs<FunctionType>()->getReturnType();
}
/// \brief Determine whether this conversion function is a conversion from
@@ -2440,7 +2509,7 @@ public:
return decls_empty() ? getLocation() : decls_begin()->getLocEnd();
}
- SourceRange getSourceRange() const LLVM_READONLY {
+ SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(ExternLoc, getLocEnd());
}
@@ -2465,7 +2534,7 @@ public:
/// artificial names for all using-directives in order to store
/// them in DeclContext effectively.
class UsingDirectiveDecl : public NamedDecl {
- virtual void anchor();
+ void anchor() override;
/// \brief The location of the \c using keyword.
SourceLocation UsingLoc;
@@ -2546,8 +2615,8 @@ public:
NamedDecl *Nominated,
DeclContext *CommonAncestor);
static UsingDirectiveDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- SourceRange getSourceRange() const LLVM_READONLY {
+
+ SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(UsingLoc, getLocation());
}
@@ -2568,7 +2637,7 @@ public:
/// namespace Foo = Bar;
/// \endcode
class NamespaceAliasDecl : public NamedDecl {
- virtual void anchor();
+ void anchor() override;
/// \brief The location of the \c namespace keyword.
SourceLocation NamespaceLoc;
@@ -2641,8 +2710,8 @@ public:
NamedDecl *Namespace);
static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- virtual SourceRange getSourceRange() const LLVM_READONLY {
+
+ SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(NamespaceLoc, IdentLoc);
}
@@ -2664,7 +2733,7 @@ public:
/// }
/// \endcode
class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> {
- virtual void anchor();
+ void anchor() override;
/// The referenced declaration.
NamedDecl *Underlying;
@@ -2674,10 +2743,10 @@ class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> {
NamedDecl *UsingOrNextShadow;
friend class UsingDecl;
- UsingShadowDecl(DeclContext *DC, SourceLocation Loc, UsingDecl *Using,
- NamedDecl *Target)
+ UsingShadowDecl(ASTContext &C, DeclContext *DC, SourceLocation Loc,
+ UsingDecl *Using, NamedDecl *Target)
: NamedDecl(UsingShadow, DC, Loc, DeclarationName()),
- Underlying(Target),
+ redeclarable_base(C), Underlying(Target),
UsingOrNextShadow(reinterpret_cast<NamedDecl *>(Using)) {
if (Target) {
setDeclName(Target->getDeclName());
@@ -2687,13 +2756,13 @@ class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> {
}
typedef Redeclarable<UsingShadowDecl> redeclarable_base;
- virtual UsingShadowDecl *getNextRedeclaration() {
- return RedeclLink.getNext();
+ UsingShadowDecl *getNextRedeclarationImpl() override {
+ return getNextRedeclaration();
}
- virtual UsingShadowDecl *getPreviousDeclImpl() {
+ UsingShadowDecl *getPreviousDeclImpl() override {
return getPreviousDecl();
}
- virtual UsingShadowDecl *getMostRecentDeclImpl() {
+ UsingShadowDecl *getMostRecentDeclImpl() override {
return getMostRecentDecl();
}
@@ -2701,21 +2770,23 @@ public:
static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation Loc, UsingDecl *Using,
NamedDecl *Target) {
- return new (C) UsingShadowDecl(DC, Loc, Using, Target);
+ return new (C, DC) UsingShadowDecl(C, DC, Loc, Using, Target);
}
static UsingShadowDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+ typedef redeclarable_base::redecl_range redecl_range;
typedef redeclarable_base::redecl_iterator redecl_iterator;
using redeclarable_base::redecls_begin;
using redeclarable_base::redecls_end;
+ using redeclarable_base::redecls;
using redeclarable_base::getPreviousDecl;
using redeclarable_base::getMostRecentDecl;
- virtual UsingShadowDecl *getCanonicalDecl() {
+ UsingShadowDecl *getCanonicalDecl() override {
return getFirstDecl();
}
- virtual const UsingShadowDecl *getCanonicalDecl() const {
+ const UsingShadowDecl *getCanonicalDecl() const {
return getFirstDecl();
}
@@ -2754,7 +2825,7 @@ public:
/// using someNameSpace::someIdentifier;
/// \endcode
class UsingDecl : public NamedDecl {
- virtual void anchor();
+ void anchor() override;
/// \brief The source location of the 'using' keyword itself.
SourceLocation UsingLocation;
@@ -2778,7 +2849,7 @@ class UsingDecl : public NamedDecl {
const DeclarationNameInfo &NameInfo, bool HasTypenameKeyword)
: NamedDecl(Using, DC, NameInfo.getLoc(), NameInfo.getName()),
UsingLocation(UL), QualifierLoc(QualifierLoc),
- DNLoc(NameInfo.getInfo()), FirstUsingShadow(0, HasTypenameKeyword) {
+ DNLoc(NameInfo.getInfo()), FirstUsingShadow(nullptr, HasTypenameKeyword) {
}
public:
@@ -2823,7 +2894,7 @@ public:
typedef std::forward_iterator_tag iterator_category;
typedef std::ptrdiff_t difference_type;
- shadow_iterator() : Current(0) { }
+ shadow_iterator() : Current(nullptr) { }
explicit shadow_iterator(UsingShadowDecl *C) : Current(C) { }
reference operator*() const { return Current; }
@@ -2848,6 +2919,11 @@ public:
}
};
+ typedef llvm::iterator_range<shadow_iterator> shadow_range;
+
+ shadow_range shadows() const {
+ return shadow_range(shadow_begin(), shadow_end());
+ }
shadow_iterator shadow_begin() const {
return shadow_iterator(FirstUsingShadow.getPointer());
}
@@ -2870,7 +2946,7 @@ public:
static UsingDecl *CreateDeserialized(ASTContext &C, unsigned ID);
- SourceRange getSourceRange() const LLVM_READONLY;
+ SourceRange getSourceRange() const override LLVM_READONLY;
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Using; }
@@ -2891,7 +2967,7 @@ public:
/// };
/// \endcode
class UnresolvedUsingValueDecl : public ValueDecl {
- virtual void anchor();
+ void anchor() override;
/// \brief The source location of the 'using' keyword
SourceLocation UsingLocation;
@@ -2944,7 +3020,7 @@ public:
static UnresolvedUsingValueDecl *
CreateDeserialized(ASTContext &C, unsigned ID);
- SourceRange getSourceRange() const LLVM_READONLY;
+ SourceRange getSourceRange() const override LLVM_READONLY;
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == UnresolvedUsingValue; }
@@ -2965,7 +3041,7 @@ public:
/// The type associated with an unresolved using typename decl is
/// currently always a typename type.
class UnresolvedUsingTypenameDecl : public TypeDecl {
- virtual void anchor();
+ void anchor() override;
/// \brief The source location of the 'typename' keyword
SourceLocation TypenameLocation;
@@ -3043,7 +3119,7 @@ public:
SourceLocation getRParenLoc() const { return RParenLoc; }
- SourceRange getSourceRange() const LLVM_READONLY {
+ SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(getLocation(), getRParenLoc());
}
@@ -3083,21 +3159,24 @@ public:
class MSPropertyDecl : public DeclaratorDecl {
IdentifierInfo *GetterId, *SetterId;
-public:
- MSPropertyDecl(DeclContext *DC, SourceLocation L,
- DeclarationName N, QualType T, TypeSourceInfo *TInfo,
- SourceLocation StartL, IdentifierInfo *Getter,
- IdentifierInfo *Setter):
- DeclaratorDecl(MSProperty, DC, L, N, T, TInfo, StartL), GetterId(Getter),
- SetterId(Setter) {}
+ MSPropertyDecl(DeclContext *DC, SourceLocation L, DeclarationName N,
+ QualType T, TypeSourceInfo *TInfo, SourceLocation StartL,
+ IdentifierInfo *Getter, IdentifierInfo *Setter)
+ : DeclaratorDecl(MSProperty, DC, L, N, T, TInfo, StartL),
+ GetterId(Getter), SetterId(Setter) {}
+public:
+ static MSPropertyDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L, DeclarationName N, QualType T,
+ TypeSourceInfo *TInfo, SourceLocation StartL,
+ IdentifierInfo *Getter, IdentifierInfo *Setter);
static MSPropertyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
static bool classof(const Decl *D) { return D->getKind() == MSProperty; }
- bool hasGetter() const { return GetterId != NULL; }
+ bool hasGetter() const { return GetterId != nullptr; }
IdentifierInfo* getGetterId() const { return GetterId; }
- bool hasSetter() const { return SetterId != NULL; }
+ bool hasSetter() const { return SetterId != nullptr; }
IdentifierInfo* getSetterId() const { return SetterId; }
friend class ASTDeclReader;