[PATCH] D49838: [AST] Sink 'part of explicit cast' down into ImplicitCastExpr
This revision was automatically updated to reflect the committed changes. Closed by commit rC338108: [AST] Sink part of explicit cast down into ImplicitCastExpr (authored by lebedevri, committed by ). Repository: rC Clang https://reviews.llvm.org/D49838 Files: include/clang/AST/Expr.h include/clang/AST/Stmt.h lib/AST/ASTDumper.cpp lib/Sema/SemaCast.cpp lib/Serialization/ASTReaderStmt.cpp lib/Serialization/ASTWriterStmt.cpp Index: include/clang/AST/Stmt.h === --- include/clang/AST/Stmt.h +++ include/clang/AST/Stmt.h @@ -198,11 +198,12 @@ class CastExprBitfields { friend class CastExpr; +friend class ImplicitCastExpr; unsigned : NumExprBits; unsigned Kind : 6; -unsigned PartOfExplicitCast : 1; +unsigned PartOfExplicitCast : 1; // Only set for ImplicitCastExpr. unsigned BasePathSize : 32 - 6 - 1 - NumExprBits; }; Index: include/clang/AST/Expr.h === --- include/clang/AST/Expr.h +++ include/clang/AST/Expr.h @@ -2830,20 +2830,14 @@ /// Construct an empty cast. CastExpr(StmtClass SC, EmptyShell Empty, unsigned BasePathSize) : Expr(SC, Empty) { +CastExprBits.PartOfExplicitCast = false; setBasePathSize(BasePathSize); } public: CastKind getCastKind() const { return (CastKind) CastExprBits.Kind; } void setCastKind(CastKind K) { CastExprBits.Kind = K; } - bool getIsPartOfExplicitCast() const { -return CastExprBits.PartOfExplicitCast; - } - void setIsPartOfExplicitCast(bool PartOfExplicitCast) { -CastExprBits.PartOfExplicitCast = PartOfExplicitCast; - } - static const char *getCastKindName(CastKind CK); const char *getCastKindName() const { return getCastKindName(getCastKind()); } @@ -2932,6 +2926,11 @@ : CastExpr(ImplicitCastExprClass, ty, VK, kind, op, 0) { } + bool isPartOfExplicitCast() const { return CastExprBits.PartOfExplicitCast; } + void setIsPartOfExplicitCast(bool PartOfExplicitCast) { +CastExprBits.PartOfExplicitCast = PartOfExplicitCast; + } + static ImplicitCastExpr *Create(const ASTContext , QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, Index: lib/AST/ASTDumper.cpp === --- lib/AST/ASTDumper.cpp +++ lib/AST/ASTDumper.cpp @@ -521,6 +521,7 @@ // Exprs void VisitExpr(const Expr *Node); void VisitCastExpr(const CastExpr *Node); +void VisitImplicitCastExpr(const ImplicitCastExpr *Node); void VisitDeclRefExpr(const DeclRefExpr *Node); void VisitPredefinedExpr(const PredefinedExpr *Node); void VisitCharacterLiteral(const CharacterLiteral *Node); @@ -2117,8 +2118,11 @@ } dumpBasePath(OS, Node); OS << ">"; +} - if (Node->getIsPartOfExplicitCast()) +void ASTDumper::VisitImplicitCastExpr(const ImplicitCastExpr *Node) { + VisitCastExpr(Node); + if (Node->isPartOfExplicitCast()) OS << " part_of_explicit_cast"; } Index: lib/Sema/SemaCast.cpp === --- lib/Sema/SemaCast.cpp +++ lib/Sema/SemaCast.cpp @@ -93,8 +93,8 @@ // Walk down from the CE to the OrigSrcExpr, and mark all immediate // ImplicitCastExpr's as being part of ExplicitCastExpr. The original CE // (which is a ExplicitCastExpr), and the OrigSrcExpr are not touched. - while ((CE = dyn_cast(CE->getSubExpr( -CE->setIsPartOfExplicitCast(true); + for (; auto *ICE = dyn_cast(CE->getSubExpr()); CE = ICE) +ICE->setIsPartOfExplicitCast(true); } /// Complete an apparently-successful cast operation that yields Index: lib/Serialization/ASTWriterStmt.cpp === --- lib/Serialization/ASTWriterStmt.cpp +++ lib/Serialization/ASTWriterStmt.cpp @@ -665,7 +665,6 @@ Record.push_back(E->path_size()); Record.AddStmt(E->getSubExpr()); Record.push_back(E->getCastKind()); // FIXME: stable encoding - Record.push_back(E->getIsPartOfExplicitCast()); for (CastExpr::path_iterator PI = E->path_begin(), PE = E->path_end(); PI != PE; ++PI) @@ -714,6 +713,7 @@ void ASTStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) { VisitCastExpr(E); + Record.push_back(E->isPartOfExplicitCast()); if (E->path_size() == 0) AbbrevToUse = Writer.getExprImplicitCastAbbrev(); Index: lib/Serialization/ASTReaderStmt.cpp === --- lib/Serialization/ASTReaderStmt.cpp +++ lib/Serialization/ASTReaderStmt.cpp @@ -723,7 +723,6 @@ assert(NumBaseSpecs == E->path_size()); E->setSubExpr(Record.readSubExpr()); E->setCastKind((CastKind)Record.readInt()); - E->setIsPartOfExplicitCast(Record.readInt()); CastExpr::path_iterator BaseI = E->path_begin();
[PATCH] D49838: [AST] Sink 'part of explicit cast' down into ImplicitCastExpr
lebedev.ri added inline comments. Comment at: include/clang/AST/Expr.h:2928 + bool getIsPartOfExplicitCast() const { +return CastExprBits.PartOfExplicitCast; rsmith wrote: > Please also rename this to`isPartOfExplicitCast` as requested on IRC. Right, sorry. Comment at: lib/Sema/SemaCast.cpp:97 while ((CE = dyn_cast(CE->getSubExpr( -CE->setIsPartOfExplicitCast(true); +dyn_cast(CE)->setIsPartOfExplicitCast(true); } rsmith wrote: > lebedev.ri wrote: > > lebedev.ri wrote: > > > erichkeane wrote: > > > > I think I'd prefer just using a different variable in the 'while' loop > > > > to avoid the cast. something like while((auto ICE = > > > > > > > > That said, either way this isn't a dyn_cast, this would be just a cast > > > > (since we KNOW the type). > > > I was trying to avoid having one extra variable, which may confuse things. > > > Let's see maybe it's not that ugly.. > > Indeed, `cast<>` should be used. > > But trying to avoid this cast at all results in uglier code, so let's not. > > (I need to call `getSubExpr()` on this new `ImplicitCastExpr`, so i'd need > > to maintain two variables, etc...) > Maybe something like: > ``` > for (auto *Next = CE->getSubExpr(); auto *ICE = > dyn_cast(Next); Next = ICE->getSubExpr()) > ICE->setIsPartOfExplicitCast(true); > ``` > or just > ``` > for (; auto *ICE = dyn_cast(CE->getSubExpr()); CE = ICE) > ICE->setIsPartOfExplicitCast(true); > ``` Oh wow, one can define variables not just in the "init-statement", how did i not notice this earlier?! That changes the picture indeed. Repository: rC Clang https://reviews.llvm.org/D49838 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D49838: [AST] Sink 'part of explicit cast' down into ImplicitCastExpr
lebedev.ri updated this revision to Diff 157576. lebedev.ri marked 3 inline comments as done. lebedev.ri added a comment. Address @rsmith review notes. Repository: rC Clang https://reviews.llvm.org/D49838 Files: include/clang/AST/Expr.h include/clang/AST/Stmt.h lib/AST/ASTDumper.cpp lib/Sema/SemaCast.cpp lib/Serialization/ASTReaderStmt.cpp lib/Serialization/ASTWriterStmt.cpp Index: lib/Serialization/ASTWriterStmt.cpp === --- lib/Serialization/ASTWriterStmt.cpp +++ lib/Serialization/ASTWriterStmt.cpp @@ -665,7 +665,6 @@ Record.push_back(E->path_size()); Record.AddStmt(E->getSubExpr()); Record.push_back(E->getCastKind()); // FIXME: stable encoding - Record.push_back(E->getIsPartOfExplicitCast()); for (CastExpr::path_iterator PI = E->path_begin(), PE = E->path_end(); PI != PE; ++PI) @@ -714,6 +713,7 @@ void ASTStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) { VisitCastExpr(E); + Record.push_back(E->isPartOfExplicitCast()); if (E->path_size() == 0) AbbrevToUse = Writer.getExprImplicitCastAbbrev(); Index: lib/Serialization/ASTReaderStmt.cpp === --- lib/Serialization/ASTReaderStmt.cpp +++ lib/Serialization/ASTReaderStmt.cpp @@ -723,7 +723,6 @@ assert(NumBaseSpecs == E->path_size()); E->setSubExpr(Record.readSubExpr()); E->setCastKind((CastKind)Record.readInt()); - E->setIsPartOfExplicitCast(Record.readInt()); CastExpr::path_iterator BaseI = E->path_begin(); while (NumBaseSpecs--) { auto *BaseSpec = new (Record.getContext()) CXXBaseSpecifier; @@ -770,6 +769,7 @@ void ASTStmtReader::VisitImplicitCastExpr(ImplicitCastExpr *E) { VisitCastExpr(E); + E->setIsPartOfExplicitCast(Record.readInt()); } void ASTStmtReader::VisitExplicitCastExpr(ExplicitCastExpr *E) { Index: lib/Sema/SemaCast.cpp === --- lib/Sema/SemaCast.cpp +++ lib/Sema/SemaCast.cpp @@ -93,8 +93,8 @@ // Walk down from the CE to the OrigSrcExpr, and mark all immediate // ImplicitCastExpr's as being part of ExplicitCastExpr. The original CE // (which is a ExplicitCastExpr), and the OrigSrcExpr are not touched. - while ((CE = dyn_cast(CE->getSubExpr( -CE->setIsPartOfExplicitCast(true); + for (; auto *ICE = dyn_cast(CE->getSubExpr()); CE = ICE) +ICE->setIsPartOfExplicitCast(true); } /// Complete an apparently-successful cast operation that yields Index: lib/AST/ASTDumper.cpp === --- lib/AST/ASTDumper.cpp +++ lib/AST/ASTDumper.cpp @@ -521,6 +521,7 @@ // Exprs void VisitExpr(const Expr *Node); void VisitCastExpr(const CastExpr *Node); +void VisitImplicitCastExpr(const ImplicitCastExpr *Node); void VisitDeclRefExpr(const DeclRefExpr *Node); void VisitPredefinedExpr(const PredefinedExpr *Node); void VisitCharacterLiteral(const CharacterLiteral *Node); @@ -2117,8 +2118,11 @@ } dumpBasePath(OS, Node); OS << ">"; +} - if (Node->getIsPartOfExplicitCast()) +void ASTDumper::VisitImplicitCastExpr(const ImplicitCastExpr *Node) { + VisitCastExpr(Node); + if (Node->isPartOfExplicitCast()) OS << " part_of_explicit_cast"; } Index: include/clang/AST/Stmt.h === --- include/clang/AST/Stmt.h +++ include/clang/AST/Stmt.h @@ -198,11 +198,12 @@ class CastExprBitfields { friend class CastExpr; +friend class ImplicitCastExpr; unsigned : NumExprBits; unsigned Kind : 6; -unsigned PartOfExplicitCast : 1; +unsigned PartOfExplicitCast : 1; // Only set for ImplicitCastExpr. unsigned BasePathSize : 32 - 6 - 1 - NumExprBits; }; Index: include/clang/AST/Expr.h === --- include/clang/AST/Expr.h +++ include/clang/AST/Expr.h @@ -2829,20 +2829,14 @@ /// Construct an empty cast. CastExpr(StmtClass SC, EmptyShell Empty, unsigned BasePathSize) : Expr(SC, Empty) { +CastExprBits.PartOfExplicitCast = false; setBasePathSize(BasePathSize); } public: CastKind getCastKind() const { return (CastKind) CastExprBits.Kind; } void setCastKind(CastKind K) { CastExprBits.Kind = K; } - bool getIsPartOfExplicitCast() const { -return CastExprBits.PartOfExplicitCast; - } - void setIsPartOfExplicitCast(bool PartOfExplicitCast) { -CastExprBits.PartOfExplicitCast = PartOfExplicitCast; - } - static const char *getCastKindName(CastKind CK); const char *getCastKindName() const { return getCastKindName(getCastKind()); } @@ -2931,6 +2925,11 @@ : CastExpr(ImplicitCastExprClass, ty, VK, kind, op, 0) { } + bool isPartOfExplicitCast() const { return CastExprBits.PartOfExplicitCast; } + void setIsPartOfExplicitCast(bool
[PATCH] D49838: [AST] Sink 'part of explicit cast' down into ImplicitCastExpr
rsmith added inline comments. Comment at: include/clang/AST/Expr.h:2928 + bool getIsPartOfExplicitCast() const { +return CastExprBits.PartOfExplicitCast; Please also rename this to`isPartOfExplicitCast` as requested on IRC. Comment at: include/clang/AST/Stmt.h:206 unsigned Kind : 6; -unsigned PartOfExplicitCast : 1; +unsigned PartOfExplicitCast : 1; // Only representable for ImplicitCastExpr. unsigned BasePathSize : 32 - 6 - 1 - NumExprBits; representable for -> set for Comment at: lib/Sema/SemaCast.cpp:97 while ((CE = dyn_cast(CE->getSubExpr( -CE->setIsPartOfExplicitCast(true); +dyn_cast(CE)->setIsPartOfExplicitCast(true); } lebedev.ri wrote: > lebedev.ri wrote: > > erichkeane wrote: > > > I think I'd prefer just using a different variable in the 'while' loop to > > > avoid the cast. something like while((auto ICE = > > > > > > That said, either way this isn't a dyn_cast, this would be just a cast > > > (since we KNOW the type). > > I was trying to avoid having one extra variable, which may confuse things. > > Let's see maybe it's not that ugly.. > Indeed, `cast<>` should be used. > But trying to avoid this cast at all results in uglier code, so let's not. > (I need to call `getSubExpr()` on this new `ImplicitCastExpr`, so i'd need to > maintain two variables, etc...) Maybe something like: ``` for (auto *Next = CE->getSubExpr(); auto *ICE = dyn_cast(Next); Next = ICE->getSubExpr()) ICE->setIsPartOfExplicitCast(true); ``` or just ``` for (; auto *ICE = dyn_cast(CE->getSubExpr()); CE = ICE) ICE->setIsPartOfExplicitCast(true); ``` Repository: rC Clang https://reviews.llvm.org/D49838 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D49838: [AST] Sink 'part of explicit cast' down into ImplicitCastExpr
lebedev.ri added inline comments. Comment at: lib/Sema/SemaCast.cpp:97 while ((CE = dyn_cast(CE->getSubExpr( -CE->setIsPartOfExplicitCast(true); +dyn_cast(CE)->setIsPartOfExplicitCast(true); } lebedev.ri wrote: > erichkeane wrote: > > I think I'd prefer just using a different variable in the 'while' loop to > > avoid the cast. something like while((auto ICE = > > > > That said, either way this isn't a dyn_cast, this would be just a cast > > (since we KNOW the type). > I was trying to avoid having one extra variable, which may confuse things. > Let's see maybe it's not that ugly.. Indeed, `cast<>` should be used. But trying to avoid this cast at all results in uglier code, so let's not. (I need to call `getSubExpr()` on this new `ImplicitCastExpr`, so i'd need to maintain two variables, etc...) Repository: rC Clang https://reviews.llvm.org/D49838 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D49838: [AST] Sink 'part of explicit cast' down into ImplicitCastExpr
lebedev.ri updated this revision to Diff 157483. lebedev.ri marked 5 inline comments as done. lebedev.ri added a comment. Address @erichkeane review notes. Repository: rC Clang https://reviews.llvm.org/D49838 Files: include/clang/AST/Expr.h include/clang/AST/Stmt.h lib/AST/ASTDumper.cpp lib/Sema/SemaCast.cpp lib/Serialization/ASTReaderStmt.cpp lib/Serialization/ASTWriterStmt.cpp Index: lib/Serialization/ASTWriterStmt.cpp === --- lib/Serialization/ASTWriterStmt.cpp +++ lib/Serialization/ASTWriterStmt.cpp @@ -665,7 +665,6 @@ Record.push_back(E->path_size()); Record.AddStmt(E->getSubExpr()); Record.push_back(E->getCastKind()); // FIXME: stable encoding - Record.push_back(E->getIsPartOfExplicitCast()); for (CastExpr::path_iterator PI = E->path_begin(), PE = E->path_end(); PI != PE; ++PI) @@ -714,6 +713,7 @@ void ASTStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) { VisitCastExpr(E); + Record.push_back(E->getIsPartOfExplicitCast()); if (E->path_size() == 0) AbbrevToUse = Writer.getExprImplicitCastAbbrev(); Index: lib/Serialization/ASTReaderStmt.cpp === --- lib/Serialization/ASTReaderStmt.cpp +++ lib/Serialization/ASTReaderStmt.cpp @@ -723,7 +723,6 @@ assert(NumBaseSpecs == E->path_size()); E->setSubExpr(Record.readSubExpr()); E->setCastKind((CastKind)Record.readInt()); - E->setIsPartOfExplicitCast(Record.readInt()); CastExpr::path_iterator BaseI = E->path_begin(); while (NumBaseSpecs--) { auto *BaseSpec = new (Record.getContext()) CXXBaseSpecifier; @@ -770,6 +769,7 @@ void ASTStmtReader::VisitImplicitCastExpr(ImplicitCastExpr *E) { VisitCastExpr(E); + E->setIsPartOfExplicitCast(Record.readInt()); } void ASTStmtReader::VisitExplicitCastExpr(ExplicitCastExpr *E) { Index: lib/Sema/SemaCast.cpp === --- lib/Sema/SemaCast.cpp +++ lib/Sema/SemaCast.cpp @@ -94,7 +94,7 @@ // ImplicitCastExpr's as being part of ExplicitCastExpr. The original CE // (which is a ExplicitCastExpr), and the OrigSrcExpr are not touched. while ((CE = dyn_cast(CE->getSubExpr( -CE->setIsPartOfExplicitCast(true); +cast(CE)->setIsPartOfExplicitCast(true); } /// Complete an apparently-successful cast operation that yields Index: lib/AST/ASTDumper.cpp === --- lib/AST/ASTDumper.cpp +++ lib/AST/ASTDumper.cpp @@ -521,6 +521,7 @@ // Exprs void VisitExpr(const Expr *Node); void VisitCastExpr(const CastExpr *Node); +void VisitImplicitCastExpr(const ImplicitCastExpr *Node); void VisitDeclRefExpr(const DeclRefExpr *Node); void VisitPredefinedExpr(const PredefinedExpr *Node); void VisitCharacterLiteral(const CharacterLiteral *Node); @@ -2117,7 +2118,10 @@ } dumpBasePath(OS, Node); OS << ">"; +} +void ASTDumper::VisitImplicitCastExpr(const ImplicitCastExpr *Node) { + VisitCastExpr(Node); if (Node->getIsPartOfExplicitCast()) OS << " part_of_explicit_cast"; } Index: include/clang/AST/Stmt.h === --- include/clang/AST/Stmt.h +++ include/clang/AST/Stmt.h @@ -198,11 +198,12 @@ class CastExprBitfields { friend class CastExpr; +friend class ImplicitCastExpr; unsigned : NumExprBits; unsigned Kind : 6; -unsigned PartOfExplicitCast : 1; +unsigned PartOfExplicitCast : 1; // Only representable for ImplicitCastExpr. unsigned BasePathSize : 32 - 6 - 1 - NumExprBits; }; Index: include/clang/AST/Expr.h === --- include/clang/AST/Expr.h +++ include/clang/AST/Expr.h @@ -2829,20 +2829,14 @@ /// Construct an empty cast. CastExpr(StmtClass SC, EmptyShell Empty, unsigned BasePathSize) : Expr(SC, Empty) { +CastExprBits.PartOfExplicitCast = false; setBasePathSize(BasePathSize); } public: CastKind getCastKind() const { return (CastKind) CastExprBits.Kind; } void setCastKind(CastKind K) { CastExprBits.Kind = K; } - bool getIsPartOfExplicitCast() const { -return CastExprBits.PartOfExplicitCast; - } - void setIsPartOfExplicitCast(bool PartOfExplicitCast) { -CastExprBits.PartOfExplicitCast = PartOfExplicitCast; - } - static const char *getCastKindName(CastKind CK); const char *getCastKindName() const { return getCastKindName(getCastKind()); } @@ -2931,6 +2925,13 @@ : CastExpr(ImplicitCastExprClass, ty, VK, kind, op, 0) { } + bool getIsPartOfExplicitCast() const { +return CastExprBits.PartOfExplicitCast; + } + void setIsPartOfExplicitCast(bool PartOfExplicitCast) { +CastExprBits.PartOfExplicitCast = PartOfExplicitCast; + } + static ImplicitCastExpr *Create(const ASTContext , QualType T,
[PATCH] D49838: [AST] Sink 'part of explicit cast' down into ImplicitCastExpr
lebedev.ri added a comment. In https://reviews.llvm.org/D49838#1176622, @erichkeane wrote: > 2 small items, otherwise looks good. Thank you for taking a look! Comment at: include/clang/AST/Expr.h:2824 CastExprBits.Kind = kind; -CastExprBits.PartOfExplicitCast = false; setBasePathSize(BasePathSize); erichkeane wrote: > So, I'd prefer that this line get left in. Removing this makes it the single > unused item in CastExprBitfields, so leaving it uninitialized is likely a bad > idea. Aha, ok. That will result in less ` CastExprBits.PartOfExplicitCast = false;` lines scattered across different constructors, too. Comment at: include/clang/AST/Expr.h:2832 : Expr(SC, Empty) { setBasePathSize(BasePathSize); } Oh, i forget to init it here. Comment at: lib/Sema/SemaCast.cpp:97 while ((CE = dyn_cast(CE->getSubExpr( -CE->setIsPartOfExplicitCast(true); +dyn_cast(CE)->setIsPartOfExplicitCast(true); } erichkeane wrote: > I think I'd prefer just using a different variable in the 'while' loop to > avoid the cast. something like while((auto ICE = > > That said, either way this isn't a dyn_cast, this would be just a cast (since > we KNOW the type). I was trying to avoid having one extra variable, which may confuse things. Let's see maybe it's not that ugly.. Repository: rC Clang https://reviews.llvm.org/D49838 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D49838: [AST] Sink 'part of explicit cast' down into ImplicitCastExpr
erichkeane added a comment. 2 small items, otherwise looks good. Comment at: include/clang/AST/Expr.h:2824 CastExprBits.Kind = kind; -CastExprBits.PartOfExplicitCast = false; setBasePathSize(BasePathSize); So, I'd prefer that this line get left in. Removing this makes it the single unused item in CastExprBitfields, so leaving it uninitialized is likely a bad idea. Comment at: lib/Sema/SemaCast.cpp:97 while ((CE = dyn_cast(CE->getSubExpr( -CE->setIsPartOfExplicitCast(true); +dyn_cast(CE)->setIsPartOfExplicitCast(true); } I think I'd prefer just using a different variable in the 'while' loop to avoid the cast. something like while((auto ICE = That said, either way this isn't a dyn_cast, this would be just a cast (since we KNOW the type). Repository: rC Clang https://reviews.llvm.org/D49838 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D49838: [AST] Sink 'part of explicit cast' down into ImplicitCastExpr
lebedev.ri created this revision. lebedev.ri added reviewers: rsmith, rjmccall, erichkeane, aaron.ballman. lebedev.ri added a project: clang. lebedev.ri added a dependency: D49508: [Sema] Mark implicitly-inserted ICE's as being part of explicit cast (PR38166). As discussed in IRC with @rsmith, it is slightly not good to keep that in the `CastExpr` itself: Given the explicit cast, which is represented in AST as an `ExplicitCastExpr` + `ImplicitCastExpr`'s, only the `ImplicitCastExpr`'s will be marked as `PartOfExplicitCast`, but not the `ExplicitCastExpr` itself. Thus, it is only ever `true` for `ImplicitCastExpr`'s, so we don't need to write/read/dump it for `ExplicitCastExpr`'s. Repository: rC Clang https://reviews.llvm.org/D49838 Files: include/clang/AST/Expr.h include/clang/AST/Stmt.h lib/AST/ASTDumper.cpp lib/Sema/SemaCast.cpp lib/Serialization/ASTReaderStmt.cpp lib/Serialization/ASTWriterStmt.cpp Index: lib/Serialization/ASTWriterStmt.cpp === --- lib/Serialization/ASTWriterStmt.cpp +++ lib/Serialization/ASTWriterStmt.cpp @@ -665,7 +665,6 @@ Record.push_back(E->path_size()); Record.AddStmt(E->getSubExpr()); Record.push_back(E->getCastKind()); // FIXME: stable encoding - Record.push_back(E->getIsPartOfExplicitCast()); for (CastExpr::path_iterator PI = E->path_begin(), PE = E->path_end(); PI != PE; ++PI) @@ -714,6 +713,7 @@ void ASTStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) { VisitCastExpr(E); + Record.push_back(E->getIsPartOfExplicitCast()); if (E->path_size() == 0) AbbrevToUse = Writer.getExprImplicitCastAbbrev(); Index: lib/Serialization/ASTReaderStmt.cpp === --- lib/Serialization/ASTReaderStmt.cpp +++ lib/Serialization/ASTReaderStmt.cpp @@ -723,7 +723,6 @@ assert(NumBaseSpecs == E->path_size()); E->setSubExpr(Record.readSubExpr()); E->setCastKind((CastKind)Record.readInt()); - E->setIsPartOfExplicitCast(Record.readInt()); CastExpr::path_iterator BaseI = E->path_begin(); while (NumBaseSpecs--) { auto *BaseSpec = new (Record.getContext()) CXXBaseSpecifier; @@ -770,6 +769,7 @@ void ASTStmtReader::VisitImplicitCastExpr(ImplicitCastExpr *E) { VisitCastExpr(E); + E->setIsPartOfExplicitCast(Record.readInt()); } void ASTStmtReader::VisitExplicitCastExpr(ExplicitCastExpr *E) { Index: lib/Sema/SemaCast.cpp === --- lib/Sema/SemaCast.cpp +++ lib/Sema/SemaCast.cpp @@ -94,7 +94,7 @@ // ImplicitCastExpr's as being part of ExplicitCastExpr. The original CE // (which is a ExplicitCastExpr), and the OrigSrcExpr are not touched. while ((CE = dyn_cast(CE->getSubExpr( -CE->setIsPartOfExplicitCast(true); +dyn_cast(CE)->setIsPartOfExplicitCast(true); } /// Complete an apparently-successful cast operation that yields Index: lib/AST/ASTDumper.cpp === --- lib/AST/ASTDumper.cpp +++ lib/AST/ASTDumper.cpp @@ -521,6 +521,7 @@ // Exprs void VisitExpr(const Expr *Node); void VisitCastExpr(const CastExpr *Node); +void VisitImplicitCastExpr(const ImplicitCastExpr *Node); void VisitDeclRefExpr(const DeclRefExpr *Node); void VisitPredefinedExpr(const PredefinedExpr *Node); void VisitCharacterLiteral(const CharacterLiteral *Node); @@ -2117,7 +2118,10 @@ } dumpBasePath(OS, Node); OS << ">"; +} +void ASTDumper::VisitImplicitCastExpr(const ImplicitCastExpr *Node) { + VisitCastExpr(Node); if (Node->getIsPartOfExplicitCast()) OS << " part_of_explicit_cast"; } Index: include/clang/AST/Stmt.h === --- include/clang/AST/Stmt.h +++ include/clang/AST/Stmt.h @@ -198,6 +198,7 @@ class CastExprBitfields { friend class CastExpr; +friend class ImplicitCastExpr; unsigned : NumExprBits; Index: include/clang/AST/Expr.h === --- include/clang/AST/Expr.h +++ include/clang/AST/Expr.h @@ -2821,7 +2821,6 @@ (op && op->containsUnexpandedParameterPack(, Op(op) { CastExprBits.Kind = kind; -CastExprBits.PartOfExplicitCast = false; setBasePathSize(BasePathSize); assert(CastConsistency()); } @@ -2836,13 +2835,6 @@ CastKind getCastKind() const { return (CastKind) CastExprBits.Kind; } void setCastKind(CastKind K) { CastExprBits.Kind = K; } - bool getIsPartOfExplicitCast() const { -return CastExprBits.PartOfExplicitCast; - } - void setIsPartOfExplicitCast(bool PartOfExplicitCast) { -CastExprBits.PartOfExplicitCast = PartOfExplicitCast; - } - static const char *getCastKindName(CastKind CK); const char *getCastKindName() const { return getCastKindName(getCastKind()); } @@