//===--- 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
/// different 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:
  DesignatorKind Kind;

  struct FieldDesignatorInfo {
    const IdentifierInfo *II;
    unsigned DotLoc;
    unsigned NameLoc;
  };
  struct ArrayDesignatorInfo {
    Expr *Index;
    unsigned LBracketLoc;
    mutable unsigned  RBracketLoc;
  };
  struct ArrayRangeDesignatorInfo {
    Expr *Start, *End;
    unsigned LBracketLoc, EllipsisLoc;
    mutable unsigned 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 SourceLocation::getFromRawEncoding(FieldInfo.DotLoc);
  }

  SourceLocation getFieldLoc() const {
    assert(isFieldDesignator() && "Invalid accessor");
    return SourceLocation::getFromRawEncoding(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 SourceLocation::getFromRawEncoding(ArrayInfo.LBracketLoc);
    else
      return SourceLocation::getFromRawEncoding(ArrayRangeInfo.LBracketLoc);
  }

  SourceLocation getRBracketLoc() const {
    assert((isArrayDesignator() || isArrayRangeDesignator()) &&
           "Invalid accessor");
    if (isArrayDesignator())
      return SourceLocation::getFromRawEncoding(ArrayInfo.RBracketLoc);
    else
      return SourceLocation::getFromRawEncoding(ArrayRangeInfo.RBracketLoc);
  }

  SourceLocation getEllipsisLoc() const {
    assert(isArrayRangeDesignator() && "Invalid accessor");
    return SourceLocation::getFromRawEncoding(ArrayRangeInfo.EllipsisLoc);
  }

  static Designator getField(const IdentifierInfo *II, SourceLocation DotLoc,
                             SourceLocation NameLoc) {
    Designator D;
    D.Kind = FieldDesignator;
    D.FieldInfo.II = II;
    D.FieldInfo.DotLoc = DotLoc.getRawEncoding();
    D.FieldInfo.NameLoc = NameLoc.getRawEncoding();
    return D;
  }

  static Designator getArray(Expr *Index,
                             SourceLocation LBracketLoc) {
    Designator D;
    D.Kind = ArrayDesignator;
    D.ArrayInfo.Index = Index;
    D.ArrayInfo.LBracketLoc = LBracketLoc.getRawEncoding();
    D.ArrayInfo.RBracketLoc = 0;
    return D;
  }

  static Designator getArrayRange(Expr *Start,
                                  Expr *End,
                                  SourceLocation LBracketLoc,
                                  SourceLocation EllipsisLoc) {
    Designator D;
    D.Kind = ArrayRangeDesignator;
    D.ArrayRangeInfo.Start = Start;
    D.ArrayRangeInfo.End = End;
    D.ArrayRangeInfo.LBracketLoc = LBracketLoc.getRawEncoding();
    D.ArrayRangeInfo.EllipsisLoc = EllipsisLoc.getRawEncoding();
    D.ArrayRangeInfo.RBracketLoc = 0;
    return D;
  }

  void setRBracketLoc(SourceLocation RBracketLoc) const {
    assert((isArrayDesignator() || isArrayRangeDesignator()) &&
           "Invalid accessor");
    if (isArrayDesignator())
      ArrayInfo.RBracketLoc = RBracketLoc.getRawEncoding();
    else
      ArrayRangeInfo.RBracketLoc = RBracketLoc.getRawEncoding();
  }

  /// 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
