diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 6 | ||||
-rw-r--r-- | lib/Parse/ParseTentative.cpp | 4 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 16 | ||||
-rw-r--r-- | lib/Sema/SemaExprObjC.cpp | 13 |
4 files changed, 39 insertions, 0 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index f73907a7c4..d898447ab5 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -3652,6 +3652,9 @@ bool Parser::isTypeSpecifierQualifier() { case tok::kw_volatile: case tok::kw_restrict: + // Debugger support. + case tok::kw___unknown_anytype: + // typedef-name case tok::annot_typename: return true; @@ -3751,6 +3754,9 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) { // Modules case tok::kw___module_private__: + // Debugger support + case tok::kw___unknown_anytype: + // type-specifiers case tok::kw_short: case tok::kw_long: diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp index 40c4eee199..b26181f08e 100644 --- a/lib/Parse/ParseTentative.cpp +++ b/lib/Parse/ParseTentative.cpp @@ -837,6 +837,7 @@ Parser::isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind) { case tok::kw___vector: case tok::kw___pixel: case tok::kw__Atomic: + case tok::kw___unknown_anytype: return TPResult::False(); default: @@ -1056,6 +1057,9 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult, // Modules case tok::kw___module_private__: + + // Debugger support + case tok::kw___unknown_anytype: // type-specifier: // simple-type-specifier diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index bf4abfcb74..58c212b62f 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -11850,6 +11850,22 @@ ExprResult Sema::forceUnknownAnyToType(Expr *E, QualType ToType) { return RebuildUnknownAnyExpr(*this, ToType).Visit(E); } +QualType Sema::checkUnknownAnyArg(Expr *&arg) { + // Filter out placeholders. + ExprResult argR = CheckPlaceholderExpr(arg); + if (argR.isInvalid()) return QualType(); + arg = argR.take(); + + // If the argument is an explicit cast, use that exact type as the + // effective parameter type. + if (ExplicitCastExpr *castArg = dyn_cast<ExplicitCastExpr>(arg)) { + return castArg->getTypeAsWritten(); + } + + // Otherwise, try to pass by value. + return arg->getType().getUnqualifiedType(); +} + static ExprResult diagnoseUnknownAnyExpr(Sema &S, Expr *E) { Expr *orig = E; unsigned diagID = diag::err_uncasted_use_of_unknown_any; diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index e43b6bff55..b0f9958bb5 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -1196,6 +1196,19 @@ bool Sema::CheckMessageArgumentTypes(QualType ReceiverType, !param->hasAttr<CFConsumedAttr>()) argExpr = stripARCUnbridgedCast(argExpr); + // If the parameter is __unknown_anytype, infer its type + // from the argument. + if (param->getType() == Context.UnknownAnyTy) { + QualType paramType = checkUnknownAnyArg(argExpr); + if (paramType.isNull()) { + IsError = true; + continue; + } + + // Update the parameter type in-place. + param->setType(paramType); + } + if (RequireCompleteType(argExpr->getSourceRange().getBegin(), param->getType(), diag::err_call_incomplete_argument, argExpr)) |