mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 13:10:12 +03:00
ImportC: allow _Alignof expression
(#21181)
Resolves https://github.com/dlang/dmd/issues/20434 Allowing this gnu/clang extension actually removes lines of code as we can unify the parsing and semantics of `_Alignof` and `sizeof` and have the normal D machinery handle the difference later.
This commit is contained in:
parent
93b0317cc3
commit
a0bf0f368a
5 changed files with 9 additions and 71 deletions
|
@ -982,6 +982,7 @@ final class CParser(AST) : Parser!AST
|
|||
* sizeof unary-expression
|
||||
* sizeof ( type-name )
|
||||
* _Alignof ( type-name )
|
||||
* _Alignof unary-expression // gcc extension
|
||||
*
|
||||
* unary-operator:
|
||||
* & * + - ~ !
|
||||
|
@ -1044,8 +1045,10 @@ final class CParser(AST) : Parser!AST
|
|||
e = new AST.ComExp(loc, e);
|
||||
break;
|
||||
|
||||
case TOK._Alignof:
|
||||
case TOK.sizeof_:
|
||||
{
|
||||
Identifier id = token.value == TOK.sizeof_? Id.__sizeof : Id.__xalignof;
|
||||
nextToken();
|
||||
if (token.value == TOK.leftParenthesis)
|
||||
{
|
||||
|
@ -1084,7 +1087,7 @@ final class CParser(AST) : Parser!AST
|
|||
e = cparseUnaryExp();
|
||||
}
|
||||
|
||||
e = new AST.DotIdExp(loc, e, Id.__sizeof);
|
||||
e = new AST.DotIdExp(loc, e, id);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1096,17 +1099,6 @@ final class CParser(AST) : Parser!AST
|
|||
e = cparseCastExp();
|
||||
break;
|
||||
|
||||
case TOK._Alignof:
|
||||
{
|
||||
nextToken();
|
||||
check(TOK.leftParenthesis);
|
||||
auto t = cparseTypeName();
|
||||
check(TOK.rightParenthesis);
|
||||
e = new AST.TypeExp(loc, t);
|
||||
e = new AST.DotIdExp(loc, e, Id.__xalignof);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
e = cparsePostfixExp(e);
|
||||
break;
|
||||
|
@ -5025,6 +5017,7 @@ final class CParser(AST) : Parser!AST
|
|||
return false;
|
||||
break;
|
||||
|
||||
case TOK._Alignof:
|
||||
case TOK.sizeof_:
|
||||
t = peek(t);
|
||||
if (t.value == TOK.leftParenthesis)
|
||||
|
@ -5042,15 +5035,6 @@ final class CParser(AST) : Parser!AST
|
|||
return false;
|
||||
break;
|
||||
|
||||
case TOK._Alignof:
|
||||
t = peek(t);
|
||||
if (t.value != TOK.leftParenthesis)
|
||||
return false;
|
||||
t = peek(t);
|
||||
if (!isTypeName(t) || t.value != TOK.rightParenthesis)
|
||||
return false;
|
||||
break;
|
||||
|
||||
default:
|
||||
// Compound literals are handled by cast and sizeof expressions,
|
||||
// so be content with just seeing a primary expression.
|
||||
|
|
|
@ -8191,37 +8191,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
|||
if (exp.arrow) // ImportC only
|
||||
exp.e1 = exp.e1.expressionSemantic(sc).arrayFuncConv(sc);
|
||||
|
||||
if (exp.ident == Id.__xalignof && exp.e1.isTypeExp())
|
||||
{
|
||||
// C11 6.5.3 says _Alignof only applies to types
|
||||
Expression e;
|
||||
Type t;
|
||||
Dsymbol s;
|
||||
dmd.typesem.resolve(exp.e1.type, exp.e1.loc, sc, e, t, s, true);
|
||||
if (e)
|
||||
{
|
||||
error(exp.e1.loc, "argument to `_Alignof` must be a type");
|
||||
return setError();
|
||||
}
|
||||
else if (t)
|
||||
{
|
||||
// Note similarity to getProperty() implementation of __xalignof
|
||||
const explicitAlignment = t.alignment();
|
||||
const naturalAlignment = t.alignsize();
|
||||
const actualAlignment = (explicitAlignment.isDefault() ? naturalAlignment : explicitAlignment.get());
|
||||
result = new IntegerExp(exp.loc, actualAlignment, Type.tsize_t);
|
||||
}
|
||||
else if (s)
|
||||
{
|
||||
error(exp.e1.loc, "argument to `_Alignof` must be a type");
|
||||
return setError();
|
||||
}
|
||||
else
|
||||
assert(0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (exp.ident != Id.__sizeof)
|
||||
if (exp.ident != Id.__sizeof && exp.ident != Id.__xalignof)
|
||||
{
|
||||
result = fieldLookup(exp.e1, sc, exp.ident, exp.arrow);
|
||||
return;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue