aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/Expr.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-01-22 00:58:24 +0000
committerDouglas Gregor <dgregor@apple.com>2009-01-22 00:58:24 +0000
commit05c13a3411782108d65aab3c77b1a231a4963bc0 (patch)
tree06c579135c022b061f4665e7607296b0920c9261 /lib/AST/Expr.cpp
parentdb2868616b966c96a5014e58892c27cea377477c (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.cpp111
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();