[cfe-commits] r69251 - in /cfe/trunk: include/clang/AST/Expr.h include/clang/Frontend/PCHBitCodes.h lib/AST/Expr.cpp lib/Frontend/PCHReader.cpp lib/Frontend/PCHWriter.cpp test/PCH/exprs.c test/PCH/exprs.h

Douglas Gregor dgregor at apple.com
Wed Apr 15 17:55:48 PDT 2009


Author: dgregor
Date: Wed Apr 15 19:55:48 2009
New Revision: 69251

URL: http://llvm.org/viewvc/llvm-project?rev=69251&view=rev
Log:
PCH support for InitListExpr, DesignatedInitExpr, and ImplicitValueInitExpr.

Modified:
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/include/clang/Frontend/PCHBitCodes.h
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/Frontend/PCHReader.cpp
    cfe/trunk/lib/Frontend/PCHWriter.cpp
    cfe/trunk/test/PCH/exprs.c
    cfe/trunk/test/PCH/exprs.h

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=69251&r1=69250&r2=69251&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Wed Apr 15 19:55:48 2009
@@ -1969,6 +1969,9 @@
 public:
   InitListExpr(SourceLocation lbraceloc, Expr **initexprs, unsigned numinits,
                SourceLocation rbraceloc);
+
+  /// \brief Build an empty initializer list.
+  explicit InitListExpr(EmptyShell Empty) : Expr(InitListExprClass, Empty) { }
   
   unsigned getNumInits() const { return InitExprs.size(); }
   
@@ -2022,6 +2025,9 @@
     return LBraceLoc.isValid() && RBraceLoc.isValid();
   }
   
+  SourceLocation getLBraceLoc() const { return LBraceLoc; }
+  void setLBraceLoc(SourceLocation Loc) { LBraceLoc = Loc; }
+  SourceLocation getRBraceLoc() const { return RBraceLoc; }
   void setRBraceLoc(SourceLocation Loc) { RBraceLoc = Loc; }
 
   /// @brief Retrieve the initializer list that describes the
@@ -2032,8 +2038,8 @@
   void setSyntacticForm(InitListExpr *Init) { SyntacticForm = Init; }
 
   bool hadArrayRangeDesignator() const { return HadArrayRangeDesignator; }
