diff options
Diffstat (limited to 'contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h')
-rw-r--r-- | contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h | 383 |
1 files changed, 231 insertions, 152 deletions
diff --git a/contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h b/contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h index dbc4132..72fad7c 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/DeclCXX.h +++ b/contrib/llvm/tools/clang/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; |