[clang-tools-extra] 3c07db5 - [Clang] Refactor "Designators" into a unified implementation [NFC]

Bill Wendling via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 7 12:59:48 PST 2023


Author: Bill Wendling
Date: 2023-02-07T12:59:17-08:00
New Revision: 3c07db5f58e9852f35202f0fffed50fc7506f37b

URL: https://github.com/llvm/llvm-project/commit/3c07db5f58e9852f35202f0fffed50fc7506f37b
DIFF: https://github.com/llvm/llvm-project/commit/3c07db5f58e9852f35202f0fffed50fc7506f37b.diff

LOG: [Clang] Refactor "Designators" into a unified implementation [NFC]

The interfaces for designators (i.e. C99 designated initializers) was
done in two slightly different ways. This was rather wasteful as the
differences could be combined into one.

Reviewed By: rsmith

Differential Revision: https://reviews.llvm.org/D140584

Added: 
    clang/include/clang/AST/Designator.h

Modified: 
    clang-tools-extra/clangd/FindTarget.cpp
    clang/include/clang/AST/Expr.h
    clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
    clang/lib/AST/ASTImporter.cpp
    clang/lib/AST/Expr.cpp
    clang/lib/AST/StmtPrinter.cpp
    clang/lib/AST/StmtProfile.cpp
    clang/lib/Index/IndexBody.cpp
    clang/lib/Parse/ParseInit.cpp
    clang/lib/Sema/SemaCodeComplete.cpp
    clang/lib/Sema/SemaExpr.cpp
    clang/lib/Sema/SemaInit.cpp
    clang/lib/Sema/TreeTransform.h
    clang/lib/Serialization/ASTReaderStmt.cpp
    clang/lib/Serialization/ASTWriterStmt.cpp
    clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
    clang/tools/libclang/CIndex.cpp

Removed: 
    clang/include/clang/Sema/Designator.h


