aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/Attr.h18
-rw-r--r--include/clang/Basic/DiagnosticParseKinds.td6
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td16
-rw-r--r--include/clang/Parse/AttributeList.h32
-rw-r--r--include/clang/Parse/Parser.h57
-rw-r--r--lib/AST/ASTContext.cpp5
-rw-r--r--lib/AST/RecordLayoutBuilder.cpp14
-rw-r--r--lib/CodeGen/CodeGenModule.cpp8
-rw-r--r--lib/Frontend/PCHReaderDecl.cpp1
-rw-r--r--lib/Frontend/PCHWriter.cpp1
-rw-r--r--lib/Parse/AttributeList.cpp11
-rw-r--r--lib/Parse/ParseDecl.cpp126
-rw-r--r--lib/Parse/ParseDeclCXX.cpp259
-rw-r--r--lib/Parse/ParseExpr.cpp8
-rw-r--r--lib/Parse/ParseExprCXX.cpp2
-rw-r--r--lib/Parse/ParseObjc.cpp8
-rw-r--r--lib/Parse/ParseStmt.cpp113
-rw-r--r--lib/Parse/ParseTemplate.cpp4
-rw-r--r--lib/Parse/ParseTentative.cpp88
-rw-r--r--lib/Parse/Parser.cpp27
-rw-r--r--lib/Sema/Sema.h5
-rw-r--r--lib/Sema/SemaDecl.cpp4
-rw-r--r--lib/Sema/SemaDeclAttr.cpp48
-rw-r--r--lib/Sema/SemaDeclCXX.cpp20
-rw-r--r--test/Parser/cxx0x-attributes.cpp61
-rw-r--r--test/SemaCXX/attr-cxx0x.cpp24
26 files changed, 802 insertions, 164 deletions
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h
index b36ff12293..35f9b330dd 100644
--- a/include/clang/AST/Attr.h
+++ b/include/clang/AST/Attr.h
@@ -59,6 +59,7 @@ public:
Deprecated,
Destructor,
FastCall,
+ Final,
Format,
FormatArg,
GNUInline,
@@ -184,12 +185,24 @@ public:
class AlignedAttr : public Attr {
unsigned Alignment;
public:
- AlignedAttr(unsigned alignment) : Attr(Aligned), Alignment(alignment) {}
+ AlignedAttr(unsigned alignment)
+ : Attr(Aligned), Alignment(alignment) {}
/// getAlignment - The specified alignment in bits.
unsigned getAlignment() const { return Alignment; }
+
+ /// getMaxAlignment - Get the maximum alignment of attributes on this list.
+ unsigned getMaxAlignment() const {
+ const AlignedAttr *Next = getNext<AlignedAttr>();
+ if (Next)
+ return std::max(Next->getMaxAlignment(), Alignment);
+ else
+ return Alignment;
+ }
- virtual Attr* clone(ASTContext &C) const { return ::new (C) AlignedAttr(Alignment); }
+ virtual Attr* clone(ASTContext &C) const {
+ return ::new (C) AlignedAttr(Alignment);
+ }
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) {
@@ -304,6 +317,7 @@ DEF_SIMPLE_ATTR(Malloc);
DEF_SIMPLE_ATTR(NoReturn);
DEF_SIMPLE_ATTR(AnalyzerNoReturn);
DEF_SIMPLE_ATTR(Deprecated);
+DEF_SIMPLE_ATTR(Final);
class SectionAttr : public Attr {
std::string Name;
diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td
index 3a8c5bf8f1..890c639431 100644
--- a/include/clang/Basic/DiagnosticParseKinds.td
+++ b/include/clang/Basic/DiagnosticParseKinds.td
@@ -75,6 +75,7 @@ def err_expected_ident_lbrace : Error<"expected identifier or '{'">;
def err_expected_lbrace : Error<"expected '{'">;
def err_expected_lparen : Error<"expected '('">;
def err_expected_rparen : Error<"expected ')'">;
+def err_expected_lsquare : Error<"expected '['">;
def err_expected_rsquare : Error<"expected ']'">;
def err_expected_rbrace : Error<"expected '}'">;
def err_expected_greater : Error<"expected '>'">;
@@ -245,6 +246,11 @@ def err_operator_missing_type_specifier : Error<
def err_anon_type_definition : Error<
"declaration of anonymous %0 must be a definition">;
+def err_cxx0x_attribute_forbids_arguments : Error<
+ "C++0x attribute '%0' cannot have an argument list">;
+def err_cxx0x_attribute_requires_arguments : Error<
+ "C++0x attribute '%0' must have an argument list">;
+def err_attributes_not_allowed : Error<"an attribute list cannot appear here">;
/// C++ Templates
def err_expected_template : Error<"expected template">;
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index a864d8ab9e..7ca011986b 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -551,6 +551,12 @@ def err_auto_not_allowed : Error<
"|class member|exception declaration|template parameter|block literal}0">;
def err_auto_var_requires_init : Error<
"declaration of variable %0 with type %1 requires an initializer">;
+
+// C++0x [[final]]
+def err_final_function_overridden : Error<
+ "declaration of %0 overrides a 'final' function">;
+def err_final_base : Error<
+ "derivation from 'final' %0">;
// Objective-C++
def err_objc_decls_may_only_appear_in_global_scope : Error<
@@ -638,8 +644,14 @@ def warn_attribute_weak_import_invalid_on_definition : Warning<
"'weak_import' attribute cannot be specified on a definition">;
def warn_attribute_wrong_decl_type : Warning<
"%0 attribute only applies to %select{function|union|"
- "variable and function|function or method|parameter|parameter or Objective-C method |"
- "function, method or block}1 types">;
+ "variable and function|function or method|parameter|"
+ "parameter or Objective-C method |function, method or block|"
+ "virtual method or class|function, method, or parameter}1 types">;
+def err_attribute_wrong_decl_type : Error<
+ "%0 attribute only applies to %select{function|union|"
+ "variable and function|function or method|parameter|"
+ "parameter or Objective-C method |function, method or block|"
+ "virtual method or class|function, method, or parameter}1 types">;
def warn_gnu_inline_attribute_requires_inline : Warning<
"'gnu_inline' attribute requires function to be marked 'inline',"
" attribute ignored">;
diff --git a/include/clang/Parse/AttributeList.h b/include/clang/Parse/AttributeList.h
index 81bb3007ba..e273cadff1 100644
--- a/include/clang/Parse/AttributeList.h
+++ b/include/clang/Parse/AttributeList.h
@@ -33,19 +33,22 @@ namespace clang {
class AttributeList {
IdentifierInfo *AttrName;
SourceLocation AttrLoc;
+ IdentifierInfo *ScopeName;
+ SourceLocation ScopeLoc;
IdentifierInfo *ParmName;
SourceLocation ParmLoc;
ActionBase::ExprTy **Args;
unsigned NumArgs;
AttributeList *Next;
- bool DeclspecAttribute;
+ bool DeclspecAttribute, CXX0XAttribute;
AttributeList(const AttributeList &); // DO NOT IMPLEMENT
void operator=(const AttributeList &); // DO NOT IMPLEMENT
public:
AttributeList(IdentifierInfo *AttrName, SourceLocation AttrLoc,
+ IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
IdentifierInfo *ParmName, SourceLocation ParmLoc,
ActionBase::ExprTy **args, unsigned numargs,
- AttributeList *Next, bool declspec = false);
+ AttributeList *Next, bool declspec = false, bool cxx0x = false);
~AttributeList();
enum Kind { // Please keep this list alphabetized.
@@ -57,6 +60,7 @@ public:
AT_analyzer_noreturn,
AT_annotate,
AT_blocks,
+ AT_carries_dependency,
AT_cdecl,
AT_cleanup,
AT_const,
@@ -67,6 +71,7 @@ public:
AT_dllimport,
AT_ext_vector_type,
AT_fastcall,
+ AT_final,
AT_format,
AT_format_arg,
AT_gnu_inline,
@@ -106,8 +111,15 @@ public:
IdentifierInfo *getName() const { return AttrName; }
SourceLocation getLoc() const { return AttrLoc; }
+
+ bool hasScope() const { return ScopeName; }
+ IdentifierInfo *getScopeName() const { return ScopeName; }
+ SourceLocation getScopeLoc() const { return ScopeLoc; }
+
IdentifierInfo *getParameterName() const { return ParmName; }
+
bool isDeclspecAttribute() const { return DeclspecAttribute; }
+ bool isCXX0XAttribute() const { return CXX0XAttribute; }
Kind getKind() const { return getKind(getName()); }
static Kind getKind(const IdentifierInfo *Name);
@@ -181,6 +193,22 @@ inline AttributeList* addAttributeLists (AttributeList *Left,
return Left;
}
+/// CXX0XAttributeList - A wrapper around a C++0x attribute list.
+/// Stores, in addition to the list proper, whether or not an actual list was
+/// (as opposed to an empty list, which may be ill-formed in some places) and
+/// the source range of the list.
+struct CXX0XAttributeList {
+ AttributeList *AttrList;
+ SourceRange Range;
+ bool HasAttr;
+ CXX0XAttributeList (AttributeList *attrList, SourceRange range, bool hasAttr)
+ : AttrList(attrList), Range(range), HasAttr (hasAttr) {
+ }
+ CXX0XAttributeList ()
+ : AttrList(0), Range(), HasAttr(false) {
+ }
+};
+
} // end namespace clang
#endif
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 814064a79e..b1375d7d65 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -24,6 +24,7 @@
namespace clang {
class AttributeList;
+ struct CXX0XAttributeList;
class PragmaHandler;
class Scope;
class DiagnosticBuilder;
@@ -753,10 +754,10 @@ private:
//===--------------------------------------------------------------------===//
// C99 6.9: External Definitions.
- DeclGroupPtrTy ParseExternalDeclaration();
+ DeclGroupPtrTy ParseExternalDeclaration(CXX0XAttributeList Attr);
bool isDeclarationAfterDeclarator();
bool isStartOfFunctionDefinition();
- DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(
+ DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(AttributeList *Attr,
AccessSpecifier AS = AS_none);
DeclPtrTy ParseFunctionDefinition(ParsingDeclarator &D,
@@ -994,24 +995,25 @@ private:
return ParseStatementOrDeclaration(true);
}
OwningStmtResult ParseStatementOrDeclaration(bool OnlyStatement = false);
- OwningStmtResult ParseLabeledStatement();
- OwningStmtResult ParseCaseStatement();
- OwningStmtResult ParseDefaultStatement();
- OwningStmtResult ParseCompoundStatement(bool isStmtExpr = false);
+ OwningStmtResult ParseLabeledStatement(AttributeList *Attr);
+ OwningStmtResult ParseCaseStatement(AttributeList *Attr);
+ OwningStmtResult ParseDefaultStatement(AttributeList *Attr);
+ OwningStmtResult ParseCompoundStatement(AttributeList *Attr,
+ bool isStmtExpr = false);
OwningStmtResult ParseCompoundStatementBody(bool isStmtExpr = false);
bool ParseParenExprOrCondition(OwningExprResult &CondExp,
bool OnlyAllowCondition = false,
SourceLocation *LParenLoc = 0,
SourceLocation *RParenLoc = 0);
- OwningStmtResult ParseIfStatement();
- OwningStmtResult ParseSwitchStatement();
- OwningStmtResult ParseWhileStatement();
- OwningStmtResult ParseDoStatement();
- OwningStmtResult ParseForStatement();
- OwningStmtResult ParseGotoStatement();
- OwningStmtResult ParseContinueStatement();
- OwningStmtResult ParseBreakStatement();
- OwningStmtResult ParseReturnStatement();
+ OwningStmtResult ParseIfStatement(AttributeList *Attr);
+ OwningStmtResult ParseSwitchStatement(AttributeList *Attr);
+ OwningStmtResult ParseWhileStatement(AttributeList *Attr);
+ OwningStmtResult ParseDoStatement(AttributeList *Attr);
+ OwningStmtResult ParseForStatement(AttributeList *Attr);
+ OwningStmtResult ParseGotoStatement(AttributeList *Attr);
+ OwningStmtResult ParseContinueStatement(AttributeList *Attr);
+ OwningStmtResult ParseBreakStatement(AttributeList *Attr);
+ OwningStmtResult ParseReturnStatement(AttributeList *Attr);
OwningStmtResult ParseAsmStatement(bool &msAsm);
OwningStmtResult FuzzyParseMicrosoftAsmStatement();
bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<std::string> &Names,
@@ -1021,7 +1023,7 @@ private:
//===--------------------------------------------------------------------===//
// C++ 6: Statements and Blocks
- OwningStmtResult ParseCXXTryBlock();
+ OwningStmtResult ParseCXXTryBlock(AttributeList *Attr);
OwningStmtResult ParseCXXTryBlockCommon(SourceLocation TryLoc);
OwningStmtResult ParseCXXCatchBlock();
@@ -1045,9 +1047,11 @@ private:
DSC_class // class context, enables 'friend'
};
- DeclGroupPtrTy ParseDeclaration(unsigned Context, SourceLocation &DeclEnd);
+ DeclGroupPtrTy ParseDeclaration(unsigned Context, SourceLocation &DeclEnd,
+ CXX0XAttributeList Attr);
DeclGroupPtrTy ParseSimpleDeclaration(unsigned Context,
- SourceLocation &DeclEnd);
+ SourceLocation &DeclEnd,
+ AttributeList *Attr);
DeclGroupPtrTy ParseDeclGroup(ParsingDeclSpec &DS, unsigned Context,
bool AllowFunctionDefinitions,
SourceLocation *DeclEnd = 0);
@@ -1217,11 +1221,14 @@ private:
void ParseBlockId();
// EndLoc, if non-NULL, is filled with the location of the last token of
// the attribute list.
- AttributeList *ParseAttributes(SourceLocation *EndLoc = 0);
+ CXX0XAttributeList ParseCXX0XAttributes(SourceLocation *EndLoc = 0);
+ AttributeList *ParseGNUAttributes(SourceLocation *EndLoc = 0);
AttributeList *ParseMicrosoftDeclSpec(AttributeList* CurrAttr = 0);
AttributeList *ParseMicrosoftTypeAttributes(AttributeList* CurrAttr = 0);
void ParseTypeofSpecifier(DeclSpec &DS);
void ParseDecltypeSpecifier(DeclSpec &DS);
+
+ OwningExprResult ParseCXX0XAlignArgument(SourceLocation Start);
/// DeclaratorScopeObj - RAII object used in Parser::ParseDirectDeclarator to
/// enter a new C++ declarator scope and exit it when the function is
@@ -1265,7 +1272,8 @@ private:
typedef void (Parser::*DirectDeclParseFunction)(Declarator&);
void ParseDeclaratorInternal(Declarator &D,
DirectDeclParseFunction DirectDeclParser);
- void ParseTypeQualifierListOpt(DeclSpec &DS, bool AttributesAllowed = true);
+ void ParseTypeQualifierListOpt(DeclSpec &DS, bool GNUAttributesAllowed = true,
+ bool CXX0XAttributesAllowed = true);
void ParseDirectDeclarator(Declarator &D);
void ParseParenDeclarator(Declarator &D);
void ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
@@ -1278,12 +1286,17 @@ private:
//===--------------------------------------------------------------------===//
// C++ 7: Declarations [dcl.dcl]
+ bool isCXX0XAttributeSpecifier(bool FullLookahead = false,
+ tok::TokenKind *After = 0);
+
DeclPtrTy ParseNamespace(unsigned Context, SourceLocation &DeclEnd);
DeclPtrTy ParseLinkage(unsigned Context);
DeclPtrTy ParseUsingDirectiveOrDeclaration(unsigned Context,
- SourceLocation &DeclEnd);
+ SourceLocation &DeclEnd,
+ CXX0XAttributeList Attrs);
DeclPtrTy ParseUsingDirective(unsigned Context, SourceLocation UsingLoc,
- SourceLocation &DeclEnd);
+ SourceLocation &DeclEnd,
+ AttributeList *Attr);
DeclPtrTy ParseUsingDeclaration(unsigned Context, SourceLocation UsingLoc,
SourceLocation &DeclEnd,
AccessSpecifier AS = AS_none);
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index aced8c7623..6121580bab 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -521,7 +521,7 @@ unsigned ASTContext::getDeclAlignInBytes(const Decl *D) {
unsigned Align = Target.getCharWidth();
if (const AlignedAttr* AA = D->getAttr<AlignedAttr>())
- Align = std::max(Align, AA->getAlignment());
+ Align = std::max(Align, AA->getMaxAlignment());
if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
QualType T = VD->getType();
@@ -761,7 +761,8 @@ ASTContext::getTypeInfo(const Type *T) {
case Type::Typedef: {
const TypedefDecl *Typedef = cast<TypedefType>(T)->getDecl();
if (const AlignedAttr *Aligned = Typedef->getAttr<AlignedAttr>()) {
- Align = Aligned->getAlignment();
+ Align = std::max(Aligned->getMaxAlignment(),
+ getTypeAlign(Typedef->getUnderlyingType().getTypePtr()));
Width = getTypeSize(Typedef->getUnderlyingType().getTypePtr());
} else
return getTypeInfo(Typedef->getUnderlyingType().getTypePtr());
diff --git a/lib/AST/RecordLayoutBuilder.cpp b/lib/AST/RecordLayoutBuilder.cpp
index b9cfcfec74..c084ba6f51 100644
--- a/lib/AST/RecordLayoutBuilder.cpp
+++ b/lib/AST/RecordLayoutBuilder.cpp
@@ -448,7 +448,7 @@ void ASTRecordLayoutBuilder::Layout(const RecordDecl *D) {
MaxFieldAlignment = PPA->getAlignment();
if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
- UpdateAlignment(AA->getAlignment());
+ UpdateAlignment(AA->getMaxAlignment());
// If this is a C++ class, lay out the vtable and the non-virtual bases.
const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D);
@@ -498,7 +498,7 @@ void ASTRecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D,
MaxFieldAlignment = PPA->getAlignment();
if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
- UpdateAlignment(AA->getAlignment());
+ UpdateAlignment(AA->getMaxAlignment());
// Layout each ivar sequentially.
llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
@@ -539,8 +539,9 @@ void ASTRecordLayoutBuilder::LayoutField(const FieldDecl *D) {
if (FieldPacked)
FieldAlign = 1;
- if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
- FieldAlign = std::max(FieldAlign, AA->getAlignment());
+ if (const AlignedAttr *AA = D->getAttr<AlignedAttr>()) {
+ FieldAlign = std::max(FieldAlign, AA->getMaxAlignment());
+ }
// The maximum field alignment overrides the aligned attribute.
if (MaxFieldAlignment)
FieldAlign = std::min(FieldAlign, MaxFieldAlignment);
@@ -574,8 +575,9 @@ void ASTRecordLayoutBuilder::LayoutField(const FieldDecl *D) {
if (FieldPacked)
FieldAlign = 8;
- if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
- FieldAlign = std::max(FieldAlign, AA->getAlignment());
+ if (const AlignedAttr *AA = D->getAttr<AlignedAttr>()) {
+ FieldAlign = std::max(FieldAlign, AA->getMaxAlignment());
+ }
// The maximum field alignment overrides the aligned attribute.
if (MaxFieldAlignment)
FieldAlign = std::min(FieldAlign, MaxFieldAlignment);
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 1fbd3b9273..b8027d8314 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -353,8 +353,12 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
else if (Features.getStackProtectorMode() == LangOptions::SSPReq)
F->addFnAttr(llvm::Attribute::StackProtectReq);
- if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
- F->setAlignment(AA->getAlignment()/8);
+ if (const AlignedAttr *AA = D->getAttr<AlignedAttr>()) {
+ unsigned width = Context.Target.getCharWidth();
+ F->setAlignment(AA->getAlignment() / width);
+ while ((AA = AA->getNext<AlignedAttr>()))
+ F->setAlignment(std::max(F->getAlignment(), AA->getAlignment() / width));
+ }
// C++ ABI requires 2-byte alignment for member functions.
if (F->getAlignment() < 2 && isa<CXXMethodDecl>(D))
F->setAlignment(2);
diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp
index 6a92a2db51..328bb611ba 100644
--- a/lib/Frontend/PCHReaderDecl.cpp
+++ b/lib/Frontend/PCHReaderDecl.cpp
@@ -461,6 +461,7 @@ Attr *PCHReader::ReadAttributes() {
SIMPLE_ATTR(Deprecated);
UNSIGNED_ATTR(Destructor);
SIMPLE_ATTR(FastCall);
+ SIMPLE_ATTR(Final);
case Attr::Format: {
std::string Type = ReadString(Record, Idx);
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index 8a45ebce1b..e3f6c62c2d 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -1792,6 +1792,7 @@ void PCHWriter::WriteAttributeRecord(const Attr *Attr) {
break;
case Attr::FastCall:
+ case Attr::Final:
break;
case Attr::Format: {
diff --git a/lib/Parse/AttributeList.cpp b/lib/Parse/AttributeList.cpp
index dde4bc866a..7e2935c2e0 100644
--- a/lib/Parse/AttributeList.cpp
+++ b/lib/Parse/AttributeList.cpp
@@ -17,11 +17,13 @@
using namespace clang;
AttributeList::AttributeList(IdentifierInfo *aName, SourceLocation aLoc,
+ IdentifierInfo *sName, SourceLocation sLoc,
IdentifierInfo *pName, SourceLocation pLoc,
ActionBase::ExprTy **ExprList, unsigned numArgs,
- AttributeList *n, bool declspec)
- : AttrName(aName), AttrLoc(aLoc), ParmName(pName), ParmLoc(pLoc),
- NumArgs(numArgs), Next(n), DeclspecAttribute(declspec) {
+ AttributeList *n, bool declspec, bool cxx0x)
+ : AttrName(aName), AttrLoc(aLoc), ScopeName(sName), ScopeLoc(sLoc),
+ ParmName(pName), ParmLoc(pLoc), NumArgs(numArgs), Next(n),
+ DeclspecAttribute(declspec), CXX0XAttribute(cxx0x) {
if (numArgs == 0)
Args = 0;
@@ -59,6 +61,8 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
.Case("mode", AT_mode)
.Case("used", AT_used)
.Case("alias", AT_alias)
+ .Case("align", AT_aligned)
+ .Case("final", AT_final)
.Case("cdecl", AT_cdecl)
.Case("const", AT_const)
.Case("packed", AT_packed)
@@ -103,6 +107,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
.Case("transparent_union", AT_transparent_union)
.Case("analyzer_noreturn", AT_analyzer_noreturn)
.Case("warn_unused_result", AT_warn_unused_result)
+ .Case("carries_dependency", AT_carries_dependency)
.Case("ns_returns_retained", AT_ns_returns_retained)
.Case("cf_returns_retained", AT_cf_returns_retained)
.Case("reqd_work_group_size", AT_reqd_wg_size)
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 2bfda30a95..b13dc73356 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -1,3 +1,4 @@
+
//===--- ParseDecl.cpp - Declaration Parsing ------------------------------===//
//
// The LLVM Compiler Infrastructure
@@ -45,7 +46,7 @@ Action::TypeResult Parser::ParseTypeName(SourceRange *Range) {
return Actions.ActOnTypeName(CurScope, DeclaratorInfo);
}
-/// ParseAttributes - Parse a non-empty attributes list.
+/// ParseGNUAttributes - Parse a non-empty attributes list.
///
/// [GNU] attributes:
/// attribute
@@ -81,8 +82,8 @@ Action::TypeResult Parser::ParseTypeName(SourceRange *Range) {
/// attributes are very simple in practice. Until we find a bug, I don't see
/// a pressing need to implement the 2 token lookahead.
-AttributeList *Parser::ParseAttributes(SourceLocation *EndLoc) {
- assert(Tok.is(tok::kw___attribute) && "Not an attribute list!");
+AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) {
+ assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!");
AttributeList *CurrAttr = 0;
@@ -121,7 +122,7 @@ AttributeList *Parser::ParseAttributes(SourceLocation *EndLoc) {
if (Tok.is(tok::r_paren)) {
// __attribute__(( mode(byte) ))
ConsumeParen(); // ignore the right paren loc for now
- CurrAttr = new AttributeList(AttrName, AttrNameLoc,
+ CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc,
ParmName, ParmLoc, 0, 0, CurrAttr);
} else if (Tok.is(tok::comma)) {
ConsumeToken();
@@ -145,8 +146,10 @@ AttributeList *Parser::ParseAttributes(SourceLocation *EndLoc) {
}
if (ArgExprsOk && Tok.is(tok::r_paren)) {
ConsumeParen(); // ignore the right paren loc for now
- CurrAttr = new AttributeList(AttrName, AttrNameLoc, ParmName,
- ParmLoc, ArgExprs.take(), ArgExprs.size(), CurrAttr);
+ CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0,
+ AttrNameLoc, ParmName, ParmLoc,
+ ArgExprs.take(), ArgExprs.size(),
+ CurrAttr);
}
}
} else { // not an identifier
@@ -155,7 +158,7 @@ AttributeList *Parser::ParseAttributes(SourceLocation *EndLoc) {
// parse a possibly empty comma separated list of expressions
// __attribute__(( nonnull() ))
ConsumeParen(); // ignore the right paren loc for now
- CurrAttr = new AttributeList(AttrName, AttrNameLoc,
+ CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc,
0, SourceLocation(), 0, 0, CurrAttr);
break;
case tok::kw_char:
@@ -175,7 +178,7 @@ AttributeList *Parser::ParseAttributes(SourceLocation *EndLoc) {
// If it's a builtin type name, eat it and expect a rparen
// __attribute__(( vec_type_hint(char) ))
ConsumeToken();
- CurrAttr = new AttributeList(AttrName, AttrNameLoc,
+ CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc,
0, SourceLocation(), 0, 0, CurrAttr);
if (Tok.is(tok::r_paren))
ConsumeParen();
@@ -203,20 +206,21 @@ AttributeList *Parser::ParseAttributes(SourceLocation *EndLoc) {
if (ArgExprsOk && Tok.is(tok::r_paren)) {
ConsumeParen(); // ignore the right paren loc for now
CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0,
- SourceLocation(), ArgExprs.take(), ArgExprs.size(),
+ AttrNameLoc, 0, SourceLocation(), ArgExprs.take(),
+ ArgExprs.size(),
CurrAttr);
}
break;
}
}
} else {
- CurrAttr = new AttributeList(AttrName, AttrNameLoc,
+ CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc,
0, SourceLocation(), 0, 0, CurrAttr);
}
}
if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
SkipUntil(tok::r_paren, false);
- SourceLocation Loc = Tok.getLocation();;
+ SourceLocation Loc = Tok.getLocation();
if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) {
SkipUntil(tok::r_paren, false);
}
@@ -254,15 +258,15 @@ AttributeList* Parser::ParseMicrosoftDeclSpec(AttributeList *CurrAttr) {
OwningExprResult ArgExpr(ParseAssignmentExpression());
if (!ArgExpr.isInvalid()) {
ExprTy* ExprList = ArgExpr.take();
- CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0,
+ CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
SourceLocation(), &ExprList, 1,
CurrAttr, true);
}
if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
SkipUntil(tok::r_paren, false);
} else {
- CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, SourceLocation(),
- 0, 0, CurrAttr, true);
+ CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc,
+ 0, SourceLocation(), 0, 0, CurrAttr, true);
}
}
if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
@@ -281,7 +285,7 @@ AttributeList* Parser::ParseMicrosoftTypeAttributes(AttributeList *CurrAttr) {
if (Tok.is(tok::kw___ptr64) || Tok.is(tok::kw___w64))
// FIXME: Support these properly!
continue;
- CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0,
+ CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
SourceLocation(), 0, 0, CurrAttr, true);
}
return CurrAttr;
@@ -304,26 +308,36 @@ AttributeList* Parser::ParseMicrosoftTypeAttributes(AttributeList *CurrAttr) {
/// others... [FIXME]
///
Parser::DeclGroupPtrTy Parser::ParseDeclaration(unsigned Context,
- SourceLocation &DeclEnd) {
+ SourceLocation &DeclEnd,
+ CXX0XAttributeList Attr) {
DeclPtrTy SingleDecl;
switch (Tok.getKind()) {
case tok::kw_template:
case tok::kw_export:
+ if (Attr.HasAttr)
+ Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
+ << Attr.Range;
SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd);
break;
case tok::kw_namespace:
+ if (Attr.HasAttr)
+ Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
+ << Attr.Range;
SingleDecl = ParseNamespace(Context, DeclEnd);
break;
case tok::kw_using:
- SingleDecl = ParseUsingDirectiveOrDeclaration(Context, DeclEnd);
+ SingleDecl = ParseUsingDirectiveOrDeclaration(Context, DeclEnd, Attr);
break;
case tok::kw_static_assert:
+ if (Attr.HasAttr)
+ Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
+ << Attr.Range;
SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
break;
default:
- return ParseSimpleDeclaration(Context, DeclEnd);
+ return ParseSimpleDeclaration(Context, DeclEnd, Attr.AttrList);
}
-
+
// This routine returns a DeclGroup, if the thing we parsed only contains a
// single decl, convert it now.
return Actions.ConvertDeclToDeclGroup(SingleDecl);
@@ -337,9 +351,12 @@ Parser::DeclGroupPtrTy Parser::ParseDeclaration(unsigned Context,
/// If RequireSemi is false, this does not check for a ';' at the end of the
/// declaration.
Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(unsigned Context,
- SourceLocation &DeclEnd) {
+ SourceLocation &DeclEnd,
+ AttributeList *Attr) {
// Parse the common declaration-specifiers piece.
ParsingDeclSpec DS(*this);
+ if (Attr)
+ DS.AddAttributes(Attr);
ParseDeclarationSpecifiers(DS);
// C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
@@ -422,7 +439,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
// short x, __attribute__((common)) var; -> declarator
if (Tok.is(tok::kw___attribute)) {
SourceLocation Loc;
- AttributeList *AttrList = ParseAttributes(&Loc);
+ AttributeList *AttrList = ParseGNUAttributes(&Loc);
D.AddAttributes(AttrList, Loc);
}
@@ -491,7 +508,7 @@ Parser::DeclPtrTy Parser::ParseDeclarationAfterDeclarator(Declarator &D,
// If attributes are present, parse them.
if (Tok.is(tok::kw___attribute)) {
SourceLocation Loc;
- AttributeList *AttrList = ParseAttributes(&Loc);
+ AttributeList *AttrList = ParseGNUAttributes(&Loc);
D.AddAttributes(AttrList, Loc);
}
@@ -988,7 +1005,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
// GNU attributes support.
case tok::kw___attribute:
- DS.AddAttributes(ParseAttributes());
+ DS.AddAttributes(ParseGNUAttributes());
continue;
// Microsoft declspec support.
@@ -1522,7 +1539,7 @@ ParseStructDeclaration(DeclSpec &DS, FieldCallback &Fields) {
// Attributes are only allowed here on successive declarators.
if (!FirstDeclarator && Tok.is(tok::kw___attribute)) {
SourceLocation Loc;
- AttributeList *AttrList = ParseAttributes(&Loc);
+ AttributeList *AttrList = ParseGNUAttributes(&Loc);
DeclaratorInfo.D.AddAttributes(AttrList, Loc);
}
@@ -1543,7 +1560,7 @@ ParseStructDeclaration(DeclSpec &DS, FieldCallback &Fields) {
// If attributes exist after the declarator, parse them.
if (Tok.is(tok::kw___attribute)) {
SourceLocation Loc;
- AttributeList *AttrList = ParseAttributes(&Loc);
+ AttributeList *AttrList = ParseGNUAttributes(&Loc);
DeclaratorInfo.D.AddAttributes(AttrList, Loc);
}
@@ -1667,7 +1684,7 @@ void P