Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:37

0001 //===--- IgnoreExpr.h - Ignore intermediate Expressions -----------------===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file defines common functions to ignore intermediate expression nodes
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_CLANG_AST_IGNOREEXPR_H
0014 #define LLVM_CLANG_AST_IGNOREEXPR_H
0015 
0016 #include "clang/AST/Expr.h"
0017 #include "clang/AST/ExprCXX.h"
0018 
0019 namespace clang {
0020 namespace detail {
0021 /// Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *,
0022 /// Return Fn_n(...(Fn_1(E)))
0023 inline Expr *IgnoreExprNodesImpl(Expr *E) { return E; }
0024 template <typename FnTy, typename... FnTys>
0025 Expr *IgnoreExprNodesImpl(Expr *E, FnTy &&Fn, FnTys &&... Fns) {
0026   return IgnoreExprNodesImpl(std::forward<FnTy>(Fn)(E),
0027                              std::forward<FnTys>(Fns)...);
0028 }
0029 } // namespace detail
0030 
0031 /// Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *,
0032 /// Recursively apply each of the functions to E until reaching a fixed point.
0033 /// Note that a null E is valid; in this case nothing is done.
0034 template <typename... FnTys> Expr *IgnoreExprNodes(Expr *E, FnTys &&... Fns) {
0035   Expr *LastE = nullptr;
0036   while (E != LastE) {
0037     LastE = E;
0038     E = detail::IgnoreExprNodesImpl(E, std::forward<FnTys>(Fns)...);
0039   }
0040   return E;
0041 }
0042 
0043 template <typename... FnTys>
0044 const Expr *IgnoreExprNodes(const Expr *E, FnTys &&...Fns) {
0045   return IgnoreExprNodes(const_cast<Expr *>(E), std::forward<FnTys>(Fns)...);
0046 }
0047 
0048 inline Expr *IgnoreImplicitCastsSingleStep(Expr *E) {
0049   if (auto *ICE = dyn_cast<ImplicitCastExpr>(E))
0050     return ICE->getSubExpr();
0051 
0052   if (auto *FE = dyn_cast<FullExpr>(E))
0053     return FE->getSubExpr();
0054 
0055   return E;
0056 }
0057 
0058 inline Expr *IgnoreImplicitCastsExtraSingleStep(Expr *E) {
0059   // FIXME: Skip MaterializeTemporaryExpr and SubstNonTypeTemplateParmExpr in
0060   // addition to what IgnoreImpCasts() skips to account for the current
0061   // behaviour of IgnoreParenImpCasts().
0062   Expr *SubE = IgnoreImplicitCastsSingleStep(E);
0063   if (SubE != E)
0064     return SubE;
0065 
0066   if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
0067     return MTE->getSubExpr();
0068 
0069   if (auto *NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E))
0070     return NTTP->getReplacement();
0071 
0072   return E;
0073 }
0074 
0075 inline Expr *IgnoreCastsSingleStep(Expr *E) {
0076   if (auto *CE = dyn_cast<CastExpr>(E))
0077     return CE->getSubExpr();
0078 
0079   if (auto *FE = dyn_cast<FullExpr>(E))
0080     return FE->getSubExpr();
0081 
0082   if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
0083     return MTE->getSubExpr();
0084 
0085   if (auto *NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E))
0086     return NTTP->getReplacement();
0087 
0088   return E;
0089 }
0090 
0091 inline Expr *IgnoreLValueCastsSingleStep(Expr *E) {
0092   // Skip what IgnoreCastsSingleStep skips, except that only
0093   // lvalue-to-rvalue casts are skipped.
0094   if (auto *CE = dyn_cast<CastExpr>(E))
0095     if (CE->getCastKind() != CK_LValueToRValue)
0096       return E;
0097 
0098   return IgnoreCastsSingleStep(E);
0099 }
0100 
0101 inline Expr *IgnoreBaseCastsSingleStep(Expr *E) {
0102   if (auto *CE = dyn_cast<CastExpr>(E))
0103     if (CE->getCastKind() == CK_DerivedToBase ||
0104         CE->getCastKind() == CK_UncheckedDerivedToBase ||
0105         CE->getCastKind() == CK_NoOp)
0106       return CE->getSubExpr();
0107 
0108   return E;
0109 }
0110 
0111 inline Expr *IgnoreImplicitSingleStep(Expr *E) {
0112   Expr *SubE = IgnoreImplicitCastsSingleStep(E);
0113   if (SubE != E)
0114     return SubE;
0115 
0116   if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
0117     return MTE->getSubExpr();
0118 
0119   if (auto *BTE = dyn_cast<CXXBindTemporaryExpr>(E))
0120     return BTE->getSubExpr();
0121 
0122   return E;
0123 }
0124 
0125 inline Expr *IgnoreElidableImplicitConstructorSingleStep(Expr *E) {
0126   auto *CCE = dyn_cast<CXXConstructExpr>(E);
0127   if (CCE && CCE->isElidable() && !isa<CXXTemporaryObjectExpr>(CCE)) {
0128     unsigned NumArgs = CCE->getNumArgs();
0129     if ((NumArgs == 1 ||
0130          (NumArgs > 1 && CCE->getArg(1)->isDefaultArgument())) &&
0131         !CCE->getArg(0)->isDefaultArgument() && !CCE->isListInitialization())
0132       return CCE->getArg(0);
0133   }
0134   return E;
0135 }
0136 
0137 inline Expr *IgnoreImplicitAsWrittenSingleStep(Expr *E) {
0138   if (auto *ICE = dyn_cast<ImplicitCastExpr>(E))
0139     return ICE->getSubExprAsWritten();
0140 
0141   return IgnoreImplicitSingleStep(E);
0142 }
0143 
0144 inline Expr *IgnoreParensOnlySingleStep(Expr *E) {
0145   if (auto *PE = dyn_cast<ParenExpr>(E))
0146     return PE->getSubExpr();
0147   return E;
0148 }
0149 
0150 inline Expr *IgnoreParensSingleStep(Expr *E) {
0151   if (auto *PE = dyn_cast<ParenExpr>(E))
0152     return PE->getSubExpr();
0153 
0154   if (auto *UO = dyn_cast<UnaryOperator>(E)) {
0155     if (UO->getOpcode() == UO_Extension)
0156       return UO->getSubExpr();
0157   }
0158 
0159   else if (auto *GSE = dyn_cast<GenericSelectionExpr>(E)) {
0160     if (!GSE->isResultDependent())
0161       return GSE->getResultExpr();
0162   }
0163 
0164   else if (auto *CE = dyn_cast<ChooseExpr>(E)) {
0165     if (!CE->isConditionDependent())
0166       return CE->getChosenSubExpr();
0167   }
0168 
0169   else if (auto *PE = dyn_cast<PredefinedExpr>(E)) {
0170     if (PE->isTransparent() && PE->getFunctionName())
0171       return PE->getFunctionName();
0172   }
0173 
0174   return E;
0175 }
0176 
0177 } // namespace clang
0178 
0179 #endif // LLVM_CLANG_AST_IGNOREEXPR_H