mirror of
https://github.com/intel/llvm.git
synced 2026-01-23 16:06:39 +08:00
If parsing a trailing-return-type fails, don't pretend we didn't have one at
all. Suppresses follow-on errors mentioned in PR13074. llvm-svn: 158348
This commit is contained in:
@@ -1104,6 +1104,10 @@ struct DeclaratorChunk {
|
||||
/// DeleteArgInfo - If this is true, we need to delete[] ArgInfo.
|
||||
unsigned DeleteArgInfo : 1;
|
||||
|
||||
/// HasTrailingReturnType - If this is true, a trailing return type was
|
||||
/// specified.
|
||||
unsigned HasTrailingReturnType : 1;
|
||||
|
||||
/// When isVariadic is true, the location of the ellipsis in the source.
|
||||
unsigned EllipsisLoc;
|
||||
|
||||
@@ -1154,10 +1158,9 @@ struct DeclaratorChunk {
|
||||
Expr *NoexceptExpr;
|
||||
};
|
||||
|
||||
/// TrailingReturnType - If this isn't null, it's the trailing return type
|
||||
/// specified. This is actually a ParsedType, but stored as void* to
|
||||
/// allow union storage.
|
||||
void *TrailingReturnType;
|
||||
/// TrailingReturnType - If HasTrailingReturnType is true, this is the
|
||||
/// trailing return type specified.
|
||||
UnionParsedType TrailingReturnType;
|
||||
|
||||
/// freeArgs - reset the argument list to having zero arguments. This is
|
||||
/// used in various places for error recovery.
|
||||
@@ -1222,6 +1225,13 @@ struct DeclaratorChunk {
|
||||
ExceptionSpecificationType getExceptionSpecType() const {
|
||||
return static_cast<ExceptionSpecificationType>(ExceptionSpecType);
|
||||
}
|
||||
|
||||
/// \brief Determine whether this function declarator had a
|
||||
/// trailing-return-type.
|
||||
bool hasTrailingReturnType() const { return HasTrailingReturnType; }
|
||||
|
||||
/// \brief Get the trailing-return-type for this function declarator.
|
||||
ParsedType getTrailingReturnType() const { return TrailingReturnType; }
|
||||
};
|
||||
|
||||
struct BlockPointerTypeInfo : TypeInfoCommon {
|
||||
@@ -1352,8 +1362,8 @@ struct DeclaratorChunk {
|
||||
SourceLocation LocalRangeBegin,
|
||||
SourceLocation LocalRangeEnd,
|
||||
Declarator &TheDeclarator,
|
||||
ParsedType TrailingReturnType =
|
||||
ParsedType());
|
||||
TypeResult TrailingReturnType =
|
||||
TypeResult());
|
||||
|
||||
/// getBlockPointer - Return a DeclaratorChunk for a block.
|
||||
///
|
||||
|
||||
@@ -4276,7 +4276,7 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
|
||||
SmallVector<SourceRange, 2> DynamicExceptionRanges;
|
||||
ExprResult NoexceptExpr;
|
||||
ParsedAttributes FnAttrs(AttrFactory);
|
||||
ParsedType TrailingReturnType;
|
||||
TypeResult TrailingReturnType;
|
||||
|
||||
Actions.ActOnStartFunctionDeclarator();
|
||||
|
||||
@@ -4358,7 +4358,7 @@ void Parser::ParseFunctionDeclarator(Declarator &D,
|
||||
if (getLangOpts().CPlusPlus0x && Tok.is(tok::arrow)) {
|
||||
Diag(Tok, diag::warn_cxx98_compat_trailing_return_type);
|
||||
SourceRange Range;
|
||||
TrailingReturnType = ParseTrailingReturnType(Range).get();
|
||||
TrailingReturnType = ParseTrailingReturnType(Range);
|
||||
if (Range.getEnd().isValid())
|
||||
EndLoc = Range.getEnd();
|
||||
}
|
||||
|
||||
@@ -792,10 +792,10 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
|
||||
MaybeParseCXX0XAttributes(Attr, &DeclEndLoc);
|
||||
|
||||
// Parse trailing-return-type[opt].
|
||||
ParsedType TrailingReturnType;
|
||||
TypeResult TrailingReturnType;
|
||||
if (Tok.is(tok::arrow)) {
|
||||
SourceRange Range;
|
||||
TrailingReturnType = ParseTrailingReturnType(Range).get();
|
||||
TrailingReturnType = ParseTrailingReturnType(Range);
|
||||
if (Range.getEnd().isValid())
|
||||
DeclEndLoc = Range.getEnd();
|
||||
}
|
||||
@@ -838,10 +838,10 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
|
||||
}
|
||||
|
||||
// Parse the return type, if there is one.
|
||||
ParsedType TrailingReturnType;
|
||||
TypeResult TrailingReturnType;
|
||||
if (Tok.is(tok::arrow)) {
|
||||
SourceRange Range;
|
||||
TrailingReturnType = ParseTrailingReturnType(Range).get();
|
||||
TrailingReturnType = ParseTrailingReturnType(Range);
|
||||
if (Range.getEnd().isValid())
|
||||
DeclEndLoc = Range.getEnd();
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
|
||||
SourceLocation LocalRangeBegin,
|
||||
SourceLocation LocalRangeEnd,
|
||||
Declarator &TheDeclarator,
|
||||
ParsedType TrailingReturnType) {
|
||||
TypeResult TrailingReturnType) {
|
||||
DeclaratorChunk I;
|
||||
I.Kind = Function;
|
||||
I.Loc = LocalRangeBegin;
|
||||
@@ -188,7 +188,9 @@ DeclaratorChunk DeclaratorChunk::getFunction(bool hasProto, bool isVariadic,
|
||||
I.Fun.NumExceptions = 0;
|
||||
I.Fun.Exceptions = 0;
|
||||
I.Fun.NoexceptExpr = 0;
|
||||
I.Fun.TrailingReturnType = TrailingReturnType.getAsOpaquePtr();
|
||||
I.Fun.HasTrailingReturnType = TrailingReturnType.isUsable() ||
|
||||
TrailingReturnType.isInvalid();
|
||||
I.Fun.TrailingReturnType = TrailingReturnType.get();
|
||||
|
||||
// new[] an argument array if needed.
|
||||
if (NumArgs) {
|
||||
|
||||
@@ -5158,7 +5158,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
|
||||
QualType T = R->getAs<FunctionType>()->getResultType();
|
||||
DeclaratorChunk &C = D.getTypeObject(0);
|
||||
if (!T->isVoidType() && C.Fun.NumArgs == 0 && !C.Fun.isVariadic &&
|
||||
!C.Fun.TrailingReturnType &&
|
||||
!C.Fun.hasTrailingReturnType() &&
|
||||
C.Fun.getExceptionSpecType() == EST_None) {
|
||||
SourceRange ParenRange(C.Loc, C.EndLoc);
|
||||
Diag(C.Loc, diag::warn_empty_parens_are_function_decl) << ParenRange;
|
||||
|
||||
@@ -1901,7 +1901,7 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
|
||||
DeclaratorChunk &DeclType = D.getTypeObject(chunkIndex);
|
||||
if (DeclType.Kind == DeclaratorChunk::Function) {
|
||||
const DeclaratorChunk::FunctionTypeInfo &FTI = DeclType.Fun;
|
||||
if (FTI.TrailingReturnType) {
|
||||
if (FTI.hasTrailingReturnType()) {
|
||||
Error = -1;
|
||||
break;
|
||||
}
|
||||
@@ -2176,12 +2176,12 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
|
||||
// trailing-return-type is only required if we're declaring a function,
|
||||
// and not, for instance, a pointer to a function.
|
||||
if (D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto &&
|
||||
!FTI.TrailingReturnType && chunkIndex == 0) {
|
||||
!FTI.hasTrailingReturnType() && chunkIndex == 0) {
|
||||
S.Diag(D.getDeclSpec().getTypeSpecTypeLoc(),
|
||||
diag::err_auto_missing_trailing_return);
|
||||
T = Context.IntTy;
|
||||
D.setInvalidType(true);
|
||||
} else if (FTI.TrailingReturnType) {
|
||||
} else if (FTI.hasTrailingReturnType()) {
|
||||
// T must be exactly 'auto' at this point. See CWG issue 681.
|
||||
if (isa<ParenType>(T)) {
|
||||
S.Diag(D.getDeclSpec().getTypeSpecTypeLoc(),
|
||||
@@ -2195,10 +2195,12 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
|
||||
<< T << D.getDeclSpec().getSourceRange();
|
||||
D.setInvalidType(true);
|
||||
}
|
||||
|
||||
T = S.GetTypeFromParser(
|
||||
ParsedType::getFromOpaquePtr(FTI.TrailingReturnType),
|
||||
&TInfo);
|
||||
T = S.GetTypeFromParser(FTI.getTrailingReturnType(), &TInfo);
|
||||
if (T.isNull()) {
|
||||
// An error occurred parsing the trailing return type.
|
||||
T = Context.IntTy;
|
||||
D.setInvalidType(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2301,7 +2303,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
|
||||
|
||||
FunctionProtoType::ExtProtoInfo EPI;
|
||||
EPI.Variadic = FTI.isVariadic;
|
||||
EPI.HasTrailingReturn = FTI.TrailingReturnType;
|
||||
EPI.HasTrailingReturn = FTI.hasTrailingReturnType();
|
||||
EPI.TypeQuals = FTI.TypeQuals;
|
||||
EPI.RefQualifier = !FTI.hasRefQualifier()? RQ_None
|
||||
: FTI.RefQualifierIsLValueRef? RQ_LValue
|
||||
@@ -3119,7 +3121,7 @@ namespace {
|
||||
assert(Chunk.Kind == DeclaratorChunk::Function);
|
||||
TL.setLocalRangeBegin(Chunk.Loc);
|
||||
TL.setLocalRangeEnd(Chunk.EndLoc);
|
||||
TL.setTrailingReturn(!!Chunk.Fun.TrailingReturnType);
|
||||
TL.setTrailingReturn(Chunk.Fun.hasTrailingReturnType());
|
||||
|
||||
const DeclaratorChunk::FunctionTypeInfo &FTI = Chunk.Fun;
|
||||
for (unsigned i = 0, e = TL.getNumArgs(), tpi = 0; i != e; ++i) {
|
||||
|
||||
@@ -64,5 +64,4 @@ template<typename T = auto> struct G { }; // expected-error{{'auto' not allowed
|
||||
|
||||
using A = auto; // expected-error{{'auto' not allowed in type alias}}
|
||||
|
||||
// FIXME: don't issue the second diagnostic for this error.
|
||||
auto k() -> auto; // expected-error{{'auto' not allowed in function return type}} unexpected-error{{without trailing return type}}
|
||||
auto k() -> auto; // expected-error{{'auto' not allowed in function return type}}
|
||||
|
||||
@@ -4,4 +4,4 @@
|
||||
// will necessarily be ill-formed as a trailing return type for a function
|
||||
// definition), and recover with a "type cannot be defined in a trailing return
|
||||
// type" error.
|
||||
auto j() -> enum { e3 }; // expected-error{{unnamed enumeration must be a definition}} expected-error {{expected a type}} expected-error {{without trailing return type}}
|
||||
auto j() -> enum { e3 }; // expected-error{{unnamed enumeration must be a definition}} expected-error {{expected a type}}
|
||||
|
||||
@@ -21,7 +21,4 @@ void f() {
|
||||
|
||||
// And for trailing-type-specifier-seq
|
||||
|
||||
// FIXME: Don't treat an ill-formed trailing-return-type the same as no
|
||||
// trailing-return-type, and avoid the second diagnostic.
|
||||
auto f() -> unknown; // expected-error{{unknown type name 'unknown'}} \
|
||||
expected-error{{'auto' return without trailing return type}}
|
||||
auto f() -> unknown; // expected-error{{unknown type name 'unknown'}}
|
||||
|
||||
Reference in New Issue
Block a user