-  void sawArrayRangeDesignator() { 
-    HadArrayRangeDesignator = true;
+  void sawArrayRangeDesignator(bool ARD = true) { 
+    HadArrayRangeDesignator = ARD;
   }
 
   virtual SourceRange getSourceRange() const {
@@ -2117,6 +2123,10 @@
                      SourceLocation EqualOrColonLoc, bool GNUSyntax,
                      unsigned NumSubExprs);
 
+  explicit DesignatedInitExpr(unsigned NumSubExprs)
+    : Expr(DesignatedInitExprClass, EmptyShell()),
+      NumDesignators(0), Designators(0), NumSubExprs(NumSubExprs) { }
+
 public:
   /// A field designator, e.g., ".x".
   struct FieldDesignator {
@@ -2250,6 +2260,12 @@
       return SourceLocation::getFromRawEncoding(ArrayOrRange.EllipsisLoc);
     }
 
+    unsigned getFirstExprIndex() const {
+      assert((Kind == ArrayDesignator || Kind == ArrayRangeDesignator) &&
+             "Only valid on an array or array-range designator");
+      return ArrayOrRange.Index;
+    }
+
     SourceLocation getStartLocation() const {
       if (Kind == FieldDesignator)
         return getDotLoc().isInvalid()? getFieldLoc() : getDotLoc();
@@ -2264,6 +2280,8 @@
                                     SourceLocation EqualOrColonLoc,
                                     bool GNUSyntax, Expr *Init);
 
+  static DesignatedInitExpr *CreateEmpty(ASTContext &C, unsigned NumIndexExprs);
+
   /// @brief Returns the number of designators in this initializer.
   unsigned size() const { return NumDesignators; }
 
@@ -2276,6 +2294,8 @@
 
   Designator *getDesignator(unsigned Idx) { return &designators_begin()[Idx]; }
 
+  void setDesignators(const Designator *Desigs, unsigned NumDesigs);
+
   Expr *getArrayIndex(const Designator& D);
   Expr *getArrayRangeStart(const Designator& D);
   Expr *getArrayRangeEnd(const Designator& D);
@@ -2283,10 +2303,12 @@
   /// @brief Retrieve the location of the '=' that precedes the
   /// initializer value itself, if present.
   SourceLocation getEqualOrColonLoc() const { return EqualOrColonLoc; }
+  void setEqualOrColonLoc(SourceLocation L) { EqualOrColonLoc = L; }
 
   /// @brief Determines whether this designated initializer used the
   /// deprecated GNU syntax for designated initializers.
   bool usesGNUSyntax() const { return GNUSyntax; }
+  void setGNUSyntax(bool GNU) { GNUSyntax = GNU; }
 
   /// @brief Retrieve the initializer value.
   Expr *getInit() const { 
@@ -2297,6 +2319,26 @@
     *child_begin() = init;
   }
 
+  /// \brief Retrieve the total number of subexpressions in this
+  /// designated initializer expression, including the actual
+  /// initialized value and any expressions that occur within array
+  /// and array-range designators.
+  unsigned getNumSubExprs() const { return NumSubExprs; }
+
+  Expr *getSubExpr(unsigned Idx) {
+    assert(Idx < NumSubExprs && "Subscript out of range");
+    char* Ptr = static_cast<char*>(static_cast<void *>(this));
+    Ptr += sizeof(DesignatedInitExpr);
+    return reinterpret_cast<Expr**>(reinterpret_cast<void**>(Ptr))[Idx];
+  }
+
+  void setSubExpr(unsigned Idx, Expr *E) {
+    assert(Idx < NumSubExprs && "Subscript out of range");
+    char* Ptr = static_cast<char*>(static_cast<void *>(this));
+    Ptr += sizeof(DesignatedInitExpr);
+    reinterpret_cast<Expr**>(reinterpret_cast<void**>(Ptr))[Idx] = E;
+  }
+
   /// \brief Replaces the designator at index @p Idx with the series
   /// of designators in [First, Last).
   void ExpandDesignator(unsigned Idx, const Designator *First, 
@@ -2329,6 +2371,10 @@
   explicit ImplicitValueInitExpr(QualType ty) 
     : Expr(ImplicitValueInitExprClass, ty) { }
 
+  /// \brief Construct an empty implicit value initialization.
+  explicit ImplicitValueInitExpr(EmptyShell Empty)
+    : Expr(ImplicitValueInitExprClass, Empty) { }
+
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == ImplicitValueInitExprClass;
   }

Modified: cfe/trunk/include/clang/Frontend/PCHBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHBitCodes.h?rev=69251&r1=69250&r2=69251&view=diff

==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHBitCodes.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHBitCodes.h Wed Apr 15 19:55:48 2009
@@ -422,9 +422,12 @@
       /// FIXME: CompoundLiteralExpr
       /// \brief An ExtVectorElementExpr record.
       EXPR_EXT_VECTOR_ELEMENT,
-      /// FIXME: InitListExpr
-      /// FIXME: DesignatedInitExpr
-      /// FIXME: ImplicitValueInitExpr
+      /// \brief An InitListExpr record.
+      EXPR_INIT_LIST,
+      /// \brief A DesignatedInitExpr record.
+      EXPR_DESIGNATED_INIT,
+      /// \brief An ImplicitValueInitExpr record.
+      EXPR_IMPLICIT_VALUE_INIT,
       /// \brief A VAArgExpr record.
       EXPR_VA_ARG,
       // FIXME: AddrLabelExpr
@@ -440,6 +443,21 @@
       /// FIXME: BlockExpr
       EXPR_BLOCK_DECL_REF
     };
+
+    /// \brief The kinds of designators that can occur in a
+    /// DesignatedInitExpr.
+    enum DesignatorTypes {
+      /// \brief Field designator where only the field name is known.
+      DESIG_FIELD_NAME  = 0,
+      /// \brief Field designator where the field has been resolved to
+      /// a declaration.
+      DESIG_FIELD_DECL  = 1,
+      /// \brief Array designator.
+      DESIG_ARRAY       = 2,
+      /// \brief GNU array range designator.
+      DESIG_ARRAY_RANGE = 3
+    };
+
     /// @}
   }
 } // end namespace clang

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=69251&r1=69250&r2=69251&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Wed Apr 15 19:55:48 2009
@@ -1581,6 +1581,24 @@
   return DIE;
 }
 
