diff options
Diffstat (limited to 'clang/lib/Sema/TreeTransform.h')
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 208 |
1 files changed, 206 insertions, 2 deletions
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 363e2c408db..0a0f5c7c328 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -2210,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. @@ -8253,7 +8281,159 @@ TreeTransform<Derived>::TransformMaterializeTemporaryExpr( template<typename Derived> ExprResult TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) { - return SemaRef.Owned(E); + return SemaRef.MaybeBindToTemporary(E); +} + +template<typename Derived> +ExprResult +TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) { + return SemaRef.MaybeBindToTemporary(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> @@ -8436,6 +8616,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()); |