summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBruno Ricci <riccibrun@gmail.com>2019-02-03 19:50:56 +0000
committerBruno Ricci <riccibrun@gmail.com>2019-02-03 19:50:56 +0000
commit749fd7613d081a12c0dd43ea88d5c63c2ead2a21 (patch)
tree34b491abc27542173921ecb14253eb81de381eb6
parent52422ef96e9821d7608f58add4e458a005836429 (diff)
[AST] Update the comments of the various Expr::Ignore* + Related cleanups
The description of what the various Expr::Ignore* do has drifted from the actual implementation. Inspection reveals that IgnoreParenImpCasts() is not equivalent to doing IgnoreParens() + IgnoreImpCasts() until reaching a fixed point, but IgnoreParenCasts() is equivalent to doing IgnoreParens() + IgnoreCasts() until reaching a fixed point. There is also a fair amount of duplication in the various Expr::Ignore* functions which increase the chance of further future inconsistencies. In preparation for the next patch which will factor out the implementation of the various Expr::Ignore*, do the following cleanups: Remove Stmt::IgnoreImplicit, in favor of Expr::IgnoreImplicit. IgnoreImplicit is the only function among all of the Expr::Ignore* which is available in Stmt. There are only a few users of Stmt::IgnoreImplicit. They can just use instead Expr::IgnoreImplicit like they have to do for the other Ignore*. Move Expr::IgnoreImpCasts() from Expr.h to Expr.cpp. This made no difference in the run-time with my usual benchmark (-fsyntax-only on all of Boost). While we are at it, make IgnoreParenNoopCasts take a const reference to the ASTContext for const correctness. Update the comments to match what the Expr::Ignore* are actually doing. I am not sure that listing exactly what each Expr::Ignore* do is optimal, but it certainly looks better than the current state which is in my opinion between misleading and just plain wrong. The whole patch is NFC (if you count removing Stmt::IgnoreImplicit as NFC). Differential Revision: https://reviews.llvm.org/D57266 Reviewed By: aaron.ballman git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@353006 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/Expr.h173
-rw-r--r--include/clang/AST/Stmt.h7
-rw-r--r--lib/ARCMigrate/TransRetainReleaseDealloc.cpp8
-rw-r--r--lib/ARCMigrate/TransformActions.cpp4
-rw-r--r--lib/ARCMigrate/Transforms.cpp7
-rw-r--r--lib/AST/Expr.cpp131
-rw-r--r--lib/AST/Stmt.cpp24
-rw-r--r--lib/Analysis/ReachableCode.cpp5
-rw-r--r--lib/Tooling/ASTDiff/ASTDiff.cpp4
9 files changed, 187 insertions, 176 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 133f28ae3f..daf33de16a 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -746,67 +746,110 @@ public:
/// member expression.
static QualType findBoundMemberType(const Expr *expr);
- /// IgnoreImpCasts - Skip past any implicit casts which might
- /// surround this expression. Only skips ImplicitCastExprs.
+ /// Skip past any implicit casts which might surround this expression until
+ /// reaching a fixed point. Skips:
+ /// * ImplicitCastExpr
+ /// * FullExpr
Expr *IgnoreImpCasts() LLVM_READONLY;
-
- /// IgnoreImplicit - Skip past any implicit AST nodes which might
- /// surround this expression.
- Expr *IgnoreImplicit() LLVM_READONLY {
- return cast<Expr>(Stmt::IgnoreImplicit());
- }
-
- const Expr *IgnoreImplicit() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreImplicit();
+ const Expr *IgnoreImpCasts() const {
+ return const_cast<Expr *>(this)->IgnoreImpCasts();
}
- /// IgnoreParens - Ignore parentheses. If this Expr is a ParenExpr, return
- /// its subexpression. If that subexpression is also a ParenExpr,
- /// then this method recursively returns its subexpression, and so forth.
- /// Otherwise, the method returns the current Expr.
- Expr *IgnoreParens() LLVM_READONLY;
-
- /// IgnoreParenCasts - Ignore parentheses and casts. Strip off any ParenExpr
- /// or CastExprs, returning their operand.
- Expr *IgnoreParenCasts() LLVM_READONLY;
-
- /// Ignore casts. Strip off any CastExprs, returning their operand.
+ /// Skip past any casts which might surround this expression until reaching
+ /// a fixed point. Skips:
+ /// * CastExpr
+ /// * FullExpr
+ /// * MaterializeTemporaryExpr
+ /// * SubstNonTypeTemplateParmExpr
Expr *IgnoreCasts() LLVM_READONLY;
-
- /// IgnoreParenImpCasts - Ignore parentheses and implicit casts. Strip off
- /// any ParenExpr or ImplicitCastExprs, returning their operand.
+ const Expr *IgnoreCasts() const {
+ return const_cast<Expr *>(this)->IgnoreCasts();
+ }
+
+ /// Skip past any implicit AST nodes which might surround this expression
+ /// until reaching a fixed point. Skips:
+ /// * What IgnoreImpCasts() skips
+ /// * MaterializeTemporaryExpr
+ /// * CXXBindTemporaryExpr
+ Expr *IgnoreImplicit() LLVM_READONLY;
+ const Expr *IgnoreImplicit() const {
+ return const_cast<Expr *>(this)->IgnoreImplicit();
+ }
+
+ /// Skip past any parentheses which might surround this expression until
+ /// reaching a fixed point. Skips:
+ /// * ParenExpr
+ /// * UnaryOperator if `UO_Extension`
+ /// * GenericSelectionExpr if `!isResultDependent()`
+ /// * ChooseExpr if `!isConditionDependent()`
+ /// * ConstantExpr
+ Expr *IgnoreParens() LLVM_READONLY;
+ const Expr *IgnoreParens() const {
+ return const_cast<Expr *>(this)->IgnoreParens();
+ }
+
+ /// Skip past any parentheses and implicit casts which might surround this
+ /// expression until reaching a fixed point.
+ /// FIXME: IgnoreParenImpCasts really ought to be equivalent to
+ /// IgnoreParens() + IgnoreImpCasts() until reaching a fixed point. However
+ /// this is currently not the case. Instead IgnoreParenImpCasts() skips:
+ /// * What IgnoreParens() skips
+ /// * ImplicitCastExpr
+ /// * MaterializeTemporaryExpr
+ /// * SubstNonTypeTemplateParmExpr
Expr *IgnoreParenImpCasts() LLVM_READONLY;
-
- /// IgnoreConversionOperator - Ignore conversion operator. If this Expr is a
- /// call to a conversion operator, return the argument.
- Expr *IgnoreConversionOperator() LLVM_READONLY;
-
- const Expr *IgnoreConversionOperator() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreConversionOperator();
+ const Expr *IgnoreParenImpCasts() const {
+ return const_cast<Expr *>(this)->IgnoreParenImpCasts();
}
- const Expr *IgnoreParenImpCasts() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreParenImpCasts();
+ /// Skip past any parentheses and casts which might surround this expression
+ /// until reaching a fixed point. Skips:
+ /// * What IgnoreParens() skips
+ /// * What IgnoreCasts() skips
+ Expr *IgnoreParenCasts() LLVM_READONLY;
+ const Expr *IgnoreParenCasts() const {
+ return const_cast<Expr *>(this)->IgnoreParenCasts();
}
- /// Ignore parentheses and lvalue casts. Strip off any ParenExpr and
- /// CastExprs that represent lvalue casts, returning their operand.
+ /// Skip conversion operators. If this Expr is a call to a conversion
+ /// operator, return the argument.
+ Expr *IgnoreConversionOperator() LLVM_READONLY;
+ const Expr *IgnoreConversionOperator() const {
+ return const_cast<Expr *>(this)->IgnoreConversionOperator();
+ }
+
+ /// Skip past any parentheses and lvalue casts which might surround this
+ /// expression until reaching a fixed point. Skips:
+ /// * What IgnoreParens() skips
+ /// * What IgnoreCasts() skips, except that only lvalue-to-rvalue
+ /// casts are skipped
+ /// FIXME: This is intended purely as a temporary workaround for code
+ /// that hasn't yet been rewritten to do the right thing about those
+ /// casts, and may disappear along with the last internal use.
Expr *IgnoreParenLValueCasts() LLVM_READONLY;
-
- const Expr *IgnoreParenLValueCasts() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreParenLValueCasts();
- }
-
- /// IgnoreParenNoopCasts - Ignore parentheses and casts that do not change the
- /// value (including ptr->int casts of the same size). Strip off any
- /// ParenExpr or CastExprs, returning their operand.
- Expr *IgnoreParenNoopCasts(ASTContext &Ctx) LLVM_READONLY;
-
- /// Ignore parentheses and derived-to-base casts.
+ const Expr *IgnoreParenLValueCasts() const {
+ return const_cast<Expr *>(this)->IgnoreParenLValueCasts();
+ }
+
+ /// Skip past any parenthese and casts which do not change the value
+ /// (including ptr->int casts of the same size) until reaching a fixed point.
+ /// Skips:
+ /// * What IgnoreParens() skips
+ /// * CastExpr which do not change the value
+ /// * SubstNonTypeTemplateParmExpr
+ Expr *IgnoreParenNoopCasts(const ASTContext &Ctx) LLVM_READONLY;
+ const Expr *IgnoreParenNoopCasts(const ASTContext &Ctx) const {
+ return const_cast<Expr *>(this)->IgnoreParenNoopCasts(Ctx);
+ }
+
+ /// Skip past any parentheses and derived-to-base casts until reaching a
+ /// fixed point. Skips:
+ /// * What IgnoreParens() skips
+ /// * CastExpr which represent a derived-to-base cast (CK_DerivedToBase,
+ /// CK_UncheckedDerivedToBase and CK_NoOp)
Expr *ignoreParenBaseCasts() LLVM_READONLY;
-
- const Expr *ignoreParenBaseCasts() const LLVM_READONLY {
- return const_cast<Expr*>(this)->ignoreParenBaseCasts();
+ const Expr *ignoreParenBaseCasts() const {
+ return const_cast<Expr *>(this)->ignoreParenBaseCasts();
}
/// Determine whether this expression is a default function argument.
@@ -825,24 +868,6 @@ public:
/// Whether this expression is an implicit reference to 'this' in C++.
bool isImplicitCXXThis() const;
- const Expr *IgnoreImpCasts() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreImpCasts();
- }
- const Expr *IgnoreParens() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreParens();
- }
- const Expr *IgnoreParenCasts() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreParenCasts();
- }
- /// Strip off casts, but keep parentheses.
- const Expr *IgnoreCasts() const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreCasts();
- }
-
- const Expr *IgnoreParenNoopCasts(ASTContext &Ctx) const LLVM_READONLY {
- return const_cast<Expr*>(this)->IgnoreParenNoopCasts(Ctx);
- }
-
static bool hasAnyTypeDependentArguments(ArrayRef<Expr *> Exprs);
/// For an expression of class type or pointer to class type,
@@ -3167,18 +3192,6 @@ public:
friend class CastExpr;
};
-inline Expr *Expr::IgnoreImpCasts() {
- Expr *e = this;
- while (true)
- if (ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(e))
- e = ice->getSubExpr();
- else if (FullExpr *fe = dyn_cast<FullExpr>(e))
- e = fe->getSubExpr();
- else
- break;
- return e;
-}
-
/// ExplicitCastExpr - An explicit cast written in the source
/// code.
///
diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h
index 66b53c0881..b892d85206 100644
--- a/include/clang/AST/Stmt.h
+++ b/include/clang/AST/Stmt.h
@@ -1072,13 +1072,6 @@ public:
/// works on systems with GraphViz (Mac OS X) or dot+gv installed.
void viewAST() const;
- /// Skip past any implicit AST nodes which might surround this
- /// statement, such as ExprWithCleanups or ImplicitCastExpr nodes.
- Stmt *IgnoreImplicit();
- const Stmt *IgnoreImplicit() const {
- return const_cast<Stmt *>(this)->IgnoreImplicit();
- }
-
/// Skip no-op (attributed, compound) container stmts and skip captured
/// stmt at the top, if \a IgnoreCaptured is true.
Stmt *IgnoreContainers(bool IgnoreCaptured = false);
diff --git a/lib/ARCMigrate/TransRetainReleaseDealloc.cpp b/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
index 347c198f68..b76fc65574 100644
--- a/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
+++ b/lib/ARCMigrate/TransRetainReleaseDealloc.cpp
@@ -269,8 +269,8 @@ private:
if (prevChildS != childE) {
prevStmt = *prevChildS;
- if (prevStmt)
- prevStmt = prevStmt->IgnoreImplicit();
+ if (auto *E = dyn_cast_or_null<Expr>(prevStmt))
+ prevStmt = E->IgnoreImplicit();
}
if (currChildS == childE)
@@ -280,8 +280,8 @@ private:
return std::make_pair(prevStmt, nextStmt);
nextStmt = *currChildS;
- if (nextStmt)
- nextStmt = nextStmt->IgnoreImplicit();
+ if (auto *E = dyn_cast_or_null<Expr>(nextStmt))
+ nextStmt = E->IgnoreImplicit();
return std::make_pair(prevStmt, nextStmt);
}
diff --git a/lib/ARCMigrate/TransformActions.cpp b/lib/ARCMigrate/TransformActions.cpp
index aa1a2c50c5..f76cc2c130 100644
--- a/lib/ARCMigrate/TransformActions.cpp
+++ b/lib/ARCMigrate/TransformActions.cpp
@@ -313,7 +313,9 @@ void TransformActionsImpl::removeStmt(Stmt *S) {
assert(IsInTransaction && "Actions only allowed during a transaction");
ActionData data;
data.Kind = Act_RemoveStmt;
- data.S = S->IgnoreImplicit(); // important for uniquing
+ if (auto *E = dyn_cast<Expr>(S))
+ S = E->IgnoreImplicit(); // important for uniquing
+ data.S = S;
CachedActions.push_back(data);
}
diff --git a/lib/ARCMigrate/Transforms.cpp b/lib/ARCMigrate/Transforms.cpp
index 6ca748bcdd..59b80a917e 100644
--- a/lib/ARCMigrate/Transforms.cpp
+++ b/lib/ARCMigrate/Transforms.cpp
@@ -286,10 +286,11 @@ private:
void mark(Stmt *S) {
if (!S) return;
- while (LabelStmt *Label = dyn_cast<LabelStmt>(S))
+ while (auto *Label = dyn_cast<LabelStmt>(S))
S = Label->getSubStmt();
- S = S->IgnoreImplicit();
- if (Expr *E = dyn_cast<Expr>(S))
+ if (auto *E = dyn_cast<Expr>(S))
+ S = E->IgnoreImplicit();
+ if (auto *E = dyn_cast<Expr>(S))
Removables.insert(E);
}
};
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 2948acd3b5..6d3ad377a3 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -2556,32 +2556,66 @@ QualType Expr::findBoundMemberType(const Expr *expr) {
return QualType();
}
-Expr* Expr::IgnoreParens() {
- Expr* E = this;
+Expr *Expr::IgnoreImpCasts() {
+ Expr *E = this;
while (true) {
- if (ParenExpr* P = dyn_cast<ParenExpr>(E)) {
- E = P->getSubExpr();
+ if (auto *ICE = dyn_cast<ImplicitCastExpr>(E))
+ E = ICE->getSubExpr();
+ else if (auto *FE = dyn_cast<FullExpr>(E))
+ E = FE->getSubExpr();
+ else
+ break;
+ }
+ return E;
+}
+
+Expr *Expr::IgnoreImplicit() {
+ Expr *E = this;
+ Expr *LastE = nullptr;
+ while (E != LastE) {
+ LastE = E;
+
+ if (auto *ICE = dyn_cast<ImplicitCastExpr>(E))
+ E = ICE->getSubExpr();
+
+ if (auto *FE = dyn_cast<FullExpr>(E))
+ E = FE->getSubExpr();
+
+ if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
+ E = MTE->GetTemporaryExpr();
+
+ if (auto *BTE = dyn_cast<CXXBindTemporaryExpr>(E))
+ E = BTE->getSubExpr();
+ }
+ return E;
+}
+
+Expr *Expr::IgnoreParens() {
+ Expr *E = this;
+ while (true) {
+ if (auto *PE = dyn_cast<ParenExpr>(E)) {
+ E = PE->getSubExpr();
continue;
}
- if (UnaryOperator* P = dyn_cast<UnaryOperator>(E)) {
- if (P->getOpcode() == UO_Extension) {
- E = P->getSubExpr();
+ if (auto *UO = dyn_cast<UnaryOperator>(E)) {
+ if (UO->getOpcode() == UO_Extension) {
+ E = UO->getSubExpr();
continue;
}
}
- if (GenericSelectionExpr* P = dyn_cast<GenericSelectionExpr>(E)) {
- if (!P->isResultDependent()) {
- E = P->getResultExpr();
+ if (auto *GSE = dyn_cast<GenericSelectionExpr>(E)) {
+ if (!GSE->isResultDependent()) {
+ E = GSE->getResultExpr();
continue;
}
}
- if (ChooseExpr* P = dyn_cast<ChooseExpr>(E)) {
- if (!P->isConditionDependent()) {
- E = P->getChosenSubExpr();
+ if (auto *CE = dyn_cast<ChooseExpr>(E)) {
+ if (!CE->isConditionDependent()) {
+ E = CE->getChosenSubExpr();
continue;
}
}
- if (ConstantExpr *CE = dyn_cast<ConstantExpr>(E)) {
+ if (auto *CE = dyn_cast<ConstantExpr>(E)) {
E = CE->getSubExpr();
continue;
}
@@ -2595,21 +2629,19 @@ Expr *Expr::IgnoreParenCasts() {
Expr *E = this;
while (true) {
E = E->IgnoreParens();
- if (CastExpr *P = dyn_cast<CastExpr>(E)) {
- E = P->getSubExpr();
+ if (auto *CE = dyn_cast<CastExpr>(E)) {
+ E = CE->getSubExpr();
continue;
}
- if (MaterializeTemporaryExpr *Materialize
- = dyn_cast<MaterializeTemporaryExpr>(E)) {
- E = Materialize->GetTemporaryExpr();
+ if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) {
+ E = MTE->GetTemporaryExpr();
continue;
}
- if (SubstNonTypeTemplateParmExpr *NTTP
- = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
+ if (auto *NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
E = NTTP->getReplacement();
continue;
}
- if (FullExpr *FE = dyn_cast<FullExpr>(E)) {
+ if (auto *FE = dyn_cast<FullExpr>(E)) {
E = FE->getSubExpr();
continue;
}
@@ -2620,21 +2652,19 @@ Expr *Expr::IgnoreParenCasts() {
Expr *Expr::IgnoreCasts() {
Expr *E = this;
while (true) {
- if (CastExpr *P = dyn_cast<CastExpr>(E)) {
- E = P->getSubExpr();
+ if (auto *CE = dyn_cast<CastExpr>(E)) {
+ E = CE->getSubExpr();
continue;
}
- if (MaterializeTemporaryExpr *Materialize
- = dyn_cast<MaterializeTemporaryExpr>(E)) {
- E = Materialize->GetTemporaryExpr();
+ if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) {
+ E = MTE->GetTemporaryExpr();
continue;
}
- if (SubstNonTypeTemplateParmExpr *NTTP
- = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
+ if (auto *NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
E = NTTP->getReplacement();
continue;
}
- if (FullExpr *FE = dyn_cast<FullExpr>(E)) {
+ if (auto *FE = dyn_cast<FullExpr>(E)) {
E = FE->getSubExpr();
continue;
}
@@ -2650,20 +2680,18 @@ Expr *Expr::IgnoreParenLValueCasts() {
Expr *E = this;
while (true) {
E = E->IgnoreParens();
- if (CastExpr *P = dyn_cast<CastExpr>(E)) {
- if (P->getCastKind() == CK_LValueToRValue) {
- E = P->getSubExpr();
+ if (auto *CE = dyn_cast<CastExpr>(E)) {
+ if (CE->getCastKind() == CK_LValueToRValue) {
+ E = CE->getSubExpr();
continue;
}
- } else if (MaterializeTemporaryExpr *Materialize
- = dyn_cast<MaterializeTemporaryExpr>(E)) {
- E = Materialize->GetTemporaryExpr();
+ } else if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) {
+ E = MTE->GetTemporaryExpr();
continue;
- } else if (SubstNonTypeTemplateParmExpr *NTTP
- = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
+ } else if (auto *NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
E = NTTP->getReplacement();
continue;
- } else if (FullExpr *FE = dyn_cast<FullExpr>(E)) {
+ } else if (auto *FE = dyn_cast<FullExpr>(E)) {
E = FE->getSubExpr();
continue;
}
@@ -2676,7 +2704,7 @@ Expr *Expr::ignoreParenBaseCasts() {
Expr *E = this;
while (true) {
E = E->IgnoreParens();
- if (CastExpr *CE = dyn_cast<CastExpr>(E)) {
+ if (auto *CE = dyn_cast<CastExpr>(E)) {
if (CE->getCastKind() == CK_DerivedToBase ||
CE->getCastKind() == CK_UncheckedDerivedToBase ||
CE->getCastKind() == CK_NoOp) {
@@ -2693,17 +2721,15 @@ Expr *Expr::IgnoreParenImpCasts() {
Expr *E = this;
while (true) {
E = E->IgnoreParens();
- if (ImplicitCastExpr *P = dyn_cast<ImplicitCastExpr>(E)) {
- E = P->getSubExpr();
+ if (auto *ICE = dyn_cast<ImplicitCastExpr>(E)) {
+ E = ICE->getSubExpr();
continue;
}
- if (MaterializeTemporaryExpr *Materialize
- = dyn_cast<MaterializeTemporaryExpr>(E)) {
- E = Materialize->GetTemporaryExpr();
+ if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) {
+ E = MTE->GetTemporaryExpr();
continue;
}
- if (SubstNonTypeTemplateParmExpr *NTTP
- = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
+ if (auto *NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
E = NTTP->getReplacement();
continue;
}
@@ -2712,7 +2738,7 @@ Expr *Expr::IgnoreParenImpCasts() {
}
Expr *Expr::IgnoreConversionOperator() {
- if (CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(this)) {
+ if (auto *MCE = dyn_cast<CXXMemberCallExpr>(this)) {
if (MCE->getMethodDecl() && isa<CXXConversionDecl>(MCE->getMethodDecl()))
return MCE->getImplicitObjectArgument();
}
@@ -2722,15 +2748,15 @@ Expr *Expr::IgnoreConversionOperator() {
/// IgnoreParenNoopCasts - Ignore parentheses and casts that do not change the
/// value (including ptr->int casts of the same size). Strip off any
/// ParenExpr or CastExprs, returning their operand.
-Expr *Expr::IgnoreParenNoopCasts(ASTContext &Ctx) {
+Expr *Expr::IgnoreParenNoopCasts(const ASTContext &Ctx) {
Expr *E = this;
while (true) {
E = E->IgnoreParens();
- if (CastExpr *P = dyn_cast<CastExpr>(E)) {
+ if (auto *CE = dyn_cast<CastExpr>(E)) {
// We ignore integer <-> casts that are of the same width, ptr<->ptr and
// ptr<->int casts of the same width. We also ignore all identity casts.
- Expr *SE = P->getSubExpr();
+ Expr *SE = CE->getSubExpr();
if (Ctx.hasSameUnqualifiedType(E->getType(), SE->getType())) {
E = SE;
@@ -2747,8 +2773,7 @@ Expr *Expr::IgnoreParenNoopCasts(ASTContext &Ctx) {
}
}
- if (SubstNonTypeTemplateParmExpr *NTTP
- = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
+ if (auto *NTTP = dyn_cast<SubstNonTypeTemplateParmExpr>(E)) {
E = NTTP->getReplacement();
continue;
}
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp
index e1a4dfc10e..d1a4dc074b 100644
--- a/lib/AST/Stmt.cpp
+++ b/lib/AST/Stmt.cpp
@@ -117,30 +117,6 @@ void Stmt::EnableStatistics() {
StatisticsEnabled = true;
}
-Stmt *Stmt::IgnoreImplicit() {
- Stmt *s = this;
-
- Stmt *lasts = nullptr;
-
- while (s != lasts) {
- lasts = s;
-
- if (auto *fe = dyn_cast<FullExpr>(s))
- s = fe->getSubExpr();
-
- if (auto *mte = dyn_cast<MaterializeTemporaryExpr>(s))
- s = mte->GetTemporaryExpr();
-
- if (auto *bte = dyn_cast<CXXBindTemporaryExpr>(s))
- s = bte->getSubExpr();
-
- if (auto *ice = dyn_cast<ImplicitCastExpr>(s))
- s = ice->getSubExpr();
- }
-
- return s;
-}
-
/// Skip no-op (attributed, compound) container stmts and skip captured
/// stmt at the top, if \a IgnoreCaptured is true.
Stmt *Stmt::IgnoreContainers(bool IgnoreCaptured) {
diff --git a/lib/Analysis/ReachableCode.cpp b/lib/Analysis/ReachableCode.cpp
index 1e174e60d6..cc64efa7f0 100644
--- a/lib/Analysis/ReachableCode.cpp
+++ b/lib/Analysis/ReachableCode.cpp
@@ -192,9 +192,10 @@ static bool isConfigurationValue(const Stmt *S,
if (!S)
return false;
- S = S->IgnoreImplicit();
+ if (const auto *Ex = dyn_cast<Expr>(S))
+ S = Ex->IgnoreImplicit();
- if (const Expr *Ex = dyn_cast<Expr>(S))
+ if (const auto *Ex = dyn_cast<Expr>(S))
S = Ex->IgnoreCasts();
// Special case looking for the sigil '()' around an integer literal.
diff --git a/lib/Tooling/ASTDiff/ASTDiff.cpp b/lib/Tooling/ASTDiff/ASTDiff.cpp
index 0d456d1c8a..69eff20bff 100644
--- a/lib/Tooling/ASTDiff/ASTDiff.cpp
+++ b/lib/Tooling/ASTDiff/ASTDiff.cpp
@@ -237,8 +237,8 @@ struct PreorderVisitor : public RecursiveASTVisitor<PreorderVisitor> {
return true;
}
bool TraverseStmt(Stmt *S) {
- if (S)
- S = S->IgnoreImplicit();
+ if (auto *E = dyn_cast_or_null<Expr>(S))
+ S = E->IgnoreImplicit();
if (isNodeExcluded(Tree.AST.getSourceManager(), S))
return true;
auto SavedState = PreTraverse(S);