15#include "clang/AST/DeclCXX.h"
16#include "clang/AST/Type.h"
17#include "llvm/ADT/ScopeExit.h"
24 return Name.size() >= 2 && Name[0] ==
'_' &&
25 (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 = 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()
const {
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) {
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;
132 llvm::DenseMap<SourceLocation, std::string> &Out,
133 std::string &Prefix) {
134 if (!Sem || Sem->isTransparent())
136 assert(Sem->isSemanticForm());
140 AggregateDesignatorNames Fields(Sem->getType());
143 for (
const Expr *Init : Sem->inits()) {
144 const llvm::scope_exit Next([&, Size(Prefix.size())] {
150 if (!Init || isa<ImplicitValueInitExpr>(Init))
153 const auto *BraceElidedSubobject = dyn_cast<InitListExpr>(Init);
154 if (BraceElidedSubobject && BraceElidedSubobject->isExplicit())
155 BraceElidedSubobject =
nullptr;
157 if (!Fields.append(Prefix, BraceElidedSubobject !=
nullptr))
159 if (BraceElidedSubobject) {
166 Out.try_emplace(Init->getBeginLoc(), Prefix);
170llvm::DenseMap<SourceLocation, std::string>
174 llvm::DenseMap<SourceLocation, std::string> Designators;
175 std::string EmptyPrefix;
177 Designators, EmptyPrefix);
This file provides utilities for designated initializers.
static bool isReservedName(StringRef Name)
Returns true if Name is reserved, like _Foo or __Vector_base.
llvm::DenseMap< SourceLocation, std::string > getUnwrittenDesignators(const InitListExpr *Syn)
Get designators describing the elements of a (syntactic) init list.
static void collectDesignators(const InitListExpr *Sem, llvm::DenseMap< SourceLocation, std::string > &Out, std::string &Prefix)