Skip to content

Commit e64aee8

Browse files
committed
[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 llvm-svn: 353006
1 parent 135413d commit e64aee8

File tree

9 files changed

+187
-176
lines changed

9 files changed

+187
-176
lines changed

clang/include/clang/AST/Expr.h

Lines changed: 93 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -746,67 +746,110 @@ class Expr : public Stmt {
746746
/// member expression.
747747
static QualType findBoundMemberType(const Expr *expr);
748748

749-
/// IgnoreImpCasts - Skip past any implicit casts which might
750-
/// surround this expression. Only skips ImplicitCastExprs.
749+
/// Skip past any implicit casts which might surround this expression until
750+
/// reaching a fixed point. Skips:
751+
/// * ImplicitCastExpr
752+
/// * FullExpr
751753
Expr *IgnoreImpCasts() LLVM_READONLY;
752-
753-
/// IgnoreImplicit - Skip past any implicit AST nodes which might
754-
/// surround this expression.
755-
Expr *IgnoreImplicit() LLVM_READONLY {
756-
return cast<Expr>(Stmt::IgnoreImplicit());
757-
}
758-
759-
const Expr *IgnoreImplicit() const LLVM_READONLY {
760-
return const_cast<Expr*>(this)->IgnoreImplicit();
754+
const Expr *IgnoreImpCasts() const {
755+
return const_cast<Expr *>(this)->IgnoreImpCasts();
761756
}
762757

763-
/// IgnoreParens - Ignore parentheses. If this Expr is a ParenExpr, return
764-
/// its subexpression. If that subexpression is also a ParenExpr,
765-
/// then this method recursively returns its subexpression, and so forth.
766-
/// Otherwise, the method returns the current Expr.
767-
Expr *IgnoreParens() LLVM_READONLY;
768-
769-
/// IgnoreParenCasts - Ignore parentheses and casts. Strip off any ParenExpr
770-
/// or CastExprs, returning their operand.
771-
Expr *IgnoreParenCasts() LLVM_READONLY;
772-
773-
/// Ignore casts. Strip off any CastExprs, returning their operand.
758+
/// Skip past any casts which might surround this expression until reaching
759+
/// a fixed point. Skips:
760+
/// * CastExpr
761+
/// * FullExpr
762+
/// * MaterializeTemporaryExpr
763+
/// * SubstNonTypeTemplateParmExpr
774764
Expr *IgnoreCasts() LLVM_READONLY;
775-
776-
/// IgnoreParenImpCasts - Ignore parentheses and implicit casts. Strip off
777-
/// any ParenExpr or ImplicitCastExprs, returning their operand.
765+
const Expr *IgnoreCasts() const {
766+
return const_cast<Expr *>(this)->IgnoreCasts();
767+
}
768+
769+
/// Skip past any implicit AST nodes which might surround this expression
770+
/// until reaching a fixed point. Skips:
771+
/// * What IgnoreImpCasts() skips
772+
/// * MaterializeTemporaryExpr
773+
/// * CXXBindTemporaryExpr
774+
Expr *IgnoreImplicit() LLVM_READONLY;
775+
const Expr *IgnoreImplicit() const {
776+
return const_cast<Expr *>(this)->IgnoreImplicit();
777+
}
778+
779+
/// Skip past any parentheses which might surround this expression until
780+
/// reaching a fixed point. Skips:
781+
/// * ParenExpr
782+
/// * UnaryOperator if `UO_Extension`
783+
/// * GenericSelectionExpr if `!isResultDependent()`
784+
/// * ChooseExpr if `!isConditionDependent()`
785+
/// * ConstantExpr
786+
Expr *IgnoreParens() LLVM_READONLY;
787+
const Expr *IgnoreParens() const {
788+
return const_cast<Expr *>(this)->IgnoreParens();
789+
}
790+
791+
/// Skip past any parentheses and implicit casts which might surround this
792+
/// expression until reaching a fixed point.
793+
/// FIXME: IgnoreParenImpCasts really ought to be equivalent to
794+
/// IgnoreParens() + IgnoreImpCasts() until reaching a fixed point. However
795+
/// this is currently not the case. Instead IgnoreParenImpCasts() skips:
796+
/// * What IgnoreParens() skips
797+
/// * ImplicitCastExpr
798+
/// * MaterializeTemporaryExpr
799+
/// * SubstNonTypeTemplateParmExpr
778800
Expr *IgnoreParenImpCasts() LLVM_READONLY;
779-
780-
/// IgnoreConversionOperator - Ignore conversion operator. If this Expr is a
781-
/// call to a conversion operator, return the argument.
782-
Expr *IgnoreConversionOperator() LLVM_READONLY;
783-
784-
const Expr *IgnoreConversionOperator() const LLVM_READONLY {
785-
return const_cast<Expr*>(this)->IgnoreConversionOperator();
801+
const Expr *IgnoreParenImpCasts() const {
802+
return const_cast<Expr *>(this)->IgnoreParenImpCasts();
786803
}
787804

788-
const Expr *IgnoreParenImpCasts() const LLVM_READONLY {
789-
return const_cast<Expr*>(this)->IgnoreParenImpCasts();
805+
/// Skip past any parentheses and casts which might surround this expression
806+
/// until reaching a fixed point. Skips:
807+
/// * What IgnoreParens() skips
808+
/// * What IgnoreCasts() skips
809+
Expr *IgnoreParenCasts() LLVM_READONLY;
810+
const Expr *IgnoreParenCasts() const {
811+
return const_cast<Expr *>(this)->IgnoreParenCasts();
790812
}
791813

792-
/// Ignore parentheses and lvalue casts. Strip off any ParenExpr and
793-
/// CastExprs that represent lvalue casts, returning their operand.
814+
/// Skip conversion operators. If this Expr is a call to a conversion
815+
/// operator, return the argument.
816+
Expr *IgnoreConversionOperator() LLVM_READONLY;
817+
const Expr *IgnoreConversionOperator() const {
818+
return const_cast<Expr *>(this)->IgnoreConversionOperator();
819+
}
820+
821+
/// Skip past any parentheses and lvalue casts which might surround this
822+
/// expression until reaching a fixed point. Skips:
823+
/// * What IgnoreParens() skips
824+
/// * What IgnoreCasts() skips, except that only lvalue-to-rvalue
825+
/// casts are skipped
826+
/// FIXME: This is intended purely as a temporary workaround for code
827+
/// that hasn't yet been rewritten to do the right thing about those
828+
/// casts, and may disappear along with the last internal use.
794829
Expr *IgnoreParenLValueCasts() LLVM_READONLY;
795-
796-
const Expr *IgnoreParenLValueCasts() const LLVM_READONLY {
797-
return const_cast<Expr*>(this)->IgnoreParenLValueCasts();
798-
}
799-
800-
/// IgnoreParenNoopCasts - Ignore parentheses and casts that do not change the
801-
/// value (including ptr->int casts of the same size). Strip off any
802-
/// ParenExpr or CastExprs, returning their operand.
803-
Expr *IgnoreParenNoopCasts(ASTContext &Ctx) LLVM_READONLY;
804-
805-
/// Ignore parentheses and derived-to-base casts.
830+
const Expr *IgnoreParenLValueCasts() const {
831+
return const_cast<Expr *>(this)->IgnoreParenLValueCasts();
832+
}
833+
834+
/// Skip past any parenthese and casts which do not change the value
835+
/// (including ptr->int casts of the same size) until reaching a fixed point.
836+
/// Skips:
837+
/// * What IgnoreParens() skips
838+
/// * CastExpr which do not change the value
839+
/// * SubstNonTypeTemplateParmExpr
840+
Expr *IgnoreParenNoopCasts(const ASTContext &Ctx) LLVM_READONLY;
841+
const Expr *IgnoreParenNoopCasts(const ASTContext &Ctx) const {
842+
return const_cast<Expr *>(this)->IgnoreParenNoopCasts(Ctx);
843+
}
844+
845+
/// Skip past any parentheses and derived-to-base casts until reaching a
846+
/// fixed point. Skips:
847+
/// * What IgnoreParens() skips
848+
/// * CastExpr which represent a derived-to-base cast (CK_DerivedToBase,
849+
/// CK_UncheckedDerivedToBase and CK_NoOp)
806850
Expr *ignoreParenBaseCasts() LLVM_READONLY;
807-
808-
const Expr *ignoreParenBaseCasts() const LLVM_READONLY {
809-
return const_cast<Expr*>(this)->ignoreParenBaseCasts();
851+
const Expr *ignoreParenBaseCasts() const {
852+
return const_cast<Expr *>(this)->ignoreParenBaseCasts();
810853
}
811854

812855
/// Determine whether this expression is a default function argument.
@@ -825,24 +868,6 @@ class Expr : public Stmt {
825868
/// Whether this expression is an implicit reference to 'this' in C++.
826869
bool isImplicitCXXThis() const;
827870

828-
const Expr *IgnoreImpCasts() const LLVM_READONLY {
829-
return const_cast<Expr*>(this)->IgnoreImpCasts();
830-
}
831-
const Expr *IgnoreParens() const LLVM_READONLY {
832-
return const_cast<Expr*>(this)->IgnoreParens();
833-
}
834-
const Expr *IgnoreParenCasts() const LLVM_READONLY {
835-
return const_cast<Expr*>(this)->IgnoreParenCasts();
836-
}
837-
/// Strip off casts, but keep parentheses.
838-
const Expr *IgnoreCasts() const LLVM_READONLY {
839-
return const_cast<Expr*>(this)->IgnoreCasts();
840-
}
841-
842-
const Expr *IgnoreParenNoopCasts(ASTContext &Ctx) const LLVM_READONLY {
843-
return const_cast<Expr*>(this)->IgnoreParenNoopCasts(Ctx);
844-
}
845-
846871
static bool hasAnyTypeDependentArguments(ArrayRef<Expr *> Exprs);
847872

848873
/// For an expression of class type or pointer to class type,
@@ -3167,18 +3192,6 @@ class ImplicitCastExpr final
31673192
friend class CastExpr;
31683193
};
31693194

3170-
inline Expr *Expr::IgnoreImpCasts() {
3171-
Expr *e = this;
3172-
while (true)
3173-
if (ImplicitCastExpr *ice = dyn_cast<ImplicitCastExpr>(e))
3174-
e = ice->getSubExpr();
3175-
else if (FullExpr *fe = dyn_cast<FullExpr>(e))
3176-
e = fe->getSubExpr();
3177-
else
3178-
break;
3179-
return e;
3180-
}
3181-
31823195
/// ExplicitCastExpr - An explicit cast written in the source
31833196
/// code.
31843197
///

clang/include/clang/AST/Stmt.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,13 +1072,6 @@ class alignas(void *) Stmt {
10721072
/// works on systems with GraphViz (Mac OS X) or dot+gv installed.
10731073
void viewAST() const;
10741074

1075-
/// Skip past any implicit AST nodes which might surround this
1076-
/// statement, such as ExprWithCleanups or ImplicitCastExpr nodes.
1077-
Stmt *IgnoreImplicit();
1078-
const Stmt *IgnoreImplicit() const {
1079-
return const_cast<Stmt *>(this)->IgnoreImplicit();
1080-
}
1081-
10821075
/// Skip no-op (attributed, compound) container stmts and skip captured
10831076
/// stmt at the top, if \a IgnoreCaptured is true.
10841077
Stmt *IgnoreContainers(bool IgnoreCaptured = false);

clang/lib/ARCMigrate/TransRetainReleaseDealloc.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -269,8 +269,8 @@ class RetainReleaseDeallocRemover :
269269

270270
if (prevChildS != childE) {
271271
prevStmt = *prevChildS;
272-
if (prevStmt)
273-
prevStmt = prevStmt->IgnoreImplicit();
272+
if (auto *E = dyn_cast_or_null<Expr>(prevStmt))
273+
prevStmt = E->IgnoreImplicit();
274274
}
275275

276276
if (currChildS == childE)
@@ -280,8 +280,8 @@ class RetainReleaseDeallocRemover :
280280
return std::make_pair(prevStmt, nextStmt);
281281

282282
nextStmt = *currChildS;
283-
if (nextStmt)
284-
nextStmt = nextStmt->IgnoreImplicit();
283+
if (auto *E = dyn_cast_or_null<Expr>(nextStmt))
284+
nextStmt = E->IgnoreImplicit();
285285

286286
return std::make_pair(prevStmt, nextStmt);
287287
}

clang/lib/ARCMigrate/TransformActions.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,9 @@ void TransformActionsImpl::removeStmt(Stmt *S) {
313313
assert(IsInTransaction && "Actions only allowed during a transaction");
314314
ActionData data;
315315
data.Kind = Act_RemoveStmt;
316-
data.S = S->IgnoreImplicit(); // important for uniquing
316+
if (auto *E = dyn_cast<Expr>(S))
317+
S = E->IgnoreImplicit(); // important for uniquing
318+
data.S = S;
317319
CachedActions.push_back(data);
318320
}
319321

clang/lib/ARCMigrate/Transforms.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,10 +286,11 @@ class RemovablesCollector : public RecursiveASTVisitor<RemovablesCollector> {
286286
void mark(Stmt *S) {
287287
if (!S) return;
288288

289-
while (LabelStmt *Label = dyn_cast<LabelStmt>(S))
289+
while (auto *Label = dyn_cast<LabelStmt>(S))
290290
S = Label->getSubStmt();
291-
S = S->IgnoreImplicit();
292-
if (Expr *E = dyn_cast<Expr>(S))
291+
if (auto *E = dyn_cast<Expr>(S))
292+
S = E->IgnoreImplicit();
293+
if (auto *E = dyn_cast<Expr>(S))
293294
Removables.insert(E);
294295
}
295296
};

0 commit comments

Comments
 (0)