| 15 | : InputFilter(FilterName, std::move(NextFilter)) {} |
| 16 | |
| 17 | bool ConstIntArrayLenFilter::check(const ASTIRNode &Node) const { |
| 18 | auto *D = Node.AST.getAssignee().getNode().get<VarDecl>(); |
| 19 | if (!D) |
| 20 | return false; |
| 21 | |
| 22 | auto &Ctx = D->getASTContext(); |
| 23 | auto QT = D->getType(); |
| 24 | auto *T = QT.getTypePtrOrNull(); |
| 25 | if (!QT.isConstant(Ctx) || !T || !T->isIntegerType()) |
| 26 | return false; |
| 27 | |
| 28 | Expr::EvalResult Eval; |
| 29 | auto *Init = D->getInit(); |
| 30 | auto VarName = D->getNameAsString(); |
| 31 | if (!Init || !Init->EvaluateAsInt(Eval, Ctx) || VarName.empty()) |
| 32 | return false; |
| 33 | |
| 34 | auto Value = Eval.Val.getInt().getExtValue(); |
| 35 | if (Value < 0) |
| 36 | return false; |
| 37 | |
| 38 | auto LangOptions = clang::LangOptions(); |
| 39 | auto &SrcManager = Ctx.getSourceManager(); |
| 40 | const std::string Tag = "Tag"; |
| 41 | auto Matcher = varDecl(hasType(constantArrayType())).bind(Tag); |
| 42 | for (auto &Node : match(Matcher, *const_cast<ASTContext *>(&Ctx))) { |
| 43 | auto *Record = Node.getNodeAs<VarDecl>(Tag); |
| 44 | if (!Record) |
| 45 | continue; |
| 46 | |
| 47 | auto Loc = Record->getLocation(); |
| 48 | auto EndLoc = Record->getEndLoc(); |
| 49 | auto Offset = SrcManager.getFileOffset(Loc); |
| 50 | int Length = SrcManager.getFileOffset(EndLoc) - Offset; |
| 51 | if (Length < 0) |
| 52 | continue; |
| 53 | |
| 54 | Length += Lexer::MeasureTokenLength(EndLoc, SrcManager, LangOptions); |
| 55 | auto Content = util::getFileContent(SrcManager.getFileID(Loc), SrcManager); |
| 56 | if (Content.size() < Offset + Length) |
| 57 | continue; |
| 58 | |
| 59 | auto Data = std::string(Content.substr(Offset, Length)); |
| 60 | Data = Data.substr(Data.find("["), Data.find("=")); |
| 61 | if (Data.find(VarName) == std::string::npos) |
| 62 | continue; |
| 63 | |
| 64 | return true; |
| 65 | } |
| 66 | return false; |
| 67 | } |
nothing calls this directly
no test coverage detected