diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/TreeTransform.h')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/TreeTransform.h | 1141 |
1 files changed, 903 insertions, 238 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/TreeTransform.h b/contrib/llvm/tools/clang/lib/Sema/TreeTransform.h index bb49eee..fdb861e 100644 --- a/contrib/llvm/tools/clang/lib/Sema/TreeTransform.h +++ b/contrib/llvm/tools/clang/lib/Sema/TreeTransform.h @@ -112,6 +112,11 @@ class TreeTransform { protected: Sema &SemaRef; + /// \brief The set of local declarations that have been transformed, for + /// cases where we are forced to build new declarations within the transformer + /// rather than in the subclass (e.g., lambda closure types). + llvm::DenseMap<Decl *, Decl *> TransformedLocalDecls; + public: /// \brief Initializes a new tree transformer. TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { } @@ -351,10 +356,36 @@ public: /// \brief Transform the given declaration, which is referenced from a type /// or expression. /// - /// By default, acts as the identity function on declarations. Subclasses + /// By default, acts as the identity function on declarations, unless the + /// transformer has had to transform the declaration itself. Subclasses /// may override this function to provide alternate behavior. - Decl *TransformDecl(SourceLocation Loc, Decl *D) { return D; } + Decl *TransformDecl(SourceLocation Loc, Decl *D) { + llvm::DenseMap<Decl *, Decl *>::iterator Known + = TransformedLocalDecls.find(D); + if (Known != TransformedLocalDecls.end()) + return Known->second; + + return D; + } + /// \brief Transform the attributes associated with the given declaration and + /// place them on the new declaration. + /// + /// By default, this operation does nothing. Subclasses may override this + /// behavior to transform attributes. + void transformAttrs(Decl *Old, Decl *New) { } + + /// \brief Note that a local declaration has been transformed by this + /// transformer. + /// + /// Local declarations are typically transformed via a call to + /// TransformDefinition. However, in some cases (e.g., lambda expressions), + /// the transformer itself has to transform the declarations. This routine + /// can be overridden by a subclass that keeps track of such mappings. + void transformedLocalDecl(Decl *Old, Decl *New) { + TransformedLocalDecls[Old] = New; + } + /// \brief Transform the definition of the given declaration. /// /// By default, invokes TransformDecl() to transform the declaration. @@ -418,7 +449,7 @@ public: /// Subclasses may override this function to provide alternate behavior. TemplateName TransformTemplateName(CXXScopeSpec &SS, TemplateName Name, - SourceLocation NameLoc, + SourceLocation NameLoc, QualType ObjectType = QualType(), NamedDecl *FirstQualifierInScope = 0); @@ -530,7 +561,8 @@ public: /// scope index; can be negative ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm, int indexAdjustment, - llvm::Optional<unsigned> NumExpansions); + llvm::Optional<unsigned> NumExpansions, + bool ExpectParameterPack); QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL); @@ -665,7 +697,8 @@ public: QualType RebuildFunctionProtoType(QualType T, QualType *ParamTypes, unsigned NumParamTypes, - bool Variadic, unsigned Quals, + bool Variadic, bool HasTrailingReturn, + unsigned Quals, RefQualifierKind RefQualifier, const FunctionType::ExtInfo &Info); @@ -845,7 +878,6 @@ public: case LookupResult::FoundOverloaded: case LookupResult::FoundUnresolvedValue: llvm_unreachable("Tag lookup cannot find non-tags"); - return QualType(); case LookupResult::Ambiguous: // Let the LookupResult structure handle ambiguities. @@ -1291,7 +1323,20 @@ public: return getSema().BuildCXXForRangeStmt(ForLoc, ColonLoc, Range, BeginEnd, Cond, Inc, LoopVar, RParenLoc); } - + + /// \brief Build a new C++0x range-based for statement. + /// + /// By default, performs semantic analysis to build the new statement. + /// Subclasses may override this routine to provide different behavior. + StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc, + bool IsIfExists, + NestedNameSpecifierLoc QualifierLoc, + DeclarationNameInfo NameInfo, + Stmt *Nested) { + return getSema().BuildMSDependentExistsStmt(KeywordLoc, IsIfExists, + QualifierLoc, NameInfo, Nested); + } + /// \brief Attach body to a C++0x range-based for statement. /// /// By default, performs semantic analysis to finish the new statement. @@ -1450,11 +1495,14 @@ public: ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc, bool isArrow, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &MemberNameInfo, ValueDecl *Member, NamedDecl *FoundDecl, const TemplateArgumentListInfo *ExplicitTemplateArgs, NamedDecl *FirstQualifierInScope) { + ExprResult BaseResult = getSema().PerformMemberExprBaseConversion(Base, + isArrow); if (!Member->getDeclName()) { // We have a reference to an unnamed field. This is always the // base of an anonymous struct/union member access, i.e. the @@ -1463,8 +1511,8 @@ public: assert(Member->getType()->isRecordType() && "unnamed member not of record type?"); - ExprResult BaseResult = - getSema().PerformObjectMemberConversion(Base, + BaseResult = + getSema().PerformObjectMemberConversion(BaseResult.take(), QualifierLoc.getNestedNameSpecifier(), FoundDecl, Member); if (BaseResult.isInvalid()) @@ -1482,9 +1530,6 @@ public: CXXScopeSpec SS; SS.Adopt(QualifierLoc); - ExprResult BaseResult = getSema().DefaultFunctionArrayConversion(Base); - if (BaseResult.isInvalid()) - return ExprError(); Base = BaseResult.take(); QualType BaseType = Base->getType(); @@ -1495,7 +1540,8 @@ public: R.resolveKind(); return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow, - SS, FirstQualifierInScope, + SS, TemplateKWLoc, + FirstQualifierInScope, R, ExplicitTemplateArgs); } @@ -1559,7 +1605,8 @@ public: DeclarationNameInfo NameInfo(&Accessor, AccessorLoc); return getSema().BuildMemberReferenceExpr(Base, Base->getType(), OpLoc, /*IsArrow*/ false, - SS, /*FirstQualifierInScope*/ 0, + SS, SourceLocation(), + /*FirstQualifierInScope*/ 0, NameInfo, /* TemplateArgs */ 0); } @@ -1629,10 +1676,9 @@ public: /// By default, performs semantic analysis to build the new expression. /// Subclasses may override this routine to provide different behavior. ExprResult RebuildParenListExpr(SourceLocation LParenLoc, - MultiExprArg SubExprs, - SourceLocation RParenLoc) { - return getSema().ActOnParenOrParenListExpr(LParenLoc, RParenLoc, - move(SubExprs)); + MultiExprArg SubExprs, + SourceLocation RParenLoc) { + return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, move(SubExprs)); } /// \brief Build a new address-of-label expression. @@ -1736,8 +1782,6 @@ public: default: llvm_unreachable("Invalid C++ named cast"); } - - return ExprError(); } /// \brief Build a new C++ static_cast expression. @@ -1878,6 +1922,7 @@ public: ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc, QualType ThisType, bool isImplicit) { + getSema().CheckCXXThisCapture(ThisLoc); return getSema().Owned( new (getSema().Context) CXXThisExpr(ThisLoc, ThisType, isImplicit)); @@ -1928,9 +1973,8 @@ public: QualType AllocatedType, TypeSourceInfo *AllocatedTypeInfo, Expr *ArraySize, - SourceLocation ConstructorLParen, - MultiExprArg ConstructorArgs, - SourceLocation ConstructorRParen) { + SourceRange DirectInitRange, + Expr *Initializer) { return getSema().BuildCXXNew(StartLoc, UseGlobal, PlacementLParen, move(PlacementArgs), @@ -1939,9 +1983,8 @@ public: AllocatedType, AllocatedTypeInfo, ArraySize, - ConstructorLParen, - move(ConstructorArgs), - ConstructorRParen); + DirectInitRange, + Initializer); } /// \brief Build a new C++ "delete" expression. @@ -1979,6 +2022,17 @@ public: return getSema().BuildBinaryTypeTrait(Trait, StartLoc, LhsT, RhsT, RParenLoc); } + /// \brief Build a new type trait expression. + /// + /// By default, performs semantic analysis to build the new expression. + /// Subclasses may override this routine to provide different behavior. + ExprResult RebuildTypeTrait(TypeTrait Trait, + SourceLocation StartLoc, + ArrayRef<TypeSourceInfo *> Args, + SourceLocation RParenLoc) { + return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc); + } + /// \brief Build a new array type trait expression. /// /// By default, performs semantic analysis to build the new expression. @@ -2009,14 +2063,15 @@ public: /// Subclasses may override this routine to provide different behavior. ExprResult RebuildDependentScopeDeclRefExpr( NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs) { CXXScopeSpec SS; SS.Adopt(QualifierLoc); - if (TemplateArgs) - return getSema().BuildQualifiedTemplateIdExpr(SS, NameInfo, - *TemplateArgs); + if (TemplateArgs || TemplateKWLoc.isValid()) + return getSema().BuildQualifiedTemplateIdExpr(SS, TemplateKWLoc, + NameInfo, TemplateArgs); return getSema().BuildQualifiedDeclarationNameExpr(SS, NameInfo); } @@ -2026,10 +2081,12 @@ public: /// By default, performs semantic analysis to build the new expression. /// Subclasses may override this routine to provide different behavior. ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS, - LookupResult &R, - bool RequiresADL, - const TemplateArgumentListInfo &TemplateArgs) { - return getSema().BuildTemplateIdExpr(SS, R, RequiresADL, TemplateArgs); + SourceLocation TemplateKWLoc, + LookupResult &R, + bool RequiresADL, + const TemplateArgumentListInfo *TemplateArgs) { + return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL, + TemplateArgs); } /// \brief Build a new object-construction expression. @@ -2094,6 +2151,7 @@ public: bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs) { @@ -2102,7 +2160,8 @@ public: return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType, OperatorLoc, IsArrow, - SS, FirstQualifierInScope, + SS, TemplateKWLoc, + FirstQualifierInScope, MemberNameInfo, TemplateArgs); } @@ -2111,20 +2170,21 @@ public: /// /// By default, performs semantic analysis to build the new expression. /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE, - QualType BaseType, - SourceLocation OperatorLoc, - bool IsArrow, - NestedNameSpecifierLoc QualifierLoc, - NamedDecl *FirstQualifierInScope, - LookupResult &R, + ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE, QualType BaseType, + SourceLocation OperatorLoc, + bool IsArrow, + NestedNameSpecifierLoc QualifierLoc, + SourceLocation TemplateKWLoc, + NamedDecl *FirstQualifierInScope, + LookupResult &R, const TemplateArgumentListInfo *TemplateArgs) { CXXScopeSpec SS; SS.Adopt(QualifierLoc); return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType, OperatorLoc, IsArrow, - SS, FirstQualifierInScope, + SS, TemplateKWLoc, + FirstQualifierInScope, R, TemplateArgs); } @@ -2150,7 +2210,35 @@ public: OperatorLoc, Pack, PackLoc, RParenLoc); } - + + /// \brief Build a new Objective-C array literal. + /// + /// By default, performs semantic analysis to build the new expression. + /// Subclasses may override this routine to provide different behavior. + ExprResult RebuildObjCArrayLiteral(SourceRange Range, + Expr **Elements, unsigned NumElements) { + return getSema().BuildObjCArrayLiteral(Range, + MultiExprArg(Elements, NumElements)); + } + + ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB, + Expr *Base, Expr *Key, + ObjCMethodDecl *getterMethod, + ObjCMethodDecl *setterMethod) { + return getSema().BuildObjCSubscriptExpression(RB, Base, Key, + getterMethod, setterMethod); + } + + /// \brief Build a new Objective-C dictionary literal. + /// + /// By default, performs semantic analysis to build the new expression. + /// Subclasses may override this routine to provide different behavior. + ExprResult RebuildObjCDictionaryLiteral(SourceRange Range, + ObjCDictionaryElement *Elements, + unsigned NumElements) { + return getSema().BuildObjCDictionaryLiteral(Range, Elements, NumElements); + } + /// \brief Build a new Objective-C @encode expression. /// /// By default, performs semantic analysis to build the new expression. @@ -2215,7 +2303,8 @@ public: return move(Result); return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(), - /*FIXME:*/IvarLoc, IsArrow, SS, + /*FIXME:*/IvarLoc, IsArrow, + SS, SourceLocation(), /*FirstQualifierInScope=*/0, R, /*TemplateArgs=*/0); @@ -2226,8 +2315,8 @@ public: /// By default, performs semantic analysis to build the new expression. /// Subclasses may override this routine to provide different behavior. ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg, - ObjCPropertyDecl *Property, - SourceLocation PropertyLoc) { + ObjCPropertyDecl *Property, + SourceLocation PropertyLoc) { CXXScopeSpec SS; ExprResult Base = getSema().Owned(BaseArg); LookupResult R(getSema(), Property->getDeclName(), PropertyLoc, @@ -2244,7 +2333,7 @@ public: return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(), /*FIXME:*/PropertyLoc, IsArrow, - SS, + SS, SourceLocation(), /*FirstQualifierInScope=*/0, R, /*TemplateArgs=*/0); @@ -2286,7 +2375,8 @@ public: return move(Result); return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(), - /*FIXME:*/IsaLoc, IsArrow, SS, + /*FIXME:*/IsaLoc, IsArrow, + SS, SourceLocation(), /*FirstQualifierInScope=*/0, R, /*TemplateArgs=*/0); @@ -2309,7 +2399,8 @@ public: // Build a reference to the __builtin_shufflevector builtin FunctionDecl *Builtin = cast<FunctionDecl>(*Lookup.first); ExprResult Callee - = SemaRef.Owned(new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(), + = SemaRef.Owned(new (SemaRef.Context) DeclRefExpr(Builtin, false, + Builtin->getType(), VK_LValue, BuiltinLoc)); Callee = SemaRef.UsualUnaryConversions(Callee.take()); if (Callee.isInvalid()) @@ -2625,10 +2716,13 @@ TreeTransform<Derived>::TransformNestedNameSpecifierLoc( return NestedNameSpecifierLoc(); if (TL.getType()->isDependentType() || TL.getType()->isRecordType() || - (SemaRef.getLangOptions().CPlusPlus0x && + (SemaRef.getLangOpts().CPlusPlus0x && TL.getType()->isEnumeralType())) { assert(!TL.getType().hasLocalQualifiers() && "Can't get cv-qualifiers here"); + if (TL.getType()->isEnumeralType()) + SemaRef.Diag(TL.getBeginLoc(), + diag::warn_cxx98_compat_enum_nested_name_spec); SS.Extend(SemaRef.Context, /*FIXME:*/SourceLocation(), TL, Q.getLocalEndLoc()); break; @@ -2797,7 +2891,6 @@ TreeTransform<Derived>::TransformTemplateName(CXXScopeSpec &SS, // These should be getting filtered out before they reach the AST. llvm_unreachable("overloaded function decl survived to here"); - return TemplateName(); } template<typename Derived> @@ -2884,8 +2977,9 @@ bool TreeTransform<Derived>::TransformTemplateArgument( Expr *SourceExpr = Input.getSourceDeclExpression(); if (SourceExpr) { EnterExpressionEvaluationContext Unevaluated(getSema(), - Sema::Unevaluated); + Sema::ConstantEvaluated); ExprResult E = getDerived().TransformExpr(SourceExpr); + E = SemaRef.ActOnConstantExpression(E); SourceExpr = (E.isInvalid() ? 0 : E.take()); } @@ -2918,14 +3012,15 @@ bool TreeTransform<Derived>::TransformTemplateArgument( llvm_unreachable("Caller should expand pack expansions"); case TemplateArgument::Expression: { - // Template argument expressions are not potentially evaluated. + // Template argument expressions are constant expressions. EnterExpressionEvaluationContext Unevaluated(getSema(), - Sema::Unevaluated); + Sema::ConstantEvaluated); Expr *InputExpr = Input.getSourceExpression(); if (!InputExpr) InputExpr = Input.getArgument().getAsExpr(); ExprResult E = getDerived().TransformExpr(InputExpr); + E = SemaRef.ActOnConstantExpression(E); if (E.isInvalid()) return true; Output = TemplateArgumentLoc(TemplateArgument(E.take()), E.take()); return false; @@ -3168,6 +3263,9 @@ QualType TreeTransform<Derived>::TransformType(QualType T) { template<typename Derived> TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *DI) { + // Refine the base location to the type's location. + TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(), + getDerived().getBaseEntity()); if (getDerived().AlreadyTransformed(DI->getType())) return DI; @@ -3195,7 +3293,6 @@ TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) { } llvm_unreachable("unhandled type loc!"); - return QualType(); } /// FIXME: By default, this routine adds type qualifiers only to types @@ -3294,7 +3391,7 @@ TreeTransform<Derived>::TransformTypeInObjectScope(TypeLoc TL, TemplateName Template = getDerived().RebuildTemplateName(SS, *SpecTL.getTypePtr()->getIdentifier(), - SpecTL.getNameLoc(), + SpecTL.getTemplateNameLoc(), ObjectType, UnqualLookup); if (Template.isNull()) return TypeLoc(); @@ -3351,7 +3448,7 @@ TreeTransform<Derived>::TransformTypeInObjectScope(TypeSourceInfo *TSInfo, TemplateName Template = getDerived().RebuildTemplateName(SS, *SpecTL.getTypePtr()->getIdentifier(), - SpecTL.getNameLoc(), + SpecTL.getTemplateNameLoc(), ObjectType, UnqualLookup); if (Template.isNull()) return 0; @@ -3574,15 +3671,21 @@ TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB, if (Result.isNull()) return QualType(); } - - ConstantArrayTypeLoc NewTL = TLB.push<ConstantArrayTypeLoc>(Result); + + // We might have either a ConstantArrayType or a VariableArrayType now: + // a ConstantArrayType is allowed to have an element type which is a + // VariableArrayType if the type is dependent. Fortunately, all array + // types have the same location layout. + ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result); NewTL.setLBracketLoc(TL.getLBracketLoc()); NewTL.setRBracketLoc(TL.getRBracketLoc()); Expr *Size = TL.getSizeExpr(); if (Size) { - EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); + EnterExpressionEvaluationContext Unevaluated(SemaRef, + Sema::ConstantEvaluated); Size = getDerived().TransformExpr(Size).template takeAs<Expr>(); + Size = SemaRef.ActOnConstantExpression(Size).take(); } NewTL.setSizeExpr(Size); @@ -3626,9 +3729,6 @@ TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB, if (ElementType.isNull()) return QualType(); - // Array bounds are not potentially evaluated contexts - EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); - ExprResult SizeResult = getDerived().TransformExpr(T->getSizeExpr()); if (SizeResult.isInvalid()) @@ -3666,8 +3766,9 @@ TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB, if (ElementType.isNull()) return QualType(); - // Array bounds are not potentially evaluated contexts - EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); + // Array bounds are constant expressions. + EnterExpressionEvaluationContext Unevaluated(SemaRef, + Sema::ConstantEvaluated); // Prefer the expression from the TypeLoc; the other may have been uniqued. Expr *origSize = TL.getSizeExpr(); @@ -3675,6 +3776,7 @@ TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB, ExprResult sizeResult = getDerived().TransformExpr(origSize); + sizeResult = SemaRef.ActOnConstantExpression(sizeResult); if (sizeResult.isInvalid()) return QualType(); @@ -3714,10 +3816,12 @@ QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType( if (ElementType.isNull()) return QualType(); - // Vector sizes are not potentially evaluated contexts - EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); + // Vector sizes are constant expressions. + EnterExpressionEvaluationContext Unevaluated(SemaRef, + Sema::ConstantEvaluated); ExprResult Size = getDerived().TransformExpr(T->getSizeExpr()); + Size = SemaRef.ActOnConstantExpression(Size); if (Size.isInvalid()) return QualType(); @@ -3796,12 +3900,14 @@ template<typename Derived> ParmVarDecl * TreeTransform<Derived>::TransformFunctionTypeParam(ParmVarDecl *OldParm, int indexAdjustment, - llvm::Optional<unsigned> NumExpansions) { + llvm::Optional<unsigned> NumExpansions, + bool ExpectParameterPack) { TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo(); TypeSourceInfo *NewDI = 0; if (NumExpansions && isa<PackExpansionType>(OldDI->getType())) { // If we're substituting into a pack expansion type and we know the + // length we want to expand to, just substitute for the pattern. TypeLoc OldTL = OldDI->getTypeLoc(); PackExpansionTypeLoc OldExpansionTL = cast<PackExpansionTypeLoc>(OldTL); @@ -3898,7 +4004,8 @@ bool TreeTransform<Derived>:: ParmVarDecl *NewParm = getDerived().TransformFunctionTypeParam(OldParm, indexAdjustment++, - OrigNumExpansions); + OrigNumExpansions, + /*ExpectParameterPack=*/false); if (!NewParm) return true; @@ -3914,7 +4021,8 @@ bool TreeTransform<Derived>:: ParmVarDecl *NewParm = getDerived().TransformFunctionTypeParam(OldParm, indexAdjustment++, - OrigNumExpansions); + OrigNumExpansions, + /*ExpectParameterPack=*/false); if (!NewParm) return true; @@ -3938,11 +4046,13 @@ bool TreeTransform<Derived>:: Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); NewParm = getDerived().TransformFunctionTypeParam(OldParm, indexAdjustment, - NumExpansions); + NumExpansions, + /*ExpectParameterPack=*/true); } else { NewParm = getDerived().TransformFunctionTypeParam(OldParm, indexAdjustment, - llvm::Optional<unsigned>()); + llvm::Optional<unsigned>(), + /*ExpectParameterPack=*/false); } if (!NewParm) @@ -4096,6 +4206,7 @@ TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB, ParamTypes.data(), ParamTypes.size(), T->isVariadic(), + T->hasTrailingReturn(), T->getTypeQuals(), T->getRefQualifier(), T->getExtInfo()); @@ -4192,6 +4303,10 @@ QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB, if (E.isInvalid()) return QualType(); + E = SemaRef.HandleExprEvaluationContextForTypeof(E.get()); + if (E.isInvalid()) + return QualType(); + QualType Result = TL.getType(); if (getDerived().AlwaysRebuild() || E.get() != TL.getUnderlyingExpr()) { @@ -4239,12 +4354,17 @@ QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB, const DecltypeType *T = TL.getTypePtr(); // decltype expressions are not potentially evaluated contexts - EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); + EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated, 0, + /*IsDecltype=*/ true); ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr()); if (E.isInvalid()) return QualType(); + E = getSema().ActOnDecltypeExpression(E.take()); + if (E.isInvalid()) + return QualType(); + QualType Result = TL.getType(); if (getDerived().AlwaysRebuild() || E.get() != T->getUnderlyingExpr()) { @@ -4549,9 +4669,10 @@ QualType TreeTransform<Derived>::TransformTemplateSpecializationType( if (isa<DependentTemplateSpecializationType>(Result)) { DependentTemplateSpecializationTypeLoc NewTL = TLB.push<DependentTemplateSpecializationTypeLoc>(Result); - NewTL.setKeywordLoc(TL.getTemplateNameLoc()); + NewTL.setElaboratedKeywordLoc(SourceLocation()); NewTL.setQualifierLoc(NestedNameSpecifierLoc()); - NewTL.setNameLoc(TL.getTemplateNameLoc()); + NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); + NewTL.setTemplateNameLoc(TL.getTemplateNameLoc()); NewTL.setLAngleLoc(TL.getLAngleLoc()); NewTL.setRAngleLoc(TL.getRAngleLoc()); for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i) @@ -4561,6 +4682,7 @@ QualType TreeTransform<Derived>::TransformTemplateSpecializationType( TemplateSpecializationTypeLoc NewTL = TLB.push<TemplateSpecializationTypeLoc>(Result); + NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); NewTL.setTemplateNameLoc(TL.getTemplateNameLoc()); NewTL.setLAngleLoc(TL.getLAngleLoc()); NewTL.setRAngleLoc(TL.getRAngleLoc()); @@ -4599,10 +4721,10 @@ QualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType( DependentTemplateSpecializationTypeLoc NewTL = TLB.push<DependentTemplateSpecializationTypeLoc>(Result); - NewTL.setKeywordLoc(TL.getKeywordLoc()); - + NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); NewTL.setQualifierLoc(SS.getWithLocInContext(SemaRef.Context)); - NewTL.setNameLoc(TL.getNameLoc()); + NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); + NewTL.setTemplateNameLoc(TL.getTemplateNameLoc()); NewTL.setLAngleLoc(TL.getLAngleLoc()); NewTL.setRAngleLoc(TL.getRAngleLoc()); for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i) @@ -4612,14 +4734,15 @@ QualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType( QualType Result = getDerived().RebuildTemplateSpecializationType(Template, - TL.getNameLoc(), + TL.getTemplateNameLoc(), NewTemplateArgs); if (!Result.isNull()) { /// FIXME: Wrap this in an elaborated-type-specifier? TemplateSpecializationTypeLoc NewTL = TLB.push<TemplateSpecializationTypeLoc>(Result); - NewTL.setTemplateNameLoc(TL.getNameLoc()); + NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); + NewTL.setTemplateNameLoc(TL.getTemplateNameLoc()); NewTL.setLAngleLoc(TL.getLAngleLoc()); NewTL.setRAngleLoc(TL.getRAngleLoc()); for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i) @@ -4669,7 +4792,7 @@ TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB, if (getDerived().AlwaysRebuild() || QualifierLoc != TL.getQualifierLoc() || NamedT != T->getNamedType()) { - Result = getDerived().RebuildElaboratedType(TL.getKeywordLoc(), + Result = getDerived().RebuildElaboratedType(TL.getElaboratedKeywordLoc(), T->getKeyword(), QualifierLoc, NamedT); if (Result.isNull()) @@ -4677,7 +4800,7 @@ TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB, } ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result); - NewTL.setKeywordLoc(TL.getKeywordLoc()); + NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); NewTL.setQualifierLoc(QualifierLoc); return Result; } @@ -4753,7 +4876,7 @@ QualType TreeTransform<Derived>::TransformDependentNameType(TypeLocBuilder &TLB, QualType Result = getDerived().RebuildDependentNameType(T->getKeyword(), - TL.getKeywordLoc(), + TL.getElaboratedKeywordLoc(), QualifierLoc, T->getIdentifier(), TL.getNameLoc()); @@ -4765,11 +4888,11 @@ QualType TreeTransform<Derived>::TransformDependentNameType(TypeLocBuilder &TLB, TLB.pushTypeSpec(NamedT).setNameLoc(TL.getNameLoc()); ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result); - NewTL.setKeywordLoc(TL.getKeywordLoc()); + NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); NewTL.setQualifierLoc(QualifierLoc); } else { DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result); - NewTL.setKeywordLoc(TL.getKeywordLoc()); + NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); NewTL.setQualifierLoc(QualifierLoc); NewTL.setNameLoc(TL.getNameLoc()); } @@ -4814,7 +4937,7 @@ TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB, = getDerived().RebuildDependentTemplateSpecializationType(T->getKeyword(), QualifierLoc, T->getIdentifier(), - TL.getNameLoc(), + TL.getTemplateNameLoc(), NewTemplateArgs); if (Result.isNull()) return QualType(); @@ -4825,7 +4948,8 @@ TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB, // Copy information relevant to the template specialization. TemplateSpecializationTypeLoc NamedTL = TLB.push<TemplateSpecializationTypeLoc>(NamedT); - NamedTL.setTemplateNameLoc(TL.getNameLoc()); + NamedTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); + NamedTL.setTemplateNameLoc(TL.getTemplateNameLoc()); NamedTL.setLAngleLoc(TL.getLAngleLoc()); NamedTL.setRAngleLoc(TL.getRAngleLoc()); for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I) @@ -4833,14 +4957,15 @@ TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB, // Copy information relevant to the elaborated type. ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result); - NewTL.setKeywordLoc(TL.getKeywordLoc()); + NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); NewTL.setQualifierLoc(QualifierLoc); } else if (isa<DependentTemplateSpecializationType>(Result)) { DependentTemplateSpecializationTypeLoc SpecTL = TLB.push<DependentTemplateSpecializationTypeLoc>(Result); - SpecTL.setKeywordLoc(TL.getKeywordLoc()); + SpecTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); SpecTL.setQualifierLoc(QualifierLoc); - SpecTL.setNameLoc(TL.getNameLoc()); + SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); + SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc()); SpecTL.setLAngleLoc(TL.getLAngleLoc()); SpecTL.setRAngleLoc(TL.getRAngleLoc()); for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I) @@ -4848,7 +4973,8 @@ TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB, } else { TemplateSpecializationTypeLoc SpecTL = TLB.push<TemplateSpecializationTypeLoc>(Result); - SpecTL.setTemplateNameLoc(TL.getNameLoc()); + SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); + SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc()); SpecTL.setLAngleLoc(TL.getLAngleLoc()); SpecTL.setRAngleLoc(TL.getRAngleLoc()); for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I) @@ -4927,6 +5053,8 @@ template<typename Derived> StmtResult TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr) { + Sema::CompoundScopeRAII CompoundScope(getSema()); + bool SubStmtInvalid = false; bool SubStmtChanged = false; ASTOwningVector<Stmt*> Statements(getSema()); @@ -4966,16 +5094,18 @@ StmtResult TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) { ExprResult LHS, RHS; { - // The case value expressions are not potentially evaluated. - EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); + EnterExpressionEvaluationContext Unevaluated(SemaRef, + Sema::ConstantEvaluated); // Transform the left-hand case value. LHS = getDerived().TransformExpr(S->getLHS()); + LHS = SemaRef.ActOnConstantExpression(LHS); if (LHS.isInvalid()) return StmtError(); // Transform the right-hand case value (for the GNU case-range extension). RHS = getDerived().TransformExpr(S->getRHS()); + RHS = SemaRef.ActOnConstantExpression(RHS); if (RHS.isInvalid()) return StmtError(); } @@ -5284,6 +5414,7 @@ TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) { ExprResult Target = getDerived().TransformExpr(S->getTarget()); if (Target.isInvalid()) return StmtError(); + Target = SemaRef.MaybeCreateExprWithCleanups(Target.take()); if (!getDerived().AlwaysRebuild() && Target.get() == S->getTarget()) @@ -5696,10 +5827,18 @@ TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) { ExprResult Cond = getDerived().TransformExpr(S->getCond()); if (Cond.isInvalid()) return StmtError(); + if (Cond.get()) + Cond = SemaRef.CheckBooleanCondition(Cond.take(), S->getColonLoc()); + if (Cond.isInvalid()) + return StmtError(); + if (Cond.get()) + Cond = SemaRef.MaybeCreateExprWithCleanups(Cond.take()); ExprResult Inc = getDerived().TransformExpr(S->getInc()); if (Inc.isInvalid()) return StmtError(); + if (Inc.get()) + Inc = SemaRef.MaybeCreateExprWithCleanups(Inc.take()); StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt()); if (LoopVar.isInvalid()) @@ -5739,6 +5878,75 @@ TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) { template<typename Derived> StmtResult +TreeTransform<Derived>::TransformMSDependentExistsStmt( + MSDependentExistsStmt *S) { + // Transform the nested-name-specifier, if any. + NestedNameSpecifierLoc QualifierLoc; + if (S->getQualifierLoc()) { + QualifierLoc + = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc()); + if (!QualifierLoc) + return StmtError(); + } + + // Transform the declaration name. + DeclarationNameInfo NameInfo = S->getNameInfo(); + if (NameInfo.getName()) { + NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo); + if (!NameInfo.getName()) + return StmtError(); + } + + // Check whether anything changed. + if (!getDerived().AlwaysRebuild() && + QualifierLoc == S->getQualifierLoc() && + NameInfo.getName() == S->getNameInfo().getName()) + return S; + + // Determine whether this name exists, if we can. + CXXScopeSpec SS; + SS.Adopt(QualifierLoc); + bool Dependent = false; + switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/0, SS, NameInfo)) { + case Sema::IER_Exists: + if (S->isIfExists()) + break; + + return new (getSema().Context) NullStmt(S->getKeywordLoc()); + + case Sema::IER_DoesNotExist: + if (S->isIfNotExists()) + break; + + return new (getSema().Context) NullStmt(S->getKeywordLoc()); + + case Sema::IER_Dependent: + Dependent = true; + break; + + case Sema::IER_Error: + return StmtError(); + } + + // We need to continue with the instantiation, so do so now. + StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt()); + if (SubStmt.isInvalid()) + return StmtError(); + + // If we have resolved the name, just transform to the substatement. + if (!Dependent) + return SubStmt; + + // The name is still dependent, so build a dependent expression again. + return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(), + S->isIfExists(), + QualifierLoc, + NameInfo, + SubStmt.get()); +} + +template<typename Derived> +StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) { StmtResult TryBlock; // = getDerived().TransformCompoundStmt(S->getTryBlock()); if(TryBlock.isInvalid()) return StmtError(); @@ -5829,7 +6037,7 @@ TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) { // Mark it referenced in the new context regardless. // FIXME: this is a bit instantiation-specific. - SemaRef.MarkDeclarationReferenced(E->getLocation(), ND); + SemaRef.MarkDeclRefReferenced(E); return SemaRef.Owned(E); } @@ -5881,6 +6089,12 @@ TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) { template<typename Derived> ExprResult +TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) { + return SemaRef.MaybeBindToTemporary(E); +} + +template<typename Derived> +ExprResult TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) { ExprResult ControllingExpr = getDerived().TransformExpr(E->getControllingExpr()); @@ -6020,6 +6234,28 @@ TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) { template<typename Derived> ExprResult +TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) { + // Rebuild the syntactic form. The original syntactic form has + // opaque-value expressions in it, so strip those away and rebuild + // the result. This is a really awful way of doing this, but the + // better solution (rebuilding the semantic expressions and + // rebinding OVEs as necessary) doesn't work; we'd need + // TreeTransform to not strip away implicit conversions. + Expr *newSyntacticForm = SemaRef.recreateSyntacticForm(E); + ExprResult result = getDerived().TransformExpr(newSyntacticForm); + if (result.isInvalid()) return ExprError(); + + // If that gives us a pseudo-object result back, the pseudo-object + // expression must have been an lvalue-to-rvalue conversion which we + // should reapply. + if (result.get()->hasPlaceholderType(BuiltinType::PseudoObject)) + result = SemaRef.checkPseudoObjectRValue(result.take()); + + return result; +} + +template<typename Derived> +ExprResult TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr( UnaryExprOrTypeTraitExpr *E) { if (E->isArgumentType()) { @@ -6037,20 +6273,17 @@ TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr( E->getSourceRange()); } - ExprResult SubExpr; - { - // C++0x [expr.sizeof]p1: - // The operand is either an expression, which is an unevaluated operand - // [...] - EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); + // C++0x [expr.sizeof]p1: + // The operand is either an expression, which is an unevaluated operand + // [...] + EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); - SubExpr = getDerived().TransformExpr(E->getArgumentExpr()); - if (SubExpr.isInvalid()) - return ExprError(); + ExprResult SubExpr = getDerived().TransformExpr(E->getArgumentExpr()); + if (SubExpr.isInvalid()) + return ExprError(); - if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr()) - return SemaRef.Owned(E); - } + if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr()) + return SemaRef.Owned(E); return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(), E->getOperatorLoc(), @@ -6099,7 +6332,7 @@ TreeTransform<Derived>::TransformCallExpr(CallExpr *E) { if (!getDerived().AlwaysRebuild() && Callee.get() == E->getCallee() && !ArgChanged) - return SemaRef.Owned(E); + return SemaRef.MaybeBindToTemporary(E);; // FIXME: Wrong source location information for the '('. SourceLocation FakeLParenLoc @@ -6124,6 +6357,7 @@ TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) { if (!QualifierLoc) return ExprError(); } + SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc(); ValueDecl *Member = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(), @@ -6150,7 +6384,8 @@ TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) { // Mark it referenced in the new context regardless. // FIXME: this is a bit instantiation-specific. - SemaRef.MarkDeclarationReferenced(E->getMemberLoc(), Member); + SemaRef.MarkMemberReferenced(E); + return SemaRef.Owned(E); } @@ -6177,6 +6412,7 @@ TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) { return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc, E->isArrow(), QualifierLoc, + TemplateKWLoc, E->getMemberNameInfo(), Member, FoundDecl, @@ -6312,7 +6548,7 @@ TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) { if (!getDerived().AlwaysRebuild() && OldT == NewT && Init.get() == E->getInitializer()) - return SemaRef.Owned(E); + return SemaRef.MaybeBindToTemporary(E); // Note: the expression type doesn't necessarily match the // type-as-written, but that's okay, because it should always be @@ -6500,14 +6736,20 @@ TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) { template<typename Derived> ExprResult TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) { + SemaRef.ActOnStartStmtExpr(); StmtResult SubStmt = getDerived().TransformCompoundStmt(E->getSubStmt(), true); - if (SubStmt.isInvalid()) + if (SubStmt.isInvalid()) { + SemaRef.ActOnStmtExprError(); return ExprError(); + } if (!getDerived().AlwaysRebuild() && - SubStmt.get() == E->getSubStmt()) - return SemaRef.Owned(E); + 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(), @@ -6555,7 +6797,6 @@ TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) { case OO_Array_New: case OO_Array_Delete: llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr"); - return ExprError(); case OO_Call: { // This is a call to an object's operator(). @@ -6592,12 +6833,10 @@ TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) { case OO_Conditional: llvm_unreachable("conditional operator is not actually overloadable"); - return ExprError(); case OO_None: case NUM_OVERLOADED_OPERATORS: llvm_unreachable("not an overloaded operator?"); - return ExprError(); } ExprResult Callee = getDerived().TransformExpr(E->getCallee()); @@ -6619,7 +6858,7 @@ TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) { Callee.get() == E->getCallee() && First.get() == E->getArg(0) && (E->getNumArgs() != 2 || Second.get() == E->getArg(1))) - return SemaRef.Owned(E); + return SemaRef.MaybeBindToTemporary(E); return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(), E->getOperatorLoc(), @@ -6657,7 +6896,7 @@ TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) { if (!getDerived().AlwaysRebuild() && Callee.get() == E->getCallee() && !ArgChanged) - return SemaRef.Owned(E); + return SemaRef.MaybeBindToTemporary(E); // FIXME: Wrong source location information for the '('. SourceLocation FakeLParenLoc @@ -6769,11 +7008,11 @@ TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) { E->getLocEnd()); } - // We don't know whether the expression is potentially evaluated until - // after we perform semantic analysis, so the expression is potentially + // We don't know whether the subexpression is potentially evaluated until + // after we perform semantic analysis. We speculatively assume it is + // unevaluated; it will get fixed later if the subexpression is in fact // potentially evaluated. - EnterExpressionEvaluationContext Unevaluated(SemaRef, - Sema::PotentiallyPotentiallyEvaluated); + EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand()); if (SubExpr.isInvalid()) @@ -6808,9 +7047,6 @@ TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) { E->getLocEnd()); } - // We don't know whether the expression is potentially evaluated until - // after we perform semantic analysis, so the expression is potentially - // potentially evaluated. EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand()); @@ -6851,9 +7087,12 @@ TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) { T = getSema().Context.getPointerType( getSema().Context.getRecordType(cast<CXXRecordDecl>(DC))); - if (!getDerived().AlwaysRebuild() && T == E->getType()) + if (!getDerived().AlwaysRebuild() && T == E->getType()) { + // Make sure that we capture 'this'. + getSema().CheckCXXThisCapture(E->getLocStart()); return SemaRef.Owned(E); - + } + return getDerived().RebuildCXXThisExpr(E->getLocStart(), T, E->isImplicit()); } @@ -6925,24 +7164,17 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) { if (getDerived().TransformExprs(E->getPlacementArgs(), E->getNumPlacementArgs(), true, PlacementArgs, &ArgumentChanged)) - return ExprError(); - - // transform the constructor arguments (if any). - ASTOwningVector<Expr*> ConstructorArgs(SemaRef); - if (TransformExprs(E->getConstructorArgs(), E->getNumConstructorArgs(), true, - ConstructorArgs, &ArgumentChanged)) - return ExprError(); - - // Transform constructor, new operator, and delete operator. - CXXConstructorDecl *Constructor = 0; - if (E->getConstructor()) { - Constructor = cast_or_null<CXXConstructorDecl>( - getDerived().TransformDecl(E->getLocStart(), - E->getConstructor())); - if (!Constructor) - return ExprError(); - } + return ExprError(); + // Transform the initializer (if any). + Expr *OldInit = E->getInitializer(); + ExprResult NewInit; + if (OldInit) + NewInit = getDerived().TransformExpr(OldInit); + if (NewInit.isInvalid()) + return ExprError(); + + // Transform new operator and delete operator. FunctionDecl *OperatorNew = 0; if (E->getOperatorNew()) { OperatorNew = cast_or_null<FunctionDecl>( @@ -6964,31 +7196,28 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) { if (!getDerived().AlwaysRebuild() && AllocTypeInfo == E->getAllocatedTypeSourceInfo() && ArraySize.get() == E->getArraySize() && - Constructor == E->getConstructor() && + NewInit.get() == OldInit && OperatorNew == E->getOperatorNew() && OperatorDelete == E->getOperatorDelete() && !ArgumentChanged) { // Mark any declarations we need as referenced. // FIXME: instantiation-specific. - if (Constructor) - SemaRef.MarkDeclarationReferenced(E->getLocStart(), Constructor); if (OperatorNew) - SemaRef.MarkDeclarationReferenced(E->getLocStart(), OperatorNew); + SemaRef.MarkFunctionReferenced(E->getLocStart(), OperatorNew); if (OperatorDelete) - SemaRef.MarkDeclarationReferenced(E->getLocStart(), OperatorDelete); + SemaRef.MarkFunctionReferenced(E->getLocStart(), OperatorDelete); - if (E->isArray() && Constructor && - !E->getAllocatedType()->isDependentType()) { + if (E->isArray() && !E->getAllocatedType()->isDependentType()) { QualType ElementType = SemaRef.Context.getBaseElementType(E->getAllocatedType()); if (const RecordType *RecordT = ElementType->getAs<RecordType>()) { CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordT->getDecl()); if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Record)) { - SemaRef.MarkDeclarationReferenced(E->getLocStart(), Destructor); + SemaRef.MarkFunctionReferenced(E->getLocStart(), Destructor); } } } - + return SemaRef.Owned(E); } @@ -7018,7 +7247,7 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) { } } } - + return getDerived().RebuildCXXNewExpr(E->getLocStart(), E->isGlobalNew(), /*FIXME:*/E->getLocStart(), @@ -7028,13 +7257,8 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) { AllocType, AllocTypeInfo, ArraySize.get(), - /*FIXME:*/E->hasInitializer() - ? E->getLocStart() - : SourceLocation(), - move_arg(ConstructorArgs), - /*FIXME:*/E->hasInitializer() - ? E->getLocEnd() - : SourceLocation()); + E->getDirectInitRange(), + NewInit.take()); } template<typename Derived> @@ -7060,15 +7284,15 @@ TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) { // Mark any declarations we need as referenced. // FIXME: instantiation-specific. if (OperatorDelete) - SemaRef.MarkDeclarationReferenced(E->getLocStart(), OperatorDelete); + SemaRef.MarkFunctionReferenced(E->getLocStart(), OperatorDelete); if (!E->getArgument()->isTypeDependent()) { QualType Destroyed = SemaRef.Context.getBaseElementType( E->getDestroyedType()); if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) { CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl()); - SemaRef.MarkDeclarationReferenced(E->getLocStart(), - SemaRef.LookupDestructor(Record)); + SemaRef.MarkFunctionReferenced(E->getLocStart(), + SemaRef.LookupDestructor(Record)); } } @@ -7118,7 +7342,7 @@ TreeTransform<Derived>::TransformCXXPseudoDestructorExpr( if (!DestroyedTypeInfo) return ExprError(); Destroyed = DestroyedTypeInfo; - } else if (ObjectType->isDependentType()) { + } else if (!ObjectType.isNull() && ObjectType->isDependentType()) { // We aren't likely to be able to resolve the identifier down to a type // now anyway, so just retain the identifier. Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(), @@ -7216,8 +7440,11 @@ TreeTransform<Derived>::TransformUnresolvedLookupExpr( R.setNamingClass(NamingClass); } - // If we have no template arguments, it's a normal declaration name. - if (!Old->hasExplicitTemplateArgs()) + SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc(); + + // If we have neither explicit template arguments, nor the template keyword, + // it's a normal declaration name. + if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid()) return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL()); // If we have template arguments, rebuild them, then rebuild the @@ -7228,8 +7455,8 @@ TreeTransform<Derived>::TransformUnresolvedLookupExpr( TransArgs)) return ExprError(); - return getDerived().RebuildTemplateIdExpr(SS, R, Old->requiresADL(), - TransArgs); + return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R, + Old->requiresADL(), &TransArgs); } template<typename Derived> @@ -7272,6 +7499,128 @@ TreeTransform<Derived>::TransformBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) { template<typename Derived> ExprResult +TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) { + bool ArgChanged = false; + llvm::SmallVector<TypeSourceInfo *, 4> Args; + for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) { + TypeSourceInfo *From = E->getArg(I); + TypeLoc FromTL = From->getTypeLoc(); + if (!isa<PackExpansionTypeLoc>(FromTL)) { + TypeLocBuilder TLB; + TLB.reserve(FromTL.getFullDataSize()); + QualType To = getDerived().TransformType(TLB, FromTL); + if (To.isNull()) + return ExprError(); + + if (To == From->getType()) + Args.push_back(From); + else { + Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To)); + ArgChanged = true; + } + continue; + } + + ArgChanged = true; + + // We have a pack expansion. Instantiate it. + PackExpansionTypeLoc ExpansionTL = cast<PackExpansionTypeLoc>(FromTL); + TypeLoc PatternTL = ExpansionTL.getPatternLoc(); + SmallVector<UnexpandedParameterPack, 2> Unexpanded; + SemaRef.collectUnexpandedParameterPacks(PatternTL, Unexpanded); + + // Determine whether the set of unexpanded parameter packs can and should + // be expanded. + bool Expand = true; + bool RetainExpansion = false; + llvm::Optional<unsigned> OrigNumExpansions + = ExpansionTL.getTypePtr()->getNumExpansions(); + llvm::Optional<unsigned> NumExpansions = OrigNumExpansions; + if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(), + PatternTL.getSourceRange(), + Unexpanded, + Expand, RetainExpansion, + NumExpansions)) + return ExprError(); + + if (!Expand) { + // The transform has determined that we should perform a simple + // transformation on the pack expansion, producing another pack + // expansion. + Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); + + TypeLocBuilder TLB; + TLB.reserve(From->getTypeLoc().getFullDataSize()); + + QualType To = getDerived().TransformType(TLB, PatternTL); + if (To.isNull()) + return ExprError(); + + To = getDerived().RebuildPackExpansionType(To, + PatternTL.getSourceRange(), + ExpansionTL.getEllipsisLoc(), + NumExpansions); + if (To.isNull()) + return ExprError(); + + PackExpansionTypeLoc ToExpansionTL + = TLB.push<PackExpansionTypeLoc>(To); + ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc()); + Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To)); + continue; + } + + // Expand the pack expansion by substituting for each argument in the + // pack(s). + for (unsigned I = 0; I != *NumExpansions; ++I) { + Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I); + TypeLocBuilder TLB; + TLB.reserve(PatternTL.getFullDataSize()); + QualType To = getDerived().TransformType(TLB, PatternTL); + if (To.isNull()) + return ExprError(); + + Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To)); + } + + if (!RetainExpansion) + continue; + + // If we're supposed to retain a pack expansion, do so by temporarily + // forgetting the partially-substituted parameter pack. + ForgetPartiallySubstitutedPackRAII Forget(getDerived()); + + TypeLocBuilder TLB; + TLB.reserve(From->getTypeLoc().getFullDataSize()); + + QualType To = getDerived().TransformType(TLB, PatternTL); + if (To.isNull()) + return ExprError(); + + To = getDerived().RebuildPackExpansionType(To, + PatternTL.getSourceRange(), + ExpansionTL.getEllipsisLoc(), + NumExpansions); + if (To.isNull()) + return ExprError(); + + PackExpansionTypeLoc ToExpansionTL + = TLB.push<PackExpansionTypeLoc>(To); + ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc()); + Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To)); + } + + if (!getDerived().AlwaysRebuild() && !ArgChanged) + return SemaRef.Owned(E); + + return getDerived().RebuildTypeTrait(E->getTrait(), + E->getLocStart(), + Args, + E->getLocEnd()); +} + +template<typename Derived> +ExprResult TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) { TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo()); if (!T) @@ -7325,6 +7674,7 @@ TreeTransform<Derived>::TransformDependentScopeDeclRefExpr( = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc()); if (!QualifierLoc) return ExprError(); + SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc(); // TODO: If this is a conversion-function-id, verify that the // destination type name (if present) resolves the same way after @@ -7344,6 +7694,7 @@ TreeTransform<Derived>::TransformDependentScopeDeclRefExpr( return SemaRef.Owned(E); return getDerived().RebuildDependentScopeDeclRefExpr(QualifierLoc, + TemplateKWLoc, NameInfo, /*TemplateArgs*/ 0); } @@ -7355,6 +7706,7 @@ TreeTransform<Derived>::TransformDependentScopeDeclRefExpr( return ExprError(); return getDerived().RebuildDependentScopeDeclRefExpr(QualifierLoc, + TemplateKWLoc, NameInfo, &TransArgs); } @@ -7393,7 +7745,7 @@ TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) { !ArgumentChanged) { // Mark the constructor as referenced. // FIXME: Instantiation-specific - SemaRef.MarkDeclarationReferenced(E->getLocStart(), Constructor); + SemaRef.MarkFunctionReferenced(E->getLocStart(), Constructor); return SemaRef.Owned(E); } @@ -7454,7 +7806,7 @@ TreeTransform<Derived>::TransformCXXTemporaryObjectExpr( Constructor == E->getConstructor() && !ArgumentChanged) { // FIXME: Instantiation-specific - SemaRef.MarkDeclarationReferenced(E->getLocStart(), Constructor); + SemaRef.MarkFunctionReferenced(E->getLocStart(), Constructor); return SemaRef.MaybeBindToTemporary(E); } @@ -7466,6 +7818,158 @@ TreeTransform<Derived>::TransformCXXTemporaryObjectExpr( template<typename Derived> ExprResult +TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) { + // Create the local class that will describe the lambda. + CXXRecordDecl *Class + = getSema().createLambdaClosureType(E->getIntroducerRange(), + /*KnownDependent=*/false); + getDerived().transformedLocalDecl(E->getLambdaClass(), Class); + + // Transform the type of the lambda parameters and start the definition of + // the lambda itself. + TypeSourceInfo *MethodTy + = TransformType(E->getCallOperator()->getTypeSourceInfo()); + if (!MethodTy) + return ExprError(); + + // Transform lambda parameters. + bool Invalid = false; + llvm::SmallVector<QualType, 4> ParamTypes; + llvm::SmallVector<ParmVarDecl *, 4> Params; + if (getDerived().TransformFunctionTypeParams(E->getLocStart(), + E->getCallOperator()->param_begin(), + E->getCallOperator()->param_size(), + 0, ParamTypes, &Params)) + Invalid = true; + + // Build the call operator. + // Note: Once a lambda mangling number and context declaration have been + // assigned, they never change. + unsigned ManglingNumber = E->getLambdaClass()->getLambdaManglingNumber(); + Decl *ContextDecl = E->getLambdaClass()->getLambdaContextDecl(); + CXXMethodDecl *CallOperator + = getSema().startLambdaDefinition(Class, E->getIntroducerRange(), + MethodTy, + E->getCallOperator()->getLocEnd(), + Params, ManglingNumber, ContextDecl); + getDerived().transformAttrs(E->getCallOperator(), CallOperator); + + // FIXME: Instantiation-specific. + CallOperator->setInstantiationOfMemberFunction(E->getCallOperator(), + TSK_ImplicitInstantiation); + + // Introduce the context of the call operator. + Sema::ContextRAII SavedContext(getSema(), CallOperator); + + // Enter the scope of the lambda. + sema::LambdaScopeInfo *LSI + = getSema().enterLambdaScope(CallOperator, E->getIntroducerRange(), + E->getCaptureDefault(), + E->hasExplicitParameters(), + E->hasExplicitResultType(), + E->isMutable()); + + // Transform captures. + bool FinishedExplicitCaptures = false; + for (LambdaExpr::capture_iterator C = E->capture_begin(), + CEnd = E->capture_end(); + C != CEnd; ++C) { + // When we hit the first implicit capture, tell Sema that we've finished + // the list of explicit captures. + if (!FinishedExplicitCaptures && C->isImplicit()) { + getSema().finishLambdaExplicitCaptures(LSI); + FinishedExplicitCaptures = true; + } + + // Capturing 'this' is trivial. + if (C->capturesThis()) { + getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit()); + continue; + } + + // Determine the capture kind for Sema. + Sema::TryCaptureKind Kind + = C->isImplicit()? Sema::TryCapture_Implicit + : C->getCaptureKind() == LCK_ByCopy + ? Sema::TryCapture_ExplicitByVal + : Sema::TryCapture_ExplicitByRef; + SourceLocation EllipsisLoc; + if (C->isPackExpansion()) { + UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation()); + bool ShouldExpand = false; + bool RetainExpansion = false; + llvm::Optional<unsigned> NumExpansions; + if (getDerived().TryExpandParameterPacks(C->getEllipsisLoc(), + C->getLocation(), + Unexpanded, + ShouldExpand, RetainExpansion, + NumExpansions)) + return ExprError(); + + if (ShouldExpand) { + // The transform has determined that we should perform an expansion; + // transform and capture each of the arguments. + // expansion of the pattern. Do so. + VarDecl *Pack = C->getCapturedVar(); + for (unsigned I = 0; I != *NumExpansions; ++I) { + Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I); + VarDecl *CapturedVar + = cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(), + Pack)); + if (!CapturedVar) { + Invalid = true; + continue; + } + + // Capture the transformed variable. + getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind); + } + continue; + } + + EllipsisLoc = C->getEllipsisLoc(); + } + + // Transform the captured variable. + VarDecl *CapturedVar + = cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(), + C->getCapturedVar())); + if (!CapturedVar) { + Invalid = true; + continue; + } + + // Capture the transformed variable. + getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind); + } + if (!FinishedExplicitCaptures) + getSema().finishLambdaExplicitCaptures(LSI); + + + // Enter a new evaluation context to insulate the lambda from any + // cleanups from the enclosing full-expression. + getSema().PushExpressionEvaluationContext(Sema::PotentiallyEvaluated); + + if (Invalid) { + getSema().ActOnLambdaError(E->getLocStart(), /*CurScope=*/0, + /*IsInstantiation=*/true); + return ExprError(); + } + + // Instantiate the body of the lambda expression. + StmtResult Body = getDerived().TransformStmt(E->getBody()); + if (Body.isInvalid()) { + getSema().ActOnLambdaError(E->getLocStart(), /*CurScope=*/0, + /*IsInstantiation=*/true); + return ExprError(); + } + + return getSema().ActOnLambdaExpr(E->getLocStart(), Body.take(), + /*CurScope=*/0, /*IsInstantiation=*/true); +} + +template<typename Derived> +ExprResult TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr( CXXUnresolvedConstructExpr *E) { TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo()); @@ -7542,6 +8046,8 @@ TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr( return ExprError(); } + SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc(); + // TODO: If this is a conversion-function-id, verify that the // destination type name (if present) resolves the same way after // instantiation as it did in the local scope. @@ -7567,6 +8073,7 @@ TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr( E->isArrow(), E->getOperatorLoc(), QualifierLoc, + TemplateKWLoc, FirstQualifierInScope, NameInfo, /*TemplateArgs*/ 0); @@ -7583,6 +8090,7 @@ TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr( E->isArrow(), E->getOperatorLoc(), QualifierLoc, + TemplateKWLoc, FirstQualifierInScope, NameInfo, &TransArgs); @@ -7598,7 +8106,11 @@ TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old) Base = getDerived().TransformExpr(Old->getBase()); if (Base.isInvalid()) return ExprError(); - BaseType = ((Expr*) Base.get())->getType(); + Base = getSema().PerformMemberExprBaseConversion(Base.take(), + Old->isArrow()); + if (Base.isInvalid()) + return ExprError(); + BaseType = Base.get()->getType(); } else { BaseType = getDerived().TransformType(Old->getBaseType()); } @@ -7611,6 +8123,8 @@ TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old) return ExprError(); } + SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc(); + LookupResult R(SemaRef, Old->getMemberNameInfo(), Sema::LookupOrdinaryName); @@ -7678,6 +8192,7 @@ TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old) Old->getOperatorLoc(), Old->isArrow(), QualifierLoc, + TemplateKWLoc, FirstQualifierInScope, R, (Old->hasExplicitTemplateArgs() @@ -7778,11 +8293,163 @@ TreeTransform<Derived>::TransformMaterializeTemporaryExpr( template<typename Derived> ExprResult TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) { + return SemaRef.MaybeBindToTemporary(E); +} + +template<typename Derived> +ExprResult +TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) { return SemaRef.Owned(E); } template<typename Derived> ExprResult +TreeTransform<Derived>::TransformObjCNumericLiteral(ObjCNumericLiteral *E) { + return SemaRef.MaybeBindToTemporary(E); +} + +template<typename Derived> +ExprResult +TreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) { + // Transform each of the elements. + llvm::SmallVector<Expr *, 8> Elements; + bool ArgChanged = false; + if (getDerived().TransformExprs(E->getElements(), E->getNumElements(), + /*IsCall=*/false, Elements, &ArgChanged)) + return ExprError(); + + if (!getDerived().AlwaysRebuild() && !ArgChanged) + return SemaRef.MaybeBindToTemporary(E); + + return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(), + Elements.data(), + Elements.size()); +} + +template<typename Derived> +ExprResult +TreeTransform<Derived>::TransformObjCDictionaryLiteral( + ObjCDictionaryLiteral *E) { + // Transform each of the elements. + llvm::SmallVector<ObjCDictionaryElement, 8> Elements; + bool ArgChanged = false; + for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) { + ObjCDictionaryElement OrigElement = E->getKeyValueElement(I); + + if (OrigElement.isPackExpansion()) { + // This key/value element is a pack expansion. + SmallVector<UnexpandedParameterPack, 2> Unexpanded; + getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded); + getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded); + assert(!Unexpanded.empty() && "Pack expansion without parameter packs?"); + + // Determine whether the set of unexpanded parameter packs can + // and should be expanded. + bool Expand = true; + bool RetainExpansion = false; + llvm::Optional<unsigned> OrigNumExpansions = OrigElement.NumExpansions; + llvm::Optional<unsigned> NumExpansions = OrigNumExpansions; + SourceRange PatternRange(OrigElement.Key->getLocStart(), + OrigElement.Value->getLocEnd()); + if (getDerived().TryExpandParameterPacks(OrigElement.EllipsisLoc, + PatternRange, + Unexpanded, + Expand, RetainExpansion, + NumExpansions)) + return ExprError(); + + if (!Expand) { + // The transform has determined that we should perform a simple + // transformation on the pack expansion, producing another pack + // expansion. + Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); + ExprResult Key = getDerived().TransformExpr(OrigElement.Key); + if (Key.isInvalid()) + return ExprError(); + + if (Key.get() != OrigElement.Key) + ArgChanged = true; + + ExprResult Value = getDerived().TransformExpr(OrigElement.Value); + if (Value.isInvalid()) + return ExprError(); + + if (Value.get() != OrigElement.Value) + ArgChanged = true; + + ObjCDictionaryElement Expansion = { + Key.get(), Value.get(), OrigElement.EllipsisLoc, NumExpansions + }; + Elements.push_back(Expansion); + continue; + } + + // Record right away that the argument was changed. This needs + // to happen even if the array expands to nothing. + ArgChanged = true; + + // The transform has determined that we should perform an elementwise + // expansion of the pattern. Do so. + for (unsigned I = 0; I != *NumExpansions; ++I) { + Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I); + ExprResult Key = getDerived().TransformExpr(OrigElement.Key); + if (Key.isInvalid()) + return ExprError(); + + ExprResult Value = getDerived().TransformExpr(OrigElement.Value); + if (Value.isInvalid()) + return ExprError(); + + ObjCDictionaryElement Element = { + Key.get(), Value.get(), SourceLocation(), NumExpansions + }; + + // If any unexpanded parameter packs remain, we still have a + // pack expansion. + if (Key.get()->containsUnexpandedParameterPack() || + Value.get()->containsUnexpandedParameterPack()) + Element.EllipsisLoc = OrigElement.EllipsisLoc; + + Elements.push_back(Element); + } + + // We've finished with this pack expansion. + continue; + } + + // Transform and check key. + ExprResult Key = getDerived().TransformExpr(OrigElement.Key); + if (Key.isInvalid()) + return ExprError(); + + if (Key.get() != OrigElement.Key) + ArgChanged = true; + + // Transform and check value. + ExprResult Value + = getDerived().TransformExpr(OrigElement.Value); + if (Value.isInvalid()) + return ExprError(); + + if (Value.get() != OrigElement.Value) + ArgChanged = true; + + ObjCDictionaryElement Element = { + Key.get(), Value.get(), SourceLocation(), llvm::Optional<unsigned>() + }; + Elements.push_back(Element); + } + + if (!getDerived().AlwaysRebuild() && !ArgChanged) + return SemaRef.MaybeBindToTemporary(E); + + return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(), + Elements.data(), + Elements.size()); +} + +template<typename Derived> +ExprResult TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) { TypeSourceInfo *EncodedTypeInfo = getDerived().TransformType(E->getEncodedTypeSourceInfo()); @@ -7856,7 +8523,7 @@ TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) { // If nothing changed, just retain the existing message send. if (!getDerived().AlwaysRebuild() && ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged) - return SemaRef.Owned(E); + return SemaRef.MaybeBindToTemporary(E); // Build a new class message send. SmallVector<SourceLocation, 16> SelLocs; @@ -7881,7 +8548,7 @@ TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) { // If nothing changed, just retain the existing message send. if (!getDerived().AlwaysRebuild() && Receiver.get() == E->getInstanceReceiver() && !ArgChanged) - return SemaRef.Owned(E); + return SemaRef.MaybeBindToTemporary(E); // Build a new instance message send. SmallVector<SourceLocation, 16> SelLocs; @@ -7953,7 +8620,7 @@ TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { E->getLocation()); return getDerived().RebuildObjCPropertyRefExpr(Base.get(), - E->getType(), + SemaRef.Context.PseudoObjectTy, E->getImplicitPropertyGetter(), E->getImplicitPropertySetter(), E->getLocation()); @@ -7961,6 +8628,30 @@ TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { template<typename Derived> ExprResult +TreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) { + // Transform the base expression. + ExprResult Base = getDerived().TransformExpr(E->getBaseExpr()); + if (Base.isInvalid()) + return ExprError(); + + // Transform the key expression. + ExprResult Key = getDerived().TransformExpr(E->getKeyExpr()); + if (Key.isInvalid()) + return ExprError(); + + // If nothing changed, just retain the existing expression. + if (!getDerived().AlwaysRebuild() && + Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr()) + return SemaRef.Owned(E); + + return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(), + Base.get(), Key.get(), + E->getAtIndexMethodDecl(), + E->setAtIndexMethodDecl()); +} + +template<typename Derived> +ExprResult TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) { // Transform the base expression. ExprResult Base = getDerived().TransformExpr(E->getBase()); @@ -8004,10 +8695,8 @@ TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) { BlockScopeInfo *blockScope = SemaRef.getCurBlock(); blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic()); - // We built a new blockScopeInfo in call to ActOnBlockStart - // in above, CapturesCXXThis need be set here from the block - // expression. - blockScope->CapturesCXXThis = oldBlock->capturesCXXThis(); + blockScope->TheDecl->setBlockMissingReturnType( + oldBlock->blockMissingReturnType()); SmallVector<ParmVarDecl*, 4> params; SmallVector<QualType, 4> paramTypes; @@ -8016,54 +8705,48 @@ TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) { if (getDerived().TransformFunctionTypeParams(E->getCaretLocation(), oldBlock->param_begin(), oldBlock->param_size(), - 0, paramTypes, ¶ms)) - return true; + 0, paramTypes, ¶ms)) { + getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/0); + return ExprError(); + } const FunctionType *exprFunctionType = E->getFunctionType(); - QualType exprResultType = exprFunctionType->getResultType(); - if (!exprResultType.isNull()) { - if (!exprResultType->isDependentType()) - blockScope->ReturnType = exprResultType; - else if (exprResultType != getSema().Context.DependentTy) - blockScope->ReturnType = getDerived().TransformType(exprResultType); - } - - // If the return type has not been determined yet, leave it as a dependent - // type; it'll get set when we process the body. - if (blockScope->ReturnType.isNull()) - blockScope->ReturnType = getSema().Context.DependentTy; + QualType exprResultType = + getDerived().TransformType(exprFunctionType->getResultType()); // Don't allow returning a objc interface by value. - if (blockScope->ReturnType->isObjCObjectType()) { + if (exprResultType->isObjCObjectType()) { getSema().Diag(E->getCaretLocation(), diag::err_object_cannot_be_passed_returned_by_value) - << 0 << blockScope->ReturnType; + << 0 << exprResultType; + getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/0); return ExprError(); } QualType functionType = getDerived().RebuildFunctionProtoType( - blockScope->ReturnType, + exprResultType, paramTypes.data(), paramTypes.size(), oldBlock->isVariadic(), - 0, RQ_None, + false, 0, RQ_None, exprFunctionType->getExtInfo()); blockScope->FunctionType = functionType; // Set the parameters on the block decl. if (!params.empty()) blockScope->TheDecl->setParams(params); - - // If the return type wasn't explicitly set, it will have been marked as a - // dependent type (DependentTy); clear out the return type setting so - // we will deduce the return type when type-checking the block's body. - if (blockScope->ReturnType == getSema().Context.DependentTy) - blockScope->ReturnType = QualType(); + + if (!oldBlock->blockMissingReturnType()) { + blockScope->HasImplicitReturnType = false; + blockScope->ReturnType = exprResultType; + } // Transform the body StmtResult body = getDerived().TransformStmt(E->getBody()); - if (body.isInvalid()) + if (body.isInvalid()) { + getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/0); return ExprError(); + } #ifndef NDEBUG // In builds with assertions, make sure that we captured everything we @@ -8083,6 +8766,7 @@ TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) { oldCapture)); assert(blockScope->CaptureMap.count(newCapture)); } + assert(oldBlock->capturesCXXThis() == blockScope->isCXXThisCaptured()); } #endif @@ -8092,29 +8776,6 @@ TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) { template<typename Derived> ExprResult -TreeTransform<Derived>::TransformBlockDeclRefExpr(BlockDeclRefExpr *E) { - ValueDecl *ND - = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(), - E->getDecl())); - if (!ND) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && - ND == E->getDecl()) { - // Mark it referenced in the new context regardless. - // FIXME: this is a bit instantiation-specific. - SemaRef.MarkDeclarationReferenced(E->getLocation(), ND); - - return SemaRef.Owned(E); - } - - DeclarationNameInfo NameInfo(E->getDecl()->getDeclName(), E->getLocation()); - return getDerived().RebuildDeclRefExpr(NestedNameSpecifierLoc(), - ND, NameInfo, 0); -} - -template<typename Derived> -ExprResult TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) { llvm_unreachable("Cannot transform asType expressions yet"); } @@ -8200,9 +8861,12 @@ TreeTransform<Derived>::RebuildArrayType(QualType ElementType, break; } - IntegerLiteral ArraySize(SemaRef.Context, *Size, SizeType, - /*FIXME*/BracketsRange.getBegin()); - return SemaRef.BuildArrayType(ElementType, SizeMod, &ArraySize, + // Note that we can return a VariableArrayType here in the case where + // the element type was a dependent VariableArrayType. + IntegerLiteral *ArraySize + = IntegerLiteral::Create(SemaRef.Context, *Size, SizeType, + /*FIXME*/BracketsRange.getBegin()); + return SemaRef.BuildArrayType(ElementType, SizeMod, ArraySize, IndexTypeQuals, BracketsRange, getDerived().getBaseEntity()); } @@ -8285,11 +8949,12 @@ QualType TreeTransform<Derived>::RebuildFunctionProtoType(QualType T, QualType *ParamTypes, unsigned NumParamTypes, bool Variadic, + bool HasTrailingReturn, unsigned Quals, RefQualifierKind RefQualifier, const FunctionType::ExtInfo &Info) { return SemaRef.BuildFunctionType(T, ParamTypes, NumParamTypes, Variadic, - Quals, RefQualifier, + HasTrailingReturn, Quals, RefQualifier, getDerived().getBaseLocation(), getDerived().getBaseEntity(), Info); @@ -8382,10 +9047,9 @@ TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS, UnqualifiedId TemplateName; TemplateName.setIdentifier(&Name, NameLoc); Sema::TemplateTy Template; + SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller. getSema().ActOnDependentTemplateName(/*Scope=*/0, - /*FIXME:*/SourceLocation(), - SS, - TemplateName, + SS, TemplateKWLoc, TemplateName, ParsedType::make(ObjectType), /*EnteringContext=*/false, Template); @@ -8400,13 +9064,12 @@ TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS, QualType ObjectType) { UnqualifiedId Name; // FIXME: Bogus location information. - SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc }; + SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc }; Name.setOperatorFunctionId(NameLoc, Operator, SymbolLocations); + SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller. Sema::TemplateTy Template; getSema().ActOnDependentTemplateName(/*Scope=*/0, - /*FIXME:*/SourceLocation(), - SS, - Name, + SS, TemplateKWLoc, Name, ParsedType::make(ObjectType), /*EnteringContext=*/false, Template); @@ -8543,9 +9206,11 @@ TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base, // FIXME: the ScopeType should be tacked onto SS. + SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller. return getSema().BuildMemberReferenceExpr(Base, BaseType, OperatorLoc, isArrow, - SS, /*FIXME: FirstQualifier*/ 0, + SS, TemplateKWLoc, + /*FIXME: FirstQualifier*/ 0, NameInfo, /*TemplateArgs*/ 0); } |