diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -1169,6 +1169,10 @@ * ``__is_trivially_constructible`` (C++, GNU, Microsoft) * ``__is_trivially_copyable`` (C++, GNU, Microsoft) * ``__is_trivially_destructible`` (C++, MSVC 2013) +* ``__is_trivially_relocatable`` (Clang): Determines whether moving an object + of type ``type``, and then destroying the source object, is functionally + equivalent to copying the underlying bytes and then dropping the source object + on the floor. * ``__is_union`` (C++, GNU, Microsoft, Embarcadero) * ``__is_unsigned`` (C++, Embarcadero) Note that this currently returns true for enumeration types if the underlying diff --git a/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def b/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def --- a/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def +++ b/clang/include/clang/AST/CXXRecordDeclDefinitionBits.def @@ -180,6 +180,16 @@ /// SMF_MoveConstructor, and SMF_Destructor are meaningful here. FIELD(DeclaredNonTrivialSpecialMembersForCall, 6, MERGE_OR) +/// True when this class's bases and fields are all trivially relocatable +/// or references, and the class itself has a defaulted move constructor +/// and a defaulted destructor. +FIELD(IsNaturallyTriviallyRelocatable, 1, NO_MERGE) + +/// True when this class has a base or field which is not trivially +/// relocatable. This negates the effect of the +/// [[clang::maybe_trivially_relocatable]] attribute. +FIELD(HasNonTriviallyRelocatableSubobject, 1, NO_MERGE) + /// True when this class has a destructor with no semantic effect. FIELD(HasIrrelevantDestructor, 1, NO_MERGE) diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -1289,6 +1289,21 @@ (SMF_CopyConstructor | SMF_MoveConstructor | SMF_Destructor); } + /// Determine whether this class is trivially relocatable + bool isTriviallyRelocatable() const; + + void setIsNotNaturallyTriviallyRelocatable() { + data().IsNaturallyTriviallyRelocatable = false; + } + + bool hasNonTriviallyRelocatableSubobject() const { + return data().HasNonTriviallyRelocatableSubobject; + } + + void setHasNonTriviallyRelocatableSubobject() { + data().HasNonTriviallyRelocatableSubobject = true; + } + /// Determine whether declaring a const variable with this type is ok /// per core issue 253. bool allowConstDefaultInit() const { diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -808,6 +808,9 @@ /// Return true if this is a trivially copyable type (C++0x [basic.types]p9) bool isTriviallyCopyableType(const ASTContext &Context) const; + /// Return true if this is a trivially relocatable type + bool isTriviallyRelocatableType(const ASTContext &Context) const; + /// Returns true if it is a class and it might be dynamic. bool mayBeDynamicClass() const; diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -2332,6 +2332,21 @@ let Documentation = [Undocumented]; } +def TriviallyRelocatable : InheritableAttr { + let Spellings = [Clang<"trivially_relocatable", 0>]; + let Subjects = SubjectList<[CXXRecord]>; + let Args = [ExprArgument<"Cond", 1>]; + let Documentation = [TriviallyRelocatableDocs]; + let LangOpts = [CPlusPlus]; +} + +def MaybeTriviallyRelocatable : InheritableAttr { + let Spellings = [Clang<"maybe_trivially_relocatable", 0>]; + let Subjects = SubjectList<[CXXRecord]>; + let Documentation = [MaybeTriviallyRelocatableDocs]; + let LangOpts = [CPlusPlus]; +} + def Unused : InheritableAttr { let Spellings = [CXX11<"", "maybe_unused", 201603>, GCC<"unused">, C2x<"", "maybe_unused">]; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -2799,6 +2799,28 @@ }]; } +def TriviallyRelocatableDocs : Documentation { + let Category = DocCatVariable; + let Content = [{ +The ``trivially_relocatable`` attribute can be applied to a C++ class, struct, or union. +It warrants to the compiler that moving an object of that type, and then destroying the +source object, is functionally equivalent to copying the underlying bytes +and then dropping the source object on the floor. + }]; +} + +def MaybeTriviallyRelocatableDocs : Documentation { + let Category = DocCatVariable; + let Content = [{ +The ``maybe_trivially_relocatable`` attribute can be applied to a C++ class, struct, or union. +It warrants to the compiler that moving an object of that type, and then destroying the +source object, is functionally equivalent to copying the underlying bytes +and then dropping the source object on the floor... But, if the type to which it +is applied has any direct subobjects of non-trivially relocatable type, then this +attribute has no effect. + }]; +} + def MSInheritanceDocs : Documentation { let Category = DocCatDecl; let Heading = "__single_inhertiance, __multiple_inheritance, __virtual_inheritance"; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3131,6 +3131,11 @@ def ext_cannot_use_trivial_abi : ExtWarn< "'trivial_abi' cannot be applied to %0">, InGroup; +def err_trivially_relocatable_class_is_not_relocatable : Error< + "'trivially_relocatable' cannot be applied to " + "%select{struct|interface|union|class|enum}0 %1 because it is " + "not %select{move-constructible|destructible}2">; + // Availability attribute def warn_availability_unknown_platform : Warning< "unknown platform %0 in availability macro">, InGroup; @@ -8805,6 +8810,11 @@ def err_block_on_vm : Error< "__block attribute not allowed on declaration with a variably modified type">; +def err_attribute_missing_on_first_decl : Error< + "type %0 declared %1 after its first declaration">; +def note_attribute_missing_first_decl : Note< + "declaration missing %0 attribute is here">; + def err_vec_builtin_non_vector : Error< "first two arguments to %0 must be vectors">; def err_vec_builtin_incompatible_vector : Error< diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -248,6 +248,7 @@ EXTENSION(cxx_init_captures, LangOpts.CPlusPlus11) EXTENSION(cxx_variable_templates, LangOpts.CPlusPlus) // Miscellaneous language extensions +EXTENSION(trivially_relocatable, LangOpts.CPlusPlus11) EXTENSION(overloadable_unmarked, true) EXTENSION(pragma_clang_attribute_namespaces, true) EXTENSION(pragma_clang_attribute_external_declaration, true) diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -489,6 +489,7 @@ KEYWORD(__underlying_type , KEYCXX) // Clang-only C++ Type Traits +TYPE_TRAIT_1(__is_trivially_relocatable, IsTriviallyRelocatable, KEYCXX) TYPE_TRAIT_2(__reference_binds_to_temporary, ReferenceBindsToTemporary, KEYCXX) // Embarcadero Expression Traits diff --git a/clang/include/clang/Basic/TypeTraits.h b/clang/include/clang/Basic/TypeTraits.h --- a/clang/include/clang/Basic/TypeTraits.h +++ b/clang/include/clang/Basic/TypeTraits.h @@ -65,6 +65,7 @@ UTT_IsTrivial, UTT_IsTriviallyCopyable, UTT_IsTriviallyDestructible, + UTT_IsTriviallyRelocatable, UTT_IsUnion, UTT_IsUnsigned, UTT_IsVoid, diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -91,7 +91,10 @@ DefaultedDestructorIsDeleted(false), HasTrivialSpecialMembers(SMF_All), HasTrivialSpecialMembersForCall(SMF_All), DeclaredNonTrivialSpecialMembers(0), - DeclaredNonTrivialSpecialMembersForCall(0), HasIrrelevantDestructor(true), + DeclaredNonTrivialSpecialMembersForCall(0), + IsNaturallyTriviallyRelocatable(true), + HasNonTriviallyRelocatableSubobject(false), + HasIrrelevantDestructor(true), HasConstexprNonCopyMoveConstructor(false), HasDefaultedDefaultConstructor(false), DefaultedDefaultConstructorIsConstexpr(true), @@ -280,6 +283,11 @@ if (!hasNonLiteralTypeFieldsOrBases() && !BaseType->isLiteralType(C)) data().HasNonLiteralTypeFieldsOrBases = true; + if (Base->isVirtual() || !BaseClassDecl->isTriviallyRelocatable()) { + setIsNotNaturallyTriviallyRelocatable(); + setHasNonTriviallyRelocatableSubobject(); + } + // Now go through all virtual bases of this base and add them. for (const auto &VBase : BaseClassDecl->vbases()) { // Add this base if it's not already in the list. @@ -547,6 +555,13 @@ return !forallBases([](const CXXRecordDecl *) { return true; }); } +bool CXXRecordDecl::isTriviallyRelocatable() const { + return (data().IsNaturallyTriviallyRelocatable || + hasAttr() || + (hasAttr() && + !data().HasNonTriviallyRelocatableSubobject)); +} + bool CXXRecordDecl::isTriviallyCopyable() const { // C++0x [class]p5: // A trivially copyable class is a class that: diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp --- a/clang/lib/AST/JSONNodeDumper.cpp +++ b/clang/lib/AST/JSONNodeDumper.cpp @@ -438,6 +438,7 @@ FIELD1(isAggregate); FIELD1(isStandardLayout); FIELD1(isTriviallyCopyable); + FIELD1(isTriviallyRelocatable); FIELD1(isPOD); FIELD1(isTrivial); FIELD1(isPolymorphic); diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -1558,6 +1558,7 @@ FLAG(isAggregate, aggregate); FLAG(isStandardLayout, standard_layout); FLAG(isTriviallyCopyable, trivially_copyable); + FLAG(isTriviallyRelocatable, trivially_relocatable); FLAG(isPOD, pod); FLAG(isTrivial, trivial); FLAG(isPolymorphic, polymorphic); diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -2321,6 +2321,19 @@ return false; } +bool QualType::isTriviallyRelocatableType(const ASTContext &Context) const { + QualType T = Context.getBaseElementType(getCanonicalType()); + if (T->isIncompleteType()) + return false; + if (CXXRecordDecl *RD = T->getAsCXXRecordDecl()) { + return RD->isTriviallyRelocatable(); + } else { + // Non-class types are always both move-constructible and destructible, + // so just check whether a non-class type is trivially copyable. + return T.isTriviallyCopyableType(Context); + } +} + bool QualType::isNonWeakInMRRWithObjCWeak(const ASTContext &Context) const { return !Context.getLangOpts().ObjCAutoRefCount && Context.getLangOpts().ObjCWeak && diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -16750,6 +16750,28 @@ Record->setArgPassingRestrictions(RecordDecl::APK_CanNeverPassInRegs); } + if (CXXRecord) { + QualType FT = FD->getType(); + if (FD->isMutable() || FT.isVolatileQualified()) { + CXXRecord->setIsNotNaturallyTriviallyRelocatable(); + CXXRecord->setHasNonTriviallyRelocatableSubobject(); + } else if (!FT->isReferenceType() && !FT.isTriviallyRelocatableType(Context)) { + CXXRecord->setIsNotNaturallyTriviallyRelocatable(); + bool cxx_record_has_nontrivially_relocatable_subobject = true; + if (FD->isAnonymousStructOrUnion()) { + // Anonymous unions are "see-through." + QualType T = Context.getBaseElementType(FT.getCanonicalType()); + if (CXXRecordDecl *RD = T->getAsCXXRecordDecl()) { + cxx_record_has_nontrivially_relocatable_subobject = + RD->hasNonTriviallyRelocatableSubobject(); + } + } + if (cxx_record_has_nontrivially_relocatable_subobject) { + CXXRecord->setHasNonTriviallyRelocatableSubobject(); + } + } + } + if (Record && FD->getType().isVolatileQualified()) Record->setHasVolatileMember(true); // Keep track of the number of named members. diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -6072,6 +6072,44 @@ D->addAttr(::new (S.Context) LayoutVersionAttr(S.Context, AL, Version)); } +#if 0 +template +static void checkAttributeNotOnFirstDecl(Sema &S, Decl *D, const ParsedAttr &AL) { + Decl *FirstD = D->getCanonicalDecl(); + if (FirstD != D && !FirstD->hasAttr()) { + NamedDecl *ND = dyn_cast(D); + S.Diag(AL.getLoc(), diag::err_attribute_missing_on_first_decl) + << (ND ? ND->getDeclName().getAsString() : "") << AL.getName(); + S.Diag(FirstD->getLocation(), diag::note_attribute_missing_first_decl) + << AL.getName() + << FirstD->getSourceRange(); + } +} +#endif + +static void handleTriviallyRelocatableAttr(Sema &S, Decl *D, const ParsedAttr &AL) { + // checkAttributeNotOnFirstDecl(S, D, AL); + + Expr *Cond = nullptr; + if (AL.getNumArgs() == 1) { + Cond = AL.getArgAsExpr(0); + if (!Cond->isTypeDependent()) { + ExprResult Converted = S.PerformContextuallyConvertToBool(Cond); + if (Converted.isInvalid()) { + return; + } + Cond = Converted.get(); + } + } + + D->addAttr(::new (S.Context) TriviallyRelocatableAttr(S.Context, AL, Cond)); +} + +static void handleMaybeTriviallyRelocatableAttr(Sema &S, Decl *D, const ParsedAttr &AL) { + // checkAttributeNotOnFirstDecl(S, D, AL); + handleSimpleAttribute(S, D, AL); +} + DLLImportAttr *Sema::mergeDLLImportAttr(Decl *D, const AttributeCommonInfo &CI) { if (D->hasAttr()) { @@ -7232,6 +7270,12 @@ case ParsedAttr::AT_TrivialABI: handleSimpleAttribute(S, D, AL); break; + case ParsedAttr::AT_TriviallyRelocatable: + handleTriviallyRelocatableAttr(S, D, AL); + break; + case ParsedAttr::AT_MaybeTriviallyRelocatable: + handleMaybeTriviallyRelocatableAttr(S, D, AL); + break; case ParsedAttr::AT_MSNoVTable: handleSimpleAttribute(S, D, AL); break; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -6293,6 +6293,36 @@ return HasNonDeletedCopyOrMove; } +static bool lookupTrivialDestructor(Sema &S, CXXRecordDecl *R, + bool AlwaysUseLookup) { + if (AlwaysUseLookup || R->hasUserDeclaredDestructor() || + R->needsOverloadResolutionForDestructor() || + (R->needsImplicitDestructor() && !R->hasTrivialDestructor())) { + + Sema::SpecialMemberOverloadResult SMOR = S.LookupSpecialMember( + R, Sema::CXXDestructor, false, false, false, false, false); + return SMOR.getKind() == Sema::SpecialMemberOverloadResult::Success; + } + + return R->hasTrivialDestructor(); +} + +static bool lookupTrivialMoveConstructor(Sema &S, CXXRecordDecl *R, + bool AlwaysUseLookup) { + if (AlwaysUseLookup || R->hasUserDeclaredMoveConstructor() || + R->needsOverloadResolutionForMoveConstructor() || + (R->needsImplicitMoveConstructor() && !R->hasTrivialMoveConstructor()) || + !R->hasMoveConstructor()) { + + Sema::SpecialMemberOverloadResult SMOR = S.LookupSpecialMember( + R, Sema::CXXMoveConstructor, false, false, false, false, false); + + return SMOR.getKind() == Sema::SpecialMemberOverloadResult::Success; + } + + return R->hasTrivialMoveConstructor(); +} + /// Perform semantic checks on a class definition that has been /// completing, introducing implicitly-declared members, checking for /// abstract types, etc. @@ -6450,6 +6480,27 @@ Record->setTrivialForCallFlags(M); } + // A move-constructible, destructible object type T is a + // trivially relocatable type if it ... + if (CSM == CXXMoveConstructor && M->isUserProvided()) { + // - has no user-provided move constructors, + Record->setIsNotNaturallyTriviallyRelocatable(); + } else if (CSM == CXXCopyConstructor && M->isUserProvided()) { + // - either has at least one move constructor or + // has no user-provided copy constructors, + if (!Record->hasMoveConstructor()) + Record->setIsNotNaturallyTriviallyRelocatable(); + } else if (CSM == CXXDestructor && + (M->isUserProvided() || M->isDeleted())) { + // - has a defaulted, non-deleted destructor, + Record->setIsNotNaturallyTriviallyRelocatable(); + } else if (CSM == CXXDestructor && M->isVirtual()) { + // - either is final, or has a final destructor, + // or has a non-virtual destructor ... + if (!M->hasAttr() && !Record->hasAttr()) + Record->setIsNotNaturallyTriviallyRelocatable(); + } + if (!M->isInvalidDecl() && M->isExplicitlyDefaulted() && M->hasAttr()) { if (getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015) && @@ -6561,6 +6612,73 @@ // is especially required for cases like vtable assumption loads. MarkVTableUsed(Record->getInnerLocStart(), Record); } + + if (getLangOpts().CPlusPlus11 && !Record->isDependentContext()) { + + // Deal with [[trivially_relocatable(condition)]]. + if (auto *TRA = Record->getAttr()) { + if (Expr *Arg = TRA->getCond()) { + // Evaluate the condition. If it's ill-formed, ignore the attribute. + // If it's well-formed and false, render this type NOT trivially relocatable. + SFINAETrap Trap(*this); + bool Result = false; + if (!Arg->EvaluateAsBooleanCondition(Result, Context)) { + // An ill-formed, non-constant, or non-boolean expression drops the attribute. + Record->dropAttr(); + } else if (!Result) { + // A well-formed "false" disables trivial relocation for this class. + // I have no use-case for this behavior, but it seems more logical than + // allowing a [[trivially_relocatable(false)]] class to be trivially + // relocatable. + Record->setIsNotNaturallyTriviallyRelocatable(); + Record->dropAttr(); + } + } + } + + // Determine whether a Record is TriviallyRelocatable. The helper functions + // can use two methods: + // - Call Sema::LookupSpecialMember this call always works but it adds + // special member function declarations to the CXXRecordDecl record. This + // is increases the size of the AST for simple classes, which is + // unwanted. For example the type_traits helper classes. + // - Look at the DefinitionData's HasTrivialSpecialMembers field. This + // value isn't always reliable. Therefore we need to test whether we can + // use this value. + // If AlwaysUseLookup represents the cases where we always need to use the + // call to Sema::LookupSpecialMember. The helper functions themselves have + // additional tests for their specific call. + bool AlwaysUseLookup = Record->isPolymorphic() || + Record->hasAttr() || + Record->hasAttr(); + if (!lookupTrivialDestructor(*this, Record, AlwaysUseLookup)) { + Record->setIsNotNaturallyTriviallyRelocatable(); + if (Record->hasAttr()) { + Record->dropAttr(); + if (!isTemplateInstantiation(Record->getTemplateSpecializationKind())) { + Diag(Record->getLocation(), + diag::err_trivially_relocatable_class_is_not_relocatable) + << Record->getCanonicalDecl()->getTagKind() + << Context.getRecordType(Record) << true; + } + } + if (Record->hasAttr()) + Record->dropAttr(); + } else if (!lookupTrivialMoveConstructor(*this, Record, AlwaysUseLookup)) { + Record->setIsNotNaturallyTriviallyRelocatable(); + if (Record->hasAttr()) { + Record->dropAttr(); + if (!isTemplateInstantiation(Record->getTemplateSpecializationKind())) { + Diag(Record->getLocation(), + diag::err_trivially_relocatable_class_is_not_relocatable) + << Record->getCanonicalDecl()->getTagKind() + << Context.getRecordType(Record) << false; + } + } + if (Record->hasAttr()) + Record->dropAttr(); + } + } } /// Look up the special member function that would be called by a special diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -4471,6 +4471,7 @@ case UTT_IsDestructible: case UTT_IsNothrowDestructible: case UTT_IsTriviallyDestructible: + case UTT_IsTriviallyRelocatable: case UTT_HasUniqueObjectRepresentations: if (ArgTy->isIncompleteArrayType() || ArgTy->isVoidType()) return true; @@ -4762,7 +4763,8 @@ } } return true; - + case UTT_IsTriviallyRelocatable: + return T.isTriviallyRelocatableType(C); case UTT_HasTrivialDestructor: // http://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html // If __is_pod (type) is true or type is a reference type diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -178,6 +178,29 @@ S.AddAllocAlignAttr(New, *Align, Param); } +static void instantiateDependentTriviallyRelocatableAttr( + Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, + const TriviallyRelocatableAttr *TRA, Decl *New) +{ + EnterExpressionEvaluationContext Unevaluated( + S, Sema::ExpressionEvaluationContext::ConstantEvaluated); + Expr *Cond = TRA->getCond(); + if (Cond != nullptr) { + ExprResult Result = S.SubstExpr(Cond, TemplateArgs); + if (Result.isInvalid()) + return; + Cond = Result.getAs(); + assert(!Cond->isTypeDependent()); + ExprResult Converted = S.PerformContextuallyConvertToBool(Cond); + if (Converted.isInvalid()) + return; + Cond = Converted.get(); + } + + New->addAttr(::new (S.Context) TriviallyRelocatableAttr( + S.Context, *TRA, Cond)); +} + static Expr *instantiateDependentFunctionAttrCondition( Sema &S, const MultiLevelTemplateArgumentList &TemplateArgs, const Attr *A, Expr *OldCond, const Decl *Tmpl, FunctionDecl *New) { @@ -573,6 +596,11 @@ continue; } + if (const auto *TRA = dyn_cast(TmplAttr)) { + instantiateDependentTriviallyRelocatableAttr(*this, TemplateArgs, TRA, New); + continue; + } + if (const auto *DiagnoseIf = dyn_cast(TmplAttr)) { instantiateDependentDiagnoseIfAttr(*this, TemplateArgs, DiagnoseIf, Tmpl, cast(New)); diff --git a/clang/test/AST/ast-dump-decl-context-json.cpp b/clang/test/AST/ast-dump-decl-context-json.cpp --- a/clang/test/AST/ast-dump-decl-context-json.cpp +++ b/clang/test/AST/ast-dump-decl-context-json.cpp @@ -202,6 +202,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, diff --git a/clang/test/AST/ast-dump-decl.cpp b/clang/test/AST/ast-dump-decl.cpp --- a/clang/test/AST/ast-dump-decl.cpp +++ b/clang/test/AST/ast-dump-decl.cpp @@ -75,7 +75,7 @@ namespace testCXXRecordDecl { class TestEmpty {}; // CHECK: CXXRecordDecl{{.*}} class TestEmpty -// CHECK-NEXT: DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init +// CHECK-NEXT: DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init // CHECK-NEXT: DefaultConstructor exists trivial constexpr // CHECK-NEXT: CopyConstructor simple trivial has_const_param // CHECK-NEXT: MoveConstructor exists simple trivial @@ -279,7 +279,7 @@ // CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-40]]:3, line:[[@LINE-34]]:3> line:[[@LINE-40]]:30 TestClassTemplate // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 typename depth 0 index 0 T // CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} line:[[@LINE-42]]:30 class TestClassTemplate definition -// CHECK-NEXT: | |-DefinitionData standard_layout has_user_declared_ctor can_const_default_init +// CHECK-NEXT: | |-DefinitionData standard_layout trivially_relocatable has_user_declared_ctor can_const_default_init // CHECK-NEXT: | | |-DefaultConstructor exists non_trivial user_provided // CHECK-NEXT: | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | | |-MoveConstructor @@ -314,7 +314,7 @@ // CHECK-NEXT: `-ClassTemplateSpecialization 0x{{.+}} 'TestClassTemplate' // CHECK: ClassTemplateSpecializationDecl 0x{{.+}} <{{.+}}:[[@LINE-65]]:3, line:[[@LINE-63]]:3> line:[[@LINE-65]]:20 class TestClassTemplate definition -// CHECK-NEXT: |-DefinitionData pass_in_registers standard_layout trivially_copyable trivial literal +// CHECK-NEXT: |-DefinitionData pass_in_registers standard_layout trivially_copyable trivially_relocatable trivial literal // CHECK-NEXT: | |-DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit @@ -328,7 +328,7 @@ // CHECK: ClassTemplateSpecializationDecl 0x{{.+}} <{{.+}}:256:3, col:44> col:25 class TestClassTemplate definition // CHECK-NEXT: |-DefinitionData standard_layout has_user_declared_ctor can_const_default_init // CHECK-NEXT: | |-DefaultConstructor exists non_trivial user_provided -// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param +// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param implicit_has_const_param // CHECK-NEXT: | |-MoveConstructor // CHECK-NEXT: | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | |-MoveAssignment @@ -339,29 +339,33 @@ // CHECK-NEXT: |-CXXConstructorDecl 0x{{.+}} col:5 TestClassTemplate 'void ()' // CHECK-NEXT: |-CXXDestructorDecl 0x{{.+}} col:5 ~TestClassTemplate 'void ()' noexcept-unevaluated 0x{{.+}} // CHECK-NEXT: |-CXXMethodDecl 0x{{.+}} col:9 j 'int ()' -// CHECK-NEXT: `-FieldDecl 0x{{.+}} col:9 i 'int' +// CHECK-NEXT: |-FieldDecl 0x{{.+}} col:9 i 'int' +// CHECK-NEXT: `-CXXConstructorDecl 0x{{.+}} col:25 implicit constexpr TestClassTemplate 'void (const testClassTemplateDecl::TestClassTemplate &)' inline default trivial noexcept-unevaluated 0x{{.+}} +// CHECK-NEXT: `-ParmVarDecl 0x{{.+}} col:25 'const testClassTemplateDecl::TestClassTemplate &' -// CHECK: ClassTemplateSpecializationDecl 0x{{.+}} <{{.+}}:[[@LINE-85]]:3, col:37> col:18 class TestClassTemplate definition +// CHECK: ClassTemplateSpecializationDecl 0x{{.+}} <{{.+}}:[[@LINE-87]]:3, col:37> col:18 class TestClassTemplate definition // CHECK-NEXT: |-DefinitionData standard_layout has_user_declared_ctor can_const_default_init // CHECK-NEXT: | |-DefaultConstructor exists non_trivial user_provided -// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param +// CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param implicit_has_const_param // CHECK-NEXT: | |-MoveConstructor // CHECK-NEXT: | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | |-MoveAssignment // CHECK-NEXT: | `-Destructor non_trivial user_declared // CHECK-NEXT: |-TemplateArgument type 'testClassTemplateDecl::D' -// CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} col:30 implicit class TestClassTemplate -// CHECK-NEXT: |-AccessSpecDecl 0x{{.+}} col:3 public -// CHECK-NEXT: |-CXXConstructorDecl 0x{{.+}} col:5 TestClassTemplate 'void ()' -// CHECK-NEXT: |-CXXDestructorDecl 0x{{.+}} col:5 ~TestClassTemplate 'void ()' noexcept-unevaluated 0x{{.+}} -// CHECK-NEXT: |-CXXMethodDecl 0x{{.+}} col:9 j 'int ()' -// CHECK-NEXT: `-FieldDecl 0x{{.+}} col:9 i 'int' - -// CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-98]]:3, line:[[@LINE-96]]:3> line:[[@LINE-98]]:44 TestClassTemplatePartial +// CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} col:30 implicit class TestClassTemplate +// CHECK-NEXT: |-AccessSpecDecl 0x{{.+}} col:3 public +// CHECK-NEXT: |-CXXConstructorDecl 0x{{.+}} col:5 TestClassTemplate 'void ()' +// CHECK-NEXT: |-CXXDestructorDecl 0x{{.+}} col:5 ~TestClassTemplate 'void ()' noexcept-unevaluated 0x{{.+}} +// CHECK-NEXT: |-CXXMethodDecl 0x{{.+}} col:9 j 'int ()' +// CHECK-NEXT: |-FieldDecl 0x{{.+}} col:9 i 'int' +// CHECK-NEXT: `-CXXConstructorDecl 0x{{.+}} col:18 implicit constexpr TestClassTemplate 'void (const testClassTemplateDecl::TestClassTemplate &)' inline default trivial noexcept-unevaluated 0x{{.+}} +// CHECK-NEXT: `-ParmVarDecl 0x{{.+}} col:18 'const testClassTemplateDecl::TestClassTemplate &' + +// CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-102]]:3, line:[[@LINE-100]]:3> line:[[@LINE-102]]:44 TestClassTemplatePartial // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 typename depth 0 index 0 T1 // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:34 typename depth 0 index 1 T2 -// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} line:[[@LINE-101]]:44 class TestClassTemplatePartial definition -// CHECK-NEXT: |-DefinitionData standard_layout trivially_copyable trivial literal +// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} line:[[@LINE-105]]:44 class TestClassTemplatePartial definition +// CHECK-NEXT: |-DefinitionData standard_layout trivially_copyable trivially_relocatable trivial literal // CHECK-NEXT: | |-DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit @@ -369,10 +373,10 @@ // CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit // CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit // CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} col:44 implicit class TestClassTemplatePartial -// CHECK-NEXT: `-FieldDecl 0x{{.+}} col:9 i 'int' +// CHECK-NEXT: `-FieldDecl 0x{{.+}} col:9 i 'int' -// CHECK: ClassTemplatePartialSpecializationDecl 0x{{.+}} <{{.+}}:[[@LINE-109]]:3, line:[[@LINE-107]]:3> line:[[@LINE-109]]:31 class TestClassTemplatePartial definition -// CHECK-NEXT: |-DefinitionData standard_layout trivially_copyable trivial literal +// CHECK: ClassTemplatePartialSpecializationDecl 0x{{.+}} <{{.+}}:[[@LINE-113]]:3, line:[[@LINE-111]]:3> line:[[@LINE-113]]:31 class TestClassTemplatePartial definition +// CHECK-NEXT: |-DefinitionData standard_layout trivially_copyable trivially_relocatable trivial literal // CHECK-NEXT: | |-DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit @@ -383,19 +387,19 @@ // CHECK-NEXT: |-TemplateArgument type 'testClassTemplateDecl::A' // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 referenced typename depth 0 index 0 T1 // CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} col:31 implicit class TestClassTemplatePartial -// CHECK-NEXT: `-FieldDecl 0x{{.+}} col:9 j 'int' +// CHECK-NEXT: `-FieldDecl 0x{{.+}} col:9 j 'int' -// CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-119]]:3, col:37> col:37 TestTemplateDefaultType +// CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-123]]:3, col:37> col:37 TestTemplateDefaultType // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 typename depth 0 index 0 T // CHECK-NEXT: | `-TemplateArgument type 'int' // CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} col:37 struct TestTemplateDefaultType -// CHECK: ClassTemplateDecl 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-123]]:3, col:57> col:31 TestTemplateDefaultType +// CHECK: ClassTemplateDecl 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-127]]:3, col:57> col:31 TestTemplateDefaultType // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 typename depth 0 index 0 T // CHECK-NEXT: | `-TemplateArgument type 'int' // CHECK-NEXT: | `-inherited from TemplateTypeParm 0x{{.+}} 'T' // CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} col:31 struct TestTemplateDefaultType definition -// CHECK-NEXT: |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init +// CHECK-NEXT: |-DefinitionData empty aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init // CHECK-NEXT: | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr // CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit @@ -404,7 +408,7 @@ // CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit // CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} col:31 implicit struct TestTemplateDefaultType -// CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-135]]:3, col:31> col:31 TestTemplateDefaultNonType +// CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-139]]:3, col:31> col:31 TestTemplateDefaultNonType // CHECK-NEXT: |-NonTypeTemplateParmDecl 0x{{.+}} col:16 'int' depth 0 index 0 I // CHECK-NEXT: | `-TemplateArgument expr // CHECK-NEXT: | `-ConstantExpr 0x{{.+}} 'int' @@ -423,7 +427,7 @@ // CHECK-NEXT: | `-TemplateArgument template TestClassTemplate // CHECK-NEXT: | `-inherited from TemplateTemplateParm 0x{{.+}} 'TT' // CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} col:48 struct TestTemplateTemplateDefaultType definition -// CHECK-NEXT: |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init +// CHECK-NEXT: |-DefinitionData empty aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init // CHECK-NEXT: | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr // CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | |-MoveConstructor exists simple trivial needs_implicit @@ -462,7 +466,7 @@ // CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:[[@LINE-4]]:3, line:[[@LINE-2]]:3> line:[[@LINE-4]]:31 TestClassTemplate // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 typename depth 0 index 0 T1 // CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} line:[[@LINE-6]]:31 class TestClassTemplate definition - // CHECK-NEXT: | |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init + // CHECK-NEXT: | |-DefinitionData empty aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init // CHECK-NEXT: | | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr // CHECK-NEXT: | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | | |-MoveConstructor exists simple trivial needs_implicit @@ -475,7 +479,7 @@ // CHECK-NEXT: | |-TemplateTypeParmDecl 0x{{.+}} col:23 typename depth 1 index 0 T2 // CHECK-NEXT: | `-CXXRecordDecl 0x{{.+}} parent 0x{{.+}} col:40 class TestClassTemplate // CHECK-NEXT: `-ClassTemplateSpecializationDecl 0x{{.+}} line:[[@LINE-19]]:31 class TestClassTemplate definition - // CHECK-NEXT: |-DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init + // CHECK-NEXT: |-DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init // CHECK-NEXT: | |-DefaultConstructor exists trivial constexpr defaulted_is_constexpr // CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param implicit_has_const_param // CHECK-NEXT: | |-MoveConstructor exists simple trivial @@ -506,7 +510,7 @@ // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 typename depth 0 index 0 T1 // CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} col:31 class TestClassTemplate2 // CHECK-NEXT: `-ClassTemplateSpecializationDecl 0x{{.+}} line:[[@LINE-6]]:31 class TestClassTemplate2 definition - // CHECK-NEXT: |-DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init + // CHECK-NEXT: |-DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init // CHECK-NEXT: | |-DefaultConstructor exists trivial constexpr defaulted_is_constexpr // CHECK-NEXT: | |-CopyConstructor simple trivial has_const_param implicit_has_const_param // CHECK-NEXT: | |-MoveConstructor exists simple trivial @@ -530,7 +534,7 @@ // CHECK: ClassTemplateDecl 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-28]]:3, line:[[@LINE-27]]:3> line:[[@LINE-28]]:31 TestClassTemplate2 // CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} col:21 typename depth 0 index 0 T1 // CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} line:[[@LINE-30]]:31 class TestClassTemplate2 definition - // CHECK-NEXT: | |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init + // CHECK-NEXT: | |-DefinitionData empty aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init // CHECK-NEXT: | | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr // CHECK-NEXT: | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: | | |-MoveConstructor exists simple trivial needs_implicit diff --git a/clang/test/AST/ast-dump-expr-json.cpp b/clang/test/AST/ast-dump-expr-json.cpp --- a/clang/test/AST/ast-dump-expr-json.cpp +++ b/clang/test/AST/ast-dump-expr-json.cpp @@ -3765,6 +3765,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -4150,6 +4151,7 @@ // CHECK-NEXT: "isLambda": true, // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": {}, // CHECK-NEXT: "moveCtor": { // CHECK-NEXT: "exists": true, @@ -4469,6 +4471,7 @@ // CHECK-NEXT: "isLiteral": true, // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": {}, // CHECK-NEXT: "moveCtor": { // CHECK-NEXT: "exists": true, @@ -4671,6 +4674,7 @@ // CHECK-NEXT: "isLiteral": true, // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": {}, // CHECK-NEXT: "moveCtor": { // CHECK-NEXT: "exists": true, @@ -5146,6 +5150,7 @@ // CHECK-NEXT: "isLiteral": true, // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": {}, // CHECK-NEXT: "moveCtor": { // CHECK-NEXT: "exists": true, @@ -5292,6 +5297,7 @@ // CHECK-NEXT: "isLiteral": true, // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": {}, // CHECK-NEXT: "moveCtor": { // CHECK-NEXT: "exists": true, @@ -5534,6 +5540,7 @@ // CHECK-NEXT: "isLiteral": true, // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": {}, // CHECK-NEXT: "moveCtor": { // CHECK-NEXT: "exists": true, @@ -5680,6 +5687,7 @@ // CHECK-NEXT: "isLiteral": true, // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": {}, // CHECK-NEXT: "moveCtor": { // CHECK-NEXT: "exists": true, @@ -5918,6 +5926,7 @@ // CHECK-NEXT: "isLambda": true, // CHECK-NEXT: "isLiteral": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": {}, // CHECK-NEXT: "moveCtor": { // CHECK-NEXT: "exists": true, @@ -6747,6 +6756,7 @@ // CHECK-NEXT: "isLiteral": true, // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": {}, // CHECK-NEXT: "moveCtor": { // CHECK-NEXT: "exists": true, @@ -6950,6 +6960,7 @@ // CHECK-NEXT: "isLiteral": true, // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": {}, // CHECK-NEXT: "moveCtor": { // CHECK-NEXT: "exists": true, @@ -7152,6 +7163,7 @@ // CHECK-NEXT: "isLiteral": true, // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": {}, // CHECK-NEXT: "moveCtor": { // CHECK-NEXT: "exists": true, @@ -7354,6 +7366,7 @@ // CHECK-NEXT: "isLiteral": true, // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": {}, // CHECK-NEXT: "moveCtor": { // CHECK-NEXT: "exists": true, diff --git a/clang/test/AST/ast-dump-record-definition-data-json.cpp b/clang/test/AST/ast-dump-record-definition-data-json.cpp --- a/clang/test/AST/ast-dump-record-definition-data-json.cpp +++ b/clang/test/AST/ast-dump-record-definition-data-json.cpp @@ -188,6 +188,7 @@ // CHECK-NEXT: "isLiteral": true, // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": {}, // CHECK-NEXT: "moveCtor": { // CHECK-NEXT: "exists": true, @@ -386,6 +387,7 @@ // CHECK-NEXT: "isLiteral": true, // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": {}, // CHECK-NEXT: "moveCtor": { // CHECK-NEXT: "exists": true, @@ -746,6 +748,7 @@ // CHECK-NEXT: "isLiteral": true, // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": {}, // CHECK-NEXT: "moveCtor": {} // CHECK-NEXT: }, @@ -1035,6 +1038,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -1133,6 +1137,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -1257,6 +1262,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -1379,6 +1385,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -1531,6 +1538,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -1634,7 +1642,6 @@ // CHECK-NEXT: "copyCtor": { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, -// CHECK-NEXT: "needsImplicit": true, // CHECK-NEXT: "nonTrivial": true, // CHECK-NEXT: "simple": true // CHECK-NEXT: }, @@ -1653,6 +1660,7 @@ // CHECK-NEXT: "hasConstexprNonCopyMoveConstructor": true, // CHECK-NEXT: "isLiteral": true, // CHECK-NEXT: "isPolymorphic": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "nonTrivial": true, @@ -1660,7 +1668,6 @@ // CHECK-NEXT: }, // CHECK-NEXT: "moveCtor": { // CHECK-NEXT: "exists": true, -// CHECK-NEXT: "needsImplicit": true, // CHECK-NEXT: "nonTrivial": true, // CHECK-NEXT: "simple": true // CHECK-NEXT: } @@ -1860,6 +1867,118 @@ // CHECK-NEXT: }, // CHECK-NEXT: "inline": true, // CHECK-NEXT: "explicitlyDefaulted": "default" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CXXConstructorDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 572, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 19 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 572, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 19 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 572, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 19 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "IsNotStandardLayout", +// CHECK-NEXT: "mangledName": "_ZN19IsNotStandardLayoutC1ERKS_", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (const IsNotStandardLayout &)" +// CHECK-NEXT: }, +// CHECK-NEXT: "inline": true, +// CHECK-NEXT: "constexpr": true, +// CHECK-NEXT: "explicitlyDefaulted": "default", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 572, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 19 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 572, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 19 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 572, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 19 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "const IsNotStandardLayout &" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CXXConstructorDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 572, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 19 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 572, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 19 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 572, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 19 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "IsNotStandardLayout", +// CHECK-NEXT: "mangledName": "_ZN19IsNotStandardLayoutC1EOS_", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (IsNotStandardLayout &&)" +// CHECK-NEXT: }, +// CHECK-NEXT: "inline": true, +// CHECK-NEXT: "constexpr": true, +// CHECK-NEXT: "explicitlyDefaulted": "default", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 572, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 19 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 572, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 19 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 572, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 19 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "IsNotStandardLayout &&" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } @@ -1925,6 +2044,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -2175,6 +2295,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -2297,6 +2418,7 @@ // CHECK-NEXT: "isLiteral": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -2424,6 +2546,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -2552,6 +2675,7 @@ // CHECK-NEXT: "isEmpty": true, // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -2674,7 +2798,6 @@ // CHECK-NEXT: "copyCtor": { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, -// CHECK-NEXT: "needsImplicit": true, // CHECK-NEXT: "nonTrivial": true, // CHECK-NEXT: "simple": true // CHECK-NEXT: }, @@ -2693,6 +2816,7 @@ // CHECK-NEXT: "hasConstexprNonCopyMoveConstructor": true, // CHECK-NEXT: "isLiteral": true, // CHECK-NEXT: "isPolymorphic": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "nonTrivial": true, @@ -2700,7 +2824,6 @@ // CHECK-NEXT: }, // CHECK-NEXT: "moveCtor": { // CHECK-NEXT: "exists": true, -// CHECK-NEXT: "needsImplicit": true, // CHECK-NEXT: "nonTrivial": true, // CHECK-NEXT: "simple": true // CHECK-NEXT: } @@ -2900,6 +3023,118 @@ // CHECK-NEXT: }, // CHECK-NEXT: "inline": true, // CHECK-NEXT: "explicitlyDefaulted": "default" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CXXConstructorDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 907, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 13 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 907, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 13 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 907, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 13 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "IsPolymorphic", +// CHECK-NEXT: "mangledName": "_ZN13IsPolymorphicC1ERKS_", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (const IsPolymorphic &)" +// CHECK-NEXT: }, +// CHECK-NEXT: "inline": true, +// CHECK-NEXT: "constexpr": true, +// CHECK-NEXT: "explicitlyDefaulted": "default", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 907, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 13 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 907, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 13 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 907, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 13 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "const IsPolymorphic &" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CXXConstructorDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 907, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 13 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 907, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 13 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 907, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 13 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "IsPolymorphic", +// CHECK-NEXT: "mangledName": "_ZN13IsPolymorphicC1EOS_", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (IsPolymorphic &&)" +// CHECK-NEXT: }, +// CHECK-NEXT: "inline": true, +// CHECK-NEXT: "constexpr": true, +// CHECK-NEXT: "explicitlyDefaulted": "default", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 907, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 13 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 907, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 13 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 907, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 13 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "IsPolymorphic &&" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } @@ -2965,6 +3200,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -3068,7 +3304,6 @@ // CHECK-NEXT: "copyCtor": { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, -// CHECK-NEXT: "needsImplicit": true, // CHECK-NEXT: "nonTrivial": true, // CHECK-NEXT: "simple": true // CHECK-NEXT: }, @@ -3088,6 +3323,7 @@ // CHECK-NEXT: "isAbstract": true, // CHECK-NEXT: "isLiteral": true, // CHECK-NEXT: "isPolymorphic": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "nonTrivial": true, @@ -3095,7 +3331,6 @@ // CHECK-NEXT: }, // CHECK-NEXT: "moveCtor": { // CHECK-NEXT: "exists": true, -// CHECK-NEXT: "needsImplicit": true, // CHECK-NEXT: "nonTrivial": true, // CHECK-NEXT: "simple": true // CHECK-NEXT: } @@ -3296,45 +3531,156 @@ // CHECK-NEXT: }, // CHECK-NEXT: "inline": true, // CHECK-NEXT: "explicitlyDefaulted": "default" -// CHECK-NEXT: } -// CHECK-NEXT: ] -// CHECK-NEXT: } - - -// CHECK: "kind": "CXXRecordDecl", -// CHECK-NEXT: "loc": { -// CHECK-NEXT: "offset": 1044, -// CHECK-NEXT: "line": 75, -// CHECK-NEXT: "col": 8, -// CHECK-NEXT: "tokLen": 13 -// CHECK-NEXT: }, -// CHECK-NEXT: "range": { -// CHECK-NEXT: "begin": { -// CHECK-NEXT: "offset": 1037, -// CHECK-NEXT: "col": 1, -// CHECK-NEXT: "tokLen": 6 -// CHECK-NEXT: }, -// CHECK-NEXT: "end": { -// CHECK-NEXT: "offset": 1080, -// CHECK-NEXT: "line": 77, -// CHECK-NEXT: "col": 1, -// CHECK-NEXT: "tokLen": 1 -// CHECK-NEXT: } -// CHECK-NEXT: }, -// CHECK-NEXT: "name": "IsNotAbstract", -// CHECK-NEXT: "tagUsed": "struct", -// CHECK-NEXT: "completeDefinition": true, -// CHECK-NEXT: "definitionData": { -// CHECK-NEXT: "canConstDefaultInit": true, -// CHECK-NEXT: "copyAssign": { -// CHECK-NEXT: "hasConstParam": true, -// CHECK-NEXT: "implicitHasConstParam": true, -// CHECK-NEXT: "nonTrivial": true +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CXXConstructorDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 996, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 10 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 996, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 10 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 996, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 10 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "IsAbstract", +// CHECK-NEXT: "mangledName": "_ZN10IsAbstractC1ERKS_", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (const IsAbstract &)" +// CHECK-NEXT: }, +// CHECK-NEXT: "inline": true, +// CHECK-NEXT: "constexpr": true, +// CHECK-NEXT: "explicitlyDefaulted": "default", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 996, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 10 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 996, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 10 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 996, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 10 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "const IsAbstract &" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CXXConstructorDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 996, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 10 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 996, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 10 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 996, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 10 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "IsAbstract", +// CHECK-NEXT: "mangledName": "_ZN10IsAbstractC1EOS_", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (IsAbstract &&)" +// CHECK-NEXT: }, +// CHECK-NEXT: "inline": true, +// CHECK-NEXT: "constexpr": true, +// CHECK-NEXT: "explicitlyDefaulted": "default", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 996, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 10 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 996, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 10 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 996, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 10 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "IsAbstract &&" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } + + +// CHECK: "kind": "CXXRecordDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 1044, +// CHECK-NEXT: "line": 75, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 13 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 1037, +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "tokLen": 6 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 1080, +// CHECK-NEXT: "line": 77, +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "name": "IsNotAbstract", +// CHECK-NEXT: "tagUsed": "struct", +// CHECK-NEXT: "completeDefinition": true, +// CHECK-NEXT: "definitionData": { +// CHECK-NEXT: "canConstDefaultInit": true, +// CHECK-NEXT: "copyAssign": { +// CHECK-NEXT: "hasConstParam": true, +// CHECK-NEXT: "implicitHasConstParam": true, +// CHECK-NEXT: "nonTrivial": true // CHECK-NEXT: }, // CHECK-NEXT: "copyCtor": { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, -// CHECK-NEXT: "needsImplicit": true, // CHECK-NEXT: "nonTrivial": true, // CHECK-NEXT: "simple": true // CHECK-NEXT: }, @@ -3353,6 +3699,7 @@ // CHECK-NEXT: "hasConstexprNonCopyMoveConstructor": true, // CHECK-NEXT: "isLiteral": true, // CHECK-NEXT: "isPolymorphic": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "nonTrivial": true, @@ -3360,7 +3707,6 @@ // CHECK-NEXT: }, // CHECK-NEXT: "moveCtor": { // CHECK-NEXT: "exists": true, -// CHECK-NEXT: "needsImplicit": true, // CHECK-NEXT: "nonTrivial": true, // CHECK-NEXT: "simple": true // CHECK-NEXT: } @@ -3560,6 +3906,118 @@ // CHECK-NEXT: }, // CHECK-NEXT: "inline": true, // CHECK-NEXT: "explicitlyDefaulted": "default" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CXXConstructorDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 1044, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 13 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 1044, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 13 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 1044, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 13 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "IsNotAbstract", +// CHECK-NEXT: "mangledName": "_ZN13IsNotAbstractC1ERKS_", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (const IsNotAbstract &)" +// CHECK-NEXT: }, +// CHECK-NEXT: "inline": true, +// CHECK-NEXT: "constexpr": true, +// CHECK-NEXT: "explicitlyDefaulted": "default", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 1044, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 13 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 1044, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 13 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 1044, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 13 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "const IsNotAbstract &" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CXXConstructorDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 1044, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 13 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 1044, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 13 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 1044, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 13 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "IsNotAbstract", +// CHECK-NEXT: "mangledName": "_ZN13IsNotAbstractC1EOS_", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (IsNotAbstract &&)" +// CHECK-NEXT: }, +// CHECK-NEXT: "inline": true, +// CHECK-NEXT: "constexpr": true, +// CHECK-NEXT: "explicitlyDefaulted": "default", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 1044, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 13 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 1044, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 13 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 1044, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 13 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "IsNotAbstract &&" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } @@ -3600,7 +4058,6 @@ // CHECK-NEXT: "copyCtor": { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, -// CHECK-NEXT: "needsImplicit": true, // CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, @@ -3623,6 +4080,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": {}, // CHECK-NEXT: "moveCtor": {} // CHECK-NEXT: }, @@ -3680,6 +4138,63 @@ // CHECK-NEXT: "qualType": "void ()" // CHECK-NEXT: }, // CHECK-NEXT: "explicitlyDefaulted": "default" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CXXConstructorDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 1091, +// CHECK-NEXT: "line": 79, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 9 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 1091, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 9 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 1091, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 9 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "IsLiteral", +// CHECK-NEXT: "mangledName": "_ZN9IsLiteralC1ERKS_", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (const IsLiteral &)" +// CHECK-NEXT: }, +// CHECK-NEXT: "inline": true, +// CHECK-NEXT: "constexpr": true, +// CHECK-NEXT: "explicitlyDefaulted": "default", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 1091, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 9 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 1091, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 9 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 1091, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 9 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "const IsLiteral &" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } @@ -3719,7 +4234,6 @@ // CHECK-NEXT: "copyCtor": { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, -// CHECK-NEXT: "needsImplicit": true, // CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, @@ -3812,6 +4326,63 @@ // CHECK-NEXT: } // CHECK-NEXT: } // CHECK-NEXT: ] +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CXXConstructorDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 1140, +// CHECK-NEXT: "line": 83, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 12 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 1140, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 12 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 1140, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 12 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "IsNotLiteral", +// CHECK-NEXT: "mangledName": "_ZN12IsNotLiteralC1ERKS_", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (const IsNotLiteral &)" +// CHECK-NEXT: }, +// CHECK-NEXT: "inline": true, +// CHECK-NEXT: "constexpr": true, +// CHECK-NEXT: "explicitlyDefaulted": "default", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 1140, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 12 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 1140, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 12 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 1140, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 12 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "const IsNotLiteral &" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } @@ -3872,6 +4443,7 @@ // CHECK-NEXT: "isEmpty": true, // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -4021,6 +4593,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -4122,6 +4695,7 @@ // CHECK-NEXT: "isLiteral": true, // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -4267,6 +4841,7 @@ // CHECK-NEXT: "isEmpty": true, // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -4651,6 +5226,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -4776,6 +5352,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -4872,6 +5449,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -5028,6 +5606,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -5128,6 +5707,7 @@ // CHECK-NEXT: "isLiteral": true, // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -5276,6 +5856,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, diff --git a/clang/test/AST/ast-dump-record-definition-data.cpp b/clang/test/AST/ast-dump-record-definition-data.cpp --- a/clang/test/AST/ast-dump-record-definition-data.cpp +++ b/clang/test/AST/ast-dump-record-definition-data.cpp @@ -69,6 +69,17 @@ IsNotTriviallyCopyable(const IsNotTriviallyCopyable&) {} }; +struct IsTriviallyRelocatable { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} line:[[@LINE-1]]:8 struct IsTriviallyRelocatable definition + // CHECK-NEXT: DefinitionData {{.*}}trivially_relocatable{{.*}} +}; + +struct IsNotTriviallyRelocatable { + // CHECK: CXXRecordDecl 0x{{[^ ]*}} line:[[@LINE-1]]:8 struct IsNotTriviallyRelocatable definition + // CHECK-NOT: DefinitionData {{.*}}trivially_relocatable{{.*}} + IsNotTriviallyRelocatable(const IsNotTriviallyRelocatable&) {} +}; + struct IsPOD { // CHECK: CXXRecordDecl 0x{{[^ ]*}} line:[[@LINE-1]]:8 struct IsPOD definition // CHECK-NEXT: DefinitionData {{.*}}pod{{.*}} diff --git a/clang/test/AST/ast-dump-records-json.cpp b/clang/test/AST/ast-dump-records-json.cpp --- a/clang/test/AST/ast-dump-records-json.cpp +++ b/clang/test/AST/ast-dump-records-json.cpp @@ -204,6 +204,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -624,6 +625,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -719,6 +721,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -847,6 +850,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -1045,6 +1049,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -1244,6 +1249,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -1470,6 +1476,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -1890,6 +1897,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -1985,6 +1993,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -2113,6 +2122,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -2311,6 +2321,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -2489,7 +2500,6 @@ // CHECK-NEXT: "copyCtor": { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, -// CHECK-NEXT: "needsImplicit": true, // CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, @@ -2513,6 +2523,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "simple": true, @@ -2520,7 +2531,6 @@ // CHECK-NEXT: }, // CHECK-NEXT: "moveCtor": { // CHECK-NEXT: "exists": true, -// CHECK-NEXT: "needsImplicit": true, // CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: } @@ -2690,6 +2700,118 @@ // CHECK-NEXT: }, // CHECK-NEXT: "inline": true, // CHECK-NEXT: "explicitlyDefaulted": "default" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CXXConstructorDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 585, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 585, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 585, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "Base1", +// CHECK-NEXT: "mangledName": "_ZN5Base1C1ERKS_", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (const Base1 &)" +// CHECK-NEXT: }, +// CHECK-NEXT: "inline": true, +// CHECK-NEXT: "constexpr": true, +// CHECK-NEXT: "explicitlyDefaulted": "default", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 585, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 585, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 585, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "const Base1 &" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CXXConstructorDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 585, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 585, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 585, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "Base1", +// CHECK-NEXT: "mangledName": "_ZN5Base1C1EOS_", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (Base1 &&)" +// CHECK-NEXT: }, +// CHECK-NEXT: "inline": true, +// CHECK-NEXT: "constexpr": true, +// CHECK-NEXT: "explicitlyDefaulted": "default", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 585, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 585, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 585, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "Base1 &&" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } @@ -2729,7 +2851,6 @@ // CHECK-NEXT: "copyCtor": { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, -// CHECK-NEXT: "needsImplicit": true, // CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, @@ -2753,6 +2874,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "simple": true, @@ -2760,7 +2882,6 @@ // CHECK-NEXT: }, // CHECK-NEXT: "moveCtor": { // CHECK-NEXT: "exists": true, -// CHECK-NEXT: "needsImplicit": true, // CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: } @@ -2930,6 +3051,118 @@ // CHECK-NEXT: }, // CHECK-NEXT: "inline": true, // CHECK-NEXT: "explicitlyDefaulted": "default" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CXXConstructorDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 602, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 602, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 602, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "Base2", +// CHECK-NEXT: "mangledName": "_ZN5Base2C1ERKS_", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (const Base2 &)" +// CHECK-NEXT: }, +// CHECK-NEXT: "inline": true, +// CHECK-NEXT: "constexpr": true, +// CHECK-NEXT: "explicitlyDefaulted": "default", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 602, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 602, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 602, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "const Base2 &" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CXXConstructorDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 602, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 602, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 602, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "Base2", +// CHECK-NEXT: "mangledName": "_ZN5Base2C1EOS_", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (Base2 &&)" +// CHECK-NEXT: }, +// CHECK-NEXT: "inline": true, +// CHECK-NEXT: "constexpr": true, +// CHECK-NEXT: "explicitlyDefaulted": "default", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 602, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 602, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 602, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "Base2 &&" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } @@ -2969,7 +3202,6 @@ // CHECK-NEXT: "copyCtor": { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, -// CHECK-NEXT: "needsImplicit": true, // CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: }, @@ -2993,6 +3225,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "simple": true, @@ -3000,7 +3233,6 @@ // CHECK-NEXT: }, // CHECK-NEXT: "moveCtor": { // CHECK-NEXT: "exists": true, -// CHECK-NEXT: "needsImplicit": true, // CHECK-NEXT: "simple": true, // CHECK-NEXT: "trivial": true // CHECK-NEXT: } @@ -3170,45 +3402,157 @@ // CHECK-NEXT: }, // CHECK-NEXT: "inline": true, // CHECK-NEXT: "explicitlyDefaulted": "default" -// CHECK-NEXT: } -// CHECK-NEXT: ] -// CHECK-NEXT: } - - -// CHECK: "kind": "CXXRecordDecl", -// CHECK-NEXT: "loc": { -// CHECK-NEXT: "offset": 637, -// CHECK-NEXT: "line": 68, -// CHECK-NEXT: "col": 8, -// CHECK-NEXT: "tokLen": 8 -// CHECK-NEXT: }, -// CHECK-NEXT: "range": { -// CHECK-NEXT: "begin": { -// CHECK-NEXT: "offset": 630, -// CHECK-NEXT: "col": 1, -// CHECK-NEXT: "tokLen": 6 -// CHECK-NEXT: }, -// CHECK-NEXT: "end": { -// CHECK-NEXT: "offset": 656, -// CHECK-NEXT: "line": 69, -// CHECK-NEXT: "col": 1, -// CHECK-NEXT: "tokLen": 1 -// CHECK-NEXT: } -// CHECK-NEXT: }, -// CHECK-NEXT: "name": "Derived1", -// CHECK-NEXT: "tagUsed": "struct", -// CHECK-NEXT: "completeDefinition": true, -// CHECK-NEXT: "definitionData": { -// CHECK-NEXT: "canConstDefaultInit": true, -// CHECK-NEXT: "canPassInRegisters": true, -// CHECK-NEXT: "copyAssign": { -// CHECK-NEXT: "hasConstParam": true, -// CHECK-NEXT: "implicitHasConstParam": true, -// CHECK-NEXT: "needsImplicit": true, -// CHECK-NEXT: "trivial": true // CHECK-NEXT: }, -// CHECK-NEXT: "copyCtor": { -// CHECK-NEXT: "hasConstParam": true, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CXXConstructorDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 619, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 619, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 619, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "Base3", +// CHECK-NEXT: "mangledName": "_ZN5Base3C1ERKS_", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (const Base3 &)" +// CHECK-NEXT: }, +// CHECK-NEXT: "inline": true, +// CHECK-NEXT: "constexpr": true, +// CHECK-NEXT: "explicitlyDefaulted": "default", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 619, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 619, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 619, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "const Base3 &" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CXXConstructorDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 619, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 619, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 619, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "Base3", +// CHECK-NEXT: "mangledName": "_ZN5Base3C1EOS_", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (Base3 &&)" +// CHECK-NEXT: }, +// CHECK-NEXT: "inline": true, +// CHECK-NEXT: "constexpr": true, +// CHECK-NEXT: "explicitlyDefaulted": "default", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 619, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 619, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 619, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 5 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "Base3 &&" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: } + + +// CHECK: "kind": "CXXRecordDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 637, +// CHECK-NEXT: "line": 68, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 630, +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "tokLen": 6 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 656, +// CHECK-NEXT: "line": 69, +// CHECK-NEXT: "col": 1, +// CHECK-NEXT: "tokLen": 1 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "name": "Derived1", +// CHECK-NEXT: "tagUsed": "struct", +// CHECK-NEXT: "completeDefinition": true, +// CHECK-NEXT: "definitionData": { +// CHECK-NEXT: "canConstDefaultInit": true, +// CHECK-NEXT: "canPassInRegisters": true, +// CHECK-NEXT: "copyAssign": { +// CHECK-NEXT: "hasConstParam": true, +// CHECK-NEXT: "implicitHasConstParam": true, +// CHECK-NEXT: "needsImplicit": true, +// CHECK-NEXT: "trivial": true +// CHECK-NEXT: }, +// CHECK-NEXT: "copyCtor": { +// CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, // CHECK-NEXT: "needsImplicit": true, // CHECK-NEXT: "simple": true, @@ -3234,6 +3578,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -3344,6 +3689,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -3429,7 +3775,6 @@ // CHECK-NEXT: "copyCtor": { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, -// CHECK-NEXT: "needsImplicit": true, // CHECK-NEXT: "nonTrivial": true, // CHECK-NEXT: "simple": true // CHECK-NEXT: }, @@ -3450,7 +3795,6 @@ // CHECK-NEXT: }, // CHECK-NEXT: "moveCtor": { // CHECK-NEXT: "exists": true, -// CHECK-NEXT: "needsImplicit": true, // CHECK-NEXT: "nonTrivial": true, // CHECK-NEXT: "simple": true // CHECK-NEXT: } @@ -3629,6 +3973,116 @@ // CHECK-NEXT: }, // CHECK-NEXT: "inline": true, // CHECK-NEXT: "explicitlyDefaulted": "default" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CXXConstructorDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 705, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 705, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 705, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "Derived3", +// CHECK-NEXT: "mangledName": "_ZN8Derived3C1ERKS_", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (const Derived3 &)" +// CHECK-NEXT: }, +// CHECK-NEXT: "inline": true, +// CHECK-NEXT: "explicitlyDefaulted": "default", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 705, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 705, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 705, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "const Derived3 &" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CXXConstructorDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 705, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 705, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 705, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "Derived3", +// CHECK-NEXT: "mangledName": "_ZN8Derived3C1EOS_", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (Derived3 &&)" +// CHECK-NEXT: }, +// CHECK-NEXT: "inline": true, +// CHECK-NEXT: "explicitlyDefaulted": "default", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 705, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 705, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 705, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "Derived3 &&" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } @@ -3667,7 +4121,6 @@ // CHECK-NEXT: "copyCtor": { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, -// CHECK-NEXT: "needsImplicit": true, // CHECK-NEXT: "nonTrivial": true, // CHECK-NEXT: "simple": true // CHECK-NEXT: }, @@ -3688,7 +4141,6 @@ // CHECK-NEXT: }, // CHECK-NEXT: "moveCtor": { // CHECK-NEXT: "exists": true, -// CHECK-NEXT: "needsImplicit": true, // CHECK-NEXT: "nonTrivial": true, // CHECK-NEXT: "simple": true // CHECK-NEXT: } @@ -3881,6 +4333,116 @@ // CHECK-NEXT: }, // CHECK-NEXT: "inline": true, // CHECK-NEXT: "explicitlyDefaulted": "default" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CXXConstructorDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 743, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 743, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 743, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "Derived4", +// CHECK-NEXT: "mangledName": "_ZN8Derived4C1ERKS_", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (const Derived4 &)" +// CHECK-NEXT: }, +// CHECK-NEXT: "inline": true, +// CHECK-NEXT: "explicitlyDefaulted": "default", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 743, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 743, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 743, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "const Derived4 &" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CXXConstructorDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 743, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 743, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 743, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "Derived4", +// CHECK-NEXT: "mangledName": "_ZN8Derived4C1EOS_", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (Derived4 &&)" +// CHECK-NEXT: }, +// CHECK-NEXT: "inline": true, +// CHECK-NEXT: "explicitlyDefaulted": "default", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 743, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 743, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 743, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "Derived4 &&" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } @@ -3919,7 +4481,6 @@ // CHECK-NEXT: "copyCtor": { // CHECK-NEXT: "hasConstParam": true, // CHECK-NEXT: "implicitHasConstParam": true, -// CHECK-NEXT: "needsImplicit": true, // CHECK-NEXT: "nonTrivial": true, // CHECK-NEXT: "simple": true // CHECK-NEXT: }, @@ -3940,7 +4501,6 @@ // CHECK-NEXT: }, // CHECK-NEXT: "moveCtor": { // CHECK-NEXT: "exists": true, -// CHECK-NEXT: "needsImplicit": true, // CHECK-NEXT: "nonTrivial": true, // CHECK-NEXT: "simple": true // CHECK-NEXT: } @@ -4119,6 +4679,116 @@ // CHECK-NEXT: }, // CHECK-NEXT: "inline": true, // CHECK-NEXT: "explicitlyDefaulted": "default" +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CXXConstructorDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 805, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 805, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 805, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "Derived5", +// CHECK-NEXT: "mangledName": "_ZN8Derived5C1ERKS_", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (const Derived5 &)" +// CHECK-NEXT: }, +// CHECK-NEXT: "inline": true, +// CHECK-NEXT: "explicitlyDefaulted": "default", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 805, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 805, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 805, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "const Derived5 &" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] +// CHECK-NEXT: }, +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CXXConstructorDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 805, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 805, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 805, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "isImplicit": true, +// CHECK-NEXT: "name": "Derived5", +// CHECK-NEXT: "mangledName": "_ZN8Derived5C1EOS_", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "void (Derived5 &&)" +// CHECK-NEXT: }, +// CHECK-NEXT: "inline": true, +// CHECK-NEXT: "explicitlyDefaulted": "default", +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "ParmVarDecl", +// CHECK-NEXT: "loc": { +// CHECK-NEXT: "offset": 805, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: }, +// CHECK-NEXT: "range": { +// CHECK-NEXT: "begin": { +// CHECK-NEXT: "offset": 805, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: }, +// CHECK-NEXT: "end": { +// CHECK-NEXT: "offset": 805, +// CHECK-NEXT: "col": 8, +// CHECK-NEXT: "tokLen": 8 +// CHECK-NEXT: } +// CHECK-NEXT: }, +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "Derived5 &&" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] // CHECK-NEXT: } // CHECK-NEXT: ] // CHECK-NEXT: } @@ -4182,6 +4852,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, diff --git a/clang/test/AST/ast-dump-records.cpp b/clang/test/AST/ast-dump-records.cpp --- a/clang/test/AST/ast-dump-records.cpp +++ b/clang/test/AST/ast-dump-records.cpp @@ -8,7 +8,7 @@ struct A { // CHECK: CXXRecordDecl 0x{{[^ ]*}} prev 0x{{[^ ]*}} line:[[@LINE-1]]:8 struct A definition - // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal + // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit @@ -40,7 +40,7 @@ struct C { // CHECK: CXXRecordDecl 0x{{[^ ]*}} line:[[@LINE-1]]:8 struct C definition - // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal has_variant_members + // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal has_variant_members // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit @@ -51,7 +51,7 @@ // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} col:8 implicit struct C struct { // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} line:[[@LINE-1]]:3 struct definition - // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal + // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit @@ -65,7 +65,7 @@ union { // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} line:[[@LINE-1]]:3 union definition - // CHECK-NEXT: DefinitionData is_anonymous pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal + // CHECK-NEXT: DefinitionData is_anonymous pass_in_registers aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit @@ -87,7 +87,7 @@ struct { // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} line:[[@LINE-1]]:3 struct definition - // CHECK-NEXT: DefinitionData is_anonymous pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal + // CHECK-NEXT: DefinitionData is_anonymous pass_in_registers aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit @@ -109,7 +109,7 @@ struct D { // CHECK: CXXRecordDecl 0x{{[^ ]*}} line:[[@LINE-1]]:8 struct D definition - // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal + // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit @@ -134,7 +134,7 @@ union E { // CHECK: CXXRecordDecl 0x{{[^ ]*}} prev 0x{{[^ ]*}} line:[[@LINE-1]]:7 union E definition - // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal + // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit @@ -166,7 +166,7 @@ union G { // CHECK: CXXRecordDecl 0x{{[^ ]*}} line:[[@LINE-1]]:7 union G definition - // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal + // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit @@ -177,7 +177,7 @@ // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} col:7 implicit union G struct { // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} line:[[@LINE-1]]:3 struct definition - // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal + // CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit @@ -194,7 +194,7 @@ union { // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} line:[[@LINE-1]]:3 union definition - // CHECK-NEXT: DefinitionData is_anonymous pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal + // CHECK-NEXT: DefinitionData is_anonymous pass_in_registers aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit @@ -217,7 +217,7 @@ struct { // CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} line:[[@LINE-1]]:3 struct definition - // CHECK-NEXT: DefinitionData is_anonymous pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal + // CHECK-NEXT: DefinitionData is_anonymous pass_in_registers aggregate standard_layout trivially_copyable trivially_relocatable pod trivial literal // CHECK-NEXT: DefaultConstructor exists trivial needs_implicit // CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param // CHECK-NEXT: MoveConstructor exists simple trivial needs_implicit diff --git a/clang/test/AST/ast-dump-template-decls-json.cpp b/clang/test/AST/ast-dump-template-decls-json.cpp --- a/clang/test/AST/ast-dump-template-decls-json.cpp +++ b/clang/test/AST/ast-dump-template-decls-json.cpp @@ -1381,6 +1381,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -1491,6 +1492,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -1673,6 +1675,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -1777,6 +1780,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -1969,6 +1973,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -2123,6 +2128,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, @@ -2277,6 +2283,7 @@ // CHECK-NEXT: "isStandardLayout": true, // CHECK-NEXT: "isTrivial": true, // CHECK-NEXT: "isTriviallyCopyable": true, +// CHECK-NEXT: "isTriviallyRelocatable": true, // CHECK-NEXT: "moveAssign": { // CHECK-NEXT: "exists": true, // CHECK-NEXT: "needsImplicit": true, diff --git a/clang/test/CXX/special/class.copy/p11.0x.move.cpp b/clang/test/CXX/special/class.copy/p11.0x.move.cpp --- a/clang/test/CXX/special/class.copy/p11.0x.move.cpp +++ b/clang/test/CXX/special/class.copy/p11.0x.move.cpp @@ -72,10 +72,12 @@ // FIXME: This diagnostic is slightly wrong: the constructor we select to move // 'IA' is deleted, but we select the copy constructor (we ignore the move // constructor, because it was defaulted and deleted). - IsAmbiguous IA; // expected-note{{deleted because field 'IA' has a deleted move constructor}} + IsAmbiguous IA; Deleted(Deleted&&); }; -Deleted::Deleted(Deleted&&) = default; // expected-error{{would delete}} +// expected-error@+2{{call to implicitly-deleted copy constructor of 'IsAmbiguous'}} +// expected-note@+1{{in defaulted move constructor for 'Deleted' first required here}} +Deleted::Deleted(Deleted&&) = default; // It's implied (but not stated) that this should also happen if overload // resolution fails. @@ -106,10 +108,12 @@ }; AmbiguousMoveBase::AmbiguousMoveBase(AmbiguousMoveBase&&) = default; // expected-error{{would delete}} -struct DeletedMoveBase : AmbiguousMoveBase { // expected-note{{deleted because base class 'AmbiguousMoveBase' has a deleted move constructor}} +struct DeletedMoveBase : AmbiguousMoveBase { DeletedMoveBase(DeletedMoveBase&&); }; -DeletedMoveBase::DeletedMoveBase(DeletedMoveBase&&) = default; // expected-error{{would delete}} +// expected-error@+2{{call to implicitly-deleted copy constructor of 'AmbiguousMoveBase'}} +// expected-note@+1{{in defaulted move constructor for 'DeletedMoveBase' first required here}} +DeletedMoveBase::DeletedMoveBase(DeletedMoveBase&&) = default; struct InaccessibleMoveBase : NoAccess { // expected-note{{deleted because base class 'NoAccess' has an inaccessible move constructor}} InaccessibleMoveBase(InaccessibleMoveBase&&); diff --git a/clang/test/CXX/special/class.dtor/p5-implicit.cpp b/clang/test/CXX/special/class.dtor/p5-implicit.cpp --- a/clang/test/CXX/special/class.dtor/p5-implicit.cpp +++ b/clang/test/CXX/special/class.dtor/p5-implicit.cpp @@ -18,4 +18,4 @@ E e; }; // CHECK-LABEL: CXXRecordDecl {{.*}} union U -// CHECK: Destructor non_trivial needs_implicit defaulted_is_deleted +// CHECK: Destructor non_trivial defaulted_is_deleted diff --git a/clang/test/Lexer/has_extension_cxx.cpp b/clang/test/Lexer/has_extension_cxx.cpp --- a/clang/test/Lexer/has_extension_cxx.cpp +++ b/clang/test/Lexer/has_extension_cxx.cpp @@ -66,3 +66,9 @@ #if __has_extension(cxx_init_captures) int has_init_captures(); #endif + +// CHECK-NOT: has_trivially_relocatable +// CHECK11: has_trivially_relocatable +#if __has_extension(trivially_relocatable) +int has_trivially_relocatable(); +#endif diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test --- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -68,6 +68,7 @@ // CHECK-NEXT: Lockable (SubjectMatchRule_record) // CHECK-NEXT: MIGServerRoutine (SubjectMatchRule_function, SubjectMatchRule_objc_method, SubjectMatchRule_block) // CHECK-NEXT: MSStruct (SubjectMatchRule_record) +// CHECK-NEXT: MaybeTriviallyRelocatable (SubjectMatchRule_record) // CHECK-NEXT: MicroMips (SubjectMatchRule_function) // CHECK-NEXT: MinSize (SubjectMatchRule_function, SubjectMatchRule_objc_method) // CHECK-NEXT: MinVectorWidth (SubjectMatchRule_function) @@ -147,6 +148,7 @@ // CHECK-NEXT: Target (SubjectMatchRule_function) // CHECK-NEXT: TestTypestate (SubjectMatchRule_function_is_member) // CHECK-NEXT: TrivialABI (SubjectMatchRule_record) +// CHECK-NEXT: TriviallyRelocatable (SubjectMatchRule_record) // CHECK-NEXT: UseHandle (SubjectMatchRule_variable_is_parameter) // CHECK-NEXT: VecReturn (SubjectMatchRule_record) // CHECK-NEXT: VecTypeHint (SubjectMatchRule_function) diff --git a/clang/test/SemaCXX/maybe-trivially-relocatable.cpp b/clang/test/SemaCXX/maybe-trivially-relocatable.cpp new file mode 100644 --- /dev/null +++ b/clang/test/SemaCXX/maybe-trivially-relocatable.cpp @@ -0,0 +1,701 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 +// expected-diagnostics + +static_assert(__has_extension(trivially_relocatable), ""); + +// It shall appear at most once in each attribute-list +// and no attribute-argument-clause shall be present. + +struct [[clang::maybe_trivially_relocatable, clang::maybe_trivially_relocatable]] B1 {}; // should really be an error + +struct [[clang::maybe_trivially_relocatable]] [[clang::maybe_trivially_relocatable]] B2 {}; // should really be an error + +struct [[clang::maybe_trivially_relocatable(42)]] B3 {}; +// expected-error@-1{{'maybe_trivially_relocatable' attribute takes no arguments}} + + +// The first declaration of a type shall specify the +// trivially_relocatable attribute if any declaration of that +// type specifies the trivially_relocatable attribute. + +struct [[clang::maybe_trivially_relocatable]] A1 {}; // ok +struct [[clang::maybe_trivially_relocatable]] A1; + +struct [[clang::maybe_trivially_relocatable]] A2; // ok +struct [[clang::maybe_trivially_relocatable]] A2 {}; + +struct [[clang::maybe_trivially_relocatable]] A3 {}; // ok +struct A3; + +struct [[clang::maybe_trivially_relocatable]] A4; // ok +struct A4 {}; + +struct A5 {}; +struct [[clang::maybe_trivially_relocatable]] A5; +// expected-warning@-1{{attribute declaration must precede definition}} +// expected-note@-3{{previous definition is here}} + +struct A6; +struct [[clang::maybe_trivially_relocatable]] A6 {}; + + +// If a type T is declared with the trivially_relocatable attribute, and T is +// either not move-constructible or not destructible, the program is ill-formed. + +struct NonDestructible { + NonDestructible(const NonDestructible&) = default; + NonDestructible(NonDestructible&&) = default; + ~NonDestructible() = delete; +}; +struct NonCopyConstructible { + NonCopyConstructible(const NonCopyConstructible&) = delete; +}; +struct NonMoveConstructible { + NonMoveConstructible(const NonMoveConstructible&) = default; + NonMoveConstructible(NonMoveConstructible&&) = delete; + // expected-note@-1{{explicitly marked deleted here}} +}; +static_assert(!__is_trivially_relocatable(NonDestructible), ""); +static_assert(!__is_trivially_relocatable(NonCopyConstructible), ""); +static_assert(!__is_constructible(NonCopyConstructible, NonCopyConstructible&&), ""); +static_assert(!__is_trivially_relocatable(NonMoveConstructible), ""); +static_assert(!__is_constructible(NonMoveConstructible, NonMoveConstructible&&), ""); + +struct [[clang::maybe_trivially_relocatable]] D1 { ~D1() = delete; }; + +struct [[clang::maybe_trivially_relocatable]] D2 : private NonDestructible { }; + +struct [[clang::maybe_trivially_relocatable]] D3 { D3(const D3&) = delete; }; + +struct [[clang::maybe_trivially_relocatable]] D4 { D4(const D4&) = default; D4(D4&&) = delete; }; + +struct [[clang::maybe_trivially_relocatable]] D5 : private NonCopyConstructible { }; +static_assert(!__is_constructible(D5, D5&&), ""); + +struct [[clang::maybe_trivially_relocatable]] D6 : private NonMoveConstructible { D6(D6&&) = default; }; +// expected-warning@-1{{explicitly defaulted move constructor is implicitly deleted}} +// expected-note@-2{{implicitly deleted because}} + +template +struct [[clang::maybe_trivially_relocatable]] DT1 : private T { }; // ok + +struct D7 { + DT1 m; +}; + +class [[clang::maybe_trivially_relocatable]] D8 { + DT1 m; +}; + + +// Now test specific types for trivial relocatability. + +static_assert(__is_trivially_relocatable(char), ""); +static_assert(__is_trivially_relocatable(int), ""); +static_assert(__is_trivially_relocatable(int*), ""); +static_assert(!__is_trivially_relocatable(int&), ""); +static_assert(__is_trivially_relocatable(float), ""); +static_assert(__is_trivially_relocatable(double), ""); +static_assert(!__is_trivially_relocatable(void), ""); +static_assert(__is_trivially_relocatable(char[1]), ""); +static_assert(__is_trivially_relocatable(char[]), ""); + +static_assert(__is_trivially_relocatable(const int), ""); +static_assert(__is_trivially_relocatable(volatile int), ""); +static_assert(!__is_trivially_relocatable(const int&), ""); +static_assert(!__is_trivially_relocatable(volatile int&), ""); + +struct C1 { int x; }; static_assert(__is_trivially_relocatable(C1), ""); +struct C2 { const int x; }; static_assert(__is_trivially_relocatable(C2), ""); +struct C3 { volatile int x; }; static_assert(!__is_trivially_relocatable(C3), "volatile member"); +struct C4 { int *x; }; static_assert(__is_trivially_relocatable(C4), ""); +struct C5 { const int *x; }; static_assert(__is_trivially_relocatable(C5), ""); +struct C6 { volatile int *x; }; static_assert(__is_trivially_relocatable(C6), ""); +struct C7 { int& x; }; static_assert(__is_trivially_relocatable(C7), ""); +struct C8 { const int& x; }; static_assert(__is_trivially_relocatable(C8), ""); +struct C9 { volatile int& x; }; static_assert(__is_trivially_relocatable(C9), ""); + +enum E { x = 1, y = 2 }; +static_assert(__is_trivially_relocatable(E), ""); +static_assert(__is_trivially_relocatable(E[1]), ""); + +struct T1 {}; +static_assert(__is_trivially_relocatable(T1), ""); + +struct T2 { int x; E y; int *z; }; +static_assert(__is_trivially_relocatable(T2), ""); + +struct T3 { int x; T3(T3&&) = default; }; +static_assert(__is_trivially_relocatable(T3), ""); + +struct T4 { int x; ~T4() = default; }; +static_assert(__is_trivially_relocatable(T4), "trivially copy-constructible, and no move constructor"); + +struct T4a { T4 a; }; +static_assert(__is_trivially_relocatable(T4a), "trivially copy-constructible, and no move constructor"); + + +struct VD { + VD(const VD&) = default; + VD(VD&&) = default; + virtual ~VD() = default; +}; +void relocate_example(VD&& src) { + VD dst(static_cast(src)); // this DEFINITELY calls the trivial move-constructor + src.~VD(); // this MAY virtually dispatch to a non-trivial destructor +} +static_assert(!__is_trivially_relocatable(VD), ""); + + +struct VD2 final { + VD2(const VD2&) = default; + VD2(VD2&&) = default; + virtual ~VD2() = default; +}; +void relocate_example(VD2&& src) { + VD2 dst(static_cast(src)); // this DEFINITELY calls the trivial move-constructor + src.~VD2(); // because "final", this CANNOT virtually dispatch to a non-trivial destructor +} +static_assert(__is_trivially_relocatable(VD2), ""); + + +struct VD3 { + VD3(const VD3&) = default; + VD3(VD3&&) = default; + virtual ~VD3() final = default; + // expected-warning@-1{{class with destructor marked 'final'}} + // expected-note@-5{{mark 'VD3' as 'final' to silence this warning}} +}; +void relocate_example(VD3&& src) { + VD3 dst(static_cast(src)); // this DEFINITELY calls the trivial move-constructor + src.~VD3(); // because "final", this CANNOT virtually dispatch to a non-trivial destructor +} +static_assert(__is_trivially_relocatable(VD3), ""); + + +struct VB : public virtual T1 { + VB(const VB&) = default; + VB(VB&&) = default; + ~VB() = default; +}; +void relocate_example(VB&& src) { + VB dst(static_cast(src)); // this MAY copy the virtual bases of "src" in a way not tantamount to memcpy + src.~VB(); // this calls the trivial destructor +} +static_assert(__is_trivially_destructible(VB), ""); +static_assert(!__is_trivially_constructible(VB, VB&&), ""); +static_assert(!__is_trivially_relocatable(VB), ""); + +struct VB2 final : public virtual T1 { + VB2(const VB2&) = default; + VB2(VB2&&) = default; + ~VB2() = default; +}; +void relocate_example(VB2&& src) { + VB2 dst(static_cast(src)); // this MAY STILL copy the VBPTR of "src" in a way not tantamount to memcpy + src.~VB2(); // this calls the trivial destructor +} +static_assert(__is_trivially_destructible(VB2), ""); +static_assert(!__is_trivially_constructible(VB2, VB2&&), ""); +static_assert(!__is_trivially_relocatable(VB2), ""); + + +struct CCNMC { + CCNMC(const CCNMC&) = default; + // no move constructor at all + ~CCNMC() = default; +}; +void relocate_example(CCNMC&& src) { + CCNMC dst(static_cast(src)); // this calls the trivial copy-constructor + src.~CCNMC(); // this calls the trivial destructor +} +static_assert(__is_constructible(CCNMC, CCNMC&&), ""); +static_assert(__is_trivially_relocatable(CCNMC), ""); + + +struct CCDMC { + CCDMC(const CCDMC&) = default; + CCDMC(CCDMC&&) = delete; + ~CCDMC() = default; +}; +void relocate_example(CCDMC&& src) { + // CCDMC dst(static_cast(src)); // this is not permitted + src.~CCDMC(); // this calls the trivial destructor +} +static_assert(!__is_constructible(CCDMC, CCDMC&&), ""); +static_assert(!__is_trivially_relocatable(CCDMC), ""); + +struct DD { ~DD() = delete; }; +static_assert(__is_trivially_copyable(DD), ""); +static_assert(!__is_trivially_destructible(DD), ""); +static_assert(!__is_trivially_relocatable(DD), ""); + + +struct T5 { int x; T5(T5&&) {} }; +static_assert(!__is_trivially_relocatable(T5), ""); + +struct T6 { int x; ~T6() {} }; +static_assert(!__is_trivially_relocatable(T6), ""); + +struct T7 { int x; T7(const T7&) {} }; +static_assert(!__is_trivially_relocatable(T7), "T7 has no implicitly declared move constructor"); + +struct T8 { virtual void f() {} int x; }; +static_assert(__is_trivially_relocatable(T8), "T8 has a vptr but that's fine"); + +struct T8a { virtual void g() = 0; int x; }; +static_assert(__is_trivially_relocatable(T8a), "T8a is abstract but that's fine"); + +struct [[clang::maybe_trivially_relocatable]] T9 { int x; T9(T9&&) {} }; +static_assert(__is_trivially_relocatable(T9), "T9 isn't naturally, but it has the attribute"); + +struct [[clang::maybe_trivially_relocatable]] T10 { int x; ~T10() {} }; +static_assert(__is_trivially_relocatable(T10), "T10 isn't naturally, but it has the attribute"); + +struct T11 { + T11(); + T1 a; + T2 b; + T3 c; + T4 d; + T8 e; + T9 f; + T10 g; +}; +static_assert(__is_trivially_relocatable(T11), "all fields have trivially relocatable types"); + +struct T12 { + T1 a; + T2 b; + T3 c; + T5 d; // not trivially relocatable + T8 e; + T9 f; + T10 g; +}; +static_assert(!__is_trivially_relocatable(T12), "not all fields have trivially relocatable types"); + +struct T13 : T1, T2, T3, T4, T8, T8a {}; +static_assert(__is_trivially_relocatable(T13), "all bases have trivially relocatable types"); + +struct T14 : T1, T6, T3, T4 {}; +static_assert(!__is_trivially_relocatable(T14), "not all bases have trivially relocatable types"); + +template +struct T15 : Ts... {}; + +static_assert(__is_trivially_relocatable(T15), "all bases have trivially relocatable types"); +static_assert(!__is_trivially_relocatable(T15), "not all bases have trivially relocatable types"); + +template +struct [[clang::maybe_trivially_relocatable]] T16 : Ts... {}; + +static_assert(__is_trivially_relocatable(T16), "all bases have trivially relocatable types"); +static_assert(!__is_trivially_relocatable(T16), "not naturally, and the 'maybe' attribute doesn't help"); + +struct T17 : T15 {}; // T10 is trivially relocatable +static_assert(__is_trivially_relocatable(T17), ""); +static_assert(__is_trivially_relocatable(T15), ""); +static_assert(__is_trivially_relocatable(T16), ""); + +struct T17a : T15 {}; // T9 is trivially relocatable +static_assert(__is_trivially_relocatable(T17a), ""); +static_assert(__is_trivially_relocatable(T15), ""); +static_assert(__is_trivially_relocatable(T16), ""); + +static_assert(__is_trivially_relocatable(T15), ""); +static_assert(__is_trivially_relocatable(T16), ""); + +struct T18 : T15 {}; // T12 is not trivially relocatable +static_assert(!__is_trivially_relocatable(T18), ""); +static_assert(!__is_trivially_relocatable(T15), ""); +static_assert(!__is_trivially_relocatable(T16), "not naturally, and the 'maybe' attribute doesn't help"); + + +// This pattern is used heavily by libc++. +struct T19 { + struct [[clang::maybe_trivially_relocatable]] Base { + Base(Base&&); + ~Base(); + }; + Base m; + T19(const T19&); + T19(T19&&) = default; +}; + +static_assert(!__is_trivially_constructible(T19, const T19&), "user-provided copy constructor"); +static_assert(!__is_trivially_constructible(T19, T19&&), "defaulted non-trivial move constructor"); +static_assert(!__is_trivially_destructible(T19), "defaulted non-trivial destructor"); +static_assert(__is_trivially_relocatable(T19), "Rule of Zero"); + + +struct T20 { + struct [[clang::maybe_trivially_relocatable]] SharedPtr { + SharedPtr(); + SharedPtr(const SharedPtr&); + SharedPtr(SharedPtr&&); + ~SharedPtr(); + }; + SharedPtr m; + T20(const T20&) = default; + ~T20() = default; + // no move constructor +}; +void relocate_example(T20&& src) { + T20 dst(static_cast(src)); // this calls the defaulted copy constructor and makes a COPY of the SharedPtr + src.~T20(); // this calls the destructor and deletes the original copy +} +static_assert(__is_trivially_relocatable(T20::SharedPtr), "because it's annotated"); +static_assert(!__is_trivially_constructible(T20, const T20&), "defaulted, non-trivial copy constructor"); +static_assert(__is_constructible(T20, T20&&), "uses the copy constructor"); +static_assert(!__is_trivially_constructible(T20, T20&&), "uses the copy constructor"); +static_assert(!__is_trivially_destructible(T20), "defaulted non-trivial destructor"); +static_assert(__is_trivially_relocatable(T20), "I'm not sure but I think copy-and-destroy should always be assumed tantamount to move-and-destroy"); + + +struct T21 { + struct [[clang::maybe_trivially_relocatable]] SharedPtr { + SharedPtr(); + SharedPtr(const SharedPtr&); + SharedPtr(SharedPtr&&); + ~SharedPtr(); + }; + SharedPtr m; + T21(const T21&); // user-provided + ~T21() = default; + // no move constructor +}; +void relocate_example(T21&& src) { + T21 dst(static_cast(src)); // this calls the user-provided copy constructor + src.~T21(); // this calls the defaulted destructor +} +static_assert(__is_trivially_relocatable(T21::SharedPtr), "because it's annotated"); +static_assert(!__is_trivially_constructible(T21, const T21&), "non-defaulted, non-trivial copy constructor"); +static_assert(__is_constructible(T21, T21&&), "uses the copy constructor"); +static_assert(!__is_trivially_constructible(T21, T21&&), "uses the copy constructor"); +static_assert(!__is_trivially_destructible(T21), "defaulted non-trivial destructor"); +static_assert(!__is_trivially_relocatable(T21), "Relocating T21 calls T21's user-provided copy constructor, which we don't know what it does"); + + +struct T22 { + struct [[clang::maybe_trivially_relocatable]] MoveOnly { MoveOnly(MoveOnly&&); }; + struct CopyOnly { ~CopyOnly() = default; }; + MoveOnly m1; + CopyOnly m2; +}; +void relocate_example(T22&& src) { + T22 dst(static_cast(src)); // this moves m1 (user-provided) and copies m2 (trivial, defaulted) + src.~T22(); // this destroys m1 (trivial, defaulted) and m2 (trivial, defaulted) +} +static_assert(!__is_constructible(T22::MoveOnly, const T22::MoveOnly&), ""); +static_assert(__is_constructible(T22::MoveOnly, T22::MoveOnly&&), ""); +static_assert(!__is_trivially_constructible(T22::MoveOnly, T22::MoveOnly&&), ""); +static_assert(__is_trivially_relocatable(T22::MoveOnly), "because it's annotated"); +static_assert(__is_constructible(T22::CopyOnly, const T22::CopyOnly&), ""); +static_assert(__is_constructible(T22::CopyOnly, T22::CopyOnly&&), ""); +static_assert(__is_trivially_constructible(T22::CopyOnly, const T22::CopyOnly&), ""); +static_assert(__is_trivially_constructible(T22::CopyOnly, T22::CopyOnly&&), ""); +static_assert(__is_trivially_relocatable(T22::CopyOnly), "because its copy constructor is defaulted and its move constructor doesn't exist"); +static_assert(!__is_constructible(T22, const T22&), "m1 is not copyable"); +static_assert(__is_constructible(T22, T22&&), ""); +static_assert(!__is_trivially_constructible(T22, T22&&), "m2 is not trivially moveable"); +static_assert(__is_trivially_destructible(T22), "both members are trivially destructible"); +static_assert(__is_trivially_relocatable(T22), "because its members are trivially relocatable"); + + +struct T23 { + struct Evil { + Evil(Evil&); + Evil(Evil&&) = default; + ~Evil() = default; + }; + mutable Evil m; +}; +void relocate_example(T23&& src) { + T23 dst(static_cast(src)); // this moves m (trivial, defaulted) + src.~T23(); // this destroys m (trivial, defaulted) +} +static_assert(__is_trivially_constructible(T23::Evil, T23::Evil&&), ""); +static_assert(__is_trivially_destructible(T23::Evil), ""); +static_assert(__is_trivially_relocatable(T23::Evil), "trivially move-constructible and trivially destructible"); +static_assert(__is_constructible(T23, T23&), ""); +static_assert(!__is_constructible(T23, const T23&), ""); +static_assert(__is_trivially_constructible(T23, T23&&), ""); +static_assert(__is_trivially_destructible(T23), ""); +static_assert(!__is_trivially_relocatable(T23), "mutable member (even though this would be safe in practice)"); + +struct T23a { + struct Evil { + Evil(Evil&); + Evil(const Evil&) = default; + ~Evil() = default; + }; + mutable Evil m; +}; +void relocate_example(T23a&& src) { + T23a dst(static_cast(src)); // this copies m using the non-defaulted copy constructor + src.~T23a(); // this destroys m (trivial, defaulted) +} +static_assert(__is_trivially_constructible(T23a::Evil, T23a::Evil&&), ""); +static_assert(__is_trivially_destructible(T23a::Evil), ""); +static_assert(!__is_trivially_relocatable(T23a::Evil), "despite being trivially move-constructible and trivially destructible, it has a user-provided copy constructor"); +static_assert(__is_trivially_constructible(T23a, T23a&&), ""); +static_assert(__is_trivially_destructible(T23a), ""); +static_assert(!__is_trivially_relocatable(T23a), "because it has a non-trivially relocatable member"); + +struct T23b { + struct Evil { + Evil(Evil&) = delete; // expected-note{{explicitly marked deleted here}} + Evil(const Evil&) = default; + ~Evil() = default; + }; + mutable Evil m; // expected-note{{implicitly deleted because}} + T23b(const T23b&) = default; // no implicit move constructor + // expected-warning@-1{{explicitly defaulted copy constructor is implicitly deleted}} +}; +static_assert(__is_trivially_constructible(T23b::Evil, T23b::Evil&&), ""); +static_assert(__is_trivially_destructible(T23b::Evil), ""); +static_assert(__is_trivially_relocatable(T23b::Evil), "it has no user-provided copy constructors"); +static_assert(!__is_constructible(T23b, T23b&&), ""); +static_assert(!__is_trivially_relocatable(T23b), "because it is not move-constructible"); + + +// Verify that the attribute is not inappropriately inherited by derived classes. +struct [[clang::maybe_trivially_relocatable]] T24 { + int i; + T24(int); + T24(const T24&); +}; +static_assert(__is_trivially_relocatable(T24), "it has the attribute"); +struct T24a : public T24 { + using T24::T24; +}; +static_assert(__is_trivially_relocatable(T24a), "all its bases are trivially relocatable"); +struct T24b : public T24 { + T24b(int i) : T24(i) {} + T24b(const T24b&); +}; +static_assert(!__is_trivially_relocatable(T24b), "it redefines the copy constructor"); +struct T24c : public T24 { + T24c(int i) : T24(i) {} + T24c(const T24c&) = default; +}; +static_assert(__is_trivially_relocatable(T24c), "its redefined copy constructor is merely defaulted"); +struct T24d : public T24 { + T24d(int i) : T24(i) {} + T24d(const T24d&); +}; +T24d::T24d(const T24d&) = default; +static_assert(!__is_trivially_relocatable(T24d), "its redefined copy constructor is not defaulted on first declaration"); + +// Example that regressed with a version of Mark de Wever's patch. +// T25 is analogous to unique_ptr; T25c is analogous to __compressed_pair. +template +struct [[clang::maybe_trivially_relocatable]] T25 { + T25(T25&&); +}; +template struct T25b { T m_a; }; +template struct T25c : T25b {}; +static_assert(__is_trivially_relocatable(T25), "it has the attribute"); +static_assert(__is_trivially_relocatable(T25b), "all its members are trivially relocatable"); +static_assert(__is_trivially_relocatable(T25c), "all its bases are trivially relocatable"); +static_assert(__is_trivially_relocatable(T25b>), "all its members are trivially relocatable"); +static_assert(__is_trivially_relocatable(T25c>), "all its bases are trivially relocatable"); + +// Example from D1144R0 +struct string { + char *data_; + unsigned long size_ = 0; + unsigned long capacity_ = 0; + string() = default; + string(const char *s); + string(string&& s); + ~string(); +}; +static_assert(!__is_trivially_relocatable(string), ""); + +// Example from D1144R0 +struct offset_ptr { + unsigned long value_; + offset_ptr(); + offset_ptr(void *p); + offset_ptr(const offset_ptr& rhs); + offset_ptr& operator=(const offset_ptr& rhs); + ~offset_ptr() = default; +}; +static_assert(!__is_trivially_relocatable(offset_ptr), ""); + +// Example from D1144R0 +struct registered_object { + registered_object(); + registered_object(registered_object&&) = default; + registered_object(const registered_object&) = default; + registered_object& operator=(registered_object&&) = default; + registered_object& operator=(const registered_object&) = default; + ~registered_object(); +}; +struct Widget : registered_object {}; +static_assert(!__is_trivially_relocatable(registered_object), ""); +static_assert(!__is_trivially_relocatable(Widget), ""); + +// Examples from D1144R0 draft revision 11 +namespace ND11 { + struct M { + M() = default; + M(M&); + M(const M&) = default; + }; + static_assert( __is_trivially_constructible(M, M&&), "" ); + static_assert( __is_trivially_destructible(M), "" ); + static_assert( !__is_trivially_relocatable(M), "" ); + + struct N { + mutable M m; + }; + static_assert( __is_trivially_constructible(N, N&&), "" ); + static_assert( __is_trivially_destructible(N), "" ); + static_assert( !__is_trivially_relocatable(N), "" ); + + struct [[clang::maybe_trivially_relocatable]] O { + O(const O&); + mutable int o; + }; + static_assert( !__is_trivially_relocatable(O), "mutable members disable the 'maybe' attribute" ); + + struct T : N { + T(const T&) = default; + }; + static_assert( !__is_trivially_constructible(T, T&&), "" ); + static_assert( __is_trivially_destructible(T), "" ); + static_assert( !__is_trivially_relocatable(T), "" ); + + struct U : N {}; + static_assert( __is_trivially_constructible(U, U&&), "" ); + static_assert( __is_trivially_destructible(U), "" ); + static_assert( !__is_trivially_relocatable(U), "" ); + + struct V { + O o; + }; + static_assert( !__is_trivially_relocatable(V), "O is not trivially relocatable" ); + + struct W { + O o; + W(const W&) = default; + }; + static_assert( !__is_trivially_relocatable(W), "O is not trivially relocatable" ); +} // namespace ND11 + +// Examples from D1144R0 draft revision 14 +namespace ND14 { + struct A { + struct MA { + MA(MA&); + MA(const MA&) = default; + MA(MA&&) = default; + }; + mutable MA ma; + A(const A&) = default; + }; + static_assert(!__is_trivially_relocatable(A), "calls user-provided MA(MA&)"); + + struct B { + struct MB { + MB(const volatile MB&); + MB(const MB&) = default; + MB(MB&&) = default; + }; + volatile MB mb; + B(const B&) = default; + }; + static_assert(!__is_trivially_relocatable(B), "calls user-provided MB(const volatile MB&)"); + + struct [[clang::maybe_trivially_relocatable]] I { + I(I&&); + }; + struct J : I { + J(const J&); + J(J&&) = default; + }; + static_assert(__is_trivially_relocatable(I), "has the attribute"); + static_assert(__is_trivially_relocatable(J), "inheritance pattern used by std::vector etc."); + + struct [[clang::maybe_trivially_relocatable]] K { + K(const K&&); + K(const K&); + K(K&&); + K(K&); + volatile int m1; + mutable int m2; + ~K(); + }; + struct L : K { + K k; + }; + static_assert(!__is_trivially_relocatable(K), "mutable/volatile members disable the 'maybe' attribute"); + static_assert(!__is_trivially_relocatable(L), "K is not trivially relocatable"); +} + +// Example from Nicolas Lesser +struct NL1 { + NL1& operator=(NL1&&); +}; +static_assert(!__is_trivially_relocatable(NL1), ""); + +struct [[clang::maybe_trivially_relocatable]] NL2 { + NL2& operator=(NL2&&); +}; +static_assert(!__is_trivially_relocatable(NL2), ""); + +union [[clang::maybe_trivially_relocatable]] NL3 { + struct [[clang::maybe_trivially_relocatable]] String { String(String&&); ~String(); }; + int i; + String s; +}; +static_assert(!__is_trivially_relocatable(NL3), ""); + +union [[clang::maybe_trivially_relocatable]] NL4 { + struct [[clang::maybe_trivially_relocatable]] String { String(String&&); ~String(); }; + int i; + String s; + NL4(const NL4&); + ~NL4(); +}; +static_assert(__is_trivially_relocatable(NL4), ""); + +template +struct [[clang::maybe_trivially_relocatable]] NL5 { + T t; +}; +struct NL5a { + NL5a() = default; + NL5a(NL5a&&) = delete; +}; +struct NL5b { + NL5b() = default; + NL5b(NL5b&&); +}; +static_assert(!__is_trivially_relocatable(NL5), ""); +static_assert(!__is_trivially_relocatable(NL5), "member 'NL5b t' is not trivially relocatable"); + +struct NL6 { + NL6(volatile NL6&) = delete; + NL6(const NL6&) = default; +}; +static_assert(__is_trivially_constructible(NL6, NL6&&), ""); +static_assert(__is_trivially_destructible(NL6), ""); +static_assert(__is_trivially_relocatable(NL6), "it is trivially move-constructible and trivially destructible"); + +template +struct [[clang::maybe_trivially_relocatable]] Vec1 { + int i; + typename A::Ptr p; + Vec1(Vec1&&); + ~Vec1(); +}; +struct Vec1_A1 { struct [[clang::trivially_relocatable]] Ptr { Ptr(Ptr&&); ~Ptr(); }; }; +struct Vec1_A2 { struct Ptr { Ptr(Ptr&&); ~Ptr(); }; }; +static_assert(__is_trivially_relocatable(Vec1_A1::Ptr), ""); +static_assert(!__is_trivially_relocatable(Vec1_A2::Ptr), ""); +static_assert(__is_trivially_relocatable(Vec1), ""); +static_assert(!__is_trivially_relocatable(Vec1), ""); diff --git a/clang/test/SemaCXX/trivially-relocatable.cpp b/clang/test/SemaCXX/trivially-relocatable.cpp new file mode 100644 --- /dev/null +++ b/clang/test/SemaCXX/trivially-relocatable.cpp @@ -0,0 +1,695 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 +// expected-diagnostics + +static_assert(__has_extension(trivially_relocatable), ""); + +// It shall appear at most once in each attribute-list +// and no attribute-argument-clause shall be present. + +struct [[clang::trivially_relocatable, clang::trivially_relocatable]] B1 {}; // should really be an error + +struct [[clang::trivially_relocatable]] [[clang::trivially_relocatable]] B2 {}; // should really be an error + +struct [[clang::trivially_relocatable(42)]] B3 {}; + + +// The first declaration of a type shall specify the +// trivially_relocatable attribute if any declaration of that +// type specifies the trivially_relocatable attribute. + +struct [[clang::trivially_relocatable]] A1 {}; // ok +struct [[clang::trivially_relocatable]] A1; + +struct [[clang::trivially_relocatable]] A2; // ok +struct [[clang::trivially_relocatable]] A2 {}; + +struct [[clang::trivially_relocatable]] A3 {}; // ok +struct A3; + +struct [[clang::trivially_relocatable]] A4; // ok +struct A4 {}; + +struct A5 {}; +struct [[clang::trivially_relocatable]] A5; +// expected-warning@-1{{attribute declaration must precede definition}} +// expected-note@-3{{previous definition is here}} + +struct A6; +struct [[clang::trivially_relocatable]] A6 {}; + + +// If a type T is declared with the trivially_relocatable attribute, and T is +// either not move-constructible or not destructible, the program is ill-formed. + +struct NonDestructible { + NonDestructible(const NonDestructible&) = default; + NonDestructible(NonDestructible&&) = default; + ~NonDestructible() = delete; +}; +struct NonCopyConstructible { + NonCopyConstructible(const NonCopyConstructible&) = delete; +}; +struct NonMoveConstructible { + NonMoveConstructible(const NonMoveConstructible&) = default; + NonMoveConstructible(NonMoveConstructible&&) = delete; + // expected-note@-1{{explicitly marked deleted here}} +}; +static_assert(!__is_trivially_relocatable(NonDestructible), ""); +static_assert(!__is_trivially_relocatable(NonCopyConstructible), ""); +static_assert(!__is_constructible(NonCopyConstructible, NonCopyConstructible&&), ""); +static_assert(!__is_trivially_relocatable(NonMoveConstructible), ""); +static_assert(!__is_constructible(NonMoveConstructible, NonMoveConstructible&&), ""); + +struct [[clang::trivially_relocatable]] D1 { ~D1() = delete; }; +// expected-error@-1{{cannot be applied to struct 'D1' because it is not destructible}} + +struct [[clang::trivially_relocatable]] D2 : private NonDestructible { }; +// expected-error@-1{{cannot be applied to struct 'D2' because it is not destructible}} + +struct [[clang::trivially_relocatable]] D3 { D3(const D3&) = delete; }; +// expected-error@-1{{cannot be applied to struct 'D3' because it is not move-constructible}} + +struct [[clang::trivially_relocatable]] D4 { D4(const D4&) = default; D4(D4&&) = delete; }; +// expected-error@-1{{cannot be applied to struct 'D4' because it is not move-constructible}} + +struct [[clang::trivially_relocatable]] D5 : private NonCopyConstructible { }; +// expected-error@-1{{cannot be applied to struct 'D5' because it is not move-constructible}} +static_assert(!__is_constructible(D5, D5&&), ""); + +struct [[clang::trivially_relocatable]] D6 : private NonMoveConstructible { D6(D6&&) = default; }; +// expected-warning@-1{{explicitly defaulted move constructor is implicitly deleted}} +// expected-note@-2{{implicitly deleted because}} +// expected-error@-3{{cannot be applied to struct 'D6' because it is not move-constructible}} + +template +struct [[clang::trivially_relocatable]] DT1 : private T { }; // ok + +struct D7 { + DT1 m; +}; + +class [[clang::trivially_relocatable]] D8 { + DT1 m; +}; +// expected-error@-3{{cannot be applied to class 'D8' because it is not destructible}} + + +// Now test specific types for trivial relocatability. + +static_assert(__is_trivially_relocatable(char), ""); +static_assert(__is_trivially_relocatable(int), ""); +static_assert(__is_trivially_relocatable(int*), ""); +static_assert(!__is_trivially_relocatable(int&), ""); +static_assert(__is_trivially_relocatable(float), ""); +static_assert(__is_trivially_relocatable(double), ""); +static_assert(!__is_trivially_relocatable(void), ""); +static_assert(__is_trivially_relocatable(char[1]), ""); +static_assert(__is_trivially_relocatable(char[]), ""); + +static_assert(__is_trivially_relocatable(const int), ""); +static_assert(__is_trivially_relocatable(volatile int), ""); +static_assert(!__is_trivially_relocatable(const int&), ""); +static_assert(!__is_trivially_relocatable(volatile int&), ""); + +struct C1 { int x; }; static_assert(__is_trivially_relocatable(C1), ""); +struct C2 { const int x; }; static_assert(__is_trivially_relocatable(C2), ""); +struct C3 { volatile int x; }; static_assert(!__is_trivially_relocatable(C3), "volatile member"); +struct C4 { int *x; }; static_assert(__is_trivially_relocatable(C4), ""); +struct C5 { const int *x; }; static_assert(__is_trivially_relocatable(C5), ""); +struct C6 { volatile int *x; }; static_assert(__is_trivially_relocatable(C6), ""); +struct C7 { int& x; }; static_assert(__is_trivially_relocatable(C7), ""); +struct C8 { const int& x; }; static_assert(__is_trivially_relocatable(C8), ""); +struct C9 { volatile int& x; }; static_assert(__is_trivially_relocatable(C9), ""); + +enum E { x = 1, y = 2 }; +static_assert(__is_trivially_relocatable(E), ""); +static_assert(__is_trivially_relocatable(E[1]), ""); + +struct T1 {}; +static_assert(__is_trivially_relocatable(T1), ""); + +struct T2 { int x; E y; int *z; }; +static_assert(__is_trivially_relocatable(T2), ""); + +struct T3 { int x; T3(T3&&) = default; }; +static_assert(__is_trivially_relocatable(T3), ""); + +struct T4 { int x; ~T4() = default; }; +static_assert(__is_trivially_relocatable(T4), "trivially copy-constructible, and no move constructor"); + +struct T4a { T4 a; }; +static_assert(__is_trivially_relocatable(T4a), "trivially copy-constructible, and no move constructor"); + + +struct VD { + VD(const VD&) = default; + VD(VD&&) = default; + virtual ~VD() = default; +}; +void relocate_example(VD&& src) { + VD dst(static_cast(src)); // this DEFINITELY calls the trivial move-constructor + src.~VD(); // this MAY virtually dispatch to a non-trivial destructor +} +static_assert(!__is_trivially_relocatable(VD), ""); + + +struct VD2 final { + VD2(const VD2&) = default; + VD2(VD2&&) = default; + virtual ~VD2() = default; +}; +void relocate_example(VD2&& src) { + VD2 dst(static_cast(src)); // this DEFINITELY calls the trivial move-constructor + src.~VD2(); // because "final", this CANNOT virtually dispatch to a non-trivial destructor +} +static_assert(__is_trivially_relocatable(VD2), ""); + + +struct VD3 { + VD3(const VD3&) = default; + VD3(VD3&&) = default; + virtual ~VD3() final = default; + // expected-warning@-1{{class with destructor marked 'final'}} + // expected-note@-5{{mark 'VD3' as 'final' to silence this warning}} +}; +void relocate_example(VD3&& src) { + VD3 dst(static_cast(src)); // this DEFINITELY calls the trivial move-constructor + src.~VD3(); // because "final", this CANNOT virtually dispatch to a non-trivial destructor +} +static_assert(__is_trivially_relocatable(VD3), ""); + + +struct VB : public virtual T1 { + VB(const VB&) = default; + VB(VB&&) = default; + ~VB() = default; +}; +void relocate_example(VB&& src) { + VB dst(static_cast(src)); // this MAY copy the virtual bases of "src" in a way not tantamount to memcpy + src.~VB(); // this calls the trivial destructor +} +static_assert(__is_trivially_destructible(VB), ""); +static_assert(!__is_trivially_constructible(VB, VB&&), ""); +static_assert(!__is_trivially_relocatable(VB), ""); + +struct VB2 final : public virtual T1 { + VB2(const VB2&) = default; + VB2(VB2&&) = default; + ~VB2() = default; +}; +void relocate_example(VB2&& src) { + VB2 dst(static_cast(src)); // this MAY STILL copy the VBPTR of "src" in a way not tantamount to memcpy + src.~VB2(); // this calls the trivial destructor +} +static_assert(__is_trivially_destructible(VB2), ""); +static_assert(!__is_trivially_constructible(VB2, VB2&&), ""); +static_assert(!__is_trivially_relocatable(VB2), ""); + + +struct CCNMC { + CCNMC(const CCNMC&) = default; + // no move constructor at all + ~CCNMC() = default; +}; +void relocate_example(CCNMC&& src) { + CCNMC dst(static_cast(src)); // this calls the trivial copy-constructor + src.~CCNMC(); // this calls the trivial destructor +} +static_assert(__is_constructible(CCNMC, CCNMC&&), ""); +static_assert(__is_trivially_relocatable(CCNMC), ""); + + +struct CCDMC { + CCDMC(const CCDMC&) = default; + CCDMC(CCDMC&&) = delete; + ~CCDMC() = default; +}; +void relocate_example(CCDMC&& src) { + // CCDMC dst(static_cast(src)); // this is not permitted + src.~CCDMC(); // this calls the trivial destructor +} +static_assert(!__is_constructible(CCDMC, CCDMC&&), ""); +static_assert(!__is_trivially_relocatable(CCDMC), ""); + +struct DD { ~DD() = delete; }; +static_assert(__is_trivially_copyable(DD), ""); +static_assert(!__is_trivially_destructible(DD), ""); +static_assert(!__is_trivially_relocatable(DD), ""); + + +struct T5 { int x; T5(T5&&) {} }; +static_assert(!__is_trivially_relocatable(T5), ""); + +struct T6 { int x; ~T6() {} }; +static_assert(!__is_trivially_relocatable(T6), ""); + +struct T7 { int x; T7(const T7&) {} }; +static_assert(!__is_trivially_relocatable(T7), "T7 has no implicitly declared move constructor"); + +struct T8 { virtual void f() {} int x; }; +static_assert(__is_trivially_relocatable(T8), "T8 has a vptr but that's fine"); + +struct T8a { virtual void g() = 0; int x; }; +static_assert(__is_trivially_relocatable(T8a), "T8a is abstract but that's fine"); + +struct [[clang::trivially_relocatable]] T9 { int x; T9(T9&&) {} }; +static_assert(__is_trivially_relocatable(T9), "T9 isn't naturally, but it has the attribute"); + +struct [[clang::trivially_relocatable]] T10 { int x; ~T10() {} }; +static_assert(__is_trivially_relocatable(T10), "T10 isn't naturally, but it has the attribute"); + +struct T11 { + T11(); + T1 a; + T2 b; + T3 c; + T4 d; + T8 e; + T9 f; + T10 g; +}; +static_assert(__is_trivially_relocatable(T11), "all fields have trivially relocatable types"); + +struct T12 { + T1 a; + T2 b; + T3 c; + T5 d; // not trivially relocatable + T8 e; + T9 f; + T10 g; +}; +static_assert(!__is_trivially_relocatable(T12), "not all fields have trivially relocatable types"); + +struct T13 : T1, T2, T3, T4, T8, T8a {}; +static_assert(__is_trivially_relocatable(T13), "all bases have trivially relocatable types"); + +struct T14 : T1, T6, T3, T4 {}; +static_assert(!__is_trivially_relocatable(T14), "not all bases have trivially relocatable types"); + +template +struct T15 : Ts... {}; + +static_assert(__is_trivially_relocatable(T15), "all bases have trivially relocatable types"); +static_assert(!__is_trivially_relocatable(T15), "not all bases have trivially relocatable types"); + +template +struct [[clang::trivially_relocatable]] T16 : Ts... {}; + +static_assert(__is_trivially_relocatable(T16), "all bases have trivially relocatable types"); +static_assert(__is_trivially_relocatable(T16), "not naturally, but it has the attribute"); + +struct T17 : T15 {}; // T10 is trivially relocatable +static_assert(__is_trivially_relocatable(T17), ""); +static_assert(__is_trivially_relocatable(T15), ""); +static_assert(__is_trivially_relocatable(T16), ""); + +struct T17a : T15 {}; // T9 is trivially relocatable +static_assert(__is_trivially_relocatable(T17a), ""); +static_assert(__is_trivially_relocatable(T15), ""); +static_assert(__is_trivially_relocatable(T16), ""); + +static_assert(__is_trivially_relocatable(T15), ""); +static_assert(__is_trivially_relocatable(T16), ""); + +struct T18 : T15 {}; // T12 is not trivially relocatable +static_assert(!__is_trivially_relocatable(T18), ""); +static_assert(!__is_trivially_relocatable(T15), ""); +static_assert(__is_trivially_relocatable(T16), "not naturally, but it has the attribute"); + + +// This pattern is used heavily by libc++. +struct T19 { + struct [[clang::trivially_relocatable]] Base { + Base(Base&&); + ~Base(); + }; + Base m; + T19(const T19&); + T19(T19&&) = default; +}; + +static_assert(!__is_trivially_constructible(T19, const T19&), "user-provided copy constructor"); +static_assert(!__is_trivially_constructible(T19, T19&&), "defaulted non-trivial move constructor"); +static_assert(!__is_trivially_destructible(T19), "defaulted non-trivial destructor"); +static_assert(__is_trivially_relocatable(T19), "Rule of Zero"); + + +struct T20 { + struct [[clang::trivially_relocatable]] SharedPtr { + SharedPtr(); + SharedPtr(const SharedPtr&); + SharedPtr(SharedPtr&&); + ~SharedPtr(); + }; + SharedPtr m; + T20(const T20&) = default; + ~T20() = default; + // no move constructor +}; +void relocate_example(T20&& src) { + T20 dst(static_cast(src)); // this calls the defaulted copy constructor and makes a COPY of the SharedPtr + src.~T20(); // this calls the destructor and deletes the original copy +} +static_assert(__is_trivially_relocatable(T20::SharedPtr), "because it's annotated"); +static_assert(!__is_trivially_constructible(T20, const T20&), "defaulted, non-trivial copy constructor"); +static_assert(__is_constructible(T20, T20&&), "uses the copy constructor"); +static_assert(!__is_trivially_constructible(T20, T20&&), "uses the copy constructor"); +static_assert(!__is_trivially_destructible(T20), "defaulted non-trivial destructor"); +static_assert(__is_trivially_relocatable(T20), "I'm not sure but I think copy-and-destroy should always be assumed tantamount to move-and-destroy"); + + +struct T21 { + struct [[clang::trivially_relocatable]] SharedPtr { + SharedPtr(); + SharedPtr(const SharedPtr&); + SharedPtr(SharedPtr&&); + ~SharedPtr(); + }; + SharedPtr m; + T21(const T21&); // user-provided + ~T21() = default; + // no move constructor +}; +void relocate_example(T21&& src) { + T21 dst(static_cast(src)); // this calls the user-provided copy constructor + src.~T21(); // this calls the defaulted destructor +} +static_assert(__is_trivially_relocatable(T21::SharedPtr), "because it's annotated"); +static_assert(!__is_trivially_constructible(T21, const T21&), "non-defaulted, non-trivial copy constructor"); +static_assert(__is_constructible(T21, T21&&), "uses the copy constructor"); +static_assert(!__is_trivially_constructible(T21, T21&&), "uses the copy constructor"); +static_assert(!__is_trivially_destructible(T21), "defaulted non-trivial destructor"); +static_assert(!__is_trivially_relocatable(T21), "Relocating T21 calls T21's user-provided copy constructor, which we don't know what it does"); + + +struct T22 { + struct [[clang::trivially_relocatable]] MoveOnly { MoveOnly(MoveOnly&&); }; + struct CopyOnly { ~CopyOnly() = default; }; + MoveOnly m1; + CopyOnly m2; +}; +void relocate_example(T22&& src) { + T22 dst(static_cast(src)); // this moves m1 (user-provided) and copies m2 (trivial, defaulted) + src.~T22(); // this destroys m1 (trivial, defaulted) and m2 (trivial, defaulted) +} +static_assert(!__is_constructible(T22::MoveOnly, const T22::MoveOnly&), ""); +static_assert(__is_constructible(T22::MoveOnly, T22::MoveOnly&&), ""); +static_assert(!__is_trivially_constructible(T22::MoveOnly, T22::MoveOnly&&), ""); +static_assert(__is_trivially_relocatable(T22::MoveOnly), "because it's annotated"); +static_assert(__is_constructible(T22::CopyOnly, const T22::CopyOnly&), ""); +static_assert(__is_constructible(T22::CopyOnly, T22::CopyOnly&&), ""); +static_assert(__is_trivially_constructible(T22::CopyOnly, const T22::CopyOnly&), ""); +static_assert(__is_trivially_constructible(T22::CopyOnly, T22::CopyOnly&&), ""); +static_assert(__is_trivially_relocatable(T22::CopyOnly), "because its copy constructor is defaulted and its move constructor doesn't exist"); +static_assert(!__is_constructible(T22, const T22&), "m1 is not copyable"); +static_assert(__is_constructible(T22, T22&&), ""); +static_assert(!__is_trivially_constructible(T22, T22&&), "m2 is not trivially moveable"); +static_assert(__is_trivially_destructible(T22), "both members are trivially destructible"); +static_assert(__is_trivially_relocatable(T22), "because its members are trivially relocatable"); + + +struct T23 { + struct Evil { + Evil(Evil&); + Evil(Evil&&) = default; + ~Evil() = default; + }; + mutable Evil m; +}; +void relocate_example(T23&& src) { + T23 dst(static_cast(src)); // this moves m (trivial, defaulted) + src.~T23(); // this destroys m (trivial, defaulted) +} +static_assert(__is_trivially_constructible(T23::Evil, T23::Evil&&), ""); +static_assert(__is_trivially_destructible(T23::Evil), ""); +static_assert(__is_trivially_relocatable(T23::Evil), "trivially move-constructible and trivially destructible"); +static_assert(__is_constructible(T23, T23&), ""); +static_assert(!__is_constructible(T23, const T23&), ""); +static_assert(__is_trivially_constructible(T23, T23&&), ""); +static_assert(__is_trivially_destructible(T23), ""); +static_assert(!__is_trivially_relocatable(T23), "mutable member (even though this would be safe in practice)"); + +struct T23a { + struct Evil { + Evil(Evil&); + Evil(const Evil&) = default; + ~Evil() = default; + }; + mutable Evil m; +}; +void relocate_example(T23a&& src) { + T23a dst(static_cast(src)); // this copies m using the non-defaulted copy constructor + src.~T23a(); // this destroys m (trivial, defaulted) +} +static_assert(__is_trivially_constructible(T23a::Evil, T23a::Evil&&), ""); +static_assert(__is_trivially_destructible(T23a::Evil), ""); +static_assert(!__is_trivially_relocatable(T23a::Evil), "despite being trivially move-constructible and trivially destructible, it has a user-provided copy constructor"); +static_assert(__is_trivially_constructible(T23a, T23a&&), ""); +static_assert(__is_trivially_destructible(T23a), ""); +static_assert(!__is_trivially_relocatable(T23a), "because it has a non-trivially relocatable member"); + +struct T23b { + struct Evil { + Evil(Evil&) = delete; // expected-note{{explicitly marked deleted here}} + Evil(const Evil&) = default; + ~Evil() = default; + }; + mutable Evil m; // expected-note{{implicitly deleted because}} + T23b(const T23b&) = default; // no implicit move constructor + // expected-warning@-1{{explicitly defaulted copy constructor is implicitly deleted}} +}; +static_assert(__is_trivially_constructible(T23b::Evil, T23b::Evil&&), ""); +static_assert(__is_trivially_destructible(T23b::Evil), ""); +static_assert(__is_trivially_relocatable(T23b::Evil), "it has no user-provided copy constructors"); +static_assert(!__is_constructible(T23b, T23b&&), ""); +static_assert(!__is_trivially_relocatable(T23b), "because it is not move-constructible"); + + +// Verify that the attribute is not inappropriately inherited by derived classes. +struct [[clang::trivially_relocatable]] T24 { + int i; + T24(int); + T24(const T24&); +}; +static_assert(__is_trivially_relocatable(T24), "it has the attribute"); +struct T24a : public T24 { + using T24::T24; +}; +static_assert(__is_trivially_relocatable(T24a), "all its bases are trivially relocatable"); +struct T24b : public T24 { + T24b(int i) : T24(i) {} + T24b(const T24b&); +}; +static_assert(!__is_trivially_relocatable(T24b), "it redefines the copy constructor"); +struct T24c : public T24 { + T24c(int i) : T24(i) {} + T24c(const T24c&) = default; +}; +static_assert(__is_trivially_relocatable(T24c), "its redefined copy constructor is merely defaulted"); +struct T24d : public T24 { + T24d(int i) : T24(i) {} + T24d(const T24d&); +}; +T24d::T24d(const T24d&) = default; +static_assert(!__is_trivially_relocatable(T24d), "its redefined copy constructor is not defaulted on first declaration"); + +// Example that regressed with a version of Mark de Wever's patch. +// T25 is analogous to unique_ptr; T25c is analogous to __compressed_pair. +template +struct [[clang::trivially_relocatable]] T25 { + T25(T25&&); +}; +template struct T25b { T m_a; }; +template struct T25c : T25b {}; +static_assert(__is_trivially_relocatable(T25), "it has the attribute"); +static_assert(__is_trivially_relocatable(T25b), "all its members are trivially relocatable"); +static_assert(__is_trivially_relocatable(T25c), "all its bases are trivially relocatable"); +static_assert(__is_trivially_relocatable(T25b>), "all its members are trivially relocatable"); +static_assert(__is_trivially_relocatable(T25c>), "all its bases are trivially relocatable"); + +// Example from D1144R0 +struct string { + char *data_; + unsigned long size_ = 0; + unsigned long capacity_ = 0; + string() = default; + string(const char *s); + string(string&& s); + ~string(); +}; +static_assert(!__is_trivially_relocatable(string), ""); + +// Example from D1144R0 +struct offset_ptr { + unsigned long value_; + offset_ptr(); + offset_ptr(void *p); + offset_ptr(const offset_ptr& rhs); + offset_ptr& operator=(const offset_ptr& rhs); + ~offset_ptr() = default; +}; +static_assert(!__is_trivially_relocatable(offset_ptr), ""); + +// Example from D1144R0 +struct registered_object { + registered_object(); + registered_object(registered_object&&) = default; + registered_object(const registered_object&) = default; + registered_object& operator=(registered_object&&) = default; + registered_object& operator=(const registered_object&) = default; + ~registered_object(); +}; +struct Widget : registered_object {}; +static_assert(!__is_trivially_relocatable(registered_object), ""); +static_assert(!__is_trivially_relocatable(Widget), ""); + +// Examples from D1144R0 draft revision 11 +namespace ND11 { + struct M { + M() = default; + M(M&); + M(const M&) = default; + }; + static_assert( __is_trivially_constructible(M, M&&), "" ); + static_assert( __is_trivially_destructible(M), "" ); + static_assert( !__is_trivially_relocatable(M), "" ); + + struct N { + mutable M m; + }; + static_assert( __is_trivially_constructible(N, N&&), "" ); + static_assert( __is_trivially_destructible(N), "" ); + static_assert( !__is_trivially_relocatable(N), "" ); + + struct [[clang::trivially_relocatable]] O { + O(const O&); + mutable int o; + }; + static_assert( __is_trivially_relocatable(O), "" ); + + struct T : N { + T(const T&) = default; + }; + static_assert( !__is_trivially_constructible(T, T&&), "" ); + static_assert( __is_trivially_destructible(T), "" ); + static_assert( !__is_trivially_relocatable(T), "" ); + + struct U : N {}; + static_assert( __is_trivially_constructible(U, U&&), "" ); + static_assert( __is_trivially_destructible(U), "" ); + static_assert( !__is_trivially_relocatable(U), "" ); + + struct V { + O o; + }; + static_assert( __is_trivially_relocatable(V), "" ); + + struct W { + O o; + W(const W&) = default; + }; + static_assert( __is_trivially_relocatable(W), "" ); +} // namespace ND11 + +// Examples from D1144R0 draft revision 14 +namespace ND14 { + struct A { + struct MA { + MA(MA&); + MA(const MA&) = default; + MA(MA&&) = default; + }; + mutable MA ma; + A(const A&) = default; + }; + static_assert(!__is_trivially_relocatable(A), "calls user-provided MA(MA&)"); + + struct B { + struct MB { + MB(const volatile MB&); + MB(const MB&) = default; + MB(MB&&) = default; + }; + volatile MB mb; + B(const B&) = default; + }; + static_assert(!__is_trivially_relocatable(B), "calls user-provided MB(const volatile MB&)"); + + struct [[clang::trivially_relocatable]] I { + I(I&&); + }; + struct J : I { + J(const J&); + J(J&&) = default; + }; + static_assert(__is_trivially_relocatable(I), "has the attribute"); + static_assert(__is_trivially_relocatable(J), "inheritance pattern used by std::vector etc."); + + struct [[clang::trivially_relocatable]] K { + K(const K&&); + K(const K&); + K(K&&); + K(K&); + volatile int m1; + mutable int m2; + ~K(); + }; + struct L : K { + K k; + }; + static_assert(__is_trivially_relocatable(K), "the attribute should override all other considerations"); + static_assert(__is_trivially_relocatable(L), "the Rule of Zero should work as expected"); +} + +// Example from Nicolas Lesser +struct NL1 { + NL1& operator=(NL1&&); +}; +static_assert(!__is_trivially_relocatable(NL1), ""); + +struct [[clang::trivially_relocatable]] NL2 { +// expected-error@-1{{cannot be applied to struct 'NL2' because it is not move-constructible}} + NL2& operator=(NL2&&); +}; +static_assert(!__is_trivially_relocatable(NL2), ""); + +union [[clang::trivially_relocatable]] NL3 { +// expected-error@-1{{cannot be applied to union 'NL3' because it is not destructible}} + struct [[clang::trivially_relocatable]] String { String(String&&); ~String(); }; + int i; + String s; +}; +static_assert(!__is_trivially_relocatable(NL3), ""); + +union [[clang::trivially_relocatable]] NL4 { + struct [[clang::trivially_relocatable]] String { String(String&&); ~String(); }; + int i; + String s; + NL4(const NL4&); + ~NL4(); +}; +static_assert(__is_trivially_relocatable(NL4), ""); + +template +struct [[clang::trivially_relocatable]] NL5 { + T t; +}; +struct NL5a { + NL5a() = default; + NL5a(NL5a&&) = delete; +}; +struct NL5b { + NL5b() = default; + NL5b(NL5b&&); +}; +static_assert(!__is_trivially_relocatable(NL5), ""); +static_assert(__is_trivially_relocatable(NL5), ""); + +struct NL6 { + NL6(volatile NL6&) = delete; + NL6(const NL6&) = default; +}; +static_assert(__is_trivially_constructible(NL6, NL6&&), ""); +static_assert(__is_trivially_destructible(NL6), ""); +static_assert(__is_trivially_relocatable(NL6), "it is trivially move-constructible and trivially destructible");