From 8d16bd4d10abac4e9c9bde73ff4505a8fea5caad Mon Sep 17 00:00:00 2001 From: Abramo Bagnara Date: Thu, 8 Nov 2012 18:41:43 +0000 Subject: [PATCH] Allow to pass from syntactic form of InitListExpr to semantic form (just as viceversa). No functionality change. llvm-svn: 167591 --- clang/include/clang/AST/Expr.h | 47 ++++++++++++++++++++++--------- clang/lib/AST/Expr.cpp | 4 +-- clang/lib/Serialization/ASTReaderStmt.cpp | 3 +- clang/lib/Serialization/ASTWriterStmt.cpp | 2 ++ 4 files changed, 39 insertions(+), 17 deletions(-) diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 9b11e8e..dc83654 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -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 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 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; diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 9dec1e8..f3a2e05 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -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()) { diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 4c3e315..367f75f 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -627,7 +627,8 @@ void ASTStmtReader::VisitExtVectorElementExpr(ExtVectorElementExpr *E) { void ASTStmtReader::VisitInitListExpr(InitListExpr *E) { VisitExpr(E); - E->setSyntacticForm(cast_or_null(Reader.ReadSubStmt())); + if (InitListExpr *SyntForm = cast_or_null(Reader.ReadSubStmt())) + E->setSyntacticForm(SyntForm); E->setLBraceLoc(ReadSourceLocation(Record, Idx)); E->setRBraceLoc(ReadSourceLocation(Record, Idx)); bool isArrayFiller = Record[Idx++]; diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index b1ee84b..7e8ce42 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -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); -- 2.7.4