Allow to pass from syntactic form of InitListExpr to semantic form (just as viceversa...
authorAbramo Bagnara <abramo.bagnara@bugseng.com>
Thu, 8 Nov 2012 18:41:43 +0000 (18:41 +0000)
committerAbramo Bagnara <abramo.bagnara@bugseng.com>
Thu, 8 Nov 2012 18:41:43 +0000 (18:41 +0000)
llvm-svn: 167591

clang/include/clang/AST/Expr.h
clang/lib/AST/Expr.cpp
clang/lib/Serialization/ASTReaderStmt.cpp
clang/lib/Serialization/ASTWriterStmt.cpp

index 9b11e8e..dc83654 100644 (file)
@@ -3539,21 +3539,32 @@ public:
 /// initializer lists may still have fewer initializers than there are
 /// elements to initialize within the object.
 ///
+/// After semantic analysis has completed, given an initializer list,
+/// method isSemanticForm() returns true if and only if this is the
+/// semantic form of the initializer list (note: the same AST node
+/// may at the same time be the syntactic form).
 /// Given the semantic form of the initializer list, one can retrieve
-/// the original syntactic form of that initializer list (if it
-/// exists) using getSyntacticForm(). Since many initializer lists
-/// have the same syntactic and semantic forms, getSyntacticForm() may
-/// return NULL, indicating that the current initializer list also
-/// serves as its syntactic form.
+/// the syntactic form of that initializer list (when different)
+/// using method getSyntacticForm(); the method returns null if applied
+/// to a initializer list which is already in syntactic form.
+/// Similarly, given the syntactic form (i.e., an initializer list such
+/// that isSemanticForm() returns false), one can retrieve the semantic
+/// form using method getSemanticForm().
+/// Since many initializer lists have the same syntactic and semantic forms,
+/// getSyntacticForm() may return NULL, indicating that the current
+/// semantic initializer list also serves as its syntactic form.
 class InitListExpr : public Expr {
   // FIXME: Eliminate this vector in favor of ASTContext allocation
   typedef ASTVector<Stmt *> InitExprsTy;
   InitExprsTy InitExprs;
   SourceLocation LBraceLoc, RBraceLoc;
 
-  /// Contains the initializer list that describes the syntactic form
-  /// written in the source code.
-  InitListExpr *SyntacticForm;
+  /// The alternative form of the initializer list (if it exists).
+  /// The int part of the pair stores whether this initalizer list is
+  /// in semantic form. If not null, the pointer points to:
+  ///   - the syntactic form, if this is in semantic form;
+  ///   - the semantic form, if this is in syntactic form.
+  llvm::PointerIntPair<InitListExpr *, 1, bool> AltForm;
 
   /// \brief Either:
   ///  If this initializer list initializes an array with more elements than
@@ -3658,12 +3669,20 @@ public:
   SourceLocation getRBraceLoc() const { return RBraceLoc; }
   void setRBraceLoc(SourceLocation Loc) { RBraceLoc = Loc; }
 
-  /// @brief Retrieve the initializer list that describes the
-  /// syntactic form of the initializer.
-  ///
-  ///
-  InitListExpr *getSyntacticForm() const { return SyntacticForm; }
-  void setSyntacticForm(InitListExpr *Init) { SyntacticForm = Init; }
+  bool isSemanticForm() const { return AltForm.getInt(); }
+  InitListExpr *getSemanticForm() const {
+    return isSemanticForm() ? 0 : AltForm.getPointer();
+  }
+  InitListExpr *getSyntacticForm() const {
+    return isSemanticForm() ? AltForm.getPointer() : 0;
+  }
+
+  void setSyntacticForm(InitListExpr *Init) {
+    AltForm.setPointer(Init);
+    AltForm.setInt(true);
+    Init->AltForm.setPointer(this);
+    Init->AltForm.setInt(false);
+  }
 
   bool hadArrayRangeDesignator() const {
     return InitListExprBits.HadArrayRangeDesignator != 0;
index 9dec1e8..f3a2e05 100644 (file)
@@ -1748,7 +1748,7 @@ InitListExpr::InitListExpr(ASTContext &C, SourceLocation lbraceloc,
   : Expr(InitListExprClass, QualType(), VK_RValue, OK_Ordinary, false, false,
          false, false),
     InitExprs(C, initExprs.size()),
-    LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), SyntacticForm(0)
+    LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), AltForm(0, true)
 {
   sawArrayRangeDesignator(false);
   setInitializesStdInitializerList(false);
@@ -1808,7 +1808,7 @@ bool InitListExpr::isStringLiteralInit() const {
 }
 
 SourceRange InitListExpr::getSourceRange() const {
-  if (SyntacticForm)
+  if (InitListExpr *SyntacticForm = getSyntacticForm())
     return SyntacticForm->getSourceRange();
   SourceLocation Beg = LBraceLoc, End = RBraceLoc;
   if (Beg.isInvalid()) {
index 4c3e315..367f75f 100644 (file)
@@ -627,7 +627,8 @@ void ASTStmtReader::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
 
 void ASTStmtReader::VisitInitListExpr(InitListExpr *E) {
   VisitExpr(E);
-  E->setSyntacticForm(cast_or_null<InitListExpr>(Reader.ReadSubStmt()));
+  if (InitListExpr *SyntForm = cast_or_null<InitListExpr>(Reader.ReadSubStmt()))
+    E->setSyntacticForm(SyntForm);
   E->setLBraceLoc(ReadSourceLocation(Record, Idx));
   E->setRBraceLoc(ReadSourceLocation(Record, Idx));
   bool isArrayFiller = Record[Idx++];
index b1ee84b..7e8ce42 100644 (file)
@@ -606,6 +606,8 @@ void ASTStmtWriter::VisitExtVectorElementExpr(ExtVectorElementExpr *E) {
 
 void ASTStmtWriter::VisitInitListExpr(InitListExpr *E) {
   VisitExpr(E);
+  // NOTE: only add the (possibly null) syntactic form.
+  // No need to serialize the isSemanticForm flag and the semantic form.
   Writer.AddStmt(E->getSyntacticForm());
   Writer.AddSourceLocation(E->getLBraceLoc(), Record);
   Writer.AddSourceLocation(E->getRBraceLoc(), Record);