| // Copyright 2023 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef TOOLS_CLANG_PLUGINS_STACKALLOCATEDCHECKER_H_ |
| #define TOOLS_CLANG_PLUGINS_STACKALLOCATEDCHECKER_H_ |
| |
| #include <map> |
| |
| namespace clang { |
| class CompilerInstance; |
| class CXXRecordDecl; |
| class FieldDecl; |
| } // namespace clang |
| |
| namespace chrome_checker { |
| |
| // This determines a record (class/struct) is annotated with |
| // |STACK_ALLOCATED()|. Even if it is explicitly annotated with |
| // |STACK_ALLOCATED()|, this will consider it as "stack allocated" when its |
| // ancestor has the annotation. Similarly, classes with a "stack allocated" |
| // template type parameter is considered "stack allocated". |
| class StackAllocatedPredicate { |
| public: |
| bool IsStackAllocated(const clang::CXXRecordDecl* record) const; |
| |
| private: |
| mutable std::map<const clang::CXXRecordDecl*, bool> cache_; |
| }; |
| |
| // This verifies usage of classes annotated with STACK_ALLOCATED(). |
| // Specifically, it ensures that an instance of such a class cannot be used as a |
| // member variable in a non-STACK_ALLOCATED() class. |
| class StackAllocatedChecker { |
| public: |
| explicit StackAllocatedChecker(clang::CompilerInstance& compiler); |
| |
| void Check(clang::CXXRecordDecl* record); |
| |
| private: |
| clang::CompilerInstance& compiler_; |
| unsigned stack_allocated_field_error_signature_; |
| StackAllocatedPredicate predicate_; |
| }; |
| |
| } // namespace chrome_checker |
| |
| #endif // TOOLS_CLANG_PLUGINS_STACKALLOCATEDCHECKER_H_ |