clang-tools 22.0.0git
Designator.h
Go to the documentation of this file.
1//===-- tools/extra/clang-reorder-fields/utils/Designator.h -----*- C++ -*-===//
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 contains the declarations of the Designator and Designators
11/// utility classes.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_REORDER_FIELDS_UTILS_DESIGNATOR_H
16#define LLVM_CLANG_TOOLS_EXTRA_CLANG_REORDER_FIELDS_UTILS_DESIGNATOR_H
17
18#include "clang/AST/Decl.h"
19#include "clang/AST/Expr.h"
20#include "clang/AST/Type.h"
21
22namespace clang {
23namespace reorder_fields {
24
25/// Represents a part of a designation in a C99/C++20 designated initializer. It
26/// is a tagged union of different kinds of designators: struct, array and array
27/// range. Holds enough information to be able to advance to the next field and
28/// to know when all fields have been iterated through.
30public:
32
33 Designator(const QualType Type, RecordDecl::field_iterator Field,
34 const RecordDecl *RD)
35 : Tag(STRUCT), Type(Type), StructIt({Field, RD}) {}
36
37 Designator(const QualType Type, uint64_t Idx, uint64_t Size)
38 : Tag(ARRAY), Type(Type), ArrayIt({Idx, Size}) {}
39
40 Designator(const QualType Type, uint64_t Start, uint64_t End, uint64_t Size)
41 : Tag(ARRAY_RANGE), Type(Type), ArrayRangeIt({Start, End, Size}) {}
42
43 /// Moves the iterator to the next element.
44 void advanceToNextField();
45
46 /// Checks if the iterator has iterated through all elements.
47 bool isFinished();
48
49 Kind getTag() const { return Tag; }
50 QualType getType() const { return Type; }
51
52 const RecordDecl::field_iterator getStructIter() const {
53 assert(Tag == STRUCT && "Must be a field designator");
54 return StructIt.Field;
55 }
56
57 const RecordDecl *getStructDecl() const {
58 assert(Tag == STRUCT && "Must be a field designator");
59 return StructIt.Record;
60 }
61
62 uint64_t getArrayIndex() const {
63 assert(Tag == ARRAY && "Must be an array designator");
64 return ArrayIt.Index;
65 }
66
67 uint64_t getArrayRangeStart() const {
68 assert(Tag == ARRAY_RANGE && "Must be an array range designator");
69 return ArrayRangeIt.Start;
70 }
71
72 uint64_t getArrayRangeEnd() const {
73 assert(Tag == ARRAY_RANGE && "Must be an array range designator");
74 return ArrayRangeIt.End;
75 }
76
77 uint64_t getArraySize() const {
78 assert((Tag == ARRAY || Tag == ARRAY_RANGE) &&
79 "Must be an array or range designator");
80 if (Tag == ARRAY)
81 return ArrayIt.Size;
82 return ArrayRangeIt.Size;
83 }
84
85private:
86 /// Type of the designator.
87 Kind Tag;
88
89 /// Type of the designated entry. For arrays this is the type of the element.
90 QualType Type;
91
92 /// Field designator has the iterator to the field and the record the field
93 /// is declared in.
94 struct StructIter {
95 RecordDecl::field_iterator Field;
96 const RecordDecl *Record;
97 };
98
99 /// Array designator has an index and size of the array.
100 struct ArrayIter {
101 uint64_t Index;
102 uint64_t Size;
103 };
104
105 /// Array range designator has a start and end index and size of the array.
106 struct ArrayRangeIter {
107 uint64_t Start;
108 uint64_t End;
109 uint64_t Size;
110 };
111
112 union {
113 StructIter StructIt;
114 ArrayIter ArrayIt;
115 ArrayRangeIter ArrayRangeIt;
116 };
117};
118
119/// List of designators.
121public:
122 /// Initialize to the first member of the struct/array. Enters implicit
123 /// initializer lists until a type that matches Init is found.
124 Designators(const Expr *Init, const InitListExpr *ILE,
125 const ASTContext *Context);
126
127 /// Initialize to the designators of the given expression.
128 Designators(const DesignatedInitExpr *DIE, const InitListExpr *ILE,
129 const ASTContext *Context);
130
131 /// Return whether this designator list is valid.
132 bool isValid() const { return !DesignatorList.empty(); }
133
134 /// Moves the designators to the next initializer in the struct/array. If the
135 /// type of next initializer doesn't match the expected type then there are
136 /// omitted braces and we add new designators to reflect that.
137 bool advanceToNextField(const Expr *Init);
138
139 /// Gets a string representation from a list of designators. This string will
140 /// be inserted before an initializer expression to make it designated.
141 std::string toString() const;
142
143 size_t size() const { return DesignatorList.size(); }
144
145 SmallVector<Designator>::const_iterator begin() const {
146 return DesignatorList.begin();
147 }
148 SmallVector<Designator>::const_iterator end() const {
149 return DesignatorList.end();
150 }
151
152private:
153 /// Enters any implicit initializer lists until a type that matches the given
154 /// expression is found.
155 bool enterImplicitInitLists(const Expr *Init);
156
157 const ASTContext *Context;
158 SmallVector<Designator, 1> DesignatorList;
159};
160
161} // namespace reorder_fields
162} // namespace clang
163
164#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_REORDER_FIELDS_UTILS_DESIGNATOR_H
bool isFinished()
Checks if the iterator has iterated through all elements.
const RecordDecl * getStructDecl() const
Definition Designator.h:57
uint64_t getArrayRangeStart() const
Definition Designator.h:67
Designator(const QualType Type, uint64_t Start, uint64_t End, uint64_t Size)
Definition Designator.h:40
void advanceToNextField()
Moves the iterator to the next element.
Designator(const QualType Type, uint64_t Idx, uint64_t Size)
Definition Designator.h:37
uint64_t getArrayRangeEnd() const
Definition Designator.h:72
Designator(const QualType Type, RecordDecl::field_iterator Field, const RecordDecl *RD)
Definition Designator.h:33
const RecordDecl::field_iterator getStructIter() const
Definition Designator.h:52
std::string toString() const
Gets a string representation from a list of designators.
bool advanceToNextField(const Expr *Init)
Moves the designators to the next initializer in the struct/array.
SmallVector< Designator >::const_iterator begin() const
Definition Designator.h:145
Designators(const Expr *Init, const InitListExpr *ILE, const ASTContext *Context)
Initialize to the first member of the struct/array.
bool isValid() const
Return whether this designator list is valid.
Definition Designator.h:132
SmallVector< Designator >::const_iterator end() const
Definition Designator.h:148
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//