diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-01-22 00:58:24 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-01-22 00:58:24 +0000 |
commit | 05c13a3411782108d65aab3c77b1a231a4963bc0 (patch) | |
tree | 06c579135c022b061f4665e7607296b0920c9261 /lib/AST/Expr.cpp | |
parent | db2868616b966c96a5014e58892c27cea377477c (diff) |
Initial implementation of semantic analysis and ASTs for C99
designated initializers. This implementation should cover all of the
constraints in C99 6.7.8, including long, complex designations and
computing the size of incomplete array types initialized with a
designated initializer. Please see the new test-case and holler if you
find cases where this doesn't work.
There are still some wrinkles with GNU's anonymous structs and
anonymous unions (it isn't clear how these should work; we'll just
follow GCC's lead) and with designated initializers for the members of a
union. I'll tackle those very soon.
CodeGen is still nonexistent, and there's some leftover code in the
parser's representation of designators that I'll also need to clean up.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62737 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/Expr.cpp')
-rw-r--r-- | lib/AST/Expr.cpp | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 03b49499ee..70b63fea1b 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -1349,6 +1349,106 @@ void SizeOfAlignOfExpr::Destroy(ASTContext& C) { } //===----------------------------------------------------------------------===// +// DesignatedInitExpr +//===----------------------------------------------------------------------===// + +IdentifierInfo *DesignatedInitExpr::Designator::getFieldName() { + assert(Kind == FieldDesignator && "Only valid on a field designator"); + if (Field.NameOrField & 0x01) + return reinterpret_cast<IdentifierInfo *>(Field.NameOrField&~0x01); + else + return getField()->getIdentifier(); +} + +DesignatedInitExpr * +DesignatedInitExpr::Create(ASTContext &C, Designator *Designators, + unsigned NumDesignators, + Expr **IndexExprs, unsigned NumIndexExprs, + SourceLocation ColonOrEqualLoc, + bool UsesColonSyntax, Expr *Init) { + void *Mem = C.getAllocator().Allocate(sizeof(DesignatedInitExpr) + + sizeof(Designator) * NumDesignators + + sizeof(Stmt *) * (NumIndexExprs + 1), + 8); + DesignatedInitExpr *DIE + = new (Mem) DesignatedInitExpr(C.VoidTy, NumDesignators, + ColonOrEqualLoc, UsesColonSyntax, + NumIndexExprs + 1); + + // Fill in the designators + unsigned ExpectedNumSubExprs = 0; + designators_iterator Desig = DIE->designators_begin(); + for (unsigned Idx = 0; Idx < NumDesignators; ++Idx, ++Desig) { + new (static_cast<void*>(Desig)) Designator(Designators[Idx]); + if (Designators[Idx].isArrayDesignator()) + ++ExpectedNumSubExprs; + else if (Designators[Idx].isArrayRangeDesignator()) + ExpectedNumSubExprs += 2; + } + assert(ExpectedNumSubExprs == NumIndexExprs && "Wrong number of indices!"); + + // Fill in the subexpressions, including the initializer expression. + child_iterator Child = DIE->child_begin(); + *Child++ = Init; + for (unsigned Idx = 0; Idx < NumIndexExprs; ++Idx, ++Child) + *Child = IndexExprs[Idx]; + + return DIE; +} + +SourceRange DesignatedInitExpr::getSourceRange() const { + SourceLocation StartLoc; + Designator &First = *const_cast<DesignatedInitExpr*>(this)->designators_begin(); + if (First.isFieldDesignator()) { + if (UsesColonSyntax) + StartLoc = SourceLocation::getFromRawEncoding(First.Field.FieldLoc); + else + StartLoc = SourceLocation::getFromRawEncoding(First.Field.DotLoc); + } else + StartLoc = SourceLocation::getFromRawEncoding(First.ArrayOrRange.LBracketLoc); + return SourceRange(StartLoc, getInit()->getSourceRange().getEnd()); +} + +DesignatedInitExpr::designators_iterator DesignatedInitExpr::designators_begin() { + char* Ptr = static_cast<char*>(static_cast<void *>(this)); + Ptr += sizeof(DesignatedInitExpr); + return static_cast<Designator*>(static_cast<void*>(Ptr)); +} + +DesignatedInitExpr::designators_iterator DesignatedInitExpr::designators_end() { + return designators_begin() + NumDesignators; +} + +Expr *DesignatedInitExpr::getArrayIndex(const Designator& D) { + assert(D.Kind == Designator::ArrayDesignator && "Requires array designator"); + char* Ptr = static_cast<char*>(static_cast<void *>(this)); + Ptr += sizeof(DesignatedInitExpr); + Ptr += sizeof(Designator) * NumDesignators; + Stmt **SubExprs = reinterpret_cast<Stmt**>(reinterpret_cast<void**>(Ptr)); + return cast<Expr>(*(SubExprs + D.ArrayOrRange.Index + 1)); +} + +Expr *DesignatedInitExpr::getArrayRangeStart(const Designator& D) { + assert(D.Kind == Designator::ArrayRangeDesignator && + "Requires array range designator"); + char* Ptr = static_cast<char*>(static_cast<void *>(this)); + Ptr += sizeof(DesignatedInitExpr); + Ptr += sizeof(Designator) * NumDesignators; + Stmt **SubExprs = reinterpret_cast<Stmt**>(reinterpret_cast<void**>(Ptr)); + return cast<Expr>(*(SubExprs + D.ArrayOrRange.Index + 1)); +} + +Expr *DesignatedInitExpr::getArrayRangeEnd(const Designator& D) { + assert(D.Kind == Designator::ArrayRangeDesignator && + "Requires array range designator"); + char* Ptr = static_cast<char*>(static_cast<void *>(this)); + Ptr += sizeof(DesignatedInitExpr); + Ptr += sizeof(Designator) * NumDesignators; + Stmt **SubExprs = reinterpret_cast<Stmt**>(reinterpret_cast<void**>(Ptr)); + return cast<Expr>(*(SubExprs + D.ArrayOrRange.Index + 2)); +} + +//===----------------------------------------------------------------------===// // ExprIterator. //===----------------------------------------------------------------------===// @@ -1533,6 +1633,17 @@ Stmt::child_iterator InitListExpr::child_end() { return InitExprs.size() ? &InitExprs[0] + InitExprs.size() : 0; } +/// DesignatedInitExpr +Stmt::child_iterator DesignatedInitExpr::child_begin() { + char* Ptr = static_cast<char*>(static_cast<void *>(this)); + Ptr += sizeof(DesignatedInitExpr); + Ptr += sizeof(Designator) * NumDesignators; + return reinterpret_cast<Stmt**>(reinterpret_cast<void**>(Ptr)); +} +Stmt::child_iterator DesignatedInitExpr::child_end() { + return child_iterator(&*child_begin() + NumSubExprs); +} + // ObjCStringLiteral Stmt::child_iterator ObjCStringLiteral::child_begin() { return child_iterator(); |