forked from OSchip/llvm-project
Add support for the C11 _Alignof keyword.
This behaves like the existing GNU __alignof and C++11 alignof keywords; most of the patch is simply adding the third token spelling to various places. llvm-svn: 159494
This commit is contained in:
parent
2b3c860397
commit
58d547200e
|
@ -92,8 +92,8 @@ def err_duplicate_default_assoc : Error<
|
|||
def note_previous_default_assoc : Note<
|
||||
"previous default generic association is here">;
|
||||
|
||||
def ext_c11_alignas : Extension<
|
||||
"_Alignas is a C11-specific feature">, InGroup<C11>;
|
||||
def ext_c11_alignment : Extension<
|
||||
"%0 is a C11-specific feature">, InGroup<C11>;
|
||||
|
||||
def ext_gnu_indirect_goto : Extension<
|
||||
"use of GNU indirect-goto extension">, InGroup<GNU>;
|
||||
|
|
|
@ -251,6 +251,7 @@ KEYWORD(void , KEYALL)
|
|||
KEYWORD(volatile , KEYALL)
|
||||
KEYWORD(while , KEYALL)
|
||||
KEYWORD(_Alignas , KEYALL)
|
||||
KEYWORD(_Alignof , KEYALL)
|
||||
KEYWORD(_Atomic , KEYALL)
|
||||
KEYWORD(_Bool , KEYNOCXX)
|
||||
KEYWORD(_Complex , KEYALL)
|
||||
|
|
|
@ -463,7 +463,7 @@ void StmtDumper::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node) {
|
|||
OS << " sizeof ";
|
||||
break;
|
||||
case UETT_AlignOf:
|
||||
OS << " __alignof ";
|
||||
OS << " alignof ";
|
||||
break;
|
||||
case UETT_VecStep:
|
||||
OS << " vec_step ";
|
||||
|
|
|
@ -814,7 +814,12 @@ void StmtPrinter::VisitUnaryExprOrTypeTraitExpr(UnaryExprOrTypeTraitExpr *Node){
|
|||
OS << "sizeof";
|
||||
break;
|
||||
case UETT_AlignOf:
|
||||
OS << "__alignof";
|
||||
if (Policy.LangOpts.CPlusPlus)
|
||||
OS << "alignof";
|
||||
else if (Policy.LangOpts.C11)
|
||||
OS << "_Alignof";
|
||||
else
|
||||
OS << "__alignof";
|
||||
break;
|
||||
case UETT_VecStep:
|
||||
OS << "vec_step";
|
||||
|
|
|
@ -2478,7 +2478,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
|
|||
// alignment-specifier
|
||||
case tok::kw__Alignas:
|
||||
if (!getLangOpts().C11)
|
||||
Diag(Tok, diag::ext_c11_alignas);
|
||||
Diag(Tok, diag::ext_c11_alignment) << Tok.getName();
|
||||
ParseAlignmentSpecifier(DS.getAttributes());
|
||||
continue;
|
||||
|
||||
|
|
|
@ -507,6 +507,7 @@ class CastExpressionIdValidator : public CorrectionCandidateCallback {
|
|||
/// [C++11] 'sizeof' '...' '(' identifier ')'
|
||||
/// [GNU] '__alignof' unary-expression
|
||||
/// [GNU] '__alignof' '(' type-name ')'
|
||||
/// [C11] '_Alignof' '(' type-name ')'
|
||||
/// [C++11] 'alignof' '(' type-id ')'
|
||||
/// [GNU] '&&' identifier
|
||||
/// [C++11] 'noexcept' '(' expression ')' [C++11 5.3.7]
|
||||
|
@ -921,12 +922,15 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
|
|||
Res = Actions.ActOnUnaryOp(getCurScope(), SavedLoc, SavedKind, Res.get());
|
||||
return move(Res);
|
||||
}
|
||||
case tok::kw_sizeof: // unary-expression: 'sizeof' unary-expression
|
||||
// unary-expression: 'sizeof' '(' type-name ')'
|
||||
case tok::kw_alignof:
|
||||
case tok::kw__Alignof: // unary-expression: '_Alignof' '(' type-name ')'
|
||||
if (!getLangOpts().C11)
|
||||
Diag(Tok, diag::ext_c11_alignment) << Tok.getName();
|
||||
// fallthrough
|
||||
case tok::kw_alignof: // unary-expression: 'alignof' '(' type-id ')'
|
||||
case tok::kw___alignof: // unary-expression: '__alignof' unary-expression
|
||||
// unary-expression: '__alignof' '(' type-name ')'
|
||||
// unary-expression: 'alignof' '(' type-id ')'
|
||||
case tok::kw_sizeof: // unary-expression: 'sizeof' unary-expression
|
||||
// unary-expression: 'sizeof' '(' type-name ')'
|
||||
case tok::kw_vec_step: // unary-expression: OpenCL 'vec_step' expression
|
||||
return ParseUnaryExprOrTypeTraitExpression();
|
||||
case tok::ampamp: { // unary-expression: '&&' identifier
|
||||
|
@ -1514,6 +1518,7 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) {
|
|||
/// 'sizeof' '(' type-name ')'
|
||||
/// [GNU] '__alignof' unary-expression
|
||||
/// [GNU] '__alignof' '(' type-name ')'
|
||||
/// [C11] '_Alignof' '(' type-name ')'
|
||||
/// [C++0x] 'alignof' '(' type-id ')'
|
||||
///
|
||||
/// [GNU] typeof-specifier:
|
||||
|
@ -1533,7 +1538,7 @@ Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok,
|
|||
|
||||
assert((OpTok.is(tok::kw_typeof) || OpTok.is(tok::kw_sizeof) ||
|
||||
OpTok.is(tok::kw___alignof) || OpTok.is(tok::kw_alignof) ||
|
||||
OpTok.is(tok::kw_vec_step)) &&
|
||||
OpTok.is(tok::kw__Alignof) || OpTok.is(tok::kw_vec_step)) &&
|
||||
"Not a typeof/sizeof/alignof/vec_step expression!");
|
||||
|
||||
ExprResult Operand;
|
||||
|
@ -1591,11 +1596,13 @@ Parser::ParseExprAfterUnaryExprOrTypeTrait(const Token &OpTok,
|
|||
/// [C++0x] 'sizeof' '...' '(' identifier ')'
|
||||
/// [GNU] '__alignof' unary-expression
|
||||
/// [GNU] '__alignof' '(' type-name ')'
|
||||
/// [C11] '_Alignof' '(' type-name ')'
|
||||
/// [C++0x] 'alignof' '(' type-id ')'
|
||||
/// \endverbatim
|
||||
ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() {
|
||||
assert((Tok.is(tok::kw_sizeof) || Tok.is(tok::kw___alignof)
|
||||
|| Tok.is(tok::kw_alignof) || Tok.is(tok::kw_vec_step)) &&
|
||||
assert((Tok.is(tok::kw_sizeof) || Tok.is(tok::kw___alignof) ||
|
||||
Tok.is(tok::kw_alignof) || Tok.is(tok::kw__Alignof) ||
|
||||
Tok.is(tok::kw_vec_step)) &&
|
||||
"Not a sizeof/alignof/vec_step expression!");
|
||||
Token OpTok = Tok;
|
||||
ConsumeToken();
|
||||
|
@ -1643,7 +1650,7 @@ ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() {
|
|||
RParenLoc);
|
||||
}
|
||||
|
||||
if (OpTok.is(tok::kw_alignof))
|
||||
if (OpTok.is(tok::kw_alignof) || OpTok.is(tok::kw__Alignof))
|
||||
Diag(OpTok, diag::warn_cxx98_compat_alignof);
|
||||
|
||||
EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated);
|
||||
|
@ -1657,7 +1664,8 @@ ExprResult Parser::ParseUnaryExprOrTypeTraitExpression() {
|
|||
CastRange);
|
||||
|
||||
UnaryExprOrTypeTrait ExprKind = UETT_SizeOf;
|
||||
if (OpTok.is(tok::kw_alignof) || OpTok.is(tok::kw___alignof))
|
||||
if (OpTok.is(tok::kw_alignof) || OpTok.is(tok::kw___alignof) ||
|
||||
OpTok.is(tok::kw__Alignof))
|
||||
ExprKind = UETT_AlignOf;
|
||||
else if (OpTok.is(tok::kw_vec_step))
|
||||
ExprKind = UETT_VecStep;
|
||||
|
|
|
@ -735,6 +735,7 @@ Parser::isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind) {
|
|||
case tok::kw_alignof:
|
||||
case tok::kw_noexcept:
|
||||
case tok::kw_nullptr:
|
||||
case tok::kw__Alignof:
|
||||
case tok::kw___null:
|
||||
case tok::kw___alignof:
|
||||
case tok::kw___builtin_choose_expr:
|
||||
|
|
|
@ -1955,6 +1955,19 @@ static void AddOrdinaryNameResults(Sema::ParserCompletionContext CCC,
|
|||
AddObjCExpressionResults(Results, true);
|
||||
}
|
||||
|
||||
if (SemaRef.getLangOpts().C11) {
|
||||
// _Alignof
|
||||
Builder.AddResultTypeChunk("size_t");
|
||||
if (SemaRef.getASTContext().Idents.get("alignof").hasMacroDefinition())
|
||||
Builder.AddTypedTextChunk("alignof");
|
||||
else
|
||||
Builder.AddTypedTextChunk("_Alignof");
|
||||
Builder.AddChunk(CodeCompletionString::CK_LeftParen);
|
||||
Builder.AddPlaceholderChunk("type");
|
||||
Builder.AddChunk(CodeCompletionString::CK_RightParen);
|
||||
Results.AddResult(Result(Builder.TakeString()));
|
||||
}
|
||||
|
||||
// sizeof expression
|
||||
Builder.AddResultTypeChunk("size_t");
|
||||
Builder.AddTypedTextChunk("sizeof");
|
||||
|
|
|
@ -3604,6 +3604,12 @@ static void AddKeywordsToConsumer(Sema &SemaRef,
|
|||
Consumer.addKeywordResult("nullptr");
|
||||
}
|
||||
}
|
||||
|
||||
if (SemaRef.getLangOpts().C11) {
|
||||
// FIXME: We should not suggest _Alignof if the alignof macro
|
||||
// is present.
|
||||
Consumer.addKeywordResult("_Alignof");
|
||||
}
|
||||
}
|
||||
|
||||
if (CCC.WantRemainingKeywords) {
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
// RUN: %clang_cc1 -std=c1x -fsyntax-only -verify %s
|
||||
// RUN: %clang_cc1 -std=c11 -fsyntax-only -verify %s
|
||||
// RUN: not %clang_cc1 -pedantic -fsyntax-only %s 2>&1 | FileCheck -check-prefix=CHECK-EXT %s
|
||||
|
||||
_Alignas(4) char c1;
|
||||
unsigned _Alignas(long) char c2;
|
||||
char _Alignas(16) c3;
|
||||
|
||||
char c4 _Alignas(32); // expected-error {{expected ';' after top level declarator}}
|
||||
|
||||
char _Alignas(_Alignof(int)) c5;
|
||||
|
||||
// CHECK-EXT: _Alignas is a C11-specific feature
|
||||
// CHECK-EXT: _Alignof is a C11-specific feature
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify -std=c1x %s
|
||||
// RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -Dalignof=__alignof %s
|
||||
// RUN: %clang_cc1 -fsyntax-only -verify -std=c11 -Dalignof=_Alignof %s
|
||||
|
||||
_Alignas(3) int align_illegal; //expected-error {{requested alignment is not a power of 2}}
|
||||
_Alignas(int) char align_big;
|
||||
|
@ -11,9 +12,9 @@ struct align_member {
|
|||
|
||||
typedef _Alignas(8) char align_typedef; // FIXME: this should be rejected
|
||||
|
||||
_Static_assert(__alignof(align_big) == __alignof(int), "k's alignment is wrong");
|
||||
_Static_assert(__alignof(align_small) == 1, "j's alignment is wrong");
|
||||
_Static_assert(__alignof(align_multiple) == 8, "l's alignment is wrong");
|
||||
_Static_assert(__alignof(struct align_member) == 8, "quuux's alignment is wrong");
|
||||
_Static_assert(alignof(align_big) == alignof(int), "k's alignment is wrong");
|
||||
_Static_assert(alignof(align_small) == 1, "j's alignment is wrong");
|
||||
_Static_assert(alignof(align_multiple) == 8, "l's alignment is wrong");
|
||||
_Static_assert(alignof(struct align_member) == 8, "quuux's alignment is wrong");
|
||||
_Static_assert(sizeof(struct align_member) == 8, "quuux's size is wrong");
|
||||
_Static_assert(__alignof(align_typedef) == 8, "typedef's alignment is wrong");
|
||||
_Static_assert(alignof(align_typedef) == 8, "typedef's alignment is wrong");
|
||||
|
|
Loading…
Reference in New Issue