- //===--- IgnoreExpr.h - Ignore intermediate Expressions -----------------===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
- // 
- // This file defines common functions to ignore intermediate expression nodes 
- // 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef LLVM_CLANG_AST_IGNOREEXPR_H 
- #define LLVM_CLANG_AST_IGNOREEXPR_H 
-   
- #include "clang/AST/Expr.h" 
- #include "clang/AST/ExprCXX.h" 
-   
- namespace clang { 
- namespace detail { 
- /// Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *, 
- /// Return Fn_n(...(Fn_1(E))) 
- inline Expr *IgnoreExprNodesImpl(Expr *E) { return E; } 
- template <typename FnTy, typename... FnTys> 
- Expr *IgnoreExprNodesImpl(Expr *E, FnTy &&Fn, FnTys &&... Fns) { 
-   return IgnoreExprNodesImpl(Fn(E), std::forward<FnTys>(Fns)...); 
- } 
- } // namespace detail 
-   
- /// Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *, 
- /// Recursively apply each of the functions to E until reaching a fixed point. 
- /// Note that a null E is valid; in this case nothing is done. 
- template <typename... FnTys> Expr *IgnoreExprNodes(Expr *E, FnTys &&... Fns) { 
-   Expr *LastE = nullptr; 
-   while (E != LastE) { 
-     LastE = E; 
-     E = detail::IgnoreExprNodesImpl(E, std::forward<FnTys>(Fns)...); 
-   } 
-   return E; 
- } 
-   
- template <typename... FnTys> 
- const Expr *IgnoreExprNodes(const Expr *E, FnTys &&...Fns) { 
-   return IgnoreExprNodes(const_cast<Expr *>(E), std::forward<FnTys>(Fns)...); 
- } 
-   
- inline Expr *IgnoreImplicitCastsSingleStep(Expr *E) { 
-   if (auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 
-     return ICE->getSubExpr(); 
-   
-   if (auto *FE = dyn_cast<FullExpr>(E)) 
-     return FE->getSubExpr(); 
-   
-   return E; 
- } 
-   
- inline Expr *IgnoreImplicitCastsExtraSingleStep(Expr *E) { 
-   // FIXME: Skip MaterializeTemporaryExpr and SubstNonTypeTemplateParmExpr in 
-   // addition to what IgnoreImpCasts() skips to account for the current 
-   // behaviour of IgnoreParenImpCasts(). 
-   Expr *SubE = IgnoreImplicitCastsSingleStep(E); 
-   if (SubE != E) 
-     return SubE; 
-   
-   if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 
-     return MTE->getSubExpr(); 
-   
-   if (auto *NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) 
-     return NTTP->getReplacement(); 
-   
-   return E; 
- } 
-   
- inline Expr *IgnoreCastsSingleStep(Expr *E) { 
-   if (auto *CE = dyn_cast<CastExpr>(E)) 
-     return CE->getSubExpr(); 
-   
-   if (auto *FE = dyn_cast<FullExpr>(E)) 
-     return FE->getSubExpr(); 
-   
-   if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 
-     return MTE->getSubExpr(); 
-   
-   if (auto *NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) 
-     return NTTP->getReplacement(); 
-   
-   return E; 
- } 
-   
- inline Expr *IgnoreLValueCastsSingleStep(Expr *E) { 
-   // Skip what IgnoreCastsSingleStep skips, except that only 
-   // lvalue-to-rvalue casts are skipped. 
-   if (auto *CE = dyn_cast<CastExpr>(E)) 
-     if (CE->getCastKind() != CK_LValueToRValue) 
-       return E; 
-   
-   return IgnoreCastsSingleStep(E); 
- } 
-   
- inline Expr *IgnoreBaseCastsSingleStep(Expr *E) { 
-   if (auto *CE = dyn_cast<CastExpr>(E)) 
-     if (CE->getCastKind() == CK_DerivedToBase || 
-         CE->getCastKind() == CK_UncheckedDerivedToBase || 
-         CE->getCastKind() == CK_NoOp) 
-       return CE->getSubExpr(); 
-   
-   return E; 
- } 
-   
- inline Expr *IgnoreImplicitSingleStep(Expr *E) { 
-   Expr *SubE = IgnoreImplicitCastsSingleStep(E); 
-   if (SubE != E) 
-     return SubE; 
-   
-   if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 
-     return MTE->getSubExpr(); 
-   
-   if (auto *BTE = dyn_cast<CXXBindTemporaryExpr>(E)) 
-     return BTE->getSubExpr(); 
-   
-   return E; 
- } 
-   
- inline Expr *IgnoreElidableImplicitConstructorSingleStep(Expr *E) { 
-   auto *CCE = dyn_cast<CXXConstructExpr>(E); 
-   if (CCE && CCE->isElidable() && !isa<CXXTemporaryObjectExpr>(CCE)) { 
-     unsigned NumArgs = CCE->getNumArgs(); 
-     if ((NumArgs == 1 || 
-          (NumArgs > 1 && CCE->getArg(1)->isDefaultArgument())) && 
-         !CCE->getArg(0)->isDefaultArgument() && !CCE->isListInitialization()) 
-       return CCE->getArg(0); 
-   } 
-   return E; 
- } 
-   
- inline Expr *IgnoreImplicitAsWrittenSingleStep(Expr *E) { 
-   if (auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 
-     return ICE->getSubExprAsWritten(); 
-   
-   return IgnoreImplicitSingleStep(E); 
- } 
-   
- inline Expr *IgnoreParensOnlySingleStep(Expr *E) { 
-   if (auto *PE = dyn_cast<ParenExpr>(E)) 
-     return PE->getSubExpr(); 
-   return E; 
- } 
-   
- inline Expr *IgnoreParensSingleStep(Expr *E) { 
-   if (auto *PE = dyn_cast<ParenExpr>(E)) 
-     return PE->getSubExpr(); 
-   
-   if (auto *UO = dyn_cast<UnaryOperator>(E)) { 
-     if (UO->getOpcode() == UO_Extension) 
-       return UO->getSubExpr(); 
-   } 
-   
-   else if (auto *GSE = dyn_cast<GenericSelectionExpr>(E)) { 
-     if (!GSE->isResultDependent()) 
-       return GSE->getResultExpr(); 
-   } 
-   
-   else if (auto *CE = dyn_cast<ChooseExpr>(E)) { 
-     if (!CE->isConditionDependent()) 
-       return CE->getChosenSubExpr(); 
-   } 
-   
-   return E; 
- } 
-   
- } // namespace clang 
-   
- #endif // LLVM_CLANG_AST_IGNOREEXPR_H 
-