forked from OSchip/llvm-project
Add an explicit LambdaExprContext to Declarator, to parallel BlockLiteralContext. Use it to ensure semantic analysis of types isn't confused by the lack of a type specifier.
llvm-svn: 147522
This commit is contained in:
parent
91a3f886ef
commit
36d129435e
|
@ -1416,6 +1416,7 @@ public:
|
|||
CXXCatchContext, // C++ catch exception-declaration
|
||||
ObjCCatchContext, // Objective-C catch exception-declaration
|
||||
BlockLiteralContext, // Block literal declarator.
|
||||
LambdaExprContext, // Lambda-expression declarator.
|
||||
TemplateTypeArgContext, // Template type argument.
|
||||
AliasDeclContext, // C++0x alias-declaration.
|
||||
AliasTemplateContext // C++0x alias-declaration template.
|
||||
|
@ -1582,6 +1583,7 @@ public:
|
|||
case CXXCatchContext:
|
||||
case ObjCCatchContext:
|
||||
case BlockLiteralContext:
|
||||
case LambdaExprContext:
|
||||
case TemplateTypeArgContext:
|
||||
return true;
|
||||
}
|
||||
|
@ -1612,6 +1614,7 @@ public:
|
|||
case ObjCParameterContext:
|
||||
case ObjCResultContext:
|
||||
case BlockLiteralContext:
|
||||
case LambdaExprContext:
|
||||
case TemplateTypeArgContext:
|
||||
return false;
|
||||
}
|
||||
|
@ -1643,6 +1646,7 @@ public:
|
|||
case AliasDeclContext:
|
||||
case AliasTemplateContext:
|
||||
case BlockLiteralContext:
|
||||
case LambdaExprContext:
|
||||
case TemplateTypeArgContext:
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -715,7 +715,7 @@ ExprResult Parser::ParseLambdaExpressionAfterIntroducer(
|
|||
|
||||
// Parse lambda-declarator[opt].
|
||||
DeclSpec DS(AttrFactory);
|
||||
Declarator D(DS, Declarator::BlockLiteralContext);
|
||||
Declarator D(DS, Declarator::LambdaExprContext);
|
||||
|
||||
if (Tok.is(tok::l_paren)) {
|
||||
ParseScope PrototypeScope(this,
|
||||
|
|
|
@ -4780,7 +4780,6 @@ Sema::CheckMicrosoftIfExistsSymbol(Scope *S, SourceLocation KeywordLoc,
|
|||
|
||||
void Sema::ActOnLambdaStart(SourceLocation StartLoc, Scope *CurScope) {
|
||||
// FIXME: Add lambda-scope
|
||||
// FIXME: Build lambda-decl
|
||||
// FIXME: PushDeclContext
|
||||
|
||||
// Enter a new evaluation context to insulate the block from any
|
||||
|
@ -4789,7 +4788,10 @@ void Sema::ActOnLambdaStart(SourceLocation StartLoc, Scope *CurScope) {
|
|||
}
|
||||
|
||||
void Sema::ActOnLambdaArguments(Declarator &ParamInfo, Scope *CurScope) {
|
||||
// FIXME: Implement
|
||||
TypeSourceInfo *MethodTyInfo;
|
||||
MethodTyInfo = GetTypeForDeclarator(ParamInfo, CurScope);
|
||||
|
||||
// FIXME: Build CXXMethodDecl
|
||||
}
|
||||
|
||||
void Sema::ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope) {
|
||||
|
|
|
@ -640,7 +640,10 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
|
|||
|
||||
// If this is a missing declspec in a block literal return context, then it
|
||||
// is inferred from the return statements inside the block.
|
||||
if (isOmittedBlockReturnType(declarator)) {
|
||||
// The declspec is always missing in a lambda expr context; it is either
|
||||
// specified with a trailing return type or inferred.
|
||||
if (declarator.getContext() == Declarator::LambdaExprContext ||
|
||||
isOmittedBlockReturnType(declarator)) {
|
||||
Result = Context.DependentTy;
|
||||
break;
|
||||
}
|
||||
|
@ -1785,6 +1788,9 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
|
|||
case Declarator::KNRTypeListContext:
|
||||
llvm_unreachable("K&R type lists aren't allowed in C++");
|
||||
break;
|
||||
case Declarator::LambdaExprContext:
|
||||
llvm_unreachable("Can't specify a type specifier in lambda grammar");
|
||||
break;
|
||||
case Declarator::ObjCParameterContext:
|
||||
case Declarator::ObjCResultContext:
|
||||
case Declarator::PrototypeContext:
|
||||
|
@ -1875,6 +1881,7 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
|
|||
case Declarator::BlockContext:
|
||||
case Declarator::ForContext:
|
||||
case Declarator::BlockLiteralContext:
|
||||
case Declarator::LambdaExprContext:
|
||||
// C++0x [dcl.type]p3:
|
||||
// A type-specifier-seq shall not define a class or enumeration unless
|
||||
// it appears in the type-id of an alias-declaration (7.1.3) that is not
|
||||
|
@ -2058,7 +2065,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
|
|||
diag::err_trailing_return_in_parens)
|
||||
<< T << D.getDeclSpec().getSourceRange();
|
||||
D.setInvalidType(true);
|
||||
} else if (T.hasQualifiers() || !isa<AutoType>(T)) {
|
||||
} else if (D.getContext() != Declarator::LambdaExprContext &&
|
||||
(T.hasQualifiers() || !isa<AutoType>(T))) {
|
||||
S.Diag(D.getDeclSpec().getTypeSpecTypeLoc(),
|
||||
diag::err_trailing_return_without_auto)
|
||||
<< T << D.getDeclSpec().getSourceRange();
|
||||
|
@ -2578,6 +2586,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
|
|||
case Declarator::CXXCatchContext:
|
||||
case Declarator::ObjCCatchContext:
|
||||
case Declarator::BlockLiteralContext:
|
||||
case Declarator::LambdaExprContext:
|
||||
case Declarator::TemplateTypeArgContext:
|
||||
// FIXME: We may want to allow parameter packs in block-literal contexts
|
||||
// in the future.
|
||||
|
|
Loading…
Reference in New Issue