parent
a950e99dee
commit
f6591ca6d9
|
@ -717,6 +717,7 @@ private:
|
||||||
CXXScopeSpec SS;
|
CXXScopeSpec SS;
|
||||||
IdentifierInfo *Identifier;
|
IdentifierInfo *Identifier;
|
||||||
SourceLocation IdentifierLoc;
|
SourceLocation IdentifierLoc;
|
||||||
|
SourceRange Range;
|
||||||
|
|
||||||
/// Context - Where we are parsing this declarator.
|
/// Context - Where we are parsing this declarator.
|
||||||
///
|
///
|
||||||
|
@ -731,7 +732,7 @@ private:
|
||||||
/// DeclTypeInfo.back() will be the least closely bound.
|
/// DeclTypeInfo.back() will be the least closely bound.
|
||||||
llvm::SmallVector<DeclaratorChunk, 8> DeclTypeInfo;
|
llvm::SmallVector<DeclaratorChunk, 8> DeclTypeInfo;
|
||||||
|
|
||||||
// InvalidType - Set by Sema::GetTypeForDeclarator().
|
/// InvalidType - Set by Sema::GetTypeForDeclarator().
|
||||||
bool InvalidType : 1;
|
bool InvalidType : 1;
|
||||||
|
|
||||||
/// GroupingParens - Set by Parser::ParseParenDeclarator().
|
/// GroupingParens - Set by Parser::ParseParenDeclarator().
|
||||||
|
@ -757,13 +758,15 @@ private:
|
||||||
/// InlineParams - This is a local array used for the first function decl
|
/// InlineParams - This is a local array used for the first function decl
|
||||||
/// chunk to avoid going to the heap for the common case when we have one
|
/// chunk to avoid going to the heap for the common case when we have one
|
||||||
/// function chunk in the declarator.
|
/// function chunk in the declarator.
|
||||||
friend class DeclaratorChunk;
|
|
||||||
DeclaratorChunk::ParamInfo InlineParams[16];
|
DeclaratorChunk::ParamInfo InlineParams[16];
|
||||||
bool InlineParamsUsed;
|
bool InlineParamsUsed;
|
||||||
|
|
||||||
|
friend class DeclaratorChunk;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Declarator(const DeclSpec &ds, TheContext C)
|
Declarator(const DeclSpec &ds, TheContext C)
|
||||||
: DS(ds), Identifier(0), Context(C), Kind(DK_Abstract),
|
: DS(ds), Identifier(0), Range(ds.getSourceRange()), Context(C),
|
||||||
|
Kind(DK_Abstract),
|
||||||
InvalidType(DS.getTypeSpecType() == DeclSpec::TST_error),
|
InvalidType(DS.getTypeSpecType() == DeclSpec::TST_error),
|
||||||
GroupingParens(false), AttrList(0), AsmLabel(0), Type(0),
|
GroupingParens(false), AttrList(0), AsmLabel(0), Type(0),
|
||||||
InlineParamsUsed(false) {
|
InlineParamsUsed(false) {
|
||||||
|
@ -792,14 +795,38 @@ public:
|
||||||
TheContext getContext() const { return Context; }
|
TheContext getContext() const { return Context; }
|
||||||
DeclaratorKind getKind() const { return Kind; }
|
DeclaratorKind getKind() const { return Kind; }
|
||||||
|
|
||||||
// getSourceRange - FIXME: This should be implemented.
|
/// getSourceRange - Get the source range that spans this declarator.
|
||||||
const SourceRange getSourceRange() const { return SourceRange(); }
|
const SourceRange &getSourceRange() const { return Range; }
|
||||||
|
|
||||||
|
void SetSourceRange(SourceRange R) { Range = R; }
|
||||||
|
/// SetRangeBegin - Set the start of the source range to Loc, unless it's
|
||||||
|
/// invalid.
|
||||||
|
void SetRangeBegin(SourceLocation Loc) {
|
||||||
|
if (!Loc.isInvalid())
|
||||||
|
Range.setBegin(Loc);
|
||||||
|
}
|
||||||
|
/// SetRangeEnd - Set the end of the source range to Loc, unless it's invalid.
|
||||||
|
void SetRangeEnd(SourceLocation Loc) {
|
||||||
|
if (!Loc.isInvalid())
|
||||||
|
Range.setEnd(Loc);
|
||||||
|
}
|
||||||
|
/// ExtendWithDeclSpec - Extend the declarator source range to include the
|
||||||
|
/// given declspec, unless its location is invalid. Adopts the range start if
|
||||||
|
/// the current range start is invalid.
|
||||||
|
void ExtendWithDeclSpec(const DeclSpec &DS) {
|
||||||
|
const SourceRange &SR = DS.getSourceRange();
|
||||||
|
if (Range.getBegin().isInvalid())
|
||||||
|
Range.setBegin(SR.getBegin());
|
||||||
|
if (!SR.getEnd().isInvalid())
|
||||||
|
Range.setEnd(SR.getEnd());
|
||||||
|
}
|
||||||
|
|
||||||
/// clear - Reset the contents of this Declarator.
|
/// clear - Reset the contents of this Declarator.
|
||||||
void clear() {
|
void clear() {
|
||||||
SS.clear();
|
SS.clear();
|
||||||
Identifier = 0;
|
Identifier = 0;
|
||||||
IdentifierLoc = SourceLocation();
|
IdentifierLoc = SourceLocation();
|
||||||
|
Range = DS.getSourceRange();
|
||||||
Kind = DK_Abstract;
|
Kind = DK_Abstract;
|
||||||
|
|
||||||
for (unsigned i = 0, e = DeclTypeInfo.size(); i != e; ++i)
|
for (unsigned i = 0, e = DeclTypeInfo.size(); i != e; ++i)
|
||||||
|
@ -856,43 +883,64 @@ public:
|
||||||
Kind = DK_Normal;
|
Kind = DK_Normal;
|
||||||
else
|
else
|
||||||
Kind = DK_Abstract;
|
Kind = DK_Abstract;
|
||||||
|
SetRangeEnd(Loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// setConstructor - Set this declarator to be a C++ constructor
|
/// setConstructor - Set this declarator to be a C++ constructor
|
||||||
/// declarator.
|
/// declarator. Also extends the range.
|
||||||
void setConstructor(Action::TypeTy *Ty, SourceLocation Loc) {
|
void setConstructor(Action::TypeTy *Ty, SourceLocation Loc) {
|
||||||
IdentifierLoc = Loc;
|
IdentifierLoc = Loc;
|
||||||
Kind = DK_Constructor;
|
Kind = DK_Constructor;
|
||||||
Type = Ty;
|
Type = Ty;
|
||||||
|
SetRangeEnd(Loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// setDestructor - Set this declarator to be a C++ destructor
|
/// setDestructor - Set this declarator to be a C++ destructor
|
||||||
/// declarator.
|
/// declarator. Also extends the range to End, which should be the identifier
|
||||||
void setDestructor(Action::TypeTy *Ty, SourceLocation Loc) {
|
/// token.
|
||||||
|
void setDestructor(Action::TypeTy *Ty, SourceLocation Loc,
|
||||||
|
SourceLocation EndLoc)
|
||||||
|
{
|
||||||
IdentifierLoc = Loc;
|
IdentifierLoc = Loc;
|
||||||
Kind = DK_Destructor;
|
Kind = DK_Destructor;
|
||||||
Type = Ty;
|
Type = Ty;
|
||||||
|
if (!EndLoc.isInvalid())
|
||||||
|
SetRangeEnd(EndLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// setConversionFunction - Set this declarator to be a C++
|
/// setConversionFunction - Set this declarator to be a C++
|
||||||
// conversion function declarator (e.g., @c operator int const *).
|
/// conversion function declarator (e.g., @c operator int const *).
|
||||||
void setConversionFunction(Action::TypeTy *Ty, SourceLocation Loc) {
|
/// Also extends the range to EndLoc, which should be the last token of the
|
||||||
|
/// type name.
|
||||||
|
void setConversionFunction(Action::TypeTy *Ty, SourceLocation Loc,
|
||||||
|
SourceLocation EndLoc) {
|
||||||
Identifier = 0;
|
Identifier = 0;
|
||||||
IdentifierLoc = Loc;
|
IdentifierLoc = Loc;
|
||||||
Kind = DK_Conversion;
|
Kind = DK_Conversion;
|
||||||
Type = Ty;
|
Type = Ty;
|
||||||
|
if (!EndLoc.isInvalid())
|
||||||
|
SetRangeEnd(EndLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// setOverloadedOperator - Set this declaration to be a C++
|
/// setOverloadedOperator - Set this declaration to be a C++
|
||||||
// overloaded operator declarator (e.g., @c operator+).
|
/// overloaded operator declarator (e.g., @c operator+).
|
||||||
void setOverloadedOperator(OverloadedOperatorKind Op, SourceLocation Loc) {
|
/// Also extends the range to EndLoc, which should be the last token of the
|
||||||
|
/// operator.
|
||||||
|
void setOverloadedOperator(OverloadedOperatorKind Op, SourceLocation Loc,
|
||||||
|
SourceLocation EndLoc) {
|
||||||
IdentifierLoc = Loc;
|
IdentifierLoc = Loc;
|
||||||
Kind = DK_Operator;
|
Kind = DK_Operator;
|
||||||
OperatorKind = Op;
|
OperatorKind = Op;
|
||||||
|
if (!EndLoc.isInvalid())
|
||||||
|
SetRangeEnd(EndLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddTypeInfo(const DeclaratorChunk &TI) {
|
/// AddTypeInfo - Add a chunk to this declarator. Also extend the range to
|
||||||
|
/// EndLoc, which should be the last token of the chunk.
|
||||||
|
void AddTypeInfo(const DeclaratorChunk &TI, SourceLocation EndLoc) {
|
||||||
DeclTypeInfo.push_back(TI);
|
DeclTypeInfo.push_back(TI);
|
||||||
|
if (!EndLoc.isInvalid())
|
||||||
|
SetRangeEnd(EndLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// getNumTypeObjects() - Return the number of types applied to this
|
/// getNumTypeObjects() - Return the number of types applied to this
|
||||||
|
@ -923,13 +971,17 @@ public:
|
||||||
/// short int x, __attribute__((aligned(16)) var
|
/// short int x, __attribute__((aligned(16)) var
|
||||||
/// __attribute__((common,deprecated));
|
/// __attribute__((common,deprecated));
|
||||||
///
|
///
|
||||||
void AddAttributes(AttributeList *alist) {
|
/// Also extends the range of the declarator.
|
||||||
|
void AddAttributes(AttributeList *alist, SourceLocation LastLoc) {
|
||||||
if (!alist)
|
if (!alist)
|
||||||
return; // we parsed __attribute__(()) or had a syntax error
|
return; // we parsed __attribute__(()) or had a syntax error
|
||||||
|
|
||||||
if (AttrList)
|
if (AttrList)
|
||||||
alist->addAttributeList(AttrList);
|
alist->addAttributeList(AttrList);
|
||||||
AttrList = alist;
|
AttrList = alist;
|
||||||
|
|
||||||
|
if (!LastLoc.isInvalid())
|
||||||
|
SetRangeEnd(LastLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
const AttributeList *getAttributes() const { return AttrList; }
|
const AttributeList *getAttributes() const { return AttrList; }
|
||||||
|
|
|
@ -22,10 +22,6 @@
|
||||||
|
|
||||||
namespace clang {
|
namespace clang {
|
||||||
class AttributeList;
|
class AttributeList;
|
||||||
class DeclSpec;
|
|
||||||
class Declarator;
|
|
||||||
class FieldDeclarator;
|
|
||||||
class ObjCDeclSpec;
|
|
||||||
class PragmaHandler;
|
class PragmaHandler;
|
||||||
class Scope;
|
class Scope;
|
||||||
class DiagnosticBuilder;
|
class DiagnosticBuilder;
|
||||||
|
@ -511,7 +507,9 @@ private:
|
||||||
TemplateParameterLists *TemplateParams = 0);
|
TemplateParameterLists *TemplateParams = 0);
|
||||||
DeclTy *ParseFunctionDefinition(Declarator &D);
|
DeclTy *ParseFunctionDefinition(Declarator &D);
|
||||||
void ParseKNRParamDeclarations(Declarator &D);
|
void ParseKNRParamDeclarations(Declarator &D);
|
||||||
OwningExprResult ParseSimpleAsm();
|
// EndLoc, if non-NULL, is filled with the location of the last token of
|
||||||
|
// the simple-asm.
|
||||||
|
OwningExprResult ParseSimpleAsm(SourceLocation *EndLoc = 0);
|
||||||
OwningExprResult ParseAsmStringLiteral();
|
OwningExprResult ParseAsmStringLiteral();
|
||||||
|
|
||||||
// Objective-C External Declarations
|
// Objective-C External Declarations
|
||||||
|
@ -634,7 +632,8 @@ private:
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// C++ 15: C++ Throw Expression
|
// C++ 15: C++ Throw Expression
|
||||||
OwningExprResult ParseThrowExpression();
|
OwningExprResult ParseThrowExpression();
|
||||||
bool ParseExceptionSpecification();
|
// EndLoc is filled with the location of the last token of the specification.
|
||||||
|
bool ParseExceptionSpecification(SourceLocation &EndLoc);
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// C++ 2.13.5: C++ Boolean Literals
|
// C++ 2.13.5: C++ Boolean Literals
|
||||||
|
@ -899,7 +898,9 @@ private:
|
||||||
|
|
||||||
TypeTy *ParseTypeName();
|
TypeTy *ParseTypeName();
|
||||||
void ParseBlockId();
|
void ParseBlockId();
|
||||||
AttributeList *ParseAttributes();
|
// EndLoc, if non-NULL, is filled with the location of the last token of
|
||||||
|
// the attribute list.
|
||||||
|
AttributeList *ParseAttributes(SourceLocation *EndLoc = 0);
|
||||||
void FuzzyParseMicrosoftDeclSpec();
|
void FuzzyParseMicrosoftDeclSpec();
|
||||||
void ParseTypeofSpecifier(DeclSpec &DS);
|
void ParseTypeofSpecifier(DeclSpec &DS);
|
||||||
|
|
||||||
|
@ -967,8 +968,10 @@ private:
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// C++ 13.5: Overloaded operators [over.oper]
|
// C++ 13.5: Overloaded operators [over.oper]
|
||||||
OverloadedOperatorKind TryParseOperatorFunctionId();
|
// EndLoc, if non-NULL, is filled with the location of the last token of
|
||||||
TypeTy *ParseConversionFunctionId();
|
// the ID.
|
||||||
|
OverloadedOperatorKind TryParseOperatorFunctionId(SourceLocation *EndLoc = 0);
|
||||||
|
TypeTy *ParseConversionFunctionId(SourceLocation *EndLoc = 0);
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// C++ 14: Templates [temp]
|
// C++ 14: Templates [temp]
|
||||||
|
|
|
@ -76,7 +76,7 @@ Parser::TypeTy *Parser::ParseTypeName() {
|
||||||
/// 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::ParseAttributes() {
|
AttributeList *Parser::ParseAttributes(SourceLocation *EndLoc) {
|
||||||
assert(Tok.is(tok::kw___attribute) && "Not an attribute list!");
|
assert(Tok.is(tok::kw___attribute) && "Not an attribute list!");
|
||||||
|
|
||||||
AttributeList *CurrAttr = 0;
|
AttributeList *CurrAttr = 0;
|
||||||
|
@ -186,8 +186,12 @@ AttributeList *Parser::ParseAttributes() {
|
||||||
}
|
}
|
||||||
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 (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen))
|
SourceLocation Loc = Tok.getLocation();;
|
||||||
|
if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) {
|
||||||
SkipUntil(tok::r_paren, false);
|
SkipUntil(tok::r_paren, false);
|
||||||
|
}
|
||||||
|
if (EndLoc)
|
||||||
|
*EndLoc = Loc;
|
||||||
}
|
}
|
||||||
return CurrAttr;
|
return CurrAttr;
|
||||||
}
|
}
|
||||||
|
@ -288,18 +292,23 @@ ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) {
|
||||||
while (1) {
|
while (1) {
|
||||||
// If a simple-asm-expr is present, parse it.
|
// If a simple-asm-expr is present, parse it.
|
||||||
if (Tok.is(tok::kw_asm)) {
|
if (Tok.is(tok::kw_asm)) {
|
||||||
OwningExprResult AsmLabel(ParseSimpleAsm());
|
SourceLocation Loc;
|
||||||
|
OwningExprResult AsmLabel(ParseSimpleAsm(&Loc));
|
||||||
if (AsmLabel.isInvalid()) {
|
if (AsmLabel.isInvalid()) {
|
||||||
SkipUntil(tok::semi);
|
SkipUntil(tok::semi);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
D.setAsmLabel(AsmLabel.release());
|
D.setAsmLabel(AsmLabel.release());
|
||||||
|
D.SetRangeEnd(Loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If attributes are present, parse them.
|
// If attributes are present, parse them.
|
||||||
if (Tok.is(tok::kw___attribute))
|
if (Tok.is(tok::kw___attribute)) {
|
||||||
D.AddAttributes(ParseAttributes());
|
SourceLocation Loc;
|
||||||
|
AttributeList *AttrList = ParseAttributes(&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.
|
||||||
LastDeclInGroup = Actions.ActOnDeclarator(CurScope, D, LastDeclInGroup);
|
LastDeclInGroup = Actions.ActOnDeclarator(CurScope, D, LastDeclInGroup);
|
||||||
|
@ -356,8 +365,11 @@ ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) {
|
||||||
// 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))
|
if (Tok.is(tok::kw___attribute)) {
|
||||||
D.AddAttributes(ParseAttributes());
|
SourceLocation Loc;
|
||||||
|
AttributeList *AttrList = ParseAttributes(&Loc);
|
||||||
|
D.AddAttributes(AttrList, Loc);
|
||||||
|
}
|
||||||
|
|
||||||
ParseDeclarator(D);
|
ParseDeclarator(D);
|
||||||
}
|
}
|
||||||
|
@ -1022,8 +1034,11 @@ ParseStructDeclaration(DeclSpec &DS,
|
||||||
}
|
}
|
||||||
|
|
||||||
// If attributes exist after the declarator, parse them.
|
// If attributes exist after the declarator, parse them.
|
||||||
if (Tok.is(tok::kw___attribute))
|
if (Tok.is(tok::kw___attribute)) {
|
||||||
DeclaratorInfo.D.AddAttributes(ParseAttributes());
|
SourceLocation Loc;
|
||||||
|
AttributeList *AttrList = ParseAttributes(&Loc);
|
||||||
|
DeclaratorInfo.D.AddAttributes(AttrList, Loc);
|
||||||
|
}
|
||||||
|
|
||||||
// If we don't have a comma, it is either the end of the list (a ';')
|
// If we don't have a comma, it is either the end of the list (a ';')
|
||||||
// or an error, bail out.
|
// or an error, bail out.
|
||||||
|
@ -1037,8 +1052,11 @@ ParseStructDeclaration(DeclSpec &DS,
|
||||||
Fields.push_back(FieldDeclarator(DS));
|
Fields.push_back(FieldDeclarator(DS));
|
||||||
|
|
||||||
// Attributes are only allowed on the second declarator.
|
// Attributes are only allowed on the second declarator.
|
||||||
if (Tok.is(tok::kw___attribute))
|
if (Tok.is(tok::kw___attribute)) {
|
||||||
Fields.back().D.AddAttributes(ParseAttributes());
|
SourceLocation Loc;
|
||||||
|
AttributeList *AttrList = ParseAttributes(&Loc);
|
||||||
|
Fields.back().D.AddAttributes(AttrList, Loc);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1584,8 +1602,10 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
|
||||||
}
|
}
|
||||||
|
|
||||||
SourceLocation Loc = ConsumeToken();
|
SourceLocation Loc = ConsumeToken();
|
||||||
|
D.SetRangeEnd(Loc);
|
||||||
DeclSpec DS;
|
DeclSpec DS;
|
||||||
ParseTypeQualifierListOpt(DS);
|
ParseTypeQualifierListOpt(DS);
|
||||||
|
D.ExtendWithDeclSpec(DS);
|
||||||
|
|
||||||
// Recurse to parse whatever is left.
|
// Recurse to parse whatever is left.
|
||||||
ParseDeclaratorInternal(D, DirectDeclParser);
|
ParseDeclaratorInternal(D, DirectDeclParser);
|
||||||
|
@ -1593,7 +1613,8 @@ 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());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1608,24 +1629,28 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, '*' -> pointer, '^' -> block, '&' -> reference.
|
// Otherwise, '*' -> pointer, '^' -> block, '&' -> reference.
|
||||||
SourceLocation Loc = ConsumeToken(); // Eat the * or &.
|
SourceLocation Loc = ConsumeToken(); // Eat the *, ^ or &.
|
||||||
|
D.SetRangeEnd(Loc);
|
||||||
|
|
||||||
if (Kind == tok::star || (Kind == tok::caret && getLang().Blocks)) {
|
if (Kind == tok::star || (Kind == tok::caret && getLang().Blocks)) {
|
||||||
// Is a pointer.
|
// Is a pointer.
|
||||||
DeclSpec DS;
|
DeclSpec DS;
|
||||||
|
|
||||||
ParseTypeQualifierListOpt(DS);
|
ParseTypeQualifierListOpt(DS);
|
||||||
|
D.ExtendWithDeclSpec(DS);
|
||||||
|
|
||||||
// Recursively parse the declarator.
|
// Recursively parse the declarator.
|
||||||
ParseDeclaratorInternal(D, DirectDeclParser);
|
ParseDeclaratorInternal(D, DirectDeclParser);
|
||||||
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());
|
||||||
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));
|
Loc),
|
||||||
|
SourceLocation());
|
||||||
} else {
|
} else {
|
||||||
// Is a reference
|
// Is a reference
|
||||||
DeclSpec DS;
|
DeclSpec DS;
|
||||||
|
@ -1637,6 +1662,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D,
|
||||||
// [GNU] Retricted references are allowed.
|
// [GNU] Retricted references are allowed.
|
||||||
// [GNU] Attributes on references are allowed.
|
// [GNU] Attributes on references are allowed.
|
||||||
ParseTypeQualifierListOpt(DS);
|
ParseTypeQualifierListOpt(DS);
|
||||||
|
D.ExtendWithDeclSpec(DS);
|
||||||
|
|
||||||
if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) {
|
if (DS.getTypeQualifiers() != DeclSpec::TQ_unspecified) {
|
||||||
if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
|
if (DS.getTypeQualifiers() & DeclSpec::TQ_const)
|
||||||
|
@ -1669,7 +1695,8 @@ 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()),
|
||||||
|
SourceLocation());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1736,37 +1763,42 @@ void Parser::ParseDirectDeclarator(Declarator &D) {
|
||||||
}
|
}
|
||||||
// If this identifier is the name of the current class, it's a
|
// If this identifier is the name of the current class, it's a
|
||||||
// constructor name.
|
// constructor name.
|
||||||
else if (Actions.isCurrentClassName(*Tok.getIdentifierInfo(), CurScope))
|
else if (Actions.isCurrentClassName(*Tok.getIdentifierInfo(),CurScope)){
|
||||||
D.setConstructor(Actions.getTypeName(*Tok.getIdentifierInfo(),
|
D.setConstructor(Actions.getTypeName(*Tok.getIdentifierInfo(),
|
||||||
Tok.getLocation(), CurScope),
|
Tok.getLocation(), CurScope),
|
||||||
Tok.getLocation());
|
Tok.getLocation());
|
||||||
// This is a normal identifier.
|
// This is a normal identifier.
|
||||||
else
|
} else
|
||||||
D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
|
D.SetIdentifier(Tok.getIdentifierInfo(), Tok.getLocation());
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
goto PastIdentifier;
|
goto PastIdentifier;
|
||||||
} else if (Tok.is(tok::kw_operator)) {
|
} else if (Tok.is(tok::kw_operator)) {
|
||||||
SourceLocation OperatorLoc = Tok.getLocation();
|
SourceLocation OperatorLoc = Tok.getLocation();
|
||||||
|
SourceLocation EndLoc;
|
||||||
|
|
||||||
// First try the name of an overloaded operator
|
// First try the name of an overloaded operator
|
||||||
if (OverloadedOperatorKind Op = TryParseOperatorFunctionId()) {
|
if (OverloadedOperatorKind Op = TryParseOperatorFunctionId(&EndLoc)) {
|
||||||
D.setOverloadedOperator(Op, OperatorLoc);
|
D.setOverloadedOperator(Op, OperatorLoc, EndLoc);
|
||||||
} else {
|
} else {
|
||||||
// This must be a conversion function (C++ [class.conv.fct]).
|
// This must be a conversion function (C++ [class.conv.fct]).
|
||||||
if (TypeTy *ConvType = ParseConversionFunctionId())
|
if (TypeTy *ConvType = ParseConversionFunctionId(&EndLoc))
|
||||||
D.setConversionFunction(ConvType, OperatorLoc);
|
D.setConversionFunction(ConvType, OperatorLoc, EndLoc);
|
||||||
else
|
else {
|
||||||
D.SetIdentifier(0, Tok.getLocation());
|
D.SetIdentifier(0, Tok.getLocation());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
goto PastIdentifier;
|
goto PastIdentifier;
|
||||||
} else if (Tok.is(tok::tilde)) {
|
} else if (Tok.is(tok::tilde)) {
|
||||||
// This should be a C++ destructor.
|
// This should be a C++ destructor.
|
||||||
SourceLocation TildeLoc = ConsumeToken();
|
SourceLocation TildeLoc = ConsumeToken();
|
||||||
if (Tok.is(tok::identifier)) {
|
if (Tok.is(tok::identifier)) {
|
||||||
if (TypeTy *Type = ParseClassName())
|
// FIXME: Inaccurate.
|
||||||
D.setDestructor(Type, TildeLoc);
|
SourceLocation NameLoc = Tok.getLocation();
|
||||||
else
|
if (TypeTy *Type = ParseClassName()) {
|
||||||
|
D.setDestructor(Type, TildeLoc, NameLoc);
|
||||||
|
} else {
|
||||||
D.SetIdentifier(0, TildeLoc);
|
D.SetIdentifier(0, TildeLoc);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Diag(Tok, diag::err_expected_class_name);
|
Diag(Tok, diag::err_expected_class_name);
|
||||||
D.SetIdentifier(0, TildeLoc);
|
D.SetIdentifier(0, TildeLoc);
|
||||||
|
@ -1906,13 +1938,14 @@ void Parser::ParseParenDeclarator(Declarator &D) {
|
||||||
bool hadGroupingParens = D.hasGroupingParens();
|
bool hadGroupingParens = D.hasGroupingParens();
|
||||||
D.setGroupingParens(true);
|
D.setGroupingParens(true);
|
||||||
if (AttrList)
|
if (AttrList)
|
||||||
D.AddAttributes(AttrList);
|
D.AddAttributes(AttrList, SourceLocation());
|
||||||
|
|
||||||
ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
|
ParseDeclaratorInternal(D, &Parser::ParseDirectDeclarator);
|
||||||
// Match the ')'.
|
// Match the ')'.
|
||||||
MatchRHSPunctuation(tok::r_paren, StartLoc);
|
SourceLocation Loc = MatchRHSPunctuation(tok::r_paren, StartLoc);
|
||||||
|
|
||||||
D.setGroupingParens(hadGroupingParens);
|
D.setGroupingParens(hadGroupingParens);
|
||||||
|
D.SetRangeEnd(Loc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1969,16 +2002,18 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
||||||
delete AttrList;
|
delete AttrList;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConsumeParen(); // Eat the closing ')'.
|
SourceLocation Loc = ConsumeParen(); // Eat the closing ')'.
|
||||||
|
|
||||||
// cv-qualifier-seq[opt].
|
// cv-qualifier-seq[opt].
|
||||||
DeclSpec DS;
|
DeclSpec DS;
|
||||||
if (getLang().CPlusPlus) {
|
if (getLang().CPlusPlus) {
|
||||||
ParseTypeQualifierListOpt(DS, false /*no attributes*/);
|
ParseTypeQualifierListOpt(DS, false /*no attributes*/);
|
||||||
|
if (!DS.getSourceRange().getEnd().isInvalid())
|
||||||
|
Loc = DS.getSourceRange().getEnd();
|
||||||
|
|
||||||
// Parse exception-specification[opt].
|
// Parse exception-specification[opt].
|
||||||
if (Tok.is(tok::kw_throw))
|
if (Tok.is(tok::kw_throw))
|
||||||
ParseExceptionSpecification();
|
ParseExceptionSpecification(Loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remember that we parsed a function type, and remember the attributes.
|
// Remember that we parsed a function type, and remember the attributes.
|
||||||
|
@ -1987,7 +2022,8 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
||||||
/*variadic*/ false,
|
/*variadic*/ false,
|
||||||
/*arglist*/ 0, 0,
|
/*arglist*/ 0, 0,
|
||||||
DS.getTypeQualifiers(),
|
DS.getTypeQualifiers(),
|
||||||
LParenLoc, D));
|
LParenLoc, D),
|
||||||
|
Loc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2051,8 +2087,11 @@ 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))
|
if (Tok.is(tok::kw___attribute)) {
|
||||||
ParmDecl.AddAttributes(ParseAttributes());
|
SourceLocation Loc;
|
||||||
|
AttributeList *AttrList = ParseAttributes(&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();
|
||||||
|
@ -2130,23 +2169,26 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
|
||||||
PrototypeScope.Exit();
|
PrototypeScope.Exit();
|
||||||
|
|
||||||
// If we have the closing ')', eat it.
|
// If we have the closing ')', eat it.
|
||||||
MatchRHSPunctuation(tok::r_paren, LParenLoc);
|
SourceLocation Loc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
|
||||||
|
|
||||||
DeclSpec DS;
|
DeclSpec DS;
|
||||||
if (getLang().CPlusPlus) {
|
if (getLang().CPlusPlus) {
|
||||||
// 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())
|
||||||
|
Loc = DS.getSourceRange().getEnd();
|
||||||
|
|
||||||
// Parse exception-specification[opt].
|
// Parse exception-specification[opt].
|
||||||
if (Tok.is(tok::kw_throw))
|
if (Tok.is(tok::kw_throw))
|
||||||
ParseExceptionSpecification();
|
ParseExceptionSpecification(Loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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(/*proto*/true, IsVariadic,
|
||||||
&ParamInfo[0], ParamInfo.size(),
|
&ParamInfo[0], ParamInfo.size(),
|
||||||
DS.getTypeQualifiers(),
|
DS.getTypeQualifiers(),
|
||||||
LParenLoc, D));
|
LParenLoc, D),
|
||||||
|
Loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator
|
/// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator
|
||||||
|
@ -2208,15 +2250,16 @@ void Parser::ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc,
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we have the closing ')', eat it and we're done.
|
||||||
|
SourceLocation RLoc = MatchRHSPunctuation(tok::r_paren, 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(/*proto*/false, /*varargs*/false,
|
||||||
&ParamInfo[0], ParamInfo.size(),
|
&ParamInfo[0], ParamInfo.size(),
|
||||||
/*TypeQuals*/0, LParenLoc, D));
|
/*TypeQuals*/0, LParenLoc, D),
|
||||||
|
RLoc);
|
||||||
// If we have the closing ')', eat it and we're done.
|
|
||||||
MatchRHSPunctuation(tok::r_paren, LParenLoc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [C90] direct-declarator '[' constant-expression[opt] ']'
|
/// [C90] direct-declarator '[' constant-expression[opt] ']'
|
||||||
|
@ -2230,10 +2273,11 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
|
||||||
// C array syntax has many features, but by-far the most common is [] and [4].
|
// C array syntax has many features, but by-far the most common is [] and [4].
|
||||||
// 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) {
|
||||||
MatchRHSPunctuation(tok::r_square, StartLoc);
|
SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
|
||||||
// Remember that we parsed the empty array type.
|
// Remember that we parsed the empty array type.
|
||||||
OwningExprResult NumElements(Actions);
|
OwningExprResult NumElements(Actions);
|
||||||
D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0, StartLoc));
|
D.AddTypeInfo(DeclaratorChunk::getArray(0, false, false, 0, StartLoc),
|
||||||
|
EndLoc);
|
||||||
return;
|
return;
|
||||||
} else if (Tok.getKind() == tok::numeric_constant &&
|
} else if (Tok.getKind() == tok::numeric_constant &&
|
||||||
GetLookAheadToken(1).is(tok::r_square)) {
|
GetLookAheadToken(1).is(tok::r_square)) {
|
||||||
|
@ -2241,7 +2285,7 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
|
||||||
OwningExprResult ExprRes(Actions.ActOnNumericConstant(Tok));
|
OwningExprResult ExprRes(Actions.ActOnNumericConstant(Tok));
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
|
|
||||||
MatchRHSPunctuation(tok::r_square, StartLoc);
|
SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
|
||||||
|
|
||||||
// If there was an error parsing the assignment-expression, recover.
|
// If there was an error parsing the assignment-expression, recover.
|
||||||
if (ExprRes.isInvalid())
|
if (ExprRes.isInvalid())
|
||||||
|
@ -2249,7 +2293,8 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
|
||||||
|
|
||||||
// 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,
|
D.AddTypeInfo(DeclaratorChunk::getArray(0, false, 0,
|
||||||
ExprRes.release(), StartLoc));
|
ExprRes.release(), StartLoc),
|
||||||
|
EndLoc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2301,12 +2346,13 @@ void Parser::ParseBracketDeclarator(Declarator &D) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MatchRHSPunctuation(tok::r_square, StartLoc);
|
SourceLocation EndLoc = MatchRHSPunctuation(tok::r_square, StartLoc);
|
||||||
|
|
||||||
// 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(),
|
||||||
StaticLoc.isValid(), isStar,
|
StaticLoc.isValid(), isStar,
|
||||||
NumElements.release(), StartLoc));
|
NumElements.release(), StartLoc),
|
||||||
|
EndLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [GNU] typeof-specifier:
|
/// [GNU] typeof-specifier:
|
||||||
|
|
|
@ -630,8 +630,11 @@ Parser::DeclTy *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))
|
if (Tok.is(tok::kw___attribute)) {
|
||||||
DeclaratorInfo.AddAttributes(ParseAttributes());
|
SourceLocation Loc;
|
||||||
|
AttributeList *AttrList = ParseAttributes(&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; LastDeclInGroup will be
|
// this call will *not* return the created decl; LastDeclInGroup will be
|
||||||
|
@ -691,8 +694,11 @@ Parser::DeclTy *Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS) {
|
||||||
Init = 0;
|
Init = 0;
|
||||||
|
|
||||||
// Attributes are only allowed on the second declarator.
|
// Attributes are only allowed on the second declarator.
|
||||||
if (Tok.is(tok::kw___attribute))
|
if (Tok.is(tok::kw___attribute)) {
|
||||||
DeclaratorInfo.AddAttributes(ParseAttributes());
|
SourceLocation Loc;
|
||||||
|
AttributeList *AttrList = ParseAttributes(&Loc);
|
||||||
|
DeclaratorInfo.AddAttributes(AttrList, Loc);
|
||||||
|
}
|
||||||
|
|
||||||
if (Tok.isNot(tok::colon))
|
if (Tok.isNot(tok::colon))
|
||||||
ParseDeclarator(DeclaratorInfo);
|
ParseDeclarator(DeclaratorInfo);
|
||||||
|
@ -921,7 +927,7 @@ Parser::MemInitResult Parser::ParseMemInitializer(DeclTy *ConstructorDecl) {
|
||||||
/// type-id
|
/// type-id
|
||||||
/// type-id-list ',' type-id
|
/// type-id-list ',' type-id
|
||||||
///
|
///
|
||||||
bool Parser::ParseExceptionSpecification() {
|
bool Parser::ParseExceptionSpecification(SourceLocation &EndLoc) {
|
||||||
assert(Tok.is(tok::kw_throw) && "expected throw");
|
assert(Tok.is(tok::kw_throw) && "expected throw");
|
||||||
|
|
||||||
SourceLocation ThrowLoc = ConsumeToken();
|
SourceLocation ThrowLoc = ConsumeToken();
|
||||||
|
@ -937,7 +943,7 @@ bool Parser::ParseExceptionSpecification() {
|
||||||
SourceLocation EllipsisLoc = ConsumeToken();
|
SourceLocation EllipsisLoc = ConsumeToken();
|
||||||
if (!getLang().Microsoft)
|
if (!getLang().Microsoft)
|
||||||
Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec);
|
Diag(EllipsisLoc, diag::ext_ellipsis_exception_spec);
|
||||||
SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
|
EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -950,6 +956,6 @@ bool Parser::ParseExceptionSpecification() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
|
EndLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1251,8 +1251,9 @@ Parser::OwningExprResult Parser::ParseBlockLiteralExpression() {
|
||||||
// argument decls, decls within the compound expression, etc. This also
|
// argument decls, decls within the compound expression, etc. This also
|
||||||
// allows determining whether a variable reference inside the block is
|
// allows determining whether a variable reference inside the block is
|
||||||
// within or outside of the block.
|
// within or outside of the block.
|
||||||
ParseScope BlockScope(this, Scope::BlockScope|Scope::FnScope|Scope::BreakScope|
|
ParseScope BlockScope(this, Scope::BlockScope | Scope::FnScope |
|
||||||
Scope::ContinueScope|Scope::DeclScope);
|
Scope::BreakScope | Scope::ContinueScope |
|
||||||
|
Scope::DeclScope);
|
||||||
|
|
||||||
// Inform sema that we are starting a block.
|
// Inform sema that we are starting a block.
|
||||||
Actions.ActOnBlockStart(CaretLoc, CurScope);
|
Actions.ActOnBlockStart(CaretLoc, CurScope);
|
||||||
|
@ -1260,13 +1261,20 @@ Parser::OwningExprResult Parser::ParseBlockLiteralExpression() {
|
||||||
// Parse the return type if present.
|
// Parse the return type if present.
|
||||||
DeclSpec DS;
|
DeclSpec DS;
|
||||||
Declarator ParamInfo(DS, Declarator::BlockLiteralContext);
|
Declarator ParamInfo(DS, Declarator::BlockLiteralContext);
|
||||||
|
// FIXME: Since the return type isn't actually parsed, it can't be used to
|
||||||
|
// fill ParamInfo with an initial valid range, so do it manually.
|
||||||
|
ParamInfo.SetSourceRange(SourceRange(Tok.getLocation(), Tok.getLocation()));
|
||||||
|
|
||||||
// If this block has arguments, parse them. There is no ambiguity here with
|
// If this block has arguments, parse them. There is no ambiguity here with
|
||||||
// the expression case, because the expression case requires a parameter list.
|
// the expression case, because the expression case requires a parameter list.
|
||||||
if (Tok.is(tok::l_paren)) {
|
if (Tok.is(tok::l_paren)) {
|
||||||
ParseParenDeclarator(ParamInfo);
|
ParseParenDeclarator(ParamInfo);
|
||||||
// Parse the pieces after the identifier as if we had "int(...)".
|
// Parse the pieces after the identifier as if we had "int(...)".
|
||||||
|
// SetIdentifier sets the source range end, but in this case we're past
|
||||||
|
// that location.
|
||||||
|
SourceLocation Tmp = ParamInfo.getSourceRange().getEnd();
|
||||||
ParamInfo.SetIdentifier(0, CaretLoc);
|
ParamInfo.SetIdentifier(0, CaretLoc);
|
||||||
|
ParamInfo.SetRangeEnd(Tmp);
|
||||||
if (ParamInfo.getInvalidType()) {
|
if (ParamInfo.getInvalidType()) {
|
||||||
// If there was an error parsing the arguments, they may have
|
// If there was an error parsing the arguments, they may have
|
||||||
// tried to use ^(x+y) which requires an argument list. Just
|
// tried to use ^(x+y) which requires an argument list. Just
|
||||||
|
@ -1281,7 +1289,8 @@ Parser::OwningExprResult Parser::ParseBlockLiteralExpression() {
|
||||||
// Otherwise, pretend we saw (void).
|
// Otherwise, pretend we saw (void).
|
||||||
ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(true, false,
|
ParamInfo.AddTypeInfo(DeclaratorChunk::getFunction(true, false,
|
||||||
0, 0, 0, CaretLoc,
|
0, 0, 0, CaretLoc,
|
||||||
ParamInfo));
|
ParamInfo),
|
||||||
|
CaretLoc);
|
||||||
// Inform sema that we are starting a block.
|
// Inform sema that we are starting a block.
|
||||||
Actions.ActOnBlockArguments(ParamInfo, CurScope);
|
Actions.ActOnBlockArguments(ParamInfo, CurScope);
|
||||||
}
|
}
|
||||||
|
|
|
@ -390,17 +390,22 @@ Parser::OwningExprResult Parser::ParseCXXCondition() {
|
||||||
|
|
||||||
// simple-asm-expr[opt]
|
// simple-asm-expr[opt]
|
||||||
if (Tok.is(tok::kw_asm)) {
|
if (Tok.is(tok::kw_asm)) {
|
||||||
OwningExprResult AsmLabel(ParseSimpleAsm());
|
SourceLocation Loc;
|
||||||
|
OwningExprResult AsmLabel(ParseSimpleAsm(&Loc));
|
||||||
if (AsmLabel.isInvalid()) {
|
if (AsmLabel.isInvalid()) {
|
||||||
SkipUntil(tok::semi);
|
SkipUntil(tok::semi);
|
||||||
return ExprError();
|
return ExprError();
|
||||||
}
|
}
|
||||||
DeclaratorInfo.setAsmLabel(AsmLabel.release());
|
DeclaratorInfo.setAsmLabel(AsmLabel.release());
|
||||||
|
DeclaratorInfo.SetRangeEnd(Loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If attributes are present, parse them.
|
// If attributes are present, parse them.
|
||||||
if (Tok.is(tok::kw___attribute))
|
if (Tok.is(tok::kw___attribute)) {
|
||||||
DeclaratorInfo.AddAttributes(ParseAttributes());
|
SourceLocation Loc;
|
||||||
|
AttributeList *AttrList = ParseAttributes(&Loc);
|
||||||
|
DeclaratorInfo.AddAttributes(AttrList, Loc);
|
||||||
|
}
|
||||||
|
|
||||||
// '=' assignment-expression
|
// '=' assignment-expression
|
||||||
if (Tok.isNot(tok::equal))
|
if (Tok.isNot(tok::equal))
|
||||||
|
@ -552,33 +557,41 @@ bool Parser::ParseCXXTypeSpecifierSeq(DeclSpec &DS) {
|
||||||
/// ^= &= |= << >> >>= <<= == !=
|
/// ^= &= |= << >> >>= <<= == !=
|
||||||
/// <= >= && || ++ -- , ->* ->
|
/// <= >= && || ++ -- , ->* ->
|
||||||
/// () []
|
/// () []
|
||||||
OverloadedOperatorKind Parser::TryParseOperatorFunctionId() {
|
OverloadedOperatorKind
|
||||||
|
Parser::TryParseOperatorFunctionId(SourceLocation *EndLoc) {
|
||||||
assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword");
|
assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword");
|
||||||
|
SourceLocation Loc;
|
||||||
|
|
||||||
OverloadedOperatorKind Op = OO_None;
|
OverloadedOperatorKind Op = OO_None;
|
||||||
switch (NextToken().getKind()) {
|
switch (NextToken().getKind()) {
|
||||||
case tok::kw_new:
|
case tok::kw_new:
|
||||||
ConsumeToken(); // 'operator'
|
ConsumeToken(); // 'operator'
|
||||||
ConsumeToken(); // 'new'
|
Loc = ConsumeToken(); // 'new'
|
||||||
if (Tok.is(tok::l_square)) {
|
if (Tok.is(tok::l_square)) {
|
||||||
ConsumeBracket(); // '['
|
ConsumeBracket(); // '['
|
||||||
|
Loc = Tok.getLocation();
|
||||||
ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']'
|
ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']'
|
||||||
Op = OO_Array_New;
|
Op = OO_Array_New;
|
||||||
} else {
|
} else {
|
||||||
Op = OO_New;
|
Op = OO_New;
|
||||||
}
|
}
|
||||||
|
if (EndLoc)
|
||||||
|
*EndLoc = Loc;
|
||||||
return Op;
|
return Op;
|
||||||
|
|
||||||
case tok::kw_delete:
|
case tok::kw_delete:
|
||||||
ConsumeToken(); // 'operator'
|
ConsumeToken(); // 'operator'
|
||||||
ConsumeToken(); // 'delete'
|
Loc = ConsumeToken(); // 'delete'
|
||||||
if (Tok.is(tok::l_square)) {
|
if (Tok.is(tok::l_square)) {
|
||||||
ConsumeBracket(); // '['
|
ConsumeBracket(); // '['
|
||||||
|
Loc = Tok.getLocation();
|
||||||
ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']'
|
ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']'
|
||||||
Op = OO_Array_Delete;
|
Op = OO_Array_Delete;
|
||||||
} else {
|
} else {
|
||||||
Op = OO_Delete;
|
Op = OO_Delete;
|
||||||
}
|
}
|
||||||
|
if (EndLoc)
|
||||||
|
*EndLoc = Loc;
|
||||||
return Op;
|
return Op;
|
||||||
|
|
||||||
#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
|
#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
|
||||||
|
@ -589,13 +602,19 @@ OverloadedOperatorKind Parser::TryParseOperatorFunctionId() {
|
||||||
case tok::l_paren:
|
case tok::l_paren:
|
||||||
ConsumeToken(); // 'operator'
|
ConsumeToken(); // 'operator'
|
||||||
ConsumeParen(); // '('
|
ConsumeParen(); // '('
|
||||||
|
Loc = Tok.getLocation();
|
||||||
ExpectAndConsume(tok::r_paren, diag::err_expected_rparen); // ')'
|
ExpectAndConsume(tok::r_paren, diag::err_expected_rparen); // ')'
|
||||||
|
if (EndLoc)
|
||||||
|
*EndLoc = Loc;
|
||||||
return OO_Call;
|
return OO_Call;
|
||||||
|
|
||||||
case tok::l_square:
|
case tok::l_square:
|
||||||
ConsumeToken(); // 'operator'
|
ConsumeToken(); // 'operator'
|
||||||
ConsumeBracket(); // '['
|
ConsumeBracket(); // '['
|
||||||
|
Loc = Tok.getLocation();
|
||||||
ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']'
|
ExpectAndConsume(tok::r_square, diag::err_expected_rsquare); // ']'
|
||||||
|
if (EndLoc)
|
||||||
|
*EndLoc = Loc;
|
||||||
return OO_Subscript;
|
return OO_Subscript;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -603,7 +622,9 @@ OverloadedOperatorKind Parser::TryParseOperatorFunctionId() {
|
||||||
}
|
}
|
||||||
|
|
||||||
ConsumeToken(); // 'operator'
|
ConsumeToken(); // 'operator'
|
||||||
ConsumeAnyToken(); // the operator itself
|
Loc = ConsumeAnyToken(); // the operator itself
|
||||||
|
if (EndLoc)
|
||||||
|
*EndLoc = Loc;
|
||||||
return Op;
|
return Op;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -620,7 +641,7 @@ OverloadedOperatorKind Parser::TryParseOperatorFunctionId() {
|
||||||
///
|
///
|
||||||
/// conversion-declarator:
|
/// conversion-declarator:
|
||||||
/// ptr-operator conversion-declarator[opt]
|
/// ptr-operator conversion-declarator[opt]
|
||||||
Parser::TypeTy *Parser::ParseConversionFunctionId() {
|
Parser::TypeTy *Parser::ParseConversionFunctionId(SourceLocation *EndLoc) {
|
||||||
assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword");
|
assert(Tok.is(tok::kw_operator) && "Expected 'operator' keyword");
|
||||||
ConsumeToken(); // 'operator'
|
ConsumeToken(); // 'operator'
|
||||||
|
|
||||||
|
@ -633,6 +654,8 @@ Parser::TypeTy *Parser::ParseConversionFunctionId() {
|
||||||
// ptr-operators.
|
// ptr-operators.
|
||||||
Declarator D(DS, Declarator::TypeNameContext);
|
Declarator D(DS, Declarator::TypeNameContext);
|
||||||
ParseDeclaratorInternal(D, /*DirectDeclParser=*/0);
|
ParseDeclaratorInternal(D, /*DirectDeclParser=*/0);
|
||||||
|
if (EndLoc)
|
||||||
|
*EndLoc = D.getSourceRange().getEnd();
|
||||||
|
|
||||||
// Finish up the type.
|
// Finish up the type.
|
||||||
Action::TypeResult Result = Actions.ActOnTypeName(CurScope, D);
|
Action::TypeResult Result = Actions.ActOnTypeName(CurScope, D);
|
||||||
|
@ -706,15 +729,18 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
|
||||||
if (Tok.is(tok::l_paren)) {
|
if (Tok.is(tok::l_paren)) {
|
||||||
SourceLocation LParen = ConsumeParen();
|
SourceLocation LParen = ConsumeParen();
|
||||||
ParseSpecifierQualifierList(DS);
|
ParseSpecifierQualifierList(DS);
|
||||||
|
DeclaratorInfo.SetSourceRange(DS.getSourceRange());
|
||||||
ParseDeclarator(DeclaratorInfo);
|
ParseDeclarator(DeclaratorInfo);
|
||||||
MatchRHSPunctuation(tok::r_paren, LParen);
|
MatchRHSPunctuation(tok::r_paren, LParen);
|
||||||
ParenTypeId = true;
|
ParenTypeId = true;
|
||||||
} else {
|
} else {
|
||||||
if (ParseCXXTypeSpecifierSeq(DS))
|
if (ParseCXXTypeSpecifierSeq(DS))
|
||||||
DeclaratorInfo.setInvalidType(true);
|
DeclaratorInfo.setInvalidType(true);
|
||||||
else
|
else {
|
||||||
|
DeclaratorInfo.SetSourceRange(DS.getSourceRange());
|
||||||
ParseDeclaratorInternal(DeclaratorInfo,
|
ParseDeclaratorInternal(DeclaratorInfo,
|
||||||
&Parser::ParseDirectNewDeclarator);
|
&Parser::ParseDirectNewDeclarator);
|
||||||
|
}
|
||||||
ParenTypeId = false;
|
ParenTypeId = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -723,9 +749,11 @@ Parser::ParseCXXNewExpression(bool UseGlobal, SourceLocation Start) {
|
||||||
// direct-declarator is replaced by a direct-new-declarator.
|
// direct-declarator is replaced by a direct-new-declarator.
|
||||||
if (ParseCXXTypeSpecifierSeq(DS))
|
if (ParseCXXTypeSpecifierSeq(DS))
|
||||||
DeclaratorInfo.setInvalidType(true);
|
DeclaratorInfo.setInvalidType(true);
|
||||||
else
|
else {
|
||||||
|
DeclaratorInfo.SetSourceRange(DS.getSourceRange());
|
||||||
ParseDeclaratorInternal(DeclaratorInfo,
|
ParseDeclaratorInternal(DeclaratorInfo,
|
||||||
&Parser::ParseDirectNewDeclarator);
|
&Parser::ParseDirectNewDeclarator);
|
||||||
|
}
|
||||||
ParenTypeId = false;
|
ParenTypeId = false;
|
||||||
}
|
}
|
||||||
if (DeclaratorInfo.getInvalidType()) {
|
if (DeclaratorInfo.getInvalidType()) {
|
||||||
|
@ -780,10 +808,12 @@ void Parser::ParseDirectNewDeclarator(Declarator &D) {
|
||||||
}
|
}
|
||||||
first = false;
|
first = false;
|
||||||
|
|
||||||
|
SourceLocation RLoc = MatchRHSPunctuation(tok::r_square, LLoc);
|
||||||
D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false,
|
D.AddTypeInfo(DeclaratorChunk::getArray(0, /*static=*/false, /*star=*/false,
|
||||||
Size.release(), LLoc));
|
Size.release(), LLoc),
|
||||||
|
RLoc);
|
||||||
|
|
||||||
if (MatchRHSPunctuation(tok::r_square, LLoc).isInvalid())
|
if (RLoc.isInvalid())
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -803,6 +833,7 @@ bool Parser::ParseExpressionListOrTypeId(ExprListTy &PlacementArgs,
|
||||||
// The '(' was already consumed.
|
// The '(' was already consumed.
|
||||||
if (isTypeIdInParens()) {
|
if (isTypeIdInParens()) {
|
||||||
ParseSpecifierQualifierList(D.getMutableDeclSpec());
|
ParseSpecifierQualifierList(D.getMutableDeclSpec());
|
||||||
|
D.SetSourceRange(D.getDeclSpec().getSourceRange());
|
||||||
ParseDeclarator(D);
|
ParseDeclarator(D);
|
||||||
return D.getInvalidType();
|
return D.getInvalidType();
|
||||||
}
|
}
|
||||||
|
|
|
@ -522,6 +522,7 @@ Parser::DeclTy *Parser::ParseFunctionDefinition(Declarator &D) {
|
||||||
D.getMutableDeclSpec().SetTypeSpecType(DeclSpec::TST_int,
|
D.getMutableDeclSpec().SetTypeSpecType(DeclSpec::TST_int,
|
||||||
D.getIdentifierLoc(),
|
D.getIdentifierLoc(),
|
||||||
PrevSpec);
|
PrevSpec);
|
||||||
|
D.SetRangeBegin(D.getDeclSpec().getSourceRange().getBegin());
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this declaration was formed with a K&R-style identifier list for the
|
// If this declaration was formed with a K&R-style identifier list for the
|
||||||
|
@ -702,7 +703,7 @@ Parser::OwningExprResult Parser::ParseAsmStringLiteral() {
|
||||||
/// [GNU] simple-asm-expr:
|
/// [GNU] simple-asm-expr:
|
||||||
/// 'asm' '(' asm-string-literal ')'
|
/// 'asm' '(' asm-string-literal ')'
|
||||||
///
|
///
|
||||||
Parser::OwningExprResult Parser::ParseSimpleAsm() {
|
Parser::OwningExprResult Parser::ParseSimpleAsm(SourceLocation *EndLoc) {
|
||||||
assert(Tok.is(tok::kw_asm) && "Not an asm!");
|
assert(Tok.is(tok::kw_asm) && "Not an asm!");
|
||||||
SourceLocation Loc = ConsumeToken();
|
SourceLocation Loc = ConsumeToken();
|
||||||
|
|
||||||
|
@ -711,14 +712,20 @@ Parser::OwningExprResult Parser::ParseSimpleAsm() {
|
||||||
return ExprError();
|
return ExprError();
|
||||||
}
|
}
|
||||||
|
|
||||||
ConsumeParen();
|
Loc = ConsumeParen();
|
||||||
|
|
||||||
OwningExprResult Result(ParseAsmStringLiteral());
|
OwningExprResult Result(ParseAsmStringLiteral());
|
||||||
|
|
||||||
if (Result.isInvalid())
|
if (Result.isInvalid()) {
|
||||||
SkipUntil(tok::r_paren);
|
SkipUntil(tok::r_paren, true, true);
|
||||||
else
|
if (EndLoc)
|
||||||
MatchRHSPunctuation(tok::r_paren, Loc);
|
*EndLoc = Tok.getLocation();
|
||||||
|
ConsumeAnyToken();
|
||||||
|
} else {
|
||||||
|
Loc = MatchRHSPunctuation(tok::r_paren, Loc);
|
||||||
|
if (EndLoc)
|
||||||
|
*EndLoc = Loc;
|
||||||
|
}
|
||||||
|
|
||||||
return move(Result);
|
return move(Result);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2770,7 +2770,8 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc,
|
||||||
Error = Error; // Silence warning.
|
Error = 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, 0, 0, 0, Loc, D));
|
D.AddTypeInfo(DeclaratorChunk::getFunction(false, false, 0, 0, 0, Loc, D),
|
||||||
|
SourceLocation());
|
||||||
D.SetIdentifier(&II, Loc);
|
D.SetIdentifier(&II, Loc);
|
||||||
|
|
||||||
// Insert this function into translation-unit scope.
|
// Insert this function into translation-unit scope.
|
||||||
|
|
Loading…
Reference in New Issue