summaryrefslogtreecommitdiffstats
path: root/clang/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
commite4a0bb7a2039ed34ce1c253816aa3020007d3447 (patch)
tree69969f33a8c827a454ef563c395f4bf232cf00e1 /clang/lib/AST/Expr.cpp
parenteee54df5b611055c537ea92c7bbf89ca1fa4a14f (diff)
downloadbcm5719-llvm-e4a0bb7a2039ed34ce1c253816aa3020007d3447.tar.gz
bcm5719-llvm-e4a0bb7a2039ed34ce1c253816aa3020007d3447.zip
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. llvm-svn: 62737
Diffstat (limited to 'clang/lib/AST/Expr.cpp')
-rw-r--r--clang/lib/AST/Expr.cpp111
1 files changed, 111 insertions, 0 deletions
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 03b49499ee2..70b63fea1bd 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/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();
OpenPOWER on IntegriCloud