aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/TreeTransform.h
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/TreeTransform.h')
-rw-r--r--clang/lib/Sema/TreeTransform.h473
1 files changed, 281 insertions, 192 deletions
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 6a05ecc5370f..10b3587885e3 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -19,8 +19,8 @@
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
-#include "clang/AST/ExprConcepts.h"
#include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprConcepts.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/ExprOpenMP.h"
#include "clang/AST/OpenMPClause.h"
@@ -31,6 +31,7 @@
#include "clang/Basic/DiagnosticParse.h"
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Sema/Designator.h"
+#include "clang/Sema/EnterExpressionEvaluationContext.h"
#include "clang/Sema/Lookup.h"
#include "clang/Sema/Ownership.h"
#include "clang/Sema/ParsedTemplate.h"
@@ -377,22 +378,43 @@ public:
/// By default, this routine transforms a statement by delegating to the
/// appropriate TransformXXXAttr function to transform a specific kind
/// of attribute. Subclasses may override this function to transform
- /// attributed statements using some other mechanism.
+ /// attributed statements/types using some other mechanism.
///
/// \returns the transformed attribute
const Attr *TransformAttr(const Attr *S);
-/// Transform the specified attribute.
-///
-/// Subclasses should override the transformation of attributes with a pragma
-/// spelling to transform expressions stored within the attribute.
-///
-/// \returns the transformed attribute.
-#define ATTR(X)
-#define PRAGMA_SPELLING_ATTR(X) \
+ // Transform the given statement attribute.
+ //
+ // Delegates to the appropriate TransformXXXAttr function to transform a
+ // specific kind of statement attribute. Unlike the non-statement taking
+ // version of this, this implements all attributes, not just pragmas.
+ const Attr *TransformStmtAttr(const Stmt *OrigS, const Stmt *InstS,
+ const Attr *A);
+
+ // Transform the specified attribute.
+ //
+ // Subclasses should override the transformation of attributes with a pragma
+ // spelling to transform expressions stored within the attribute.
+ //
+ // \returns the transformed attribute.
+#define ATTR(X) \
const X##Attr *Transform##X##Attr(const X##Attr *R) { return R; }
#include "clang/Basic/AttrList.inc"
+ // Transform the specified attribute.
+ //
+ // Subclasses should override the transformation of attributes to do
+ // transformation and checking of statement attributes. By default, this
+ // delegates to the non-statement taking version.
+ //
+ // \returns the transformed attribute.
+#define ATTR(X) \
+ const X##Attr *TransformStmt##X##Attr(const Stmt *, const Stmt *, \
+ const X##Attr *A) { \
+ return getDerived().Transform##X##Attr(A); \
+ }
+#include "clang/Basic/AttrList.inc"
+
/// Transform the given expression.
///
/// By default, this routine transforms an expression by delegating to the
@@ -2400,6 +2422,19 @@ public:
return getSema().ActOnOpenMPMessageClause(MS, StartLoc, LParenLoc, EndLoc);
}
+ /// Build a new OpenMP 'doacross' clause.
+ ///
+ /// By default, performs semantic analysis to build the new OpenMP clause.
+ /// Subclasses may override this routine to provide different behavior.
+ OMPClause *
+ RebuildOMPDoacrossClause(OpenMPDoacrossClauseModifier DepType,
+ SourceLocation DepLoc, SourceLocation ColonLoc,
+ ArrayRef<Expr *> VarList, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation EndLoc) {
+ return getSema().ActOnOpenMPDoacrossClause(
+ DepType, DepLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
+ }
+
/// Rebuild the operand to an Objective-C \@synchronized statement.
///
/// By default, performs semantic analysis to build the new statement.
@@ -2803,6 +2838,21 @@ public:
R.addDecl(FoundDecl);
R.resolveKind();
+ if (getSema().isUnevaluatedContext() && Base->isImplicitCXXThis() &&
+ isa<FieldDecl, IndirectFieldDecl, MSPropertyDecl>(Member)) {
+ if (auto *ThisClass = cast<CXXThisExpr>(Base)
+ ->getType()
+ ->getPointeeType()
+ ->getAsCXXRecordDecl()) {
+ auto *Class = cast<CXXRecordDecl>(Member->getDeclContext());
+ // In unevaluated contexts, an expression supposed to be a member access
+ // might reference a member in an unrelated class.
+ if (!ThisClass->Equals(Class) && !ThisClass->isDerivedFrom(Class))
+ return getSema().BuildDeclRefExpr(Member, Member->getType(),
+ VK_LValue, Member->getLocation());
+ }
+ }
+
return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow,
SS, TemplateKWLoc,
FirstQualifierInScope,
@@ -2977,7 +3027,7 @@ public:
RParenLoc);
}
- /// Build a new generic selection expression.
+ /// Build a new generic selection expression with an expression predicate.
///
/// By default, performs semantic analysis to build the new expression.
/// Subclasses may override this routine to provide different behavior.
@@ -2988,9 +3038,25 @@ public:
ArrayRef<TypeSourceInfo *> Types,
ArrayRef<Expr *> Exprs) {
return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
+ /*PredicateIsExpr=*/true,
ControllingExpr, Types, Exprs);
}
+ /// Build a new generic selection expression with a type predicate.
+ ///
+ /// By default, performs semantic analysis to build the new expression.
+ /// Subclasses may override this routine to provide different behavior.
+ ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
+ SourceLocation DefaultLoc,
+ SourceLocation RParenLoc,
+ TypeSourceInfo *ControllingType,
+ ArrayRef<TypeSourceInfo *> Types,
+ ArrayRef<Expr *> Exprs) {
+ return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
+ /*PredicateIsExpr=*/false,
+ ControllingType, Types, Exprs);
+ }
+
/// Build a new overloaded operator call expression.
///
/// By default, performs semantic analysis to build the new expression.
@@ -3000,10 +3066,11 @@ public:
/// argument-dependent lookup, etc. Subclasses may override this routine to
/// provide different behavior.
ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
- SourceLocation OpLoc,
- Expr *Callee,
- Expr *First,
- Expr *Second);
+ SourceLocation OpLoc,
+ SourceLocation CalleeLoc,
+ bool RequiresADL,
+ const UnresolvedSetImpl &Functions,
+ Expr *First, Expr *Second);
/// Build a new C++ "named" cast expression, such as static_cast or
/// reinterpret_cast.
@@ -3137,6 +3204,13 @@ public:
Expr *Sub,
SourceLocation RParenLoc,
bool ListInitialization) {
+ // If Sub is a ParenListExpr, then Sub is the syntatic form of a
+ // CXXParenListInitExpr. Pass its expanded arguments so that the
+ // CXXParenListInitExpr can be rebuilt.
+ if (auto *PLE = dyn_cast<ParenListExpr>(Sub))
+ return getSema().BuildCXXTypeConstructExpr(
+ TInfo, LParenLoc, MultiExprArg(PLE->getExprs(), PLE->getNumExprs()),
+ RParenLoc, ListInitialization);
return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc,
MultiExprArg(&Sub, 1), RParenLoc,
ListInitialization);
@@ -3866,16 +3940,6 @@ public:
return getSema().BuildEmptyCXXFoldExpr(EllipsisLoc, Operator);
}
- ExprResult RebuildCXXParenListInitExpr(ArrayRef<Expr *> Args, QualType T,
- unsigned NumUserSpecifiedExprs,
- SourceLocation InitLoc,
- SourceLocation LParenLoc,
- SourceLocation RParenLoc) {
- return CXXParenListInitExpr::Create(getSema().Context, Args, T,
- NumUserSpecifiedExprs, InitLoc,
- LParenLoc, RParenLoc);
- }
-
/// Build a new atomic operation expression.
///
/// By default, performs semantic analysis to build the new expression.
@@ -4569,7 +4633,7 @@ bool TreeTransform<Derived>::TransformTemplateArgument(
getSema(),
Uneval ? Sema::ExpressionEvaluationContext::Unevaluated
: Sema::ExpressionEvaluationContext::ConstantEvaluated,
- /*LambdaContextDecl=*/nullptr, /*ExprContext=*/
+ Sema::ReuseLambdaContextDecl, /*ExprContext=*/
Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
Expr *InputExpr = Input.getSourceExpression();
@@ -5897,7 +5961,6 @@ bool TreeTransform<Derived>::TransformFunctionTypeParams(
= dyn_cast<PackExpansionType>(OldType)) {
// We have a function parameter pack that may need to be expanded.
QualType Pattern = Expansion->getPattern();
- NumExpansions = Expansion->getNumExpansions();
SmallVector<UnexpandedParameterPack, 2> Unexpanded;
getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
@@ -6992,7 +7055,8 @@ QualType TreeTransform<Derived>::TransformAttributedType(
// type sugar, and therefore cannot be diagnosed in any other way.
if (auto nullability = oldType->getImmediateNullability()) {
if (!modifiedType->canHaveNullability()) {
- SemaRef.Diag(TL.getAttr()->getLocation(),
+ SemaRef.Diag((TL.getAttr() ? TL.getAttr()->getLocation()
+ : TL.getModifiedLoc().getBeginLoc()),
diag::err_nullability_nonpointer)
<< DiagNullabilityKind(*nullability, false) << modifiedType;
return QualType();
@@ -7536,36 +7600,52 @@ const Attr *TreeTransform<Derived>::TransformAttr(const Attr *R) {
return R;
switch (R->getKind()) {
-// Transform attributes with a pragma spelling by calling TransformXXXAttr.
-#define ATTR(X)
-#define PRAGMA_SPELLING_ATTR(X) \
+// Transform attributes by calling TransformXXXAttr.
+#define ATTR(X) \
case attr::X: \
return getDerived().Transform##X##Attr(cast<X##Attr>(R));
#include "clang/Basic/AttrList.inc"
- default:
+ }
+ return R;
+}
+
+template <typename Derived>
+const Attr *TreeTransform<Derived>::TransformStmtAttr(const Stmt *OrigS,
+ const Stmt *InstS,
+ const Attr *R) {
+ if (!R)
return R;
+
+ switch (R->getKind()) {
+// Transform attributes by calling TransformStmtXXXAttr.
+#define ATTR(X) \
+ case attr::X: \
+ return getDerived().TransformStmt##X##Attr(OrigS, InstS, cast<X##Attr>(R));
+#include "clang/Basic/AttrList.inc"
}
+ return TransformAttr(R);
}
template <typename Derived>
StmtResult
TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S,
StmtDiscardKind SDK) {
+ StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
+ if (SubStmt.isInvalid())
+ return StmtError();
+
bool AttrsChanged = false;
SmallVector<const Attr *, 1> Attrs;
// Visit attributes and keep track if any are transformed.
for (const auto *I : S->getAttrs()) {
- const Attr *R = getDerived().TransformAttr(I);
+ const Attr *R =
+ getDerived().TransformStmtAttr(S->getSubStmt(), SubStmt.get(), I);
AttrsChanged |= (I != R);
if (R)
Attrs.push_back(R);
}
- StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
- if (SubStmt.isInvalid())
- return StmtError();
-
if (SubStmt.get() == S->getSubStmt() && !AttrsChanged)
return S;
@@ -7943,8 +8023,7 @@ TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {
TransformedExprs, S->getEndLoc());
}
-// C++ Coroutines TS
-
+// C++ Coroutines
template<typename Derived>
StmtResult
TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
@@ -8052,6 +8131,13 @@ TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
return StmtError();
Builder.Deallocate = DeallocRes.get();
+ if (auto *ResultDecl = S->getResultDecl()) {
+ StmtResult Res = getDerived().TransformStmt(ResultDecl);
+ if (Res.isInvalid())
+ return StmtError();
+ Builder.ResultDecl = Res.get();
+ }
+
if (auto *ReturnStmt = S->getReturnStmt()) {
StmtResult Res = getDerived().TransformStmt(ReturnStmt);
if (Res.isInvalid())
@@ -10654,6 +10740,22 @@ OMPClause *TreeTransform<Derived>::TransformOMPXDynCGroupMemClause(
Size.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
}
+template <typename Derived>
+OMPClause *
+TreeTransform<Derived>::TransformOMPDoacrossClause(OMPDoacrossClause *C) {
+ llvm::SmallVector<Expr *, 16> Vars;
+ Vars.reserve(C->varlist_size());
+ for (auto *VE : C->varlists()) {
+ ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
+ if (EVar.isInvalid())
+ return nullptr;
+ Vars.push_back(EVar.get());
+ }
+ return getDerived().RebuildOMPDoacrossClause(
+ C->getDependenceType(), C->getDependenceLoc(), C->getColonLoc(), Vars,
+ C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
+}
+
//===----------------------------------------------------------------------===//
// Expression transformation
//===----------------------------------------------------------------------===//
@@ -10797,9 +10899,14 @@ TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) {
template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
- ExprResult ControllingExpr =
- getDerived().TransformExpr(E->getControllingExpr());
- if (ControllingExpr.isInvalid())
+ ExprResult ControllingExpr;
+ TypeSourceInfo *ControllingType = nullptr;
+ if (E->isExprPredicate())
+ ControllingExpr = getDerived().TransformExpr(E->getControllingExpr());
+ else
+ ControllingType = getDerived().TransformType(E->getControllingType());
+
+ if (ControllingExpr.isInvalid() && !ControllingType)
return ExprError();
SmallVector<Expr *, 4> AssocExprs;
@@ -10822,12 +10929,16 @@ TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
AssocExprs.push_back(AssocExpr.get());
}
+ if (!ControllingType)
return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),
E->getDefaultLoc(),
E->getRParenLoc(),
ControllingExpr.get(),
AssocTypes,
AssocExprs);
+ return getDerived().RebuildGenericSelectionExpr(
+ E->getGenericLoc(), E->getDefaultLoc(), E->getRParenLoc(),
+ ControllingType, AssocTypes, AssocExprs);
}
template<typename Derived>
@@ -11346,7 +11457,8 @@ TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
if (LHS.isInvalid())
return ExprError();
- ExprResult RHS = getDerived().TransformExpr(E->getRHS());
+ ExprResult RHS =
+ getDerived().TransformInitializer(E->getRHS(), /*NotCopyInit=*/false);
if (RHS.isInvalid())
return ExprError();
@@ -11606,13 +11718,12 @@ TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
bool ExprChanged = false;
for (const DesignatedInitExpr::Designator &D : E->designators()) {
if (D.isFieldDesignator()) {
- Desig.AddDesignator(Designator::getField(D.getFieldName(),
- D.getDotLoc(),
- D.getFieldLoc()));
- if (D.getField()) {
+ Desig.AddDesignator(Designator::CreateFieldDesignator(
+ D.getFieldName(), D.getDotLoc(), D.getFieldLoc()));
+ if (D.getFieldDecl()) {
FieldDecl *Field = cast_or_null<FieldDecl>(
- getDerived().TransformDecl(D.getFieldLoc(), D.getField()));
- if (Field != D.getField())
+ getDerived().TransformDecl(D.getFieldLoc(), D.getFieldDecl()));
+ if (Field != D.getFieldDecl())
// Rebuild the expression when the transformed FieldDecl is
// different to the already assigned FieldDecl.
ExprChanged = true;
@@ -11631,7 +11742,7 @@ TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
return ExprError();
Desig.AddDesignator(
- Designator::getArray(Index.get(), D.getLBracketLoc()));
+ Designator::CreateArrayDesignator(Index.get(), D.getLBracketLoc()));
ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(D);
ArrayExprs.push_back(Index.get());
@@ -11648,10 +11759,8 @@ TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
if (End.isInvalid())
return ExprError();
- Desig.AddDesignator(Designator::getArrayRange(Start.get(),
- End.get(),
- D.getLBracketLoc(),
- D.getEllipsisLoc()));
+ Desig.AddDesignator(Designator::CreateArrayRangeDesignator(
+ Start.get(), End.get(), D.getLBracketLoc(), D.getEllipsisLoc()));
ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(D) ||
End.get() != E->getArrayRangeEnd(D);
@@ -11883,10 +11992,6 @@ TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
llvm_unreachable("not an overloaded operator?");
}
- ExprResult Callee = getDerived().TransformExpr(E->getCallee());
- if (Callee.isInvalid())
- return ExprError();
-
ExprResult First;
if (E->getOperator() == OO_Amp)
First = getDerived().TransformAddressOfOperand(E->getArg(0));
@@ -11897,28 +12002,45 @@ TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
ExprResult Second;
if (E->getNumArgs() == 2) {
- Second = getDerived().TransformExpr(E->getArg(1));
+ Second =
+ getDerived().TransformInitializer(E->getArg(1), /*NotCopyInit=*/false);
if (Second.isInvalid())
return ExprError();
}
- if (!getDerived().AlwaysRebuild() &&
- Callee.get() == E->getCallee() &&
- First.get() == E->getArg(0) &&
- (E->getNumArgs() != 2 || Second.get() == E->getArg(1)))
- return SemaRef.MaybeBindToTemporary(E);
-
Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
FPOptionsOverride NewOverrides(E->getFPFeatures());
getSema().CurFPFeatures =
NewOverrides.applyOverrides(getSema().getLangOpts());
getSema().FpPragmaStack.CurrentValue = NewOverrides;
- return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(),
- E->getOperatorLoc(),
- Callee.get(),
- First.get(),
- Second.get());
+ Expr *Callee = E->getCallee();
+ if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Callee)) {
+ LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
+ Sema::LookupOrdinaryName);
+ if (getDerived().TransformOverloadExprDecls(ULE, ULE->requiresADL(), R))
+ return ExprError();
+
+ return getDerived().RebuildCXXOperatorCallExpr(
+ E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
+ ULE->requiresADL(), R.asUnresolvedSet(), First.get(), Second.get());
+ }
+
+ UnresolvedSet<1> Functions;
+ if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
+ Callee = ICE->getSubExprAsWritten();
+ NamedDecl *DR = cast<DeclRefExpr>(Callee)->getDecl();
+ ValueDecl *VD = cast_or_null<ValueDecl>(
+ getDerived().TransformDecl(DR->getLocation(), DR));
+ if (!VD)
+ return ExprError();
+
+ if (!isa<CXXMethodDecl>(VD))
+ Functions.addDecl(VD);
+
+ return getDerived().RebuildCXXOperatorCallExpr(
+ E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
+ /*RequiresADL=*/false, Functions, First.get(), Second.get());
}
template<typename Derived>
@@ -13237,37 +13359,6 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
LambdaScopeInfo *LSI = getSema().PushLambdaScope();
Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
- // Transform the template parameters, and add them to the current
- // instantiation scope. The null case is handled correctly.
- auto TPL = getDerived().TransformTemplateParameterList(
- E->getTemplateParameterList());
- LSI->GLTemplateParameterList = TPL;
-
- // Transform the type of the original lambda's call operator.
- // The transformation MUST be done in the CurrentInstantiationScope since
- // it introduces a mapping of the original to the newly created
- // transformed parameters.
- TypeSourceInfo *NewCallOpTSI = nullptr;
- {
- TypeSourceInfo *OldCallOpTSI = E->getCallOperator()->getTypeSourceInfo();
- FunctionProtoTypeLoc OldCallOpFPTL =
- OldCallOpTSI->getTypeLoc().getAs<FunctionProtoTypeLoc>();
-
- TypeLocBuilder NewCallOpTLBuilder;
- SmallVector<QualType, 4> ExceptionStorage;
- TreeTransform *This = this; // Work around gcc.gnu.org/PR56135.
- QualType NewCallOpType = TransformFunctionProtoType(
- NewCallOpTLBuilder, OldCallOpFPTL, nullptr, Qualifiers(),
- [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
- return This->TransformExceptionSpec(OldCallOpFPTL.getBeginLoc(), ESI,
- ExceptionStorage, Changed);
- });
- if (NewCallOpType.isNull())
- return ExprError();
- NewCallOpTSI = NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context,
- NewCallOpType);
- }
-
// Create the local class that will describe the lambda.
// FIXME: DependencyKind below is wrong when substituting inside a templated
@@ -13284,49 +13375,24 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
DependencyKind = CXXRecordDecl::LDK_NeverDependent;
CXXRecordDecl *OldClass = E->getLambdaClass();
- CXXRecordDecl *Class =
- getSema().createLambdaClosureType(E->getIntroducerRange(), NewCallOpTSI,
- DependencyKind, E->getCaptureDefault());
-
+ CXXRecordDecl *Class = getSema().createLambdaClosureType(
+ E->getIntroducerRange(), /*Info=*/nullptr, DependencyKind,
+ E->getCaptureDefault());
getDerived().transformedLocalDecl(OldClass, {Class});
- std::optional<std::tuple<bool, unsigned, unsigned, Decl *>> Mangling;
- if (getDerived().ReplacingOriginal())
- Mangling = std::make_tuple(OldClass->hasKnownLambdaInternalLinkage(),
- OldClass->getLambdaManglingNumber(),
- OldClass->getDeviceLambdaManglingNumber(),
- OldClass->getLambdaContextDecl());
-
- // Build the call operator.
- CXXMethodDecl *NewCallOperator = getSema().startLambdaDefinition(
- Class, E->getIntroducerRange(), NewCallOpTSI,
- E->getCallOperator()->getEndLoc(),
- NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams(),
- E->getCallOperator()->getConstexprKind(),
- E->getCallOperator()->getStorageClass(),
- E->getCallOperator()->getTrailingRequiresClause());
-
- LSI->CallOperator = NewCallOperator;
-
- getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
- getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
+ CXXMethodDecl *NewCallOperator =
+ getSema().CreateLambdaCallOperator(E->getIntroducerRange(), Class);
+ NewCallOperator->setLexicalDeclContext(getSema().CurContext);
- // Number the lambda for linkage purposes if necessary.
- getSema().handleLambdaNumbering(Class, NewCallOperator, Mangling);
+ // Enter the scope of the lambda.
+ getSema().buildLambdaScope(LSI, NewCallOperator, E->getIntroducerRange(),
+ E->getCaptureDefault(), E->getCaptureDefaultLoc(),
+ E->hasExplicitParameters(), E->isMutable());
// Introduce the context of the call operator.
Sema::ContextRAII SavedContext(getSema(), NewCallOperator,
/*NewThisContext*/false);
- // Enter the scope of the lambda.
- getSema().buildLambdaScope(LSI, NewCallOperator,
- E->getIntroducerRange(),
- E->getCaptureDefault(),
- E->getCaptureDefaultLoc(),
- E->hasExplicitParameters(),
- E->hasExplicitResultType(),
- E->isMutable());
-
bool Invalid = false;
// Transform captures.
@@ -13366,7 +13432,8 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
}
VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(
OldVD->getLocation(), InitQualType, NewC.EllipsisLoc,
- OldVD->getIdentifier(), OldVD->getInitStyle(), Init.get());
+ OldVD->getIdentifier(), OldVD->getInitStyle(), Init.get(),
+ getSema().CurContext);
if (!NewVD) {
Invalid = true;
break;
@@ -13446,6 +13513,61 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
}
getSema().finishLambdaExplicitCaptures(LSI);
+ // Transform the template parameters, and add them to the current
+ // instantiation scope. The null case is handled correctly.
+ auto TPL = getDerived().TransformTemplateParameterList(
+ E->getTemplateParameterList());
+ LSI->GLTemplateParameterList = TPL;
+
+ // Transform the type of the original lambda's call operator.
+ // The transformation MUST be done in the CurrentInstantiationScope since
+ // it introduces a mapping of the original to the newly created
+ // transformed parameters.
+ TypeSourceInfo *NewCallOpTSI = nullptr;
+ {
+ TypeSourceInfo *OldCallOpTSI = E->getCallOperator()->getTypeSourceInfo();
+ auto OldCallOpFPTL =
+ OldCallOpTSI->getTypeLoc().getAs<FunctionProtoTypeLoc>();
+
+ TypeLocBuilder NewCallOpTLBuilder;
+ SmallVector<QualType, 4> ExceptionStorage;
+ TreeTransform *This = this; // Work around gcc.gnu.org/PR56135.
+ QualType NewCallOpType = TransformFunctionProtoType(
+ NewCallOpTLBuilder, OldCallOpFPTL, nullptr, Qualifiers(),
+ [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
+ return This->TransformExceptionSpec(OldCallOpFPTL.getBeginLoc(), ESI,
+ ExceptionStorage, Changed);
+ });
+ if (NewCallOpType.isNull())
+ return ExprError();
+ NewCallOpTSI =
+ NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context, NewCallOpType);
+ }
+
+ getSema().CompleteLambdaCallOperator(
+ NewCallOperator, E->getCallOperator()->getLocation(),
+ E->getCallOperator()->getInnerLocStart(),
+ E->getCallOperator()->getTrailingRequiresClause(), NewCallOpTSI,
+ E->getCallOperator()->getConstexprKind(),
+ E->getCallOperator()->getStorageClass(),
+ NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams(),
+ E->hasExplicitResultType());
+
+ getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
+ getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
+
+ {
+ // Number the lambda for linkage purposes if necessary.
+ Sema::ContextRAII ManglingContext(getSema(), Class->getDeclContext());
+
+ std::optional<CXXRecordDecl::LambdaNumbering> Numbering;
+ if (getDerived().ReplacingOriginal()) {
+ Numbering = OldClass->getLambdaNumbering();
+ }
+
+ getSema().handleLambdaNumbering(Class, NewCallOperator, Numbering);
+ }
+
// FIXME: Sema's lambda-building mechanism expects us to push an expression
// evaluation context even if we're not transforming the function body.
getSema().PushExpressionEvaluationContext(
@@ -14028,13 +14150,17 @@ TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) {
// We've got down to a single element; build a binary operator.
Expr *LHS = LeftFold ? Result.get() : Out.get();
Expr *RHS = LeftFold ? Out.get() : Result.get();
- if (Callee)
+ if (Callee) {
+ UnresolvedSet<16> Functions;
+ Functions.append(Callee->decls_begin(), Callee->decls_end());
Result = getDerived().RebuildCXXOperatorCallExpr(
BinaryOperator::getOverloadedOperator(E->getOperator()),
- E->getEllipsisLoc(), Callee, LHS, RHS);
- else
+ E->getEllipsisLoc(), Callee->getBeginLoc(), Callee->requiresADL(),
+ Functions, LHS, RHS);
+ } else {
Result = getDerived().RebuildBinaryOperator(E->getEllipsisLoc(),
E->getOperator(), LHS, RHS);
+ }
} else
Result = Out;
@@ -14076,9 +14202,8 @@ TreeTransform<Derived>::TransformCXXParenListInitExpr(CXXParenListInitExpr *E) {
TransformedInits))
return ExprError();
- return getDerived().RebuildCXXParenListInitExpr(
- TransformedInits, E->getType(), E->getUserSpecifiedInitExprs().size(),
- E->getInitLoc(), E->getBeginLoc(), E->getEndLoc());
+ return getDerived().RebuildParenListExpr(E->getBeginLoc(), TransformedInits,
+ E->getEndLoc());
}
template<typename Derived>
@@ -14600,7 +14725,12 @@ TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
oldCapture));
assert(blockScope->CaptureMap.count(newCapture));
}
- assert(oldBlock->capturesCXXThis() == blockScope->isCXXThisCaptured());
+
+ // The this pointer may not be captured by the instantiated block, even when
+ // it's captured by the original block, if the expression causing the
+ // capture is in the discarded branch of a constexpr if statement.
+ assert((!blockScope->isCXXThisCaptured() || oldBlock->capturesCXXThis()) &&
+ "this pointer isn't captured in the old block");
}
#endif
@@ -15034,14 +15164,11 @@ TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
return Template.get();
}
-template<typename Derived>
-ExprResult
-TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
- SourceLocation OpLoc,
- Expr *OrigCallee,
- Expr *First,
- Expr *Second) {
- Expr *Callee = OrigCallee->IgnoreParenCasts();
+template <typename Derived>
+ExprResult TreeTransform<Derived>::RebuildCXXOperatorCallExpr(
+ OverloadedOperatorKind Op, SourceLocation OpLoc, SourceLocation CalleeLoc,
+ bool RequiresADL, const UnresolvedSetImpl &Functions, Expr *First,
+ Expr *Second) {
bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
if (First->getObjectKind() == OK_ObjCProperty) {
@@ -15066,8 +15193,8 @@ TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
if (Op == OO_Subscript) {
if (!First->getType()->isOverloadableType() &&
!Second->getType()->isOverloadableType())
- return getSema().CreateBuiltinArraySubscriptExpr(
- First, Callee->getBeginLoc(), Second, OpLoc);
+ return getSema().CreateBuiltinArraySubscriptExpr(First, CalleeLoc, Second,
+ OpLoc);
} else if (Op == OO_Arrow) {
// It is possible that the type refers to a RecoveryExpr created earlier
// in the tree transformation.
@@ -15101,27 +15228,6 @@ TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
}
}
- // Compute the transformed set of functions (and function templates) to be
- // used during overload resolution.
- UnresolvedSet<16> Functions;
- bool RequiresADL;
-
- if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Callee)) {
- Functions.append(ULE->decls_begin(), ULE->decls_end());
- // If the overload could not be resolved in the template definition
- // (because we had a dependent argument), ADL is performed as part of
- // template instantiation.
- RequiresADL = ULE->requiresADL();
- } else {
- // If we've resolved this to a particular non-member function, just call
- // that function. If we resolved it to a member function,
- // CreateOverloaded* will find that function for us.
- NamedDecl *ND = cast<DeclRefExpr>(Callee)->getDecl();
- if (!isa<CXXMethodDecl>(ND))
- Functions.addDecl(ND);
- RequiresADL = false;
- }
-
// Add any functions found via argument-dependent lookup.
Expr *Args[2] = { First, Second };
unsigned NumArgs = 1 + (Second != nullptr);
@@ -15134,23 +15240,6 @@ TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
RequiresADL);
}
- if (Op == OO_Subscript) {
- SourceLocation LBrace;
- SourceLocation RBrace;
-
- if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee)) {
- DeclarationNameLoc NameLoc = DRE->getNameInfo().getInfo();
- LBrace = NameLoc.getCXXOperatorNameBeginLoc();
- RBrace = NameLoc.getCXXOperatorNameEndLoc();
- } else {
- LBrace = Callee->getBeginLoc();
- RBrace = OpLoc;
- }
-
- return SemaRef.CreateOverloadedArraySubscriptExpr(LBrace, RBrace,
- First, Second);
- }
-
// Create the overloaded operator invocation for binary operators.
BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
ExprResult Result = SemaRef.CreateOverloadedBinOp(