################################################################################
diff  --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp
index 1caf70183fdb6..9656d9ba34550 100644
--- a/clang-tools-extra/clangd/FindTarget.cpp
+++ b/clang-tools-extra/clangd/FindTarget.cpp
@@ -285,8 +285,7 @@ struct TargetFinder {
         Outer.add(CCE->getConstructor(), Flags);
       }
       void VisitDesignatedInitExpr(const DesignatedInitExpr *DIE) {
-        for (const DesignatedInitExpr::Designator &D :
-             llvm::reverse(DIE->designators()))
+        for (const Designator &D : llvm::reverse(DIE->designators()))
           if (D.isFieldDesignator()) {
             Outer.add(D.getField(), Flags);
             // We don't know which designator was intended, we assume the outer.
@@ -801,7 +800,7 @@ llvm::SmallVector<ReferenceLoc> refInStmt(const Stmt *S,
     }
 
     void VisitDesignatedInitExpr(const DesignatedInitExpr *DIE) {
-      for (const DesignatedInitExpr::Designator &D : DIE->designators()) {
+      for (const Designator &D : DIE->designators()) {
         if (!D.isFieldDesignator())
           continue;
 

diff  --git a/clang/include/clang/AST/Designator.h b/clang/include/clang/AST/Designator.h
new file mode 100644
index 0000000000000..c9884680da14c
--- /dev/null
+++ b/clang/include/clang/AST/Designator.h
@@ -0,0 +1,326 @@
+//===--- Designator.h - Initialization Designator ---------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines interfaces used to represent designators (i.e. C99
+// designated initializers) during parsing and sema.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_DESIGNATOR_H
+#define LLVM_CLANG_AST_DESIGNATOR_H
+
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace clang {
+
+class Expr;
+class FieldDecl;
+class IdentifierInfo;
+class Sema;
+
+/// Designator - A designator in a C99 designated initializer.
+///
+/// This class is a discriminated union which holds the various
+/// 
diff erent sorts of designators possible. A Designation is an array of
+/// these.  An example of a designator are things like this:
+///
+///      [8] .field [47]        // C99 designation: 3 designators
+///      [8 ... 47]  field:     // GNU extensions: 2 designators
+///
+/// These occur in initializers, e.g.:
+///
+///      int a[10] = {2, 4, [8]=9, 10};
+///
+class Designator {
+  enum DesignatorKind {
+    FieldDesignator,
+    ArrayDesignatorExpr,
+    ArrayDesignatorInt,
+    ArrayRangeDesignatorExpr,
+    ArrayRangeDesignatorInt,
+  };
+
+  DesignatorKind Kind;
+
+  /// A field designator, e.g., ".x = 42".
+  class FieldDesignatorInfo {
+    /// Refers to the field that is being initialized. The low bit of this
+    /// field determines whether this is actually a pointer to an
+    /// IdentifierInfo (if 1) or a FieldDecl (if 0). When initially
+    /// constructed, a field designator will store an IdentifierInfo*. After
+    /// semantic analysis has resolved that name, the field designator will
+    /// instead store a FieldDecl*.
+    uintptr_t NameOrField;
+
+  public:
+    /// The location of the '.' in the designated initializer.
+    SourceLocation DotLoc;
+
+    /// The location of the field name in the designated initializer.
+    SourceLocation NameLoc;
+
+    FieldDesignatorInfo(const IdentifierInfo *II, SourceLocation DotLoc,
+                        SourceLocation NameLoc)
+        : NameOrField(reinterpret_cast<uintptr_t>(II) | 0x01), DotLoc(DotLoc),
+          NameLoc(NameLoc) {}
+
+    FieldDecl *getFieldDecl() const {
+      if (NameOrField & 0x01)
+        return nullptr;
+      return reinterpret_cast<FieldDecl *>(NameOrField);
+    }
+    const IdentifierInfo *getIdentifierInfo() const {
+      if (NameOrField & 0x01)
+        return reinterpret_cast<const IdentifierInfo *>(NameOrField & ~0x1);
+      return nullptr;
+    }
+
+    void set(FieldDecl *FD) { NameOrField = reinterpret_cast<uintptr_t>(FD); }
+  };
+
+  /// An array designator, e.g., "[42] = 0" and "[42 ... 50] = 1".
+  template <typename Ty> struct ArrayDesignatorInfo {
+    /// Location of the first and last index expression within the designated
+    /// initializer expression's list of subexpressions.
+    Ty Start;
+    Ty End;
+
+    /// The location of the '[' starting the array designator.
+    SourceLocation LBracketLoc;
+
+    /// The location of the ellipsis separating the start and end indices.
+    /// Only valid for GNU array-range designators.
+    SourceLocation EllipsisLoc;
+
+    /// The location of the ']' terminating the array designator.
+    SourceLocation RBracketLoc;
+
+    ArrayDesignatorInfo(Ty Start, Ty End, SourceLocation LBracketLoc,
+                        SourceLocation EllipsisLoc, SourceLocation RBracketLoc)
+        : Start(Start), End(End), LBracketLoc(LBracketLoc),
+          EllipsisLoc(EllipsisLoc), RBracketLoc(RBracketLoc) {}
+
+    Ty getStart() const { return Start; }
+    Ty getEnd() const { return End; }
+  };
+
+  union {
+    FieldDesignatorInfo FieldInfo;
+    ArrayDesignatorInfo<Expr *> ArrayInfoExpr;
+    ArrayDesignatorInfo<unsigned> ArrayInfoInt;
+  };
+
+  Designator(DesignatorKind Kind) : Kind(Kind) {}
+
+public:
+  Designator() {}
+
+  bool isFieldDesignator() const { return Kind == FieldDesignator; }
+  bool isArrayDesignator() const {
+    return Kind == ArrayDesignatorExpr || Kind == ArrayDesignatorInt;
+  }
+  bool isArrayRangeDesignator() const {
+    return Kind == ArrayRangeDesignatorExpr || Kind == ArrayRangeDesignatorInt;
+  }
+
+  /// FieldDesignatorInfo:
+  static Designator CreateFieldDesignator(const IdentifierInfo *FieldName,
+                                          SourceLocation DotLoc,
+                                          SourceLocation NameLoc) {
+    Designator D(FieldDesignator);
+    new (&D.FieldInfo) FieldDesignatorInfo(FieldName, DotLoc, NameLoc);
+    return D;
+  }
+
+  const IdentifierInfo *getFieldName() const;
+
+  FieldDecl *getField() const {
+    assert(isFieldDesignator() && "Invalid accessor");
+    return FieldInfo.getFieldDecl();
+  }
+
+  void setField(FieldDecl *FD) {
+    assert(isFieldDesignator() && "Invalid accessor");
+    FieldInfo.set(FD);
+  }
+
+  SourceLocation getDotLoc() const {
+    assert(isFieldDesignator() && "Invalid accessor");
+    return FieldInfo.DotLoc;
+  }
+
+  SourceLocation getFieldLoc() const {
+    assert(isFieldDesignator() && "Invalid accessor");
+    return FieldInfo.NameLoc;
+  }
+
+  /// ArrayDesignatorInfo:
+  static Designator
+  CreateArrayDesignator(Expr *Start, SourceLocation LBracketLoc,
+                        SourceLocation RBracketLoc = SourceLocation()) {
+    Designator D(ArrayDesignatorExpr);
+    new (&D.ArrayInfoExpr) ArrayDesignatorInfo<Expr *>(
+        Start, nullptr, LBracketLoc, SourceLocation(), RBracketLoc);
+    return D;
+  }
+  static Designator
+  CreateArrayDesignator(unsigned Start, SourceLocation LBracketLoc,
+                        SourceLocation RBracketLoc = SourceLocation()) {
+    Designator D(ArrayDesignatorInt);
+    new (&D.ArrayInfoInt) ArrayDesignatorInfo<unsigned>(
+        Start, 0, LBracketLoc, SourceLocation(), RBracketLoc);
+    return D;
+  }
+
+  template <typename Ty = Expr *> Ty getArrayIndex() const {
+    assert(isArrayDesignator() && "Invalid accessor");
+    return ArrayInfoExpr.getStart();
+  }
+
+  /// ArrayRangeDesignatorInfo:
+  static Designator
+  CreateArrayRangeDesignator(Expr *Start, Expr *End, SourceLocation LBracketLoc,
+                             SourceLocation EllipsisLoc,
+                             SourceLocation RBracketLoc = SourceLocation()) {
+    Designator D(ArrayRangeDesignatorExpr);
+    new (&D.ArrayInfoExpr) ArrayDesignatorInfo<Expr *>(
+        Start, End, LBracketLoc, EllipsisLoc, RBracketLoc);
+    return D;
+  }
+  static Designator
+  CreateArrayRangeDesignator(unsigned Index, SourceLocation LBracketLoc,
+                             SourceLocation EllipsisLoc,
+                             SourceLocation RBracketLoc = SourceLocation()) {
+    Designator D(ArrayRangeDesignatorInt);
+    new (&D.ArrayInfoInt) ArrayDesignatorInfo<unsigned>(
+        Index, 0, LBracketLoc, EllipsisLoc, RBracketLoc);
+    return D;
+  }
+
+  Expr *getArrayRangeStart() const {
+    assert(isArrayRangeDesignator() && "Invalid accessor");
+    return ArrayInfoExpr.getStart();
+  }
+
+  Expr *getArrayRangeEnd() const {
+    assert(isArrayRangeDesignator() && "Invalid accessor");
+    return ArrayInfoExpr.getEnd();
+  }
+
+  SourceLocation getLBracketLoc() const {
+    switch (Kind) {
+    default:
+      break;
+    case ArrayDesignatorExpr:
+    case ArrayRangeDesignatorExpr:
+      return ArrayInfoExpr.LBracketLoc;
+    case ArrayDesignatorInt:
+    case ArrayRangeDesignatorInt:
+      return ArrayInfoInt.LBracketLoc;
+    }
+
+    assert(false && "Invalid accessor");
+    return SourceLocation();
+  }
+
+  SourceLocation getEllipsisLoc() const {
+    switch (Kind) {
+    default:
+      break;
+    case ArrayRangeDesignatorExpr:
+      return ArrayInfoExpr.EllipsisLoc;
+    case ArrayRangeDesignatorInt:
+      return ArrayInfoInt.EllipsisLoc;
+    }
+
+    assert(false && "Invalid accessor");
+    return SourceLocation();
+  }
+
+  SourceLocation getRBracketLoc() const {
+    switch (Kind) {
+    default:
+      break;
+    case ArrayDesignatorExpr:
+    case ArrayRangeDesignatorExpr:
+      return ArrayInfoExpr.RBracketLoc;
+    case ArrayDesignatorInt:
+    case ArrayRangeDesignatorInt:
+      return ArrayInfoInt.RBracketLoc;
+    }
+
+    assert(false && "Invalid accessor");
+    return SourceLocation();
+  }
+
+  void setRBracketLoc(SourceLocation RBracketLoc) {
+    switch (Kind) {
+    default:
+      assert(false && "Invalid accessor");
+      break;
+    case ArrayDesignatorExpr:
+    case ArrayRangeDesignatorExpr:
+      ArrayInfoExpr.RBracketLoc = RBracketLoc;
+      break;
+    case ArrayDesignatorInt:
+    case ArrayRangeDesignatorInt:
+      ArrayInfoInt.RBracketLoc = RBracketLoc;
+      break;
+    }
+  }
+
+  unsigned getFirstExprIndex() const {
+    if (Kind == ArrayDesignatorInt || Kind == ArrayRangeDesignatorInt)
+      return ArrayInfoInt.getStart();
+
+    assert(false && "Invalid accessor");
+    return 0;
+  }
+
+  /// Source location accessors.
+  SourceLocation getBeginLoc() const LLVM_READONLY {
+    if (isFieldDesignator())
+      return getDotLoc().isInvalid() ? getFieldLoc() : getDotLoc();
+    return getLBracketLoc();
+  }
+  SourceLocation getEndLoc() const LLVM_READONLY {
+    return isFieldDesignator() ? getFieldLoc() : getRBracketLoc();
+  }
+  SourceRange getSourceRange() const LLVM_READONLY {
+    return SourceRange(getBeginLoc(), getEndLoc());
+  }
+};
+
+/// Designation - Represent a full designation, which is a sequence of
+/// designators.  This class is mostly a helper for InitListDesignations.
+class Designation {
+  /// Designators - The actual designators for this initializer.
+  SmallVector<Designator, 2> Designators;
+
+public:
+  /// AddDesignator - Add a designator to the end of this list.
+  void AddDesignator(Designator D) { Designators.push_back(D); }
+
+  bool empty() const { return Designators.empty(); }
+
+  unsigned getNumDesignators() const { return Designators.size(); }
+
+  const Designator &getDesignator(unsigned Idx) const {
+    assert(Idx < getNumDesignators());
+    return Designators[Idx];
+  }
+  Designator &getDesignator(unsigned Idx) {
+    assert(Idx < getNumDesignators());
+    return Designators[Idx];
+  }
+};
+
+} // end namespace clang
+
+#endif

diff  --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index df2573324b752..8bc18c025a0cb 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -19,6 +19,7 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclAccessPair.h"
 #include "clang/AST/DependenceFlags.h"
+#include "clang/AST/Designator.h"
 #include "clang/AST/OperationKinds.h"
 #include "clang/AST/Stmt.h"
 #include "clang/AST/TemplateBase.h"
@@ -5034,10 +5035,6 @@ class InitListExpr : public Expr {
 class DesignatedInitExpr final
     : public Expr,
       private llvm::TrailingObjects<DesignatedInitExpr, Stmt *> {
-public:
-  /// Forward declaration of the Designator class.
-  class Designator;
-
 private:
   /// The location of the '=' or ':' prior to the actual initializer
   /// expression.
@@ -5069,161 +5066,6 @@ class DesignatedInitExpr final
       NumDesignators(0), NumSubExprs(NumSubExprs), Designators(nullptr) { }
 
 public:
-  /// A field designator, e.g., ".x".
-  struct FieldDesignator {
-    /// Refers to the field that is being initialized. The low bit
-    /// of this field determines whether this is actually a pointer
-    /// to an IdentifierInfo (if 1) or a FieldDecl (if 0). When
-    /// initially constructed, a field designator will store an
-    /// IdentifierInfo*. After semantic analysis has resolved that
-    /// name, the field designator will instead store a FieldDecl*.
-    uintptr_t NameOrField;
-
-    /// The location of the '.' in the designated initializer.
-    SourceLocation DotLoc;
-
-    /// The location of the field name in the designated initializer.
-    SourceLocation FieldLoc;
-  };
-
-  /// An array or GNU array-range designator, e.g., "[9]" or "[10..15]".
-  struct ArrayOrRangeDesignator {
-    /// Location of the first index expression within the designated
-    /// initializer expression's list of subexpressions.
-    unsigned Index;
-    /// The location of the '[' starting the array range designator.
-    SourceLocation LBracketLoc;
-    /// The location of the ellipsis separating the start and end
-    /// indices. Only valid for GNU array-range designators.
-    SourceLocation EllipsisLoc;
-    /// The location of the ']' terminating the array range designator.
-    SourceLocation RBracketLoc;
-  };
-
-  /// Represents a single C99 designator.
-  ///
-  /// @todo This class is infuriatingly similar to clang::Designator,
-  /// but minor 
diff erences (storing indices vs. storing pointers)
-  /// keep us from reusing it. Try harder, later, to rectify these
-  /// 
diff erences.
-  class Designator {
-    /// The kind of designator this describes.
-    enum {
-      FieldDesignator,
-      ArrayDesignator,
-      ArrayRangeDesignator
-    } Kind;
-
-    union {
-      /// A field designator, e.g., ".x".
-      struct FieldDesignator Field;
-      /// An array or GNU array-range designator, e.g., "[9]" or "[10..15]".
-      struct ArrayOrRangeDesignator ArrayOrRange;
-    };
-    friend class DesignatedInitExpr;
-
-  public:
-    Designator() {}
-
-    /// Initializes a field designator.
-    Designator(const IdentifierInfo *FieldName, SourceLocation DotLoc,
-               SourceLocation FieldLoc)
-      : Kind(FieldDesignator) {
-      new (&Field) DesignatedInitExpr::FieldDesignator;
-      Field.NameOrField = reinterpret_cast<uintptr_t>(FieldName) | 0x01;
-      Field.DotLoc = DotLoc;
-      Field.FieldLoc = FieldLoc;
-    }
-
-    /// Initializes an array designator.
-    Designator(unsigned Index, SourceLocation LBracketLoc,
-               SourceLocation RBracketLoc)
-      : Kind(ArrayDesignator) {
-      new (&ArrayOrRange) DesignatedInitExpr::ArrayOrRangeDesignator;
-      ArrayOrRange.Index = Index;
-      ArrayOrRange.LBracketLoc = LBracketLoc;
-      ArrayOrRange.EllipsisLoc = SourceLocation();
-      ArrayOrRange.RBracketLoc = RBracketLoc;
-    }
-
-    /// Initializes a GNU array-range designator.
-    Designator(unsigned Index, SourceLocation LBracketLoc,
-               SourceLocation EllipsisLoc, SourceLocation RBracketLoc)
-      : Kind(ArrayRangeDesignator) {
-      new (&ArrayOrRange) DesignatedInitExpr::ArrayOrRangeDesignator;
-      ArrayOrRange.Index = Index;
-      ArrayOrRange.LBracketLoc = LBracketLoc;
-      ArrayOrRange.EllipsisLoc = EllipsisLoc;
-      ArrayOrRange.RBracketLoc = RBracketLoc;
-    }
-
-    bool isFieldDesignator() const { return Kind == FieldDesignator; }
-    bool isArrayDesignator() const { return Kind == ArrayDesignator; }
-    bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; }
-
-    IdentifierInfo *getFieldName() const;
-
-    FieldDecl *getField() const {
-      assert(Kind == FieldDesignator && "Only valid on a field designator");
-      if (Field.NameOrField & 0x01)
-        return nullptr;
-      else
-        return reinterpret_cast<FieldDecl *>(Field.NameOrField);
-    }
-
-    void setField(FieldDecl *FD) {
-      assert(Kind == FieldDesignator && "Only valid on a field designator");
-      Field.NameOrField = reinterpret_cast<uintptr_t>(FD);
-    }
-
-    SourceLocation getDotLoc() const {
-      assert(Kind == FieldDesignator && "Only valid on a field designator");
-      return Field.DotLoc;
-    }
-
-    SourceLocation getFieldLoc() const {
-      assert(Kind == FieldDesignator && "Only valid on a field designator");
-      return Field.FieldLoc;
-    }
-
-    SourceLocation getLBracketLoc() const {
-      assert((Kind == ArrayDesignator || Kind == ArrayRangeDesignator) &&
-             "Only valid on an array or array-range designator");
-      return ArrayOrRange.LBracketLoc;
-    }
-
-    SourceLocation getRBracketLoc() const {
-      assert((Kind == ArrayDesignator || Kind == ArrayRangeDesignator) &&
-             "Only valid on an array or array-range designator");
-      return ArrayOrRange.RBracketLoc;
-    }
-
-    SourceLocation getEllipsisLoc() const {
-      assert(Kind == ArrayRangeDesignator &&
-             "Only valid on an array-range designator");
-      return ArrayOrRange.EllipsisLoc;
-    }
-
-    unsigned getFirstExprIndex() const {
-      assert((Kind == ArrayDesignator || Kind == ArrayRangeDesignator) &&
-             "Only valid on an array or array-range designator");
-      return ArrayOrRange.Index;
-    }
-
-    SourceLocation getBeginLoc() const LLVM_READONLY {
-      if (Kind == FieldDesignator)
-        return getDotLoc().isInvalid()? getFieldLoc() : getDotLoc();
-      else
-        return getLBracketLoc();
-    }
-    SourceLocation getEndLoc() const LLVM_READONLY {
-      return Kind == FieldDesignator ? getFieldLoc() : getRBracketLoc();
-    }
-    SourceRange getSourceRange() const LLVM_READONLY {
-      return SourceRange(getBeginLoc(), getEndLoc());
-    }
-  };
-
   static DesignatedInitExpr *Create(const ASTContext &C,
                                     llvm::ArrayRef<Designator> Designators,
                                     ArrayRef<Expr*> IndexExprs,

diff  --git a/clang/include/clang/Sema/Designator.h b/clang/include/clang/Sema/Designator.h
deleted file mode 100644
index 84837bfeba5bb..0000000000000
--- a/clang/include/clang/Sema/Designator.h
+++ /dev/null
@@ -1,214 +0,0 @@
-//===--- Designator.h - Initialization Designator ---------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines interfaces used to represent designators (a la
-// C99 designated initializers) during parsing.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_SEMA_DESIGNATOR_H
-#define LLVM_CLANG_SEMA_DESIGNATOR_H
-
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/SmallVector.h"
-
-namespace clang {
-
-class Expr;
-class IdentifierInfo;
-class Sema;
-
-/// Designator - A designator in a C99 designated initializer.
-///
-/// This class is a discriminated union which holds the various
-/// 
diff erent sorts of designators possible.  A Designation is an array of
-/// these.  An example of a designator are things like this:
-///     [8] .field [47]        // C99 designation: 3 designators
-///     [8 ... 47]  field:     // GNU extensions: 2 designators
-/// These occur in initializers, e.g.:
-///  int a[10] = {2, 4, [8]=9, 10};
-///
-class Designator {
-public:
-  enum DesignatorKind {
-    FieldDesignator, ArrayDesignator, ArrayRangeDesignator
-  };
-private:
-  Designator() {};
-
-  DesignatorKind Kind;
-
-  struct FieldDesignatorInfo {
-    const IdentifierInfo *II;
-    SourceLocation DotLoc;
-    SourceLocation NameLoc;
-  };
-  struct ArrayDesignatorInfo {
-    Expr *Index;
-    SourceLocation LBracketLoc;
-    mutable SourceLocation RBracketLoc;
-  };
-  struct ArrayRangeDesignatorInfo {
-    Expr *Start, *End;
-    SourceLocation LBracketLoc, EllipsisLoc;
-    mutable SourceLocation RBracketLoc;
-  };
-
-  union {
-    FieldDesignatorInfo FieldInfo;
-    ArrayDesignatorInfo ArrayInfo;
-    ArrayRangeDesignatorInfo ArrayRangeInfo;
-  };
-
-public:
-
-  DesignatorKind getKind() const { return Kind; }
-  bool isFieldDesignator() const { return Kind == FieldDesignator; }
-  bool isArrayDesignator() const { return Kind == ArrayDesignator; }
-  bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; }
-
-  const IdentifierInfo *getField() const {
-    assert(isFieldDesignator() && "Invalid accessor");
-    return FieldInfo.II;
-  }
-
-  SourceLocation getDotLoc() const {
-    assert(isFieldDesignator() && "Invalid accessor");
-    return FieldInfo.DotLoc;
-  }
-
-  SourceLocation getFieldLoc() const {
-    assert(isFieldDesignator() && "Invalid accessor");
-    return FieldInfo.NameLoc;
-  }
-
-  Expr *getArrayIndex() const {
-    assert(isArrayDesignator() && "Invalid accessor");
-    return ArrayInfo.Index;
-  }
-
-  Expr *getArrayRangeStart() const {
-    assert(isArrayRangeDesignator() && "Invalid accessor");
-    return ArrayRangeInfo.Start;
-  }
-  Expr *getArrayRangeEnd() const {
-    assert(isArrayRangeDesignator() && "Invalid accessor");
-    return ArrayRangeInfo.End;
-  }
-
-  SourceLocation getLBracketLoc() const {
-    assert((isArrayDesignator() || isArrayRangeDesignator()) &&
-           "Invalid accessor");
-    if (isArrayDesignator())
-      return ArrayInfo.LBracketLoc;
-    else
-      return ArrayRangeInfo.LBracketLoc;
-  }
-
-  SourceLocation getRBracketLoc() const {
-    assert((isArrayDesignator() || isArrayRangeDesignator()) &&
-           "Invalid accessor");
-    if (isArrayDesignator())
-      return ArrayInfo.RBracketLoc;
-    else
-      return ArrayRangeInfo.RBracketLoc;
-  }
-
-  SourceLocation getEllipsisLoc() const {
-    assert(isArrayRangeDesignator() && "Invalid accessor");
-    return ArrayRangeInfo.EllipsisLoc;
-  }
-
-  static Designator getField(const IdentifierInfo *II, SourceLocation DotLoc,
-                             SourceLocation NameLoc) {
-    Designator D;
-    D.Kind = FieldDesignator;
-    new (&D.FieldInfo) FieldDesignatorInfo;
-    D.FieldInfo.II = II;
-    D.FieldInfo.DotLoc = DotLoc;
-    D.FieldInfo.NameLoc = NameLoc;
-    return D;
-  }
-
-  static Designator getArray(Expr *Index,
-                             SourceLocation LBracketLoc) {
-    Designator D;
-    D.Kind = ArrayDesignator;
-    new (&D.ArrayInfo) ArrayDesignatorInfo;
-    D.ArrayInfo.Index = Index;
-    D.ArrayInfo.LBracketLoc = LBracketLoc;
-    D.ArrayInfo.RBracketLoc = SourceLocation();
-    return D;
-  }
-
-  static Designator getArrayRange(Expr *Start,
-                                  Expr *End,
-                                  SourceLocation LBracketLoc,
-                                  SourceLocation EllipsisLoc) {
-    Designator D;
-    D.Kind = ArrayRangeDesignator;
-    new (&D.ArrayRangeInfo) ArrayRangeDesignatorInfo;
-    D.ArrayRangeInfo.Start = Start;
-    D.ArrayRangeInfo.End = End;
-    D.ArrayRangeInfo.LBracketLoc = LBracketLoc;
-    D.ArrayRangeInfo.EllipsisLoc = EllipsisLoc;
-    D.ArrayRangeInfo.RBracketLoc = SourceLocation();
-    return D;
-  }
-
-  void setRBracketLoc(SourceLocation RBracketLoc) const {
-    assert((isArrayDesignator() || isArrayRangeDesignator()) &&
-           "Invalid accessor");
-    if (isArrayDesignator())
-      ArrayInfo.RBracketLoc = RBracketLoc;
-    else
-      ArrayRangeInfo.RBracketLoc = RBracketLoc;
-  }
-
-  /// ClearExprs - Null out any expression references, which prevents
-  /// them from being 'delete'd later.
-  void ClearExprs(Sema &Actions) {}
-
-  /// FreeExprs - Release any unclaimed memory for the expressions in
-  /// this designator.
-  void FreeExprs(Sema &Actions) {}
-};
-
-
-/// Designation - Represent a full designation, which is a sequence of
-/// designators.  This class is mostly a helper for InitListDesignations.
-class Designation {
-  /// Designators - The actual designators for this initializer.
-  SmallVector<Designator, 2> Designators;
-
-public:
-  /// AddDesignator - Add a designator to the end of this list.
-  void AddDesignator(Designator D) {
-    Designators.push_back(D);
-  }
-
-  bool empty() const { return Designators.empty(); }
-
-  unsigned getNumDesignators() const { return Designators.size(); }
-  const Designator &getDesignator(unsigned Idx) const {
-    assert(Idx < Designators.size());
-    return Designators[Idx];
-  }
-
-  /// ClearExprs - Null out any expression references, which prevents them from
-  /// being 'delete'd later.
-  void ClearExprs(Sema &Actions) {}
-
-  /// FreeExprs - Release any unclaimed memory for the expressions in this
-  /// designation.
-  void FreeExprs(Sema &Actions) {}
-};
-
-} // end namespace clang
-
-#endif

diff  --git a/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h b/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
index 6fb2decf8614a..ead5a71bedc41 100644
--- a/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
+++ b/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
@@ -123,7 +123,7 @@ class RecursiveSymbolVisitor
   }
 
   bool VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
-    for (const DesignatedInitExpr::Designator &D : E->designators()) {
+    for (const Designator &D : E->designators()) {
       if (D.isFieldDesignator() && D.getField()) {
         const FieldDecl *Decl = D.getField();
         if (!visit(Decl, D.getFieldLoc(), D.getFieldLoc()))

diff  --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index e9bac0d0529d4..379b3058ea313 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -27,6 +27,7 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/DeclVisitor.h"
 #include "clang/AST/DeclarationName.h"
+#include "clang/AST/Designator.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
@@ -436,8 +437,6 @@ namespace clang {
     Expected<CXXCastPath> ImportCastPath(CastExpr *E);
     Expected<APValue> ImportAPValue(const APValue &FromValue);
 
-    using Designator = DesignatedInitExpr::Designator;
-
     /// What we should import from the definition.
     enum ImportDefinitionKind {
       /// Import the default subset of the definition, which might be
@@ -962,9 +961,7 @@ Expected<DeclGroupRef> ASTNodeImporter::import(const DeclGroupRef &DG) {
                               NumDecls);
 }
 
-template <>
-Expected<ASTNodeImporter::Designator>
-ASTNodeImporter::import(const Designator &D) {
+template <> Expected<Designator> ASTNodeImporter::import(const Designator &D) {
   if (D.isFieldDesignator()) {
     IdentifierInfo *ToFieldName = Importer.Import(D.getFieldName());
 
@@ -976,7 +973,8 @@ ASTNodeImporter::import(const Designator &D) {
     if (!ToFieldLocOrErr)
       return ToFieldLocOrErr.takeError();
 
-    return Designator(ToFieldName, *ToDotLocOrErr, *ToFieldLocOrErr);
+    return Designator::CreateFieldDesignator(ToFieldName, *ToDotLocOrErr,
+                                             *ToFieldLocOrErr);
   }
 
   ExpectedSLoc ToLBracketLocOrErr = import(D.getLBracketLoc());
@@ -988,15 +986,15 @@ ASTNodeImporter::import(const Designator &D) {
     return ToRBracketLocOrErr.takeError();
 
   if (D.isArrayDesignator())
-    return Designator(D.getFirstExprIndex(),
-                      *ToLBracketLocOrErr, *ToRBracketLocOrErr);
+    return Designator::CreateArrayDesignator(
+        D.getFirstExprIndex(), *ToLBracketLocOrErr, *ToRBracketLocOrErr);
 
   ExpectedSLoc ToEllipsisLocOrErr = import(D.getEllipsisLoc());
   if (!ToEllipsisLocOrErr)
     return ToEllipsisLocOrErr.takeError();
 
   assert(D.isArrayRangeDesignator());
-  return Designator(
+  return Designator::CreateArrayRangeDesignator(
       D.getFirstExprIndex(), *ToLBracketLocOrErr, *ToEllipsisLocOrErr,
       *ToRBracketLocOrErr);
 }

diff  --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 67862a8692acd..3d508ba4dc87c 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -4389,11 +4389,11 @@ GenericSelectionExpr::CreateEmpty(const ASTContext &Context,
 //  DesignatedInitExpr
 //===----------------------------------------------------------------------===//
 
-IdentifierInfo *DesignatedInitExpr::Designator::getFieldName() const {
-  assert(Kind == FieldDesignator && "Only valid on a field designator");
-  if (Field.NameOrField & 0x01)
-    return reinterpret_cast<IdentifierInfo *>(Field.NameOrField & ~0x01);
-  return getField()->getIdentifier();
+const IdentifierInfo *Designator::getFieldName() const {
+  assert(isFieldDesignator() && "Invalid accessor");
+  if (auto *II = FieldInfo.getIdentifierInfo())
+    return II;
+  return FieldInfo.getFieldDecl()->getIdentifier();
 }
 
 DesignatedInitExpr::DesignatedInitExpr(const ASTContext &C, QualType Ty,
@@ -4468,14 +4468,9 @@ SourceRange DesignatedInitExpr::getDesignatorsSourceRange() const {
 }
 
 SourceLocation DesignatedInitExpr::getBeginLoc() const {
-  SourceLocation StartLoc;
   auto *DIE = const_cast<DesignatedInitExpr *>(this);
   Designator &First = *DIE->getDesignator(0);
-  if (First.isFieldDesignator())
-    StartLoc = GNUSyntax ? First.Field.FieldLoc : First.Field.DotLoc;
-  else
-    StartLoc = First.ArrayOrRange.LBracketLoc;
-  return StartLoc;
+  return First.getBeginLoc();
 }
 
 SourceLocation DesignatedInitExpr::getEndLoc() const {
@@ -4483,20 +4478,18 @@ SourceLocation DesignatedInitExpr::getEndLoc() const {
 }
 
 Expr *DesignatedInitExpr::getArrayIndex(const Designator& D) const {
-  assert(D.Kind == Designator::ArrayDesignator && "Requires array designator");
-  return getSubExpr(D.ArrayOrRange.Index + 1);
+  assert(D.isArrayDesignator() && "Requires array designator");
+  return getSubExpr(D.getFirstExprIndex() + 1);
 }
 
 Expr *DesignatedInitExpr::getArrayRangeStart(const Designator &D) const {
-  assert(D.Kind == Designator::ArrayRangeDesignator &&
-         "Requires array range designator");
-  return getSubExpr(D.ArrayOrRange.Index + 1);
+  assert(D.isArrayRangeDesignator() && "Requires array range designator");
+  return getSubExpr(D.getFirstExprIndex() + 1);
 }
 
 Expr *DesignatedInitExpr::getArrayRangeEnd(const Designator &D) const {
-  assert(D.Kind == Designator::ArrayRangeDesignator &&
-         "Requires array range designator");
-  return getSubExpr(D.ArrayOrRange.Index + 2);
+  assert(D.isArrayRangeDesignator() && "Requires array range designator");
+  return getSubExpr(D.getFirstExprIndex() + 2);
 }
 
 /// Replaces the designator at index @p Idx with the series

diff  --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index 0a879bb6df2af..552789ad81142 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -1737,10 +1737,10 @@ void StmtPrinter::VisitParenListExpr(ParenListExpr* Node) {
 
 void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
   bool NeedsEquals = true;
-  for (const DesignatedInitExpr::Designator &D : Node->designators()) {
+  for (const Designator &D : Node->designators()) {
     if (D.isFieldDesignator()) {
       if (D.getDotLoc().isInvalid()) {
-        if (IdentifierInfo *II = D.getFieldName()) {
+        if (const IdentifierInfo *II = D.getFieldName()) {
           OS << II->getName() << ":";
           NeedsEquals = false;
         }

diff  --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index 960cc4f4fc27b..c12b5dad204a5 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -1506,7 +1506,7 @@ void StmtProfiler::VisitInitListExpr(const InitListExpr *S) {
 void StmtProfiler::VisitDesignatedInitExpr(const DesignatedInitExpr *S) {
   VisitExpr(S);
   ID.AddBoolean(S->usesGNUSyntax());
-  for (const DesignatedInitExpr::Designator &D : S->designators()) {
+  for (const Designator &D : S->designators()) {
     if (D.isFieldDesignator()) {
       ID.AddInteger(0);
       VisitName(D.getFieldName());

diff  --git a/clang/lib/Index/IndexBody.cpp b/clang/lib/Index/IndexBody.cpp
index 8b8235c133023..023cd87bb2084 100644
--- a/clang/lib/Index/IndexBody.cpp
+++ b/clang/lib/Index/IndexBody.cpp
@@ -202,7 +202,7 @@ class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
   }
 
   bool VisitDesignatedInitExpr(DesignatedInitExpr *E) {
-    for (DesignatedInitExpr::Designator &D : llvm::reverse(E->designators())) {
+    for (Designator &D : llvm::reverse(E->designators())) {
       if (D.isFieldDesignator() && D.getField())
         return IndexCtx.handleReference(D.getField(), D.getFieldLoc(), Parent,
                                         ParentDC, SymbolRoleSet(), {}, E);
@@ -416,7 +416,7 @@ class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
     };
 
     auto visitSyntacticDesignatedInitExpr = [&](DesignatedInitExpr *E) -> bool {
-      for (DesignatedInitExpr::Designator &D : llvm::reverse(E->designators())) {
+      for (Designator &D : llvm::reverse(E->designators())) {
         if (D.isFieldDesignator() && D.getField())
           return IndexCtx.handleReference(D.getField(), D.getFieldLoc(),
                                           Parent, ParentDC, SymbolRoleSet(),

diff  --git a/clang/lib/Parse/ParseInit.cpp b/clang/lib/Parse/ParseInit.cpp
index af0c3b47958d2..900927fd97fbc 100644
--- a/clang/lib/Parse/ParseInit.cpp
+++ b/clang/lib/Parse/ParseInit.cpp
@@ -10,11 +10,11 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "clang/AST/Designator.h"
 #include "clang/Basic/TokenKinds.h"
 #include "clang/Parse/ParseDiagnostic.h"
 #include "clang/Parse/Parser.h"
 #include "clang/Parse/RAIIObjectsForParser.h"
-#include "clang/Sema/Designator.h"
 #include "clang/Sema/Ownership.h"
 #include "clang/Sema/Scope.h"
 #include "llvm/ADT/STLExtras.h"
@@ -181,7 +181,8 @@ ExprResult Parser::ParseInitializerWithPotentialDesignator(
                                       NewSyntax);
 
     Designation D;
-    D.AddDesignator(Designator::getField(FieldName, SourceLocation(), NameLoc));
+    D.AddDesignator(Designator::CreateFieldDesignator(
+        FieldName, SourceLocation(), NameLoc));
     PreferredType.enterDesignatedInitializer(
         Tok.getLocation(), DesignatorCompletion.PreferredBaseType, D);
     return Actions.ActOnDesignatedInitializer(D, ColonLoc, true,
@@ -210,8 +211,8 @@ ExprResult Parser::ParseInitializerWithPotentialDesignator(
         return ExprError();
       }
 
-      Desig.AddDesignator(Designator::getField(Tok.getIdentifierInfo(), DotLoc,
-                                               Tok.getLocation()));
+      Desig.AddDesignator(Designator::CreateFieldDesignator(
+          Tok.getIdentifierInfo(), DotLoc, Tok.getLocation()));
       ConsumeToken(); // Eat the identifier.
       continue;
     }
@@ -360,7 +361,8 @@ ExprResult Parser::ParseInitializerWithPotentialDesignator(
 
     // If this is a normal array designator, remember it.
     if (Tok.isNot(tok::ellipsis)) {
-      Desig.AddDesignator(Designator::getArray(Idx.get(), StartLoc));
+      Desig.AddDesignator(
+          Designator::CreateArrayDesignator(Idx.get(), StartLoc));
     } else {
       // Handle the gnu array range extension.
       Diag(Tok, diag::ext_gnu_array_range);
@@ -371,9 +373,8 @@ ExprResult Parser::ParseInitializerWithPotentialDesignator(
         SkipUntil(tok::r_square, StopAtSemi);
         return RHS;
       }
-      Desig.AddDesignator(Designator::getArrayRange(Idx.get(),
-                                                    RHS.get(),
-                                                    StartLoc, EllipsisLoc));
+      Desig.AddDesignator(Designator::CreateArrayRangeDesignator(
+          Idx.get(), RHS.get(), StartLoc, EllipsisLoc));
     }
 
     T.consumeClose();

diff  --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index 144bbe150abb9..d5f906b1c7a93 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -15,6 +15,7 @@
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Designator.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprConcepts.h"
@@ -32,7 +33,6 @@
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/CodeCompleteConsumer.h"
 #include "clang/Sema/DeclSpec.h"
-#include "clang/Sema/Designator.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/Overload.h"
 #include "clang/Sema/ParsedAttr.h"
@@ -6217,7 +6217,7 @@ getNextAggregateIndexAfterDesignatedInit(const ResultCandidate &Aggregate,
 
   // Look for designated initializers.
   // They're in their syntactic form, not yet resolved to fields.
-  IdentifierInfo *DesignatedFieldName = nullptr;
+  const IdentifierInfo *DesignatedFieldName = nullptr;
   unsigned ArgsAfterDesignator = 0;
   for (const Expr *Arg : Args) {
     if (const auto *DIE = dyn_cast<DesignatedInitExpr>(Arg)) {
@@ -6423,7 +6423,7 @@ static QualType getDesignatedType(QualType BaseType, const Designation &Desig) {
       assert(D.isFieldDesignator());
       auto *RD = getAsRecordDecl(BaseType);
       if (RD && RD->isCompleteDefinition()) {
-        for (const auto *Member : RD->lookup(D.getField()))
+        for (const auto *Member : RD->lookup(D.getFieldName()))
           if (const FieldDecl *FD = llvm::dyn_cast<FieldDecl>(Member)) {
             NextType = FD->getType();
             break;

diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 0c4fa43d88061..84ec4d7bb0ef0 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -19,6 +19,7 @@
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Designator.h"
 #include "clang/AST/EvaluatedExprVisitor.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
@@ -40,7 +41,6 @@
 #include "clang/Sema/AnalysisBasedWarnings.h"
 #include "clang/Sema/DeclSpec.h"
 #include "clang/Sema/DelayedDiagnostic.h"
-#include "clang/Sema/Designator.h"
 #include "clang/Sema/Initialization.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/Overload.h"

diff  --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index ddb2b5cf5cd16..4df4715376593 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -12,6 +12,7 @@
 
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/DeclObjC.h"
+#include "clang/AST/Designator.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/ExprOpenMP.h"
@@ -19,7 +20,6 @@
 #include "clang/Basic/CharInfo.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
-#include "clang/Sema/Designator.h"
 #include "clang/Sema/Initialization.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/SemaInternal.h"
@@ -2340,19 +2340,17 @@ static void ExpandAnonymousFieldDesignator(Sema &SemaRef,
                                            DesignatedInitExpr *DIE,
                                            unsigned DesigIdx,
                                            IndirectFieldDecl *IndirectField) {
-  typedef DesignatedInitExpr::Designator Designator;
-
   // Build the replacement designators.
   SmallVector<Designator, 4> Replacements;
   for (IndirectFieldDecl::chain_iterator PI = IndirectField->chain_begin(),
        PE = IndirectField->chain_end(); PI != PE; ++PI) {
     if (PI + 1 == PE)
-      Replacements.push_back(Designator((IdentifierInfo *)nullptr,
-                                    DIE->getDesignator(DesigIdx)->getDotLoc(),
-                                DIE->getDesignator(DesigIdx)->getFieldLoc()));
+      Replacements.push_back(Designator::CreateFieldDesignator(
+          nullptr, DIE->getDesignator(DesigIdx)->getDotLoc(),
+          DIE->getDesignator(DesigIdx)->getFieldLoc()));
     else
-      Replacements.push_back(Designator((IdentifierInfo *)nullptr,
-                                        SourceLocation(), SourceLocation()));
+      Replacements.push_back(Designator::CreateFieldDesignator(
+          nullptr, SourceLocation(), SourceLocation()));
     assert(isa<FieldDecl>(*PI));
     Replacements.back().setField(cast<FieldDecl>(*PI));
   }
@@ -2495,7 +2493,7 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
     return hadError && !prevHadError;
   }
 
-  DesignatedInitExpr::Designator *D = DIE->getDesignator(DesigIdx);
+  Designator *D = DIE->getDesignator(DesigIdx);
   bool IsFirstDesignator = (DesigIdx == 0);
   if (IsFirstDesignator ? FullyStructuredList : StructuredList) {
     // Determine the structural initializer list that corresponds to the
@@ -2577,7 +2575,7 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
 
     FieldDecl *KnownField = D->getField();
     if (!KnownField) {
-      IdentifierInfo *FieldName = D->getFieldName();
+      const IdentifierInfo *FieldName = D->getFieldName();
       DeclContext::lookup_result Lookup = RT->getDecl()->lookup(FieldName);
       for (NamedDecl *ND : Lookup) {
         if (auto *FD = dyn_cast<FieldDecl>(ND)) {
@@ -2753,8 +2751,7 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
         // We can't designate an object within the flexible array
         // member (because GCC doesn't allow it).
         if (!VerifyOnly) {
-          DesignatedInitExpr::Designator *NextD
-            = DIE->getDesignator(DesigIdx + 1);
+          Designator *NextD = DIE->getDesignator(DesigIdx + 1);
           SemaRef.Diag(NextD->getBeginLoc(),
                        diag::err_designator_into_flexible_array_member)
               << SourceRange(NextD->getBeginLoc(), DIE->getEndLoc());
@@ -3214,40 +3211,32 @@ CheckArrayDesignatorExpr(Sema &S, Expr *Index, llvm::APSInt &Value) {
 
 ExprResult Sema::ActOnDesignatedInitializer(Designation &Desig,
                                             SourceLocation EqualOrColonLoc,
-                                            bool GNUSyntax,
-                                            ExprResult Init) {
-  typedef DesignatedInitExpr::Designator ASTDesignator;
-
+                                            bool GNUSyntax, ExprResult Init) {
   bool Invalid = false;
-  SmallVector<ASTDesignator, 32> Designators;
+  SmallVector<Designator, 32> Designators;
   SmallVector<Expr *, 32> InitExpressions;
 
   // Build designators and check array designator expressions.
   for (unsigned Idx = 0; Idx < Desig.getNumDesignators(); ++Idx) {
     const Designator &D = Desig.getDesignator(Idx);
-    switch (D.getKind()) {
-    case Designator::FieldDesignator:
-      Designators.push_back(ASTDesignator(D.getField(), D.getDotLoc(),
-                                          D.getFieldLoc()));
-      break;
 
-    case Designator::ArrayDesignator: {
+    if (D.isFieldDesignator()) {
+      Designators.push_back(Designator::CreateFieldDesignator(
+          D.getFieldName(), D.getDotLoc(), D.getFieldLoc()));
+    } else if (D.isArrayDesignator()) {
       Expr *Index = static_cast<Expr *>(D.getArrayIndex());
       llvm::APSInt IndexValue;
+
       if (!Index->isTypeDependent() && !Index->isValueDependent())
         Index = CheckArrayDesignatorExpr(*this, Index, IndexValue).get();
       if (!Index)
         Invalid = true;
       else {
-        Designators.push_back(ASTDesignator(InitExpressions.size(),
-                                            D.getLBracketLoc(),
-                                            D.getRBracketLoc()));
+        Designators.push_back(Designator::CreateArrayDesignator(
+            InitExpressions.size(), D.getLBracketLoc(), D.getRBracketLoc()));
         InitExpressions.push_back(Index);
       }
-      break;
-    }
-
-    case Designator::ArrayRangeDesignator: {
+    } else if (D.isArrayRangeDesignator()) {
       Expr *StartIndex = static_cast<Expr *>(D.getArrayRangeStart());
       Expr *EndIndex = static_cast<Expr *>(D.getArrayRangeEnd());
       llvm::APSInt StartValue;
@@ -3256,9 +3245,11 @@ ExprResult Sema::ActOnDesignatedInitializer(Designation &Desig,
                             StartIndex->isValueDependent();
       bool EndDependent = EndIndex->isTypeDependent() ||
                           EndIndex->isValueDependent();
+
       if (!StartDependent)
         StartIndex =
             CheckArrayDesignatorExpr(*this, StartIndex, StartValue).get();
+
       if (!EndDependent)
         EndIndex = CheckArrayDesignatorExpr(*this, EndIndex, EndValue).get();
 
@@ -3279,25 +3270,19 @@ ExprResult Sema::ActOnDesignatedInitializer(Designation &Desig,
             << StartIndex->getSourceRange() << EndIndex->getSourceRange();
           Invalid = true;
         } else {
-          Designators.push_back(ASTDesignator(InitExpressions.size(),
-                                              D.getLBracketLoc(),
-                                              D.getEllipsisLoc(),
-                                              D.getRBracketLoc()));
+          Designators.push_back(Designator::CreateArrayRangeDesignator(
+              InitExpressions.size(), D.getLBracketLoc(), D.getEllipsisLoc(),
+              D.getRBracketLoc()));
           InitExpressions.push_back(StartIndex);
           InitExpressions.push_back(EndIndex);
         }
       }
-      break;
-    }
     }
   }
 
   if (Invalid || Init.isInvalid())
     return ExprError();
 
-  // Clear out the expressions within the designation.
-  Desig.ClearExprs(*this);
-
   return DesignatedInitExpr::Create(Context, Designators, InitExpressions,
                                     EqualOrColonLoc, GNUSyntax,
                                     Init.getAs<Expr>());

diff  --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index ef56f6219868c..25b3034a5efac 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -18,9 +18,10 @@
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclObjC.h"
 #include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Designator.h"
 #include "clang/AST/Expr.h"
-#include "clang/AST/ExprConcepts.h"
 #include "clang/AST/ExprCXX.h"
+#include "clang/AST/ExprConcepts.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/ExprOpenMP.h"
 #include "clang/AST/OpenMPClause.h"
@@ -30,7 +31,6 @@
 #include "clang/AST/StmtOpenMP.h"
 #include "clang/Basic/DiagnosticParse.h"
 #include "clang/Basic/OpenMPKinds.h"
-#include "clang/Sema/Designator.h"
 #include "clang/Sema/Lookup.h"
 #include "clang/Sema/Ownership.h"
 #include "clang/Sema/ParsedTemplate.h"
@@ -11605,11 +11605,10 @@ TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
   // transform the designators.
   SmallVector<Expr*, 4> ArrayExprs;
   bool ExprChanged = false;
-  for (const DesignatedInitExpr::Designator &D : E->designators()) {
+  for (const Designator &D : E->designators()) {
     if (D.isFieldDesignator()) {
-      Desig.AddDesignator(Designator::getField(D.getFieldName(),
-                                               D.getDotLoc(),
-                                               D.getFieldLoc()));
+      Desig.AddDesignator(Designator::CreateFieldDesignator(
+          D.getFieldName(), D.getDotLoc(), D.getFieldLoc()));
       if (D.getField()) {
         FieldDecl *Field = cast_or_null<FieldDecl>(
             getDerived().TransformDecl(D.getFieldLoc(), D.getField()));
@@ -11632,7 +11631,7 @@ TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
         return ExprError();
 
       Desig.AddDesignator(
-          Designator::getArray(Index.get(), D.getLBracketLoc()));
+          Designator::CreateArrayDesignator(Index.get(), D.getLBracketLoc()));
 
       ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(D);
       ArrayExprs.push_back(Index.get());
@@ -11649,10 +11648,8 @@ TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
     if (End.isInvalid())
       return ExprError();
 
-    Desig.AddDesignator(Designator::getArrayRange(Start.get(),
-                                                  End.get(),
-                                                  D.getLBracketLoc(),
-                                                  D.getEllipsisLoc()));
+    Desig.AddDesignator(Designator::CreateArrayRangeDesignator(
+        Start.get(), End.get(), D.getLBracketLoc(), D.getEllipsisLoc()));
 
     ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(D) ||
                   End.get() != E->getArrayRangeEnd(D);

diff  --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp
index 46d653c7f9407..3eae047b63b4c 100644
--- a/clang/lib/Serialization/ASTReaderStmt.cpp
+++ b/clang/lib/Serialization/ASTReaderStmt.cpp
@@ -1199,8 +1199,6 @@ void ASTStmtReader::VisitInitListExpr(InitListExpr *E) {
 }
 
 void ASTStmtReader::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
-  using Designator = DesignatedInitExpr::Designator;
-
   VisitExpr(E);
   unsigned NumSubExprs = Record.readInt();
   assert(NumSubExprs == E->getNumSubExprs() && "Wrong number of subexprs");
@@ -1216,8 +1214,8 @@ void ASTStmtReader::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
       auto *Field = readDeclAs<FieldDecl>();
       SourceLocation DotLoc = readSourceLocation();
       SourceLocation FieldLoc = readSourceLocation();
-      Designators.push_back(Designator(Field->getIdentifier(), DotLoc,
-                                       FieldLoc));
+      Designators.push_back(Designator::CreateFieldDesignator(
+          Field->getIdentifier(), DotLoc, FieldLoc));
       Designators.back().setField(Field);
       break;
     }
@@ -1226,7 +1224,8 @@ void ASTStmtReader::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
       const IdentifierInfo *Name = Record.readIdentifier();
       SourceLocation DotLoc = readSourceLocation();
       SourceLocation FieldLoc = readSourceLocation();
-      Designators.push_back(Designator(Name, DotLoc, FieldLoc));
+      Designators.push_back(
+          Designator::CreateFieldDesignator(Name, DotLoc, FieldLoc));
       break;
     }
 
@@ -1234,7 +1233,8 @@ void ASTStmtReader::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
       unsigned Index = Record.readInt();
       SourceLocation LBracketLoc = readSourceLocation();
       SourceLocation RBracketLoc = readSourceLocation();
-      Designators.push_back(Designator(Index, LBracketLoc, RBracketLoc));
+      Designators.push_back(
+          Designator::CreateArrayDesignator(Index, LBracketLoc, RBracketLoc));
       break;
     }
 
@@ -1243,8 +1243,8 @@ void ASTStmtReader::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
       SourceLocation LBracketLoc = readSourceLocation();
       SourceLocation EllipsisLoc = readSourceLocation();
       SourceLocation RBracketLoc = readSourceLocation();
-      Designators.push_back(Designator(Index, LBracketLoc, EllipsisLoc,
-                                       RBracketLoc));
+      Designators.push_back(Designator::CreateArrayRangeDesignator(
+          Index, LBracketLoc, EllipsisLoc, RBracketLoc));
       break;
     }
     }

diff  --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp
index b35a7cee5af20..3f6c93a68208a 100644
--- a/clang/lib/Serialization/ASTWriterStmt.cpp
+++ b/clang/lib/Serialization/ASTWriterStmt.cpp
@@ -1085,7 +1085,7 @@ void ASTStmtWriter::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
     Record.AddStmt(E->getSubExpr(I));
   Record.AddSourceLocation(E->getEqualOrColonLoc());
   Record.push_back(E->usesGNUSyntax());
-  for (const DesignatedInitExpr::Designator &D : E->designators()) {
+  for (const Designator &D : E->designators()) {
     if (D.isFieldDesignator()) {
       if (FieldDecl *Field = D.getField()) {
         Record.push_back(serialization::DESIG_FIELD_DECL);

diff  --git a/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp b/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
index aecfffcbef1fa..03893ca974fcf 100644
--- a/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
+++ b/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
@@ -227,7 +227,7 @@ class RenameLocFinder : public RecursiveASTVisitor<RenameLocFinder> {
   }
 
   bool VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
-    for (const DesignatedInitExpr::Designator &D : E->designators()) {
+    for (const Designator &D : E->designators()) {
       if (D.isFieldDesignator() && D.getField()) {
         const FieldDecl *Decl = D.getField();
         if (isInUSRSet(Decl)) {

diff  --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index bf26fdabc747f..18cb4861849e9 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -2852,8 +2852,7 @@ void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
 }
 void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
   AddStmt(E->getInit());
-  for (const DesignatedInitExpr::Designator &D :
-       llvm::reverse(E->designators())) {
+  for (const Designator &D : llvm::reverse(E->designators())) {
     if (D.isFieldDesignator()) {
       if (FieldDecl *Field = D.getField())
         AddMemberRef(Field, D.getFieldLoc());


        


More information about the cfe-commits mailing list