diff options
Diffstat (limited to 'include/clang/AST/DeclCXX.h')
-rw-r--r-- | include/clang/AST/DeclCXX.h | 343 |
1 files changed, 65 insertions, 278 deletions
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 7add83f89624..66212f72b787 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -42,6 +42,7 @@ #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/iterator_range.h" +#include "llvm/BinaryFormat/Dwarf.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/PointerLikeTypeTraits.h" @@ -73,52 +74,6 @@ class TemplateDecl; class TemplateParameterList; class UsingDecl; -/// Represents any kind of function declaration, whether it is a -/// concrete function or a function template. -class AnyFunctionDecl { - NamedDecl *Function; - - AnyFunctionDecl(NamedDecl *ND) : Function(ND) {} - -public: - AnyFunctionDecl(FunctionDecl *FD) : Function(FD) {} - AnyFunctionDecl(FunctionTemplateDecl *FTD); - - /// Implicily converts any function or function template into a - /// named declaration. - operator NamedDecl *() const { return Function; } - - /// Retrieve the underlying function or function template. - NamedDecl *get() const { return Function; } - - static AnyFunctionDecl getFromNamedDecl(NamedDecl *ND) { - return AnyFunctionDecl(ND); - } -}; - -} // namespace clang - -namespace llvm { - - // Provide PointerLikeTypeTraits for non-cvr pointers. - template<> - struct PointerLikeTypeTraits< ::clang::AnyFunctionDecl> { - static void *getAsVoidPointer(::clang::AnyFunctionDecl F) { - return F.get(); - } - - static ::clang::AnyFunctionDecl getFromVoidPointer(void *P) { - return ::clang::AnyFunctionDecl::getFromNamedDecl( - static_cast< ::clang::NamedDecl*>(P)); - } - - enum { NumLowBitsAvailable = 2 }; - }; - -} // namespace llvm - -namespace clang { - /// Represents an access specifier followed by colon ':'. /// /// An objects of this class represents sugar for the syntactic occurrence @@ -322,207 +277,9 @@ class CXXRecordDecl : public RecordDecl { }; struct DefinitionData { - /// True if this class has any user-declared constructors. - unsigned UserDeclaredConstructor : 1; - - /// The user-declared special members which this class has. - unsigned UserDeclaredSpecialMembers : 6; - - /// True when this class is an aggregate. - unsigned Aggregate : 1; - - /// True when this class is a POD-type. - unsigned PlainOldData : 1; - - /// True when this class is empty for traits purposes, that is: - /// * has no data members other than 0-width bit-fields and empty fields - /// marked [[no_unique_address]] - /// * has no virtual function/base, and - /// * doesn't inherit from a non-empty class. - /// Doesn't take union-ness into account. - unsigned Empty : 1; - - /// True when this class is polymorphic, i.e., has at - /// least one virtual member or derives from a polymorphic class. - unsigned Polymorphic : 1; - - /// True when this class is abstract, i.e., has at least - /// one pure virtual function, (that can come from a base class). - unsigned Abstract : 1; - - /// True when this class is standard-layout, per the applicable - /// language rules (including DRs). - unsigned IsStandardLayout : 1; - - /// True when this class was standard-layout under the C++11 - /// definition. - /// - /// C++11 [class]p7. A standard-layout class is a class that: - /// * has no non-static data members of type non-standard-layout class (or - /// array of such types) or reference, - /// * has no virtual functions (10.3) and no virtual base classes (10.1), - /// * has the same access control (Clause 11) for all non-static data - /// members - /// * has no non-standard-layout base classes, - /// * either has no non-static data members in the most derived class and at - /// most one base class with non-static data members, or has no base - /// classes with non-static data members, and - /// * has no base classes of the same type as the first non-static data - /// member. - unsigned IsCXX11StandardLayout : 1; - - /// True when any base class has any declared non-static data - /// members or bit-fields. - /// This is a helper bit of state used to implement IsStandardLayout more - /// efficiently. - unsigned HasBasesWithFields : 1; - - /// True when any base class has any declared non-static data - /// members. - /// This is a helper bit of state used to implement IsCXX11StandardLayout - /// more efficiently. - unsigned HasBasesWithNonStaticDataMembers : 1; - - /// True when there are private non-static data members. - unsigned HasPrivateFields : 1; - - /// True when there are protected non-static data members. - unsigned HasProtectedFields : 1; - - /// True when there are private non-static data members. - unsigned HasPublicFields : 1; - - /// True if this class (or any subobject) has mutable fields. - unsigned HasMutableFields : 1; - - /// True if this class (or any nested anonymous struct or union) - /// has variant members. - unsigned HasVariantMembers : 1; - - /// True if there no non-field members declared by the user. - unsigned HasOnlyCMembers : 1; - - /// True if any field has an in-class initializer, including those - /// within anonymous unions or structs. - unsigned HasInClassInitializer : 1; - - /// True if any field is of reference type, and does not have an - /// in-class initializer. - /// - /// In this case, value-initialization of this class is illegal in C++98 - /// even if the class has a trivial default constructor. - unsigned HasUninitializedReferenceMember : 1; - - /// True if any non-mutable field whose type doesn't have a user- - /// provided default ctor also doesn't have an in-class initializer. - unsigned HasUninitializedFields : 1; - - /// True if there are any member using-declarations that inherit - /// constructors from a base class. - unsigned HasInheritedConstructor : 1; - - /// True if there are any member using-declarations named - /// 'operator='. - unsigned HasInheritedAssignment : 1; - - /// These flags are \c true if a defaulted corresponding special - /// member can't be fully analyzed without performing overload resolution. - /// @{ - unsigned NeedOverloadResolutionForCopyConstructor : 1; - unsigned NeedOverloadResolutionForMoveConstructor : 1; - unsigned NeedOverloadResolutionForMoveAssignment : 1; - unsigned NeedOverloadResolutionForDestructor : 1; - /// @} - - /// These flags are \c true if an implicit defaulted corresponding - /// special member would be defined as deleted. - /// @{ - unsigned DefaultedCopyConstructorIsDeleted : 1; - unsigned DefaultedMoveConstructorIsDeleted : 1; - unsigned DefaultedMoveAssignmentIsDeleted : 1; - unsigned DefaultedDestructorIsDeleted : 1; - /// @} - - /// The trivial special members which this class has, per - /// C++11 [class.ctor]p5, C++11 [class.copy]p12, C++11 [class.copy]p25, - /// C++11 [class.dtor]p5, or would have if the member were not suppressed. - /// - /// This excludes any user-declared but not user-provided special members - /// which have been declared but not yet defined. - unsigned HasTrivialSpecialMembers : 6; - - /// These bits keep track of the triviality of special functions for the - /// purpose of calls. Only the bits corresponding to SMF_CopyConstructor, - /// SMF_MoveConstructor, and SMF_Destructor are meaningful here. - unsigned HasTrivialSpecialMembersForCall : 6; - - /// The declared special members of this class which are known to be - /// non-trivial. - /// - /// This excludes any user-declared but not user-provided special members - /// which have been declared but not yet defined, and any implicit special - /// members which have not yet been declared. - unsigned DeclaredNonTrivialSpecialMembers : 6; - - /// These bits keep track of the declared special members that are - /// non-trivial for the purpose of calls. - /// Only the bits corresponding to SMF_CopyConstructor, - /// SMF_MoveConstructor, and SMF_Destructor are meaningful here. - unsigned DeclaredNonTrivialSpecialMembersForCall : 6; - - /// True when this class has a destructor with no semantic effect. - unsigned HasIrrelevantDestructor : 1; - - /// True when this class has at least one user-declared constexpr - /// constructor which is neither the copy nor move constructor. - unsigned HasConstexprNonCopyMoveConstructor : 1; - - /// True if this class has a (possibly implicit) defaulted default - /// constructor. - unsigned HasDefaultedDefaultConstructor : 1; - - /// True if a defaulted default constructor for this class would - /// be constexpr. - unsigned DefaultedDefaultConstructorIsConstexpr : 1; - - /// 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. - unsigned HasConstexprDefaultConstructor : 1; - - /// True when this class contains at least one non-static data - /// member or base class of non-literal or volatile type. - unsigned HasNonLiteralTypeFieldsOrBases : 1; - - /// True when visible conversion functions are already computed - /// and are available. - unsigned ComputedVisibleConversions : 1; - - /// Whether we have a C++11 user-provided default constructor (not - /// explicitly deleted or defaulted). - unsigned UserProvidedDefaultConstructor : 1; - - /// The special members which have been declared for this class, - /// either by the user or implicitly. - unsigned DeclaredSpecialMembers : 6; - - /// Whether an implicit copy constructor could have a const-qualified - /// parameter, for initializing virtual bases and for other subobjects. - unsigned ImplicitCopyConstructorCanHaveConstParamForVBase : 1; - unsigned ImplicitCopyConstructorCanHaveConstParamForNonVBase : 1; - - /// Whether an implicit copy assignment operator would have a - /// const-qualified parameter. - unsigned ImplicitCopyAssignmentHasConstParam : 1; - - /// Whether any declared copy constructor has a const-qualified - /// parameter. - unsigned HasDeclaredCopyConstructorWithConstParam : 1; - - /// Whether any declared copy assignment operator has either a - /// const-qualified reference parameter or a non-reference parameter. - unsigned HasDeclaredCopyAssignmentWithConstParam : 1; + #define FIELD(Name, Width, Merge) \ + unsigned Name : Width; + #include "CXXRecordDeclDefinitionBits.def" /// Whether this class describes a C++ lambda. unsigned IsLambda : 1; @@ -530,6 +287,10 @@ class CXXRecordDecl : public RecordDecl { /// Whether we are currently parsing base specifiers. unsigned IsParsingBaseSpecifiers : 1; + /// True when visible conversion functions are already computed + /// and are available. + unsigned ComputedVisibleConversions : 1; + unsigned HasODRHash : 1; /// A hash of parts of the class to help in ODR checking. @@ -628,9 +389,12 @@ class CXXRecordDecl : public RecordDecl { /// The number of explicit captures in this lambda. unsigned NumExplicitCaptures : 13; + /// Has known `internal` linkage. + unsigned HasKnownInternalLinkage : 1; + /// The number used to indicate this lambda expression for name /// mangling in the Itanium C++ ABI. - unsigned ManglingNumber = 0; + unsigned ManglingNumber : 31; /// The declaration that provides context for this lambda, if the /// actual DeclContext does not suffice. This is used for lambdas that @@ -645,12 +409,12 @@ class CXXRecordDecl : public RecordDecl { /// The type of the call method. TypeSourceInfo *MethodTyInfo; - LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info, - bool Dependent, bool IsGeneric, - LambdaCaptureDefault CaptureDefault) - : DefinitionData(D), Dependent(Dependent), IsGenericLambda(IsGeneric), - CaptureDefault(CaptureDefault), NumCaptures(0), NumExplicitCaptures(0), - MethodTyInfo(Info) { + LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info, bool Dependent, + bool IsGeneric, LambdaCaptureDefault CaptureDefault) + : DefinitionData(D), Dependent(Dependent), IsGenericLambda(IsGeneric), + CaptureDefault(CaptureDefault), NumCaptures(0), + NumExplicitCaptures(0), HasKnownInternalLinkage(0), ManglingNumber(0), + MethodTyInfo(Info) { IsLambda = true; // C++1z [expr.prim.lambda]p4: @@ -1214,6 +978,10 @@ public: /// if this is a closure type. CXXMethodDecl *getLambdaCallOperator() const; + /// Retrieve the dependent lambda call operator of the closure type + /// if this is a templated closure type. + FunctionTemplateDecl *getDependentLambdaCallOperator() const; + /// Retrieve the lambda static invoker, the address of which /// is returned by the conversion operator, and the body of which /// is forwarded to the lambda call operator. @@ -1398,7 +1166,8 @@ public: /// would be constexpr. bool defaultedDefaultConstructorIsConstexpr() const { return data().DefaultedDefaultConstructorIsConstexpr && - (!isUnion() || hasInClassInitializer() || !hasVariantMembers()); + (!isUnion() || hasInClassInitializer() || !hasVariantMembers() || + getASTContext().getLangOpts().CPlusPlus2a); } /// Determine whether this class has a constexpr default constructor. @@ -1486,6 +1255,16 @@ public: !(data().HasTrivialSpecialMembers & SMF_MoveAssignment)); } + /// Determine whether a defaulted default constructor for this class + /// would be constexpr. + bool defaultedDestructorIsConstexpr() const { + return data().DefaultedDestructorIsConstexpr && + getASTContext().getLangOpts().CPlusPlus2a; + } + + /// Determine whether this class has a constexpr destructor. + bool hasConstexprDestructor() const; + /// Determine whether this class has a trivial destructor /// (C++ [class.dtor]p3) bool hasTrivialDestructor() const { @@ -1577,8 +1356,10 @@ public: /// /// Only in C++17 and beyond, are lambdas literal types. bool isLiteral() const { - return hasTrivialDestructor() && - (!isLambda() || getASTContext().getLangOpts().CPlusPlus17) && + ASTContext &Ctx = getASTContext(); + return (Ctx.getLangOpts().CPlusPlus2a ? hasConstexprDestructor() + : hasTrivialDestructor()) && + (!isLambda() || Ctx.getLangOpts().CPlusPlus17) && !hasNonLiteralTypeFieldsOrBases() && (isAggregate() || isLambda() || hasConstexprNonCopyMoveConstructor() || @@ -1927,6 +1708,13 @@ public: return getLambdaData().ManglingNumber; } + /// The lambda is known to has internal linkage no matter whether it has name + /// mangling number. + bool hasKnownLambdaInternalLinkage() const { + assert(isLambda() && "Not a lambda closure type!"); + return getLambdaData().HasKnownInternalLinkage; + } + /// Retrieve the declaration that provides additional context for a /// lambda, when the normal declaration context is not specific enough. /// @@ -1940,9 +1728,12 @@ public: /// Set the mangling number and context declaration for a lambda /// class. - void setLambdaMangling(unsigned ManglingNumber, Decl *ContextDecl) { + void setLambdaMangling(unsigned ManglingNumber, Decl *ContextDecl, + bool HasKnownInternalLinkage = false) { + assert(isLambda() && "Not a lambda closure type!"); getLambdaData().ManglingNumber = ManglingNumber; getLambdaData().ContextDecl = ContextDecl; + getLambdaData().HasKnownInternalLinkage = HasKnownInternalLinkage; } /// Returns the inheritance model used for this record. @@ -2265,7 +2056,7 @@ public: const CXXRecordDecl *Decl); Qualifiers getMethodQualifiers() const { - return getType()->getAs<FunctionProtoType>()->getMethodQuals(); + return getType()->castAs<FunctionProtoType>()->getMethodQuals(); } /// Retrieve the ref-qualifier associated with this method. @@ -2280,7 +2071,7 @@ public: /// }; /// @endcode RefQualifierKind getRefQualifier() const { - return getType()->getAs<FunctionProtoType>()->getRefQualifier(); + return getType()->castAs<FunctionProtoType>()->getRefQualifier(); } bool hasInlineBody() const; @@ -2600,9 +2391,9 @@ class CXXConstructorDecl final ExplicitSpecifier getExplicitSpecifierInternal() const { if (CXXConstructorDeclBits.HasTrailingExplicitSpecifier) - return *getCanonicalDecl()->getTrailingObjects<ExplicitSpecifier>(); + return *getTrailingObjects<ExplicitSpecifier>(); return ExplicitSpecifier( - nullptr, getCanonicalDecl()->CXXConstructorDeclBits.IsSimpleExplicit + nullptr, CXXConstructorDeclBits.IsSimpleExplicit ? ExplicitSpecKind::ResolvedTrue : ExplicitSpecKind::ResolvedFalse); } @@ -2643,10 +2434,10 @@ public: InheritedConstructor Inherited = InheritedConstructor()); ExplicitSpecifier getExplicitSpecifier() { - return getExplicitSpecifierInternal(); + return getCanonicalDecl()->getExplicitSpecifierInternal(); } const ExplicitSpecifier getExplicitSpecifier() const { - return getExplicitSpecifierInternal(); + return getCanonicalDecl()->getExplicitSpecifierInternal(); } /// Return true if the declartion is already resolved to be explicit. @@ -2847,9 +2638,9 @@ class CXXDestructorDecl : public CXXMethodDecl { CXXDestructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, bool isInline, - bool isImplicitlyDeclared) + bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind) : CXXMethodDecl(CXXDestructor, C, RD, StartLoc, NameInfo, T, TInfo, - SC_None, isInline, CSK_unspecified, SourceLocation()) { + SC_None, isInline, ConstexprKind, SourceLocation()) { setImplicit(isImplicitlyDeclared); } @@ -2859,9 +2650,9 @@ public: static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, - QualType T, TypeSourceInfo* TInfo, - bool isInline, - bool isImplicitlyDeclared); + QualType T, TypeSourceInfo *TInfo, + bool isInline, bool isImplicitlyDeclared, + ConstexprSpecKind ConstexprKind); static CXXDestructorDecl *CreateDeserialized(ASTContext & C, unsigned ID); void setOperatorDelete(FunctionDecl *OD, Expr *ThisArg); @@ -2934,7 +2725,7 @@ public: /// Returns the type that this conversion function is converting to. QualType getConversionType() const { - return getType()->getAs<FunctionType>()->getReturnType(); + return getType()->castAs<FunctionType>()->getReturnType(); } /// Determine whether this conversion function is a conversion from @@ -2971,8 +2762,10 @@ public: /// ensure a stable ABI for this, we choose the DW_LANG_ encodings /// from the dwarf standard. enum LanguageIDs { - lang_c = /* DW_LANG_C */ 0x0002, - lang_cxx = /* DW_LANG_C_plus_plus */ 0x0004 + lang_c = llvm::dwarf::DW_LANG_C, + lang_cxx = llvm::dwarf::DW_LANG_C_plus_plus, + lang_cxx_11 = llvm::dwarf::DW_LANG_C_plus_plus_11, + lang_cxx_14 = llvm::dwarf::DW_LANG_C_plus_plus_14 }; private: @@ -3469,12 +3262,6 @@ public: return IsVirtual; } - /// Get the constructor or constructor template in the derived class - /// correspnding to this using shadow declaration, if it has been implicitly - /// declared already. - CXXConstructorDecl *getConstructor() const; - void setConstructor(NamedDecl *Ctor); - static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == ConstructorUsingShadow; } }; |