diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2020-07-26 19:36:28 +0000 | 
| commit | cfca06d7963fa0909f90483b42a6d7d194d01e08 (patch) | |
| tree | 209fb2a2d68f8f277793fc8df46c753d31bc853b /clang/lib/Sema/TreeTransform.h | |
| parent | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (diff) | |
Notes
Diffstat (limited to 'clang/lib/Sema/TreeTransform.h')
| -rw-r--r-- | clang/lib/Sema/TreeTransform.h | 1322 | 
1 files changed, 1119 insertions, 203 deletions
| diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 3b827fbc950b..ae0e9f1119b4 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -19,6 +19,7 @@  #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/ExprObjC.h"  #include "clang/AST/ExprOpenMP.h" @@ -27,6 +28,7 @@  #include "clang/AST/StmtCXX.h"  #include "clang/AST/StmtObjC.h"  #include "clang/AST/StmtOpenMP.h" +#include "clang/Basic/OpenMPKinds.h"  #include "clang/Sema/Designator.h"  #include "clang/Sema/Lookup.h"  #include "clang/Sema/Ownership.h" @@ -156,6 +158,13 @@ public:    /// existing lambdas.    bool ReplacingOriginal() { return false; } +  /// Wether CXXConstructExpr can be skipped when they are implicit. +  /// They will be reconstructed when used if needed. +  /// This is usefull when the user that cause rebuilding of the +  /// CXXConstructExpr is outside of the expression at which the TreeTransform +  /// started. +  bool AllowSkippingCXXConstructExpr() { return true; } +    /// Returns the location of the entity being transformed, if that    /// information was not available elsewhere in the AST.    /// @@ -211,6 +220,14 @@ public:      return T.isNull();    } +  /// Transform a template parameter depth level. +  /// +  /// During a transformation that transforms template parameters, this maps +  /// an old template parameter depth to a new depth. +  unsigned TransformTemplateDepth(unsigned Depth) { +    return Depth; +  } +    /// Determine whether the given call argument should be dropped, e.g.,    /// because it is a default argument.    /// @@ -509,6 +526,15 @@ public:    DeclarationNameInfo    TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo); +  bool TransformRequiresExprRequirements(ArrayRef<concepts::Requirement *> Reqs, +      llvm::SmallVectorImpl<concepts::Requirement *> &Transformed); +  concepts::TypeRequirement * +  TransformTypeRequirement(concepts::TypeRequirement *Req); +  concepts::ExprRequirement * +  TransformExprRequirement(concepts::ExprRequirement *Req); +  concepts::NestedRequirement * +  TransformNestedRequirement(concepts::NestedRequirement *Req); +    /// Transform the given template name.    ///    /// \param SS The nested-name-specifier that qualifies the template @@ -704,10 +730,10 @@ public:  #define ABSTRACT_STMT(Stmt)  #include "clang/AST/StmtNodes.inc" -#define OPENMP_CLAUSE(Name, Class)                        \ +#define OMP_CLAUSE_CLASS(Enum, Str, Class)                                           \    LLVM_ATTRIBUTE_NOINLINE \    OMPClause *Transform ## Class(Class *S); -#include "clang/Basic/OpenMPKinds.def" +#include "llvm/Frontend/OpenMP/OMPKinds.def"    /// Build a new qualified type given its unqualified type and type location.    /// @@ -868,6 +894,16 @@ public:                                                Expr *SizeExpr,                                                SourceLocation AttributeLoc); +  /// Build a new matrix type given the element type and dimensions. +  QualType RebuildConstantMatrixType(QualType ElementType, unsigned NumRows, +                                     unsigned NumColumns); + +  /// Build a new matrix type given the type and dependently-defined +  /// dimensions. +  QualType RebuildDependentSizedMatrixType(QualType ElementType, Expr *RowExpr, +                                           Expr *ColumnExpr, +                                           SourceLocation AttributeLoc); +    /// Build a new DependentAddressSpaceType or return the pointee    /// type variable with the correct address space (retrieved from    /// AddrSpaceExpr) applied to it. The former will be returned in cases @@ -941,12 +977,16 @@ public:    /// Build a new C++11 auto type.    ///    /// By default, builds a new AutoType with the given deduced type. -  QualType RebuildAutoType(QualType Deduced, AutoTypeKeyword Keyword) { +  QualType RebuildAutoType(QualType Deduced, AutoTypeKeyword Keyword, +                           ConceptDecl *TypeConstraintConcept, +                           ArrayRef<TemplateArgument> TypeConstraintArgs) {      // Note, IsDependent is always false here: we implicitly convert an 'auto'      // which has been deduced to a dependent type into an undeduced 'auto', so      // that we'll retry deduction after the transformation.      return SemaRef.Context.getAutoType(Deduced, Keyword, -                                       /*IsDependent*/ false); +                                       /*IsDependent*/ false, /*IsPack=*/false, +                                       TypeConstraintConcept, +                                       TypeConstraintArgs);    }    /// By default, builds a new DeducedTemplateSpecializationType with the given @@ -1056,23 +1096,8 @@ public:      }      if (Keyword == ETK_None || Keyword == ETK_Typename) { -      QualType T = SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc, -                                             *Id, IdLoc); -      // If a dependent name resolves to a deduced template specialization type, -      // check that we're in one of the syntactic contexts permitting it. -      if (!DeducedTSTContext) { -        if (auto *Deduced = dyn_cast_or_null<DeducedTemplateSpecializationType>( -                T.isNull() ? nullptr : T->getContainedDeducedType())) { -          SemaRef.Diag(IdLoc, diag::err_dependent_deduced_tst) -            << (int)SemaRef.getTemplateNameKindForDiagnostics( -                   Deduced->getTemplateName()) -            << QualType(QualifierLoc.getNestedNameSpecifier()->getAsType(), 0); -          if (auto *TD = Deduced->getTemplateName().getAsTemplateDecl()) -            SemaRef.Diag(TD->getLocation(), diag::note_template_decl_here); -          return QualType(); -        } -      } -      return T; +      return SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc, +                                       *Id, IdLoc, DeducedTSTContext);      }      TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword); @@ -1168,6 +1193,14 @@ public:    QualType RebuildPipeType(QualType ValueType, SourceLocation KWLoc,                             bool isReadPipe); +   /// Build an extended int given its value type. +  QualType RebuildExtIntType(bool IsUnsigned, unsigned NumBits, +                             SourceLocation Loc); + +  /// Build a dependent extended int given its value type. +  QualType RebuildDependentExtIntType(bool IsUnsigned, Expr *NumBitsExpr, +                                      SourceLocation Loc); +    /// Build a new template name given a nested name specifier, a flag    /// indicating whether the "template" keyword was provided, and the template    /// that the template name refers to. @@ -1314,9 +1347,10 @@ public:    ///    /// By default, performs semantic analysis to build the new statement.    /// Subclasses may override this routine to provide different behavior. -  StmtResult RebuildWhileStmt(SourceLocation WhileLoc, -                              Sema::ConditionResult Cond, Stmt *Body) { -    return getSema().ActOnWhileStmt(WhileLoc, Cond, Body); +  StmtResult RebuildWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc, +                              Sema::ConditionResult Cond, +                              SourceLocation RParenLoc, Stmt *Body) { +    return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body);    }    /// Build a new do-while statement. @@ -1603,8 +1637,7 @@ public:    ///    /// By default, performs semantic analysis to build the new OpenMP clause.    /// Subclasses may override this routine to provide different behavior. -  OMPClause *RebuildOMPDefaultClause(OpenMPDefaultClauseKind Kind, -                                     SourceLocation KindKwLoc, +  OMPClause *RebuildOMPDefaultClause(DefaultKind Kind, SourceLocation KindKwLoc,                                       SourceLocation StartLoc,                                       SourceLocation LParenLoc,                                       SourceLocation EndLoc) { @@ -1704,17 +1737,16 @@ public:    ///    /// By default, performs semantic analysis to build the new statement.    /// Subclasses may override this routine to provide different behavior. -  OMPClause *RebuildOMPReductionClause(ArrayRef<Expr *> VarList, -                                       SourceLocation StartLoc, -                                       SourceLocation LParenLoc, -                                       SourceLocation ColonLoc, -                                       SourceLocation EndLoc, -                                       CXXScopeSpec &ReductionIdScopeSpec, -                                       const DeclarationNameInfo &ReductionId, -                                       ArrayRef<Expr *> UnresolvedReductions) { +  OMPClause *RebuildOMPReductionClause( +      ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier, +      SourceLocation StartLoc, SourceLocation LParenLoc, +      SourceLocation ModifierLoc, SourceLocation ColonLoc, +      SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, +      const DeclarationNameInfo &ReductionId, +      ArrayRef<Expr *> UnresolvedReductions) {      return getSema().ActOnOpenMPReductionClause( -        VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec, -        ReductionId, UnresolvedReductions); +        VarList, Modifier, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, +        ReductionIdScopeSpec, ReductionId, UnresolvedReductions);    }    /// Build a new OpenMP 'task_reduction' clause. @@ -1813,28 +1845,42 @@ public:                                              EndLoc);    } +  /// Build a new OpenMP 'depobj' pseudo clause. +  /// +  /// By default, performs semantic analysis to build the new OpenMP clause. +  /// Subclasses may override this routine to provide different behavior. +  OMPClause *RebuildOMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, +                                    SourceLocation LParenLoc, +                                    SourceLocation EndLoc) { +    return getSema().ActOnOpenMPDepobjClause(Depobj, StartLoc, LParenLoc, +                                             EndLoc); +  } +    /// Build a new OpenMP 'depend' pseudo clause.    ///    /// By default, performs semantic analysis to build the new OpenMP clause.    /// Subclasses may override this routine to provide different behavior.    OMPClause * -  RebuildOMPDependClause(OpenMPDependClauseKind DepKind, SourceLocation DepLoc, -                         SourceLocation ColonLoc, ArrayRef<Expr *> VarList, -                         SourceLocation StartLoc, SourceLocation LParenLoc, -                         SourceLocation EndLoc) { -    return getSema().ActOnOpenMPDependClause(DepKind, DepLoc, ColonLoc, VarList, -                                             StartLoc, LParenLoc, EndLoc); +  RebuildOMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, +                         SourceLocation DepLoc, SourceLocation ColonLoc, +                         ArrayRef<Expr *> VarList, SourceLocation StartLoc, +                         SourceLocation LParenLoc, SourceLocation EndLoc) { +    return getSema().ActOnOpenMPDependClause(DepModifier, DepKind, DepLoc, +                                             ColonLoc, VarList, StartLoc, +                                             LParenLoc, EndLoc);    }    /// Build a new OpenMP 'device' clause.    ///    /// By default, performs semantic analysis to build the new statement.    /// Subclasses may override this routine to provide different behavior. -  OMPClause *RebuildOMPDeviceClause(Expr *Device, SourceLocation StartLoc, +  OMPClause *RebuildOMPDeviceClause(OpenMPDeviceClauseModifier Modifier, +                                    Expr *Device, SourceLocation StartLoc,                                      SourceLocation LParenLoc, +                                    SourceLocation ModifierLoc,                                      SourceLocation EndLoc) { -    return getSema().ActOnOpenMPDeviceClause(Device, StartLoc, LParenLoc, -                                             EndLoc); +    return getSema().ActOnOpenMPDeviceClause(Modifier, Device, StartLoc, +                                             LParenLoc, ModifierLoc, EndLoc);    }    /// Build a new OpenMP 'map' clause. @@ -1933,6 +1979,16 @@ public:      return getSema().ActOnOpenMPHintClause(Hint, StartLoc, LParenLoc, EndLoc);    } +  /// Build a new OpenMP 'detach' clause. +  /// +  /// By default, performs semantic analysis to build the new statement. +  /// Subclasses may override this routine to provide different behavior. +  OMPClause *RebuildOMPDetachClause(Expr *Evt, SourceLocation StartLoc, +                                    SourceLocation LParenLoc, +                                    SourceLocation EndLoc) { +    return getSema().ActOnOpenMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc); +  } +    /// Build a new OpenMP 'dist_schedule' clause.    ///    /// By default, performs semantic analysis to build the new OpenMP clause. @@ -1981,6 +2037,15 @@ public:      return getSema().ActOnOpenMPUseDevicePtrClause(VarList, Locs);    } +  /// Build a new OpenMP 'use_device_addr' clause. +  /// +  /// By default, performs semantic analysis to build the new OpenMP clause. +  /// Subclasses may override this routine to provide different behavior. +  OMPClause *RebuildOMPUseDeviceAddrClause(ArrayRef<Expr *> VarList, +                                           const OMPVarListLocTy &Locs) { +    return getSema().ActOnOpenMPUseDeviceAddrClause(VarList, Locs); +  } +    /// Build a new OpenMP 'is_device_ptr' clause.    ///    /// By default, performs semantic analysis to build the new OpenMP clause. @@ -2017,6 +2082,67 @@ public:                                                    EndLoc);    } +  /// Build a new OpenMP 'inclusive' clause. +  /// +  /// By default, performs semantic analysis to build the new OpenMP clause. +  /// Subclasses may override this routine to provide different behavior. +  OMPClause *RebuildOMPInclusiveClause(ArrayRef<Expr *> VarList, +                                       SourceLocation StartLoc, +                                       SourceLocation LParenLoc, +                                       SourceLocation EndLoc) { +    return getSema().ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, +                                                EndLoc); +  } + +  /// Build a new OpenMP 'exclusive' clause. +  /// +  /// By default, performs semantic analysis to build the new OpenMP clause. +  /// Subclasses may override this routine to provide different behavior. +  OMPClause *RebuildOMPExclusiveClause(ArrayRef<Expr *> VarList, +                                       SourceLocation StartLoc, +                                       SourceLocation LParenLoc, +                                       SourceLocation EndLoc) { +    return getSema().ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, +                                                EndLoc); +  } + +  /// Build a new OpenMP 'uses_allocators' clause. +  /// +  /// By default, performs semantic analysis to build the new OpenMP clause. +  /// Subclasses may override this routine to provide different behavior. +  OMPClause *RebuildOMPUsesAllocatorsClause( +      ArrayRef<Sema::UsesAllocatorsData> Data, SourceLocation StartLoc, +      SourceLocation LParenLoc, SourceLocation EndLoc) { +    return getSema().ActOnOpenMPUsesAllocatorClause(StartLoc, LParenLoc, EndLoc, +                                                    Data); +  } + +  /// Build a new OpenMP 'affinity' clause. +  /// +  /// By default, performs semantic analysis to build the new OpenMP clause. +  /// Subclasses may override this routine to provide different behavior. +  OMPClause *RebuildOMPAffinityClause(SourceLocation StartLoc, +                                      SourceLocation LParenLoc, +                                      SourceLocation ColonLoc, +                                      SourceLocation EndLoc, Expr *Modifier, +                                      ArrayRef<Expr *> Locators) { +    return getSema().ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, +                                               EndLoc, Modifier, Locators); +  } + +  /// Build a new OpenMP 'order' clause. +  /// +  /// By default, performs semantic analysis to build the new OpenMP clause. +  /// Subclasses may override this routine to provide different behavior. +  OMPClause *RebuildOMPOrderClause(OpenMPOrderClauseKind Kind, +                                   SourceLocation KindKwLoc, +                                   SourceLocation StartLoc, +                                   SourceLocation LParenLoc, +                                   SourceLocation EndLoc) { +    return getSema().ActOnOpenMPOrderClause(Kind, KindKwLoc, StartLoc, +                                            LParenLoc, EndLoc); +  } +    /// Rebuild the operand to an Objective-C \@synchronized statement.    ///    /// By default, performs semantic analysis to build the new statement. @@ -2294,16 +2420,53 @@ public:                                               RBracketLoc);    } +  /// Build a new matrix subscript expression. +  /// +  /// By default, performs semantic analysis to build the new expression. +  /// Subclasses may override this routine to provide different behavior. +  ExprResult RebuildMatrixSubscriptExpr(Expr *Base, Expr *RowIdx, +                                        Expr *ColumnIdx, +                                        SourceLocation RBracketLoc) { +    return getSema().CreateBuiltinMatrixSubscriptExpr(Base, RowIdx, ColumnIdx, +                                                      RBracketLoc); +  } +    /// Build a new array section expression.    ///    /// By default, performs semantic analysis to build the new expression.    /// Subclasses may override this routine to provide different behavior.    ExprResult RebuildOMPArraySectionExpr(Expr *Base, SourceLocation LBracketLoc,                                          Expr *LowerBound, -                                        SourceLocation ColonLoc, Expr *Length, +                                        SourceLocation ColonLocFirst, +                                        SourceLocation ColonLocSecond, +                                        Expr *Length, Expr *Stride,                                          SourceLocation RBracketLoc) {      return getSema().ActOnOMPArraySectionExpr(Base, LBracketLoc, LowerBound, -                                              ColonLoc, Length, RBracketLoc); +                                              ColonLocFirst, ColonLocSecond, +                                              Length, Stride, RBracketLoc); +  } + +  /// Build a new array shaping expression. +  /// +  /// By default, performs semantic analysis to build the new expression. +  /// Subclasses may override this routine to provide different behavior. +  ExprResult RebuildOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc, +                                        SourceLocation RParenLoc, +                                        ArrayRef<Expr *> Dims, +                                        ArrayRef<SourceRange> BracketsRanges) { +    return getSema().ActOnOMPArrayShapingExpr(Base, LParenLoc, RParenLoc, Dims, +                                              BracketsRanges); +  } + +  /// Build a new iterator expression. +  /// +  /// By default, performs semantic analysis to build the new expression. +  /// Subclasses may override this routine to provide different behavior. +  ExprResult RebuildOMPIteratorExpr( +      SourceLocation IteratorKwLoc, SourceLocation LLoc, SourceLocation RLoc, +      ArrayRef<Sema::OMPIteratorData> Data) { +    return getSema().ActOnOMPIteratorExpr(/*Scope=*/nullptr, IteratorKwLoc, +                                          LLoc, RLoc, Data);    }    /// Build a new call expression. @@ -2314,8 +2477,8 @@ public:                                     MultiExprArg Args,                                     SourceLocation RParenLoc,                                     Expr *ExecConfig = nullptr) { -    return getSema().BuildCallExpr(/*Scope=*/nullptr, Callee, LParenLoc, Args, -                                   RParenLoc, ExecConfig); +    return getSema().ActOnCallExpr( +        /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc, ExecConfig);    }    /// Build a new member access expression. @@ -2527,10 +2690,10 @@ public:    ///    /// By default, performs semantic analysis to build the new expression.    /// Subclasses may override this routine to provide different behavior. -  ExprResult RebuildStmtExpr(SourceLocation LParenLoc, -                                   Stmt *SubStmt, -                                   SourceLocation RParenLoc) { -    return getSema().ActOnStmtExpr(LParenLoc, SubStmt, RParenLoc); +  ExprResult RebuildStmtExpr(SourceLocation LParenLoc, Stmt *SubStmt, +                             SourceLocation RParenLoc, unsigned TemplateDepth) { +    return getSema().BuildStmtExpr(LParenLoc, SubStmt, RParenLoc, +                                   TemplateDepth);    }    /// Build a new __builtin_choose_expr expression. @@ -2609,6 +2772,10 @@ public:                                                     RAngleLoc, LParenLoc,                                                     SubExpr, RParenLoc); +    case Stmt::CXXAddrspaceCastExprClass: +      return getDerived().RebuildCXXAddrspaceCastExpr( +          OpLoc, LAngleLoc, TInfo, RAngleLoc, LParenLoc, SubExpr, RParenLoc); +      default:        llvm_unreachable("Invalid C++ named cast");      } @@ -2682,6 +2849,16 @@ public:                                         SourceRange(LParenLoc, RParenLoc));    } +  ExprResult +  RebuildCXXAddrspaceCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc, +                              TypeSourceInfo *TInfo, SourceLocation RAngleLoc, +                              SourceLocation LParenLoc, Expr *SubExpr, +                              SourceLocation RParenLoc) { +    return getSema().BuildCXXNamedCast( +        OpLoc, tok::kw_addrspace_cast, TInfo, SubExpr, +        SourceRange(LAngleLoc, RAngleLoc), SourceRange(LParenLoc, RParenLoc)); +  } +    /// Build a new C++ functional-style cast expression.    ///    /// By default, performs semantic analysis to build the new expression. @@ -2735,24 +2912,19 @@ public:    ///    /// By default, performs semantic analysis to build the new expression.    /// Subclasses may override this routine to provide different behavior. -  ExprResult RebuildCXXUuidofExpr(QualType TypeInfoType, -                                        SourceLocation TypeidLoc, -                                        TypeSourceInfo *Operand, -                                        SourceLocation RParenLoc) { -    return getSema().BuildCXXUuidof(TypeInfoType, TypeidLoc, Operand, -                                    RParenLoc); +  ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc, +                                  TypeSourceInfo *Operand, +                                  SourceLocation RParenLoc) { +    return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);    }    /// Build a new C++ __uuidof(expr) expression.    ///    /// By default, performs semantic analysis to build the new expression.    /// Subclasses may override this routine to provide different behavior. -  ExprResult RebuildCXXUuidofExpr(QualType TypeInfoType, -                                        SourceLocation TypeidLoc, -                                        Expr *Operand, -                                        SourceLocation RParenLoc) { -    return getSema().BuildCXXUuidof(TypeInfoType, TypeidLoc, Operand, -                                    RParenLoc); +  ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc, +                                  Expr *Operand, SourceLocation RParenLoc) { +    return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);    }    /// Build a new C++ "this" expression. @@ -2931,9 +3103,14 @@ public:                                       bool RequiresZeroInit,                               CXXConstructExpr::ConstructionKind ConstructKind,                                       SourceRange ParenRange) { +    // Reconstruct the constructor we originally found, which might be +    // different if this is a call to an inherited constructor. +    CXXConstructorDecl *FoundCtor = Constructor; +    if (Constructor->isInheritingConstructor()) +      FoundCtor = Constructor->getInheritedConstructor().getConstructor(); +      SmallVector<Expr*, 8> ConvertedArgs; -    if (getSema().CompleteConstructorCall(Constructor, Args, Loc, -                                          ConvertedArgs)) +    if (getSema().CompleteConstructorCall(FoundCtor, Args, Loc, ConvertedArgs))        return ExprError();      return getSema().BuildCXXConstructExpr(Loc, T, Constructor, @@ -3078,7 +3255,56 @@ public:      return Result;    } -    /// \brief Build a new Objective-C boxed expression. +  /// \brief Build a new requires expression. +  /// +  /// By default, performs semantic analysis to build the new expression. +  /// Subclasses may override this routine to provide different behavior. +  ExprResult RebuildRequiresExpr(SourceLocation RequiresKWLoc, +                                 RequiresExprBodyDecl *Body, +                                 ArrayRef<ParmVarDecl *> LocalParameters, +                                 ArrayRef<concepts::Requirement *> Requirements, +                                 SourceLocation ClosingBraceLoc) { +    return RequiresExpr::Create(SemaRef.Context, RequiresKWLoc, Body, +                                LocalParameters, Requirements, ClosingBraceLoc); +  } + +  concepts::TypeRequirement * +  RebuildTypeRequirement( +      concepts::Requirement::SubstitutionDiagnostic *SubstDiag) { +    return SemaRef.BuildTypeRequirement(SubstDiag); +  } + +  concepts::TypeRequirement *RebuildTypeRequirement(TypeSourceInfo *T) { +    return SemaRef.BuildTypeRequirement(T); +  } + +  concepts::ExprRequirement * +  RebuildExprRequirement( +      concepts::Requirement::SubstitutionDiagnostic *SubstDiag, bool IsSimple, +      SourceLocation NoexceptLoc, +      concepts::ExprRequirement::ReturnTypeRequirement Ret) { +    return SemaRef.BuildExprRequirement(SubstDiag, IsSimple, NoexceptLoc, +                                        std::move(Ret)); +  } + +  concepts::ExprRequirement * +  RebuildExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc, +                         concepts::ExprRequirement::ReturnTypeRequirement Ret) { +    return SemaRef.BuildExprRequirement(E, IsSimple, NoexceptLoc, +                                        std::move(Ret)); +  } + +  concepts::NestedRequirement * +  RebuildNestedRequirement( +      concepts::Requirement::SubstitutionDiagnostic *SubstDiag) { +    return SemaRef.BuildNestedRequirement(SubstDiag); +  } + +  concepts::NestedRequirement *RebuildNestedRequirement(Expr *Constraint) { +    return SemaRef.BuildNestedRequirement(Constraint); +  } + +  /// \brief Build a new Objective-C boxed expression.    ///    /// By default, performs semantic analysis to build the new expression.    /// Subclasses may override this routine to provide different behavior. @@ -3382,6 +3608,11 @@ public:                                       Sema::AtomicArgumentOrder::AST);    } +  ExprResult RebuildRecoveryExpr(SourceLocation BeginLoc, SourceLocation EndLoc, +                                 ArrayRef<Expr *> SubExprs) { +    return getSema().CreateRecoveryExpr(BeginLoc, EndLoc, SubExprs); +  } +  private:    TypeLoc TransformTypeInObjectScope(TypeLoc TL,                                       QualType ObjectType, @@ -3446,10 +3677,10 @@ OMPClause *TreeTransform<Derived>::TransformOMPClause(OMPClause *S) {    switch (S->getClauseKind()) {    default: break;    // Transform individual clause nodes -#define OPENMP_CLAUSE(Name, Class)                                             \ -  case OMPC_ ## Name :                                                         \ +#define OMP_CLAUSE_CLASS(Enum, Str, Class) \ +  case Enum:                                                                   \      return getDerived().Transform ## Class(cast<Class>(S)); -#include "clang/Basic/OpenMPKinds.def" +#include "llvm/Frontend/OpenMP/OMPKinds.def"    }    return S; @@ -3966,50 +4197,8 @@ template<typename Derived>  void TreeTransform<Derived>::InventTemplateArgumentLoc(                                           const TemplateArgument &Arg,                                           TemplateArgumentLoc &Output) { -  SourceLocation Loc = getDerived().getBaseLocation(); -  switch (Arg.getKind()) { -  case TemplateArgument::Null: -    llvm_unreachable("null template argument in TreeTransform"); -    break; - -  case TemplateArgument::Type: -    Output = TemplateArgumentLoc(Arg, -               SemaRef.Context.getTrivialTypeSourceInfo(Arg.getAsType(), Loc)); - -    break; - -  case TemplateArgument::Template: -  case TemplateArgument::TemplateExpansion: { -    NestedNameSpecifierLocBuilder Builder; -    TemplateName Template = Arg.getAsTemplateOrTemplatePattern(); -    if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) -      Builder.MakeTrivial(SemaRef.Context, DTN->getQualifier(), Loc); -    else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName()) -      Builder.MakeTrivial(SemaRef.Context, QTN->getQualifier(), Loc); - -    if (Arg.getKind() == TemplateArgument::Template) -      Output = TemplateArgumentLoc(Arg, -                                   Builder.getWithLocInContext(SemaRef.Context), -                                   Loc); -    else -      Output = TemplateArgumentLoc(Arg, -                                   Builder.getWithLocInContext(SemaRef.Context), -                                   Loc, Loc); - -    break; -  } - -  case TemplateArgument::Expression: -    Output = TemplateArgumentLoc(Arg, Arg.getAsExpr()); -    break; - -  case TemplateArgument::Declaration: -  case TemplateArgument::Integral: -  case TemplateArgument::Pack: -  case TemplateArgument::NullPtr: -    Output = TemplateArgumentLoc(Arg, TemplateArgumentLocInfo()); -    break; -  } +  Output = getSema().getTrivialTemplateArgumentLoc( +      Arg, QualType(), getDerived().getBaseLocation());  }  template<typename Derived> @@ -4019,12 +4208,45 @@ bool TreeTransform<Derived>::TransformTemplateArgument(    const TemplateArgument &Arg = Input.getArgument();    switch (Arg.getKind()) {    case TemplateArgument::Null: -  case TemplateArgument::Integral:    case TemplateArgument::Pack: -  case TemplateArgument::Declaration: -  case TemplateArgument::NullPtr:      llvm_unreachable("Unexpected TemplateArgument"); +  case TemplateArgument::Integral: +  case TemplateArgument::NullPtr: +  case TemplateArgument::Declaration: { +    // Transform a resolved template argument straight to a resolved template +    // argument. We get here when substituting into an already-substituted +    // template type argument during concept satisfaction checking. +    QualType T = Arg.getNonTypeTemplateArgumentType(); +    QualType NewT = getDerived().TransformType(T); +    if (NewT.isNull()) +      return true; + +    ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration +                       ? Arg.getAsDecl() +                       : nullptr; +    ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl( +                              getDerived().getBaseLocation(), D)) +                        : nullptr; +    if (D && !NewD) +      return true; + +    if (NewT == T && D == NewD) +      Output = Input; +    else if (Arg.getKind() == TemplateArgument::Integral) +      Output = TemplateArgumentLoc( +          TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT), +          TemplateArgumentLocInfo()); +    else if (Arg.getKind() == TemplateArgument::NullPtr) +      Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true), +                                   TemplateArgumentLocInfo()); +    else +      Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT), +                                   TemplateArgumentLocInfo()); + +    return false; +  } +    case TemplateArgument::Type: {      TypeSourceInfo *DI = Input.getTypeSourceInfo();      if (!DI) @@ -4456,7 +4678,10 @@ QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T,          Deduced =              SemaRef.Context.getQualifiedType(Deduced.getUnqualifiedType(), Qs);          T = SemaRef.Context.getAutoType(Deduced, AutoTy->getKeyword(), -                                        AutoTy->isDependentType()); +                                        AutoTy->isDependentType(), +                                        /*isPack=*/false, +                                        AutoTy->getTypeConstraintConcept(), +                                        AutoTy->getTypeConstraintArguments());        } else {          // Otherwise, complain about the addition of a qualifier to an          // already-qualified type. @@ -5016,6 +5241,86 @@ QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(  }  template <typename Derived> +QualType +TreeTransform<Derived>::TransformConstantMatrixType(TypeLocBuilder &TLB, +                                                    ConstantMatrixTypeLoc TL) { +  const ConstantMatrixType *T = TL.getTypePtr(); +  QualType ElementType = getDerived().TransformType(T->getElementType()); +  if (ElementType.isNull()) +    return QualType(); + +  QualType Result = TL.getType(); +  if (getDerived().AlwaysRebuild() || ElementType != T->getElementType()) { +    Result = getDerived().RebuildConstantMatrixType( +        ElementType, T->getNumRows(), T->getNumColumns()); +    if (Result.isNull()) +      return QualType(); +  } + +  ConstantMatrixTypeLoc NewTL = TLB.push<ConstantMatrixTypeLoc>(Result); +  NewTL.setAttrNameLoc(TL.getAttrNameLoc()); +  NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange()); +  NewTL.setAttrRowOperand(TL.getAttrRowOperand()); +  NewTL.setAttrColumnOperand(TL.getAttrColumnOperand()); + +  return Result; +} + +template <typename Derived> +QualType TreeTransform<Derived>::TransformDependentSizedMatrixType( +    TypeLocBuilder &TLB, DependentSizedMatrixTypeLoc TL) { +  const DependentSizedMatrixType *T = TL.getTypePtr(); + +  QualType ElementType = getDerived().TransformType(T->getElementType()); +  if (ElementType.isNull()) { +    return QualType(); +  } + +  // Matrix dimensions are constant expressions. +  EnterExpressionEvaluationContext Unevaluated( +      SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated); + +  Expr *origRows = TL.getAttrRowOperand(); +  if (!origRows) +    origRows = T->getRowExpr(); +  Expr *origColumns = TL.getAttrColumnOperand(); +  if (!origColumns) +    origColumns = T->getColumnExpr(); + +  ExprResult rowResult = getDerived().TransformExpr(origRows); +  rowResult = SemaRef.ActOnConstantExpression(rowResult); +  if (rowResult.isInvalid()) +    return QualType(); + +  ExprResult columnResult = getDerived().TransformExpr(origColumns); +  columnResult = SemaRef.ActOnConstantExpression(columnResult); +  if (columnResult.isInvalid()) +    return QualType(); + +  Expr *rows = rowResult.get(); +  Expr *columns = columnResult.get(); + +  QualType Result = TL.getType(); +  if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() || +      rows != origRows || columns != origColumns) { +    Result = getDerived().RebuildDependentSizedMatrixType( +        ElementType, rows, columns, T->getAttributeLoc()); + +    if (Result.isNull()) +      return QualType(); +  } + +  // We might have any sort of matrix type now, but fortunately they +  // all have the same location layout. +  MatrixTypeLoc NewTL = TLB.push<MatrixTypeLoc>(Result); +  NewTL.setAttrNameLoc(TL.getAttrNameLoc()); +  NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange()); +  NewTL.setAttrRowOperand(rows); +  NewTL.setAttrColumnOperand(columns); +  return Result; +} + +template <typename Derived>  QualType TreeTransform<Derived>::TransformDependentAddressSpaceType(      TypeLocBuilder &TLB, DependentAddressSpaceTypeLoc TL) {    const DependentAddressSpaceType *T = TL.getTypePtr(); @@ -5189,21 +5494,29 @@ bool TreeTransform<Derived>::TransformFunctionTypeParams(          PackExpansionTypeLoc ExpansionTL = TL.castAs<PackExpansionTypeLoc>();          TypeLoc Pattern = ExpansionTL.getPatternLoc();          SemaRef.collectUnexpandedParameterPacks(Pattern, Unexpanded); -        assert(Unexpanded.size() > 0 && "Could not find parameter packs!");          // Determine whether we should expand the parameter packs.          bool ShouldExpand = false;          bool RetainExpansion = false; -        Optional<unsigned> OrigNumExpansions = -            ExpansionTL.getTypePtr()->getNumExpansions(); -        NumExpansions = OrigNumExpansions; -        if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(), -                                                 Pattern.getSourceRange(), -                                                 Unexpanded, -                                                 ShouldExpand, -                                                 RetainExpansion, -                                                 NumExpansions)) { -          return true; +        Optional<unsigned> OrigNumExpansions; +        if (Unexpanded.size() > 0) { +          OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions(); +          NumExpansions = OrigNumExpansions; +          if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(), +                                                   Pattern.getSourceRange(), +                                                   Unexpanded, +                                                   ShouldExpand, +                                                   RetainExpansion, +                                                   NumExpansions)) { +            return true; +          } +        } else { +#ifndef NDEBUG +          const AutoType *AT = +              Pattern.getType().getTypePtr()->getContainedAutoType(); +          assert((AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) && +                 "Could not find parameter packs or undeduced auto type!"); +#endif          }          if (ShouldExpand) { @@ -5263,6 +5576,9 @@ bool TreeTransform<Derived>::TransformFunctionTypeParams(                                                            indexAdjustment,                                                            NumExpansions,                                                    /*ExpectParameterPack=*/true); +        assert(NewParm->isParameterPack() && +               "Parameter pack no longer a parameter pack after " +               "transformation.");        } else {          NewParm = getDerived().TransformFunctionTypeParam(              OldParm, indexAdjustment, None, /*ExpectParameterPack=*/ false); @@ -5768,32 +6084,6 @@ QualType TreeTransform<Derived>::TransformUnaryTransformType(  }  template<typename Derived> -QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB, -                                                   AutoTypeLoc TL) { -  const AutoType *T = TL.getTypePtr(); -  QualType OldDeduced = T->getDeducedType(); -  QualType NewDeduced; -  if (!OldDeduced.isNull()) { -    NewDeduced = getDerived().TransformType(OldDeduced); -    if (NewDeduced.isNull()) -      return QualType(); -  } - -  QualType Result = TL.getType(); -  if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced || -      T->isDependentType()) { -    Result = getDerived().RebuildAutoType(NewDeduced, T->getKeyword()); -    if (Result.isNull()) -      return QualType(); -  } - -  AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(Result); -  NewTL.setNameLoc(TL.getNameLoc()); - -  return Result; -} - -template<typename Derived>  QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(      TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {    const DeducedTemplateSpecializationType *T = TL.getTypePtr(); @@ -5990,6 +6280,57 @@ QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,    return Result;  } +template <typename Derived> +QualType TreeTransform<Derived>::TransformExtIntType(TypeLocBuilder &TLB, +                                                     ExtIntTypeLoc TL) { +  const ExtIntType *EIT = TL.getTypePtr(); +  QualType Result = TL.getType(); + +  if (getDerived().AlwaysRebuild()) { +    Result = getDerived().RebuildExtIntType(EIT->isUnsigned(), +                                            EIT->getNumBits(), TL.getNameLoc()); +    if (Result.isNull()) +      return QualType(); +  } + +  ExtIntTypeLoc NewTL = TLB.push<ExtIntTypeLoc>(Result); +  NewTL.setNameLoc(TL.getNameLoc()); +  return Result; +} + +template <typename Derived> +QualType TreeTransform<Derived>::TransformDependentExtIntType( +    TypeLocBuilder &TLB, DependentExtIntTypeLoc TL) { +  const DependentExtIntType *EIT = TL.getTypePtr(); + +  EnterExpressionEvaluationContext Unevaluated( +      SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated); +  ExprResult BitsExpr = getDerived().TransformExpr(EIT->getNumBitsExpr()); +  BitsExpr = SemaRef.ActOnConstantExpression(BitsExpr); + +  if (BitsExpr.isInvalid()) +    return QualType(); + +  QualType Result = TL.getType(); + +  if (getDerived().AlwaysRebuild() || BitsExpr.get() != EIT->getNumBitsExpr()) { +    Result = getDerived().RebuildDependentExtIntType( +        EIT->isUnsigned(), BitsExpr.get(), TL.getNameLoc()); + +    if (Result.isNull()) +      return QualType(); +  } + +  if (isa<DependentExtIntType>(Result)) { +    DependentExtIntTypeLoc NewTL = TLB.push<DependentExtIntTypeLoc>(Result); +    NewTL.setNameLoc(TL.getNameLoc()); +  } else { +    ExtIntTypeLoc NewTL = TLB.push<ExtIntTypeLoc>(Result); +    NewTL.setNameLoc(TL.getNameLoc()); +  } +  return Result; +} +    /// Simple iterator that traverses the template arguments in a    /// container that provides a \c getArgLoc() member function.    /// @@ -6054,6 +6395,71 @@ QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,      }    }; +template<typename Derived> +QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB, +                                                   AutoTypeLoc TL) { +  const AutoType *T = TL.getTypePtr(); +  QualType OldDeduced = T->getDeducedType(); +  QualType NewDeduced; +  if (!OldDeduced.isNull()) { +    NewDeduced = getDerived().TransformType(OldDeduced); +    if (NewDeduced.isNull()) +      return QualType(); +  } + +  ConceptDecl *NewCD = nullptr; +  TemplateArgumentListInfo NewTemplateArgs; +  NestedNameSpecifierLoc NewNestedNameSpec; +  if (TL.getTypePtr()->isConstrained()) { +    NewCD = cast_or_null<ConceptDecl>( +        getDerived().TransformDecl( +            TL.getConceptNameLoc(), +            TL.getTypePtr()->getTypeConstraintConcept())); + +    NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc()); +    NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc()); +    typedef TemplateArgumentLocContainerIterator<AutoTypeLoc> ArgIterator; +    if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0), +                                                ArgIterator(TL, +                                                            TL.getNumArgs()), +                                                NewTemplateArgs)) +      return QualType(); + +    if (TL.getNestedNameSpecifierLoc()) { +      NewNestedNameSpec +        = getDerived().TransformNestedNameSpecifierLoc( +            TL.getNestedNameSpecifierLoc()); +      if (!NewNestedNameSpec) +        return QualType(); +    } +  } + +  QualType Result = TL.getType(); +  if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced || +      T->isDependentType()) { +    llvm::SmallVector<TemplateArgument, 4> NewArgList; +    NewArgList.reserve(NewArgList.size()); +    for (const auto &ArgLoc : NewTemplateArgs.arguments()) +      NewArgList.push_back(ArgLoc.getArgument()); +    Result = getDerived().RebuildAutoType(NewDeduced, T->getKeyword(), NewCD, +                                          NewArgList); +    if (Result.isNull()) +      return QualType(); +  } + +  AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(Result); +  NewTL.setNameLoc(TL.getNameLoc()); +  NewTL.setNestedNameSpecifierLoc(NewNestedNameSpec); +  NewTL.setTemplateKWLoc(TL.getTemplateKWLoc()); +  NewTL.setConceptNameLoc(TL.getConceptNameLoc()); +  NewTL.setFoundDecl(TL.getFoundDecl()); +  NewTL.setLAngleLoc(TL.getLAngleLoc()); +  NewTL.setRAngleLoc(TL.getRAngleLoc()); +  for (unsigned I = 0; I < TL.getNumArgs(); ++I) +    NewTL.setArgLocInfo(I, NewTemplateArgs.arguments()[I].getLocInfo()); + +  return Result; +}  template <typename Derived>  QualType TreeTransform<Derived>::TransformTemplateSpecializationType( @@ -6930,7 +7336,8 @@ TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {        Body.get() == S->getBody())      return Owned(S); -  return getDerived().RebuildWhileStmt(S->getWhileLoc(), Cond, Body.get()); +  return getDerived().RebuildWhileStmt(S->getWhileLoc(), S->getLParenLoc(), +                                       Cond, S->getRParenLoc(), Body.get());  }  template<typename Derived> @@ -7228,7 +7635,8 @@ TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {      return StmtError();    StmtResult FinalSuspend =        getDerived().TransformStmt(S->getFinalSuspendStmt()); -  if (FinalSuspend.isInvalid()) +  if (FinalSuspend.isInvalid() || +      !SemaRef.checkFinalSuspendNoThrow(FinalSuspend.get()))      return StmtError();    ScopeInfo->setCoroutineSuspends(InitSuspend.get(), FinalSuspend.get());    assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get())); @@ -7684,8 +8092,12 @@ TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {                                                    Cond.get(),                                                    Inc.get(), LoopVar.get(),                                                    S->getRParenLoc()); -    if (NewStmt.isInvalid()) +    if (NewStmt.isInvalid() && LoopVar.get() != S->getLoopVarStmt()) { +      // Might not have attached any initializer to the loop variable. +      getSema().ActOnInitializerError( +          cast<DeclStmt>(LoopVar.get())->getSingleDecl());        return StmtError(); +    }    }    StmtResult Body = getDerived().TransformStmt(S->getBody()); @@ -8152,6 +8564,28 @@ TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {  template <typename Derived>  StmtResult +TreeTransform<Derived>::TransformOMPDepobjDirective(OMPDepobjDirective *D) { +  DeclarationNameInfo DirName; +  getDerived().getSema().StartOpenMPDSABlock(OMPD_depobj, DirName, nullptr, +                                             D->getBeginLoc()); +  StmtResult Res = getDerived().TransformOMPExecutableDirective(D); +  getDerived().getSema().EndOpenMPDSABlock(Res.get()); +  return Res; +} + +template <typename Derived> +StmtResult +TreeTransform<Derived>::TransformOMPScanDirective(OMPScanDirective *D) { +  DeclarationNameInfo DirName; +  getDerived().getSema().StartOpenMPDSABlock(OMPD_scan, DirName, nullptr, +                                             D->getBeginLoc()); +  StmtResult Res = getDerived().TransformOMPExecutableDirective(D); +  getDerived().getSema().EndOpenMPDSABlock(Res.get()); +  return Res; +} + +template <typename Derived> +StmtResult  TreeTransform<Derived>::TransformOMPOrderedDirective(OMPOrderedDirective *D) {    DeclarationNameInfo DirName;    getDerived().getSema().StartOpenMPDSABlock(OMPD_ordered, DirName, nullptr, @@ -8638,6 +9072,19 @@ TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) {  template <typename Derived>  OMPClause * +TreeTransform<Derived>::TransformOMPDetachClause(OMPDetachClause *C) { +  ExprResult E; +  if (Expr *Evt = C->getEventHandler()) { +    E = getDerived().TransformExpr(Evt); +    if (E.isInvalid()) +      return nullptr; +  } +  return getDerived().RebuildOMPDetachClause(E.get(), C->getBeginLoc(), +                                             C->getLParenLoc(), C->getEndLoc()); +} + +template <typename Derived> +OMPClause *  TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {    // No need to rebuild this clause, no template-dependent parameters.    return C; @@ -8692,6 +9139,34 @@ TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) {  template <typename Derived>  OMPClause * +TreeTransform<Derived>::TransformOMPAcqRelClause(OMPAcqRelClause *C) { +  // No need to rebuild this clause, no template-dependent parameters. +  return C; +} + +template <typename Derived> +OMPClause * +TreeTransform<Derived>::TransformOMPAcquireClause(OMPAcquireClause *C) { +  // No need to rebuild this clause, no template-dependent parameters. +  return C; +} + +template <typename Derived> +OMPClause * +TreeTransform<Derived>::TransformOMPReleaseClause(OMPReleaseClause *C) { +  // No need to rebuild this clause, no template-dependent parameters. +  return C; +} + +template <typename Derived> +OMPClause * +TreeTransform<Derived>::TransformOMPRelaxedClause(OMPRelaxedClause *C) { +  // No need to rebuild this clause, no template-dependent parameters. +  return C; +} + +template <typename Derived> +OMPClause *  TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {    // No need to rebuild this clause, no template-dependent parameters.    return C; @@ -8711,6 +9186,13 @@ TreeTransform<Derived>::TransformOMPNogroupClause(OMPNogroupClause *C) {  }  template <typename Derived> +OMPClause * +TreeTransform<Derived>::TransformOMPDestroyClause(OMPDestroyClause *C) { +  // No need to rebuild this clause, no template-dependent parameters. +  return C; +} + +template <typename Derived>  OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause(      OMPUnifiedAddressClause *C) {    llvm_unreachable("unified_address clause cannot appear in dependent context"); @@ -8847,8 +9329,9 @@ TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {        UnresolvedReductions.push_back(nullptr);    }    return getDerived().RebuildOMPReductionClause( -      Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), -      C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions); +      Vars, C->getModifier(), C->getBeginLoc(), C->getLParenLoc(), +      C->getModifierLoc(), C->getColonLoc(), C->getEndLoc(), +      ReductionIdScopeSpec, NameInfo, UnresolvedReductions);  }  template <typename Derived> @@ -9025,8 +9508,25 @@ OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {  template <typename Derived>  OMPClause * +TreeTransform<Derived>::TransformOMPDepobjClause(OMPDepobjClause *C) { +  ExprResult E = getDerived().TransformExpr(C->getDepobj()); +  if (E.isInvalid()) +    return nullptr; +  return getDerived().RebuildOMPDepobjClause(E.get(), C->getBeginLoc(), +                                             C->getLParenLoc(), C->getEndLoc()); +} + +template <typename Derived> +OMPClause *  TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) {    llvm::SmallVector<Expr *, 16> Vars; +  Expr *DepModifier = C->getModifier(); +  if (DepModifier) { +    ExprResult DepModRes = getDerived().TransformExpr(DepModifier); +    if (DepModRes.isInvalid()) +      return nullptr; +    DepModifier = DepModRes.get(); +  }    Vars.reserve(C->varlist_size());    for (auto *VE : C->varlists()) {      ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); @@ -9035,8 +9535,9 @@ TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) {      Vars.push_back(EVar.get());    }    return getDerived().RebuildOMPDependClause( -      C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(), Vars, -      C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); +      DepModifier, C->getDependencyKind(), C->getDependencyLoc(), +      C->getColonLoc(), Vars, C->getBeginLoc(), C->getLParenLoc(), +      C->getEndLoc());  }  template <typename Derived> @@ -9045,8 +9546,9 @@ TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) {    ExprResult E = getDerived().TransformExpr(C->getDevice());    if (E.isInvalid())      return nullptr; -  return getDerived().RebuildOMPDeviceClause(E.get(), C->getBeginLoc(), -                                             C->getLParenLoc(), C->getEndLoc()); +  return getDerived().RebuildOMPDeviceClause( +      C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(), +      C->getModifierLoc(), C->getEndLoc());  }  template <typename Derived, class T> @@ -9269,6 +9771,21 @@ OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause(  }  template <typename Derived> +OMPClause *TreeTransform<Derived>::TransformOMPUseDeviceAddrClause( +    OMPUseDeviceAddrClause *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()); +  } +  OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); +  return getDerived().RebuildOMPUseDeviceAddrClause(Vars, Locs); +} + +template <typename Derived>  OMPClause *  TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {    llvm::SmallVector<Expr *, 16> Vars; @@ -9298,6 +9815,91 @@ TreeTransform<Derived>::TransformOMPNontemporalClause(OMPNontemporalClause *C) {        Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());  } +template <typename Derived> +OMPClause * +TreeTransform<Derived>::TransformOMPInclusiveClause(OMPInclusiveClause *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().RebuildOMPInclusiveClause( +      Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); +} + +template <typename Derived> +OMPClause * +TreeTransform<Derived>::TransformOMPExclusiveClause(OMPExclusiveClause *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().RebuildOMPExclusiveClause( +      Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); +} + +template <typename Derived> +OMPClause *TreeTransform<Derived>::TransformOMPUsesAllocatorsClause( +    OMPUsesAllocatorsClause *C) { +  SmallVector<Sema::UsesAllocatorsData, 16> Data; +  Data.reserve(C->getNumberOfAllocators()); +  for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) { +    OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I); +    ExprResult Allocator = getDerived().TransformExpr(D.Allocator); +    if (Allocator.isInvalid()) +      continue; +    ExprResult AllocatorTraits; +    if (Expr *AT = D.AllocatorTraits) { +      AllocatorTraits = getDerived().TransformExpr(AT); +      if (AllocatorTraits.isInvalid()) +        continue; +    } +    Sema::UsesAllocatorsData &NewD = Data.emplace_back(); +    NewD.Allocator = Allocator.get(); +    NewD.AllocatorTraits = AllocatorTraits.get(); +    NewD.LParenLoc = D.LParenLoc; +    NewD.RParenLoc = D.RParenLoc; +  } +  return getDerived().RebuildOMPUsesAllocatorsClause( +      Data, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); +} + +template <typename Derived> +OMPClause * +TreeTransform<Derived>::TransformOMPAffinityClause(OMPAffinityClause *C) { +  SmallVector<Expr *, 4> Locators; +  Locators.reserve(C->varlist_size()); +  ExprResult ModifierRes; +  if (Expr *Modifier = C->getModifier()) { +    ModifierRes = getDerived().TransformExpr(Modifier); +    if (ModifierRes.isInvalid()) +      return nullptr; +  } +  for (Expr *E : C->varlists()) { +    ExprResult Locator = getDerived().TransformExpr(E); +    if (Locator.isInvalid()) +      continue; +    Locators.push_back(Locator.get()); +  } +  return getDerived().RebuildOMPAffinityClause( +      C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), C->getEndLoc(), +      ModifierRes.get(), Locators); +} + +template <typename Derived> +OMPClause *TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) { +  return getDerived().RebuildOMPOrderClause(C->getKind(), C->getKindKwLoc(), +                                            C->getBeginLoc(), C->getLParenLoc(), +                                            C->getEndLoc()); +} +  //===----------------------------------------------------------------------===//  // Expression transformation  //===----------------------------------------------------------------------===// @@ -9581,6 +10183,24 @@ TreeTransform<Derived>::TransformTypoExpr(TypoExpr *E) {    return E;  } +template <typename Derived> +ExprResult TreeTransform<Derived>::TransformRecoveryExpr(RecoveryExpr *E) { +  llvm::SmallVector<Expr *, 8> Children; +  bool Changed = false; +  for (Expr *C : E->subExpressions()) { +    ExprResult NewC = getDerived().TransformExpr(C); +    if (NewC.isInvalid()) +      return ExprError(); +    Children.push_back(NewC.get()); + +    Changed |= NewC.get() != C; +  } +  if (!getDerived().AlwaysRebuild() && !Changed) +    return E; +  return getDerived().RebuildRecoveryExpr(E->getBeginLoc(), E->getEndLoc(), +                                          Children); +} +  template<typename Derived>  ExprResult  TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) { @@ -9680,6 +10300,29 @@ TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {  template <typename Derived>  ExprResult +TreeTransform<Derived>::TransformMatrixSubscriptExpr(MatrixSubscriptExpr *E) { +  ExprResult Base = getDerived().TransformExpr(E->getBase()); +  if (Base.isInvalid()) +    return ExprError(); + +  ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx()); +  if (RowIdx.isInvalid()) +    return ExprError(); + +  ExprResult ColumnIdx = getDerived().TransformExpr(E->getColumnIdx()); +  if (ColumnIdx.isInvalid()) +    return ExprError(); + +  if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() && +      RowIdx.get() == E->getRowIdx() && ColumnIdx.get() == E->getColumnIdx()) +    return E; + +  return getDerived().RebuildMatrixSubscriptExpr( +      Base.get(), RowIdx.get(), ColumnIdx.get(), E->getRBracketLoc()); +} + +template <typename Derived> +ExprResult  TreeTransform<Derived>::TransformOMPArraySectionExpr(OMPArraySectionExpr *E) {    ExprResult Base = getDerived().TransformExpr(E->getBase());    if (Base.isInvalid()) @@ -9699,13 +10342,105 @@ TreeTransform<Derived>::TransformOMPArraySectionExpr(OMPArraySectionExpr *E) {        return ExprError();    } +  ExprResult Stride; +  if (Expr *Str = E->getStride()) { +    Stride = getDerived().TransformExpr(Str); +    if (Stride.isInvalid()) +      return ExprError(); +  } +    if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&        LowerBound.get() == E->getLowerBound() && Length.get() == E->getLength())      return E;    return getDerived().RebuildOMPArraySectionExpr( -      Base.get(), E->getBase()->getEndLoc(), LowerBound.get(), E->getColonLoc(), -      Length.get(), E->getRBracketLoc()); +      Base.get(), E->getBase()->getEndLoc(), LowerBound.get(), +      E->getColonLocFirst(), E->getColonLocSecond(), Length.get(), Stride.get(), +      E->getRBracketLoc()); +} + +template <typename Derived> +ExprResult +TreeTransform<Derived>::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) { +  ExprResult Base = getDerived().TransformExpr(E->getBase()); +  if (Base.isInvalid()) +    return ExprError(); + +  SmallVector<Expr *, 4> Dims; +  bool ErrorFound = false; +  for (Expr *Dim : E->getDimensions()) { +    ExprResult DimRes = getDerived().TransformExpr(Dim); +    if (DimRes.isInvalid()) { +      ErrorFound = true; +      continue; +    } +    Dims.push_back(DimRes.get()); +  } + +  if (ErrorFound) +    return ExprError(); +  return getDerived().RebuildOMPArrayShapingExpr(Base.get(), E->getLParenLoc(), +                                                 E->getRParenLoc(), Dims, +                                                 E->getBracketsRanges()); +} + +template <typename Derived> +ExprResult +TreeTransform<Derived>::TransformOMPIteratorExpr(OMPIteratorExpr *E) { +  unsigned NumIterators = E->numOfIterators(); +  SmallVector<Sema::OMPIteratorData, 4> Data(NumIterators); + +  bool ErrorFound = false; +  bool NeedToRebuild = getDerived().AlwaysRebuild(); +  for (unsigned I = 0; I < NumIterators; ++I) { +    auto *D = cast<VarDecl>(E->getIteratorDecl(I)); +    Data[I].DeclIdent = D->getIdentifier(); +    Data[I].DeclIdentLoc = D->getLocation(); +    if (D->getLocation() == D->getBeginLoc()) { +      assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) && +             "Implicit type must be int."); +    } else { +      TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo()); +      QualType DeclTy = getDerived().TransformType(D->getType()); +      Data[I].Type = SemaRef.CreateParsedType(DeclTy, TSI); +    } +    OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I); +    ExprResult Begin = getDerived().TransformExpr(Range.Begin); +    ExprResult End = getDerived().TransformExpr(Range.End); +    ExprResult Step = getDerived().TransformExpr(Range.Step); +    ErrorFound = ErrorFound || +                 !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() && +                                               !Data[I].Type.get().isNull())) || +                 Begin.isInvalid() || End.isInvalid() || Step.isInvalid(); +    if (ErrorFound) +      continue; +    Data[I].Range.Begin = Begin.get(); +    Data[I].Range.End = End.get(); +    Data[I].Range.Step = Step.get(); +    Data[I].AssignLoc = E->getAssignLoc(I); +    Data[I].ColonLoc = E->getColonLoc(I); +    Data[I].SecColonLoc = E->getSecondColonLoc(I); +    NeedToRebuild = +        NeedToRebuild || +        (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() != +                                       D->getType().getTypePtrOrNull()) || +        Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End || +        Range.Step != Data[I].Range.Step; +  } +  if (ErrorFound) +    return ExprError(); +  if (!NeedToRebuild) +    return E; + +  ExprResult Res = getDerived().RebuildOMPIteratorExpr( +      E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data); +  if (!Res.isUsable()) +    return Res; +  auto *IE = cast<OMPIteratorExpr>(Res.get()); +  for (unsigned I = 0; I < NumIterators; ++I) +    getDerived().transformedLocalDecl(E->getIteratorDecl(I), +                                      IE->getIteratorDecl(I)); +  return Res;  }  template<typename Derived> @@ -9837,9 +10572,15 @@ TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {        RHS.get() == E->getRHS())      return E; -  Sema::FPContractStateRAII FPContractState(getSema()); -  getSema().FPFeatures = E->getFPFeatures(); - +  if (E->isCompoundAssignmentOp()) +    // FPFeatures has already been established from trailing storage +    return getDerived().RebuildBinaryOperator( +        E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get()); +  Sema::FPFeaturesStateRAII FPFeaturesState(getSema()); +  FPOptionsOverride NewOverrides(E->getFPFeatures(getSema().getLangOpts())); +  getSema().CurFPFeatures = +      NewOverrides.applyOverrides(getSema().getLangOpts()); +  getSema().FpPragmaStack.CurrentValue = NewOverrides.getAsOpaqueInt();    return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),                                              LHS.get(), RHS.get());  } @@ -9892,6 +10633,11 @@ template<typename Derived>  ExprResult  TreeTransform<Derived>::TransformCompoundAssignOperator(                                                        CompoundAssignOperator *E) { +  Sema::FPFeaturesStateRAII FPFeaturesState(getSema()); +  FPOptionsOverride NewOverrides(E->getFPFeatures(getSema().getLangOpts())); +  getSema().CurFPFeatures = +      NewOverrides.applyOverrides(getSema().getLangOpts()); +  getSema().FpPragmaStack.CurrentValue = NewOverrides.getAsOpaqueInt();    return getDerived().TransformBinaryOperator(E);  } @@ -10245,16 +10991,18 @@ TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {      return ExprError();    } -  if (!getDerived().AlwaysRebuild() && +  unsigned OldDepth = E->getTemplateDepth(); +  unsigned NewDepth = getDerived().TransformTemplateDepth(OldDepth); + +  if (!getDerived().AlwaysRebuild() && OldDepth == NewDepth &&        SubStmt.get() == E->getSubStmt()) {      // Calling this an 'error' is unintuitive, but it does the right thing.      SemaRef.ActOnStmtExprError();      return SemaRef.MaybeBindToTemporary(E);    } -  return getDerived().RebuildStmtExpr(E->getLParenLoc(), -                                      SubStmt.get(), -                                      E->getRParenLoc()); +  return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(), +                                      E->getRParenLoc(), NewDepth);  }  template<typename Derived> @@ -10363,8 +11111,11 @@ TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {        (E->getNumArgs() != 2 || Second.get() == E->getArg(1)))      return SemaRef.MaybeBindToTemporary(E); -  Sema::FPContractStateRAII FPContractState(getSema()); -  getSema().FPFeatures = E->getFPFeatures(); +  Sema::FPFeaturesStateRAII FPFeaturesState(getSema()); +  FPOptionsOverride NewOverrides(E->getFPFeatures()); +  getSema().CurFPFeatures = +      NewOverrides.applyOverrides(getSema().getLangOpts()); +  getSema().FpPragmaStack.CurrentValue = NewOverrides.getAsOpaqueInt();    return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(),                                                   E->getOperatorLoc(), @@ -10491,6 +11242,12 @@ TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {  template<typename Derived>  ExprResult +TreeTransform<Derived>::TransformCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) { +  return getDerived().TransformCXXNamedCastExpr(E); +} + +template<typename Derived> +ExprResult  TreeTransform<Derived>::TransformCXXFunctionalCastExpr(                                                       CXXFunctionalCastExpr *E) {    TypeSourceInfo *Type = @@ -11179,6 +11936,146 @@ TreeTransform<Derived>::TransformConceptSpecializationExpr(        &TransArgs);  } +template<typename Derived> +ExprResult +TreeTransform<Derived>::TransformRequiresExpr(RequiresExpr *E) { +  SmallVector<ParmVarDecl*, 4> TransParams; +  SmallVector<QualType, 4> TransParamTypes; +  Sema::ExtParameterInfoBuilder ExtParamInfos; + +  // C++2a [expr.prim.req]p2 +  // Expressions appearing within a requirement-body are unevaluated operands. +  EnterExpressionEvaluationContext Ctx( +      SemaRef, Sema::ExpressionEvaluationContext::Unevaluated); + +  RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create( +      getSema().Context, getSema().CurContext, +      E->getBody()->getBeginLoc()); + +  Sema::ContextRAII SavedContext(getSema(), Body, /*NewThisContext*/false); + +  if (getDerived().TransformFunctionTypeParams(E->getRequiresKWLoc(), +                                               E->getLocalParameters(), +                                               /*ParamTypes=*/nullptr, +                                               /*ParamInfos=*/nullptr, +                                               TransParamTypes, &TransParams, +                                               ExtParamInfos)) +    return ExprError(); + +  for (ParmVarDecl *Param : TransParams) +    Param->setDeclContext(Body); + +  SmallVector<concepts::Requirement *, 4> TransReqs; +  if (getDerived().TransformRequiresExprRequirements(E->getRequirements(), +                                                     TransReqs)) +    return ExprError(); + +  for (concepts::Requirement *Req : TransReqs) { +    if (auto *ER = dyn_cast<concepts::ExprRequirement>(Req)) { +      if (ER->getReturnTypeRequirement().isTypeConstraint()) { +        ER->getReturnTypeRequirement() +                .getTypeConstraintTemplateParameterList()->getParam(0) +                ->setDeclContext(Body); +      } +    } +  } + +  return getDerived().RebuildRequiresExpr(E->getRequiresKWLoc(), Body, +                                          TransParams, TransReqs, +                                          E->getRBraceLoc()); +} + +template<typename Derived> +bool TreeTransform<Derived>::TransformRequiresExprRequirements( +    ArrayRef<concepts::Requirement *> Reqs, +    SmallVectorImpl<concepts::Requirement *> &Transformed) { +  for (concepts::Requirement *Req : Reqs) { +    concepts::Requirement *TransReq = nullptr; +    if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) +      TransReq = getDerived().TransformTypeRequirement(TypeReq); +    else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) +      TransReq = getDerived().TransformExprRequirement(ExprReq); +    else +      TransReq = getDerived().TransformNestedRequirement( +                     cast<concepts::NestedRequirement>(Req)); +    if (!TransReq) +      return true; +    Transformed.push_back(TransReq); +  } +  return false; +} + +template<typename Derived> +concepts::TypeRequirement * +TreeTransform<Derived>::TransformTypeRequirement( +    concepts::TypeRequirement *Req) { +  if (Req->isSubstitutionFailure()) { +    if (getDerived().AlwaysRebuild()) +      return getDerived().RebuildTypeRequirement( +              Req->getSubstitutionDiagnostic()); +    return Req; +  } +  TypeSourceInfo *TransType = getDerived().TransformType(Req->getType()); +  if (!TransType) +    return nullptr; +  return getDerived().RebuildTypeRequirement(TransType); +} + +template<typename Derived> +concepts::ExprRequirement * +TreeTransform<Derived>::TransformExprRequirement(concepts::ExprRequirement *Req) { +  llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *> TransExpr; +  if (Req->isExprSubstitutionFailure()) +    TransExpr = Req->getExprSubstitutionDiagnostic(); +  else { +    ExprResult TransExprRes = getDerived().TransformExpr(Req->getExpr()); +    if (TransExprRes.isInvalid()) +      return nullptr; +    TransExpr = TransExprRes.get(); +  } + +  llvm::Optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq; +  const auto &RetReq = Req->getReturnTypeRequirement(); +  if (RetReq.isEmpty()) +    TransRetReq.emplace(); +  else if (RetReq.isSubstitutionFailure()) +    TransRetReq.emplace(RetReq.getSubstitutionDiagnostic()); +  else if (RetReq.isTypeConstraint()) { +    TemplateParameterList *OrigTPL = +        RetReq.getTypeConstraintTemplateParameterList(); +    TemplateParameterList *TPL = +        getDerived().TransformTemplateParameterList(OrigTPL); +    if (!TPL) +      return nullptr; +    TransRetReq.emplace(TPL); +  } +  assert(TransRetReq.hasValue() && +         "All code paths leading here must set TransRetReq"); +  if (Expr *E = TransExpr.dyn_cast<Expr *>()) +    return getDerived().RebuildExprRequirement(E, Req->isSimple(), +                                               Req->getNoexceptLoc(), +                                               std::move(*TransRetReq)); +  return getDerived().RebuildExprRequirement( +      TransExpr.get<concepts::Requirement::SubstitutionDiagnostic *>(), +      Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq)); +} + +template<typename Derived> +concepts::NestedRequirement * +TreeTransform<Derived>::TransformNestedRequirement( +    concepts::NestedRequirement *Req) { +  if (Req->isSubstitutionFailure()) { +    if (getDerived().AlwaysRebuild()) +      return getDerived().RebuildNestedRequirement( +          Req->getSubstitutionDiagnostic()); +    return Req; +  } +  ExprResult TransConstraint = +      getDerived().TransformExpr(Req->getConstraintExpr()); +  if (TransConstraint.isInvalid()) +    return nullptr; +  return getDerived().RebuildNestedRequirement(TransConstraint.get()); +}  template<typename Derived>  ExprResult @@ -11303,10 +12200,11 @@ TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {    // CXXConstructExprs other than for list-initialization and    // CXXTemporaryObjectExpr are always implicit, so when we have    // a 1-argument construction we just transform that argument. -  if ((E->getNumArgs() == 1 || -       (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(1)))) && -      (!getDerived().DropCallArgument(E->getArg(0))) && -      !E->isListInitialization()) +  if (getDerived().AllowSkippingCXXConstructExpr() && +      ((E->getNumArgs() == 1 || +        (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(1)))) && +       (!getDerived().DropCallArgument(E->getArg(0))) && +       !E->isListInitialization()))      return getDerived().TransformExpr(E->getArg(0));    TemporaryBase Rebase(*this, /*FIXME*/ E->getBeginLoc(), DeclarationName()); @@ -11560,6 +12458,8 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {      NewTrailingRequiresClause = getDerived().TransformExpr(TRC);    // Create the local class that will describe the lambda. +  // FIXME: KnownDependent below is wrong when substituting inside a templated +  // context that isn't a DeclContext (such as a variable template).    CXXRecordDecl *OldClass = E->getLambdaClass();    CXXRecordDecl *Class      = getSema().createLambdaClosureType(E->getIntroducerRange(), @@ -11584,19 +12484,6 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {    LSI->CallOperator = NewCallOperator; -  for (unsigned I = 0, NumParams = NewCallOperator->getNumParams(); -       I != NumParams; ++I) { -    auto *P = NewCallOperator->getParamDecl(I); -    if (P->hasUninstantiatedDefaultArg()) { -      EnterExpressionEvaluationContext Eval( -          getSema(), -          Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed, P); -      ExprResult R = getDerived().TransformExpr( -          E->getCallOperator()->getParamDecl(I)->getDefaultArg()); -      P->setDefaultArg(R.get()); -    } -  } -    getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);    getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator}); @@ -13092,6 +13979,21 @@ TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,    return SemaRef.BuildExtVectorType(ElementType, SizeExpr, AttributeLoc);  } +template <typename Derived> +QualType TreeTransform<Derived>::RebuildConstantMatrixType( +    QualType ElementType, unsigned NumRows, unsigned NumColumns) { +  return SemaRef.Context.getConstantMatrixType(ElementType, NumRows, +                                               NumColumns); +} + +template <typename Derived> +QualType TreeTransform<Derived>::RebuildDependentSizedMatrixType( +    QualType ElementType, Expr *RowExpr, Expr *ColumnExpr, +    SourceLocation AttributeLoc) { +  return SemaRef.BuildMatrixType(ElementType, RowExpr, ColumnExpr, +                                 AttributeLoc); +} +  template<typename Derived>  QualType TreeTransform<Derived>::RebuildFunctionProtoType(      QualType T, @@ -13206,6 +14108,23 @@ QualType TreeTransform<Derived>::RebuildPipeType(QualType ValueType,                      : SemaRef.BuildWritePipeType(ValueType, KWLoc);  } +template <typename Derived> +QualType TreeTransform<Derived>::RebuildExtIntType(bool IsUnsigned, +                                                   unsigned NumBits, +                                                   SourceLocation Loc) { +  llvm::APInt NumBitsAP(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy), +                        NumBits, true); +  IntegerLiteral *Bits = IntegerLiteral::Create(SemaRef.Context, NumBitsAP, +                                                SemaRef.Context.IntTy, Loc); +  return SemaRef.BuildExtIntType(IsUnsigned, Bits, Loc); +} + +template <typename Derived> +QualType TreeTransform<Derived>::RebuildDependentExtIntType( +    bool IsUnsigned, Expr *NumBitsExpr, SourceLocation Loc) { +  return SemaRef.BuildExtIntType(IsUnsigned, NumBitsExpr, Loc); +} +  template<typename Derived>  TemplateName  TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS, @@ -13227,11 +14146,10 @@ TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,    UnqualifiedId TemplateName;    TemplateName.setIdentifier(&Name, NameLoc);    Sema::TemplateTy Template; -  getSema().ActOnDependentTemplateName(/*Scope=*/nullptr, -                                       SS, TemplateKWLoc, TemplateName, -                                       ParsedType::make(ObjectType), -                                       /*EnteringContext=*/false, -                                       Template, AllowInjectedClassName); +  getSema().ActOnTemplateName(/*Scope=*/nullptr, SS, TemplateKWLoc, +                              TemplateName, ParsedType::make(ObjectType), +                              /*EnteringContext=*/false, Template, +                              AllowInjectedClassName);    return Template.get();  } @@ -13248,11 +14166,9 @@ TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,    SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc };    Name.setOperatorFunctionId(NameLoc, Operator, SymbolLocations);    Sema::TemplateTy Template; -  getSema().ActOnDependentTemplateName(/*Scope=*/nullptr, -                                       SS, TemplateKWLoc, Name, -                                       ParsedType::make(ObjectType), -                                       /*EnteringContext=*/false, -                                       Template, AllowInjectedClassName); +  getSema().ActOnTemplateName( +      /*Scope=*/nullptr, SS, TemplateKWLoc, Name, ParsedType::make(ObjectType), +      /*EnteringContext=*/false, Template, AllowInjectedClassName);    return Template.get();  } | 
