lebedev.ri created this revision. lebedev.ri added reviewers: rsmith, erichkeane, rjmccall, aaron.ballman. Herald added a subscriber: cfe-commits. lebedev.ri added a dependency: D49838: [AST] Sink 'part of explicit cast' down into ImplicitCastExpr.
This is mostly factored out of https://reviews.llvm.org/D48958. As of https://reviews.llvm.org/D49838, `ImplicitCastExpr` can tell whether it is a part of ExplicitCastExpr group. But given just the `CastExpr`, one still has to check that it is not `ExplicitCastExpr` itself, before using `ImplicitCastExpr::getIsPartOfExplicitCast()`. Thus, it makes sense to factor out it into a helper function in `CastExpr` baseclass. This indeed does not have tests. Would be happy to add those, if needed and told how to write those. Repository: rC Clang https://reviews.llvm.org/D49844 Files: include/clang/AST/Expr.h Index: include/clang/AST/Expr.h =================================================================== --- include/clang/AST/Expr.h +++ include/clang/AST/Expr.h @@ -2850,6 +2850,15 @@ return const_cast<CastExpr *>(this)->getSubExprAsWritten(); } + /// There are two global types of casts - implicit and explicit. + /// The Explicit cast is something that was directly written in the source + /// code. And the implicit cast is expected to be the opposite. + /// But in AST, some explicit casts are represented as ExplicitCastExpr plus + /// one or more immediate ImplicitCastExpr (i.e. with nothing inbetween). + /// This function returns false if this cast is either an ExplicitCastExpr + /// itself, or it is a part of the ExplicitCastExpr group. + bool isActuallyImplicitCast() const; + /// If this cast applies a user-defined conversion, retrieve the conversion /// function that it invokes. NamedDecl *getConversionFunction() const; @@ -3011,6 +3020,14 @@ } }; +inline bool CastExpr::isActuallyImplicitCast() const { + // If this is an Implicit cast, is it *NOT* a part of Explicit cast group? + if (auto *IC = dyn_cast<ImplicitCastExpr>(this)) + return !IC->getIsPartOfExplicitCast(); + assert(isa<ExplicitCastExpr>(this) && "it has to be Explicit cast then."); + return false; // Explicit cast is clearly not an Implicit cast. +} + /// CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style /// cast in C++ (C++ [expr.cast]), which uses the syntax /// (Type)expr. For example: @c (int)f.
Index: include/clang/AST/Expr.h =================================================================== --- include/clang/AST/Expr.h +++ include/clang/AST/Expr.h @@ -2850,6 +2850,15 @@ return const_cast<CastExpr *>(this)->getSubExprAsWritten(); } + /// There are two global types of casts - implicit and explicit. + /// The Explicit cast is something that was directly written in the source + /// code. And the implicit cast is expected to be the opposite. + /// But in AST, some explicit casts are represented as ExplicitCastExpr plus + /// one or more immediate ImplicitCastExpr (i.e. with nothing inbetween). + /// This function returns false if this cast is either an ExplicitCastExpr + /// itself, or it is a part of the ExplicitCastExpr group. + bool isActuallyImplicitCast() const; + /// If this cast applies a user-defined conversion, retrieve the conversion /// function that it invokes. NamedDecl *getConversionFunction() const; @@ -3011,6 +3020,14 @@ } }; +inline bool CastExpr::isActuallyImplicitCast() const { + // If this is an Implicit cast, is it *NOT* a part of Explicit cast group? + if (auto *IC = dyn_cast<ImplicitCastExpr>(this)) + return !IC->getIsPartOfExplicitCast(); + assert(isa<ExplicitCastExpr>(this) && "it has to be Explicit cast then."); + return false; // Explicit cast is clearly not an Implicit cast. +} + /// CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style /// cast in C++ (C++ [expr.cast]), which uses the syntax /// (Type)expr. For example: @c (int)f.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits