Skip to content

Commit

Permalink
C++ front-end: More work on brace init
Browse files Browse the repository at this point in the history
  • Loading branch information
tautschnig committed Jul 16, 2024
1 parent 549d1f9 commit c8ef059
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 103 deletions.
7 changes: 1 addition & 6 deletions src/cpp/cpp_typecheck_expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -967,13 +967,8 @@ void cpp_typecheckt::typecheck_expr_explicit_constructor_call(exprt &expr)
}
else
{
CHECK_RETURN(expr.type().id() == ID_struct);

struct_tag_typet tag(expr.type().get(ID_name));
tag.add_source_location() = expr.source_location();

exprt e=expr;
new_temporary(e.source_location(), tag, e.operands(), expr);
new_temporary(e.source_location(), e.type(), e.operands(), expr);
}
}

Expand Down
154 changes: 57 additions & 97 deletions src/cpp/parse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ Author: Daniel Kroening, [email protected]
#include "cpp_member_spec.h"
#include "cpp_enum_type.h"

#define DEBUG
#ifdef DEBUG
#include <iostream>

Expand Down Expand Up @@ -6363,7 +6362,10 @@ bool Parser::rAllocateInitializer(exprt &init)
postfix.exp
: primary.exp
| postfix.expr '[' comma.expression ']'
| postfix.expr '[' initializer ']'
| postfix.expr '(' function.arguments ')'
| integral.or.class.spec '(' function.arguments ')'
| integral.or.class.spec initializer
| postfix.expr '.' var.name
| postfix.expr ArrowOp var.name
| postfix.expr IncOp
Expand All @@ -6372,8 +6374,6 @@ bool Parser::rAllocateInitializer(exprt &init)
openc++.postfix.expr
: postfix.expr '.' userdef.statement
| postfix.expr ArrowOp userdef.statement
Note: function-style casts are accepted as function calls.
*/
bool Parser::rPostfixExpr(exprt &exp)
{
Expand All @@ -6382,8 +6382,52 @@ bool Parser::rPostfixExpr(exprt &exp)
std::cout << std::string(__indent, ' ') << "Parser::rPostfixExpr 0\n";
#endif

if(!rPrimaryExpr(exp))
return false;
typet type;

cpp_token_buffert::post pos=lex.Save();
// try to see whether this is explicit type conversion, else it has to be
// a primary-expression
if(optIntegralTypeOrClassSpec(type) &&
(type.is_not_nil() || rName(type)) &&
(lex.LookAhead(0) == '(' || lex.LookAhead(0) == '{'))
{
#ifdef DEBUG
std::cout << std::string(__indent, ' ') << "Parser::rPostfixExpr 0.1\n";
#endif

cpp_tokent tk;
lex.LookAhead(0, tk);
exprt exp2;
if(lex.LookAhead(0)=='{')
{
if(!rInitializeExpr(exp2))
return false;
}
else
{
// lex.LookAhead(0)=='('
lex.get_token(tk);

exprt exp2;
if(!rFunctionArguments(exp2))
return false;

cpp_tokent tk2;
if(lex.get_token(tk2)!=')')
return false;
}

exp=exprt("explicit-constructor-call");
exp.type().swap(type);
exp.operands().swap(exp2.operands());
set_location(exp, tk);
}
else
{
lex.Restore(pos);
if(!rPrimaryExpr(exp))
return false;
}

#ifdef DEBUG
std::cout << std::string(__indent, ' ') << "Parser::rPostfixExpr 1\n";
Expand All @@ -6399,7 +6443,14 @@ bool Parser::rPostfixExpr(exprt &exp)
{
case '[':
lex.get_token(op);
if(!rCommaExpression(e))

if(lex.LookAhead(0) == '{')
{
// C++11 initialisation expression
if(!rInitializeExpr(e))
return false;
}
else if(!rCommaExpression(e))
return false;

#ifdef DEBUG
Expand Down Expand Up @@ -6447,35 +6498,6 @@ bool Parser::rPostfixExpr(exprt &exp)
}
break;

case '{':
#ifdef DEBUG
std::cout << std::string(__indent, ' ') << "Parser::rPostfixExpr 3a\n";
#endif

// this is a C++11 extension
if(!rInitializeExpr(e))
return false;

if(lex.get_token(cp)!='}')
return false;

#ifdef DEBUG
std::cout << std::string(__indent, ' ') << "Parser::rPostfixExpr 4a\n";
#endif

{
side_effect_expr_function_callt fc(
std::move(exp), {}, typet{}, source_locationt{});
fc.arguments().reserve(e.operands().size());
set_location(fc, op);

Forall_operands(it, e)
fc.arguments().push_back(*it);
e.operands().clear(); // save some
exp.swap(fc);
}
break;

case TOK_INCR:
lex.get_token(op);

Expand Down Expand Up @@ -6746,8 +6768,6 @@ bool Parser::rTypePredicate(exprt &expr)
| THIS
| var.name
| '(' comma.expression ')'
| integral.or.class.spec '(' function.arguments ')'
| integral.or.class.spec initializer
| typeid.expr
| true
| false
Expand Down Expand Up @@ -6865,12 +6885,6 @@ bool Parser::rPrimaryExpr(exprt &exp)
#endif
return true;

case '{': // C++11 initialisation expression
#ifdef DEBUG
std::cout << std::string(__indent, ' ') << "Parser::rPrimaryExpr 10\n";
#endif
return rInitializeExpr(exp);

case TOK_TYPEID:
return rTypeidExpr(exp);

Expand Down Expand Up @@ -6901,60 +6915,6 @@ bool Parser::rPrimaryExpr(exprt &exp)
std::cout << std::string(__indent, ' ') << "Parser::rPrimaryExpr 14\n";
#endif
{
typet type;

if(!optIntegralTypeOrClassSpec(type))
return false;

#ifdef DEBUG
std::cout << std::string(__indent, ' ') << "Parser::rPrimaryExpr 15\n";
#endif

if(type.is_not_nil() && lex.LookAhead(0)==TOK_SCOPE)
{
lex.get_token(tk);
lex.get_token(tk);

// TODO
}
else if(type.is_not_nil())
{
#ifdef DEBUG
std::cout << std::string(__indent, ' ') << "Parser::rPrimaryExpr 16\n";
#endif
if(lex.LookAhead(0)=='{')
{
lex.LookAhead(0, tk);

exprt exp2;
if(!rInitializeExpr(exp2))
return false;

exp=exprt("explicit-constructor-call");
exp.type().swap(type);
exp.add_to_operands(std::move(exp2));
set_location(exp, tk);
}
else if(lex.LookAhead(0)=='(')
{
lex.get_token(tk);

exprt exp2;
if(!rFunctionArguments(exp2))
return false;

if(lex.get_token(tk2)!=')')
return false;

exp=exprt("explicit-constructor-call");
exp.type().swap(type);
exp.operands().swap(exp2.operands());
set_location(exp, tk);
}
else
return false;
}
else
{
if(!rVarName(exp))
return false;
Expand Down

0 comments on commit c8ef059

Please sign in to comment.