1 //===--- IdDependentBackwardBranchCheck.h - clang-tidy ----------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ALTERA_IDDEPENDENTBACKWARDBRANCHCHECK_H 10 #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ALTERA_IDDEPENDENTBACKWARDBRANCHCHECK_H 11 12 #include "../ClangTidyCheck.h" 13 14 namespace clang::tidy::altera { 15 16 /// Finds ID-dependent variables and fields used within loops, and warns of 17 /// their usage. Using these variables in loops can lead to performance 18 /// degradation. 19 /// 20 /// For the user-facing documentation see: 21 /// http://clang.llvm.org/extra/clang-tidy/checks/altera/id-dependent-backward-branch.html 22 class IdDependentBackwardBranchCheck : public ClangTidyCheck { 23 private: 24 enum LoopType { UnknownLoop = -1, DoLoop = 0, WhileLoop = 1, ForLoop = 2 }; 25 // Stores information necessary for printing out source of error. 26 struct IdDependencyRecord { IdDependencyRecordIdDependencyRecord27 IdDependencyRecord(const VarDecl *Declaration, SourceLocation Location, 28 const llvm::Twine &Message) 29 : VariableDeclaration(Declaration), Location(Location), 30 Message(Message.str()) {} IdDependencyRecordIdDependencyRecord31 IdDependencyRecord(const FieldDecl *Declaration, SourceLocation Location, 32 const llvm::Twine &Message) 33 : FieldDeclaration(Declaration), Location(Location), 34 Message(Message.str()) {} 35 IdDependencyRecord() = default; 36 const VarDecl *VariableDeclaration = nullptr; 37 const FieldDecl *FieldDeclaration = nullptr; 38 SourceLocation Location; 39 std::string Message; 40 }; 41 // Stores the locations where ID-dependent variables are created. 42 std::map<const VarDecl *, IdDependencyRecord> IdDepVarsMap; 43 // Stores the locations where ID-dependent fields are created. 44 std::map<const FieldDecl *, IdDependencyRecord> IdDepFieldsMap; 45 /// Returns an IdDependencyRecord if the Expression contains an ID-dependent 46 /// variable, returns a nullptr otherwise. 47 IdDependencyRecord *hasIdDepVar(const Expr *Expression); 48 /// Returns an IdDependencyRecord if the Expression contains an ID-dependent 49 /// field, returns a nullptr otherwise. 50 IdDependencyRecord *hasIdDepField(const Expr *Expression); 51 /// Stores the location an ID-dependent variable is created from a call to 52 /// an ID function in IdDepVarsMap. 53 void saveIdDepVar(const Stmt *Statement, const VarDecl *Variable); 54 /// Stores the location an ID-dependent field is created from a call to an ID 55 /// function in IdDepFieldsMap. 56 void saveIdDepField(const Stmt *Statement, const FieldDecl *Field); 57 /// Stores the location an ID-dependent variable is created from a reference 58 /// to another ID-dependent variable or field in IdDepVarsMap. 59 void saveIdDepVarFromReference(const DeclRefExpr *RefExpr, 60 const MemberExpr *MemExpr, 61 const VarDecl *PotentialVar); 62 /// Stores the location an ID-dependent field is created from a reference to 63 /// another ID-dependent variable or field in IdDepFieldsMap. 64 void saveIdDepFieldFromReference(const DeclRefExpr *RefExpr, 65 const MemberExpr *MemExpr, 66 const FieldDecl *PotentialField); 67 /// Returns the loop type. 68 LoopType getLoopType(const Stmt *Loop); 69 70 public: IdDependentBackwardBranchCheck(StringRef Name,ClangTidyContext * Context)71 IdDependentBackwardBranchCheck(StringRef Name, ClangTidyContext *Context) 72 : ClangTidyCheck(Name, Context) {} 73 void registerMatchers(ast_matchers::MatchFinder *Finder) override; 74 void check(const ast_matchers::MatchFinder::MatchResult &Result) override; 75 }; 76 77 } // namespace clang::tidy::altera 78 79 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ALTERA_IDDEPENDENTBACKWARDBRANCHCHECK_H 80