[cfe-commits] r140796 - in /cfe/trunk: include/clang/Basic/Attr.td include/clang/Basic/DiagnosticParseKinds.td include/clang/Basic/TokenKinds.def include/clang/Parse/Parser.h lib/AST/ASTContext.cpp lib/Headers/CMakeLists.txt lib/Headers/stdalign.h lib/Parse/ParseDecl.cpp lib/Parse/ParseDeclCXX.cpp lib/Parse/ParseTentative.cpp test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp test/Parser/c1x-alignas.c test/Parser/cxx0x-attributes.cpp test/Sema/alignas.c test/Sema/warn-cast-align.c test/SemaCXX/attr-cxx0x.cpp
Peter Collingbourne
peter at pcc.me.uk
Thu Sep 29 11:04:29 PDT 2011
Author: pcc
Date: Thu Sep 29 13:04:28 2011
New Revision: 140796
URL: http://llvm.org/viewvc/llvm-project?rev=140796&view=rev
Log:
Add support for alignment-specifiers in C1X and C++11, remove
support for the C++0x draft [[align]] attribute and add the C1X
standard header file stdalign.h
Added:
cfe/trunk/lib/Headers/stdalign.h
cfe/trunk/test/Parser/c1x-alignas.c
cfe/trunk/test/Sema/alignas.c
Modified:
cfe/trunk/include/clang/Basic/Attr.td
cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
cfe/trunk/include/clang/Basic/TokenKinds.def
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/Headers/CMakeLists.txt
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Parse/ParseTentative.cpp
cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp
cfe/trunk/test/Parser/cxx0x-attributes.cpp
cfe/trunk/test/Sema/warn-cast-align.c
cfe/trunk/test/SemaCXX/attr-cxx0x.cpp
Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=140796&r1=140795&r2=140796&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Thu Sep 29 13:04:28 2011
@@ -114,7 +114,7 @@
}
def Aligned : InheritableAttr {
- let Spellings = ["align", "aligned"];
+ let Spellings = ["aligned"];
let Subjects = [NonBitField, NormalVar, Tag];
let Args = [AlignedArgument<"Alignment">];
let Namespaces = ["", "std"];
Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=140796&r1=140795&r2=140796&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Thu Sep 29 13:04:28 2011
@@ -70,6 +70,9 @@
def note_previous_default_assoc : Note<
"previous default generic association is here">;
+def ext_c1x_alignas : Extension<
+ "_Alignas is a C1X-specific feature">, InGroup<C1X>;
+
def ext_gnu_indirect_goto : Extension<
"use of GNU indirect-goto extension">, InGroup<GNU>;
def ext_gnu_address_of_label : Extension<
Modified: cfe/trunk/include/clang/Basic/TokenKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/TokenKinds.def?rev=140796&r1=140795&r2=140796&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/TokenKinds.def (original)
+++ cfe/trunk/include/clang/Basic/TokenKinds.def Thu Sep 29 13:04:28 2011
@@ -249,6 +249,7 @@
KEYWORD(void , KEYALL)
KEYWORD(volatile , KEYALL)
KEYWORD(while , KEYALL)
+KEYWORD(_Alignas , KEYALL)
KEYWORD(_Bool , KEYNOCXX)
KEYWORD(_Complex , KEYALL)
KEYWORD(_Generic , KEYALL)
@@ -302,6 +303,7 @@
CXX_KEYWORD_OPERATOR(xor_eq , caretequal)
// C++0x keywords
+KEYWORD(alignas , KEYCXX0X)
KEYWORD(alignof , KEYCXX0X)
KEYWORD(char16_t , KEYCXX0X)
KEYWORD(char32_t , KEYCXX0X)
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=140796&r1=140795&r2=140796&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Thu Sep 29 13:04:28 2011
@@ -1775,7 +1775,9 @@
void ParseDecltypeSpecifier(DeclSpec &DS);
void ParseUnderlyingTypeSpecifier(DeclSpec &DS);
- ExprResult ParseCXX0XAlignArgument(SourceLocation Start);
+ ExprResult ParseAlignArgument(SourceLocation Start);
+ void ParseAlignmentSpecifier(ParsedAttributes &Attrs,
+ SourceLocation *endLoc = 0);
VirtSpecifiers::Specifier isCXX0XVirtSpecifier() const;
void ParseOptionalCXX0XVirtSpecifierSeq(VirtSpecifiers &VS);
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=140796&r1=140795&r2=140796&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Thu Sep 29 13:04:28 2011
@@ -705,7 +705,7 @@
// *except* on a struct or struct member, where it only increases
// alignment unless 'packed' is also specified.
//
- // It is an error for [[align]] to decrease alignment, so we can
+ // It is an error for alignas to decrease alignment, so we can
// ignore that possibility; Sema should diagnose it.
if (isa<FieldDecl>(D)) {
UseAlignAttrOnly = D->hasAttr<PackedAttr>() ||
Modified: cfe/trunk/lib/Headers/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/CMakeLists.txt?rev=140796&r1=140795&r2=140796&view=diff
==============================================================================
--- cfe/trunk/lib/Headers/CMakeLists.txt (original)
+++ cfe/trunk/lib/Headers/CMakeLists.txt Thu Sep 29 13:04:28 2011
@@ -12,6 +12,7 @@
nmmintrin.h
pmmintrin.h
smmintrin.h
+ stdalign.h
stdarg.h
stdbool.h
stddef.h
Added: cfe/trunk/lib/Headers/stdalign.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/stdalign.h?rev=140796&view=auto
==============================================================================
--- cfe/trunk/lib/Headers/stdalign.h (added)
+++ cfe/trunk/lib/Headers/stdalign.h Thu Sep 29 13:04:28 2011
@@ -0,0 +1,30 @@
+/*===---- stdalign.h - Standard header for alignment ------------------------===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-----------------------------------------------------------------------===
+ */
+
+#ifndef __STDALIGN_H
+#define __STDALIGN_H
+
+#define alignas _Alignas
+#define __alignas_is_defined 1
+
+#endif /* __STDALIGN_H */
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=140796&r1=140795&r2=140796&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Thu Sep 29 13:04:28 2011
@@ -1314,6 +1314,7 @@
void Parser::ParseSpecifierQualifierList(DeclSpec &DS, AccessSpecifier AS) {
/// specifier-qualifier-list is a subset of declaration-specifiers. Just
/// parse declaration-specifiers and complain about extra stuff.
+ /// TODO: diagnose attribute-specifiers and alignment-specifiers.
ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS);
// Validate declspec for type-name.
@@ -1497,11 +1498,68 @@
return DSC_normal;
}
+/// ParseAlignArgument - Parse the argument to an alignment-specifier.
+///
+/// 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) {
+ 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);
+ } else
+ return ParseConstantExpression();
+}
+
+/// ParseAlignmentSpecifier - Parse an alignment-specifier, and add the
+/// attribute to Attrs.
+///
+/// alignment-specifier:
+/// [C1X] '_Alignas' '(' type-id ')'
+/// [C1X] '_Alignas' '(' constant-expression ')'
+/// [C++0x] 'alignas' '(' type-id ')'
+/// [C++0x] 'alignas' '(' assignment-expression ')'
+void Parser::ParseAlignmentSpecifier(ParsedAttributes &Attrs,
+ SourceLocation *endLoc) {
+ assert((Tok.is(tok::kw_alignas) || Tok.is(tok::kw__Alignas)) &&
+ "Not an alignment-specifier!");
+
+ SourceLocation KWLoc = Tok.getLocation();
+ ConsumeToken();
+
+ SourceLocation ParamLoc = Tok.getLocation();
+ if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen))
+ return;
+
+ ExprResult ArgExpr = ParseAlignArgument(ParamLoc);
+ if (ArgExpr.isInvalid()) {
+ SkipUntil(tok::r_paren);
+ return;
+ }
+
+ SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, ParamLoc);
+ if (endLoc)
+ *endLoc = RParenLoc;
+
+ ExprVector ArgExprs(Actions);
+ ArgExprs.push_back(ArgExpr.release());
+ Attrs.addNew(PP.getIdentifierInfo("aligned"), KWLoc, 0, KWLoc,
+ 0, ParamLoc, ArgExprs.take(), 1, false, true);
+}
+
/// ParseDeclarationSpecifiers
/// declaration-specifiers: [C99 6.7]
/// storage-class-specifier declaration-specifiers[opt]
/// type-specifier declaration-specifiers[opt]
/// [C99] function-specifier declaration-specifiers[opt]
+/// [C1X] alignment-specifier declaration-specifiers[opt]
/// [GNU] attributes declaration-specifiers[opt]
/// [Clang] '__module_private__' declaration-specifiers[opt]
///
@@ -1946,6 +2004,13 @@
isInvalid = DS.SetFunctionSpecExplicit(Loc, PrevSpec, DiagID);
break;
+ // alignment-specifier
+ case tok::kw__Alignas:
+ if (!getLang().C1X)
+ Diag(Tok, diag::ext_c1x_alignas);
+ ParseAlignmentSpecifier(DS.getAttributes());
+ continue;
+
// friend
case tok::kw_friend:
if (DSContext == DSC_class)
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=140796&r1=140795&r2=140796&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Thu Sep 29 13:04:28 2011
@@ -2561,6 +2561,7 @@
///
/// [C++0x] attribute-specifier:
/// '[' '[' attribute-list ']' ']'
+/// alignment-specifier
///
/// [C++0x] attribute-list:
/// attribute[opt]
@@ -2593,6 +2594,11 @@
/// any token but '(', ')', '[', ']', '{', or '}'
void Parser::ParseCXX0XAttributeSpecifier(ParsedAttributes &attrs,
SourceLocation *endLoc) {
+ if (Tok.is(tok::kw_alignas)) {
+ ParseAlignmentSpecifier(attrs, endLoc);
+ return;
+ }
+
assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square)
&& "Not a C++0x attribute list");
@@ -2652,29 +2658,6 @@
break;
}
- // One argument; must be a type-id or assignment-expression
- case AttributeList::AT_aligned: {
- if (Tok.isNot(tok::l_paren)) {
- Diag(Tok.getLocation(), diag::err_cxx0x_attribute_requires_arguments)
- << AttrName->getName();
- break;
- }
- SourceLocation ParamLoc = ConsumeParen();
-
- ExprResult ArgExpr = ParseCXX0XAlignArgument(ParamLoc);
-
- MatchRHSPunctuation(tok::r_paren, ParamLoc);
-
- ExprVector ArgExprs(Actions);
- ArgExprs.push_back(ArgExpr.release());
- attrs.addNew(AttrName, AttrLoc, 0, AttrLoc,
- 0, ParamLoc, ArgExprs.take(), 1,
- false, true);
-
- AttrParsed = true;
- break;
- }
-
// Silence warnings
default: break;
}
@@ -2713,26 +2696,6 @@
attrs.Range = SourceRange(StartLoc, *endLoc);
}
-/// ParseCXX0XAlignArgument - Parse the argument to C++0x's [[align]]
-/// attribute.
-///
-/// FIXME: Simply returns an alignof() expression if the argument is a
-/// type. Ideally, the type should be propagated directly into Sema.
-///
-/// [C++0x] 'align' '(' type-id ')'
-/// [C++0x] 'align' '(' assignment-expression ')'
-ExprResult Parser::ParseCXX0XAlignArgument(SourceLocation Start) {
- 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);
- } else
- return ParseConstantExpression();
-}
-
/// ParseMicrosoftAttributes - Parse a Microsoft attribute [Attr]
///
/// [MS] ms-attribute:
Modified: cfe/trunk/lib/Parse/ParseTentative.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTentative.cpp?rev=140796&r1=140795&r2=140796&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTentative.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTentative.cpp Thu Sep 29 13:04:28 2011
@@ -377,6 +377,7 @@
///
/// [C++0x] attribute-specifier:
/// '[' '[' attribute-list ']' ']'
+/// alignment-specifier
///
/// [C++0x] attribute-list:
/// attribute[opt]
@@ -409,6 +410,9 @@
/// any token but '(', ')', '[', ']', '{', or '}'
bool Parser::isCXX0XAttributeSpecifier (bool CheckClosing,
tok::TokenKind *After) {
+ if (Tok.is(tok::kw_alignas))
+ return true;
+
if (Tok.isNot(tok::l_square) || NextToken().isNot(tok::l_square))
return false;
Modified: cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp?rev=140796&r1=140795&r2=140796&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp (original)
+++ cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/p3-0x.cpp Thu Sep 29 13:04:28 2011
@@ -33,8 +33,7 @@
void g() throw (struct Ex {}) { // expected-error {{'Ex' can not be defined in a type specifier}}
}
-// FIXME: this currently gives a strange error because alignas is not recognised as a keyword yet.
-int alignas(struct Aa {}) x; // expected-error {{'Aa' can not be defined in a parameter type}} expected-error {{expected function body}}
+int alignas(struct Aa {}) x; // expected-error {{'Aa' can not be defined in a type specifier}}
int a = sizeof(struct So {}); // expected-error {{'So' can not be defined in a type specifier}}
int b = alignof(struct Ao {}); // expected-error {{'Ao' can not be defined in a type specifier}}
Added: cfe/trunk/test/Parser/c1x-alignas.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/c1x-alignas.c?rev=140796&view=auto
==============================================================================
--- cfe/trunk/test/Parser/c1x-alignas.c (added)
+++ cfe/trunk/test/Parser/c1x-alignas.c Thu Sep 29 13:04:28 2011
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -std=c1x -fsyntax-only -verify %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}}
Modified: cfe/trunk/test/Parser/cxx0x-attributes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-attributes.cpp?rev=140796&r1=140795&r2=140796&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx0x-attributes.cpp (original)
+++ cfe/trunk/test/Parser/cxx0x-attributes.cpp Thu Sep 29 13:04:28 2011
@@ -6,7 +6,7 @@
int after_attr [[]];
int * [[]] ptr_attr;
int array_attr [1] [[]];
-[[align(8)]] int aligned_attr;
+alignas(8) int aligned_attr;
[[test::valid(for 42 [very] **** '+' symbols went on a trip; the end.)]]
int garbage_attr;
void fn_attr () [[]];
@@ -32,8 +32,8 @@
[[]] using namespace ns;
// Argument tests
-[[align]] int aligned_no_params; // expected-error {{C++0x attribute 'align' must have an argument list}}
-[[align(i)]] int aligned_nonconst; // expected-error {{'aligned' attribute requires integer constant}}
+alignas int aligned_no_params; // expected-error {{expected '('}}
+alignas(i) int aligned_nonconst; // expected-error {{'aligned' attribute requires integer constant}}
// Statement tests
void foo () {
Added: cfe/trunk/test/Sema/alignas.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/alignas.c?rev=140796&view=auto
==============================================================================
--- cfe/trunk/test/Sema/alignas.c (added)
+++ cfe/trunk/test/Sema/alignas.c Thu Sep 29 13:04:28 2011
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c1x %s
+
+_Alignas(3) int align_illegal; //expected-error {{requested alignment is not a power of 2}}
+_Alignas(int) char align_big;
+_Alignas(1) int align_small; // FIXME: this should be rejected
+_Alignas(1) unsigned _Alignas(8) int _Alignas(1) align_multiple;
+
+struct align_member {
+ _Alignas(8) int 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(sizeof(struct align_member) == 8, "quuux's size is wrong");
+_Static_assert(__alignof(align_typedef) == 8, "typedef's alignment is wrong");
Modified: cfe/trunk/test/Sema/warn-cast-align.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/warn-cast-align.c?rev=140796&r1=140795&r2=140796&view=diff
==============================================================================
--- cfe/trunk/test/Sema/warn-cast-align.c (original)
+++ cfe/trunk/test/Sema/warn-cast-align.c Thu Sep 29 13:04:28 2011
@@ -28,7 +28,7 @@
}
// Aligned struct.
-__attribute__((align(16))) struct A {
+__attribute__((aligned(16))) struct A {
char buffer[16];
};
void test2(char *P) {
Modified: cfe/trunk/test/SemaCXX/attr-cxx0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-cxx0x.cpp?rev=140796&r1=140795&r2=140796&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/attr-cxx0x.cpp (original)
+++ cfe/trunk/test/SemaCXX/attr-cxx0x.cpp Thu Sep 29 13:04:28 2011
@@ -1,15 +1,15 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
-int align_illegal [[align(3)]]; //expected-error {{requested alignment is not a power of 2}}
-char align_big [[align(int)]];
-int align_small [[align(1)]]; // FIXME: this should be rejected
-int align_multiple [[align(1), align(8), align(1)]];
+int align_illegal alignas(3); //expected-error {{requested alignment is not a power of 2}}
+char align_big alignas(int);
+int align_small alignas(1); // FIXME: this should be rejected
+int align_multiple alignas(1) alignas(8) alignas(1);
struct align_member {
- int member [[align(8)]];
+ int member alignas(8);
};
-typedef char align_typedef [[align(8)]];
+typedef char align_typedef alignas(8);
template<typename T> using align_alias_template = align_typedef;
static_assert(alignof(align_big) == alignof(int), "k's alignment is wrong");
More information about the cfe-commits
mailing list