+DesignatedInitExpr *DesignatedInitExpr::CreateEmpty(ASTContext &C, 
+                                                    unsigned NumIndexExprs) {
+  void *Mem = C.Allocate(sizeof(DesignatedInitExpr) +
+                         sizeof(Stmt *) * (NumIndexExprs + 1), 8);
+  return new (Mem) DesignatedInitExpr(NumIndexExprs + 1);
+}
+
+void DesignatedInitExpr::setDesignators(const Designator *Desigs, 
+                                        unsigned NumDesigs) {
+  if (Designators)
+    delete [] Designators;
+
+  Designators = new Designator[NumDesigs];
+  NumDesignators = NumDesigs;
+  for (unsigned I = 0; I != NumDesigs; ++I)
+    Designators[I] = Desigs[I];
+}
+
 SourceRange DesignatedInitExpr::getSourceRange() const {
   SourceLocation StartLoc;
   Designator &First =

Modified: cfe/trunk/lib/Frontend/PCHReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReader.cpp?rev=69251&r1=69250&r2=69251&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHReader.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReader.cpp Wed Apr 15 19:55:48 2009
@@ -258,6 +258,9 @@
     unsigned VisitExplicitCastExpr(ExplicitCastExpr *E);
     unsigned VisitCStyleCastExpr(CStyleCastExpr *E);
     unsigned VisitExtVectorElementExpr(ExtVectorElementExpr *E);
+    unsigned VisitInitListExpr(InitListExpr *E);
+    unsigned VisitDesignatedInitExpr(DesignatedInitExpr *E);
+    unsigned VisitImplicitValueInitExpr(ImplicitValueInitExpr *E);
     unsigned VisitVAArgExpr(VAArgExpr *E);
     unsigned VisitTypesCompatibleExpr(TypesCompatibleExpr *E);
     unsigned VisitChooseExpr(ChooseExpr *E);
@@ -452,6 +455,91 @@
   return 1;
 }
 
