aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/AST
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2024-01-11 18:29:01 +0000
committerDimitry Andric <dim@FreeBSD.org>2024-04-19 21:24:43 +0000
commit52e4ee64c25fe0837e9cf783a63e8c214b3180cf (patch)
treeef0a98fe51363441060377330e2e714855102bf6 /contrib/llvm-project/clang/lib/AST
parented89c59104c13195cbbad881f64c6a71f687c1e4 (diff)
Diffstat (limited to 'contrib/llvm-project/clang/lib/AST')
-rw-r--r--contrib/llvm-project/clang/lib/AST/ASTContext.cpp7
-rw-r--r--contrib/llvm-project/clang/lib/AST/ASTImporter.cpp37
-rw-r--r--contrib/llvm-project/clang/lib/AST/DeclBase.cpp74
-rw-r--r--contrib/llvm-project/clang/lib/AST/DeclCXX.cpp13
-rw-r--r--contrib/llvm-project/clang/lib/AST/Expr.cpp83
-rw-r--r--contrib/llvm-project/clang/lib/AST/Interp/ByteCodeExprGen.cpp7
-rw-r--r--contrib/llvm-project/clang/lib/AST/Interp/Descriptor.cpp6
-rw-r--r--contrib/llvm-project/clang/lib/AST/Interp/Descriptor.h7
-rw-r--r--contrib/llvm-project/clang/lib/AST/Interp/Interp.cpp12
-rw-r--r--contrib/llvm-project/clang/lib/AST/Interp/InterpBuiltin.cpp33
-rw-r--r--contrib/llvm-project/clang/lib/AST/Interp/Program.cpp16
-rw-r--r--contrib/llvm-project/clang/lib/AST/Type.cpp34
12 files changed, 222 insertions, 107 deletions
diff --git a/contrib/llvm-project/clang/lib/AST/ASTContext.cpp b/contrib/llvm-project/clang/lib/AST/ASTContext.cpp
index b60dcfaabfd1..d9cefcaa84d7 100644
--- a/contrib/llvm-project/clang/lib/AST/ASTContext.cpp
+++ b/contrib/llvm-project/clang/lib/AST/ASTContext.cpp
@@ -1318,6 +1318,13 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
InitBuiltinType(OMPArrayShapingTy, BuiltinType::OMPArrayShaping);
InitBuiltinType(OMPIteratorTy, BuiltinType::OMPIterator);
}
+ // Placeholder type for OpenACC array sections.
+ if (LangOpts.OpenACC) {
+ // FIXME: Once we implement OpenACC array sections in Sema, this will either
+ // be combined with the OpenMP type, or given its own type. In the meantime,
+ // just use the OpenMP type so that parsing can work.
+ InitBuiltinType(OMPArraySectionTy, BuiltinType::OMPArraySection);
+ }
if (LangOpts.MatrixTypes)
InitBuiltinType(IncompleteMatrixIdxTy, BuiltinType::IncompleteMatrixIdx);
diff --git a/contrib/llvm-project/clang/lib/AST/ASTImporter.cpp b/contrib/llvm-project/clang/lib/AST/ASTImporter.cpp
index 5e5570bb42a1..b762d6a4cd38 100644
--- a/contrib/llvm-project/clang/lib/AST/ASTImporter.cpp
+++ b/contrib/llvm-project/clang/lib/AST/ASTImporter.cpp
@@ -5929,15 +5929,22 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
if (ToD)
return ToD;
- bool IsFriendTemplate = D->getFriendObjectKind() != Decl::FOK_None;
- bool IsDependentContext = DC != LexicalDC ? LexicalDC->isDependentContext()
- : DC->isDependentContext();
- bool DependentFriend = IsFriendTemplate && IsDependentContext;
+ // Should check if a declaration is friend in a dependent context.
+ // Such templates are not linked together in a declaration chain.
+ // The ASTImporter strategy is to map existing forward declarations to
+ // imported ones only if strictly necessary, otherwise import these as new
+ // forward declarations. In case of the "dependent friend" declarations, new
+ // declarations are created, but not linked in a declaration chain.
+ auto IsDependentFriend = [](ClassTemplateDecl *TD) {
+ return TD->getFriendObjectKind() != Decl::FOK_None &&
+ TD->getLexicalDeclContext()->isDependentContext();
+ };
+ bool DependentFriend = IsDependentFriend(D);
ClassTemplateDecl *FoundByLookup = nullptr;
// We may already have a template of the same name; try to find and match it.
- if (!DependentFriend && !DC->isFunctionOrMethod()) {
+ if (!DC->isFunctionOrMethod()) {
SmallVector<NamedDecl *, 4> ConflictingDecls;
auto FoundDecls = Importer.findDeclsInToCtx(DC, Name);
for (auto *FoundDecl : FoundDecls) {
@@ -5953,10 +5960,13 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
// FIXME: sufficient conditon for 'IgnoreTemplateParmDepth'?
bool IgnoreTemplateParmDepth =
- FoundTemplate->getFriendObjectKind() != Decl::FOK_None &&
- !D->specializations().empty();
+ (FoundTemplate->getFriendObjectKind() != Decl::FOK_None) !=
+ (D->getFriendObjectKind() != Decl::FOK_None);
if (IsStructuralMatch(D, FoundTemplate, /*Complain=*/true,
IgnoreTemplateParmDepth)) {
+ if (DependentFriend || IsDependentFriend(FoundTemplate))
+ continue;
+
ClassTemplateDecl *TemplateWithDef =
getTemplateDefinition(FoundTemplate);
if (D->isThisDeclarationADefinition() && TemplateWithDef)
@@ -9030,6 +9040,10 @@ class AttrImporter {
public:
AttrImporter(ASTImporter &I) : Importer(I), NImporter(I) {}
+ // Useful for accessing the imported attribute.
+ template <typename T> T *castAttrAs() { return cast<T>(ToAttr); }
+ template <typename T> const T *castAttrAs() const { return cast<T>(ToAttr); }
+
// Create an "importer" for an attribute parameter.
// Result of the 'value()' of that object is to be passed to the function
// 'importAttr', in the order that is expected by the attribute class.
@@ -9243,6 +9257,15 @@ Expected<Attr *> ASTImporter::Import(const Attr *FromAttr) {
From->args_size());
break;
}
+ case attr::CountedBy: {
+ AI.cloneAttr(FromAttr);
+ const auto *CBA = cast<CountedByAttr>(FromAttr);
+ Expected<SourceRange> SR = Import(CBA->getCountedByFieldLoc()).get();
+ if (!SR)
+ return SR.takeError();
+ AI.castAttrAs<CountedByAttr>()->setCountedByFieldLoc(SR.get());
+ break;
+ }
default: {
// The default branch works for attributes that have no arguments to import.
diff --git a/contrib/llvm-project/clang/lib/AST/DeclBase.cpp b/contrib/llvm-project/clang/lib/AST/DeclBase.cpp
index b1733c2d052a..8163f9bdaf8d 100644
--- a/contrib/llvm-project/clang/lib/AST/DeclBase.cpp
+++ b/contrib/llvm-project/clang/lib/AST/DeclBase.cpp
@@ -29,7 +29,6 @@
#include "clang/AST/Type.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
-#include "clang/Basic/LangOptions.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/ObjCRuntime.h"
#include "clang/Basic/PartialDiagnostic.h"
@@ -411,6 +410,79 @@ bool Decl::isFileContextDecl() const {
return DC && DC->isFileContext();
}
+bool Decl::isFlexibleArrayMemberLike(
+ ASTContext &Ctx, const Decl *D, QualType Ty,
+ LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel,
+ bool IgnoreTemplateOrMacroSubstitution) {
+ // For compatibility with existing code, we treat arrays of length 0 or
+ // 1 as flexible array members.
+ const auto *CAT = Ctx.getAsConstantArrayType(Ty);
+ if (CAT) {
+ using FAMKind = LangOptions::StrictFlexArraysLevelKind;
+
+ llvm::APInt Size = CAT->getSize();
+ if (StrictFlexArraysLevel == FAMKind::IncompleteOnly)
+ return false;
+
+ // GCC extension, only allowed to represent a FAM.
+ if (Size.isZero())
+ return true;
+
+ if (StrictFlexArraysLevel == FAMKind::ZeroOrIncomplete && Size.uge(1))
+ return false;
+
+ if (StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete && Size.uge(2))
+ return false;
+ } else if (!Ctx.getAsIncompleteArrayType(Ty)) {
+ return false;
+ }
+
+ if (const auto *OID = dyn_cast_if_present<ObjCIvarDecl>(D))
+ return OID->getNextIvar() == nullptr;
+
+ const auto *FD = dyn_cast_if_present<FieldDecl>(D);
+ if (!FD)
+ return false;
+
+ if (CAT) {
+ // GCC treats an array memeber of a union as an FAM if the size is one or
+ // zero.
+ llvm::APInt Size = CAT->getSize();
+ if (FD->getParent()->isUnion() && (Size.isZero() || Size.isOne()))
+ return true;
+ }
+
+ // Don't consider sizes resulting from macro expansions or template argument
+ // substitution to form C89 tail-padded arrays.
+ if (IgnoreTemplateOrMacroSubstitution) {
+ TypeSourceInfo *TInfo = FD->getTypeSourceInfo();
+ while (TInfo) {
+ TypeLoc TL = TInfo->getTypeLoc();
+
+ // Look through typedefs.
+ if (TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>()) {
+ const TypedefNameDecl *TDL = TTL.getTypedefNameDecl();
+ TInfo = TDL->getTypeSourceInfo();
+ continue;
+ }
+
+ if (auto CTL = TL.getAs<ConstantArrayTypeLoc>()) {
+ if (const Expr *SizeExpr =
+ dyn_cast_if_present<IntegerLiteral>(CTL.getSizeExpr());
+ !SizeExpr || SizeExpr->getExprLoc().isMacroID())
+ return false;
+ }
+
+ break;
+ }
+ }
+
+ // Test that the field is the last in the structure.
+ RecordDecl::field_iterator FI(
+ DeclContext::decl_iterator(const_cast<FieldDecl *>(FD)));
+ return ++FI == FD->getParent()->field_end();
+}
+
TranslationUnitDecl *Decl::getTranslationUnitDecl() {
if (auto *TUD = dyn_cast<TranslationUnitDecl>(this))
return TUD;
diff --git a/contrib/llvm-project/clang/lib/AST/DeclCXX.cpp b/contrib/llvm-project/clang/lib/AST/DeclCXX.cpp
index c944862fcefe..98b0a6dc28ea 100644
--- a/contrib/llvm-project/clang/lib/AST/DeclCXX.cpp
+++ b/contrib/llvm-project/clang/lib/AST/DeclCXX.cpp
@@ -587,6 +587,19 @@ bool CXXRecordDecl::isTriviallyCopyable() const {
return true;
}
+bool CXXRecordDecl::isTriviallyCopyConstructible() const {
+
+ // A trivially copy constructible class is a class that:
+ // -- has no non-trivial copy constructors,
+ if (hasNonTrivialCopyConstructor())
+ return false;
+ // -- has a trivial destructor.
+ if (!hasTrivialDestructor())
+ return false;
+
+ return true;
+}
+
void CXXRecordDecl::markedVirtualFunctionPure() {
// C++ [class.abstract]p2:
// A class is abstract if it has at least one pure virtual function.
diff --git a/contrib/llvm-project/clang/lib/AST/Expr.cpp b/contrib/llvm-project/clang/lib/AST/Expr.cpp
index a90f92d07f86..b125fc676da8 100644
--- a/contrib/llvm-project/clang/lib/AST/Expr.cpp
+++ b/contrib/llvm-project/clang/lib/AST/Expr.cpp
@@ -205,85 +205,22 @@ bool Expr::isKnownToHaveBooleanValue(bool Semantic) const {
}
bool Expr::isFlexibleArrayMemberLike(
- ASTContext &Context,
+ ASTContext &Ctx,
LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel,
bool IgnoreTemplateOrMacroSubstitution) const {
-
- // For compatibility with existing code, we treat arrays of length 0 or
- // 1 as flexible array members.
- const auto *CAT = Context.getAsConstantArrayType(getType());
- if (CAT) {
- llvm::APInt Size = CAT->getSize();
-
- using FAMKind = LangOptions::StrictFlexArraysLevelKind;
-
- if (StrictFlexArraysLevel == FAMKind::IncompleteOnly)
- return false;
-
- // GCC extension, only allowed to represent a FAM.
- if (Size == 0)
- return true;
-
- if (StrictFlexArraysLevel == FAMKind::ZeroOrIncomplete && Size.uge(1))
- return false;
-
- if (StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete && Size.uge(2))
- return false;
- } else if (!Context.getAsIncompleteArrayType(getType()))
- return false;
-
const Expr *E = IgnoreParens();
+ const Decl *D = nullptr;
- const NamedDecl *ND = nullptr;
- if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
- ND = DRE->getDecl();
- else if (const auto *ME = dyn_cast<MemberExpr>(E))
- ND = ME->getMemberDecl();
+ if (const auto *ME = dyn_cast<MemberExpr>(E))
+ D = ME->getMemberDecl();
+ else if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
+ D = DRE->getDecl();
else if (const auto *IRE = dyn_cast<ObjCIvarRefExpr>(E))
- return IRE->getDecl()->getNextIvar() == nullptr;
-
- if (!ND)
- return false;
+ D = IRE->getDecl();
- // A flexible array member must be the last member in the class.
- // FIXME: If the base type of the member expr is not FD->getParent(),
- // this should not be treated as a flexible array member access.
- if (const auto *FD = dyn_cast<FieldDecl>(ND)) {
- // GCC treats an array memeber of a union as an FAM if the size is one or
- // zero.
- if (CAT) {
- llvm::APInt Size = CAT->getSize();
- if (FD->getParent()->isUnion() && (Size.isZero() || Size.isOne()))
- return true;
- }
-
- // Don't consider sizes resulting from macro expansions or template argument
- // substitution to form C89 tail-padded arrays.
- if (IgnoreTemplateOrMacroSubstitution) {
- TypeSourceInfo *TInfo = FD->getTypeSourceInfo();
- while (TInfo) {
- TypeLoc TL = TInfo->getTypeLoc();
- // Look through typedefs.
- if (TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>()) {
- const TypedefNameDecl *TDL = TTL.getTypedefNameDecl();
- TInfo = TDL->getTypeSourceInfo();
- continue;
- }
- if (ConstantArrayTypeLoc CTL = TL.getAs<ConstantArrayTypeLoc>()) {
- const Expr *SizeExpr = dyn_cast<IntegerLiteral>(CTL.getSizeExpr());
- if (!SizeExpr || SizeExpr->getExprLoc().isMacroID())
- return false;
- }
- break;
- }
- }
-
- RecordDecl::field_iterator FI(
- DeclContext::decl_iterator(const_cast<FieldDecl *>(FD)));
- return ++FI == FD->getParent()->field_end();
- }
-
- return false;
+ return Decl::isFlexibleArrayMemberLike(Ctx, D, E->getType(),
+ StrictFlexArraysLevel,
+ IgnoreTemplateOrMacroSubstitution);
}
const ValueDecl *
diff --git a/contrib/llvm-project/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/contrib/llvm-project/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index e6b3097a80d8..7f8bbe787324 100644
--- a/contrib/llvm-project/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/contrib/llvm-project/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -114,6 +114,8 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
}
case CK_FloatingCast: {
+ if (DiscardResult)
+ return this->discard(SubExpr);
if (!this->visit(SubExpr))
return false;
const auto *TargetSemantics = &Ctx.getFloatSemantics(CE->getType());
@@ -121,6 +123,8 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
}
case CK_IntegralToFloating: {
+ if (DiscardResult)
+ return this->discard(SubExpr);
std::optional<PrimType> FromT = classify(SubExpr->getType());
if (!FromT)
return false;
@@ -135,6 +139,9 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
case CK_FloatingToBoolean:
case CK_FloatingToIntegral: {
+ if (DiscardResult)
+ return this->discard(SubExpr);
+
std::optional<PrimType> ToT = classify(CE->getType());
if (!ToT)
diff --git a/contrib/llvm-project/clang/lib/AST/Interp/Descriptor.cpp b/contrib/llvm-project/clang/lib/AST/Interp/Descriptor.cpp
index 59a952135a2d..b330e54baf33 100644
--- a/contrib/llvm-project/clang/lib/AST/Interp/Descriptor.cpp
+++ b/contrib/llvm-project/clang/lib/AST/Interp/Descriptor.cpp
@@ -275,8 +275,8 @@ Descriptor::Descriptor(const DeclTy &D, const Descriptor *Elem, MetadataSize MD,
}
/// Unknown-size arrays of composite elements.
-Descriptor::Descriptor(const DeclTy &D, Descriptor *Elem, bool IsTemporary,
- UnknownSize)
+Descriptor::Descriptor(const DeclTy &D, const Descriptor *Elem,
+ bool IsTemporary, UnknownSize)
: Source(D), ElemSize(Elem->getAllocSize() + sizeof(InlineDescriptor)),
Size(UnknownSizeMark), MDSize(0),
AllocSize(alignof(void *) + sizeof(InitMapPtr)), ElemDesc(Elem),
@@ -286,7 +286,7 @@ Descriptor::Descriptor(const DeclTy &D, Descriptor *Elem, bool IsTemporary,
}
/// Composite records.
-Descriptor::Descriptor(const DeclTy &D, Record *R, MetadataSize MD,
+Descriptor::Descriptor(const DeclTy &D, const Record *R, MetadataSize MD,
bool IsConst, bool IsTemporary, bool IsMutable)
: Source(D), ElemSize(std::max<size_t>(alignof(void *), R->getFullSize())),
Size(ElemSize), MDSize(MD.value_or(0)), AllocSize(Size + MDSize),
diff --git a/contrib/llvm-project/clang/lib/AST/Interp/Descriptor.h b/contrib/llvm-project/clang/lib/AST/Interp/Descriptor.h
index 8135f3d12f70..580c200f9095 100644
--- a/contrib/llvm-project/clang/lib/AST/Interp/Descriptor.h
+++ b/contrib/llvm-project/clang/lib/AST/Interp/Descriptor.h
@@ -100,7 +100,7 @@ public:
static constexpr MetadataSize InlineDescMD = sizeof(InlineDescriptor);
/// Pointer to the record, if block contains records.
- Record *const ElemRecord = nullptr;
+ const Record *const ElemRecord = nullptr;
/// Descriptor of the array element.
const Descriptor *const ElemDesc = nullptr;
/// Flag indicating if the block is mutable.
@@ -135,10 +135,11 @@ public:
unsigned NumElems, bool IsConst, bool IsTemporary, bool IsMutable);
/// Allocates a descriptor for an array of composites of unknown size.
- Descriptor(const DeclTy &D, Descriptor *Elem, bool IsTemporary, UnknownSize);
+ Descriptor(const DeclTy &D, const Descriptor *Elem, bool IsTemporary,
+ UnknownSize);
/// Allocates a descriptor for a record.
- Descriptor(const DeclTy &D, Record *R, MetadataSize MD, bool IsConst,
+ Descriptor(const DeclTy &D, const Record *R, MetadataSize MD, bool IsConst,
bool IsTemporary, bool IsMutable);
Descriptor(const DeclTy &D, MetadataSize MD);
diff --git a/contrib/llvm-project/clang/lib/AST/Interp/Interp.cpp b/contrib/llvm-project/clang/lib/AST/Interp/Interp.cpp
index 21ea2503b94b..9de0926b9dba 100644
--- a/contrib/llvm-project/clang/lib/AST/Interp/Interp.cpp
+++ b/contrib/llvm-project/clang/lib/AST/Interp/Interp.cpp
@@ -134,6 +134,18 @@ void cleanupAfterFunctionCall(InterpState &S, CodePtr OpPC) {
if (CurFunc->isUnevaluatedBuiltin())
return;
+ // Some builtin functions require us to only look at the call site, since
+ // the classified parameter types do not match.
+ if (CurFunc->isBuiltin()) {
+ const auto *CE =
+ cast<CallExpr>(S.Current->Caller->getExpr(S.Current->getRetPC()));
+ for (int32_t I = CE->getNumArgs() - 1; I >= 0; --I) {
+ const Expr *A = CE->getArg(I);
+ popArg(S, A);
+ }
+ return;
+ }
+
if (S.Current->Caller && CurFunc->isVariadic()) {
// CallExpr we're look for is at the return PC of the current function, i.e.
// in the caller.
diff --git a/contrib/llvm-project/clang/lib/AST/Interp/InterpBuiltin.cpp b/contrib/llvm-project/clang/lib/AST/Interp/InterpBuiltin.cpp
index b55b1569a259..754ca96b0c64 100644
--- a/contrib/llvm-project/clang/lib/AST/Interp/InterpBuiltin.cpp
+++ b/contrib/llvm-project/clang/lib/AST/Interp/InterpBuiltin.cpp
@@ -164,6 +164,8 @@ static bool retPrimValue(InterpState &S, CodePtr OpPC, APValue &Result,
case X: \
return Ret<X>(S, OpPC, Result);
switch (*T) {
+ RET_CASE(PT_Ptr);
+ RET_CASE(PT_FnPtr);
RET_CASE(PT_Float);
RET_CASE(PT_Bool);
RET_CASE(PT_Sint8);
@@ -613,15 +615,34 @@ static bool interp__builtin_ffs(InterpState &S, CodePtr OpPC,
return true;
}
+static bool interp__builtin_addressof(InterpState &S, CodePtr OpPC,
+ const InterpFrame *Frame,
+ const Function *Func,
+ const CallExpr *Call) {
+ PrimType PtrT =
+ S.getContext().classify(Call->getArg(0)->getType()).value_or(PT_Ptr);
+
+ if (PtrT == PT_FnPtr) {
+ const FunctionPointer &Arg = S.Stk.peek<FunctionPointer>();
+ S.Stk.push<FunctionPointer>(Arg);
+ } else if (PtrT == PT_Ptr) {
+ const Pointer &Arg = S.Stk.peek<Pointer>();
+ S.Stk.push<Pointer>(Arg);
+ } else {
+ assert(false && "Unsupported pointer type passed to __builtin_addressof()");
+ }
+ return true;
+}
+
bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
const CallExpr *Call) {
InterpFrame *Frame = S.Current;
APValue Dummy;
- QualType ReturnType = Call->getCallReturnType(S.getCtx());
- std::optional<PrimType> ReturnT = S.getContext().classify(ReturnType);
+ std::optional<PrimType> ReturnT = S.getContext().classify(Call->getType());
+
// If classify failed, we assume void.
- assert(ReturnT || ReturnType->isVoidType());
+ assert(ReturnT || Call->getType()->isVoidType());
switch (F->getBuiltinID()) {
case Builtin::BI__builtin_is_constant_evaluated:
@@ -820,6 +841,12 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F,
if (!interp__builtin_ffs(S, OpPC, Frame, F, Call))
return false;
break;
+ case Builtin::BIaddressof:
+ case Builtin::BI__addressof:
+ case Builtin::BI__builtin_addressof:
+ if (!interp__builtin_addressof(S, OpPC, Frame, F, Call))
+ return false;
+ break;
default:
return false;
diff --git a/contrib/llvm-project/clang/lib/AST/Interp/Program.cpp b/contrib/llvm-project/clang/lib/AST/Interp/Program.cpp
index 52e13398163e..1daefab4dcda 100644
--- a/contrib/llvm-project/clang/lib/AST/Interp/Program.cpp
+++ b/contrib/llvm-project/clang/lib/AST/Interp/Program.cpp
@@ -315,14 +315,14 @@ Descriptor *Program::createDescriptor(const DeclTy &D, const Type *Ty,
bool IsConst, bool IsTemporary,
bool IsMutable, const Expr *Init) {
// Classes and structures.
- if (auto *RT = Ty->getAs<RecordType>()) {
- if (auto *Record = getOrCreateRecord(RT->getDecl()))
+ if (const auto *RT = Ty->getAs<RecordType>()) {
+ if (const auto *Record = getOrCreateRecord(RT->getDecl()))
return allocateDescriptor(D, Record, MDSize, IsConst, IsTemporary,
IsMutable);
}
// Arrays.
- if (auto ArrayType = Ty->getAsArrayTypeUnsafe()) {
+ if (const auto ArrayType = Ty->getAsArrayTypeUnsafe()) {
QualType ElemTy = ArrayType->getElementType();
// Array of well-known bounds.
if (auto CAT = dyn_cast<ConstantArrayType>(ArrayType)) {
@@ -338,7 +338,7 @@ Descriptor *Program::createDescriptor(const DeclTy &D, const Type *Ty,
} else {
// Arrays of composites. In this case, the array is a list of pointers,
// followed by the actual elements.
- Descriptor *ElemDesc = createDescriptor(
+ const Descriptor *ElemDesc = createDescriptor(
D, ElemTy.getTypePtr(), std::nullopt, IsConst, IsTemporary);
if (!ElemDesc)
return nullptr;
@@ -358,8 +358,8 @@ Descriptor *Program::createDescriptor(const DeclTy &D, const Type *Ty,
return allocateDescriptor(D, *T, IsTemporary,
Descriptor::UnknownSize{});
} else {
- Descriptor *Desc = createDescriptor(D, ElemTy.getTypePtr(), MDSize,
- IsConst, IsTemporary);
+ const Descriptor *Desc = createDescriptor(D, ElemTy.getTypePtr(),
+ MDSize, IsConst, IsTemporary);
if (!Desc)
return nullptr;
return allocateDescriptor(D, Desc, IsTemporary,
@@ -369,14 +369,14 @@ Descriptor *Program::createDescriptor(const DeclTy &D, const Type *Ty,
}
// Atomic types.
- if (auto *AT = Ty->getAs<AtomicType>()) {
+ if (const auto *AT = Ty->getAs<AtomicType>()) {
const Type *InnerTy = AT->getValueType().getTypePtr();
return createDescriptor(D, InnerTy, MDSize, IsConst, IsTemporary,
IsMutable);
}
// Complex types - represented as arrays of elements.
- if (auto *CT = Ty->getAs<ComplexType>()) {
+ if (const auto *CT = Ty->getAs<ComplexType>()) {
PrimType ElemTy = *Ctx.classify(CT->getElementType());
return allocateDescriptor(D, ElemTy, MDSize, 2, IsConst, IsTemporary,
IsMutable);
diff --git a/contrib/llvm-project/clang/lib/AST/Type.cpp b/contrib/llvm-project/clang/lib/AST/Type.cpp
index a894d3289eb1..b419fc8836b0 100644
--- a/contrib/llvm-project/clang/lib/AST/Type.cpp
+++ b/contrib/llvm-project/clang/lib/AST/Type.cpp
@@ -2604,19 +2604,22 @@ bool QualType::isTrivialType(const ASTContext &Context) const {
return false;
}
-bool QualType::isTriviallyCopyableType(const ASTContext &Context) const {
- if ((*this)->isArrayType())
- return Context.getBaseElementType(*this).isTriviallyCopyableType(Context);
+static bool isTriviallyCopyableTypeImpl(const QualType &type,
+ const ASTContext &Context,
+ bool IsCopyConstructible) {
+ if (type->isArrayType())
+ return isTriviallyCopyableTypeImpl(Context.getBaseElementType(type),
+ Context, IsCopyConstructible);
- if (hasNonTrivialObjCLifetime())
+ if (type.hasNonTrivialObjCLifetime())
return false;
// C++11 [basic.types]p9 - See Core 2094
// Scalar types, trivially copyable class types, arrays of such types, and
// cv-qualified versions of these types are collectively
- // called trivially copyable types.
+ // called trivially copy constructible types.
- QualType CanonicalType = getCanonicalType();
+ QualType CanonicalType = type.getCanonicalType();
if (CanonicalType->isDependentType())
return false;
@@ -2634,16 +2637,29 @@ bool QualType::isTriviallyCopyableType(const ASTContext &Context) const {
if (const auto *RT = CanonicalType->getAs<RecordType>()) {
if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
- if (!ClassDecl->isTriviallyCopyable()) return false;
+ if (IsCopyConstructible) {
+ return ClassDecl->isTriviallyCopyConstructible();
+ } else {
+ return ClassDecl->isTriviallyCopyable();
+ }
}
-
return true;
}
-
// No other types can match.
return false;
}
+bool QualType::isTriviallyCopyableType(const ASTContext &Context) const {
+ return isTriviallyCopyableTypeImpl(*this, Context,
+ /*IsCopyConstructible=*/false);
+}
+
+bool QualType::isTriviallyCopyConstructibleType(
+ const ASTContext &Context) const {
+ return isTriviallyCopyableTypeImpl(*this, Context,
+ /*IsCopyConstructible=*/true);
+}
+
bool QualType::isTriviallyRelocatableType(const ASTContext &Context) const {
QualType BaseElementType = Context.getBaseElementType(*this);