Build CastExpr AST nodes
llvm-svn: 38950
diff --git a/clang/Parse/ParseExpr.cpp b/clang/Parse/ParseExpr.cpp
index 18a0e51..f6443bc 100644
--- a/clang/Parse/ParseExpr.cpp
+++ b/clang/Parse/ParseExpr.cpp
@@ -430,12 +430,15 @@
// suffixes. Cases that cannot be followed by postfix exprs should
// return without invoking ParsePostfixExpressionSuffix.
switch (Tok.getKind()) {
- case tok::l_paren:
+ case tok::l_paren: {
// If this expression is limited to being a unary-expression, the parent can
// not start a cast expression.
ParenParseOption ParenExprType =
isUnaryExpression ? CompoundLiteral : CastExpr;
- Res = ParseParenExpression(ParenExprType);
+ TypeTy *CastTy;
+ SourceLocation LParenLoc = Tok.getLocation();
+ SourceLocation RParenLoc;
+ Res = ParseParenExpression(ParenExprType, CastTy, RParenLoc);
if (Res.isInvalid) return Res;
switch (ParenExprType) {
@@ -448,11 +451,16 @@
case CastExpr:
// We parsed '(' type-name ')' and the thing after it wasn't a '{'. Parse
// the cast-expression that follows it next.
- return ParseCastExpression(false);
+ // TODO: For cast expression with CastTy.
+ Res = ParseCastExpression(false);
+ if (!Res.isInvalid)
+ Res = Actions.ParseCastExpr(LParenLoc, CastTy, RParenLoc, Res.Val);
+ return Res;
}
// These can be followed by postfix-expr pieces.
return ParsePostfixExpressionSuffix(Res);
+ }
// primary-expression
case tok::numeric_constant:
@@ -661,7 +669,6 @@
ConsumeToken();
// If the operand doesn't start with an '(', it must be an expression.
- // TODO: Build AST.
ExprResult Operand;
if (Tok.getKind() != tok::l_paren) {
Operand = ParseCastExpression(true);
@@ -671,12 +678,15 @@
// literal, or starts with a primary-expression that is a parenthesized
// expression.
ParenParseOption ExprType = CastExpr;
- Operand = ParseParenExpression(ExprType);
+ TypeTy *CastTy;
+ SourceLocation RParenLoc;
+ Operand = ParseParenExpression(ExprType, CastTy, RParenLoc);
// If ParseParenExpression parsed a '(typename)' sequence only, the this is
// sizeof/alignof a type. Otherwise, it is sizeof/alignof an expression.
if (ExprType == CastExpr) {
- // TODO: Get type from ParseParenExpression and build AST here.
+ // TODO: Build AST here for sizeof type.
+ CastTy;
return ExprResult(false);
}
}
@@ -831,11 +841,14 @@
/// cast-expression: [C99 6.5.4]
/// '(' type-name ')' cast-expression
///
-Parser::ExprResult Parser::ParseParenExpression(ParenParseOption &ExprType) {
+Parser::ExprResult Parser::ParseParenExpression(ParenParseOption &ExprType,
+ TypeTy *&CastTy,
+ SourceLocation &RParenLoc) {
assert(Tok.getKind() == tok::l_paren && "Not a paren expr!");
SourceLocation OpenLoc = Tok.getLocation();
ConsumeParen();
ExprResult Result(false);
+ CastTy = 0;
if (ExprType >= CompoundStmt && Tok.getKind() == tok::l_brace &&
!getLang().NoExtensions) {
@@ -845,11 +858,16 @@
// TODO: Build AST for GNU compound stmt.
} else if (ExprType >= CompoundLiteral && isTypeSpecifierQualifier()) {
// Otherwise, this is a compound literal expression or cast expression.
- ParseTypeName();
+ TypeTy *Ty = ParseTypeName();
// Match the ')'.
- MatchRHSPunctuation(tok::r_paren, OpenLoc);
-
+ if (Tok.getKind() == tok::r_paren) {
+ RParenLoc = Tok.getLocation();
+ ConsumeParen();
+ } else {
+ MatchRHSPunctuation(tok::r_paren, OpenLoc);
+ }
+
if (Tok.getKind() == tok::l_brace) {
if (!getLang().C99) // Compound literals don't exist in C90.
Diag(OpenLoc, diag::ext_c99_compound_literal);
@@ -857,9 +875,11 @@
ExprType = CompoundLiteral;
// TODO: Build AST for compound literal.
} else if (ExprType == CastExpr) {
- // Note that this doesn't parse the subsequence cast-expression.
+ // Note that this doesn't parse the subsequence cast-expression, it just
+ // returns the parsed type to the callee.
ExprType = CastExpr;
- // TODO: Build AST for cast in caller.
+ CastTy = Ty;
+ return ExprResult(false);
} else {
Diag(Tok, diag::err_expected_lbrace_in_compound_literal);
return ExprResult(true);
@@ -875,8 +895,14 @@
// Match the ')'.
if (Result.isInvalid)
SkipUntil(tok::r_paren);
- else
- MatchRHSPunctuation(tok::r_paren, OpenLoc);
+ else {
+ if (Tok.getKind() == tok::r_paren) {
+ RParenLoc = Tok.getLocation();
+ ConsumeParen();
+ } else {
+ MatchRHSPunctuation(tok::r_paren, OpenLoc);
+ }
+ }
return Result;
}