+unsigned PCHStmtReader::VisitInitListExpr(InitListExpr *E) {
+  VisitExpr(E);
+  unsigned NumInits = Record[Idx++];
+  E->reserveInits(NumInits);
+  for (unsigned I = 0; I != NumInits; ++I)
+    E->updateInit(I, ExprStack[ExprStack.size() - NumInits - 1 + I]);
+  E->setSyntacticForm(cast_or_null<InitListExpr>(ExprStack.back()));
+  E->setLBraceLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRBraceLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setInitializedFieldInUnion(
+                      cast_or_null<FieldDecl>(Reader.GetDecl(Record[Idx++])));
+  E->sawArrayRangeDesignator(Record[Idx++]);
+  return NumInits + 1;
+}
+
+unsigned PCHStmtReader::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
+  typedef DesignatedInitExpr::Designator Designator;
+
+  VisitExpr(E);
+  unsigned NumSubExprs = Record[Idx++];
+  assert(NumSubExprs == E->getNumSubExprs() && "Wrong number of subexprs");
+  for (unsigned I = 0; I != NumSubExprs; ++I)
+    E->setSubExpr(I, ExprStack[ExprStack.size() - NumSubExprs + I]);
+  E->setEqualOrColonLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setGNUSyntax(Record[Idx++]);
+
+  llvm::SmallVector<Designator, 4> Designators;
+  while (Idx < Record.size()) {
+    switch ((pch::DesignatorTypes)Record[Idx++]) {
+    case pch::DESIG_FIELD_DECL: {
+      FieldDecl *Field = cast<FieldDecl>(Reader.GetDecl(Record[Idx++]));
+      SourceLocation DotLoc 
+        = SourceLocation::getFromRawEncoding(Record[Idx++]);
+      SourceLocation FieldLoc 
+        = SourceLocation::getFromRawEncoding(Record[Idx++]);
+      Designators.push_back(Designator(Field->getIdentifier(), DotLoc, 
+                                       FieldLoc));
+      Designators.back().setField(Field);
+      break;
+    }
+
+    case pch::DESIG_FIELD_NAME: {
+      const IdentifierInfo *Name = Reader.GetIdentifierInfo(Record, Idx);
+      SourceLocation DotLoc 
+        = SourceLocation::getFromRawEncoding(Record[Idx++]);
+      SourceLocation FieldLoc 
+        = SourceLocation::getFromRawEncoding(Record[Idx++]);
+      Designators.push_back(Designator(Name, DotLoc, FieldLoc));
+      break;
+    }
+      
+    case pch::DESIG_ARRAY: {
+      unsigned Index = Record[Idx++];
+      SourceLocation LBracketLoc
+        = SourceLocation::getFromRawEncoding(Record[Idx++]);
+      SourceLocation RBracketLoc
+        = SourceLocation::getFromRawEncoding(Record[Idx++]);
+      Designators.push_back(Designator(Index, LBracketLoc, RBracketLoc));
+      break;
+    }
+
+    case pch::DESIG_ARRAY_RANGE: {
+      unsigned Index = Record[Idx++];
+      SourceLocation LBracketLoc
+        = SourceLocation::getFromRawEncoding(Record[Idx++]);
+      SourceLocation EllipsisLoc
+        = SourceLocation::getFromRawEncoding(Record[Idx++]);
+      SourceLocation RBracketLoc
+        = SourceLocation::getFromRawEncoding(Record[Idx++]);
+      Designators.push_back(Designator(Index, LBracketLoc, EllipsisLoc,
+                                       RBracketLoc));
+      break;
+    }
+    }
+  }
+  E->setDesignators(&Designators[0], Designators.size());
+
+  return NumSubExprs;
+}
+
+unsigned PCHStmtReader::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
+  VisitExpr(E);
+  return 0;
+}
+
 unsigned PCHStmtReader::VisitVAArgExpr(VAArgExpr *E) {
   VisitExpr(E);
   E->setSubExpr(ExprStack.back());
@@ -2019,6 +2107,20 @@
       E = new (Context) ExtVectorElementExpr(Empty);
       break;
 
+    case pch::EXPR_INIT_LIST:
+      E = new (Context) InitListExpr(Empty);
+      break;
+
+    case pch::EXPR_DESIGNATED_INIT:
+      E = DesignatedInitExpr::CreateEmpty(Context, 
+                                     Record[PCHStmtReader::NumExprFields] - 1);
+     
+      break;
+
+    case pch::EXPR_IMPLICIT_VALUE_INIT:
+      E = new (Context) ImplicitValueInitExpr(Empty);
+      break;
+
     case pch::EXPR_VA_ARG:
       // FIXME: untested; we need function bodies first
       E = new (Context) VAArgExpr(Empty);

Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=69251&r1=69250&r2=69251&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Wed Apr 15 19:55:48 2009
@@ -465,6 +465,9 @@
     void VisitExplicitCastExpr(ExplicitCastExpr *E);
     void VisitCStyleCastExpr(CStyleCastExpr *E);
     void VisitExtVectorElementExpr(ExtVectorElementExpr *E);
+    void VisitInitListExpr(InitListExpr *E);
+    void VisitDesignatedInitExpr(DesignatedInitExpr *E);
+    void VisitImplicitValueInitExpr(ImplicitValueInitExpr *E);
     void VisitVAArgExpr(VAArgExpr *E);
     void VisitTypesCompatibleExpr(TypesCompatibleExpr *E);
     void VisitChooseExpr(ChooseExpr *E);
@@ -652,6 +655,61 @@
   Code = pch::EXPR_EXT_VECTOR_ELEMENT;
 }
 
