|
12 | 12 | #include "clang/AST/Stmt.h"
|
13 | 13 | #include "clang/ASTMatchers/ASTMatchFinder.h"
|
14 | 14 | #include "clang/ASTMatchers/ASTMatchers.h"
|
| 15 | +#include "clang/ASTMatchers/ASTMatchersMacros.h" |
15 | 16 | #include <algorithm>
|
16 | 17 | #include <iterator>
|
17 | 18 | #include <vector>
|
@@ -40,24 +41,32 @@ UseDesignatedInitializersCheck::UseDesignatedInitializersCheck(
|
40 | 41 | Options.get(IgnoreSingleElementAggregatesName,
|
41 | 42 | IgnoreSingleElementAggregatesDefault)) {}
|
42 | 43 |
|
| 44 | +AST_MATCHER(CXXRecordDecl, isAggregate) { return Node.isAggregate(); } |
| 45 | + |
| 46 | +AST_MATCHER(InitListExpr, isFullyDesignated) { |
| 47 | + return getUndesignatedComponents(&Node).empty(); |
| 48 | +} |
| 49 | + |
| 50 | +AST_MATCHER(InitListExpr, hasSingleElement) { return Node.getNumInits() == 1; } |
43 | 51 | void UseDesignatedInitializersCheck::registerMatchers(MatchFinder *Finder) {
|
44 | 52 | Finder->addMatcher(
|
45 |
| - initListExpr(hasType(recordDecl().bind("type"))).bind("init"), this); |
| 53 | + initListExpr(hasType(cxxRecordDecl(isAggregate()).bind("type")), |
| 54 | + unless(IgnoreSingleElementAggregates ? hasSingleElement() |
| 55 | + : unless(anything())), |
| 56 | + unless(isFullyDesignated())) |
| 57 | + .bind("init"), |
| 58 | + this); |
46 | 59 | }
|
47 | 60 |
|
48 | 61 | void UseDesignatedInitializersCheck::check(
|
49 | 62 | const MatchFinder::MatchResult &Result) {
|
50 | 63 | const auto *InitList = Result.Nodes.getNodeAs<InitListExpr>("init");
|
51 | 64 | const auto *Type = Result.Nodes.getNodeAs<CXXRecordDecl>("type");
|
52 |
| - if (!Type || !InitList || !Type->isAggregate()) |
53 |
| - return; |
54 |
| - if (IgnoreSingleElementAggregates && InitList->getNumInits() == 1) |
| 65 | + if (!Type || !InitList) |
55 | 66 | return;
|
56 | 67 | if (const auto *SyntacticInitList = InitList->getSyntacticForm()) {
|
57 | 68 | const auto UndesignatedComponents =
|
58 | 69 | getUndesignatedComponents(SyntacticInitList);
|
59 |
| - if (UndesignatedComponents.empty()) |
60 |
| - return; |
61 | 70 | if (UndesignatedComponents.size() == SyntacticInitList->getNumInits()) {
|
62 | 71 | diag(InitList->getLBraceLoc(), "use designated initializer list");
|
63 | 72 | return;
|
|
0 commit comments