aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Naroff <snaroff@apple.com>2007-07-19 01:06:55 +0000
committerSteve Naroff <snaroff@apple.com>2007-07-19 01:06:55 +0000
commit4aa88f8d8469ced8fe04a0c411bbccc5d313e055 (patch)
treea97e5da5cc19f88582b7950ae237a1150160ab1f
parent5265af5b555f703be365dbc32c4e518fe38d4d9a (diff)
Work towards fixing crasher with compound literals...
Before this commit, we crashed in ParseBinOp... [dylan:~/llvm/tools/clang] admin% ../../Debug/bin/clang -parse-ast-check compound_literal.c SemaExpr.cpp:1298: failed assertion `(rhs != 0) && "ParseBinOp(): missing right expression"' With this commit, we still crash in the newly added action ParseCompoundLiteral (which is progress:-) [dylan:~/llvm/tools/clang] admin% ../../Debug/bin/clang -parse-ast-check compound_literal.c SemaExpr.cpp:478: failed assertion `(Op != 0) && "ParseCompoundLiteral(): missing expression"' The crash go away once the actions return AST nodes. I will do this in a separate commit. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@40032 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--Parse/ParseExpr.cpp3
-rw-r--r--Parse/ParseInit.cpp63
-rw-r--r--Sema/Sema.h7
-rw-r--r--Sema/SemaExpr.cpp22
-rw-r--r--include/clang/Parse/Action.h9
-rw-r--r--test/Parser/compound_literal.c5
6 files changed, 82 insertions, 27 deletions
diff --git a/Parse/ParseExpr.cpp b/Parse/ParseExpr.cpp
index 41f347f9aa..5862e7bd84 100644
--- a/Parse/ParseExpr.cpp
+++ b/Parse/ParseExpr.cpp
@@ -880,7 +880,8 @@ Parser::ExprResult Parser::ParseParenExpression(ParenParseOption &ExprType,
Diag(OpenLoc, diag::ext_c99_compound_literal);
Result = ParseInitializer();
ExprType = CompoundLiteral;
- // TODO: Build AST for compound literal.
+ if (!Result.isInvalid)
+ return Actions.ParseCompoundLiteral(OpenLoc, Ty, RParenLoc, Result.Val);
} else if (ExprType == CastExpr) {
// Note that this doesn't parse the subsequence cast-expression, it just
// returns the parsed type to the callee.
diff --git a/Parse/ParseInit.cpp b/Parse/ParseInit.cpp
index 01169d8859..75e1c7356e 100644
--- a/Parse/ParseInit.cpp
+++ b/Parse/ParseInit.cpp
@@ -13,6 +13,7 @@
#include "clang/Parse/Parser.h"
#include "clang/Basic/Diagnostic.h"
+#include "llvm/ADT/SmallString.h"
using namespace clang;
@@ -152,37 +153,47 @@ Parser::ExprResult Parser::ParseInitializer() {
// We support empty initializers, but tell the user that they aren't using
// C99-clean code.
- if (Tok.getKind() == tok::r_brace)
+ if (Tok.getKind() == tok::r_brace) {
Diag(LBraceLoc, diag::ext_gnu_empty_initializer);
- else {
- while (1) {
- // Parse: designation[opt] initializer
-
- // If we know that this cannot be a designation, just parse the nested
- // initializer directly.
- ExprResult SubElt;
- if (!MayBeDesignationStart(Tok.getKind()))
- SubElt = ParseInitializer();
- else
- SubElt = ParseInitializerWithPotentialDesignator();
-
- // If we couldn't parse the subelement, bail out.
- if (SubElt.isInvalid) {
- SkipUntil(tok::r_brace);
- return SubElt;
- }
+ // Match the '}'.
+ return Actions.ParseInitList(LBraceLoc, 0, 0, ConsumeBrace());
+ }
+ llvm::SmallVector<ExprTy*, 8> InitExprs;
+ bool InitExprsOk = true;
+
+ while (1) {
+ // Parse: designation[opt] initializer
- // If we don't have a comma continued list, we're done.
- if (Tok.getKind() != tok::comma) break;
- ConsumeToken();
+ // If we know that this cannot be a designation, just parse the nested
+ // initializer directly.
+ ExprResult SubElt;
+ if (!MayBeDesignationStart(Tok.getKind()))
+ SubElt = ParseInitializer();
+ else
+ SubElt = ParseInitializerWithPotentialDesignator();
+
+ // If we couldn't parse the subelement, bail out.
+ if (SubElt.isInvalid) {
+ InitExprsOk = false;
+ SkipUntil(tok::r_brace);
+ break;
+ } else
+ InitExprs.push_back(SubElt.Val);
- // Handle trailing comma.
- if (Tok.getKind() == tok::r_brace) break;
- }
+ // If we don't have a comma continued list, we're done.
+ if (Tok.getKind() != tok::comma) break;
+
+ // FIXME: save comma locations.
+ ConsumeToken();
+
+ // Handle trailing comma.
+ if (Tok.getKind() == tok::r_brace) break;
}
-
+ if (InitExprsOk && Tok.getKind() == tok::r_brace)
+ return Actions.ParseInitList(LBraceLoc, &InitExprs[0], InitExprs.size(),
+ ConsumeBrace());
// Match the '}'.
MatchRHSPunctuation(tok::r_brace, LBraceLoc);
- return ExprResult(false);
+ return ExprResult(true); // an error occurred.
}
diff --git a/Sema/Sema.h b/Sema/Sema.h
index f87cee60a9..0feddd3b15 100644
--- a/Sema/Sema.h
+++ b/Sema/Sema.h
@@ -245,7 +245,14 @@ public:
virtual ExprResult ParseCastExpr(SourceLocation LParenLoc, TypeTy *Ty,
SourceLocation RParenLoc, ExprTy *Op);
+
+ virtual ExprResult ParseCompoundLiteral(SourceLocation LParenLoc, TypeTy *Ty,
+ SourceLocation RParenLoc, ExprTy *Op);
+ virtual ExprResult ParseInitList(SourceLocation LParenLoc,
+ ExprTy **InitList, unsigned NumInit,
+ SourceLocation RParenLoc);
+
virtual ExprResult ParseBinOp(SourceLocation TokLoc, tok::TokenKind Kind,
ExprTy *LHS,ExprTy *RHS);
diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp
index 044fb63bf0..999f29a8ae 100644
--- a/Sema/SemaExpr.cpp
+++ b/Sema/SemaExpr.cpp
@@ -471,6 +471,28 @@ ParseCallExpr(ExprTy *Fn, SourceLocation LParenLoc,
}
Action::ExprResult Sema::
+ParseCompoundLiteral(SourceLocation LParenLoc, TypeTy *Ty,
+ SourceLocation RParenLoc, ExprTy *Op) {
+ assert((Ty != 0) && "ParseCompoundLiteral(): missing type");
+ QualType literalType = QualType::getFromOpaquePtr(Ty);
+ assert((Op != 0) && "ParseCompoundLiteral(): missing expression");
+ Expr *literalExpr = static_cast<Expr*>(Op);
+
+ // FIXME: add semantic analysis (C99 6.5.2.5).
+ return false; // FIXME: instantiate a CompoundLiteralExpr
+}
+
+Action::ExprResult Sema::
+ParseInitList(SourceLocation LParenLoc, ExprTy **InitList, unsigned NumInit,
+ SourceLocation RParenLoc) {
+ // FIXME: add semantic analysis (C99 6.7.8). This involves
+ // knowledge of the object being intialized. As a result, the code for
+ // doing the semantic analysis will likely be located elsewhere (i.e. in
+ // consumers of InitListExpr (e.g. ParseDeclarator, ParseCompoundLiteral).
+ return false; // FIXME instantiate an InitListExpr.
+}
+
+Action::ExprResult Sema::
ParseCastExpr(SourceLocation LParenLoc, TypeTy *Ty,
SourceLocation RParenLoc, ExprTy *Op) {
assert((Ty != 0) && (Op != 0) && "ParseCastExpr(): missing type or expr");
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
index bf5499a081..4922c9a463 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -332,6 +332,15 @@ public:
return 0;
}
+ virtual ExprResult ParseCompoundLiteral(SourceLocation LParen, TypeTy *Ty,
+ SourceLocation RParen, ExprTy *Op) {
+ return 0;
+ }
+ virtual ExprResult ParseInitList(SourceLocation LParenLoc,
+ ExprTy **InitList, unsigned NumInit,
+ SourceLocation RParenLoc) {
+ return 0;
+ }
virtual ExprResult ParseCastExpr(SourceLocation LParenLoc, TypeTy *Ty,
SourceLocation RParenLoc, ExprTy *Op) {
return 0;
diff --git a/test/Parser/compound_literal.c b/test/Parser/compound_literal.c
new file mode 100644
index 0000000000..ef4576d18f
--- /dev/null
+++ b/test/Parser/compound_literal.c
@@ -0,0 +1,5 @@
+// RUN: clang -parse-ast-check %s
+int main() {
+ char *s;
+ s = (char []){"whatever"};
+}