aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/AST/ExprCXX.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/AST/ExprCXX.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/AST/ExprCXX.cpp123
1 files changed, 104 insertions, 19 deletions
diff --git a/contrib/llvm-project/clang/lib/AST/ExprCXX.cpp b/contrib/llvm-project/clang/lib/AST/ExprCXX.cpp
index e61c11dffd88..45e2badf2ddd 100644
--- a/contrib/llvm-project/clang/lib/AST/ExprCXX.cpp
+++ b/contrib/llvm-project/clang/lib/AST/ExprCXX.cpp
@@ -166,6 +166,53 @@ QualType CXXTypeidExpr::getTypeOperand(ASTContext &Context) const {
Operand.get<TypeSourceInfo *>()->getType().getNonReferenceType(), Quals);
}
+static bool isGLValueFromPointerDeref(const Expr *E) {
+ E = E->IgnoreParens();
+
+ if (const auto *CE = dyn_cast<CastExpr>(E)) {
+ if (!CE->getSubExpr()->isGLValue())
+ return false;
+ return isGLValueFromPointerDeref(CE->getSubExpr());
+ }
+
+ if (const auto *OVE = dyn_cast<OpaqueValueExpr>(E))
+ return isGLValueFromPointerDeref(OVE->getSourceExpr());
+
+ if (const auto *BO = dyn_cast<BinaryOperator>(E))
+ if (BO->getOpcode() == BO_Comma)
+ return isGLValueFromPointerDeref(BO->getRHS());
+
+ if (const auto *ACO = dyn_cast<AbstractConditionalOperator>(E))
+ return isGLValueFromPointerDeref(ACO->getTrueExpr()) ||
+ isGLValueFromPointerDeref(ACO->getFalseExpr());
+
+ // C++11 [expr.sub]p1:
+ // The expression E1[E2] is identical (by definition) to *((E1)+(E2))
+ if (isa<ArraySubscriptExpr>(E))
+ return true;
+
+ if (const auto *UO = dyn_cast<UnaryOperator>(E))
+ if (UO->getOpcode() == UO_Deref)
+ return true;
+
+ return false;
+}
+
+bool CXXTypeidExpr::hasNullCheck() const {
+ if (!isPotentiallyEvaluated())
+ return false;
+
+ // C++ [expr.typeid]p2:
+ // If the glvalue expression is obtained by applying the unary * operator to
+ // a pointer and the pointer is a null pointer value, the typeid expression
+ // throws the std::bad_typeid exception.
+ //
+ // However, this paragraph's intent is not clear. We choose a very generous
+ // interpretation which implores us to consider comma operators, conditional
+ // operators, parentheses and other such constructs.
+ return isGLValueFromPointerDeref(getExprOperand());
+}
+
QualType CXXUuidofExpr::getTypeOperand(ASTContext &Context) const {
assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)");
Qualifiers Quals;
@@ -353,15 +400,15 @@ SourceLocation CXXPseudoDestructorExpr::getEndLoc() const {
UnresolvedLookupExpr::UnresolvedLookupExpr(
const ASTContext &Context, CXXRecordDecl *NamingClass,
NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
- const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded,
+ const DeclarationNameInfo &NameInfo, bool RequiresADL,
const TemplateArgumentListInfo *TemplateArgs, UnresolvedSetIterator Begin,
- UnresolvedSetIterator End, bool KnownDependent)
+ UnresolvedSetIterator End, bool KnownDependent,
+ bool KnownInstantiationDependent)
: OverloadExpr(UnresolvedLookupExprClass, Context, QualifierLoc,
TemplateKWLoc, NameInfo, TemplateArgs, Begin, End,
- KnownDependent, false, false),
+ KnownDependent, KnownInstantiationDependent, false),
NamingClass(NamingClass) {
UnresolvedLookupExprBits.RequiresADL = RequiresADL;
- UnresolvedLookupExprBits.Overloaded = Overloaded;
}
UnresolvedLookupExpr::UnresolvedLookupExpr(EmptyShell Empty,
@@ -373,15 +420,17 @@ UnresolvedLookupExpr::UnresolvedLookupExpr(EmptyShell Empty,
UnresolvedLookupExpr *UnresolvedLookupExpr::Create(
const ASTContext &Context, CXXRecordDecl *NamingClass,
NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
- bool RequiresADL, bool Overloaded, UnresolvedSetIterator Begin,
- UnresolvedSetIterator End) {
+ bool RequiresADL, UnresolvedSetIterator Begin, UnresolvedSetIterator End,
+ bool KnownDependent, bool KnownInstantiationDependent) {
unsigned NumResults = End - Begin;
unsigned Size = totalSizeToAlloc<DeclAccessPair, ASTTemplateKWAndArgsInfo,
TemplateArgumentLoc>(NumResults, 0, 0);
void *Mem = Context.Allocate(Size, alignof(UnresolvedLookupExpr));
- return new (Mem) UnresolvedLookupExpr(Context, NamingClass, QualifierLoc,
- SourceLocation(), NameInfo, RequiresADL,
- Overloaded, nullptr, Begin, End, false);
+ return new (Mem) UnresolvedLookupExpr(
+ Context, NamingClass, QualifierLoc,
+ /*TemplateKWLoc=*/SourceLocation(), NameInfo, RequiresADL,
+ /*TemplateArgs=*/nullptr, Begin, End, KnownDependent,
+ KnownInstantiationDependent);
}
UnresolvedLookupExpr *UnresolvedLookupExpr::Create(
@@ -389,17 +438,18 @@ UnresolvedLookupExpr *UnresolvedLookupExpr::Create(
NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc,
const DeclarationNameInfo &NameInfo, bool RequiresADL,
const TemplateArgumentListInfo *Args, UnresolvedSetIterator Begin,
- UnresolvedSetIterator End, bool KnownDependent) {
- assert(Args || TemplateKWLoc.isValid());
+ UnresolvedSetIterator End, bool KnownDependent,
+ bool KnownInstantiationDependent) {
unsigned NumResults = End - Begin;
+ bool HasTemplateKWAndArgsInfo = Args || TemplateKWLoc.isValid();
unsigned NumTemplateArgs = Args ? Args->size() : 0;
- unsigned Size =
- totalSizeToAlloc<DeclAccessPair, ASTTemplateKWAndArgsInfo,
- TemplateArgumentLoc>(NumResults, 1, NumTemplateArgs);
+ unsigned Size = totalSizeToAlloc<DeclAccessPair, ASTTemplateKWAndArgsInfo,
+ TemplateArgumentLoc>(
+ NumResults, HasTemplateKWAndArgsInfo, NumTemplateArgs);
void *Mem = Context.Allocate(Size, alignof(UnresolvedLookupExpr));
return new (Mem) UnresolvedLookupExpr(
Context, NamingClass, QualifierLoc, TemplateKWLoc, NameInfo, RequiresADL,
- /*Overloaded=*/true, Args, Begin, End, KnownDependent);
+ Args, Begin, End, KnownDependent, KnownInstantiationDependent);
}
UnresolvedLookupExpr *UnresolvedLookupExpr::CreateEmpty(
@@ -511,14 +561,14 @@ DependentScopeDeclRefExpr::CreateEmpty(const ASTContext &Context,
}
SourceLocation CXXConstructExpr::getBeginLoc() const {
- if (isa<CXXTemporaryObjectExpr>(this))
- return cast<CXXTemporaryObjectExpr>(this)->getBeginLoc();
+ if (const auto *TOE = dyn_cast<CXXTemporaryObjectExpr>(this))
+ return TOE->getBeginLoc();
return getLocation();
}
SourceLocation CXXConstructExpr::getEndLoc() const {
- if (isa<CXXTemporaryObjectExpr>(this))
- return cast<CXXTemporaryObjectExpr>(this)->getEndLoc();
+ if (const auto *TOE = dyn_cast<CXXTemporaryObjectExpr>(this))
+ return TOE->getEndLoc();
if (ParenOrBraceRange.isValid())
return ParenOrBraceRange.getEnd();
@@ -1665,6 +1715,41 @@ NonTypeTemplateParmDecl *SubstNonTypeTemplateParmExpr::getParameter() const {
getReplacedTemplateParameterList(getAssociatedDecl())->asArray()[Index]);
}
+PackIndexingExpr *PackIndexingExpr::Create(
+ ASTContext &Context, SourceLocation EllipsisLoc, SourceLocation RSquareLoc,
+ Expr *PackIdExpr, Expr *IndexExpr, std::optional<int64_t> Index,
+ ArrayRef<Expr *> SubstitutedExprs, bool ExpandedToEmptyPack) {
+ QualType Type;
+ if (Index && !SubstitutedExprs.empty())
+ Type = SubstitutedExprs[*Index]->getType();
+ else
+ Type = Context.DependentTy;
+
+ void *Storage =
+ Context.Allocate(totalSizeToAlloc<Expr *>(SubstitutedExprs.size()));
+ return new (Storage)
+ PackIndexingExpr(Type, EllipsisLoc, RSquareLoc, PackIdExpr, IndexExpr,
+ SubstitutedExprs, ExpandedToEmptyPack);
+}
+
+NamedDecl *PackIndexingExpr::getPackDecl() const {
+ if (auto *D = dyn_cast<DeclRefExpr>(getPackIdExpression()); D) {
+ NamedDecl *ND = dyn_cast<NamedDecl>(D->getDecl());
+ assert(ND && "exected a named decl");
+ return ND;
+ }
+ assert(false && "invalid declaration kind in pack indexing expression");
+ return nullptr;
+}
+
+PackIndexingExpr *
+PackIndexingExpr::CreateDeserialized(ASTContext &Context,
+ unsigned NumTransformedExprs) {
+ void *Storage =
+ Context.Allocate(totalSizeToAlloc<Expr *>(NumTransformedExprs));
+ return new (Storage) PackIndexingExpr(EmptyShell{});
+}
+
QualType SubstNonTypeTemplateParmExpr::getParameterType(
const ASTContext &Context) const {
// Note that, for a class type NTTP, we will have an lvalue of type 'const