forked from OSchip/llvm-project
Refactor how we collect attributes during parsing, and add slots for attributes
on array and function declarators. This is pretty far from complete, and I'll revisit it later if someone doesn't beat me to it. llvm-svn: 122535
This commit is contained in:
parent
b4d271ef46
commit
53fa71476d
|
@ -920,14 +920,17 @@ private:
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// C99 6.9: External Definitions.
|
// C99 6.9: External Definitions.
|
||||||
DeclGroupPtrTy ParseExternalDeclaration(CXX0XAttributeList Attr,
|
struct ParsedAttributesWithRange : ParsedAttributes {
|
||||||
|
SourceRange Range;
|
||||||
|
};
|
||||||
|
|
||||||
|
DeclGroupPtrTy ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
|
||||||
ParsingDeclSpec *DS = 0);
|
ParsingDeclSpec *DS = 0);
|
||||||
bool isDeclarationAfterDeclarator() const;
|
bool isDeclarationAfterDeclarator() const;
|
||||||
bool isStartOfFunctionDefinition(const ParsingDeclarator &Declarator);
|
bool isStartOfFunctionDefinition(const ParsingDeclarator &Declarator);
|
||||||
DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(AttributeList *Attr,
|
DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(ParsedAttributes &attrs,
|
||||||
AccessSpecifier AS = AS_none);
|
AccessSpecifier AS = AS_none);
|
||||||
DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(ParsingDeclSpec &DS,
|
DeclGroupPtrTy ParseDeclarationOrFunctionDefinition(ParsingDeclSpec &DS,
|
||||||
AttributeList *Attr,
|
|
||||||
AccessSpecifier AS = AS_none);
|
AccessSpecifier AS = AS_none);
|
||||||
|
|
||||||
Decl *ParseFunctionDefinition(ParsingDeclarator &D,
|
Decl *ParseFunctionDefinition(ParsingDeclarator &D,
|
||||||
|
@ -942,7 +945,7 @@ private:
|
||||||
Decl *ParseObjCAtDirectives();
|
Decl *ParseObjCAtDirectives();
|
||||||
Decl *ParseObjCAtClassDeclaration(SourceLocation atLoc);
|
Decl *ParseObjCAtClassDeclaration(SourceLocation atLoc);
|
||||||
Decl *ParseObjCAtInterfaceDeclaration(SourceLocation atLoc,
|
Decl *ParseObjCAtInterfaceDeclaration(SourceLocation atLoc,
|
||||||
AttributeList *prefixAttrs = 0);
|
ParsedAttributes &prefixAttrs);
|
||||||
void ParseObjCClassInstanceVariables(Decl *interfaceDecl,
|
void ParseObjCClassInstanceVariables(Decl *interfaceDecl,
|
||||||
tok::ObjCKeywordKind visibility,
|
tok::ObjCKeywordKind visibility,
|
||||||
SourceLocation atLoc);
|
SourceLocation atLoc);
|
||||||
|
@ -955,7 +958,7 @@ private:
|
||||||
void ParseObjCInterfaceDeclList(Decl *interfaceDecl,
|
void ParseObjCInterfaceDeclList(Decl *interfaceDecl,
|
||||||
tok::ObjCKeywordKind contextKey);
|
tok::ObjCKeywordKind contextKey);
|
||||||
Decl *ParseObjCAtProtocolDeclaration(SourceLocation atLoc,
|
Decl *ParseObjCAtProtocolDeclaration(SourceLocation atLoc,
|
||||||
AttributeList *prefixAttrs = 0);
|
ParsedAttributes &prefixAttrs);
|
||||||
|
|
||||||
Decl *ObjCImpDecl;
|
Decl *ObjCImpDecl;
|
||||||
llvm::SmallVector<Decl *, 4> PendingObjCImpDecl;
|
llvm::SmallVector<Decl *, 4> PendingObjCImpDecl;
|
||||||
|
@ -1189,25 +1192,25 @@ private:
|
||||||
}
|
}
|
||||||
StmtResult ParseStatementOrDeclaration(StmtVector& Stmts,
|
StmtResult ParseStatementOrDeclaration(StmtVector& Stmts,
|
||||||
bool OnlyStatement = false);
|
bool OnlyStatement = false);
|
||||||
StmtResult ParseLabeledStatement(AttributeList *Attr);
|
StmtResult ParseLabeledStatement(ParsedAttributes &Attr);
|
||||||
StmtResult ParseCaseStatement(AttributeList *Attr);
|
StmtResult ParseCaseStatement(ParsedAttributes &Attr);
|
||||||
StmtResult ParseDefaultStatement(AttributeList *Attr);
|
StmtResult ParseDefaultStatement(ParsedAttributes &Attr);
|
||||||
StmtResult ParseCompoundStatement(AttributeList *Attr,
|
StmtResult ParseCompoundStatement(ParsedAttributes &Attr,
|
||||||
bool isStmtExpr = false);
|
bool isStmtExpr = false);
|
||||||
StmtResult ParseCompoundStatementBody(bool isStmtExpr = false);
|
StmtResult ParseCompoundStatementBody(bool isStmtExpr = false);
|
||||||
bool ParseParenExprOrCondition(ExprResult &ExprResult,
|
bool ParseParenExprOrCondition(ExprResult &ExprResult,
|
||||||
Decl *&DeclResult,
|
Decl *&DeclResult,
|
||||||
SourceLocation Loc,
|
SourceLocation Loc,
|
||||||
bool ConvertToBoolean);
|
bool ConvertToBoolean);
|
||||||
StmtResult ParseIfStatement(AttributeList *Attr);
|
StmtResult ParseIfStatement(ParsedAttributes &Attr);
|
||||||
StmtResult ParseSwitchStatement(AttributeList *Attr);
|
StmtResult ParseSwitchStatement(ParsedAttributes &Attr);
|
||||||
StmtResult ParseWhileStatement(AttributeList *Attr);
|
StmtResult ParseWhileStatement(ParsedAttributes &Attr);
|
||||||
StmtResult ParseDoStatement(AttributeList *Attr);
|
StmtResult ParseDoStatement(ParsedAttributes &Attr);
|
||||||
StmtResult ParseForStatement(AttributeList *Attr);
|
StmtResult ParseForStatement(ParsedAttributes &Attr);
|
||||||
StmtResult ParseGotoStatement(AttributeList *Attr);
|
StmtResult ParseGotoStatement(ParsedAttributes &Attr);
|
||||||
StmtResult ParseContinueStatement(AttributeList *Attr);
|
StmtResult ParseContinueStatement(ParsedAttributes &Attr);
|
||||||
StmtResult ParseBreakStatement(AttributeList *Attr);
|
StmtResult ParseBreakStatement(ParsedAttributes &Attr);
|
||||||
StmtResult ParseReturnStatement(AttributeList *Attr);
|
StmtResult ParseReturnStatement(ParsedAttributes &Attr);
|
||||||
StmtResult ParseAsmStatement(bool &msAsm);
|
StmtResult ParseAsmStatement(bool &msAsm);
|
||||||
StmtResult FuzzyParseMicrosoftAsmStatement(SourceLocation AsmLoc);
|
StmtResult FuzzyParseMicrosoftAsmStatement(SourceLocation AsmLoc);
|
||||||
bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names,
|
bool ParseAsmOperandsOpt(llvm::SmallVectorImpl<IdentifierInfo *> &Names,
|
||||||
|
@ -1217,7 +1220,7 @@ private:
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// C++ 6: Statements and Blocks
|
// C++ 6: Statements and Blocks
|
||||||
|
|
||||||
StmtResult ParseCXXTryBlock(AttributeList *Attr);
|
StmtResult ParseCXXTryBlock(ParsedAttributes &Attr);
|
||||||
StmtResult ParseCXXTryBlockCommon(SourceLocation TryLoc);
|
StmtResult ParseCXXTryBlockCommon(SourceLocation TryLoc);
|
||||||
StmtResult ParseCXXCatchBlock();
|
StmtResult ParseCXXCatchBlock();
|
||||||
|
|
||||||
|
@ -1244,11 +1247,11 @@ private:
|
||||||
|
|
||||||
DeclGroupPtrTy ParseDeclaration(StmtVector &Stmts,
|
DeclGroupPtrTy ParseDeclaration(StmtVector &Stmts,
|
||||||
unsigned Context, SourceLocation &DeclEnd,
|
unsigned Context, SourceLocation &DeclEnd,
|
||||||
CXX0XAttributeList Attr);
|
ParsedAttributesWithRange &attrs);
|
||||||
DeclGroupPtrTy ParseSimpleDeclaration(StmtVector &Stmts,
|
DeclGroupPtrTy ParseSimpleDeclaration(StmtVector &Stmts,
|
||||||
unsigned Context,
|
unsigned Context,
|
||||||
SourceLocation &DeclEnd,
|
SourceLocation &DeclEnd,
|
||||||
AttributeList *Attr,
|
ParsedAttributes &attrs,
|
||||||
bool RequireSemi);
|
bool RequireSemi);
|
||||||
DeclGroupPtrTy ParseDeclGroup(ParsingDeclSpec &DS, unsigned Context,
|
DeclGroupPtrTy ParseDeclGroup(ParsingDeclSpec &DS, unsigned Context,
|
||||||
bool AllowFunctionDefinitions,
|
bool AllowFunctionDefinitions,
|
||||||
|
@ -1447,14 +1450,64 @@ private:
|
||||||
|
|
||||||
TypeResult ParseTypeName(SourceRange *Range = 0);
|
TypeResult ParseTypeName(SourceRange *Range = 0);
|
||||||
void ParseBlockId();
|
void ParseBlockId();
|
||||||
// EndLoc, if non-NULL, is filled with the location of the last token of
|
|
||||||
// the attribute list.
|
void ProhibitAttributes(ParsedAttributesWithRange &attrs) {
|
||||||
CXX0XAttributeList ParseCXX0XAttributes(SourceLocation *EndLoc = 0);
|
if (!attrs.Range.isValid()) return;
|
||||||
void ParseMicrosoftAttributes();
|
DiagnoseProhibitedAttributes(attrs);
|
||||||
AttributeList *ParseGNUAttributes(SourceLocation *EndLoc = 0);
|
}
|
||||||
AttributeList *ParseMicrosoftDeclSpec(AttributeList* CurrAttr = 0);
|
void DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs);
|
||||||
AttributeList *ParseMicrosoftTypeAttributes(AttributeList* CurrAttr = 0);
|
|
||||||
AttributeList *ParseBorlandTypeAttributes(AttributeList* CurrAttr = 0);
|
void MaybeParseGNUAttributes(Declarator &D) {
|
||||||
|
if (Tok.is(tok::kw___attribute)) {
|
||||||
|
ParsedAttributes attrs;
|
||||||
|
SourceLocation endLoc;
|
||||||
|
ParseGNUAttributes(attrs, &endLoc);
|
||||||
|
D.addAttributes(attrs.getList(), endLoc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void MaybeParseGNUAttributes(ParsedAttributes &attrs,
|
||||||
|
SourceLocation *endLoc = 0) {
|
||||||
|
if (Tok.is(tok::kw___attribute))
|
||||||
|
ParseGNUAttributes(attrs, endLoc);
|
||||||
|
}
|
||||||
|
void ParseGNUAttributes(ParsedAttributes &attrs,
|
||||||
|
SourceLocation *endLoc = 0);
|
||||||
|
|
||||||
|
void MaybeParseCXX0XAttributes(Declarator &D) {
|
||||||
|
if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
|
||||||
|
ParsedAttributesWithRange attrs;
|
||||||
|
SourceLocation endLoc;
|
||||||
|
ParseCXX0XAttributes(attrs, &endLoc);
|
||||||
|
D.addAttributes(attrs.getList(), endLoc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void MaybeParseCXX0XAttributes(ParsedAttributes &attrs,
|
||||||
|
SourceLocation *endLoc = 0) {
|
||||||
|
if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
|
||||||
|
ParsedAttributesWithRange attrsWithRange;
|
||||||
|
ParseCXX0XAttributes(attrsWithRange, endLoc);
|
||||||
|
attrs.append(attrsWithRange.getList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void MaybeParseCXX0XAttributes(ParsedAttributesWithRange &attrs,
|
||||||
|
SourceLocation *endLoc = 0) {
|
||||||
|
if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
|
||||||
|
ParseCXX0XAttributes(attrs, endLoc);
|
||||||
|
}
|
||||||
|
void ParseCXX0XAttributes(ParsedAttributesWithRange &attrs,
|
||||||
|
SourceLocation *EndLoc = 0);
|
||||||
|
|
||||||
|
void MaybeParseMicrosoftAttributes(ParsedAttributes &attrs,
|
||||||
|
SourceLocation *endLoc = 0) {
|
||||||
|
if (getLang().Microsoft && Tok.is(tok::l_square))
|
||||||
|
ParseMicrosoftAttributes(attrs, endLoc);
|
||||||
|
}
|
||||||
|
void ParseMicrosoftAttributes(ParsedAttributes &attrs,
|
||||||
|
SourceLocation *endLoc = 0);
|
||||||
|
void ParseMicrosoftDeclSpec(ParsedAttributes &attrs);
|
||||||
|
void ParseMicrosoftTypeAttributes(ParsedAttributes &attrs);
|
||||||
|
void ParseBorlandTypeAttributes(ParsedAttributes &attrs);
|
||||||
|
|
||||||
void ParseTypeofSpecifier(DeclSpec &DS);
|
void ParseTypeofSpecifier(DeclSpec &DS);
|
||||||
void ParseDecltypeSpecifier(DeclSpec &DS);
|
void ParseDecltypeSpecifier(DeclSpec &DS);
|
||||||
|
|
||||||
|
@ -1499,12 +1552,13 @@ private:
|
||||||
typedef void (Parser::*DirectDeclParseFunction)(Declarator&);
|
typedef void (Parser::*DirectDeclParseFunction)(Declarator&);
|
||||||
void ParseDeclaratorInternal(Declarator &D,
|
void ParseDeclaratorInternal(Declarator &D,
|
||||||
DirectDeclParseFunction DirectDeclParser);
|
DirectDeclParseFunction DirectDeclParser);
|
||||||
|
|
||||||
void ParseTypeQualifierListOpt(DeclSpec &DS, bool GNUAttributesAllowed = true,
|
void ParseTypeQualifierListOpt(DeclSpec &DS, bool GNUAttributesAllowed = true,
|
||||||
bool CXX0XAttributesAllowed = true);
|
bool CXX0XAttributesAllowed = true);
|
||||||
void ParseDirectDeclarator(Declarator &D);
|
void ParseDirectDeclarator(Declarator &D);
|
||||||
void ParseParenDeclarator(Declarator &D);
|
void ParseParenDeclarator(Declarator &D);
|
||||||
void ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
void ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
||||||
AttributeList *AttrList = 0,
|
ParsedAttributes &attrs,
|
||||||
bool RequiresArg = false);
|
bool RequiresArg = false);
|
||||||
void ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,
|
void ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,
|
||||||
IdentifierInfo *FirstIdent,
|
IdentifierInfo *FirstIdent,
|
||||||
|
@ -1524,10 +1578,11 @@ private:
|
||||||
Decl *ParseUsingDirectiveOrDeclaration(unsigned Context,
|
Decl *ParseUsingDirectiveOrDeclaration(unsigned Context,
|
||||||
const ParsedTemplateInfo &TemplateInfo,
|
const ParsedTemplateInfo &TemplateInfo,
|
||||||
SourceLocation &DeclEnd,
|
SourceLocation &DeclEnd,
|
||||||
CXX0XAttributeList Attrs);
|
ParsedAttributesWithRange &attrs);
|
||||||
Decl *ParseUsingDirective(unsigned Context,
|
Decl *ParseUsingDirective(unsigned Context,
|
||||||
SourceLocation UsingLoc,
|
SourceLocation UsingLoc,
|
||||||
SourceLocation &DeclEnd, AttributeList *Attr);
|
SourceLocation &DeclEnd,
|
||||||
|
ParsedAttributes &attrs);
|
||||||
Decl *ParseUsingDeclaration(unsigned Context,
|
Decl *ParseUsingDeclaration(unsigned Context,
|
||||||
const ParsedTemplateInfo &TemplateInfo,
|
const ParsedTemplateInfo &TemplateInfo,
|
||||||
SourceLocation UsingLoc,
|
SourceLocation UsingLoc,
|
||||||
|
|
|
@ -56,7 +56,7 @@ private:
|
||||||
IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
|
IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
|
||||||
IdentifierInfo *ParmName, SourceLocation ParmLoc,
|
IdentifierInfo *ParmName, SourceLocation ParmLoc,
|
||||||
Expr **args, unsigned numargs,
|
Expr **args, unsigned numargs,
|
||||||
AttributeList *Next, bool declspec, bool cxx0x);
|
bool declspec, bool cxx0x);
|
||||||
public:
|
public:
|
||||||
class Factory {
|
class Factory {
|
||||||
llvm::BumpPtrAllocator Alloc;
|
llvm::BumpPtrAllocator Alloc;
|
||||||
|
@ -66,12 +66,11 @@ public:
|
||||||
AttributeList *Create(IdentifierInfo *AttrName, SourceLocation AttrLoc,
|
AttributeList *Create(IdentifierInfo *AttrName, SourceLocation AttrLoc,
|
||||||
IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
|
IdentifierInfo *ScopeName, SourceLocation ScopeLoc,
|
||||||
IdentifierInfo *ParmName, SourceLocation ParmLoc,
|
IdentifierInfo *ParmName, SourceLocation ParmLoc,
|
||||||
Expr **args, unsigned numargs,
|
Expr **args, unsigned numargs, bool declspec = false, bool cxx0x = false) {
|
||||||
AttributeList *Next, bool declspec = false, bool cxx0x = false) {
|
|
||||||
AttributeList *Mem = Alloc.Allocate<AttributeList>();
|
AttributeList *Mem = Alloc.Allocate<AttributeList>();
|
||||||
new (Mem) AttributeList(Alloc, AttrName, AttrLoc, ScopeName, ScopeLoc,
|
new (Mem) AttributeList(Alloc, AttrName, AttrLoc, ScopeName, ScopeLoc,
|
||||||
ParmName, ParmLoc, args, numargs,
|
ParmName, ParmLoc, args, numargs,
|
||||||
Next, declspec, cxx0x);
|
declspec, cxx0x);
|
||||||
return Mem;
|
return Mem;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -266,6 +265,47 @@ struct CXX0XAttributeList {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// ParsedAttributes - A collection of parsed attributes. Currently
|
||||||
|
/// we don't differentiate between the various attribute syntaxes,
|
||||||
|
/// which is basically silly.
|
||||||
|
///
|
||||||
|
/// Right now this is a very lightweight container, but the expectation
|
||||||
|
/// is that this will become significantly more serious.
|
||||||
|
class ParsedAttributes {
|
||||||
|
public:
|
||||||
|
ParsedAttributes() : list(0) {}
|
||||||
|
|
||||||
|
bool empty() const { return list == 0; }
|
||||||
|
|
||||||
|
void add(AttributeList *newAttr) {
|
||||||
|
assert(newAttr);
|
||||||
|
assert(newAttr->getNext() == 0);
|
||||||
|
newAttr->setNext(list);
|
||||||
|
list = newAttr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void append(AttributeList *newList) {
|
||||||
|
if (!newList) return;
|
||||||
|
|
||||||
|
AttributeList *lastInNewList = newList;
|
||||||
|
while (AttributeList *next = lastInNewList->getNext())
|
||||||
|
lastInNewList = next;
|
||||||
|
|
||||||
|
lastInNewList->setNext(list);
|
||||||
|
list = newList;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set(AttributeList *newList) {
|
||||||
|
list = newList;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() { list = 0; }
|
||||||
|
AttributeList *getList() const { return list; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
AttributeList *list;
|
||||||
|
};
|
||||||
|
|
||||||
} // end namespace clang
|
} // end namespace clang
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -170,32 +170,32 @@ private:
|
||||||
|
|
||||||
// storage-class-specifier
|
// storage-class-specifier
|
||||||
/*SCS*/unsigned StorageClassSpec : 3;
|
/*SCS*/unsigned StorageClassSpec : 3;
|
||||||
bool SCS_thread_specified : 1;
|
unsigned SCS_thread_specified : 1;
|
||||||
bool SCS_extern_in_linkage_spec : 1;
|
unsigned SCS_extern_in_linkage_spec : 1;
|
||||||
|
|
||||||
// type-specifier
|
// type-specifier
|
||||||
/*TSW*/unsigned TypeSpecWidth : 2;
|
/*TSW*/unsigned TypeSpecWidth : 2;
|
||||||
/*TSC*/unsigned TypeSpecComplex : 2;
|
/*TSC*/unsigned TypeSpecComplex : 2;
|
||||||
/*TSS*/unsigned TypeSpecSign : 2;
|
/*TSS*/unsigned TypeSpecSign : 2;
|
||||||
/*TST*/unsigned TypeSpecType : 5;
|
/*TST*/unsigned TypeSpecType : 5;
|
||||||
bool TypeAltiVecVector : 1;
|
unsigned TypeAltiVecVector : 1;
|
||||||
bool TypeAltiVecPixel : 1;
|
unsigned TypeAltiVecPixel : 1;
|
||||||
bool TypeAltiVecBool : 1;
|
unsigned TypeAltiVecBool : 1;
|
||||||
bool TypeSpecOwned : 1;
|
unsigned TypeSpecOwned : 1;
|
||||||
|
|
||||||
// type-qualifiers
|
// type-qualifiers
|
||||||
unsigned TypeQualifiers : 3; // Bitwise OR of TQ.
|
unsigned TypeQualifiers : 3; // Bitwise OR of TQ.
|
||||||
|
|
||||||
// function-specifier
|
// function-specifier
|
||||||
bool FS_inline_specified : 1;
|
unsigned FS_inline_specified : 1;
|
||||||
bool FS_virtual_specified : 1;
|
unsigned FS_virtual_specified : 1;
|
||||||
bool FS_explicit_specified : 1;
|
unsigned FS_explicit_specified : 1;
|
||||||
|
|
||||||
// friend-specifier
|
// friend-specifier
|
||||||
bool Friend_specified : 1;
|
unsigned Friend_specified : 1;
|
||||||
|
|
||||||
// constexpr-specifier
|
// constexpr-specifier
|
||||||
bool Constexpr_specified : 1;
|
unsigned Constexpr_specified : 1;
|
||||||
|
|
||||||
/*SCS*/unsigned StorageClassSpecAsWritten : 3;
|
/*SCS*/unsigned StorageClassSpecAsWritten : 3;
|
||||||
|
|
||||||
|
@ -206,7 +206,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
// attributes.
|
// attributes.
|
||||||
AttributeList *AttrList;
|
ParsedAttributes Attrs;
|
||||||
|
|
||||||
// Scope specifier for the type spec, if applicable.
|
// Scope specifier for the type spec, if applicable.
|
||||||
CXXScopeSpec TypeScope;
|
CXXScopeSpec TypeScope;
|
||||||
|
@ -268,7 +268,6 @@ public:
|
||||||
Friend_specified(false),
|
Friend_specified(false),
|
||||||
Constexpr_specified(false),
|
Constexpr_specified(false),
|
||||||
StorageClassSpecAsWritten(SCS_unspecified),
|
StorageClassSpecAsWritten(SCS_unspecified),
|
||||||
AttrList(0),
|
|
||||||
ProtocolQualifiers(0),
|
ProtocolQualifiers(0),
|
||||||
NumProtocolQualifiers(0),
|
NumProtocolQualifiers(0),
|
||||||
ProtocolLocs(0),
|
ProtocolLocs(0),
|
||||||
|
@ -473,19 +472,29 @@ public:
|
||||||
/// short __attribute__((unused)) __attribute__((deprecated))
|
/// short __attribute__((unused)) __attribute__((deprecated))
|
||||||
/// int __attribute__((may_alias)) __attribute__((aligned(16))) var;
|
/// int __attribute__((may_alias)) __attribute__((aligned(16))) var;
|
||||||
///
|
///
|
||||||
void AddAttributes(AttributeList *alist) {
|
void addAttributes(AttributeList *AL) {
|
||||||
AttrList = addAttributeLists(AttrList, alist);
|
Attrs.append(AL);
|
||||||
}
|
}
|
||||||
void SetAttributes(AttributeList *AL) { AttrList = AL; }
|
void aetAttributes(AttributeList *AL) {
|
||||||
const AttributeList *getAttributes() const { return AttrList; }
|
Attrs.set(AL);
|
||||||
AttributeList *getAttributes() { return AttrList; }
|
}
|
||||||
|
|
||||||
|
bool hasAttributes() const { return !Attrs.empty(); }
|
||||||
|
|
||||||
|
ParsedAttributes &getAttributes() { return Attrs; }
|
||||||
|
const ParsedAttributes &getAttributes() const { return Attrs; }
|
||||||
|
|
||||||
/// TakeAttributes - Return the current attribute list and remove them from
|
/// TakeAttributes - Return the current attribute list and remove them from
|
||||||
/// the DeclSpec so that it doesn't own them.
|
/// the DeclSpec so that it doesn't own them.
|
||||||
AttributeList *TakeAttributes() {
|
ParsedAttributes takeAttributes() {
|
||||||
AttributeList *AL = AttrList;
|
ParsedAttributes saved = Attrs;
|
||||||
AttrList = 0;
|
Attrs.clear();
|
||||||
return AL;
|
return saved;
|
||||||
|
}
|
||||||
|
|
||||||
|
void takeAttributesFrom(ParsedAttributes &attrs) {
|
||||||
|
Attrs.append(attrs.getList());
|
||||||
|
attrs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef Decl * const *ProtocolQualifierListTy;
|
typedef Decl * const *ProtocolQualifierListTy;
|
||||||
|
@ -809,25 +818,27 @@ struct DeclaratorChunk {
|
||||||
/// EndLoc - If valid, the place where this chunck ends.
|
/// EndLoc - If valid, the place where this chunck ends.
|
||||||
SourceLocation EndLoc;
|
SourceLocation EndLoc;
|
||||||
|
|
||||||
struct PointerTypeInfo {
|
struct TypeInfoCommon {
|
||||||
|
AttributeList *AttrList;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PointerTypeInfo : TypeInfoCommon {
|
||||||
/// The type qualifiers: const/volatile/restrict.
|
/// The type qualifiers: const/volatile/restrict.
|
||||||
unsigned TypeQuals : 3;
|
unsigned TypeQuals : 3;
|
||||||
AttributeList *AttrList;
|
|
||||||
void destroy() {
|
void destroy() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ReferenceTypeInfo {
|
struct ReferenceTypeInfo : TypeInfoCommon {
|
||||||
/// The type qualifier: restrict. [GNU] C++ extension
|
/// The type qualifier: restrict. [GNU] C++ extension
|
||||||
bool HasRestrict : 1;
|
bool HasRestrict : 1;
|
||||||
/// True if this is an lvalue reference, false if it's an rvalue reference.
|
/// True if this is an lvalue reference, false if it's an rvalue reference.
|
||||||
bool LValueRef : 1;
|
bool LValueRef : 1;
|
||||||
AttributeList *AttrList;
|
|
||||||
void destroy() {
|
void destroy() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ArrayTypeInfo {
|
struct ArrayTypeInfo : TypeInfoCommon {
|
||||||
/// The type qualifiers for the array: const/volatile/restrict.
|
/// The type qualifiers for the array: const/volatile/restrict.
|
||||||
unsigned TypeQuals : 3;
|
unsigned TypeQuals : 3;
|
||||||
|
|
||||||
|
@ -841,6 +852,7 @@ struct DeclaratorChunk {
|
||||||
/// Since the parser is multi-purpose, and we don't want to impose a root
|
/// Since the parser is multi-purpose, and we don't want to impose a root
|
||||||
/// expression class on all clients, NumElts is untyped.
|
/// expression class on all clients, NumElts is untyped.
|
||||||
Expr *NumElts;
|
Expr *NumElts;
|
||||||
|
|
||||||
void destroy() {}
|
void destroy() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -875,29 +887,29 @@ struct DeclaratorChunk {
|
||||||
SourceRange Range;
|
SourceRange Range;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FunctionTypeInfo {
|
struct FunctionTypeInfo : TypeInfoCommon {
|
||||||
/// hasPrototype - This is true if the function had at least one typed
|
/// hasPrototype - This is true if the function had at least one typed
|
||||||
/// argument. If the function is () or (a,b,c), then it has no prototype,
|
/// argument. If the function is () or (a,b,c), then it has no prototype,
|
||||||
/// and is treated as a K&R-style function.
|
/// and is treated as a K&R-style function.
|
||||||
bool hasPrototype : 1;
|
unsigned hasPrototype : 1;
|
||||||
|
|
||||||
/// isVariadic - If this function has a prototype, and if that
|
/// isVariadic - If this function has a prototype, and if that
|
||||||
/// proto ends with ',...)', this is true. When true, EllipsisLoc
|
/// proto ends with ',...)', this is true. When true, EllipsisLoc
|
||||||
/// contains the location of the ellipsis.
|
/// contains the location of the ellipsis.
|
||||||
bool isVariadic : 1;
|
unsigned isVariadic : 1;
|
||||||
|
|
||||||
/// The type qualifiers: const/volatile/restrict.
|
/// The type qualifiers: const/volatile/restrict.
|
||||||
/// The qualifier bitmask values are the same as in QualType.
|
/// The qualifier bitmask values are the same as in QualType.
|
||||||
unsigned TypeQuals : 3;
|
unsigned TypeQuals : 3;
|
||||||
|
|
||||||
/// hasExceptionSpec - True if the function has an exception specification.
|
/// hasExceptionSpec - True if the function has an exception specification.
|
||||||
bool hasExceptionSpec : 1;
|
unsigned hasExceptionSpec : 1;
|
||||||
|
|
||||||
/// hasAnyExceptionSpec - True if the function has a throw(...) specifier.
|
/// hasAnyExceptionSpec - True if the function has a throw(...) specifier.
|
||||||
bool hasAnyExceptionSpec : 1;
|
unsigned hasAnyExceptionSpec : 1;
|
||||||
|
|
||||||
/// DeleteArgInfo - If this is true, we need to delete[] ArgInfo.
|
/// DeleteArgInfo - If this is true, we need to delete[] ArgInfo.
|
||||||
bool DeleteArgInfo : 1;
|
unsigned DeleteArgInfo : 1;
|
||||||
|
|
||||||
/// When isVariadic is true, the location of the ellipsis in the source.
|
/// When isVariadic is true, the location of the ellipsis in the source.
|
||||||
unsigned EllipsisLoc;
|
unsigned EllipsisLoc;
|
||||||
|
@ -960,19 +972,18 @@ struct DeclaratorChunk {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BlockPointerTypeInfo {
|
struct BlockPointerTypeInfo : TypeInfoCommon {
|
||||||
/// For now, sema will catch these as invalid.
|
/// For now, sema will catch these as invalid.
|
||||||
/// The type qualifiers: const/volatile/restrict.
|
/// The type qualifiers: const/volatile/restrict.
|
||||||
unsigned TypeQuals : 3;
|
unsigned TypeQuals : 3;
|
||||||
AttributeList *AttrList;
|
|
||||||
void destroy() {
|
void destroy() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MemberPointerTypeInfo {
|
struct MemberPointerTypeInfo : TypeInfoCommon {
|
||||||
/// The type qualifiers: const/volatile/restrict.
|
/// The type qualifiers: const/volatile/restrict.
|
||||||
unsigned TypeQuals : 3;
|
unsigned TypeQuals : 3;
|
||||||
AttributeList *AttrList;
|
|
||||||
// CXXScopeSpec has a constructor, so it can't be a direct member.
|
// CXXScopeSpec has a constructor, so it can't be a direct member.
|
||||||
// So we need some pointer-aligned storage and a bit of trickery.
|
// So we need some pointer-aligned storage and a bit of trickery.
|
||||||
union {
|
union {
|
||||||
|
@ -1019,8 +1030,8 @@ struct DeclaratorChunk {
|
||||||
case Pointer: return Ptr.AttrList;
|
case Pointer: return Ptr.AttrList;
|
||||||
case Reference: return Ref.AttrList;
|
case Reference: return Ref.AttrList;
|
||||||
case MemberPointer: return Mem.AttrList;
|
case MemberPointer: return Mem.AttrList;
|
||||||
case Array: return 0;
|
case Array: return Arr.AttrList;
|
||||||
case Function: return 0;
|
case Function: return Fun.AttrList;
|
||||||
case BlockPointer: return Cls.AttrList;
|
case BlockPointer: return Cls.AttrList;
|
||||||
case Paren: return 0;
|
case Paren: return 0;
|
||||||
}
|
}
|
||||||
|
@ -1032,37 +1043,40 @@ struct DeclaratorChunk {
|
||||||
/// getPointer - Return a DeclaratorChunk for a pointer.
|
/// getPointer - Return a DeclaratorChunk for a pointer.
|
||||||
///
|
///
|
||||||
static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc,
|
static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc,
|
||||||
AttributeList *AL) {
|
const ParsedAttributes &attrs) {
|
||||||
DeclaratorChunk I;
|
DeclaratorChunk I;
|
||||||
I.Kind = Pointer;
|
I.Kind = Pointer;
|
||||||
I.Loc = Loc;
|
I.Loc = Loc;
|
||||||
I.Ptr.TypeQuals = TypeQuals;
|
I.Ptr.TypeQuals = TypeQuals;
|
||||||
I.Ptr.AttrList = AL;
|
I.Ptr.AttrList = attrs.getList();
|
||||||
return I;
|
return I;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// getReference - Return a DeclaratorChunk for a reference.
|
/// getReference - Return a DeclaratorChunk for a reference.
|
||||||
///
|
///
|
||||||
static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc,
|
static DeclaratorChunk getReference(unsigned TypeQuals, SourceLocation Loc,
|
||||||
AttributeList *AL, bool lvalue) {
|
const ParsedAttributes &attrs,
|
||||||
|
bool lvalue) {
|
||||||
DeclaratorChunk I;
|
DeclaratorChunk I;
|
||||||
I.Kind = Reference;
|
I.Kind = Reference;
|
||||||
I.Loc = Loc;
|
I.Loc = Loc;
|
||||||
I.Ref.HasRestrict = (TypeQuals & DeclSpec::TQ_restrict) != 0;
|
I.Ref.HasRestrict = (TypeQuals & DeclSpec::TQ_restrict) != 0;
|
||||||
I.Ref.LValueRef = lvalue;
|
I.Ref.LValueRef = lvalue;
|
||||||
I.Ref.AttrList = AL;
|
I.Ref.AttrList = attrs.getList();
|
||||||
return I;
|
return I;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// getArray - Return a DeclaratorChunk for an array.
|
/// getArray - Return a DeclaratorChunk for an array.
|
||||||
///
|
///
|
||||||
static DeclaratorChunk getArray(unsigned TypeQuals, bool isStatic,
|
static DeclaratorChunk getArray(unsigned TypeQuals,
|
||||||
bool isStar, Expr *NumElts,
|
const ParsedAttributes &attrs,
|
||||||
|
bool isStatic, bool isStar, Expr *NumElts,
|
||||||
SourceLocation LBLoc, SourceLocation RBLoc) {
|
SourceLocation LBLoc, SourceLocation RBLoc) {
|
||||||
DeclaratorChunk I;
|
DeclaratorChunk I;
|
||||||
I.Kind = Array;
|
I.Kind = Array;
|
||||||
I.Loc = LBLoc;
|
I.Loc = LBLoc;
|
||||||
I.EndLoc = RBLoc;
|
I.EndLoc = RBLoc;
|
||||||
|
I.Arr.AttrList = attrs.getList();
|
||||||
I.Arr.TypeQuals = TypeQuals;
|
I.Arr.TypeQuals = TypeQuals;
|
||||||
I.Arr.hasStatic = isStatic;
|
I.Arr.hasStatic = isStatic;
|
||||||
I.Arr.isStar = isStar;
|
I.Arr.isStar = isStar;
|
||||||
|
@ -1072,7 +1086,8 @@ struct DeclaratorChunk {
|
||||||
|
|
||||||
/// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
|
/// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
|
||||||
/// "TheDeclarator" is the declarator that this will be added to.
|
/// "TheDeclarator" is the declarator that this will be added to.
|
||||||
static DeclaratorChunk getFunction(bool hasProto, bool isVariadic,
|
static DeclaratorChunk getFunction(const ParsedAttributes &attrs,
|
||||||
|
bool hasProto, bool isVariadic,
|
||||||
SourceLocation EllipsisLoc,
|
SourceLocation EllipsisLoc,
|
||||||
ParamInfo *ArgInfo, unsigned NumArgs,
|
ParamInfo *ArgInfo, unsigned NumArgs,
|
||||||
unsigned TypeQuals, bool hasExceptionSpec,
|
unsigned TypeQuals, bool hasExceptionSpec,
|
||||||
|
@ -1088,24 +1103,24 @@ struct DeclaratorChunk {
|
||||||
/// getBlockPointer - Return a DeclaratorChunk for a block.
|
/// getBlockPointer - Return a DeclaratorChunk for a block.
|
||||||
///
|
///
|
||||||
static DeclaratorChunk getBlockPointer(unsigned TypeQuals, SourceLocation Loc,
|
static DeclaratorChunk getBlockPointer(unsigned TypeQuals, SourceLocation Loc,
|
||||||
AttributeList *AL) {
|
const ParsedAttributes &attrs) {
|
||||||
DeclaratorChunk I;
|
DeclaratorChunk I;
|
||||||
I.Kind = BlockPointer;
|
I.Kind = BlockPointer;
|
||||||
I.Loc = Loc;
|
I.Loc = Loc;
|
||||||
I.Cls.TypeQuals = TypeQuals;
|
I.Cls.TypeQuals = TypeQuals;
|
||||||
I.Cls.AttrList = AL;
|
I.Cls.AttrList = attrs.getList();
|
||||||
return I;
|
return I;
|
||||||
}
|
}
|
||||||
|
|
||||||
static DeclaratorChunk getMemberPointer(const CXXScopeSpec &SS,
|
static DeclaratorChunk getMemberPointer(const CXXScopeSpec &SS,
|
||||||
unsigned TypeQuals,
|
unsigned TypeQuals,
|
||||||
SourceLocation Loc,
|
SourceLocation Loc,
|
||||||
AttributeList *AL) {
|
const ParsedAttributes &attrs) {
|
||||||
DeclaratorChunk I;
|
DeclaratorChunk I;
|
||||||
I.Kind = MemberPointer;
|
I.Kind = MemberPointer;
|
||||||
I.Loc = Loc;
|
I.Loc = Loc;
|
||||||
I.Mem.TypeQuals = TypeQuals;
|
I.Mem.TypeQuals = TypeQuals;
|
||||||
I.Mem.AttrList = AL;
|
I.Mem.AttrList = attrs.getList();
|
||||||
new (I.Mem.ScopeMem.Mem) CXXScopeSpec(SS);
|
new (I.Mem.ScopeMem.Mem) CXXScopeSpec(SS);
|
||||||
return I;
|
return I;
|
||||||
}
|
}
|
||||||
|
@ -1399,19 +1414,23 @@ public:
|
||||||
/// __attribute__((common,deprecated));
|
/// __attribute__((common,deprecated));
|
||||||
///
|
///
|
||||||
/// Also extends the range of the declarator.
|
/// Also extends the range of the declarator.
|
||||||
void AddAttributes(AttributeList *alist, SourceLocation LastLoc) {
|
void addAttributes(AttributeList *alist, SourceLocation LastLoc) {
|
||||||
AttrList = addAttributeLists(AttrList, alist);
|
AttrList = addAttributeLists(AttrList, alist);
|
||||||
|
|
||||||
if (!LastLoc.isInvalid())
|
if (!LastLoc.isInvalid())
|
||||||
SetRangeEnd(LastLoc);
|
SetRangeEnd(LastLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addAttributes(const ParsedAttributes &attrs) {
|
||||||
|
addAttributes(attrs.getList(), SourceLocation());
|
||||||
|
}
|
||||||
|
|
||||||
const AttributeList *getAttributes() const { return AttrList; }
|
const AttributeList *getAttributes() const { return AttrList; }
|
||||||
AttributeList *getAttributes() { return AttrList; }
|
AttributeList *getAttributes() { return AttrList; }
|
||||||
|
|
||||||
/// hasAttributes - do we contain any attributes?
|
/// hasAttributes - do we contain any attributes?
|
||||||
bool hasAttributes() const {
|
bool hasAttributes() const {
|
||||||
if (getAttributes() || getDeclSpec().getAttributes()) return true;
|
if (getAttributes() || getDeclSpec().hasAttributes()) return true;
|
||||||
for (unsigned i = 0, e = getNumTypeObjects(); i != e; ++i)
|
for (unsigned i = 0, e = getNumTypeObjects(); i != e; ++i)
|
||||||
if (getTypeObject(i).getAttrs())
|
if (getTypeObject(i).getAttrs())
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -1119,8 +1119,8 @@ QualType ASTContext::getObjCGCQualType(QualType T,
|
||||||
if (CanT.getObjCGCAttr() == GCAttr)
|
if (CanT.getObjCGCAttr() == GCAttr)
|
||||||
return T;
|
return T;
|
||||||
|
|
||||||
if (T->isPointerType()) {
|
if (const PointerType *ptr = T->getAs<PointerType>()) {
|
||||||
QualType Pointee = T->getAs<PointerType>()->getPointeeType();
|
QualType Pointee = ptr->getPointeeType();
|
||||||
if (Pointee->isAnyPointerType()) {
|
if (Pointee->isAnyPointerType()) {
|
||||||
QualType ResultType = getObjCGCQualType(Pointee, GCAttr);
|
QualType ResultType = getObjCGCQualType(Pointee, GCAttr);
|
||||||
return getPointerType(ResultType);
|
return getPointerType(ResultType);
|
||||||
|
|
|
@ -82,21 +82,20 @@ TypeResult Parser::ParseTypeName(SourceRange *Range) {
|
||||||
/// attributes are very simple in practice. Until we find a bug, I don't see
|
/// attributes are very simple in practice. Until we find a bug, I don't see
|
||||||
/// a pressing need to implement the 2 token lookahead.
|
/// a pressing need to implement the 2 token lookahead.
|
||||||
|
|
||||||
AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) {
|
void Parser::ParseGNUAttributes(ParsedAttributes &attrs,
|
||||||
|
SourceLocation *endLoc) {
|
||||||
assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!");
|
assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!");
|
||||||
|
|
||||||
AttributeList *CurrAttr = 0;
|
|
||||||
|
|
||||||
while (Tok.is(tok::kw___attribute)) {
|
while (Tok.is(tok::kw___attribute)) {
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
|
if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
|
||||||
"attribute")) {
|
"attribute")) {
|
||||||
SkipUntil(tok::r_paren, true); // skip until ) or ;
|
SkipUntil(tok::r_paren, true); // skip until ) or ;
|
||||||
return CurrAttr;
|
return;
|
||||||
}
|
}
|
||||||
if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "(")) {
|
if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "(")) {
|
||||||
SkipUntil(tok::r_paren, true); // skip until ) or ;
|
SkipUntil(tok::r_paren, true); // skip until ) or ;
|
||||||
return CurrAttr;
|
return;
|
||||||
}
|
}
|
||||||
// Parse the attribute-list. e.g. __attribute__(( weak, alias("__f") ))
|
// Parse the attribute-list. e.g. __attribute__(( weak, alias("__f") ))
|
||||||
while (Tok.is(tok::identifier) || isDeclarationSpecifier() ||
|
while (Tok.is(tok::identifier) || isDeclarationSpecifier() ||
|
||||||
|
@ -122,8 +121,8 @@ AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) {
|
||||||
if (Tok.is(tok::r_paren)) {
|
if (Tok.is(tok::r_paren)) {
|
||||||
// __attribute__(( mode(byte) ))
|
// __attribute__(( mode(byte) ))
|
||||||
ConsumeParen(); // ignore the right paren loc for now
|
ConsumeParen(); // ignore the right paren loc for now
|
||||||
CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
|
attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
|
||||||
ParmName, ParmLoc, 0, 0, CurrAttr);
|
ParmName, ParmLoc, 0, 0));
|
||||||
} else if (Tok.is(tok::comma)) {
|
} else if (Tok.is(tok::comma)) {
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
// __attribute__(( format(printf, 1, 2) ))
|
// __attribute__(( format(printf, 1, 2) ))
|
||||||
|
@ -146,10 +145,9 @@ AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) {
|
||||||
}
|
}
|
||||||
if (ArgExprsOk && Tok.is(tok::r_paren)) {
|
if (ArgExprsOk && Tok.is(tok::r_paren)) {
|
||||||
ConsumeParen(); // ignore the right paren loc for now
|
ConsumeParen(); // ignore the right paren loc for now
|
||||||
CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0,
|
attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0,
|
||||||
AttrNameLoc, ParmName, ParmLoc,
|
AttrNameLoc, ParmName, ParmLoc,
|
||||||
ArgExprs.take(), ArgExprs.size(),
|
ArgExprs.take(), ArgExprs.size()));
|
||||||
CurrAttr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { // not an identifier
|
} else { // not an identifier
|
||||||
|
@ -158,8 +156,8 @@ AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) {
|
||||||
// parse a possibly empty comma separated list of expressions
|
// parse a possibly empty comma separated list of expressions
|
||||||
// __attribute__(( nonnull() ))
|
// __attribute__(( nonnull() ))
|
||||||
ConsumeParen(); // ignore the right paren loc for now
|
ConsumeParen(); // ignore the right paren loc for now
|
||||||
CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
|
attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
|
||||||
0, SourceLocation(), 0, 0, CurrAttr);
|
0, SourceLocation(), 0, 0));
|
||||||
break;
|
break;
|
||||||
case tok::kw_char:
|
case tok::kw_char:
|
||||||
case tok::kw_wchar_t:
|
case tok::kw_wchar_t:
|
||||||
|
@ -174,10 +172,12 @@ AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) {
|
||||||
case tok::kw_float:
|
case tok::kw_float:
|
||||||
case tok::kw_double:
|
case tok::kw_double:
|
||||||
case tok::kw_void:
|
case tok::kw_void:
|
||||||
case tok::kw_typeof:
|
case tok::kw_typeof: {
|
||||||
CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
|
AttributeList *attr
|
||||||
0, SourceLocation(), 0, 0, CurrAttr);
|
= AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
|
||||||
if (CurrAttr->getKind() == AttributeList::AT_IBOutletCollection)
|
0, SourceLocation(), 0, 0);
|
||||||
|
attrs.add(attr);
|
||||||
|
if (attr->getKind() == AttributeList::AT_IBOutletCollection)
|
||||||
Diag(Tok, diag::err_iboutletcollection_builtintype);
|
Diag(Tok, diag::err_iboutletcollection_builtintype);
|
||||||
// If it's a builtin type name, eat it and expect a rparen
|
// If it's a builtin type name, eat it and expect a rparen
|
||||||
// __attribute__(( vec_type_hint(char) ))
|
// __attribute__(( vec_type_hint(char) ))
|
||||||
|
@ -185,6 +185,7 @@ AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) {
|
||||||
if (Tok.is(tok::r_paren))
|
if (Tok.is(tok::r_paren))
|
||||||
ConsumeParen();
|
ConsumeParen();
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
// __attribute__(( aligned(16) ))
|
// __attribute__(( aligned(16) ))
|
||||||
ExprVector ArgExprs(Actions);
|
ExprVector ArgExprs(Actions);
|
||||||
|
@ -207,17 +208,16 @@ AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) {
|
||||||
// Match the ')'.
|
// Match the ')'.
|
||||||
if (ArgExprsOk && Tok.is(tok::r_paren)) {
|
if (ArgExprsOk && Tok.is(tok::r_paren)) {
|
||||||
ConsumeParen(); // ignore the right paren loc for now
|
ConsumeParen(); // ignore the right paren loc for now
|
||||||
CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0,
|
attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0,
|
||||||
AttrNameLoc, 0, SourceLocation(), ArgExprs.take(),
|
AttrNameLoc, 0, SourceLocation(),
|
||||||
ArgExprs.size(),
|
ArgExprs.take(), ArgExprs.size()));
|
||||||
CurrAttr);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
|
attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
|
||||||
0, SourceLocation(), 0, 0, CurrAttr);
|
0, SourceLocation(), 0, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
|
if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
|
||||||
|
@ -226,10 +226,9 @@ AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) {
|
||||||
if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) {
|
if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) {
|
||||||
SkipUntil(tok::r_paren, false);
|
SkipUntil(tok::r_paren, false);
|
||||||
}
|
}
|
||||||
if (EndLoc)
|
if (endLoc)
|
||||||
*EndLoc = Loc;
|
*endLoc = Loc;
|
||||||
}
|
}
|
||||||
return CurrAttr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseMicrosoftDeclSpec - Parse an __declspec construct
|
/// ParseMicrosoftDeclSpec - Parse an __declspec construct
|
||||||
|
@ -241,14 +240,14 @@ AttributeList *Parser::ParseGNUAttributes(SourceLocation *EndLoc) {
|
||||||
/// extended-decl-modifier[opt]
|
/// extended-decl-modifier[opt]
|
||||||
/// extended-decl-modifier extended-decl-modifier-seq
|
/// extended-decl-modifier extended-decl-modifier-seq
|
||||||
|
|
||||||
AttributeList* Parser::ParseMicrosoftDeclSpec(AttributeList *CurrAttr) {
|
void Parser::ParseMicrosoftDeclSpec(ParsedAttributes &attrs) {
|
||||||
assert(Tok.is(tok::kw___declspec) && "Not a declspec!");
|
assert(Tok.is(tok::kw___declspec) && "Not a declspec!");
|
||||||
|
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
|
if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
|
||||||
"declspec")) {
|
"declspec")) {
|
||||||
SkipUntil(tok::r_paren, true); // skip until ) or ;
|
SkipUntil(tok::r_paren, true); // skip until ) or ;
|
||||||
return CurrAttr;
|
return;
|
||||||
}
|
}
|
||||||
while (Tok.getIdentifierInfo()) {
|
while (Tok.getIdentifierInfo()) {
|
||||||
IdentifierInfo *AttrName = Tok.getIdentifierInfo();
|
IdentifierInfo *AttrName = Tok.getIdentifierInfo();
|
||||||
|
@ -260,23 +259,22 @@ AttributeList* Parser::ParseMicrosoftDeclSpec(AttributeList *CurrAttr) {
|
||||||
ExprResult ArgExpr(ParseAssignmentExpression());
|
ExprResult ArgExpr(ParseAssignmentExpression());
|
||||||
if (!ArgExpr.isInvalid()) {
|
if (!ArgExpr.isInvalid()) {
|
||||||
Expr *ExprList = ArgExpr.take();
|
Expr *ExprList = ArgExpr.take();
|
||||||
CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
|
attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
|
||||||
SourceLocation(), &ExprList, 1,
|
SourceLocation(), &ExprList, 1, true));
|
||||||
CurrAttr, true);
|
|
||||||
}
|
}
|
||||||
if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
|
if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
|
||||||
SkipUntil(tok::r_paren, false);
|
SkipUntil(tok::r_paren, false);
|
||||||
} else {
|
} else {
|
||||||
CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
|
attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc,
|
||||||
0, SourceLocation(), 0, 0, CurrAttr, true);
|
0, SourceLocation(), 0, 0, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
|
if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
|
||||||
SkipUntil(tok::r_paren, false);
|
SkipUntil(tok::r_paren, false);
|
||||||
return CurrAttr;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AttributeList* Parser::ParseMicrosoftTypeAttributes(AttributeList *CurrAttr) {
|
void Parser::ParseMicrosoftTypeAttributes(ParsedAttributes &attrs) {
|
||||||
// Treat these like attributes
|
// Treat these like attributes
|
||||||
// FIXME: Allow Sema to distinguish between these and real attributes!
|
// FIXME: Allow Sema to distinguish between these and real attributes!
|
||||||
while (Tok.is(tok::kw___fastcall) || Tok.is(tok::kw___stdcall) ||
|
while (Tok.is(tok::kw___fastcall) || Tok.is(tok::kw___stdcall) ||
|
||||||
|
@ -287,21 +285,24 @@ AttributeList* Parser::ParseMicrosoftTypeAttributes(AttributeList *CurrAttr) {
|
||||||
if (Tok.is(tok::kw___ptr64) || Tok.is(tok::kw___w64))
|
if (Tok.is(tok::kw___ptr64) || Tok.is(tok::kw___w64))
|
||||||
// FIXME: Support these properly!
|
// FIXME: Support these properly!
|
||||||
continue;
|
continue;
|
||||||
CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
|
attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
|
||||||
SourceLocation(), 0, 0, CurrAttr, true);
|
SourceLocation(), 0, 0, true));
|
||||||
}
|
}
|
||||||
return CurrAttr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AttributeList* Parser::ParseBorlandTypeAttributes(AttributeList *CurrAttr) {
|
void Parser::ParseBorlandTypeAttributes(ParsedAttributes &attrs) {
|
||||||
// Treat these like attributes
|
// Treat these like attributes
|
||||||
while (Tok.is(tok::kw___pascal)) {
|
while (Tok.is(tok::kw___pascal)) {
|
||||||
IdentifierInfo *AttrName = Tok.getIdentifierInfo();
|
IdentifierInfo *AttrName = Tok.getIdentifierInfo();
|
||||||
SourceLocation AttrNameLoc = ConsumeToken();
|
SourceLocation AttrNameLoc = ConsumeToken();
|
||||||
CurrAttr = AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
|
attrs.add(AttrFactory.Create(AttrName, AttrNameLoc, 0, AttrNameLoc, 0,
|
||||||
SourceLocation(), 0, 0, CurrAttr, true);
|
SourceLocation(), 0, 0, true));
|
||||||
}
|
}
|
||||||
return CurrAttr;
|
}
|
||||||
|
|
||||||
|
void Parser::DiagnoseProhibitedAttributes(ParsedAttributesWithRange &attrs) {
|
||||||
|
Diag(attrs.Range.getBegin(), diag::err_attributes_not_allowed)
|
||||||
|
<< attrs.Range;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseDeclaration - Parse a full 'declaration', which consists of
|
/// ParseDeclaration - Parse a full 'declaration', which consists of
|
||||||
|
@ -323,49 +324,40 @@ AttributeList* Parser::ParseBorlandTypeAttributes(AttributeList *CurrAttr) {
|
||||||
Parser::DeclGroupPtrTy Parser::ParseDeclaration(StmtVector &Stmts,
|
Parser::DeclGroupPtrTy Parser::ParseDeclaration(StmtVector &Stmts,
|
||||||
unsigned Context,
|
unsigned Context,
|
||||||
SourceLocation &DeclEnd,
|
SourceLocation &DeclEnd,
|
||||||
CXX0XAttributeList Attr) {
|
ParsedAttributesWithRange &attrs) {
|
||||||
ParenBraceBracketBalancer BalancerRAIIObj(*this);
|
ParenBraceBracketBalancer BalancerRAIIObj(*this);
|
||||||
|
|
||||||
Decl *SingleDecl = 0;
|
Decl *SingleDecl = 0;
|
||||||
switch (Tok.getKind()) {
|
switch (Tok.getKind()) {
|
||||||
case tok::kw_template:
|
case tok::kw_template:
|
||||||
case tok::kw_export:
|
case tok::kw_export:
|
||||||
if (Attr.HasAttr)
|
ProhibitAttributes(attrs);
|
||||||
Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
|
|
||||||
<< Attr.Range;
|
|
||||||
SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd);
|
SingleDecl = ParseDeclarationStartingWithTemplate(Context, DeclEnd);
|
||||||
break;
|
break;
|
||||||
case tok::kw_inline:
|
case tok::kw_inline:
|
||||||
// Could be the start of an inline namespace. Allowed as an ext in C++03.
|
// Could be the start of an inline namespace. Allowed as an ext in C++03.
|
||||||
if (getLang().CPlusPlus && NextToken().is(tok::kw_namespace)) {
|
if (getLang().CPlusPlus && NextToken().is(tok::kw_namespace)) {
|
||||||
if (Attr.HasAttr)
|
ProhibitAttributes(attrs);
|
||||||
Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
|
|
||||||
<< Attr.Range;
|
|
||||||
SourceLocation InlineLoc = ConsumeToken();
|
SourceLocation InlineLoc = ConsumeToken();
|
||||||
SingleDecl = ParseNamespace(Context, DeclEnd, InlineLoc);
|
SingleDecl = ParseNamespace(Context, DeclEnd, InlineLoc);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return ParseSimpleDeclaration(Stmts, Context, DeclEnd, Attr.AttrList,
|
return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs,
|
||||||
true);
|
true);
|
||||||
case tok::kw_namespace:
|
case tok::kw_namespace:
|
||||||
if (Attr.HasAttr)
|
ProhibitAttributes(attrs);
|
||||||
Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
|
|
||||||
<< Attr.Range;
|
|
||||||
SingleDecl = ParseNamespace(Context, DeclEnd);
|
SingleDecl = ParseNamespace(Context, DeclEnd);
|
||||||
break;
|
break;
|
||||||
case tok::kw_using:
|
case tok::kw_using:
|
||||||
SingleDecl = ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
|
SingleDecl = ParseUsingDirectiveOrDeclaration(Context, ParsedTemplateInfo(),
|
||||||
DeclEnd, Attr);
|
DeclEnd, attrs);
|
||||||
break;
|
break;
|
||||||
case tok::kw_static_assert:
|
case tok::kw_static_assert:
|
||||||
if (Attr.HasAttr)
|
ProhibitAttributes(attrs);
|
||||||
Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
|
|
||||||
<< Attr.Range;
|
|
||||||
SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
|
SingleDecl = ParseStaticAssertDeclaration(DeclEnd);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return ParseSimpleDeclaration(Stmts, Context, DeclEnd, Attr.AttrList,
|
return ParseSimpleDeclaration(Stmts, Context, DeclEnd, attrs, true);
|
||||||
true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This routine returns a DeclGroup, if the thing we parsed only contains a
|
// This routine returns a DeclGroup, if the thing we parsed only contains a
|
||||||
|
@ -383,12 +375,11 @@ Parser::DeclGroupPtrTy Parser::ParseDeclaration(StmtVector &Stmts,
|
||||||
Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(StmtVector &Stmts,
|
Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(StmtVector &Stmts,
|
||||||
unsigned Context,
|
unsigned Context,
|
||||||
SourceLocation &DeclEnd,
|
SourceLocation &DeclEnd,
|
||||||
AttributeList *Attr,
|
ParsedAttributes &attrs,
|
||||||
bool RequireSemi) {
|
bool RequireSemi) {
|
||||||
// Parse the common declaration-specifiers piece.
|
// Parse the common declaration-specifiers piece.
|
||||||
ParsingDeclSpec DS(*this);
|
ParsingDeclSpec DS(*this);
|
||||||
if (Attr)
|
DS.takeAttributesFrom(attrs);
|
||||||
DS.AddAttributes(Attr);
|
|
||||||
ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none,
|
ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS_none,
|
||||||
getDeclSpecContextFromDeclaratorContext(Context));
|
getDeclSpecContextFromDeclaratorContext(Context));
|
||||||
StmtResult R = Actions.ActOnVlaStmt(DS);
|
StmtResult R = Actions.ActOnVlaStmt(DS);
|
||||||
|
@ -482,11 +473,7 @@ Parser::DeclGroupPtrTy Parser::ParseDeclGroup(ParsingDeclSpec &DS,
|
||||||
// short __attribute__((common)) var; -> declspec
|
// short __attribute__((common)) var; -> declspec
|
||||||
// short var __attribute__((common)); -> declarator
|
// short var __attribute__((common)); -> declarator
|
||||||
// short x, __attribute__((common)) var; -> declarator
|
// short x, __attribute__((common)) var; -> declarator
|
||||||
if (Tok.is(tok::kw___attribute)) {
|
MaybeParseGNUAttributes(D);
|
||||||
SourceLocation Loc;
|
|
||||||
AttributeList *AttrList = ParseGNUAttributes(&Loc);
|
|
||||||
D.AddAttributes(AttrList, Loc);
|
|
||||||
}
|
|
||||||
|
|
||||||
ParseDeclarator(D);
|
ParseDeclarator(D);
|
||||||
|
|
||||||
|
@ -555,12 +542,7 @@ Decl *Parser::ParseDeclarationAfterDeclarator(Declarator &D,
|
||||||
D.SetRangeEnd(Loc);
|
D.SetRangeEnd(Loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If attributes are present, parse them.
|
MaybeParseGNUAttributes(D);
|
||||||
if (Tok.is(tok::kw___attribute)) {
|
|
||||||
SourceLocation Loc;
|
|
||||||
AttributeList *AttrList = ParseGNUAttributes(&Loc);
|
|
||||||
D.AddAttributes(AttrList, Loc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inform the current actions module that we just parsed this declarator.
|
// Inform the current actions module that we just parsed this declarator.
|
||||||
Decl *ThisDecl = 0;
|
Decl *ThisDecl = 0;
|
||||||
|
@ -688,7 +670,7 @@ void Parser::ParseSpecifierQualifierList(DeclSpec &DS) {
|
||||||
// Validate declspec for type-name.
|
// Validate declspec for type-name.
|
||||||
unsigned Specs = DS.getParsedSpecifiers();
|
unsigned Specs = DS.getParsedSpecifiers();
|
||||||
if (Specs == DeclSpec::PQ_None && !DS.getNumProtocolQualifiers() &&
|
if (Specs == DeclSpec::PQ_None && !DS.getNumProtocolQualifiers() &&
|
||||||
!DS.getAttributes())
|
!DS.hasAttributes())
|
||||||
Diag(Tok, diag::err_typename_requires_specqual);
|
Diag(Tok, diag::err_typename_requires_specqual);
|
||||||
|
|
||||||
// Issue diagnostic and remove storage class if present.
|
// Issue diagnostic and remove storage class if present.
|
||||||
|
@ -1191,12 +1173,12 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
|
||||||
|
|
||||||
// GNU attributes support.
|
// GNU attributes support.
|
||||||
case tok::kw___attribute:
|
case tok::kw___attribute:
|
||||||
DS.AddAttributes(ParseGNUAttributes());
|
ParseGNUAttributes(DS.getAttributes());
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Microsoft declspec support.
|
// Microsoft declspec support.
|
||||||
case tok::kw___declspec:
|
case tok::kw___declspec:
|
||||||
DS.AddAttributes(ParseMicrosoftDeclSpec());
|
ParseMicrosoftDeclSpec(DS.getAttributes());
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Microsoft single token adornments.
|
// Microsoft single token adornments.
|
||||||
|
@ -1210,12 +1192,12 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
|
||||||
case tok::kw___stdcall:
|
case tok::kw___stdcall:
|
||||||
case tok::kw___fastcall:
|
case tok::kw___fastcall:
|
||||||
case tok::kw___thiscall:
|
case tok::kw___thiscall:
|
||||||
DS.AddAttributes(ParseMicrosoftTypeAttributes());
|
ParseMicrosoftTypeAttributes(DS.getAttributes());
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Borland single token adornments.
|
// Borland single token adornments.
|
||||||
case tok::kw___pascal:
|
case tok::kw___pascal:
|
||||||
DS.AddAttributes(ParseBorlandTypeAttributes());
|
ParseBorlandTypeAttributes(DS.getAttributes());
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// storage-class-specifier
|
// storage-class-specifier
|
||||||
|
@ -1692,11 +1674,11 @@ bool Parser::ParseOptionalTypeSpecifier(DeclSpec &DS, bool& isInvalid,
|
||||||
case tok::kw___stdcall:
|
case tok::kw___stdcall:
|
||||||
case tok::kw___fastcall:
|
case tok::kw___fastcall:
|
||||||
case tok::kw___thiscall:
|
case tok::kw___thiscall:
|
||||||
DS.AddAttributes(ParseMicrosoftTypeAttributes());
|
ParseMicrosoftTypeAttributes(DS.getAttributes());
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case tok::kw___pascal:
|
case tok::kw___pascal:
|
||||||
DS.AddAttributes(ParseBorlandTypeAttributes());
|
ParseBorlandTypeAttributes(DS.getAttributes());
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -1759,11 +1741,8 @@ ParseStructDeclaration(DeclSpec &DS, FieldCallback &Fields) {
|
||||||
FieldDeclarator DeclaratorInfo(DS);
|
FieldDeclarator DeclaratorInfo(DS);
|
||||||
|
|
||||||
// Attributes are only allowed here on successive declarators.
|
// Attributes are only allowed here on successive declarators.
|
||||||
if (!FirstDeclarator && Tok.is(tok::kw___attribute)) {
|
if (!FirstDeclarator)
|
||||||
SourceLocation Loc;
|
MaybeParseGNUAttributes(DeclaratorInfo.D);
|
||||||
AttributeList *AttrList = ParseGNUAttributes(&Loc);
|
|
||||||
DeclaratorInfo.D.AddAttributes(AttrList, Loc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// struct-declarator: declarator
|
/// struct-declarator: declarator
|
||||||
/// struct-declarator: declarator[opt] ':' constant-expression
|
/// struct-declarator: declarator[opt] ':' constant-expression
|
||||||
|
@ -1783,11 +1762,7 @@ ParseStructDeclaration(DeclSpec &DS, FieldCallback &Fields) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If attributes exist after the declarator, parse them.
|
// If attributes exist after the declarator, parse them.
|
||||||
if (Tok.is(tok::kw___attribute)) {
|
MaybeParseGNUAttributes(DeclaratorInfo.D);
|
||||||
SourceLocation Loc;
|
|
||||||
AttributeList *AttrList = ParseGNUAttributes(&Loc);
|
|
||||||
DeclaratorInfo.D.AddAttributes(AttrList, Loc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We're done with this declarator; invoke the callback.
|
// We're done with this declarator; invoke the callback.
|
||||||
Decl *D = Fields.invoke(DeclaratorInfo);
|
Decl *D = Fields.invoke(DeclaratorInfo);
|
||||||
|
@ -1908,15 +1883,14 @@ void Parser::ParseStructUnionBody(SourceLocation RecordLoc,
|
||||||
|
|
||||||
SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
|
SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
|
||||||
|
|
||||||
AttributeList *AttrList = 0;
|
ParsedAttributes attrs;
|
||||||
// If attributes exist after struct contents, parse them.
|
// If attributes exist after struct contents, parse them.
|
||||||
if (Tok.is(tok::kw___attribute))
|
MaybeParseGNUAttributes(attrs);
|
||||||
AttrList = ParseGNUAttributes();
|
|
||||||
|
|
||||||
Actions.ActOnFields(getCurScope(),
|
Actions.ActOnFields(getCurScope(),
|
||||||
RecordLoc, TagDecl, FieldDecls.data(), FieldDecls.size(),
|
RecordLoc, TagDecl, FieldDecls.data(), FieldDecls.size(),
|
||||||
LBraceLoc, RBraceLoc,
|
LBraceLoc, RBraceLoc,
|
||||||
AttrList);
|
attrs.getList());
|
||||||
StructScope.Exit();
|
StructScope.Exit();
|
||||||
Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, RBraceLoc);
|
Actions.ActOnTagFinishDefinition(getCurScope(), TagDecl, RBraceLoc);
|
||||||
}
|
}
|
||||||
|
@ -1958,10 +1932,9 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
|
||||||
ConsumeCodeCompletionToken();
|
ConsumeCodeCompletionToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
AttributeList *Attr = 0;
|
|
||||||
// If attributes exist after tag, parse them.
|
// If attributes exist after tag, parse them.
|
||||||
if (Tok.is(tok::kw___attribute))
|
ParsedAttributes attrs;
|
||||||
Attr = ParseGNUAttributes();
|
MaybeParseGNUAttributes(attrs);
|
||||||
|
|
||||||
CXXScopeSpec &SS = DS.getTypeSpecScope();
|
CXXScopeSpec &SS = DS.getTypeSpecScope();
|
||||||
if (getLang().CPlusPlus) {
|
if (getLang().CPlusPlus) {
|
||||||
|
@ -2102,7 +2075,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
|
||||||
const char *PrevSpec = 0;
|
const char *PrevSpec = 0;
|
||||||
unsigned DiagID;
|
unsigned DiagID;
|
||||||
Decl *TagDecl = Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK,
|
Decl *TagDecl = Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK,
|
||||||
StartLoc, SS, Name, NameLoc, Attr,
|
StartLoc, SS, Name, NameLoc, attrs.getList(),
|
||||||
AS,
|
AS,
|
||||||
MultiTemplateParamsArg(Actions),
|
MultiTemplateParamsArg(Actions),
|
||||||
Owned, IsDependent, IsScopedEnum,
|
Owned, IsDependent, IsScopedEnum,
|
||||||
|
@ -2185,9 +2158,8 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
|
||||||
SourceLocation IdentLoc = ConsumeToken();
|
SourceLocation IdentLoc = ConsumeToken();
|
||||||
|
|
||||||
// If attributes exist after the enumerator, parse them.
|
// If attributes exist after the enumerator, parse them.
|
||||||
AttributeList *Attr = 0;
|
ParsedAttributes attrs;
|
||||||
if (Tok.is(tok::kw___attribute))
|
MaybeParseGNUAttributes(attrs);
|
||||||
Attr = ParseGNUAttributes();
|
|
||||||
|
|
||||||
SourceLocation EqualLoc;
|
SourceLocation EqualLoc;
|
||||||
ExprResult AssignedVal;
|
ExprResult AssignedVal;
|
||||||
|
@ -2202,7 +2174,7 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
|
||||||
Decl *EnumConstDecl = Actions.ActOnEnumConstant(getCurScope(), EnumDecl,
|
Decl *EnumConstDecl = Actions.ActOnEnumConstant(getCurScope(), EnumDecl,
|
||||||
LastEnumConstDecl,
|
LastEnumConstDecl,
|
||||||
IdentLoc, Ident,
|
IdentLoc, Ident,
|
||||||
Attr, EqualLoc,
|
attrs.getList(), EqualLoc,
|
||||||
AssignedVal.release());
|
AssignedVal.release());
|
||||||
EnumConstantDecls.push_back(EnumConstDecl);
|
EnumConstantDecls.push_back(EnumConstDecl);
|
||||||
LastEnumConstDecl = EnumConstDecl;
|
LastEnumConstDecl = EnumConstDecl;
|
||||||
|
@ -2229,14 +2201,13 @@ void Parser::ParseEnumBody(SourceLocation StartLoc, Decl *EnumDecl) {
|
||||||
// Eat the }.
|
// Eat the }.
|
||||||
SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
|
SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc);
|
||||||
|
|
||||||
AttributeList *Attr = 0;
|
|
||||||
// If attributes exist after the identifier list, parse them.
|
// If attributes exist after the identifier list, parse them.
|
||||||
if (Tok.is(tok::kw___attribute))
|
ParsedAttributes attrs;
|
||||||
Attr = ParseGNUAttributes(); // FIXME: where do they do?
|
MaybeParseGNUAttributes(attrs);
|
||||||
|
|
||||||
Actions.ActOnEnumBody(StartLoc, LBraceLoc, RBraceLoc, EnumDecl,
|
Actions.ActOnEnumBody(StartLoc, LBraceLoc, RBraceLoc, EnumDecl,
|
||||||
EnumConstantDecls.data(), EnumConstantDecls.size(),
|
EnumConstantDecls.data(), EnumConstantDecls.size(),
|
||||||
getCurScope(), Attr);
|
getCurScope(), attrs.getList());
|
||||||
|
|
||||||
EnumScope.Exit();
|
EnumScope.Exit();
|
||||||
Actions.ActOnTagFinishDefinition(getCurScope(), EnumDecl, RBraceLoc);
|
Actions.ActOnTagFinishDefinition(getCurScope(), EnumDecl, RBraceLoc);
|
||||||
|
@ -2567,9 +2538,10 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS,
|
||||||
bool CXX0XAttributesAllowed) {
|
bool CXX0XAttributesAllowed) {
|
||||||
if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
|
if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
|
||||||
SourceLocation Loc = Tok.getLocation();
|
SourceLocation Loc = Tok.getLocation();
|
||||||
CXX0XAttributeList Attr = ParseCXX0XAttributes();
|
ParsedAttributesWithRange attrs;
|
||||||
|
ParseCXX0XAttributes(attrs);
|
||||||
if (CXX0XAttributesAllowed)
|
if (CXX0XAttributesAllowed)
|
||||||
DS.AddAttributes(Attr.AttrList);
|
DS.takeAttributesFrom(attrs);
|
||||||
else
|
else
|
||||||
Diag(Loc, diag::err_attributes_not_allowed);
|
Diag(Loc, diag::err_attributes_not_allowed);
|
||||||
}
|
}
|
||||||
|
@ -2605,19 +2577,19 @@ void Parser::ParseTypeQualifierListOpt(DeclSpec &DS,
|
||||||
case tok::kw___fastcall:
|
case tok::kw___fastcall:
|
||||||
case tok::kw___thiscall:
|
case tok::kw___thiscall:
|
||||||
if (VendorAttributesAllowed) {
|
if (VendorAttributesAllowed) {
|
||||||
DS.AddAttributes(ParseMicrosoftTypeAttributes());
|
ParseMicrosoftTypeAttributes(DS.getAttributes());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
goto DoneWithTypeQuals;
|
goto DoneWithTypeQuals;
|
||||||
case tok::kw___pascal:
|
case tok::kw___pascal:
|
||||||
if (VendorAttributesAllowed) {
|
if (VendorAttributesAllowed) {
|
||||||
DS.AddAttributes(ParseBorlandTypeAttributes());
|
ParseBorlandTypeAttributes(DS.getAttributes());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
goto DoneWithTypeQuals;
|
goto DoneWithTypeQuals;
|
||||||
case tok::kw___attribute:
|
case tok::kw___attribute:
|
||||||
if (VendorAttributesAllowed) {
|
if (VendorAttributesAllowed) {
|
||||||
DS.AddAttributes(ParseGNUAttributes());
|
ParseGNUAttributes(DS.getAttributes());
|
||||||
continue; // do *not* consume the next token!
|
continue; // do *not* consume the next token!
|
||||||
}
|
}
|
||||||
// otherwise, FALL THROUGH!
|
// otherwise, FALL THROUGH!
|
||||||
|
@ -2703,7 +2675,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
|
||||||
// Sema will have to catch (syntactically invalid) pointers into global
|
// Sema will have to catch (syntactically invalid) pointers into global
|
||||||
// scope. It has to catch pointers into namespace scope anyway.
|
// scope. It has to catch pointers into namespace scope anyway.
|
||||||
D.AddTypeInfo(DeclaratorChunk::getMemberPointer(SS,DS.getTypeQualifiers(),
|
D.AddTypeInfo(DeclaratorChunk::getMemberPointer(SS,DS.getTypeQualifiers(),
|
||||||
Loc, DS.TakeAttributes()),
|
Loc, DS.takeAttributes()),
|
||||||
/* Don't replace range end. */SourceLocation());
|
/* Don't replace range end. */SourceLocation());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2737,12 +2709,12 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
|
||||||
if (Kind == tok::star)
|
if (Kind == tok::star)
|
||||||
// Remember that we parsed a pointer type, and remember the type-quals.
|
// Remember that we parsed a pointer type, and remember the type-quals.
|
||||||
D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,
|
D.AddTypeInfo(DeclaratorChunk::getPointer(DS.getTypeQualifiers(), Loc,
|
||||||
DS.TakeAttributes()),
|
DS.takeAttributes()),
|
||||||
SourceLocation());
|
SourceLocation());
|
||||||
else
|
else
|
||||||
// Remember that we parsed a Block type, and remember the type-quals.
|
// Remember that we parsed a Block type, and remember the type-quals.
|
||||||
D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(),
|
D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(),
|
||||||
Loc, DS.TakeAttributes()),
|
Loc, DS.takeAttributes()),
|
||||||
SourceLocation());
|
SourceLocation());
|
||||||
} else {
|
} else {
|
||||||
// Is a reference
|
// Is a reference
|
||||||
|
@ -2794,7 +2766,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
|
||||||
|
|
||||||
// Remember that we parsed a reference type. It doesn't have type-quals.
|
// Remember that we parsed a reference type. It doesn't have type-quals.
|
||||||
D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc,
|
D.AddTypeInfo(DeclaratorChunk::getReference(DS.getTypeQualifiers(), Loc,
|
||||||
DS.TakeAttributes(),
|
DS.takeAttributes(),
|
||||||
Kind == tok::amp),
|
Kind == tok::amp),
|
||||||
SourceLocation());
|
SourceLocation());
|
||||||
}
|
}
|
||||||
|
@ -2946,12 +2918,8 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
|
||||||
"Haven't past the location of the identifier yet?");
|
"Haven't past the location of the identifier yet?");
|
||||||
|
|
||||||
// Don't parse attributes unless we have an identifier.
|
// Don't parse attributes unless we have an identifier.
|
||||||
if (D.getIdentifier() && getLang().CPlusPlus0x
|
if (D.getIdentifier())
|
||||||
&& isCXX0XAttributeSpecifier(true)) {
|
MaybeParseCXX0XAttributes(D);
|
||||||
SourceLocation AttrEndLoc;
|
|
||||||
CXX0XAttributeList Attr = ParseCXX0XAttributes();
|
|
||||||
D.AddAttributes(Attr.AttrList, AttrEndLoc);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (Tok.is(tok::l_paren)) {
|
if (Tok.is(tok::l_paren)) {
|
||||||
|
@ -2965,7 +2933,8 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
|
||||||
if (!isCXXFunctionDeclarator(warnIfAmbiguous))
|
if (!isCXXFunctionDeclarator(warnIfAmbiguous))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ParseFunctionDeclarator(ConsumeParen(), D);
|
ParsedAttributes attrs;
|
||||||
|
ParseFunctionDeclarator(ConsumeParen(), D, attrs);
|
||||||
} else if (Tok.is(tok::l_square)) {
|
} else if (Tok.is(tok::l_square)) {
|
||||||
ParseBracketDeclarator(D);
|
ParseBracketDeclarator(D);
|
||||||
} else {
|
} else {
|
||||||
|
@ -3001,10 +2970,10 @@ void Parser::ParseParenDeclarator(Declarator &D) {
|
||||||
// In either case, we need to eat any attributes to be able to determine what
|
// In either case, we need to eat any attributes to be able to determine what
|
||||||
// sort of paren this is.
|
// sort of paren this is.
|
||||||
//
|
//
|
||||||
AttributeList *AttrList = 0;
|
ParsedAttributes attrs;
|
||||||
bool RequiresArg = false;
|
bool RequiresArg = false;
|
||||||
if (Tok.is(tok::kw___attribute)) {
|
if (Tok.is(tok::kw___attribute)) {
|
||||||
AttrList = ParseGNUAttributes();
|
ParseGNUAttributes(attrs);
|
||||||
|
|
||||||
// We require that the argument list (if this is a non-grouping paren) be
|
// We require that the argument list (if this is a non-grouping paren) be
|
||||||
// present even if the attribute list was empty.
|
// present even if the attribute list was empty.
|
||||||
|
@ -3014,11 +2983,11 @@ void Parser::ParseParenDeclarator(Declarator &D) {
|
||||||
if (Tok.is(tok::kw___cdecl) || Tok.is(tok::kw___stdcall) ||
|
if (Tok.is(tok::kw___cdecl) || Tok.is(tok::kw___stdcall) ||
|
||||||
Tok.is(tok::kw___thiscall) || Tok.is(tok::kw___fastcall) ||
|
Tok.is(tok::kw___thiscall) || Tok.is(tok::kw___fastcall) ||
|
||||||
Tok.is(tok::kw___w64) || Tok.is(tok::kw___ptr64)) {
|
Tok.is(tok::kw___w64) || Tok.is(tok::kw___ptr64)) {
|
||||||
AttrList = ParseMicrosoftTypeAttributes(AttrList);
|
ParseMicrosoftTypeAttributes(attrs);
|
||||||
}
|
}
|
||||||
// Eat any Borland extensions.
|
// Eat any Borland extensions.
|
||||||
if (Tok.is(tok::kw___pascal))
|
if (Tok.is(tok::kw___pascal))
|
||||||
AttrList = ParseBorlandTypeAttributes(AttrList);
|
ParseBorlandTypeAttributes(attrs);
|
||||||
|
|
||||||
// If we haven't past the identifier yet (or where the identifier would be
|
// If we haven't past the identifier yet (or where the identifier would be
|
||||||
// stored, if this is an abstract declarator), then this is probably just
|
// stored, if this is an abstract declarator), then this is probably just
|
||||||
|
@ -3047,8 +3016,8 @@ void Parser::ParseParenDeclarator(Declarator &D) {
|
||||||
if (isGrouping) {
|
if (isGrouping) {
|
||||||
bool hadGroupingParens = D.hasGroupingParens();
|
bool hadGroupingParens = D.hasGroupingParens();
|
||||||
D.setGroupingParens(true);
|
D.setGroupingParens(true);
|
||||||
if (AttrList)
|
if (!attrs.empty())
|
||||||
D.AddAttributes(AttrList, SourceLocation());
|
D.addAttributes(attrs.getList(), SourceLocation());
|
||||||
|
|
||||||
ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
|
ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
|
||||||
// Match the ')'.
|
// Match the ')'.
|
||||||
|
@ -3065,7 +3034,7 @@ void Parser::ParseParenDeclarator(Declarator &D) {
|
||||||
// ParseFunctionDeclarator to handle of argument list.
|
// ParseFunctionDeclarator to handle of argument list.
|
||||||
D.SetIdentifier(0, Tok.getLocation());
|
D.SetIdentifier(0, Tok.getLocation());
|
||||||
|
|
||||||
ParseFunctionDeclarator(StartLoc, D, AttrList, RequiresArg);
|
ParseFunctionDeclarator(StartLoc, D, attrs, RequiresArg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseFunctionDeclarator - We are after the identifier and have parsed the
|
/// ParseFunctionDeclarator - We are after the identifier and have parsed the
|
||||||
|
@ -3101,7 +3070,7 @@ void Parser::ParseParenDeclarator(Declarator &D) {
|
||||||
/// and "exception-specification[opt]".
|
/// and "exception-specification[opt]".
|
||||||
///
|
///
|
||||||
void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
||||||
AttributeList *AttrList,
|
ParsedAttributes &attrs,
|
||||||
bool RequiresArg) {
|
bool RequiresArg) {
|
||||||
// lparen is already consumed!
|
// lparen is already consumed!
|
||||||
assert(D.isPastIdentifier() && "Should not call before identifier!");
|
assert(D.isPastIdentifier() && "Should not call before identifier!");
|
||||||
|
@ -3124,6 +3093,8 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
||||||
llvm::SmallVector<ParsedType, 2> Exceptions;
|
llvm::SmallVector<ParsedType, 2> Exceptions;
|
||||||
llvm::SmallVector<SourceRange, 2> ExceptionRanges;
|
llvm::SmallVector<SourceRange, 2> ExceptionRanges;
|
||||||
if (getLang().CPlusPlus) {
|
if (getLang().CPlusPlus) {
|
||||||
|
MaybeParseCXX0XAttributes(attrs);
|
||||||
|
|
||||||
ParseTypeQualifierListOpt(DS, false /*no attributes*/);
|
ParseTypeQualifierListOpt(DS, false /*no attributes*/);
|
||||||
if (!DS.getSourceRange().getEnd().isInvalid())
|
if (!DS.getSourceRange().getEnd().isInvalid())
|
||||||
EndLoc = DS.getSourceRange().getEnd();
|
EndLoc = DS.getSourceRange().getEnd();
|
||||||
|
@ -3146,7 +3117,8 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
||||||
|
|
||||||
// Remember that we parsed a function type, and remember the attributes.
|
// Remember that we parsed a function type, and remember the attributes.
|
||||||
// int() -> no prototype, no '...'.
|
// int() -> no prototype, no '...'.
|
||||||
D.AddTypeInfo(DeclaratorChunk::getFunction(/*prototype*/getLang().CPlusPlus,
|
D.AddTypeInfo(DeclaratorChunk::getFunction(attrs,
|
||||||
|
/*prototype*/getLang().CPlusPlus,
|
||||||
/*variadic*/ false,
|
/*variadic*/ false,
|
||||||
SourceLocation(),
|
SourceLocation(),
|
||||||
/*arglist*/ 0, 0,
|
/*arglist*/ 0, 0,
|
||||||
|
@ -3220,21 +3192,20 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip any Microsoft attributes before a param.
|
|
||||||
if (getLang().Microsoft && Tok.is(tok::l_square))
|
|
||||||
ParseMicrosoftAttributes();
|
|
||||||
|
|
||||||
SourceLocation DSStart = Tok.getLocation();
|
|
||||||
|
|
||||||
// Parse the declaration-specifiers.
|
// Parse the declaration-specifiers.
|
||||||
// Just use the ParsingDeclaration "scope" of the declarator.
|
// Just use the ParsingDeclaration "scope" of the declarator.
|
||||||
DeclSpec DS;
|
DeclSpec DS;
|
||||||
|
|
||||||
|
// Skip any Microsoft attributes before a param.
|
||||||
|
if (getLang().Microsoft && Tok.is(tok::l_square))
|
||||||
|
ParseMicrosoftAttributes(DS.getAttributes());
|
||||||
|
|
||||||
|
SourceLocation DSStart = Tok.getLocation();
|
||||||
|
|
||||||
// If the caller parsed attributes for the first argument, add them now.
|
// If the caller parsed attributes for the first argument, add them now.
|
||||||
if (AttrList) {
|
// Take them so that we only apply the attributes to the first parameter.
|
||||||
DS.AddAttributes(AttrList);
|
DS.takeAttributesFrom(attrs);
|
||||||
AttrList = 0; // Only apply the attributes to the first parameter.
|
|
||||||
}
|
|
||||||
ParseDeclarationSpecifiers(DS);
|
ParseDeclarationSpecifiers(DS);
|
||||||
|
|
||||||
// Parse the declarator. This is "PrototypeContext", because we must
|
// Parse the declarator. This is "PrototypeContext", because we must
|
||||||
|
@ -3243,11 +3214,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
||||||
ParseDeclarator(ParmDecl);
|
ParseDeclarator(ParmDecl);
|
||||||
|
|
||||||
// Parse GNU attributes, if present.
|
// Parse GNU attributes, if present.
|
||||||
if (Tok.is(tok::kw___attribute)) {
|
MaybeParseGNUAttributes(ParmDecl);
|
||||||
SourceLocation Loc;
|
|
||||||
AttributeList *AttrList = ParseGNUAttributes(&Loc);
|
|
||||||
ParmDecl.AddAttributes(AttrList, Loc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remember this parsed parameter in ParamInfo.
|
// Remember this parsed parameter in ParamInfo.
|
||||||
IdentifierInfo *ParmII = ParmDecl.getIdentifier();
|
IdentifierInfo *ParmII = ParmDecl.getIdentifier();
|
||||||
|
@ -3362,6 +3329,8 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
||||||
llvm::SmallVector<SourceRange, 2> ExceptionRanges;
|
llvm::SmallVector<SourceRange, 2> ExceptionRanges;
|
||||||
|
|
||||||
if (getLang().CPlusPlus) {
|
if (getLang().CPlusPlus) {
|
||||||
|
MaybeParseCXX0XAttributes(attrs);
|
||||||
|
|
||||||
// Parse cv-qualifier-seq[opt].
|
// Parse cv-qualifier-seq[opt].
|
||||||
ParseTypeQualifierListOpt(DS, false /*no attributes*/);
|
ParseTypeQualifierListOpt(DS, false /*no attributes*/);
|
||||||
if (!DS.getSourceRange().getEnd().isInvalid())
|
if (!DS.getSourceRange().getEnd().isInvalid())
|
||||||
|
@ -3390,7 +3359,8 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
||||||
PrototypeScope.Exit();
|
PrototypeScope.Exit();
|
||||||
|
|
||||||
// Remember that we parsed a function type, and remember the attributes.
|
// Remember that we parsed a function type, and remember the attributes.
|
||||||
D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/true, IsVariadic,
|
D.AddTypeInfo(DeclaratorChunk::getFunction(attrs,
|
||||||
|
/*proto*/true, IsVariadic,
|
||||||
EllipsisLoc,
|
EllipsisLoc,
|
||||||
ParamInfo.data(), ParamInfo.size(),
|
ParamInfo.data(), ParamInfo.size(),
|
||||||
DS.getTypeQualifiers(),
|
DS.getTypeQualifiers(),
|
||||||
|
@ -3470,7 +3440,8 @@ void Parser::ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,
|
||||||
// Remember that we parsed a function type, and remember the attributes. This
|
// Remember that we parsed a function type, and remember the attributes. This
|
||||||
// function type is always a K&R style function type, which is not varargs and
|
// function type is always a K&R style function type, which is not varargs and
|
||||||
// has no prototype.
|
// has no prototype.
|
||||||
D.AddTypeInfo(DeclaratorChunk::getFunction(/*proto*/false, /*varargs*/false,
|
D.AddTypeInfo(DeclaratorChunk::getFunction(ParsedAttributes(),
|
||||||
|
/*proto*/false, /*varargs*/false,
|
||||||
SourceLocation(),
|
SourceLocation(),
|
||||||
&ParamInfo[0], ParamInfo.size(),
|
&ParamInfo[0], ParamInfo.size(),
|
||||||
/*TypeQuals*/0,
|
/*TypeQuals*/0,
|
||||||
|
@ -3492,15 +3463,12 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
|
||||||
// This code does a fast path to handle some of the most obvious cases.
|
// This code does a fast path to handle some of the most obvious cases.
|
||||||
if (Tok.getKind() == tok::r_square) {
|
if (Tok.getKind() == tok::r_square) {
|
||||||
SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
|
SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
|
||||||
//FIXME: Use these
|
ParsedAttributes attrs;
|
||||||
CXX0XAttributeList Attr;
|
MaybeParseCXX0XAttributes(attrs);
|
||||||
if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier(true)) {
|
|
||||||
Attr = ParseCXX0XAttributes();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remember that we parsed the empty array type.
|
// Remember that we parsed the empty array type.
|
||||||
ExprResult NumElements;
|
ExprResult NumElements;
|
||||||
D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0,
|
D.AddTypeInfo(DeclaratorChunk::getArray(0, attrs, false, false, 0,
|
||||||
StartLoc, EndLoc),
|
StartLoc, EndLoc),
|
||||||
EndLoc);
|
EndLoc);
|
||||||
return;
|
return;
|
||||||
|
@ -3511,18 +3479,12 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
|
|
||||||
SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
|
SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
|
||||||
//FIXME: Use these
|
ParsedAttributes attrs;
|
||||||
CXX0XAttributeList Attr;
|
MaybeParseCXX0XAttributes(attrs);
|
||||||
if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
|
|
||||||
Attr = ParseCXX0XAttributes();
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there was an error parsing the assignment-expression, recover.
|
|
||||||
if (ExprRes.isInvalid())
|
|
||||||
ExprRes.release(); // Deallocate expr, just use [].
|
|
||||||
|
|
||||||
// Remember that we parsed a array type, and remember its features.
|
// Remember that we parsed a array type, and remember its features.
|
||||||
D.AddTypeInfo(DeclaratorChunk::getArray(0, false, 0, ExprRes.release(),
|
D.AddTypeInfo(DeclaratorChunk::getArray(0, attrs, false, 0,
|
||||||
|
ExprRes.release(),
|
||||||
StartLoc, EndLoc),
|
StartLoc, EndLoc),
|
||||||
EndLoc);
|
EndLoc);
|
||||||
return;
|
return;
|
||||||
|
@ -3583,14 +3545,11 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
|
||||||
|
|
||||||
SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
|
SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
|
||||||
|
|
||||||
//FIXME: Use these
|
ParsedAttributes attrs;
|
||||||
CXX0XAttributeList Attr;
|
MaybeParseCXX0XAttributes(attrs);
|
||||||
if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
|
|
||||||
Attr = ParseCXX0XAttributes();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remember that we parsed a array type, and remember its features.
|
// Remember that we parsed a array type, and remember its features.
|
||||||
D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(),
|
D.AddTypeInfo(DeclaratorChunk::getArray(DS.getTypeQualifiers(), attrs,
|
||||||
StaticLoc.isValid(), isStar,
|
StaticLoc.isValid(), isStar,
|
||||||
NumElements.release(),
|
NumElements.release(),
|
||||||
StartLoc, EndLoc),
|
StartLoc, EndLoc),
|
||||||
|
|
|
@ -69,16 +69,16 @@ Decl *Parser::ParseNamespace(unsigned Context,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read label attributes, if present.
|
// Read label attributes, if present.
|
||||||
AttributeList *AttrList = 0;
|
ParsedAttributes attrs;
|
||||||
if (Tok.is(tok::kw___attribute)) {
|
if (Tok.is(tok::kw___attribute)) {
|
||||||
attrTok = Tok;
|
attrTok = Tok;
|
||||||
|
|
||||||
// FIXME: save these somewhere.
|
// FIXME: save these somewhere.
|
||||||
AttrList = ParseGNUAttributes();
|
ParseGNUAttributes(attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Tok.is(tok::equal)) {
|
if (Tok.is(tok::equal)) {
|
||||||
if (AttrList)
|
if (!attrs.empty())
|
||||||
Diag(attrTok, diag::err_unexpected_namespace_attributes_alias);
|
Diag(attrTok, diag::err_unexpected_namespace_attributes_alias);
|
||||||
if (InlineLoc.isValid())
|
if (InlineLoc.isValid())
|
||||||
Diag(InlineLoc, diag::err_inline_namespace_alias)
|
Diag(InlineLoc, diag::err_inline_namespace_alias)
|
||||||
|
@ -112,18 +112,16 @@ Decl *Parser::ParseNamespace(unsigned Context,
|
||||||
|
|
||||||
Decl *NamespcDecl =
|
Decl *NamespcDecl =
|
||||||
Actions.ActOnStartNamespaceDef(getCurScope(), InlineLoc, IdentLoc, Ident,
|
Actions.ActOnStartNamespaceDef(getCurScope(), InlineLoc, IdentLoc, Ident,
|
||||||
LBrace, AttrList);
|
LBrace, attrs.getList());
|
||||||
|
|
||||||
PrettyDeclStackTraceEntry CrashInfo(Actions, NamespcDecl, NamespaceLoc,
|
PrettyDeclStackTraceEntry CrashInfo(Actions, NamespcDecl, NamespaceLoc,
|
||||||
"parsing namespace");
|
"parsing namespace");
|
||||||
|
|
||||||
while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
|
while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
|
||||||
CXX0XAttributeList Attr;
|
ParsedAttributesWithRange attrs;
|
||||||
if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
|
MaybeParseCXX0XAttributes(attrs);
|
||||||
Attr = ParseCXX0XAttributes();
|
MaybeParseMicrosoftAttributes(attrs);
|
||||||
if (getLang().Microsoft && Tok.is(tok::l_square))
|
ParseExternalDeclaration(attrs);
|
||||||
ParseMicrosoftAttributes();
|
|
||||||
ParseExternalDeclaration(Attr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Leave the namespace scope.
|
// Leave the namespace scope.
|
||||||
|
@ -201,34 +199,27 @@ Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, unsigned Context) {
|
||||||
Tok.is(tok::l_brace)? Tok.getLocation()
|
Tok.is(tok::l_brace)? Tok.getLocation()
|
||||||
: SourceLocation());
|
: SourceLocation());
|
||||||
|
|
||||||
CXX0XAttributeList Attr;
|
ParsedAttributesWithRange attrs;
|
||||||
if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
|
MaybeParseCXX0XAttributes(attrs);
|
||||||
Attr = ParseCXX0XAttributes();
|
MaybeParseMicrosoftAttributes(attrs);
|
||||||
|
|
||||||
if (getLang().Microsoft && Tok.is(tok::l_square))
|
|
||||||
ParseMicrosoftAttributes();
|
|
||||||
|
|
||||||
if (Tok.isNot(tok::l_brace)) {
|
if (Tok.isNot(tok::l_brace)) {
|
||||||
DS.setExternInLinkageSpec(true);
|
DS.setExternInLinkageSpec(true);
|
||||||
ParseExternalDeclaration(Attr, &DS);
|
ParseExternalDeclaration(attrs, &DS);
|
||||||
return Actions.ActOnFinishLinkageSpecification(getCurScope(), LinkageSpec,
|
return Actions.ActOnFinishLinkageSpecification(getCurScope(), LinkageSpec,
|
||||||
SourceLocation());
|
SourceLocation());
|
||||||
}
|
}
|
||||||
|
|
||||||
DS.abort();
|
DS.abort();
|
||||||
|
|
||||||
if (Attr.HasAttr)
|
ProhibitAttributes(attrs);
|
||||||
Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
|
|
||||||
<< Attr.Range;
|
|
||||||
|
|
||||||
SourceLocation LBrace = ConsumeBrace();
|
SourceLocation LBrace = ConsumeBrace();
|
||||||
while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
|
while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) {
|
||||||
CXX0XAttributeList Attr;
|
ParsedAttributesWithRange attrs;
|
||||||
if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
|
MaybeParseCXX0XAttributes(attrs);
|
||||||
Attr = ParseCXX0XAttributes();
|
MaybeParseMicrosoftAttributes(attrs);
|
||||||
if (getLang().Microsoft && Tok.is(tok::l_square))
|
ParseExternalDeclaration(attrs);
|
||||||
ParseMicrosoftAttributes();
|
|
||||||
ParseExternalDeclaration(Attr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
|
SourceLocation RBrace = MatchRHSPunctuation(tok::r_brace, LBrace);
|
||||||
|
@ -241,7 +232,7 @@ Decl *Parser::ParseLinkage(ParsingDeclSpec &DS, unsigned Context) {
|
||||||
Decl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
|
Decl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
|
||||||
const ParsedTemplateInfo &TemplateInfo,
|
const ParsedTemplateInfo &TemplateInfo,
|
||||||
SourceLocation &DeclEnd,
|
SourceLocation &DeclEnd,
|
||||||
CXX0XAttributeList Attr) {
|
ParsedAttributesWithRange &attrs) {
|
||||||
assert(Tok.is(tok::kw_using) && "Not using token");
|
assert(Tok.is(tok::kw_using) && "Not using token");
|
||||||
|
|
||||||
// Eat 'using'.
|
// Eat 'using'.
|
||||||
|
@ -261,15 +252,13 @@ Decl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
|
||||||
<< R << FixItHint::CreateRemoval(R);
|
<< R << FixItHint::CreateRemoval(R);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ParseUsingDirective(Context, UsingLoc, DeclEnd, Attr.AttrList);
|
return ParseUsingDirective(Context, UsingLoc, DeclEnd, attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, it must be a using-declaration.
|
// Otherwise, it must be a using-declaration.
|
||||||
|
|
||||||
// Using declarations can't have attributes.
|
// Using declarations can't have attributes.
|
||||||
if (Attr.HasAttr)
|
ProhibitAttributes(attrs);
|
||||||
Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
|
|
||||||
<< Attr.Range;
|
|
||||||
|
|
||||||
return ParseUsingDeclaration(Context, TemplateInfo, UsingLoc, DeclEnd);
|
return ParseUsingDeclaration(Context, TemplateInfo, UsingLoc, DeclEnd);
|
||||||
}
|
}
|
||||||
|
@ -287,7 +276,7 @@ Decl *Parser::ParseUsingDirectiveOrDeclaration(unsigned Context,
|
||||||
Decl *Parser::ParseUsingDirective(unsigned Context,
|
Decl *Parser::ParseUsingDirective(unsigned Context,
|
||||||
SourceLocation UsingLoc,
|
SourceLocation UsingLoc,
|
||||||
SourceLocation &DeclEnd,
|
SourceLocation &DeclEnd,
|
||||||
AttributeList *Attr) {
|
ParsedAttributes &attrs) {
|
||||||
assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token");
|
assert(Tok.is(tok::kw_namespace) && "Not 'namespace' token");
|
||||||
|
|
||||||
// Eat 'namespace'.
|
// Eat 'namespace'.
|
||||||
|
@ -322,7 +311,7 @@ Decl *Parser::ParseUsingDirective(unsigned Context,
|
||||||
bool GNUAttr = false;
|
bool GNUAttr = false;
|
||||||
if (Tok.is(tok::kw___attribute)) {
|
if (Tok.is(tok::kw___attribute)) {
|
||||||
GNUAttr = true;
|
GNUAttr = true;
|
||||||
Attr = addAttributeLists(Attr, ParseGNUAttributes());
|
ParseGNUAttributes(attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Eat ';'.
|
// Eat ';'.
|
||||||
|
@ -333,7 +322,7 @@ Decl *Parser::ParseUsingDirective(unsigned Context,
|
||||||
"", tok::semi);
|
"", tok::semi);
|
||||||
|
|
||||||
return Actions.ActOnUsingDirective(getCurScope(), UsingLoc, NamespcLoc, SS,
|
return Actions.ActOnUsingDirective(getCurScope(), UsingLoc, NamespcLoc, SS,
|
||||||
IdentLoc, NamespcName, Attr);
|
IdentLoc, NamespcName, attrs.getList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseUsingDeclaration - Parse C++ using-declaration. Assumes that
|
/// ParseUsingDeclaration - Parse C++ using-declaration. Assumes that
|
||||||
|
@ -391,14 +380,13 @@ Decl *Parser::ParseUsingDeclaration(unsigned Context,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse (optional) attributes (most likely GNU strong-using extension).
|
// Parse (optional) attributes (most likely GNU strong-using extension).
|
||||||
AttributeList *AttrList = 0;
|
ParsedAttributes attrs;
|
||||||
if (Tok.is(tok::kw___attribute))
|
MaybeParseGNUAttributes(attrs);
|
||||||
AttrList = ParseGNUAttributes();
|
|
||||||
|
|
||||||
// Eat ';'.
|
// Eat ';'.
|
||||||
DeclEnd = Tok.getLocation();
|
DeclEnd = Tok.getLocation();
|
||||||
ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
|
ExpectAndConsume(tok::semi, diag::err_expected_semi_after,
|
||||||
AttrList ? "attributes list" : "using declaration",
|
!attrs.empty() ? "attributes list" : "using declaration",
|
||||||
tok::semi);
|
tok::semi);
|
||||||
|
|
||||||
// Diagnose an attempt to declare a templated using-declaration.
|
// Diagnose an attempt to declare a templated using-declaration.
|
||||||
|
@ -414,7 +402,8 @@ Decl *Parser::ParseUsingDeclaration(unsigned Context,
|
||||||
}
|
}
|
||||||
|
|
||||||
return Actions.ActOnUsingDeclaration(getCurScope(), AS, true, UsingLoc, SS,
|
return Actions.ActOnUsingDeclaration(getCurScope(), AS, true, UsingLoc, SS,
|
||||||
Name, AttrList, IsTypeName, TypenameLoc);
|
Name, attrs.getList(),
|
||||||
|
IsTypeName, TypenameLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseStaticAssertDeclaration - Parse C++0x static_assert-declaratoion.
|
/// ParseStaticAssertDeclaration - Parse C++0x static_assert-declaratoion.
|
||||||
|
@ -685,20 +674,19 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
|
||||||
SuppressingAccessChecks = true;
|
SuppressingAccessChecks = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
AttributeList *AttrList = 0;
|
ParsedAttributes attrs;
|
||||||
// If attributes exist after tag, parse them.
|
// If attributes exist after tag, parse them.
|
||||||
if (Tok.is(tok::kw___attribute))
|
if (Tok.is(tok::kw___attribute))
|
||||||
AttrList = ParseGNUAttributes();
|
ParseGNUAttributes(attrs);
|
||||||
|
|
||||||
// If declspecs exist after tag, parse them.
|
// If declspecs exist after tag, parse them.
|
||||||
while (Tok.is(tok::kw___declspec))
|
while (Tok.is(tok::kw___declspec))
|
||||||
AttrList = ParseMicrosoftDeclSpec(AttrList);
|
ParseMicrosoftDeclSpec(attrs);
|
||||||
|
|
||||||
// If C++0x attributes exist here, parse them.
|
// If C++0x attributes exist here, parse them.
|
||||||
// FIXME: Are we consistent with the ordering of parsing of different
|
// FIXME: Are we consistent with the ordering of parsing of different
|
||||||
// styles of attributes?
|
// styles of attributes?
|
||||||
if (isCXX0XAttributeSpecifier())
|
MaybeParseCXX0XAttributes(attrs);
|
||||||
AttrList = addAttributeLists(AttrList, ParseCXX0XAttributes().AttrList);
|
|
||||||
|
|
||||||
if (TagType == DeclSpec::TST_struct && Tok.is(tok::kw___is_pod)) {
|
if (TagType == DeclSpec::TST_struct && Tok.is(tok::kw___is_pod)) {
|
||||||
// GNU libstdc++ 4.2 uses __is_pod as the name of a struct template, but
|
// GNU libstdc++ 4.2 uses __is_pod as the name of a struct template, but
|
||||||
|
@ -892,7 +880,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
|
||||||
TemplateId->LAngleLoc,
|
TemplateId->LAngleLoc,
|
||||||
TemplateArgsPtr,
|
TemplateArgsPtr,
|
||||||
TemplateId->RAngleLoc,
|
TemplateId->RAngleLoc,
|
||||||
AttrList);
|
attrs.getList());
|
||||||
|
|
||||||
// Friend template-ids are treated as references unless
|
// Friend template-ids are treated as references unless
|
||||||
// they have template headers, in which case they're ill-formed
|
// they have template headers, in which case they're ill-formed
|
||||||
|
@ -954,7 +942,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
|
||||||
TemplateId->LAngleLoc,
|
TemplateId->LAngleLoc,
|
||||||
TemplateArgsPtr,
|
TemplateArgsPtr,
|
||||||
TemplateId->RAngleLoc,
|
TemplateId->RAngleLoc,
|
||||||
AttrList,
|
attrs.getList(),
|
||||||
MultiTemplateParamsArg(Actions,
|
MultiTemplateParamsArg(Actions,
|
||||||
TemplateParams? &(*TemplateParams)[0] : 0,
|
TemplateParams? &(*TemplateParams)[0] : 0,
|
||||||
TemplateParams? TemplateParams->size() : 0));
|
TemplateParams? TemplateParams->size() : 0));
|
||||||
|
@ -972,13 +960,13 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
|
||||||
TemplateInfo.ExternLoc,
|
TemplateInfo.ExternLoc,
|
||||||
TemplateInfo.TemplateLoc,
|
TemplateInfo.TemplateLoc,
|
||||||
TagType, StartLoc, SS, Name,
|
TagType, StartLoc, SS, Name,
|
||||||
NameLoc, AttrList);
|
NameLoc, attrs.getList());
|
||||||
} else if (TUK == Sema::TUK_Friend &&
|
} else if (TUK == Sema::TUK_Friend &&
|
||||||
TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) {
|
TemplateInfo.Kind != ParsedTemplateInfo::NonTemplate) {
|
||||||
TagOrTempResult =
|
TagOrTempResult =
|
||||||
Actions.ActOnTemplatedFriendTag(getCurScope(), DS.getFriendSpecLoc(),
|
Actions.ActOnTemplatedFriendTag(getCurScope(), DS.getFriendSpecLoc(),
|
||||||
TagType, StartLoc, SS,
|
TagType, StartLoc, SS,
|
||||||
Name, NameLoc, AttrList,
|
Name, NameLoc, attrs.getList(),
|
||||||
MultiTemplateParamsArg(Actions,
|
MultiTemplateParamsArg(Actions,
|
||||||
TemplateParams? &(*TemplateParams)[0] : 0,
|
TemplateParams? &(*TemplateParams)[0] : 0,
|
||||||
TemplateParams? TemplateParams->size() : 0));
|
TemplateParams? TemplateParams->size() : 0));
|
||||||
|
@ -1000,7 +988,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
|
||||||
|
|
||||||
// Declaration or definition of a class type
|
// Declaration or definition of a class type
|
||||||
TagOrTempResult = Actions.ActOnTag(getCurScope(), TagType, TUK, StartLoc,
|
TagOrTempResult = Actions.ActOnTag(getCurScope(), TagType, TUK, StartLoc,
|
||||||
SS, Name, NameLoc, AttrList, AS,
|
SS, Name, NameLoc, attrs.getList(), AS,
|
||||||
TParams, Owned, IsDependent, false,
|
TParams, Owned, IsDependent, false,
|
||||||
false, clang::TypeResult());
|
false, clang::TypeResult());
|
||||||
|
|
||||||
|
@ -1364,19 +1352,15 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
|
||||||
// is a bitfield.
|
// is a bitfield.
|
||||||
ColonProtectionRAIIObject X(*this);
|
ColonProtectionRAIIObject X(*this);
|
||||||
|
|
||||||
CXX0XAttributeList AttrList;
|
ParsedAttributesWithRange attrs;
|
||||||
// Optional C++0x attribute-specifier
|
// Optional C++0x attribute-specifier
|
||||||
if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
|
MaybeParseCXX0XAttributes(attrs);
|
||||||
AttrList = ParseCXX0XAttributes();
|
MaybeParseMicrosoftAttributes(attrs);
|
||||||
if (getLang().Microsoft && Tok.is(tok::l_square))
|
|
||||||
ParseMicrosoftAttributes();
|
|
||||||
|
|
||||||
if (Tok.is(tok::kw_using)) {
|
if (Tok.is(tok::kw_using)) {
|
||||||
// FIXME: Check for template aliases
|
// FIXME: Check for template aliases
|
||||||
|
|
||||||
if (AttrList.HasAttr)
|
ProhibitAttributes(attrs);
|
||||||
Diag(AttrList.Range.getBegin(), diag::err_attributes_not_allowed)
|
|
||||||
<< AttrList.Range;
|
|
||||||
|
|
||||||
// Eat 'using'.
|
// Eat 'using'.
|
||||||
SourceLocation UsingLoc = ConsumeToken();
|
SourceLocation UsingLoc = ConsumeToken();
|
||||||
|
@ -1397,7 +1381,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
|
||||||
// decl-specifier-seq:
|
// decl-specifier-seq:
|
||||||
// Parse the common declaration-specifiers piece.
|
// Parse the common declaration-specifiers piece.
|
||||||
ParsingDeclSpec DS(*this, TemplateDiags);
|
ParsingDeclSpec DS(*this, TemplateDiags);
|
||||||
DS.AddAttributes(AttrList.AttrList);
|
DS.takeAttributesFrom(attrs);
|
||||||
ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC_class);
|
ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DSC_class);
|
||||||
|
|
||||||
MultiTemplateParamsArg TemplateParams(Actions,
|
MultiTemplateParamsArg TemplateParams(Actions,
|
||||||
|
@ -1430,11 +1414,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
|
||||||
}
|
}
|
||||||
|
|
||||||
// If attributes exist after the declarator, but before an '{', parse them.
|
// If attributes exist after the declarator, but before an '{', parse them.
|
||||||
if (Tok.is(tok::kw___attribute)) {
|
MaybeParseGNUAttributes(DeclaratorInfo);
|
||||||
SourceLocation Loc;
|
|
||||||
AttributeList *AttrList = ParseGNUAttributes(&Loc);
|
|
||||||
DeclaratorInfo.AddAttributes(AttrList, Loc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// function-definition:
|
// function-definition:
|
||||||
if (Tok.is(tok::l_brace)
|
if (Tok.is(tok::l_brace)
|
||||||
|
@ -1518,11 +1498,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
|
||||||
}
|
}
|
||||||
|
|
||||||
// If attributes exist after the declarator, parse them.
|
// If attributes exist after the declarator, parse them.
|
||||||
if (Tok.is(tok::kw___attribute)) {
|
MaybeParseGNUAttributes(DeclaratorInfo);
|
||||||
SourceLocation Loc;
|
|
||||||
AttributeList *AttrList = ParseGNUAttributes(&Loc);
|
|
||||||
DeclaratorInfo.AddAttributes(AttrList, Loc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: If Sema is the Action module and declarator is an instance field,
|
// NOTE: If Sema is the Action module and declarator is an instance field,
|
||||||
// this call will *not* return the created decl; It will return null.
|
// this call will *not* return the created decl; It will return null.
|
||||||
|
@ -1569,11 +1545,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS,
|
||||||
Deleted = false;
|
Deleted = false;
|
||||||
|
|
||||||
// Attributes are only allowed on the second declarator.
|
// Attributes are only allowed on the second declarator.
|
||||||
if (Tok.is(tok::kw___attribute)) {
|
MaybeParseGNUAttributes(DeclaratorInfo);
|
||||||
SourceLocation Loc;
|
|
||||||
AttributeList *AttrList = ParseGNUAttributes(&Loc);
|
|
||||||
DeclaratorInfo.AddAttributes(AttrList, Loc);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Tok.isNot(tok::colon))
|
if (Tok.isNot(tok::colon))
|
||||||
ParseDeclarator(DeclaratorInfo);
|
ParseDeclarator(DeclaratorInfo);
|
||||||
|
@ -1708,14 +1680,13 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc,
|
||||||
}
|
}
|
||||||
|
|
||||||
// If attributes exist after class contents, parse them.
|
// If attributes exist after class contents, parse them.
|
||||||
AttributeList *AttrList = 0;
|
ParsedAttributes attrs;
|
||||||
if (Tok.is(tok::kw___attribute))
|
MaybeParseGNUAttributes(attrs);
|
||||||
AttrList = ParseGNUAttributes();
|
|
||||||
|
|
||||||
if (TagDecl)
|
if (TagDecl)
|
||||||
Actions.ActOnFinishCXXMemberSpecification(getCurScope(), RecordLoc, TagDecl,
|
Actions.ActOnFinishCXXMemberSpecification(getCurScope(), RecordLoc, TagDecl,
|
||||||
LBraceLoc, RBraceLoc,
|
LBraceLoc, RBraceLoc,
|
||||||
AttrList);
|
attrs.getList());
|
||||||
|
|
||||||
// C++ 9.2p2: Within the class member-specification, the class is regarded as
|
// C++ 9.2p2: Within the class member-specification, the class is regarded as
|
||||||
// complete within function bodies, default arguments,
|
// complete within function bodies, default arguments,
|
||||||
|
@ -2043,12 +2014,12 @@ void Parser::PopParsingClass() {
|
||||||
/// '[' balanced-token-seq ']'
|
/// '[' balanced-token-seq ']'
|
||||||
/// '{' balanced-token-seq '}'
|
/// '{' balanced-token-seq '}'
|
||||||
/// any token but '(', ')', '[', ']', '{', or '}'
|
/// any token but '(', ')', '[', ']', '{', or '}'
|
||||||
CXX0XAttributeList Parser::ParseCXX0XAttributes(SourceLocation *EndLoc) {
|
void Parser::ParseCXX0XAttributes(ParsedAttributesWithRange &attrs,
|
||||||
|
SourceLocation *endLoc) {
|
||||||
assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square)
|
assert(Tok.is(tok::l_square) && NextToken().is(tok::l_square)
|
||||||
&& "Not a C++0x attribute list");
|
&& "Not a C++0x attribute list");
|
||||||
|
|
||||||
SourceLocation StartLoc = Tok.getLocation(), Loc;
|
SourceLocation StartLoc = Tok.getLocation(), Loc;
|
||||||
AttributeList *CurrAttr = 0;
|
|
||||||
|
|
||||||
ConsumeBracket();
|
ConsumeBracket();
|
||||||
ConsumeBracket();
|
ConsumeBracket();
|
||||||
|
@ -2104,9 +2075,8 @@ CXX0XAttributeList Parser::ParseCXX0XAttributes(SourceLocation *EndLoc) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
CurrAttr = AttrFactory.Create(AttrName, AttrLoc, 0, AttrLoc, 0,
|
attrs.add(AttrFactory.Create(AttrName, AttrLoc, 0, AttrLoc, 0,
|
||||||
SourceLocation(), 0, 0, CurrAttr, false,
|
SourceLocation(), 0, 0, false, true));
|
||||||
true);
|
|
||||||
AttrParsed = true;
|
AttrParsed = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2126,9 +2096,9 @@ CXX0XAttributeList Parser::ParseCXX0XAttributes(SourceLocation *EndLoc) {
|
||||||
|
|
||||||
ExprVector ArgExprs(Actions);
|
ExprVector ArgExprs(Actions);
|
||||||
ArgExprs.push_back(ArgExpr.release());
|
ArgExprs.push_back(ArgExpr.release());
|
||||||
CurrAttr = AttrFactory.Create(AttrName, AttrLoc, 0, AttrLoc,
|
attrs.add(AttrFactory.Create(AttrName, AttrLoc, 0, AttrLoc,
|
||||||
0, ParamLoc, ArgExprs.take(), 1, CurrAttr,
|
0, ParamLoc, ArgExprs.take(), 1,
|
||||||
false, true);
|
false, true));
|
||||||
|
|
||||||
AttrParsed = true;
|
AttrParsed = true;
|
||||||
break;
|
break;
|
||||||
|
@ -2153,8 +2123,7 @@ CXX0XAttributeList Parser::ParseCXX0XAttributes(SourceLocation *EndLoc) {
|
||||||
if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare))
|
if (ExpectAndConsume(tok::r_square, diag::err_expected_rsquare))
|
||||||
SkipUntil(tok::r_square, false);
|
SkipUntil(tok::r_square, false);
|
||||||
|
|
||||||
CXX0XAttributeList Attr (CurrAttr, SourceRange(StartLoc, Loc), true);
|
attrs.Range = SourceRange(StartLoc, Loc);
|
||||||
return Attr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseCXX0XAlignArgument - Parse the argument to C++0x's [[align]]
|
/// ParseCXX0XAlignArgument - Parse the argument to C++0x's [[align]]
|
||||||
|
@ -2185,12 +2154,14 @@ ExprResult Parser::ParseCXX0XAlignArgument(SourceLocation Start) {
|
||||||
/// [MS] ms-attribute-seq:
|
/// [MS] ms-attribute-seq:
|
||||||
/// ms-attribute[opt]
|
/// ms-attribute[opt]
|
||||||
/// ms-attribute ms-attribute-seq
|
/// ms-attribute ms-attribute-seq
|
||||||
void Parser::ParseMicrosoftAttributes() {
|
void Parser::ParseMicrosoftAttributes(ParsedAttributes &attrs,
|
||||||
|
SourceLocation *endLoc) {
|
||||||
assert(Tok.is(tok::l_square) && "Not a Microsoft attribute list");
|
assert(Tok.is(tok::l_square) && "Not a Microsoft attribute list");
|
||||||
|
|
||||||
while (Tok.is(tok::l_square)) {
|
while (Tok.is(tok::l_square)) {
|
||||||
ConsumeBracket();
|
ConsumeBracket();
|
||||||
SkipUntil(tok::r_square, true, true);
|
SkipUntil(tok::r_square, true, true);
|
||||||
|
if (endLoc) *endLoc = Tok.getLocation();
|
||||||
ExpectAndConsume(tok::r_square, diag::err_expected_rsquare);
|
ExpectAndConsume(tok::r_square, diag::err_expected_rsquare);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1522,7 +1522,8 @@ Parser::ParseParenExpression(ParenParseOption &ExprType, bool stopIfCastExpr,
|
||||||
|
|
||||||
if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) {
|
if (ExprType >= CompoundStmt && Tok.is(tok::l_brace)) {
|
||||||
Diag(Tok, diag::ext_gnu_statement_expr);
|
Diag(Tok, diag::ext_gnu_statement_expr);
|
||||||
StmtResult Stmt(ParseCompoundStatement(0, true));
|
ParsedAttributes attrs;
|
||||||
|
StmtResult Stmt(ParseCompoundStatement(attrs, true));
|
||||||
ExprType = CompoundStmt;
|
ExprType = CompoundStmt;
|
||||||
|
|
||||||
// If the substmt parsed correctly, build the AST node.
|
// If the substmt parsed correctly, build the AST node.
|
||||||
|
@ -1741,14 +1742,9 @@ void Parser::ParseBlockId() {
|
||||||
ParseDeclarator(DeclaratorInfo);
|
ParseDeclarator(DeclaratorInfo);
|
||||||
|
|
||||||
// We do this for: ^ __attribute__((noreturn)) {, as DS has the attributes.
|
// We do this for: ^ __attribute__((noreturn)) {, as DS has the attributes.
|
||||||
DeclaratorInfo.AddAttributes(DS.TakeAttributes(),
|
DeclaratorInfo.addAttributes(DS.takeAttributes());
|
||||||
SourceLocation());
|
|
||||||
|
|
||||||
if (Tok.is(tok::kw___attribute)) {
|
MaybeParseGNUAttributes(DeclaratorInfo);
|
||||||
SourceLocation Loc;
|
|
||||||
AttributeList *AttrList = ParseGNUAttributes(&Loc);
|
|
||||||
DeclaratorInfo.AddAttributes(AttrList, Loc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inform sema that we are starting a block.
|
// Inform sema that we are starting a block.
|
||||||
Actions.ActOnBlockArguments(DeclaratorInfo, getCurScope());
|
Actions.ActOnBlockArguments(DeclaratorInfo, getCurScope());
|
||||||
|
@ -1806,11 +1802,7 @@ ExprResult Parser::ParseBlockLiteralExpression() {
|
||||||
return ExprError();
|
return ExprError();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Tok.is(tok::kw___attribute)) {
|
MaybeParseGNUAttributes(ParamInfo);
|
||||||
SourceLocation Loc;
|
|
||||||
AttributeList *AttrList = ParseGNUAttributes(&Loc);
|
|
||||||
ParamInfo.AddAttributes(AttrList, Loc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inform sema that we are starting a block.
|
// Inform sema that we are starting a block.
|
||||||
Actions.ActOnBlockArguments(ParamInfo, getCurScope());
|
Actions.ActOnBlockArguments(ParamInfo, getCurScope());
|
||||||
|
@ -1818,7 +1810,8 @@ ExprResult Parser::ParseBlockLiteralExpression() {
|
||||||
ParseBlockId();
|
ParseBlockId();
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, pretend we saw (void).
|
// Otherwise, pretend we saw (void).
|
||||||
ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(true, false,
|
ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(ParsedAttributes(),
|
||||||
|
true, false,
|
||||||
SourceLocation(),
|
SourceLocation(),
|
||||||
0, 0, 0,
|
0, 0, 0,
|
||||||
false, SourceLocation(),
|
false, SourceLocation(),
|
||||||
|
@ -1827,11 +1820,7 @@ ExprResult Parser::ParseBlockLiteralExpression() {
|
||||||
ParamInfo),
|
ParamInfo),
|
||||||
CaretLoc);
|
CaretLoc);
|
||||||
|
|
||||||
if (Tok.is(tok::kw___attribute)) {
|
MaybeParseGNUAttributes(ParamInfo);
|
||||||
SourceLocation Loc;
|
|
||||||
AttributeList *AttrList = ParseGNUAttributes(&Loc);
|
|
||||||
ParamInfo.AddAttributes(AttrList, Loc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inform sema that we are starting a block.
|
// Inform sema that we are starting a block.
|
||||||
Actions.ActOnBlockArguments(ParamInfo, getCurScope());
|
Actions.ActOnBlockArguments(ParamInfo, getCurScope());
|
||||||
|
|
|
@ -810,11 +810,7 @@ bool Parser::ParseCXXCondition(ExprResult &ExprOut,
|
||||||
}
|
}
|
||||||
|
|
||||||
// If attributes are present, parse them.
|
// If attributes are present, parse them.
|
||||||
if (Tok.is(tok::kw___attribute)) {
|
MaybeParseGNUAttributes(DeclaratorInfo);
|
||||||
SourceLocation Loc;
|
|
||||||
AttributeList *AttrList = ParseGNUAttributes(&Loc);
|
|
||||||
DeclaratorInfo.AddAttributes(AttrList, Loc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Type-check the declaration itself.
|
// Type-check the declaration itself.
|
||||||
DeclResult Dcl = Actions.ActOnCXXConditionDeclaration(getCurScope(),
|
DeclResult Dcl = Actions.ActOnCXXConditionDeclaration(getCurScope(),
|
||||||
|
@ -1729,7 +1725,8 @@ void Parser::ParseDirectNewDeclarator(Declarator &D) {
|
||||||
first = false;
|
first = false;
|
||||||
|
|
||||||
SourceLocation RLoc = MatchRHSPunctuation(tok::r_square, LLoc);
|
SourceLocation RLoc = MatchRHSPunctuation(tok::r_square, LLoc);
|
||||||
D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false,
|
D.AddTypeInfo(DeclaratorChunk::getArray(0, ParsedAttributes(),
|
||||||
|
/*static=*/false, /*star=*/false,
|
||||||
Size.release(), LLoc, RLoc),
|
Size.release(), LLoc, RLoc),
|
||||||
RLoc);
|
RLoc);
|
||||||
|
|
||||||
|
|
|
@ -40,10 +40,14 @@ Decl *Parser::ParseObjCAtDirectives() {
|
||||||
switch (Tok.getObjCKeywordID()) {
|
switch (Tok.getObjCKeywordID()) {
|
||||||
case tok::objc_class:
|
case tok::objc_class:
|
||||||
return ParseObjCAtClassDeclaration(AtLoc);
|
return ParseObjCAtClassDeclaration(AtLoc);
|
||||||
case tok::objc_interface:
|
case tok::objc_interface: {
|
||||||
return ParseObjCAtInterfaceDeclaration(AtLoc);
|
ParsedAttributes attrs;
|
||||||
case tok::objc_protocol:
|
return ParseObjCAtInterfaceDeclaration(AtLoc, attrs);
|
||||||
return ParseObjCAtProtocolDeclaration(AtLoc);
|
}
|
||||||
|
case tok::objc_protocol: {
|
||||||
|
ParsedAttributes attrs;
|
||||||
|
return ParseObjCAtProtocolDeclaration(AtLoc, attrs);
|
||||||
|
}
|
||||||
case tok::objc_implementation:
|
case tok::objc_implementation:
|
||||||
return ParseObjCAtImplementationDeclaration(AtLoc);
|
return ParseObjCAtImplementationDeclaration(AtLoc);
|
||||||
case tok::objc_end:
|
case tok::objc_end:
|
||||||
|
@ -124,8 +128,8 @@ Decl *Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) {
|
||||||
/// __attribute__((unavailable))
|
/// __attribute__((unavailable))
|
||||||
/// __attribute__((objc_exception)) - used by NSException on 64-bit
|
/// __attribute__((objc_exception)) - used by NSException on 64-bit
|
||||||
///
|
///
|
||||||
Decl *Parser::ParseObjCAtInterfaceDeclaration(
|
Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation atLoc,
|
||||||
SourceLocation atLoc, AttributeList *attrList) {
|
ParsedAttributes &attrs) {
|
||||||
assert(Tok.isObjCAtKeyword(tok::objc_interface) &&
|
assert(Tok.isObjCAtKeyword(tok::objc_interface) &&
|
||||||
"ParseObjCAtInterfaceDeclaration(): Expected @interface");
|
"ParseObjCAtInterfaceDeclaration(): Expected @interface");
|
||||||
ConsumeToken(); // the "interface" identifier
|
ConsumeToken(); // the "interface" identifier
|
||||||
|
@ -178,7 +182,7 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(
|
||||||
LAngleLoc, EndProtoLoc))
|
LAngleLoc, EndProtoLoc))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (attrList) // categories don't support attributes.
|
if (!attrs.empty()) // categories don't support attributes.
|
||||||
Diag(Tok, diag::err_objc_no_attributes_on_category);
|
Diag(Tok, diag::err_objc_no_attributes_on_category);
|
||||||
|
|
||||||
Decl *CategoryType =
|
Decl *CategoryType =
|
||||||
|
@ -230,7 +234,7 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(
|
||||||
superClassId, superClassLoc,
|
superClassId, superClassLoc,
|
||||||
ProtocolRefs.data(), ProtocolRefs.size(),
|
ProtocolRefs.data(), ProtocolRefs.size(),
|
||||||
ProtocolLocs.data(),
|
ProtocolLocs.data(),
|
||||||
EndProtoLoc, attrList);
|
EndProtoLoc, attrs.getList());
|
||||||
|
|
||||||
if (Tok.is(tok::l_brace))
|
if (Tok.is(tok::l_brace))
|
||||||
ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, atLoc);
|
ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, atLoc);
|
||||||
|
@ -365,7 +369,8 @@ void Parser::ParseObjCInterfaceDeclList(Decl *interfaceDecl,
|
||||||
|
|
||||||
// FIXME: as the name implies, this rule allows function definitions.
|
// FIXME: as the name implies, this rule allows function definitions.
|
||||||
// We could pass a flag or check for functions during semantic analysis.
|
// We could pass a flag or check for functions during semantic analysis.
|
||||||
allTUVariables.push_back(ParseDeclarationOrFunctionDefinition(0));
|
ParsedAttributes attrs;
|
||||||
|
allTUVariables.push_back(ParseDeclarationOrFunctionDefinition(attrs));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -830,9 +835,9 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
|
||||||
ReturnType = ParseObjCTypeName(DSRet, false);
|
ReturnType = ParseObjCTypeName(DSRet, false);
|
||||||
|
|
||||||
// If attributes exist before the method, parse them.
|
// If attributes exist before the method, parse them.
|
||||||
AttributeList *MethodAttrs = 0;
|
ParsedAttributes attrs;
|
||||||
if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
|
if (getLang().ObjC2)
|
||||||
MethodAttrs = ParseGNUAttributes();
|
MaybeParseGNUAttributes(attrs);
|
||||||
|
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus,
|
Actions.CodeCompleteObjCMethodDecl(getCurScope(), mType == tok::minus,
|
||||||
|
@ -856,8 +861,8 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
|
||||||
llvm::SmallVector<DeclaratorChunk::ParamInfo, 8> CParamInfo;
|
llvm::SmallVector<DeclaratorChunk::ParamInfo, 8> CParamInfo;
|
||||||
if (Tok.isNot(tok::colon)) {
|
if (Tok.isNot(tok::colon)) {
|
||||||
// If attributes exist after the method, parse them.
|
// If attributes exist after the method, parse them.
|
||||||
if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
|
if (getLang().ObjC2)
|
||||||
MethodAttrs = addAttributeLists(MethodAttrs, ParseGNUAttributes());
|
MaybeParseGNUAttributes(attrs);
|
||||||
|
|
||||||
Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent);
|
Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent);
|
||||||
Decl *Result
|
Decl *Result
|
||||||
|
@ -865,7 +870,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
|
||||||
mType, IDecl, DSRet, ReturnType, Sel,
|
mType, IDecl, DSRet, ReturnType, Sel,
|
||||||
0,
|
0,
|
||||||
CParamInfo.data(), CParamInfo.size(),
|
CParamInfo.data(), CParamInfo.size(),
|
||||||
MethodAttrs, MethodImplKind);
|
attrs.getList(), MethodImplKind);
|
||||||
PD.complete(Result);
|
PD.complete(Result);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
@ -889,8 +894,11 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
|
||||||
|
|
||||||
// If attributes exist before the argument name, parse them.
|
// If attributes exist before the argument name, parse them.
|
||||||
ArgInfo.ArgAttrs = 0;
|
ArgInfo.ArgAttrs = 0;
|
||||||
if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
|
if (getLang().ObjC2) {
|
||||||
ArgInfo.ArgAttrs = ParseGNUAttributes();
|
ParsedAttributes attrs;
|
||||||
|
MaybeParseGNUAttributes(attrs);
|
||||||
|
ArgInfo.ArgAttrs = attrs.getList();
|
||||||
|
}
|
||||||
|
|
||||||
// Code completion for the next piece of the selector.
|
// Code completion for the next piece of the selector.
|
||||||
if (Tok.is(tok::code_completion)) {
|
if (Tok.is(tok::code_completion)) {
|
||||||
|
@ -964,8 +972,8 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
|
||||||
|
|
||||||
// FIXME: Add support for optional parameter list...
|
// FIXME: Add support for optional parameter list...
|
||||||
// If attributes exist after the method, parse them.
|
// If attributes exist after the method, parse them.
|
||||||
if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
|
if (getLang().ObjC2)
|
||||||
MethodAttrs = addAttributeLists(MethodAttrs, ParseGNUAttributes());
|
MaybeParseGNUAttributes(attrs);
|
||||||
|
|
||||||
if (KeyIdents.size() == 0)
|
if (KeyIdents.size() == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -976,7 +984,7 @@ Decl *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
|
||||||
mType, IDecl, DSRet, ReturnType, Sel,
|
mType, IDecl, DSRet, ReturnType, Sel,
|
||||||
&ArgInfos[0],
|
&ArgInfos[0],
|
||||||
CParamInfo.data(), CParamInfo.size(),
|
CParamInfo.data(), CParamInfo.size(),
|
||||||
MethodAttrs,
|
attrs.getList(),
|
||||||
MethodImplKind, isVariadic);
|
MethodImplKind, isVariadic);
|
||||||
PD.complete(Result);
|
PD.complete(Result);
|
||||||
return Result;
|
return Result;
|
||||||
|
@ -1184,7 +1192,7 @@ void Parser::ParseObjCClassInstanceVariables(Decl *interfaceDecl,
|
||||||
/// identifier-list ;": objc-interface-decl-list may not start with a
|
/// identifier-list ;": objc-interface-decl-list may not start with a
|
||||||
/// semicolon in the first alternative if objc-protocol-refs are omitted.
|
/// semicolon in the first alternative if objc-protocol-refs are omitted.
|
||||||
Decl *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
|
Decl *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
|
||||||
AttributeList *attrList) {
|
ParsedAttributes &attrs) {
|
||||||
assert(Tok.isObjCAtKeyword(tok::objc_protocol) &&
|
assert(Tok.isObjCAtKeyword(tok::objc_protocol) &&
|
||||||
"ParseObjCAtProtocolDeclaration(): Expected @protocol");
|
"ParseObjCAtProtocolDeclaration(): Expected @protocol");
|
||||||
ConsumeToken(); // the "protocol" identifier
|
ConsumeToken(); // the "protocol" identifier
|
||||||
|
@ -1206,7 +1214,7 @@ Decl *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
|
||||||
IdentifierLocPair ProtoInfo(protocolName, nameLoc);
|
IdentifierLocPair ProtoInfo(protocolName, nameLoc);
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
return Actions.ActOnForwardProtocolDeclaration(AtLoc, &ProtoInfo, 1,
|
return Actions.ActOnForwardProtocolDeclaration(AtLoc, &ProtoInfo, 1,
|
||||||
attrList);
|
attrs.getList());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Tok.is(tok::comma)) { // list of forward declarations.
|
if (Tok.is(tok::comma)) { // list of forward declarations.
|
||||||
|
@ -1235,7 +1243,7 @@ Decl *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
|
||||||
return Actions.ActOnForwardProtocolDeclaration(AtLoc,
|
return Actions.ActOnForwardProtocolDeclaration(AtLoc,
|
||||||
&ProtocolRefs[0],
|
&ProtocolRefs[0],
|
||||||
ProtocolRefs.size(),
|
ProtocolRefs.size(),
|
||||||
attrList);
|
attrs.getList());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Last, and definitely not least, parse a protocol declaration.
|
// Last, and definitely not least, parse a protocol declaration.
|
||||||
|
@ -1253,7 +1261,7 @@ Decl *Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc,
|
||||||
ProtocolRefs.data(),
|
ProtocolRefs.data(),
|
||||||
ProtocolRefs.size(),
|
ProtocolRefs.size(),
|
||||||
ProtocolLocs.data(),
|
ProtocolLocs.data(),
|
||||||
EndProtoLoc, attrList);
|
EndProtoLoc, attrs.getList());
|
||||||
ParseObjCInterfaceDeclList(ProtoType, tok::objc_protocol);
|
ParseObjCInterfaceDeclList(ProtoType, tok::objc_protocol);
|
||||||
return ProtoType;
|
return ProtoType;
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,10 +81,8 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement) {
|
||||||
|
|
||||||
ParenBraceBracketBalancer BalancerRAIIObj(*this);
|
ParenBraceBracketBalancer BalancerRAIIObj(*this);
|
||||||
|
|
||||||
CXX0XAttributeList Attr;
|
ParsedAttributesWithRange attrs;
|
||||||
if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
|
MaybeParseCXX0XAttributes(attrs);
|
||||||
Attr = ParseCXX0XAttributes();
|
|
||||||
AttributeList *AttrList = Attr.AttrList;
|
|
||||||
|
|
||||||
// Cases in this switch statement should fall through if the parser expects
|
// Cases in this switch statement should fall through if the parser expects
|
||||||
// the token to end in a semicolon (in which case SemiError should be set),
|
// the token to end in a semicolon (in which case SemiError should be set),
|
||||||
|
@ -106,7 +104,7 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement) {
|
||||||
case tok::identifier:
|
case tok::identifier:
|
||||||
if (NextToken().is(tok::colon)) { // C99 6.8.1: labeled-statement
|
if (NextToken().is(tok::colon)) { // C99 6.8.1: labeled-statement
|
||||||
// identifier ':' statement
|
// identifier ':' statement
|
||||||
return ParseLabeledStatement(AttrList);
|
return ParseLabeledStatement(attrs);
|
||||||
}
|
}
|
||||||
// PASS THROUGH.
|
// PASS THROUGH.
|
||||||
|
|
||||||
|
@ -114,7 +112,7 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement) {
|
||||||
if ((getLang().CPlusPlus || !OnlyStatement) && isDeclarationStatement()) {
|
if ((getLang().CPlusPlus || !OnlyStatement) && isDeclarationStatement()) {
|
||||||
SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
|
SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
|
||||||
DeclGroupPtrTy Decl = ParseDeclaration(Stmts, Declarator::BlockContext,
|
DeclGroupPtrTy Decl = ParseDeclaration(Stmts, Declarator::BlockContext,
|
||||||
DeclEnd, Attr);
|
DeclEnd, attrs);
|
||||||
return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);
|
return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,52 +139,50 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case tok::kw_case: // C99 6.8.1: labeled-statement
|
case tok::kw_case: // C99 6.8.1: labeled-statement
|
||||||
return ParseCaseStatement(AttrList);
|
return ParseCaseStatement(attrs);
|
||||||
case tok::kw_default: // C99 6.8.1: labeled-statement
|
case tok::kw_default: // C99 6.8.1: labeled-statement
|
||||||
return ParseDefaultStatement(AttrList);
|
return ParseDefaultStatement(attrs);
|
||||||
|
|
||||||
case tok::l_brace: // C99 6.8.2: compound-statement
|
case tok::l_brace: // C99 6.8.2: compound-statement
|
||||||
return ParseCompoundStatement(AttrList);
|
return ParseCompoundStatement(attrs);
|
||||||
case tok::semi: { // C99 6.8.3p3: expression[opt] ';'
|
case tok::semi: { // C99 6.8.3p3: expression[opt] ';'
|
||||||
bool LeadingEmptyMacro = Tok.hasLeadingEmptyMacro();
|
bool LeadingEmptyMacro = Tok.hasLeadingEmptyMacro();
|
||||||
return Actions.ActOnNullStmt(ConsumeToken(), LeadingEmptyMacro);
|
return Actions.ActOnNullStmt(ConsumeToken(), LeadingEmptyMacro);
|
||||||
}
|
}
|
||||||
|
|
||||||
case tok::kw_if: // C99 6.8.4.1: if-statement
|
case tok::kw_if: // C99 6.8.4.1: if-statement
|
||||||
return ParseIfStatement(AttrList);
|
return ParseIfStatement(attrs);
|
||||||
case tok::kw_switch: // C99 6.8.4.2: switch-statement
|
case tok::kw_switch: // C99 6.8.4.2: switch-statement
|
||||||
return ParseSwitchStatement(AttrList);
|
return ParseSwitchStatement(attrs);
|
||||||
|
|
||||||
case tok::kw_while: // C99 6.8.5.1: while-statement
|
case tok::kw_while: // C99 6.8.5.1: while-statement
|
||||||
return ParseWhileStatement(AttrList);
|
return ParseWhileStatement(attrs);
|
||||||
case tok::kw_do: // C99 6.8.5.2: do-statement
|
case tok::kw_do: // C99 6.8.5.2: do-statement
|
||||||
Res = ParseDoStatement(AttrList);
|
Res = ParseDoStatement(attrs);
|
||||||
SemiError = "do/while";
|
SemiError = "do/while";
|
||||||
break;
|
break;
|
||||||
case tok::kw_for: // C99 6.8.5.3: for-statement
|
case tok::kw_for: // C99 6.8.5.3: for-statement
|
||||||
return ParseForStatement(AttrList);
|
return ParseForStatement(attrs);
|
||||||
|
|
||||||
case tok::kw_goto: // C99 6.8.6.1: goto-statement
|
case tok::kw_goto: // C99 6.8.6.1: goto-statement
|
||||||
Res = ParseGotoStatement(AttrList);
|
Res = ParseGotoStatement(attrs);
|
||||||
SemiError = "goto";
|
SemiError = "goto";
|
||||||
break;
|
break;
|
||||||
case tok::kw_continue: // C99 6.8.6.2: continue-statement
|
case tok::kw_continue: // C99 6.8.6.2: continue-statement
|
||||||
Res = ParseContinueStatement(AttrList);
|
Res = ParseContinueStatement(attrs);
|
||||||
SemiError = "continue";
|
SemiError = "continue";
|
||||||
break;
|
break;
|
||||||
case tok::kw_break: // C99 6.8.6.3: break-statement
|
case tok::kw_break: // C99 6.8.6.3: break-statement
|
||||||
Res = ParseBreakStatement(AttrList);
|
Res = ParseBreakStatement(attrs);
|
||||||
SemiError = "break";
|
SemiError = "break";
|
||||||
break;
|
break;
|
||||||
case tok::kw_return: // C99 6.8.6.4: return-statement
|
case tok::kw_return: // C99 6.8.6.4: return-statement
|
||||||
Res = ParseReturnStatement(AttrList);
|
Res = ParseReturnStatement(attrs);
|
||||||
SemiError = "return";
|
SemiError = "return";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case tok::kw_asm: {
|
case tok::kw_asm: {
|
||||||
if (Attr.HasAttr)
|
ProhibitAttributes(attrs);
|
||||||
Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
|
|
||||||
<< Attr.Range;
|
|
||||||
bool msAsm = false;
|
bool msAsm = false;
|
||||||
Res = ParseAsmStatement(msAsm);
|
Res = ParseAsmStatement(msAsm);
|
||||||
Res = Actions.ActOnFinishFullStmt(Res.get());
|
Res = Actions.ActOnFinishFullStmt(Res.get());
|
||||||
|
@ -196,7 +192,7 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case tok::kw_try: // C++ 15: try-block
|
case tok::kw_try: // C++ 15: try-block
|
||||||
return ParseCXXTryBlock(AttrList);
|
return ParseCXXTryBlock(attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we reached this code, the statement must end in a semicolon.
|
// If we reached this code, the statement must end in a semicolon.
|
||||||
|
@ -220,7 +216,7 @@ Parser::ParseStatementOrDeclaration(StmtVector &Stmts, bool OnlyStatement) {
|
||||||
/// identifier ':' statement
|
/// identifier ':' statement
|
||||||
/// [GNU] identifier ':' attributes[opt] statement
|
/// [GNU] identifier ':' attributes[opt] statement
|
||||||
///
|
///
|
||||||
StmtResult Parser::ParseLabeledStatement(AttributeList *Attr) {
|
StmtResult Parser::ParseLabeledStatement(ParsedAttributes &attrs) {
|
||||||
assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() &&
|
assert(Tok.is(tok::identifier) && Tok.getIdentifierInfo() &&
|
||||||
"Not an identifier!");
|
"Not an identifier!");
|
||||||
|
|
||||||
|
@ -233,8 +229,7 @@ StmtResult Parser::ParseLabeledStatement(AttributeList *Attr) {
|
||||||
SourceLocation ColonLoc = ConsumeToken();
|
SourceLocation ColonLoc = ConsumeToken();
|
||||||
|
|
||||||
// Read label attributes, if present.
|
// Read label attributes, if present.
|
||||||
if (Tok.is(tok::kw___attribute))
|
MaybeParseGNUAttributes(attrs);
|
||||||
Attr = addAttributeLists(Attr, ParseGNUAttributes());
|
|
||||||
|
|
||||||
StmtResult SubStmt(ParseStatement());
|
StmtResult SubStmt(ParseStatement());
|
||||||
|
|
||||||
|
@ -244,7 +239,7 @@ StmtResult Parser::ParseLabeledStatement(AttributeList *Attr) {
|
||||||
|
|
||||||
return Actions.ActOnLabelStmt(IdentTok.getLocation(),
|
return Actions.ActOnLabelStmt(IdentTok.getLocation(),
|
||||||
IdentTok.getIdentifierInfo(),
|
IdentTok.getIdentifierInfo(),
|
||||||
ColonLoc, SubStmt.get(), Attr);
|
ColonLoc, SubStmt.get(), attrs.getList());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseCaseStatement
|
/// ParseCaseStatement
|
||||||
|
@ -252,7 +247,7 @@ StmtResult Parser::ParseLabeledStatement(AttributeList *Attr) {
|
||||||
/// 'case' constant-expression ':' statement
|
/// 'case' constant-expression ':' statement
|
||||||
/// [GNU] 'case' constant-expression '...' constant-expression ':' statement
|
/// [GNU] 'case' constant-expression '...' constant-expression ':' statement
|
||||||
///
|
///
|
||||||
StmtResult Parser::ParseCaseStatement(AttributeList *Attr) {
|
StmtResult Parser::ParseCaseStatement(ParsedAttributes &attrs) {
|
||||||
assert(Tok.is(tok::kw_case) && "Not a case stmt!");
|
assert(Tok.is(tok::kw_case) && "Not a case stmt!");
|
||||||
// FIXME: Use attributes?
|
// FIXME: Use attributes?
|
||||||
|
|
||||||
|
@ -380,7 +375,7 @@ StmtResult Parser::ParseCaseStatement(AttributeList *Attr) {
|
||||||
/// 'default' ':' statement
|
/// 'default' ':' statement
|
||||||
/// Note that this does not parse the 'statement' at the end.
|
/// Note that this does not parse the 'statement' at the end.
|
||||||
///
|
///
|
||||||
StmtResult Parser::ParseDefaultStatement(AttributeList *Attr) {
|
StmtResult Parser::ParseDefaultStatement(ParsedAttributes &attrs) {
|
||||||
//FIXME: Use attributes?
|
//FIXME: Use attributes?
|
||||||
|
|
||||||
assert(Tok.is(tok::kw_default) && "Not a default stmt!");
|
assert(Tok.is(tok::kw_default) && "Not a default stmt!");
|
||||||
|
@ -438,7 +433,7 @@ StmtResult Parser::ParseDefaultStatement(AttributeList *Attr) {
|
||||||
/// [OMP] barrier-directive
|
/// [OMP] barrier-directive
|
||||||
/// [OMP] flush-directive
|
/// [OMP] flush-directive
|
||||||
///
|
///
|
||||||
StmtResult Parser::ParseCompoundStatement(AttributeList *Attr,
|
StmtResult Parser::ParseCompoundStatement(ParsedAttributes &attrs,
|
||||||
bool isStmtExpr) {
|
bool isStmtExpr) {
|
||||||
//FIXME: Use attributes?
|
//FIXME: Use attributes?
|
||||||
|
|
||||||
|
@ -482,9 +477,8 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
|
||||||
while (Tok.is(tok::kw___extension__))
|
while (Tok.is(tok::kw___extension__))
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
|
|
||||||
CXX0XAttributeList Attr;
|
ParsedAttributesWithRange attrs;
|
||||||
if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
|
MaybeParseCXX0XAttributes(attrs);
|
||||||
Attr = ParseCXX0XAttributes();
|
|
||||||
|
|
||||||
// If this is the start of a declaration, parse it as such.
|
// If this is the start of a declaration, parse it as such.
|
||||||
if (isDeclarationStatement()) {
|
if (isDeclarationStatement()) {
|
||||||
|
@ -495,7 +489,7 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) {
|
||||||
SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
|
SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
|
||||||
DeclGroupPtrTy Res = ParseDeclaration(Stmts,
|
DeclGroupPtrTy Res = ParseDeclaration(Stmts,
|
||||||
Declarator::BlockContext, DeclEnd,
|
Declarator::BlockContext, DeclEnd,
|
||||||
Attr);
|
attrs);
|
||||||
R = Actions.ActOnDeclStmt(Res, DeclStart, DeclEnd);
|
R = Actions.ActOnDeclStmt(Res, DeclStart, DeclEnd);
|
||||||
} else {
|
} else {
|
||||||
// Otherwise this was a unary __extension__ marker.
|
// Otherwise this was a unary __extension__ marker.
|
||||||
|
@ -585,7 +579,7 @@ bool Parser::ParseParenExprOrCondition(ExprResult &ExprResult,
|
||||||
/// [C++] 'if' '(' condition ')' statement
|
/// [C++] 'if' '(' condition ')' statement
|
||||||
/// [C++] 'if' '(' condition ')' statement 'else' statement
|
/// [C++] 'if' '(' condition ')' statement 'else' statement
|
||||||
///
|
///
|
||||||
StmtResult Parser::ParseIfStatement(AttributeList *Attr) {
|
StmtResult Parser::ParseIfStatement(ParsedAttributes &attrs) {
|
||||||
// FIXME: Use attributes?
|
// FIXME: Use attributes?
|
||||||
|
|
||||||
assert(Tok.is(tok::kw_if) && "Not an if stmt!");
|
assert(Tok.is(tok::kw_if) && "Not an if stmt!");
|
||||||
|
@ -707,7 +701,7 @@ StmtResult Parser::ParseIfStatement(AttributeList *Attr) {
|
||||||
/// switch-statement:
|
/// switch-statement:
|
||||||
/// 'switch' '(' expression ')' statement
|
/// 'switch' '(' expression ')' statement
|
||||||
/// [C++] 'switch' '(' condition ')' statement
|
/// [C++] 'switch' '(' condition ')' statement
|
||||||
StmtResult Parser::ParseSwitchStatement(AttributeList *Attr) {
|
StmtResult Parser::ParseSwitchStatement(ParsedAttributes &attrs) {
|
||||||
// FIXME: Use attributes?
|
// FIXME: Use attributes?
|
||||||
|
|
||||||
assert(Tok.is(tok::kw_switch) && "Not a switch stmt!");
|
assert(Tok.is(tok::kw_switch) && "Not a switch stmt!");
|
||||||
|
@ -792,7 +786,7 @@ StmtResult Parser::ParseSwitchStatement(AttributeList *Attr) {
|
||||||
/// while-statement: [C99 6.8.5.1]
|
/// while-statement: [C99 6.8.5.1]
|
||||||
/// 'while' '(' expression ')' statement
|
/// 'while' '(' expression ')' statement
|
||||||
/// [C++] 'while' '(' condition ')' statement
|
/// [C++] 'while' '(' condition ')' statement
|
||||||
StmtResult Parser::ParseWhileStatement(AttributeList *Attr) {
|
StmtResult Parser::ParseWhileStatement(ParsedAttributes &attrs) {
|
||||||
// FIXME: Use attributes?
|
// FIXME: Use attributes?
|
||||||
|
|
||||||
assert(Tok.is(tok::kw_while) && "Not a while stmt!");
|
assert(Tok.is(tok::kw_while) && "Not a while stmt!");
|
||||||
|
@ -866,7 +860,7 @@ StmtResult Parser::ParseWhileStatement(AttributeList *Attr) {
|
||||||
/// do-statement: [C99 6.8.5.2]
|
/// do-statement: [C99 6.8.5.2]
|
||||||
/// 'do' statement 'while' '(' expression ')' ';'
|
/// 'do' statement 'while' '(' expression ')' ';'
|
||||||
/// Note: this lets the caller parse the end ';'.
|
/// Note: this lets the caller parse the end ';'.
|
||||||
StmtResult Parser::ParseDoStatement(AttributeList *Attr) {
|
StmtResult Parser::ParseDoStatement(ParsedAttributes &attrs) {
|
||||||
// FIXME: Use attributes?
|
// FIXME: Use attributes?
|
||||||
|
|
||||||
assert(Tok.is(tok::kw_do) && "Not a do stmt!");
|
assert(Tok.is(tok::kw_do) && "Not a do stmt!");
|
||||||
|
@ -942,7 +936,7 @@ StmtResult Parser::ParseDoStatement(AttributeList *Attr) {
|
||||||
/// [C++] expression-statement
|
/// [C++] expression-statement
|
||||||
/// [C++] simple-declaration
|
/// [C++] simple-declaration
|
||||||
///
|
///
|
||||||
StmtResult Parser::ParseForStatement(AttributeList *Attr) {
|
StmtResult Parser::ParseForStatement(ParsedAttributes &attrs) {
|
||||||
// FIXME: Use attributes?
|
// FIXME: Use attributes?
|
||||||
|
|
||||||
assert(Tok.is(tok::kw_for) && "Not a for stmt!");
|
assert(Tok.is(tok::kw_for) && "Not a for stmt!");
|
||||||
|
@ -1007,14 +1001,13 @@ StmtResult Parser::ParseForStatement(AttributeList *Attr) {
|
||||||
if (!C99orCXXorObjC) // Use of C99-style for loops in C90 mode?
|
if (!C99orCXXorObjC) // Use of C99-style for loops in C90 mode?
|
||||||
Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
|
Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
|
||||||
|
|
||||||
AttributeList *AttrList = 0;
|
ParsedAttributesWithRange attrs;
|
||||||
if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
|
MaybeParseCXX0XAttributes(attrs);
|
||||||
AttrList = ParseCXX0XAttributes().AttrList;
|
|
||||||
|
|
||||||
SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
|
SourceLocation DeclStart = Tok.getLocation(), DeclEnd;
|
||||||
StmtVector Stmts(Actions);
|
StmtVector Stmts(Actions);
|
||||||
DeclGroupPtrTy DG = ParseSimpleDeclaration(Stmts, Declarator::ForContext,
|
DeclGroupPtrTy DG = ParseSimpleDeclaration(Stmts, Declarator::ForContext,
|
||||||
DeclEnd, AttrList, false);
|
DeclEnd, attrs, false);
|
||||||
FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
|
FirstPart = Actions.ActOnDeclStmt(DG, DeclStart, Tok.getLocation());
|
||||||
|
|
||||||
if (Tok.is(tok::semi)) { // for (int x = 4;
|
if (Tok.is(tok::semi)) { // for (int x = 4;
|
||||||
|
@ -1141,7 +1134,7 @@ StmtResult Parser::ParseForStatement(AttributeList *Attr) {
|
||||||
///
|
///
|
||||||
/// Note: this lets the caller parse the end ';'.
|
/// Note: this lets the caller parse the end ';'.
|
||||||
///
|
///
|
||||||
StmtResult Parser::ParseGotoStatement(AttributeList *Attr) {
|
StmtResult Parser::ParseGotoStatement(ParsedAttributes &attrs) {
|
||||||
// FIXME: Use attributes?
|
// FIXME: Use attributes?
|
||||||
|
|
||||||
assert(Tok.is(tok::kw_goto) && "Not a goto stmt!");
|
assert(Tok.is(tok::kw_goto) && "Not a goto stmt!");
|
||||||
|
@ -1176,7 +1169,7 @@ StmtResult Parser::ParseGotoStatement(AttributeList *Attr) {
|
||||||
///
|
///
|
||||||
/// Note: this lets the caller parse the end ';'.
|
/// Note: this lets the caller parse the end ';'.
|
||||||
///
|
///
|
||||||
StmtResult Parser::ParseContinueStatement(AttributeList *Attr) {
|
StmtResult Parser::ParseContinueStatement(ParsedAttributes &attrs) {
|
||||||
// FIXME: Use attributes?
|
// FIXME: Use attributes?
|
||||||
|
|
||||||
SourceLocation ContinueLoc = ConsumeToken(); // eat the 'continue'.
|
SourceLocation ContinueLoc = ConsumeToken(); // eat the 'continue'.
|
||||||
|
@ -1189,7 +1182,7 @@ StmtResult Parser::ParseContinueStatement(AttributeList *Attr) {
|
||||||
///
|
///
|
||||||
/// Note: this lets the caller parse the end ';'.
|
/// Note: this lets the caller parse the end ';'.
|
||||||
///
|
///
|
||||||
StmtResult Parser::ParseBreakStatement(AttributeList *Attr) {
|
StmtResult Parser::ParseBreakStatement(ParsedAttributes &attrs) {
|
||||||
// FIXME: Use attributes?
|
// FIXME: Use attributes?
|
||||||
|
|
||||||
SourceLocation BreakLoc = ConsumeToken(); // eat the 'break'.
|
SourceLocation BreakLoc = ConsumeToken(); // eat the 'break'.
|
||||||
|
@ -1199,7 +1192,7 @@ StmtResult Parser::ParseBreakStatement(AttributeList *Attr) {
|
||||||
/// ParseReturnStatement
|
/// ParseReturnStatement
|
||||||
/// jump-statement:
|
/// jump-statement:
|
||||||
/// 'return' expression[opt] ';'
|
/// 'return' expression[opt] ';'
|
||||||
StmtResult Parser::ParseReturnStatement(AttributeList *Attr) {
|
StmtResult Parser::ParseReturnStatement(ParsedAttributes &attrs) {
|
||||||
// FIXME: Use attributes?
|
// FIXME: Use attributes?
|
||||||
|
|
||||||
assert(Tok.is(tok::kw_return) && "Not a return stmt!");
|
assert(Tok.is(tok::kw_return) && "Not a return stmt!");
|
||||||
|
@ -1521,7 +1514,7 @@ Decl *Parser::ParseFunctionTryBlock(Decl *Decl) {
|
||||||
/// try-block:
|
/// try-block:
|
||||||
/// 'try' compound-statement handler-seq
|
/// 'try' compound-statement handler-seq
|
||||||
///
|
///
|
||||||
StmtResult Parser::ParseCXXTryBlock(AttributeList* Attr) {
|
StmtResult Parser::ParseCXXTryBlock(ParsedAttributes &attrs) {
|
||||||
// FIXME: Add attributes?
|
// FIXME: Add attributes?
|
||||||
|
|
||||||
assert(Tok.is(tok::kw_try) && "Expected 'try'");
|
assert(Tok.is(tok::kw_try) && "Expected 'try'");
|
||||||
|
@ -1546,16 +1539,15 @@ StmtResult Parser::ParseCXXTryBlockCommon(SourceLocation TryLoc) {
|
||||||
if (Tok.isNot(tok::l_brace))
|
if (Tok.isNot(tok::l_brace))
|
||||||
return StmtError(Diag(Tok, diag::err_expected_lbrace));
|
return StmtError(Diag(Tok, diag::err_expected_lbrace));
|
||||||
// FIXME: Possible draft standard bug: attribute-specifier should be allowed?
|
// FIXME: Possible draft standard bug: attribute-specifier should be allowed?
|
||||||
StmtResult TryBlock(ParseCompoundStatement(0));
|
ParsedAttributesWithRange attrs;
|
||||||
|
StmtResult TryBlock(ParseCompoundStatement(attrs));
|
||||||
if (TryBlock.isInvalid())
|
if (TryBlock.isInvalid())
|
||||||
return move(TryBlock);
|
return move(TryBlock);
|
||||||
|
|
||||||
StmtVector Handlers(Actions);
|
StmtVector Handlers(Actions);
|
||||||
if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) {
|
MaybeParseCXX0XAttributes(attrs);
|
||||||
CXX0XAttributeList Attr = ParseCXX0XAttributes();
|
ProhibitAttributes(attrs);
|
||||||
Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
|
|
||||||
<< Attr.Range;
|
|
||||||
}
|
|
||||||
if (Tok.isNot(tok::kw_catch))
|
if (Tok.isNot(tok::kw_catch))
|
||||||
return StmtError(Diag(Tok, diag::err_expected_catch));
|
return StmtError(Diag(Tok, diag::err_expected_catch));
|
||||||
while (Tok.is(tok::kw_catch)) {
|
while (Tok.is(tok::kw_catch)) {
|
||||||
|
@ -1616,7 +1608,8 @@ StmtResult Parser::ParseCXXCatchBlock() {
|
||||||
return StmtError(Diag(Tok, diag::err_expected_lbrace));
|
return StmtError(Diag(Tok, diag::err_expected_lbrace));
|
||||||
|
|
||||||
// FIXME: Possible draft standard bug: attribute-specifier should be allowed?
|
// FIXME: Possible draft standard bug: attribute-specifier should be allowed?
|
||||||
StmtResult Block(ParseCompoundStatement(0));
|
ParsedAttributes attrs;
|
||||||
|
StmtResult Block(ParseCompoundStatement(attrs));
|
||||||
if (Block.isInvalid())
|
if (Block.isInvalid())
|
||||||
return move(Block);
|
return move(Block);
|
||||||
|
|
||||||
|
|
|
@ -196,20 +196,18 @@ Parser::ParseSingleDeclarationAfterTemplate(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
CXX0XAttributeList PrefixAttrs;
|
ParsedAttributesWithRange prefixAttrs;
|
||||||
if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
|
MaybeParseCXX0XAttributes(prefixAttrs);
|
||||||
PrefixAttrs = ParseCXX0XAttributes();
|
|
||||||
|
|
||||||
if (Tok.is(tok::kw_using))
|
if (Tok.is(tok::kw_using))
|
||||||
return ParseUsingDirectiveOrDeclaration(Context, TemplateInfo, DeclEnd,
|
return ParseUsingDirectiveOrDeclaration(Context, TemplateInfo, DeclEnd,
|
||||||
PrefixAttrs);
|
prefixAttrs);
|
||||||
|
|
||||||
// Parse the declaration specifiers, stealing the accumulated
|
// Parse the declaration specifiers, stealing the accumulated
|
||||||
// diagnostics from the template parameters.
|
// diagnostics from the template parameters.
|
||||||
ParsingDeclSpec DS(DiagsFromTParams);
|
ParsingDeclSpec DS(DiagsFromTParams);
|
||||||
|
|
||||||
if (PrefixAttrs.HasAttr)
|
DS.takeAttributesFrom(prefixAttrs);
|
||||||
DS.AddAttributes(PrefixAttrs.AttrList);
|
|
||||||
|
|
||||||
ParseDeclarationSpecifiers(DS, TemplateInfo, AS,
|
ParseDeclarationSpecifiers(DS, TemplateInfo, AS,
|
||||||
getDeclSpecContextFromDeclaratorContext(Context));
|
getDeclSpecContextFromDeclaratorContext(Context));
|
||||||
|
|
|
@ -1151,8 +1151,8 @@ Parser::TPResult Parser::TryParseParameterDeclarationClause() {
|
||||||
return TPResult::True(); // '...' is a sign of a function declarator.
|
return TPResult::True(); // '...' is a sign of a function declarator.
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getLang().Microsoft && Tok.is(tok::l_square))
|
ParsedAttributes attrs;
|
||||||
ParseMicrosoftAttributes();
|
MaybeParseMicrosoftAttributes(attrs);
|
||||||
|
|
||||||
// decl-specifier-seq
|
// decl-specifier-seq
|
||||||
TPResult TPR = TryParseDeclarationSpecifier();
|
TPResult TPR = TryParseDeclarationSpecifier();
|
||||||
|
|
|
@ -402,13 +402,11 @@ bool Parser::ParseTopLevelDecl(DeclGroupPtrTy &Result) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CXX0XAttributeList Attr;
|
ParsedAttributesWithRange attrs;
|
||||||
if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier())
|
MaybeParseCXX0XAttributes(attrs);
|
||||||
Attr = ParseCXX0XAttributes();
|
MaybeParseMicrosoftAttributes(attrs);
|
||||||
if (getLang().Microsoft && Tok.is(tok::l_square))
|
|
||||||
ParseMicrosoftAttributes();
|
|
||||||
|
|
||||||
Result = ParseExternalDeclaration(Attr);
|
Result = ParseExternalDeclaration(attrs);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,7 +447,8 @@ void Parser::ParseTranslationUnit() {
|
||||||
/// ';'
|
/// ';'
|
||||||
///
|
///
|
||||||
/// [C++0x/GNU] 'extern' 'template' declaration
|
/// [C++0x/GNU] 'extern' 'template' declaration
|
||||||
Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr,
|
Parser::DeclGroupPtrTy
|
||||||
|
Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
|
||||||
ParsingDeclSpec *DS) {
|
ParsingDeclSpec *DS) {
|
||||||
ParenBraceBracketBalancer BalancerRAIIObj(*this);
|
ParenBraceBracketBalancer BalancerRAIIObj(*this);
|
||||||
|
|
||||||
|
@ -474,12 +473,10 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr,
|
||||||
// __extension__ silences extension warnings in the subexpression.
|
// __extension__ silences extension warnings in the subexpression.
|
||||||
ExtensionRAIIObject O(Diags); // Use RAII to do this.
|
ExtensionRAIIObject O(Diags); // Use RAII to do this.
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
return ParseExternalDeclaration(Attr);
|
return ParseExternalDeclaration(attrs);
|
||||||
}
|
}
|
||||||
case tok::kw_asm: {
|
case tok::kw_asm: {
|
||||||
if (Attr.HasAttr)
|
ProhibitAttributes(attrs);
|
||||||
Diag(Attr.Range.getBegin(), diag::err_attributes_not_allowed)
|
|
||||||
<< Attr.Range;
|
|
||||||
|
|
||||||
ExprResult Result(ParseSimpleAsm());
|
ExprResult Result(ParseSimpleAsm());
|
||||||
|
|
||||||
|
@ -511,7 +508,7 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr,
|
||||||
ObjCImpDecl? Sema::PCC_ObjCImplementation
|
ObjCImpDecl? Sema::PCC_ObjCImplementation
|
||||||
: Sema::PCC_Namespace);
|
: Sema::PCC_Namespace);
|
||||||
ConsumeCodeCompletionToken();
|
ConsumeCodeCompletionToken();
|
||||||
return ParseExternalDeclaration(Attr);
|
return ParseExternalDeclaration(attrs);
|
||||||
case tok::kw_using:
|
case tok::kw_using:
|
||||||
case tok::kw_namespace:
|
case tok::kw_namespace:
|
||||||
case tok::kw_typedef:
|
case tok::kw_typedef:
|
||||||
|
@ -522,7 +519,7 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr,
|
||||||
{
|
{
|
||||||
SourceLocation DeclEnd;
|
SourceLocation DeclEnd;
|
||||||
StmtVector Stmts(Actions);
|
StmtVector Stmts(Actions);
|
||||||
return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, Attr);
|
return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
case tok::kw_static:
|
case tok::kw_static:
|
||||||
|
@ -533,7 +530,7 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr,
|
||||||
<< 0;
|
<< 0;
|
||||||
SourceLocation DeclEnd;
|
SourceLocation DeclEnd;
|
||||||
StmtVector Stmts(Actions);
|
StmtVector Stmts(Actions);
|
||||||
return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, Attr);
|
return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, attrs);
|
||||||
}
|
}
|
||||||
goto dont_know;
|
goto dont_know;
|
||||||
|
|
||||||
|
@ -545,7 +542,7 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr,
|
||||||
if (NextKind == tok::kw_namespace) {
|
if (NextKind == tok::kw_namespace) {
|
||||||
SourceLocation DeclEnd;
|
SourceLocation DeclEnd;
|
||||||
StmtVector Stmts(Actions);
|
StmtVector Stmts(Actions);
|
||||||
return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, Attr);
|
return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse (then ignore) 'inline' prior to a template instantiation. This is
|
// Parse (then ignore) 'inline' prior to a template instantiation. This is
|
||||||
|
@ -555,7 +552,7 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr,
|
||||||
<< 1;
|
<< 1;
|
||||||
SourceLocation DeclEnd;
|
SourceLocation DeclEnd;
|
||||||
StmtVector Stmts(Actions);
|
StmtVector Stmts(Actions);
|
||||||
return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, Attr);
|
return ParseDeclaration(Stmts, Declarator::FileContext, DeclEnd, attrs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
goto dont_know;
|
goto dont_know;
|
||||||
|
@ -575,10 +572,12 @@ Parser::DeclGroupPtrTy Parser::ParseExternalDeclaration(CXX0XAttributeList Attr,
|
||||||
default:
|
default:
|
||||||
dont_know:
|
dont_know:
|
||||||
// We can't tell whether this is a function-definition or declaration yet.
|
// We can't tell whether this is a function-definition or declaration yet.
|
||||||
if (DS)
|
if (DS) {
|
||||||
return ParseDeclarationOrFunctionDefinition(*DS, Attr.AttrList);
|
DS->takeAttributesFrom(attrs);
|
||||||
else
|
return ParseDeclarationOrFunctionDefinition(*DS);
|
||||||
return ParseDeclarationOrFunctionDefinition(Attr.AttrList);
|
} else {
|
||||||
|
return ParseDeclarationOrFunctionDefinition(attrs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This routine returns a DeclGroup, if the thing we parsed only contains a
|
// This routine returns a DeclGroup, if the thing we parsed only contains a
|
||||||
|
@ -632,12 +631,8 @@ bool Parser::isStartOfFunctionDefinition(const ParsingDeclarator &Declarator) {
|
||||||
///
|
///
|
||||||
Parser::DeclGroupPtrTy
|
Parser::DeclGroupPtrTy
|
||||||
Parser::ParseDeclarationOrFunctionDefinition(ParsingDeclSpec &DS,
|
Parser::ParseDeclarationOrFunctionDefinition(ParsingDeclSpec &DS,
|
||||||
AttributeList *Attr,
|
|
||||||
AccessSpecifier AS) {
|
AccessSpecifier AS) {
|
||||||
// Parse the common declaration-specifiers piece.
|
// Parse the common declaration-specifiers piece.
|
||||||
if (Attr)
|
|
||||||
DS.AddAttributes(Attr);
|
|
||||||
|
|
||||||
ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC_top_level);
|
ParseDeclarationSpecifiers(DS, ParsedTemplateInfo(), AS, DSC_top_level);
|
||||||
|
|
||||||
// C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
|
// C99 6.7.2.3p6: Handle "struct-or-union identifier;", "enum { X };"
|
||||||
|
@ -690,10 +685,11 @@ Parser::ParseDeclarationOrFunctionDefinition(ParsingDeclSpec &DS,
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser::DeclGroupPtrTy
|
Parser::DeclGroupPtrTy
|
||||||
Parser::ParseDeclarationOrFunctionDefinition(AttributeList *Attr,
|
Parser::ParseDeclarationOrFunctionDefinition(ParsedAttributes &attrs,
|
||||||
AccessSpecifier AS) {
|
AccessSpecifier AS) {
|
||||||
ParsingDeclSpec DS(*this);
|
ParsingDeclSpec DS(*this);
|
||||||
return ParseDeclarationOrFunctionDefinition(DS, Attr, AS);
|
DS.takeAttributesFrom(attrs);
|
||||||
|
return ParseDeclarationOrFunctionDefinition(DS, AS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseFunctionDefinition - We parsed and verified that the specified
|
/// ParseFunctionDefinition - We parsed and verified that the specified
|
||||||
|
@ -835,11 +831,7 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) {
|
||||||
// Handle the full declarator list.
|
// Handle the full declarator list.
|
||||||
while (1) {
|
while (1) {
|
||||||
// If attributes are present, parse them.
|
// If attributes are present, parse them.
|
||||||
if (Tok.is(tok::kw___attribute)) {
|
MaybeParseGNUAttributes(ParmDeclarator);
|
||||||
SourceLocation Loc;
|
|
||||||
AttributeList *AttrList = ParseGNUAttributes(&Loc);
|
|
||||||
ParmDeclarator.AddAttributes(AttrList, Loc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ask the actions module to compute the type for this declarator.
|
// Ask the actions module to compute the type for this declarator.
|
||||||
Decl *Param =
|
Decl *Param =
|
||||||
|
|
|
@ -21,10 +21,10 @@ AttributeList::AttributeList(llvm::BumpPtrAllocator &Alloc,
|
||||||
IdentifierInfo *sName, SourceLocation sLoc,
|
IdentifierInfo *sName, SourceLocation sLoc,
|
||||||
IdentifierInfo *pName, SourceLocation pLoc,
|
IdentifierInfo *pName, SourceLocation pLoc,
|
||||||
Expr **ExprList, unsigned numArgs,
|
Expr **ExprList, unsigned numArgs,
|
||||||
AttributeList *n, bool declspec, bool cxx0x)
|
bool declspec, bool cxx0x)
|
||||||
: AttrName(aName), AttrLoc(aLoc), ScopeName(sName),
|
: AttrName(aName), AttrLoc(aLoc), ScopeName(sName),
|
||||||
ScopeLoc(sLoc),
|
ScopeLoc(sLoc),
|
||||||
ParmName(pName), ParmLoc(pLoc), NumArgs(numArgs), Next(n),
|
ParmName(pName), ParmLoc(pLoc), NumArgs(numArgs), Next(0),
|
||||||
DeclspecAttribute(declspec), CXX0XAttribute(cxx0x), Invalid(false) {
|
DeclspecAttribute(declspec), CXX0XAttribute(cxx0x), Invalid(false) {
|
||||||
|
|
||||||
if (numArgs == 0)
|
if (numArgs == 0)
|
||||||
|
|
|
@ -46,7 +46,8 @@ void UnqualifiedId::setConstructorTemplateId(TemplateIdAnnotation *TemplateId) {
|
||||||
|
|
||||||
/// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
|
/// DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
|
||||||
/// "TheDeclarator" is the declarator that this will be added to.
|
/// "TheDeclarator" is the declarator that this will be added to.
|
||||||
DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
|
DeclaratorChunk DeclaratorChunk::getFunction(const ParsedAttributes &attrs,
|
||||||
|
bool hasProto, bool isVariadic,
|
||||||
SourceLocation EllipsisLoc,
|
SourceLocation EllipsisLoc,
|
||||||
ParamInfo *ArgInfo,
|
ParamInfo *ArgInfo,
|
||||||
unsigned NumArgs,
|
unsigned NumArgs,
|
||||||
|
@ -65,6 +66,7 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
|
||||||
I.Kind = Function;
|
I.Kind = Function;
|
||||||
I.Loc = LPLoc;
|
I.Loc = LPLoc;
|
||||||
I.EndLoc = RPLoc;
|
I.EndLoc = RPLoc;
|
||||||
|
I.Fun.AttrList = attrs.getList();
|
||||||
I.Fun.hasPrototype = hasProto;
|
I.Fun.hasPrototype = hasProto;
|
||||||
I.Fun.isVariadic = isVariadic;
|
I.Fun.isVariadic = isVariadic;
|
||||||
I.Fun.EllipsisLoc = EllipsisLoc.getRawEncoding();
|
I.Fun.EllipsisLoc = EllipsisLoc.getRawEncoding();
|
||||||
|
@ -483,7 +485,7 @@ void DeclSpec::SaveWrittenBuiltinSpecs() {
|
||||||
writtenBS.Type = getTypeSpecType();
|
writtenBS.Type = getTypeSpecType();
|
||||||
// Search the list of attributes for the presence of a mode attribute.
|
// Search the list of attributes for the presence of a mode attribute.
|
||||||
writtenBS.ModeAttr = false;
|
writtenBS.ModeAttr = false;
|
||||||
AttributeList* attrs = getAttributes();
|
AttributeList* attrs = getAttributes().getList();
|
||||||
while (attrs) {
|
while (attrs) {
|
||||||
if (attrs->getKind() == AttributeList::AT_mode) {
|
if (attrs->getKind() == AttributeList::AT_mode) {
|
||||||
writtenBS.ModeAttr = true;
|
writtenBS.ModeAttr = true;
|
||||||
|
|
|
@ -1642,7 +1642,7 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RecordDecl *Record = dyn_cast_or_null<RecordDecl>(Tag)) {
|
if (RecordDecl *Record = dyn_cast_or_null<RecordDecl>(Tag)) {
|
||||||
ProcessDeclAttributeList(S, Record, DS.getAttributes());
|
ProcessDeclAttributeList(S, Record, DS.getAttributes().getList());
|
||||||
|
|
||||||
if (!Record->getDeclName() && Record->isDefinition() &&
|
if (!Record->getDeclName() && Record->isDefinition() &&
|
||||||
DS.getStorageClassSpec() != DeclSpec::SCS_typedef) {
|
DS.getStorageClassSpec() != DeclSpec::SCS_typedef) {
|
||||||
|
@ -5553,7 +5553,8 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,
|
||||||
(void)Error; // Silence warning.
|
(void)Error; // Silence warning.
|
||||||
assert(!Error && "Error setting up implicit decl!");
|
assert(!Error && "Error setting up implicit decl!");
|
||||||
Declarator D(DS, Declarator::BlockContext);
|
Declarator D(DS, Declarator::BlockContext);
|
||||||
D.AddTypeInfo(DeclaratorChunk::getFunction(false, false, SourceLocation(), 0,
|
D.AddTypeInfo(DeclaratorChunk::getFunction(ParsedAttributes(),
|
||||||
|
false, false, SourceLocation(), 0,
|
||||||
0, 0, false, SourceLocation(),
|
0, 0, false, SourceLocation(),
|
||||||
false, 0,0,0, Loc, Loc, D),
|
false, 0,0,0, Loc, Loc, D),
|
||||||
SourceLocation());
|
SourceLocation());
|
||||||
|
|
|
@ -2808,7 +2808,7 @@ void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply decl attributes from the DeclSpec if present.
|
// Apply decl attributes from the DeclSpec if present.
|
||||||
if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes())
|
if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList())
|
||||||
ProcessDeclAttributeList(S, D, Attrs);
|
ProcessDeclAttributeList(S, D, Attrs);
|
||||||
|
|
||||||
// Walk the declarator structure, applying decl attributes that were in a type
|
// Walk the declarator structure, applying decl attributes that were in a type
|
||||||
|
|
|
@ -402,7 +402,7 @@ static QualType ConvertDeclSpecToType(Sema &TheSema,
|
||||||
|
|
||||||
// See if there are any attributes on the declspec that apply to the type (as
|
// See if there are any attributes on the declspec that apply to the type (as
|
||||||
// opposed to the decl).
|
// opposed to the decl).
|
||||||
if (const AttributeList *AL = DS.getAttributes())
|
if (const AttributeList *AL = DS.getAttributes().getList())
|
||||||
ProcessTypeAttributeList(TheSema, Result, true, AL, Delayed);
|
ProcessTypeAttributeList(TheSema, Result, true, AL, Delayed);
|
||||||
|
|
||||||
// Apply const/volatile/restrict qualifiers to T.
|
// Apply const/volatile/restrict qualifiers to T.
|
||||||
|
|
Loading…
Reference in New Issue