clang API Documentation

Designator.h
Go to the documentation of this file.
00001 //===--- Designator.h - Initialization Designator ---------------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file defines interfaces used to represent designators (a la
00011 // C99 designated initializers) during parsing.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #ifndef LLVM_CLANG_SEMA_DESIGNATOR_H
00016 #define LLVM_CLANG_SEMA_DESIGNATOR_H
00017 
00018 #include "clang/Basic/SourceLocation.h"
00019 #include "llvm/ADT/SmallVector.h"
00020 
00021 namespace clang {
00022 
00023 class Expr;
00024 class IdentifierInfo;
00025 class Sema;
00026 
00027 /// Designator - A designator in a C99 designated initializer.
00028 ///
00029 /// This class is a discriminated union which holds the various
00030 /// different sorts of designators possible.  A Designation is an array of
00031 /// these.  An example of a designator are things like this:
00032 ///     [8] .field [47]        // C99 designation: 3 designators
00033 ///     [8 ... 47]  field:     // GNU extensions: 2 designators
00034 /// These occur in initializers, e.g.:
00035 ///  int a[10] = {2, 4, [8]=9, 10};
00036 ///
00037 class Designator {
00038 public:
00039   enum DesignatorKind {
00040     FieldDesignator, ArrayDesignator, ArrayRangeDesignator
00041   };
00042 private:
00043   DesignatorKind Kind;
00044 
00045   struct FieldDesignatorInfo {
00046     const IdentifierInfo *II;
00047     unsigned DotLoc;
00048     unsigned NameLoc;
00049   };
00050   struct ArrayDesignatorInfo {
00051     Expr *Index;
00052     unsigned LBracketLoc;
00053     mutable unsigned  RBracketLoc;
00054   };
00055   struct ArrayRangeDesignatorInfo {
00056     Expr *Start, *End;
00057     unsigned LBracketLoc, EllipsisLoc;
00058     mutable unsigned RBracketLoc;
00059   };
00060 
00061   union {
00062     FieldDesignatorInfo FieldInfo;
00063     ArrayDesignatorInfo ArrayInfo;
00064     ArrayRangeDesignatorInfo ArrayRangeInfo;
00065   };
00066 
00067 public:
00068 
00069   DesignatorKind getKind() const { return Kind; }
00070   bool isFieldDesignator() const { return Kind == FieldDesignator; }
00071   bool isArrayDesignator() const { return Kind == ArrayDesignator; }
00072   bool isArrayRangeDesignator() const { return Kind == ArrayRangeDesignator; }
00073 
00074   const IdentifierInfo *getField() const {
00075     assert(isFieldDesignator() && "Invalid accessor");
00076     return FieldInfo.II;
00077   }
00078 
00079   SourceLocation getDotLoc() const {
00080     assert(isFieldDesignator() && "Invalid accessor");
00081     return SourceLocation::getFromRawEncoding(FieldInfo.DotLoc);
00082   }
00083 
00084   SourceLocation getFieldLoc() const {
00085     assert(isFieldDesignator() && "Invalid accessor");
00086     return SourceLocation::getFromRawEncoding(FieldInfo.NameLoc);
00087   }
00088 
00089   Expr *getArrayIndex() const {
00090     assert(isArrayDesignator() && "Invalid accessor");
00091     return ArrayInfo.Index;
00092   }
00093 
00094   Expr *getArrayRangeStart() const {
00095     assert(isArrayRangeDesignator() && "Invalid accessor");
00096     return ArrayRangeInfo.Start;
00097   }
00098   Expr *getArrayRangeEnd() const {
00099     assert(isArrayRangeDesignator() && "Invalid accessor");
00100     return ArrayRangeInfo.End;
00101   }
00102 
00103   SourceLocation getLBracketLoc() const {
00104     assert((isArrayDesignator() || isArrayRangeDesignator()) &&
00105            "Invalid accessor");
00106     if (isArrayDesignator())
00107       return SourceLocation::getFromRawEncoding(ArrayInfo.LBracketLoc);
00108     else
00109       return SourceLocation::getFromRawEncoding(ArrayRangeInfo.LBracketLoc);
00110   }
00111 
00112   SourceLocation getRBracketLoc() const {
00113     assert((isArrayDesignator() || isArrayRangeDesignator()) &&
00114            "Invalid accessor");
00115     if (isArrayDesignator())
00116       return SourceLocation::getFromRawEncoding(ArrayInfo.RBracketLoc);
00117     else
00118       return SourceLocation::getFromRawEncoding(ArrayRangeInfo.RBracketLoc);
00119   }
00120 
00121   SourceLocation getEllipsisLoc() const {
00122     assert(isArrayRangeDesignator() && "Invalid accessor");
00123     return SourceLocation::getFromRawEncoding(ArrayRangeInfo.EllipsisLoc);
00124   }
00125 
00126   static Designator getField(const IdentifierInfo *II, SourceLocation DotLoc,
00127                              SourceLocation NameLoc) {
00128     Designator D;
00129     D.Kind = FieldDesignator;
00130     D.FieldInfo.II = II;
00131     D.FieldInfo.DotLoc = DotLoc.getRawEncoding();
00132     D.FieldInfo.NameLoc = NameLoc.getRawEncoding();
00133     return D;
00134   }
00135 
00136   static Designator getArray(Expr *Index,
00137                              SourceLocation LBracketLoc) {
00138     Designator D;
00139     D.Kind = ArrayDesignator;
00140     D.ArrayInfo.Index = Index;
00141     D.ArrayInfo.LBracketLoc = LBracketLoc.getRawEncoding();
00142     D.ArrayInfo.RBracketLoc = 0;
00143     return D;
00144   }
00145 
00146   static Designator getArrayRange(Expr *Start,
00147                                   Expr *End,
00148                                   SourceLocation LBracketLoc,
00149                                   SourceLocation EllipsisLoc) {
00150     Designator D;
00151     D.Kind = ArrayRangeDesignator;
00152     D.ArrayRangeInfo.Start = Start;
00153     D.ArrayRangeInfo.End = End;
00154     D.ArrayRangeInfo.LBracketLoc = LBracketLoc.getRawEncoding();
00155     D.ArrayRangeInfo.EllipsisLoc = EllipsisLoc.getRawEncoding();
00156     D.ArrayRangeInfo.RBracketLoc = 0;
00157     return D;
00158   }
00159 
00160   void setRBracketLoc(SourceLocation RBracketLoc) const {
00161     assert((isArrayDesignator() || isArrayRangeDesignator()) &&
00162            "Invalid accessor");
00163     if (isArrayDesignator())
00164       ArrayInfo.RBracketLoc = RBracketLoc.getRawEncoding();
00165     else
00166       ArrayRangeInfo.RBracketLoc = RBracketLoc.getRawEncoding();
00167   }
00168 
00169   /// ClearExprs - Null out any expression references, which prevents
00170   /// them from being 'delete'd later.
00171   void ClearExprs(Sema &Actions) {}
00172 
00173   /// FreeExprs - Release any unclaimed memory for the expressions in
00174   /// this designator.
00175   void FreeExprs(Sema &Actions) {}
00176 };
00177 
00178 
00179 /// Designation - Represent a full designation, which is a sequence of
00180 /// designators.  This class is mostly a helper for InitListDesignations.
00181 class Designation {
00182   /// Designators - The actual designators for this initializer.
00183   SmallVector<Designator, 2> Designators;
00184 
00185 public:
00186   /// AddDesignator - Add a designator to the end of this list.
00187   void AddDesignator(Designator D) {
00188     Designators.push_back(D);
00189   }
00190 
00191   bool empty() const { return Designators.empty(); }
00192 
00193   unsigned getNumDesignators() const { return Designators.size(); }
00194   const Designator &getDesignator(unsigned Idx) const {
00195     assert(Idx < Designators.size());
00196     return Designators[Idx];
00197   }
00198 
00199   /// ClearExprs - Null out any expression references, which prevents them from
00200   /// being 'delete'd later.
00201   void ClearExprs(Sema &Actions) {}
00202 
00203   /// FreeExprs - Release any unclaimed memory for the expressions in this
00204   /// designation.
00205   void FreeExprs(Sema &Actions) {}
00206 };
00207 
00208 } // end namespace clang
00209 
00210 #endif