1 | //===--- DesignatedInitializers.cpp - clang-tidy --------------------------===// |
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 | /// \file |
10 | /// This file provides utilities for designated initializers. |
11 | /// |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #include "DesignatedInitializers.h" |
15 | #include "clang/AST/DeclCXX.h" |
16 | #include "llvm/ADT/DenseSet.h" |
17 | #include "llvm/ADT/ScopeExit.h" |
18 | |
19 | namespace clang::tidy::utils { |
20 | |
21 | namespace { |
22 | |
23 | /// Returns true if Name is reserved, like _Foo or __Vector_base. |
24 | static inline bool isReservedName(llvm::StringRef Name) { |
25 | // This doesn't catch all cases, but the most common. |
26 | return Name.size() >= 2 && Name[0] == '_' && |
27 | (isUppercase(c: Name[1]) || Name[1] == '_'); |
28 | } |
29 | |
30 | // Helper class to iterate over the designator names of an aggregate type. |
31 | // |
32 | // For an array type, yields [0], [1], [2]... |
33 | // For aggregate classes, yields null for each base, then .field1, .field2, |
34 | // ... |
35 | class AggregateDesignatorNames { |
36 | public: |
37 | AggregateDesignatorNames(QualType T) { |
38 | if (!T.isNull()) { |
39 | T = T.getCanonicalType(); |
40 | if (T->isArrayType()) { |
41 | IsArray = true; |
42 | Valid = true; |
43 | return; |
44 | } |
45 | if (const RecordDecl *RD = T->getAsRecordDecl()) { |
46 | Valid = true; |
47 | FieldsIt = RD->field_begin(); |
48 | FieldsEnd = RD->field_end(); |
49 | if (const auto *CRD = llvm::dyn_cast<CXXRecordDecl>(Val: RD)) { |
50 | BasesIt = CRD->bases_begin(); |
51 | BasesEnd = CRD->bases_end(); |
52 | Valid = CRD->isAggregate(); |
53 | } |
54 | OneField = Valid && BasesIt == BasesEnd && FieldsIt != FieldsEnd && |
55 | std::next(x: FieldsIt) == FieldsEnd; |
56 | } |
57 | } |
58 | } |
59 | // Returns false if the type was not an aggregate. |
60 | operator bool() { return Valid; } |
61 | // Advance to the next element in the aggregate. |
62 | void next() { |
63 | if (IsArray) |
64 | ++Index; |
65 | else if (BasesIt != BasesEnd) |
66 | ++BasesIt; |
67 | else if (FieldsIt != FieldsEnd) |
68 | ++FieldsIt; |
69 | } |
70 | // Print the designator to Out. |
71 | // Returns false if we could not produce a designator for this element. |
72 | bool append(std::string &Out, bool ForSubobject) { |
73 | if (IsArray) { |
74 | Out.push_back(c: '['); |
75 | Out.append(str: std::to_string(val: Index)); |
76 | Out.push_back(c: ']'); |
77 | return true; |
78 | } |
79 | if (BasesIt != BasesEnd) |
80 | return false; // Bases can't be designated. Should we make one up? |
81 | if (FieldsIt != FieldsEnd) { |
82 | llvm::StringRef FieldName; |
83 | if (const IdentifierInfo *II = FieldsIt->getIdentifier()) |
84 | FieldName = II->getName(); |
85 | |
86 | // For certain objects, their subobjects may be named directly. |
87 | if (ForSubobject && |
88 | (FieldsIt->isAnonymousStructOrUnion() || |
89 | // std::array<int,3> x = {1,2,3}. Designators not strictly valid! |
90 | (OneField && isReservedName(Name: FieldName)))) |
91 | return true; |
92 | |
93 | if (!FieldName.empty() && !isReservedName(Name: FieldName)) { |
94 | Out.push_back(c: '.'); |
95 | Out.append(first: FieldName.begin(), last: FieldName.end()); |
96 | return true; |
97 | } |
98 | return false; |
99 | } |
100 | return false; |
101 | } |
102 | |
103 | private: |
104 | bool Valid = false; |
105 | bool IsArray = false; |
106 | bool OneField = false; // e.g. std::array { T __elements[N]; } |
107 | unsigned Index = 0; |
108 | CXXRecordDecl::base_class_const_iterator BasesIt; |
109 | CXXRecordDecl::base_class_const_iterator BasesEnd; |
110 | RecordDecl::field_iterator FieldsIt; |
111 | RecordDecl::field_iterator FieldsEnd; |
112 | }; |
113 | |
114 | // Collect designator labels describing the elements of an init list. |
115 | // |
116 | // This function contributes the designators of some (sub)object, which is |
117 | // represented by the semantic InitListExpr Sem. |
118 | // This includes any nested subobjects, but *only* if they are part of the |
119 | // same original syntactic init list (due to brace elision). In other words, |
120 | // it may descend into subobjects but not written init-lists. |
121 | // |
122 | // For example: struct Outer { Inner a,b; }; struct Inner { int x, y; } |
123 | // Outer o{{1, 2}, 3}; |
124 | // This function will be called with Sem = { {1, 2}, {3, ImplicitValue} } |
125 | // It should generate designators '.a:' and '.b.x:'. |
126 | // '.a:' is produced directly without recursing into the written sublist. |
127 | // (The written sublist will have a separate collectDesignators() call later). |
128 | // Recursion with Prefix='.b' and Sem = {3, ImplicitValue} produces '.b.x:'. |
129 | void collectDesignators(const InitListExpr *Sem, |
130 | llvm::DenseMap<SourceLocation, std::string> &Out, |
131 | const llvm::DenseSet<SourceLocation> &NestedBraces, |
132 | std::string &Prefix) { |
133 | if (!Sem || Sem->isTransparent()) |
134 | return; |
135 | assert(Sem->isSemanticForm()); |
136 | |
137 | // The elements of the semantic form all correspond to direct subobjects of |
138 | // the aggregate type. `Fields` iterates over these subobject names. |
139 | AggregateDesignatorNames Fields(Sem->getType()); |
140 | if (!Fields) |
141 | return; |
142 | for (const Expr *Init : Sem->inits()) { |
143 | auto Next = llvm::make_scope_exit(F: [&, Size(Prefix.size())] { |
144 | Fields.next(); // Always advance to the next subobject name. |
145 | Prefix.resize(n: Size); // Erase any designator we appended. |
146 | }); |
147 | // Skip for a broken initializer or if it is a "hole" in a subobject that |
148 | // was not explicitly initialized. |
149 | if (!Init || llvm::isa<ImplicitValueInitExpr>(Val: Init)) |
150 | continue; |
151 | |
152 | const auto *BraceElidedSubobject = llvm::dyn_cast<InitListExpr>(Val: Init); |
153 | if (BraceElidedSubobject && |
154 | NestedBraces.contains(V: BraceElidedSubobject->getLBraceLoc())) |
155 | BraceElidedSubobject = nullptr; // there were braces! |
156 | |
157 | if (!Fields.append(Out&: Prefix, ForSubobject: BraceElidedSubobject != nullptr)) |
158 | continue; // no designator available for this subobject |
159 | if (BraceElidedSubobject) { |
160 | // If the braces were elided, this aggregate subobject is initialized |
161 | // inline in the same syntactic list. |
162 | // Descend into the semantic list describing the subobject. |
163 | // (NestedBraces are still correct, they're from the same syntactic |
164 | // list). |
165 | collectDesignators(Sem: BraceElidedSubobject, Out, NestedBraces, Prefix); |
166 | continue; |
167 | } |
168 | Out.try_emplace(Init->getBeginLoc(), Prefix); |
169 | } |
170 | } |
171 | |
172 | } // namespace |
173 | |
174 | llvm::DenseMap<SourceLocation, std::string> |
175 | getUnwrittenDesignators(const InitListExpr *Syn) { |
176 | assert(Syn->isSyntacticForm()); |
177 | |
178 | // collectDesignators needs to know which InitListExprs in the semantic tree |
179 | // were actually written, but InitListExpr::isExplicit() lies. |
180 | // Instead, record where braces of sub-init-lists occur in the syntactic form. |
181 | llvm::DenseSet<SourceLocation> NestedBraces; |
182 | for (const Expr *Init : Syn->inits()) |
183 | if (auto *Nested = llvm::dyn_cast<InitListExpr>(Val: Init)) |
184 | NestedBraces.insert(V: Nested->getLBraceLoc()); |
185 | |
186 | // Traverse the semantic form to find the designators. |
187 | // We use their SourceLocation to correlate with the syntactic form later. |
188 | llvm::DenseMap<SourceLocation, std::string> Designators; |
189 | std::string EmptyPrefix; |
190 | collectDesignators(Sem: Syn->isSemanticForm() ? Syn : Syn->getSemanticForm(), |
191 | Out&: Designators, NestedBraces, Prefix&: EmptyPrefix); |
192 | return Designators; |
193 | } |
194 | |
195 | } // namespace clang::tidy::utils |
196 | |