File indexing completed on 2026-05-10 08:36:38
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CLANG_AST_LEXICALLYORDEREDRECURSIVEASTVISITOR_H
0015 #define LLVM_CLANG_AST_LEXICALLYORDEREDRECURSIVEASTVISITOR_H
0016
0017 #include "clang/AST/RecursiveASTVisitor.h"
0018 #include "clang/Basic/LLVM.h"
0019 #include "clang/Basic/SourceManager.h"
0020 #include "llvm/Support/SaveAndRestore.h"
0021
0022 namespace clang {
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058 template <typename Derived>
0059 class LexicallyOrderedRecursiveASTVisitor
0060 : public RecursiveASTVisitor<Derived> {
0061 using BaseType = RecursiveASTVisitor<Derived>;
0062
0063 public:
0064 LexicallyOrderedRecursiveASTVisitor(const SourceManager &SM) : SM(SM) {}
0065
0066 bool TraverseObjCImplementationDecl(ObjCImplementationDecl *D) {
0067
0068
0069
0070 bool Result = BaseType::TraverseObjCImplementationDecl(D);
0071 return TraverseAdditionalLexicallyNestedDeclarations() ? Result : false;
0072 }
0073
0074 bool TraverseObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
0075 bool Result = BaseType::TraverseObjCCategoryImplDecl(D);
0076 return TraverseAdditionalLexicallyNestedDeclarations() ? Result : false;
0077 }
0078
0079 bool TraverseDeclContextHelper(DeclContext *DC) {
0080 if (!DC)
0081 return true;
0082
0083 for (auto I = DC->decls_begin(), E = DC->decls_end(); I != E;) {
0084 Decl *Child = *I;
0085 if (BaseType::canIgnoreChildDeclWhileTraversingDeclContext(Child)) {
0086 ++I;
0087 continue;
0088 }
0089 if (!isa<ObjCImplementationDecl>(Child) &&
0090 !isa<ObjCCategoryImplDecl>(Child)) {
0091 if (!BaseType::getDerived().TraverseDecl(Child))
0092 return false;
0093 ++I;
0094 continue;
0095 }
0096
0097
0098 LexicallyNestedDeclarations.clear();
0099 for (++I; I != E; ++I) {
0100 Decl *Sibling = *I;
0101 if (!SM.isBeforeInTranslationUnit(Sibling->getBeginLoc(),
0102 Child->getEndLoc()))
0103 break;
0104 if (!BaseType::canIgnoreChildDeclWhileTraversingDeclContext(Sibling))
0105 LexicallyNestedDeclarations.push_back(Sibling);
0106 }
0107 if (!BaseType::getDerived().TraverseDecl(Child))
0108 return false;
0109 }
0110 return true;
0111 }
0112
0113 Stmt::child_range getStmtChildren(Stmt *S) { return S->children(); }
0114
0115 SmallVector<Stmt *, 8> getStmtChildren(CXXOperatorCallExpr *CE) {
0116 SmallVector<Stmt *, 8> Children(CE->children());
0117 bool Swap;
0118
0119
0120 switch (CE->getOperator()) {
0121 case OO_Arrow:
0122 case OO_Call:
0123 case OO_Subscript:
0124 Swap = true;
0125 break;
0126 case OO_PlusPlus:
0127 case OO_MinusMinus:
0128
0129 Swap = Children.size() != 2;
0130 break;
0131 default:
0132 Swap = CE->isInfixBinaryOp();
0133 break;
0134 }
0135 if (Swap && Children.size() > 1)
0136 std::swap(Children[0], Children[1]);
0137 return Children;
0138 }
0139
0140 private:
0141 bool TraverseAdditionalLexicallyNestedDeclarations() {
0142
0143
0144
0145
0146
0147 assert(!BaseType::getDerived().shouldTraversePostOrder() &&
0148 "post-order traversal is not supported for lexically ordered "
0149 "recursive ast visitor");
0150 for (Decl *D : LexicallyNestedDeclarations) {
0151 if (!BaseType::getDerived().TraverseDecl(D))
0152 return false;
0153 }
0154 return true;
0155 }
0156
0157 const SourceManager &SM;
0158 llvm::SmallVector<Decl *, 8> LexicallyNestedDeclarations;
0159 };
0160
0161 }
0162
0163 #endif