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.h343
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; }
};