[cfe-commits] r168826 - in /cfe/trunk: include/clang/Sema/DeclSpec.h lib/Parse/ParseDeclCXX.cpp test/Parser/cxx0x-attributes.cpp
Michael Han
Michael.Han at autodesk.com
Wed Nov 28 15:17:40 PST 2012
Author: hanm
Date: Wed Nov 28 17:17:40 2012
New Revision: 168826
URL: http://llvm.org/viewvc/llvm-project?rev=168826&view=rev
Log:
Implement C++11 [dcl.attr.grammar] p4: If an attribute-specifier-seq appertains to a friend declaration, that declaration shall be a definition.
Modified:
cfe/trunk/include/clang/Sema/DeclSpec.h
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/test/Parser/cxx0x-attributes.cpp
Modified: cfe/trunk/include/clang/Sema/DeclSpec.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=168826&r1=168825&r2=168826&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Sema/DeclSpec.h Wed Nov 28 17:17:40 2012
@@ -1897,6 +1897,17 @@
return false;
}
+ /// \brief Return a source range list of C++11 attributes associated
+ /// with the declarator.
+ void getCXX11AttributeRanges(SmallVector<SourceRange, 4> &Ranges) {
+ AttributeList *AttrList = Attrs.getList();
+ while (AttrList) {
+ if (AttrList->isCXX0XAttribute())
+ Ranges.push_back(AttrList->getRange());
+ AttrList = AttrList->getNext();
+ }
+ }
+
void setAsmLabel(Expr *E) { AsmLabel = E; }
Expr *getAsmLabel() const { return AsmLabel; }
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=168826&r1=168825&r2=168826&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Wed Nov 28 17:17:40 2012
@@ -1915,8 +1915,14 @@
ColonProtectionRAIIObject X(*this);
ParsedAttributesWithRange attrs(AttrFactory);
+ ParsedAttributesWithRange FnAttrs(AttrFactory);
// Optional C++0x attribute-specifier
MaybeParseCXX0XAttributes(attrs);
+ // We need to keep these attributes for future diagnostic
+ // before they are taken over by declaration specifier.
+ FnAttrs.addAll(attrs.getList());
+ FnAttrs.Range = attrs.Range;
+
MaybeParseMicrosoftAttributes(attrs);
if (Tok.is(tok::kw_using)) {
@@ -1955,6 +1961,10 @@
if (Tok.is(tok::semi)) {
ConsumeToken();
+
+ if (DS.isFriendSpecified())
+ ProhibitAttributes(FnAttrs);
+
Decl *TheDecl =
Actions.ParsedFreeStandingDeclSpec(getCurScope(), AS, DS, TemplateParams);
DS.complete(TheDecl);
@@ -2023,12 +2033,21 @@
}
}
+ // C++11 [dcl.attr.grammar] p4: If an attribute-specifier-seq appertains
+ // to a friend declaration, that declaration shall be a definition.
+ if (DeclaratorInfo.isFunctionDeclarator() &&
+ DefinitionKind != FDK_Definition && DS.isFriendSpecified()) {
+ // Diagnose attributes that appear before decl specifier:
+ // [[]] friend int foo();
+ ProhibitAttributes(FnAttrs);
+ }
+
if (DefinitionKind) {
if (!DeclaratorInfo.isFunctionDeclarator()) {
Diag(DeclaratorInfo.getIdentifierLoc(), diag::err_func_def_no_params);
ConsumeBrace();
SkipUntil(tok::r_brace, /*StopAtSemi*/false);
-
+
// Consume the optional ';'
if (Tok.is(tok::semi))
ConsumeToken();
@@ -2123,6 +2142,21 @@
Decl *ThisDecl = 0;
if (DS.isFriendSpecified()) {
+ // C++11 [dcl.attr.grammar] p4: If an attribute-specifier-seq appertains
+ // to a friend declaration, that declaration shall be a definition.
+ //
+ // Diagnose attributes appear after friend member function declarator:
+ // foo [[]] ();
+ SmallVector<SourceRange, 4> Ranges;
+ DeclaratorInfo.getCXX11AttributeRanges(Ranges);
+ if (!Ranges.empty()) {
+ for (SmallVector<SourceRange, 4>::iterator I = Ranges.begin(),
+ E = Ranges.end(); I != E; ++I) {
+ Diag((*I).getBegin(), diag::err_attributes_not_allowed)
+ << *I;
+ }
+ }
+
// TODO: handle initializers, bitfields, 'delete'
ThisDecl = Actions.ActOnFriendFunctionDecl(getCurScope(), DeclaratorInfo,
TemplateParams);
Modified: cfe/trunk/test/Parser/cxx0x-attributes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-attributes.cpp?rev=168826&r1=168825&r2=168826&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx0x-attributes.cpp (original)
+++ cfe/trunk/test/Parser/cxx0x-attributes.cpp Wed Nov 28 17:17:40 2012
@@ -151,10 +151,16 @@
struct S {
friend int f [[]] (); // expected-FIXME{{an attribute list cannot appear here}}
- [[]] friend int g(); // expected-FIXME{{an attribute list cannot appear here}}
+ friend int f1 [[noreturn]] (); //expected-error{{an attribute list cannot appear here}}
+ friend int f2 [[]] [[noreturn]] () {}
+ [[]] friend int g(); // expected-error{{an attribute list cannot appear here}}
[[]] friend int h() {
}
+ [[]] friend int f3(), f4(), f5(); // expected-error{{an attribute list cannot appear here}}
+ friend int f6 [[noreturn]] (), f7 [[noreturn]] (), f8 [[noreturn]] (); // expected-error3 {{an attribute list cannot appear here}}
friend class [[]] C; // expected-error{{an attribute list cannot appear here}}
+ [[]] friend class D; // expected-error{{an attribute list cannot appear here}}
+ [[]] friend int; // expected-error{{an attribute list cannot appear here}}
};
template<typename T> void tmpl(T) {}
template void tmpl [[]] (int); // expected-FIXME {{an attribute list cannot appear here}}
More information about the cfe-commits
mailing list