| 25 | } |
| 26 | |
| 27 | std::vector<std::pair<std::string, ASTValue>> |
| 28 | ConstAnalyzer::extractConst(clang::ASTUnit &AST) { |
| 29 | std::vector<std::pair<std::string, ASTValue>> Constants; |
| 30 | const std::string Tag = "VarDecl"; |
| 31 | auto &Ctx = AST.getASTContext(); |
| 32 | auto Matcher = clang::ast_matchers::varDecl( |
| 33 | clang::ast_matchers::unless( |
| 34 | clang::ast_matchers::isExpansionInSystemHeader())) |
| 35 | .bind(Tag); |
| 36 | for (auto &Node : clang::ast_matchers::match(Matcher, Ctx)) { |
| 37 | auto *Record = Node.getNodeAs<clang::VarDecl>(Tag); |
| 38 | if (!Record) |
| 39 | continue; |
| 40 | |
| 41 | auto *Init = Record->getInit(); |
| 42 | if (!Init || |
| 43 | llvm::isa_and_nonnull<clang::OffsetOfExpr>(Init->IgnoreCasts())) |
| 44 | continue; |
| 45 | |
| 46 | auto T = Record->getType(); |
| 47 | if (T.isNull() || !T.isConstant(Ctx)) |
| 48 | continue; |
| 49 | |
| 50 | auto Name = Record->getQualifiedNameAsString(); |
| 51 | if (Name.empty()) |
| 52 | continue; |
| 53 | |
| 54 | ASTValue Value(*Init, Ctx); |
| 55 | if (!Value.isValid()) |
| 56 | continue; |
| 57 | |
| 58 | Constants.emplace_back(std::make_pair(Name, Value)); |
| 59 | } |
| 60 | return Constants; |
| 61 | } |