brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.1 KiB · 859be28 Raw
165 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// This file contains the declarations of the Designator and Designators11/// utility classes.12///13//===----------------------------------------------------------------------===//14 15#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_REORDER_FIELDS_UTILS_DESIGNATOR_H16#define LLVM_CLANG_TOOLS_EXTRA_CLANG_REORDER_FIELDS_UTILS_DESIGNATOR_H17 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. It26/// is a tagged union of different kinds of designators: struct, array and array27/// range. Holds enough information to be able to advance to the next field and28/// to know when all fields have been iterated through.29class Designator {30public:31  enum Kind { STRUCT, ARRAY, ARRAY_RANGE };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 field93  /// 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.120class Designators {121public:122  /// Initialize to the first member of the struct/array. Enters implicit123  /// 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 the135  /// type of next initializer doesn't match the expected type then there are136  /// 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 will140  /// 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 given154  /// expression is found.155  bool enterImplicitInitLists(const Expr *Init);156 157  const ASTContext *Context;158  SmallVector<Designator, 1> DesignatorList;159};160 161} // namespace reorder_fields162} // namespace clang163 164#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_REORDER_FIELDS_UTILS_DESIGNATOR_H165