forked from OSchip/llvm-project
Fix grammar for C++11 alignment specifiers, and add a few FIXMEs.
llvm-svn: 142760
This commit is contained in:
parent
e0916cd408
commit
7d33cd3a2f
|
@ -427,6 +427,8 @@ def err_cxx0x_attribute_forbids_arguments : Error<
|
|||
def err_cxx0x_attribute_requires_arguments : Error<
|
||||
"C++11 attribute '%0' must have an argument list">;
|
||||
def err_attributes_not_allowed : Error<"an attribute list cannot appear here">;
|
||||
def err_alignas_pack_exp_unsupported : Error<
|
||||
"pack expansions in alignment specifiers are not supported yet">;
|
||||
|
||||
/// C++ Templates
|
||||
def err_expected_template : Error<"expected template">;
|
||||
|
|
|
@ -1853,7 +1853,8 @@ private:
|
|||
void ParseUnderlyingTypeSpecifier(DeclSpec &DS);
|
||||
void ParseAtomicSpecifier(DeclSpec &DS);
|
||||
|
||||
ExprResult ParseAlignArgument(SourceLocation Start);
|
||||
ExprResult ParseAlignArgument(SourceLocation Start,
|
||||
SourceLocation &EllipsisLoc);
|
||||
void ParseAlignmentSpecifier(ParsedAttributes &Attrs,
|
||||
SourceLocation *endLoc = 0);
|
||||
|
||||
|
|
|
@ -1552,19 +1552,28 @@ Parser::getDeclSpecContextFromDeclaratorContext(unsigned Context) {
|
|||
/// FIXME: Simply returns an alignof() expression if the argument is a
|
||||
/// type. Ideally, the type should be propagated directly into Sema.
|
||||
///
|
||||
/// [C1X/C++0x] type-id
|
||||
/// [C1X] constant-expression
|
||||
/// [C++0x] assignment-expression
|
||||
ExprResult Parser::ParseAlignArgument(SourceLocation Start) {
|
||||
/// [C1X] type-id
|
||||
/// [C1X] constant-expression
|
||||
/// [C++0x] type-id ...[opt]
|
||||
/// [C++0x] assignment-expression ...[opt]
|
||||
ExprResult Parser::ParseAlignArgument(SourceLocation Start,
|
||||
SourceLocation &EllipsisLoc) {
|
||||
ExprResult ER;
|
||||
if (isTypeIdInParens()) {
|
||||
EnterExpressionEvaluationContext Unevaluated(Actions, Sema::Unevaluated);
|
||||
SourceLocation TypeLoc = Tok.getLocation();
|
||||
ParsedType Ty = ParseTypeName().get();
|
||||
SourceRange TypeRange(Start, Tok.getLocation());
|
||||
return Actions.ActOnUnaryExprOrTypeTraitExpr(TypeLoc, UETT_AlignOf, true,
|
||||
Ty.getAsOpaquePtr(), TypeRange);
|
||||
ER = Actions.ActOnUnaryExprOrTypeTraitExpr(TypeLoc, UETT_AlignOf, true,
|
||||
Ty.getAsOpaquePtr(), TypeRange);
|
||||
} else
|
||||
return ParseConstantExpression();
|
||||
ER = ParseConstantExpression();
|
||||
|
||||
if (getLang().CPlusPlus0x && Tok.is(tok::ellipsis)) {
|
||||
EllipsisLoc = Tok.getLocation();
|
||||
ConsumeToken();
|
||||
}
|
||||
|
||||
return ER;
|
||||
}
|
||||
|
||||
/// ParseAlignmentSpecifier - Parse an alignment-specifier, and add the
|
||||
|
@ -1573,8 +1582,8 @@ ExprResult Parser::ParseAlignArgument(SourceLocation Start) {
|
|||
/// alignment-specifier:
|
||||
/// [C1X] '_Alignas' '(' type-id ')'
|
||||
/// [C1X] '_Alignas' '(' constant-expression ')'
|
||||
/// [C++0x] 'alignas' '(' type-id ')'
|
||||
/// [C++0x] 'alignas' '(' assignment-expression ')'
|
||||
/// [C++0x] 'alignas' '(' type-id ...[opt] ')'
|
||||
/// [C++0x] 'alignas' '(' assignment-expression ...[opt] ')'
|
||||
void Parser::ParseAlignmentSpecifier(ParsedAttributes &Attrs,
|
||||
SourceLocation *endLoc) {
|
||||
assert((Tok.is(tok::kw_alignas) || Tok.is(tok::kw__Alignas)) &&
|
||||
|
@ -1587,7 +1596,8 @@ void Parser::ParseAlignmentSpecifier(ParsedAttributes &Attrs,
|
|||
if (T.expectAndConsume(diag::err_expected_lparen))
|
||||
return;
|
||||
|
||||
ExprResult ArgExpr = ParseAlignArgument(T.getOpenLocation());
|
||||
SourceLocation EllipsisLoc;
|
||||
ExprResult ArgExpr = ParseAlignArgument(T.getOpenLocation(), EllipsisLoc);
|
||||
if (ArgExpr.isInvalid()) {
|
||||
SkipUntil(tok::r_paren);
|
||||
return;
|
||||
|
@ -1597,6 +1607,12 @@ void Parser::ParseAlignmentSpecifier(ParsedAttributes &Attrs,
|
|||
if (endLoc)
|
||||
*endLoc = T.getCloseLocation();
|
||||
|
||||
// FIXME: Handle pack-expansions here.
|
||||
if (EllipsisLoc.isValid()) {
|
||||
Diag(EllipsisLoc, diag::err_alignas_pack_exp_unsupported);
|
||||
return;
|
||||
}
|
||||
|
||||
ExprVector ArgExprs(Actions);
|
||||
ArgExprs.push_back(ArgExpr.release());
|
||||
Attrs.addNew(PP.getIdentifierInfo("aligned"), KWLoc, 0, KWLoc,
|
||||
|
|
|
@ -2544,6 +2544,10 @@ static void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
|
|||
}
|
||||
|
||||
void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E) {
|
||||
// FIXME: Handle pack-expansions here.
|
||||
if (DiagnoseUnexpandedParameterPack(E))
|
||||
return;
|
||||
|
||||
if (E->isTypeDependent() || E->isValueDependent()) {
|
||||
// Save dependent expressions in the AST to be instantiated.
|
||||
D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E));
|
||||
|
|
|
@ -160,8 +160,9 @@ struct TestUnexpandedTTP {
|
|||
};
|
||||
|
||||
// Test for unexpanded parameter packs in declarations.
|
||||
// FIXME: Attributes?
|
||||
template<typename T, typename... Types>
|
||||
// FIXME: this should test that the diagnostic reads "type contains..."
|
||||
alignas(Types) // expected-error{{expression contains unexpanded parameter pack 'Types'}}
|
||||
struct TestUnexpandedDecls : T{
|
||||
void member_function(Types); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
|
||||
void member_function () throw(Types); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
|
||||
|
|
|
@ -11,6 +11,10 @@ struct align_member {
|
|||
|
||||
template <unsigned A> alignas(A) struct align_class_template {};
|
||||
|
||||
// FIXME: these should not error
|
||||
template <typename... T> alignas(T...) struct align_class_temp_pack_type {}; // expected-error{{pack expansions in alignment specifiers are not supported yet}}
|
||||
template <unsigned... A> alignas(A...) struct align_class_temp_pack_expr {}; // expected-error{{pack expansions in alignment specifiers are not supported yet}}
|
||||
|
||||
typedef char align_typedef alignas(8);
|
||||
template<typename T> using align_alias_template = align_typedef;
|
||||
|
||||
|
@ -22,4 +26,7 @@ static_assert(sizeof(align_member) == 8, "quuux's size is wrong");
|
|||
static_assert(alignof(align_typedef) == 8, "typedef's alignment is wrong");
|
||||
static_assert(alignof(align_class_template<8>) == 8, "template's alignment is wrong");
|
||||
static_assert(alignof(align_class_template<16>) == 16, "template's alignment is wrong");
|
||||
// FIXME: enable these tests
|
||||
// static_assert(alignof(align_class_temp_pack_type<short, int, long>) == alignof(long), "template's alignment is wrong");
|
||||
// static_assert(alignof(align_class_temp_pack_expr<8, 16, 32>) == 32, "template's alignment is wrong");
|
||||
static_assert(alignof(align_alias_template<int>) == 8, "alias template's alignment is wrong");
|
||||
|
|
Loading…
Reference in New Issue