//===--- LexicallyOrderedRecursiveASTVisitor.h - ----------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file defines the LexicallyOrderedRecursiveASTVisitor interface, which // recursively traverses the entire AST in a lexical order. // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_AST_LEXICALLYORDEREDRECURSIVEASTVISITOR_H #define LLVM_CLANG_AST_LEXICALLYORDEREDRECURSIVEASTVISITOR_H #include "clang/AST/RecursiveASTVisitor.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceManager.h" #include "llvm/Support/SaveAndRestore.h" namespace clang { /// A RecursiveASTVisitor subclass that guarantees that AST traversal is /// performed in a lexical order (i.e. the order in which declarations are /// written in the source). /// /// RecursiveASTVisitor doesn't guarantee lexical ordering because there are /// some declarations, like Objective-C @implementation declarations /// that might be represented in the AST differently to how they were written /// in the source. /// In particular, Objective-C @implementation declarations may contain /// non-Objective-C declarations, like functions: /// /// @implementation MyClass /// /// - (void) method { } /// void normalFunction() { } /// /// @end /// /// Clang's AST stores these declarations outside of the @implementation /// declaration, so the example above would be represented using the following /// AST: /// |-ObjCImplementationDecl ... MyClass /// | `-ObjCMethodDecl ... method /// | ... /// `-FunctionDecl ... normalFunction /// ... /// /// This class ensures that these declarations are traversed before the /// corresponding TraverseDecl for the @implementation returns. This ensures /// that the lexical parent relationship between these declarations and the /// @implementation is preserved while traversing the AST. Note that the /// current implementation doesn't mix these declarations with the declarations /// contained in the @implementation, so the traversal of all of the /// declarations in the @implementation still doesn't follow the lexical order. template <typename Derived> class LexicallyOrderedRecursiveASTVisitor : public RecursiveASTVisitor<Derived> { … }; } // end namespace clang #endif // LLVM_CLANG_AST_LEXICALLYORDEREDRECURSIVEASTVISITOR_H