+void PCHStmtWriter::VisitInitListExpr(InitListExpr *E) {
+  VisitExpr(E);
+  Record.push_back(E->getNumInits());
+  for (unsigned I = 0, N = E->getNumInits(); I != N; ++I)
+    Writer.WriteSubExpr(E->getInit(I));
+  Writer.WriteSubExpr(E->getSyntacticForm());
+  Writer.AddSourceLocation(E->getLBraceLoc(), Record);
+  Writer.AddSourceLocation(E->getRBraceLoc(), Record);
+  Writer.AddDeclRef(E->getInitializedFieldInUnion(), Record);
+  Record.push_back(E->hadArrayRangeDesignator());
+  Code = pch::EXPR_INIT_LIST;
+}
+
+void PCHStmtWriter::VisitDesignatedInitExpr(DesignatedInitExpr *E) {
+  VisitExpr(E);
+  Record.push_back(E->getNumSubExprs());
+  for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I)
+    Writer.WriteSubExpr(E->getSubExpr(I));
+  Writer.AddSourceLocation(E->getEqualOrColonLoc(), Record);
+  Record.push_back(E->usesGNUSyntax());
+  for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
+                                             DEnd = E->designators_end();
+       D != DEnd; ++D) {
+    if (D->isFieldDesignator()) {
+      if (FieldDecl *Field = D->getField()) {
+        Record.push_back(pch::DESIG_FIELD_DECL);
+        Writer.AddDeclRef(Field, Record);
+      } else {
+        Record.push_back(pch::DESIG_FIELD_NAME);
+        Writer.AddIdentifierRef(D->getFieldName(), Record);
+      }
+      Writer.AddSourceLocation(D->getDotLoc(), Record);
+      Writer.AddSourceLocation(D->getFieldLoc(), Record);
+    } else if (D->isArrayDesignator()) {
+      Record.push_back(pch::DESIG_ARRAY);
+      Record.push_back(D->getFirstExprIndex());
+      Writer.AddSourceLocation(D->getLBracketLoc(), Record);
+      Writer.AddSourceLocation(D->getRBracketLoc(), Record);
+    } else {
+      assert(D->isArrayRangeDesignator() && "Unknown designator");
+      Record.push_back(pch::DESIG_ARRAY_RANGE);
+      Record.push_back(D->getFirstExprIndex());
+      Writer.AddSourceLocation(D->getLBracketLoc(), Record);
+      Writer.AddSourceLocation(D->getEllipsisLoc(), Record);
+      Writer.AddSourceLocation(D->getRBracketLoc(), Record);
+    }
+  }
+  Code = pch::EXPR_DESIGNATED_INIT;
+}
+
+void PCHStmtWriter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
+  VisitExpr(E);
+  Code = pch::EXPR_IMPLICIT_VALUE_INIT;
+}
+
 void PCHStmtWriter::VisitVAArgExpr(VAArgExpr *E) {
   VisitExpr(E);
   Writer.WriteSubExpr(E->getSubExpr());

Modified: cfe/trunk/test/PCH/exprs.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/exprs.c?rev=69251&r1=69250&r2=69251&view=diff

==============================================================================
--- cfe/trunk/test/PCH/exprs.c (original)
+++ cfe/trunk/test/PCH/exprs.c Wed Apr 15 19:55:48 2009
@@ -64,6 +64,14 @@
 // ExtVectorElementExpr
 ext_vector_element *double_ptr5 = &floating;
 
+// InitListExpr
+double get_from_double_array(unsigned Idx) { return double_array[Idx]; }
+
+/// DesignatedInitExpr
+float get_from_designated(unsigned Idx) {
+  return designated_inits[2].y;
+}
+
 // TypesCompatibleExpr
 types_compatible *int_ptr7 = &integer;
 

Modified: cfe/trunk/test/PCH/exprs.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/exprs.h?rev=69251&r1=69250&r2=69251&view=diff

==============================================================================
--- cfe/trunk/test/PCH/exprs.h (original)
+++ cfe/trunk/test/PCH/exprs.h Wed Apr 15 19:55:48 2009
@@ -61,6 +61,15 @@
 extern double2 vec2, vec2b;
 typedef typeof(vec2.x) ext_vector_element;
 
+// InitListExpr
+double double_array[3] = { 1.0, 2.0 };
+
+// DesignatedInitExpr
+struct {
+  int x;
+  float y;
+} designated_inits[3] = { [0].y = 17, [2].x = 12.3, 3.5 };
+
 // TypesCompatibleExpr
 typedef typeof(__builtin_types_compatible_p(float, double)) types_compatible;
 





More information about the cfe-commits mailing list