diff options
author | Stephen Kelly <steveire@gmail.com> | 2019-05-04 16:51:58 +0100 |
---|---|---|
committer | Stephen Kelly <steveire@gmail.com> | 2019-12-18 22:33:23 +0000 |
commit | 98e8f774eb6ca8946b3104b4e82beefd41ca2c35 (patch) | |
tree | a8452417e927406cee681323fa71bae48cd5ef76 /clang/lib | |
parent | 84fd2bedf4096e78b892165138051b8563169fe3 (diff) | |
download | bcm5719-llvm-98e8f774eb6ca8946b3104b4e82beefd41ca2c35.tar.gz bcm5719-llvm-98e8f774eb6ca8946b3104b4e82beefd41ca2c35.zip |
Add method to ignore invisible AST nodes
Reviewers: aaron.ballman
Subscribers: mgorny, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D70613
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 2 | ||||
-rw-r--r-- | clang/lib/AST/Expr.cpp | 28 |
2 files changed, 30 insertions, 0 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index da279fa8215..a09b1aca7c2 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -112,6 +112,8 @@ Expr *ASTContext::traverseIgnored(Expr *E) const { return E; case ast_type_traits::TK_IgnoreImplicitCastsAndParentheses: return E->IgnoreParenImpCasts(); + case ast_type_traits::TK_IgnoreUnlessSpelledInSource: + return E->IgnoreUnlessSpelledInSource(); } llvm_unreachable("Invalid Traversal type!"); } diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index c4c8fcf2549..5c9ceac854c 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -3020,6 +3020,34 @@ Expr *Expr::IgnoreParenNoopCasts(const ASTContext &Ctx) { }); } +Expr *Expr::IgnoreUnlessSpelledInSource() { + Expr *E = this; + + Expr *LastE = nullptr; + while (E != LastE) { + LastE = E; + E = E->IgnoreImplicit(); + + auto SR = E->getSourceRange(); + + if (auto *C = dyn_cast<CXXConstructExpr>(E)) { + if (C->getNumArgs() == 1) { + Expr *A = C->getArg(0); + if (A->getSourceRange() == SR || !isa<CXXTemporaryObjectExpr>(C)) + E = A; + } + } + + if (auto *C = dyn_cast<CXXMemberCallExpr>(E)) { + Expr *ExprNode = C->getImplicitObjectArgument()->IgnoreParenImpCasts(); + if (ExprNode->getSourceRange() == SR) + E = ExprNode; + } + } + + return E; +} + bool Expr::isDefaultArgument() const { const Expr *E = this; if (const MaterializeTemporaryExpr *M = dyn_cast<MaterializeTemporaryExpr>(E)) |