15#include "clang/AST/DeclCXX.h"
16#include "llvm/ADT/DenseSet.h"
17#include "llvm/ADT/ScopeExit.h"
26 return Name.size() >= 2 &&
Name[0] ==
'_' &&
27 (isUppercase(
Name[1]) ||
Name[1] ==
'_');
35class AggregateDesignatorNames {
37 AggregateDesignatorNames(QualType T) {
39 T =
T.getCanonicalType();
40 if (
T->isArrayType()) {
45 if (
const RecordDecl *RD =
T->getAsRecordDecl()) {
47 FieldsIt = RD->field_begin();
48 FieldsEnd = RD->field_end();
49 if (
const auto *CRD = llvm::dyn_cast<CXXRecordDecl>(RD)) {
50 BasesIt = CRD->bases_begin();
51 BasesEnd = CRD->bases_end();
52 Valid = CRD->isAggregate();
54 OneField = Valid && BasesIt == BasesEnd && FieldsIt != FieldsEnd &&
55 std::next(FieldsIt) == FieldsEnd;
60 operator bool() {
return Valid; }
65 else if (BasesIt != BasesEnd)
67 else if (FieldsIt != FieldsEnd)
72 bool append(std::string &
Out,
bool ForSubobject) {
75 Out.append(std::to_string(Index));
79 if (BasesIt != BasesEnd)
81 if (FieldsIt != FieldsEnd) {
82 llvm::StringRef FieldName;
83 if (
const IdentifierInfo *II = FieldsIt->getIdentifier())
84 FieldName = II->getName();
88 (FieldsIt->isAnonymousStructOrUnion() ||
95 Out.append(FieldName.begin(), FieldName.end());
105 bool IsArray =
false;
106 bool OneField =
false;
108 CXXRecordDecl::base_class_const_iterator BasesIt;
109 CXXRecordDecl::base_class_const_iterator BasesEnd;
110 RecordDecl::field_iterator FieldsIt;
111 RecordDecl::field_iterator FieldsEnd;
129void 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())
135 assert(Sem->isSemanticForm());
139 AggregateDesignatorNames Fields(Sem->getType());
142 for (
const Expr *Init : Sem->inits()) {
143 auto Next = llvm::make_scope_exit([&, Size(Prefix.size())] {
149 if (!Init || llvm::isa<ImplicitValueInitExpr>(Init))
152 const auto *BraceElidedSubobject = llvm::dyn_cast<InitListExpr>(Init);
153 if (BraceElidedSubobject &&
154 NestedBraces.contains(BraceElidedSubobject->getLBraceLoc()))
155 BraceElidedSubobject =
nullptr;
157 if (!Fields.append(Prefix, BraceElidedSubobject !=
nullptr))
159 if (BraceElidedSubobject) {
165 collectDesignators(BraceElidedSubobject,
Out, NestedBraces, Prefix);
168 Out.try_emplace(Init->getBeginLoc(), Prefix);
174llvm::DenseMap<SourceLocation, std::string>
176 assert(Syn->isSyntacticForm());
181 llvm::DenseSet<SourceLocation> NestedBraces;
182 for (
const Expr *Init : Syn->inits())
183 if (
auto *Nested = llvm::dyn_cast<InitListExpr>(Init))
184 NestedBraces.insert(Nested->getLBraceLoc());
188 llvm::DenseMap<SourceLocation, std::string> Designators;
189 std::string EmptyPrefix;
190 collectDesignators(Syn->isSemanticForm() ? Syn : Syn->getSemanticForm(),
191 Designators, NestedBraces, EmptyPrefix);
llvm::SmallString< 256U > Name
CompiledFragmentImpl & Out
This file provides utilities for designated initializers.
bool isReservedName(llvm::StringRef Name)
Returns true if Name is reserved, like _Foo or __Vector_base.
llvm::DenseMap< SourceLocation, std::string > getUnwrittenDesignators(const InitListExpr *Syn)