Implement Declarator::getSourceRange().

llvm-svn: 64151
This commit is contained in:
Sebastian Redl 2009-02-09 18:23:29 +00:00
parent a950e99dee
commit f6591ca6d9
9 changed files with 273 additions and 118 deletions

View File

@ -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; }

View File

@ -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]

View File

@ -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:

View File

@ -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;
} }

View File

@ -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);
} }

View File

@ -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();
} }

View File

@ -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);
} }

View File

@ -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.