diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-04-16 00:55:48 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-04-16 00:55:48 +0000 |
commit | d077d759d0c7fceee98f4e77b6423a3f11cfc849 (patch) | |
tree | 9d9c61b9a10e40bf3465f327d29b05e86aaee330 | |
parent | 8ac3af96a162a0d01331e1a32b03d081be49d19b (diff) |
PCH support for InitListExpr, DesignatedInitExpr, and ImplicitValueInitExpr.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69251 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/Expr.h | 50 | ||||
-rw-r--r-- | include/clang/Frontend/PCHBitCodes.h | 24 | ||||
-rw-r--r-- | lib/AST/Expr.cpp | 18 | ||||
-rw-r--r-- | lib/Frontend/PCHReader.cpp | 102 | ||||
-rw-r--r-- | lib/Frontend/PCHWriter.cpp | 58 | ||||
-rw-r--r-- | test/PCH/exprs.c | 8 | ||||
-rw-r--r-- | test/PCH/exprs.h | 9 |
7 files changed, 264 insertions, 5 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index a0a1689d18..fbe2953300 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -1969,6 +1969,9 @@ class InitListExpr : public Expr { 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 @@ public: 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 @@ public: 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 @@ private: 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 @@ public: 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 @@ public: 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 @@ public: 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 @@ public: /// @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 @@ public: *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 @@ public: 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; } diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h index 568bda0b98..6a75245b80 100644 --- a/include/clang/Frontend/PCHBitCodes.h +++ b/include/clang/Frontend/PCHBitCodes.h @@ -422,9 +422,12 @@ namespace clang { /// 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 @@ namespace clang { /// 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 diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index e1603c90e1..9e8958c073 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -1581,6 +1581,24 @@ DesignatedInitExpr::Create(ASTContext &C, Designator *Designators, 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 = diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index b829075913..2da35a09d6 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -258,6 +258,9 @@ namespace { 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 @@ unsigned PCHStmtReader::VisitExtVectorElementExpr(ExtVectorElementExpr *E) { 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 @@ Expr *PCHReader::ReadExpr() { 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); diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index 4201a69f73..f96288864b 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -465,6 +465,9 @@ namespace { 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 @@ void PCHStmtWriter::VisitExtVectorElementExpr(ExtVectorElementExpr *E) { 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()); diff --git a/test/PCH/exprs.c b/test/PCH/exprs.c index d3d4b37a88..e08024b9bb 100644 --- a/test/PCH/exprs.c +++ b/test/PCH/exprs.c @@ -64,6 +64,14 @@ void_ptr vp1 = &integer; // 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; diff --git a/test/PCH/exprs.h b/test/PCH/exprs.h index a928b9b2e8..43fd89595e 100644 --- a/test/PCH/exprs.h +++ b/test/PCH/exprs.h @@ -61,6 +61,15 @@ typedef __attribute__(( ext_vector_type(2) )) double double2; 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; |