aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/ASTContext.cpp3
-rw-r--r--lib/AST/ASTImporter.cpp1
-rw-r--r--lib/AST/Expr.cpp2
-rw-r--r--lib/AST/ExprConstant.cpp2
-rw-r--r--lib/AST/ItaniumMangle.cpp1
-rw-r--r--lib/AST/MicrosoftMangle.cpp1
-rw-r--r--lib/AST/Type.cpp1
-rw-r--r--lib/AST/TypeLoc.cpp1
-rw-r--r--lib/CodeGen/CGExpr.cpp6
-rw-r--r--lib/CodeGen/CGExprAgg.cpp4
-rw-r--r--lib/CodeGen/CGExprConstant.cpp1
-rw-r--r--lib/CodeGen/CGExprScalar.cpp3
-rw-r--r--lib/CodeGen/CGRTTI.cpp1
-rw-r--r--lib/CodeGen/CodeGenModule.cpp50
-rw-r--r--lib/CodeGen/CodeGenModule.h2
-rw-r--r--lib/CodeGen/CodeGenTypes.cpp5
-rw-r--r--lib/Sema/SemaCXXCast.cpp1
-rw-r--r--lib/Sema/SemaExpr.cpp220
-rw-r--r--lib/Serialization/ASTCommon.cpp1
-rw-r--r--lib/Serialization/ASTReader.cpp1
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp3
21 files changed, 271 insertions, 39 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index e208bfdf1d..01e8f8e396 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -402,6 +402,9 @@ void ASTContext::InitBuiltinTypes() {
// Placeholder type for functions.
InitBuiltinType(OverloadTy, BuiltinType::Overload);
+ // "any" type; useful for debugger-like clients.
+ InitBuiltinType(UnknownAnyTy, BuiltinType::UnknownAny);
+
// C99 6.2.5p11.
FloatComplexTy = getComplexType(FloatTy);
DoubleComplexTy = getComplexType(DoubleTy);
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index c92087d85f..3cc9670c34 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -1360,6 +1360,7 @@ QualType ASTNodeImporter::VisitBuiltinType(const BuiltinType *T) {
case BuiltinType::Overload: return Importer.getToContext().OverloadTy;
case BuiltinType::Dependent: return Importer.getToContext().DependentTy;
+ case BuiltinType::UnknownAny: return Importer.getToContext().UnknownAnyTy;
case BuiltinType::ObjCId:
// FIXME: Make sure that the "to" context supports Objective-C!
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 59de3fe6ee..28f42124f9 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -1055,6 +1055,8 @@ const char *CastExpr::getCastKindName() const {
return "IntegralComplexCast";
case CK_IntegralComplexToFloatingComplex:
return "IntegralComplexToFloatingComplex";
+ case CK_ResolveUnknownAnyType:
+ return "ResolveUnknownAnyType";
}
llvm_unreachable("Unhandled cast kind!");
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index cdd7efaaf5..e0f9958298 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -1798,6 +1798,7 @@ bool IntExprEvaluator::VisitCastExpr(CastExpr *E) {
case CK_GetObjCProperty:
case CK_LValueBitCast:
case CK_UserDefinedConversion:
+ case CK_ResolveUnknownAnyType:
return false;
case CK_LValueToRValue:
@@ -2351,6 +2352,7 @@ bool ComplexExprEvaluator::VisitCastExpr(CastExpr *E) {
case CK_GetObjCProperty:
case CK_LValueBitCast:
case CK_UserDefinedConversion:
+ case CK_ResolveUnknownAnyType:
return false;
case CK_FloatingRealToComplex: {
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index 6ab68dbae9..be17ccf2d8 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -1327,6 +1327,7 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
case BuiltinType::Overload:
case BuiltinType::Dependent:
+ case BuiltinType::UnknownAny:
assert(false &&
"Overloaded and dependent types shouldn't get to name mangling");
break;
diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp
index 4bf7f23a0a..5b4dc5a191 100644
--- a/lib/AST/MicrosoftMangle.cpp
+++ b/lib/AST/MicrosoftMangle.cpp
@@ -717,6 +717,7 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T) {
case BuiltinType::Overload:
case BuiltinType::Dependent:
+ case BuiltinType::UnknownAny:
assert(false &&
"Overloaded and dependent types shouldn't get to name mangling");
break;
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 3224f642bc..b0726e4275 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -1132,6 +1132,7 @@ const char *BuiltinType::getName(const LangOptions &LO) const {
case NullPtr: return "nullptr_t";
case Overload: return "<overloaded function type>";
case Dependent: return "<dependent type>";
+ case UnknownAny: return "<unknown type>";
case ObjCId: return "id";
case ObjCClass: return "Class";
case ObjCSel: return "SEL";
diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp
index 0873e837d8..cc64830428 100644
--- a/lib/AST/TypeLoc.cpp
+++ b/lib/AST/TypeLoc.cpp
@@ -234,6 +234,7 @@ TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const {
case BuiltinType::NullPtr:
case BuiltinType::Overload:
case BuiltinType::Dependent:
+ case BuiltinType::UnknownAny:
case BuiltinType::ObjCId:
case BuiltinType::ObjCClass:
case BuiltinType::ObjCSel:
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 92e6a19c25..a35f81ca20 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -1930,6 +1930,12 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
ConvertType(ToType));
return MakeAddrLValue(V, E->getType());
}
+ case CK_ResolveUnknownAnyType: {
+ const DeclRefExpr *declRef = cast<DeclRefExpr>(E->getSubExpr());
+ llvm::Constant *addr = CGM.getAddrOfUnknownAnyDecl(declRef->getDecl(),
+ E->getType());
+ return MakeAddrLValue(addr, E->getType());
+ }
}
llvm_unreachable("Unhandled lvalue cast kind?");
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp
index eb64996bd3..75e3a7879d 100644
--- a/lib/CodeGen/CGExprAgg.cpp
+++ b/lib/CodeGen/CGExprAgg.cpp
@@ -309,6 +309,10 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) {
case CK_LValueBitCast:
llvm_unreachable("should not be emitting lvalue bitcast as rvalue");
break;
+
+ case CK_ResolveUnknownAnyType:
+ EmitAggLoadOfLValue(E);
+ break;
case CK_Dependent:
case CK_BitCast:
diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp
index 3a2fb9bd9d..822a999b96 100644
--- a/lib/CodeGen/CGExprConstant.cpp
+++ b/lib/CodeGen/CGExprConstant.cpp
@@ -552,6 +552,7 @@ public:
case CK_GetObjCProperty:
case CK_ToVoid:
case CK_Dynamic:
+ case CK_ResolveUnknownAnyType:
return 0;
// These might need to be supported for constexpr.
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index 97effaa515..a3c765e352 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -1126,6 +1126,9 @@ Value *ScalarExprEmitter::EmitCastExpr(CastExpr *CE) {
RValue RV = CGF.EmitLoadOfLValue(CGF.EmitLValue(E), E->getType());
return RV.getScalarVal();
}
+
+ case CK_ResolveUnknownAnyType:
+ return EmitLoadOfLValue(CE);
case CK_LValueToRValue:
assert(CGF.getContext().hasSameUnqualifiedType(E->getType(), DestTy));
diff --git a/lib/CodeGen/CGRTTI.cpp b/lib/CodeGen/CGRTTI.cpp
index e276d98f12..0726641030 100644
--- a/lib/CodeGen/CGRTTI.cpp
+++ b/lib/CodeGen/CGRTTI.cpp
@@ -196,6 +196,7 @@ static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) {
case BuiltinType::Overload:
case BuiltinType::Dependent:
+ case BuiltinType::UnknownAny:
assert(false && "Should not see this type here!");
case BuiltinType::ObjCId:
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 34f594ecaa..fe8462bc7c 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -1072,12 +1072,60 @@ llvm::Constant *CodeGenModule::GetAddrOfGlobalVar(const VarDecl *D,
return GetOrCreateLLVMGlobal(MangledName, PTy, D);
}
+/// getAddrOfUnknownAnyDecl - Return an llvm::Constant for the address
+/// of a global which was declared with unknown type. It is possible
+/// for a VarDecl to end up getting resolved to have function type,
+/// which complicates this substantially; on the other hand, these are
+/// always external references, which does simplify the logic a lot.
+llvm::Constant *
+CodeGenModule::getAddrOfUnknownAnyDecl(const NamedDecl *decl, QualType type) {
+ GlobalDecl global;
+
+ // FunctionDecls will always end up with function types, but
+ // VarDecls can end up with them too.
+ if (isa<FunctionDecl>(decl))
+ global = GlobalDecl(cast<FunctionDecl>(decl));
+ else
+ global = GlobalDecl(cast<VarDecl>(decl));
+ llvm::StringRef mangledName = getMangledName(global);
+
+ const llvm::Type *ty = getTypes().ConvertTypeForMem(type);
+ const llvm::PointerType *pty =
+ llvm::PointerType::get(ty, getContext().getTargetAddressSpace(type));
+
+
+ // Check for an existing global value with this name.
+ llvm::GlobalValue *entry = GetGlobalValue(mangledName);
+ if (entry)
+ return llvm::ConstantExpr::getBitCast(entry, pty);
+
+ // If we're creating something with function type, go ahead and
+ // create a function.
+ if (const llvm::FunctionType *fnty = dyn_cast<llvm::FunctionType>(ty)) {
+ llvm::Function *fn = llvm::Function::Create(fnty,
+ llvm::Function::ExternalLinkage,
+ mangledName, &getModule());
+ return fn;
+
+ // Otherwise, make a global variable.
+ } else {
+ llvm::GlobalVariable *var
+ = new llvm::GlobalVariable(getModule(), ty, false,
+ llvm::GlobalValue::ExternalLinkage,
+ 0, mangledName, 0,
+ false, pty->getAddressSpace());
+ if (isa<VarDecl>(decl) && cast<VarDecl>(decl)->isThreadSpecified())
+ var->setThreadLocal(true);
+ return var;
+ }
+}
+
/// CreateRuntimeVariable - Create a new runtime global variable with the
/// specified type and name.
llvm::Constant *
CodeGenModule::CreateRuntimeVariable(const llvm::Type *Ty,
llvm::StringRef Name) {
- return GetOrCreateLLVMGlobal(Name, llvm::PointerType::getUnqual(Ty), 0,
+ return GetOrCreateLLVMGlobal(Name, llvm::PointerType::getUnqual(Ty), 0,
true);
}
diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h
index 0f86257757..b29437d962 100644
--- a/lib/CodeGen/CodeGenModule.h
+++ b/lib/CodeGen/CodeGenModule.h
@@ -358,6 +358,8 @@ public:
llvm::Constant *GetAddrOfGlobalVar(const VarDecl *D,
const llvm::Type *Ty = 0);
+ llvm::Constant *getAddrOfUnknownAnyDecl(const NamedDecl *D, QualType type);
+
/// GetAddrOfFunction - Return the address of the given function. If Ty is
/// non-null, then this function will use the specified type if it has to
/// create it.
diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp
index b9acbc4e9b..13aa23d8d0 100644
--- a/lib/CodeGen/CodeGenTypes.cpp
+++ b/lib/CodeGen/CodeGenTypes.cpp
@@ -253,10 +253,11 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) {
case BuiltinType::Overload:
case BuiltinType::Dependent:
- assert(0 && "Unexpected builtin type!");
+ case BuiltinType::UnknownAny:
+ llvm_unreachable("Unexpected builtin type!");
break;
}
- assert(0 && "Unknown builtin type!");
+ llvm_unreachable("Unknown builtin type!");
break;
}
case Type::Complex: {
diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp
index d10042ad03..e519d1db17 100644
--- a/lib/Sema/SemaCXXCast.cpp
+++ b/lib/Sema/SemaCXXCast.cpp
@@ -1590,3 +1590,4 @@ Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, ExprValueKind &VK,
return tcr != TC_Success;
}
+
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 13ac32dcb1..b62b2eeff1 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -4658,6 +4658,47 @@ Sema::ActOnCUDAExecConfigExpr(Scope *S, SourceLocation LLLLoc,
return ActOnCallExpr(S, ConfigDR, LLLLoc, execConfig, GGGLoc, 0);
}
+/// Given a function expression of unknown-any type, rebuild it to
+/// have a type appropriate for being called with the given arguments,
+/// yielding a value of unknown-any type.
+static ExprResult rebuildUnknownAnyFunction(Sema &S, Expr *fn,
+ Expr **args, unsigned numArgs) {
+ // Build a simple function type exactly matching the arguments.
+ llvm::SmallVector<QualType, 8> argTypes;
+ argTypes.reserve(numArgs);
+ for (unsigned i = 0; i != numArgs; ++i) {
+ // Require all the sub-expression to not be placeholders.
+ ExprResult result = S.CheckPlaceholderExpr(args[i], SourceLocation());
+ if (result.isInvalid()) return ExprError();
+ args[i] = result.take();
+
+ // Do l2r conversions on all the arguments.
+ S.DefaultLvalueConversion(args[i]);
+
+ argTypes.push_back(args[i]->getType());
+ }
+
+ // Resolve the symbol to a function type that returns an unknown-any
+ // type. In the fully resolved expression, this cast will surround
+ // the DeclRefExpr.
+ FunctionProtoType::ExtProtoInfo extInfo;
+ QualType fnType = S.Context.getFunctionType(S.Context.UnknownAnyTy,
+ argTypes.data(), numArgs,
+ extInfo);
+ fn = ImplicitCastExpr::Create(S.Context, fnType,
+ CK_ResolveUnknownAnyType,
+ fn, /*path*/ 0,
+ (S.getLangOptions().CPlusPlus ? VK_LValue : VK_RValue));
+
+ // Decay that to a pointer.
+ fnType = S.Context.getPointerType(fnType);
+ fn = ImplicitCastExpr::Create(S.Context, fnType,
+ CK_FunctionToPointerDecay,
+ fn, /*path*/ 0, VK_RValue);
+
+ return S.Owned(fn);
+}
+
/// BuildResolvedCallExpr - Build a call to a resolved expression,
/// i.e. an expression not of \p OverloadTy. The expression should
/// unary-convert to an expression of function-pointer or
@@ -4699,6 +4740,7 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
if (BuiltinID && Context.BuiltinInfo.hasCustomTypechecking(BuiltinID))
return CheckBuiltinFunctionCall(BuiltinID, TheCall);
+ retry:
const FunctionType *FuncT;
if (const PointerType *PT = Fn->getType()->getAs<PointerType>()) {
// C99 6.5.2.2p1 - "The expression that denotes the called function shall
@@ -4711,6 +4753,15 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
Fn->getType()->getAs<BlockPointerType>()) {
FuncT = BPT->getPointeeType()->castAs<FunctionType>();
} else {
+ // Handle calls to expressions of unknown-any type.
+ if (Fn->getType() == Context.UnknownAnyTy) {
+ ExprResult rewrite = rebuildUnknownAnyFunction(*this, Fn, Args, NumArgs);
+ if (rewrite.isInvalid()) return ExprError();
+ Fn = rewrite.take();
+ NDecl = FDecl = 0;
+ goto retry;
+ }
+
return ExprError(Diag(LParenLoc, diag::err_typecheck_call_not_function)
<< Fn->getType() << Fn->getSourceRange());
}
@@ -5038,6 +5089,9 @@ static CastKind PrepareScalarCast(Sema &S, Expr *&Src, QualType DestTy) {
bool Sema::CheckCastTypes(SourceRange TyR, QualType castType,
Expr *&castExpr, CastKind& Kind, ExprValueKind &VK,
CXXCastPath &BasePath, bool FunctionalStyle) {
+ if (castExpr->getType() == Context.UnknownAnyTy)
+ return checkUnknownAnyCast(TyR, castType, castExpr, Kind, VK, BasePath);
+
if (getLangOptions().CPlusPlus)
return CXXCheckCStyleCast(SourceRange(TyR.getBegin(),
castExpr->getLocEnd()),
@@ -5398,19 +5452,13 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
SourceLocation QuestionLoc) {
// If either LHS or RHS are overloaded functions, try to resolve them.
- if (LHS->getType() == Context.OverloadTy ||
- RHS->getType() == Context.OverloadTy) {
- ExprResult LHSResult = CheckPlaceholderExpr(LHS, QuestionLoc);
- if (LHSResult.isInvalid())
- return QualType();
-
- ExprResult RHSResult = CheckPlaceholderExpr(RHS, QuestionLoc);
- if (RHSResult.isInvalid())
- return QualType();
+ ExprResult lhsResult = CheckPlaceholderExpr(LHS, QuestionLoc);
+ if (!lhsResult.isUsable()) return QualType();
+ LHS = lhsResult.take();
- LHS = LHSResult.take();
- RHS = RHSResult.take();
- }
+ ExprResult rhsResult = CheckPlaceholderExpr(RHS, QuestionLoc);
+ if (!rhsResult.isUsable()) return QualType();
+ RHS = rhsResult.take();
// C++ is sufficiently different to merit its own checker.
if (getLangOptions().CPlusPlus)
@@ -8161,16 +8209,13 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
// f<int> == 0; // resolve f<int> blindly
// void (*p)(int); p = f<int>; // resolve f<int> using target
if (Opc != BO_Assign) {
- if (lhs->getType() == Context.OverloadTy) {
- ExprResult resolvedLHS =
- ResolveAndFixSingleFunctionTemplateSpecialization(lhs);
- if (resolvedLHS.isUsable()) lhs = resolvedLHS.release();
- }
- if (rhs->getType() == Context.OverloadTy) {
- ExprResult resolvedRHS =
- ResolveAndFixSingleFunctionTemplateSpecialization(rhs);
- if (resolvedRHS.isUsable()) rhs = resolvedRHS.release();
- }
+ ExprResult resolvedLHS = CheckPlaceholderExpr(lhs, OpLoc);
+ if (!resolvedLHS.isUsable()) return ExprError();
+ lhs = resolvedLHS.take();
+
+ ExprResult resolvedRHS = CheckPlaceholderExpr(rhs, OpLoc);
+ if (!resolvedRHS.isUsable()) return ExprError();
+ rhs = resolvedRHS.take();
}
switch (Opc) {
@@ -8529,15 +8574,14 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
case UO_AddrOf:
resultType = CheckAddressOfOperand(*this, Input, OpLoc);
break;
- case UO_Deref:
- if (Input->getType() == Context.OverloadTy ) {
- ExprResult er = ResolveAndFixSingleFunctionTemplateSpecialization(Input);
- if (er.isUsable())
- Input = er.release();
- }
+ case UO_Deref: {
+ ExprResult resolved = CheckPlaceholderExpr(Input, OpLoc);
+ if (!resolved.isUsable()) return ExprError();
+ Input = resolved.take();
DefaultFunctionArrayLvalueConversion(Input);
resultType = CheckIndirectionOperand(*this, Input, VK, OpLoc);
break;
+ }
case UO_Plus:
case UO_Minus:
UsualUnaryConversions(Input);
@@ -9904,16 +9948,122 @@ ExprResult Sema::ActOnBooleanCondition(Scope *S, SourceLocation Loc,
return Owned(Sub);
}
+namespace {
+ struct RebuildUnknownAnyExpr
+ : StmtVisitor<RebuildUnknownAnyExpr, Expr*> {
+
+ Sema &S;
+
+ /// The current destination type.
+ QualType DestType;
+
+ RebuildUnknownAnyExpr(Sema &S, QualType castType)
+ : S(S), DestType(castType) {}
+
+ Expr *VisitStmt(Stmt *S) {
+ llvm_unreachable("unexpected expression kind!");
+ return 0;
+ }
+
+ Expr *VisitCallExpr(CallExpr *call) {
+ call->setCallee(Visit(call->getCallee()));
+ return call;
+ }
+
+ Expr *VisitParenExpr(ParenExpr *paren) {
+ paren->setSubExpr(Visit(paren->getSubExpr()));
+ return paren;
+ }
+
+ Expr *VisitUnaryExtension(UnaryOperator *op) {
+ op->setSubExpr(Visit(op->getSubExpr()));
+ return op;
+ }
+
+ Expr *VisitImplicitCastExpr(ImplicitCastExpr *ice) {
+ // If this isn't an inner resolution, just recurse down.
+ if (ice->getCastKind() != CK_ResolveUnknownAnyType) {
+ assert(ice->getCastKind() == CK_FunctionToPointerDecay);
+ ice->setSubExpr(Visit(ice->getSubExpr()));
+ return ice;
+ }
+
+ QualType type = ice->getType();
+ assert(type.getUnqualifiedType() == type);
+
+ // The only time it should be possible for this to appear
+ // internally to an unknown-any expression is when handling a call.
+ const FunctionProtoType *proto = type->castAs<FunctionProtoType>();
+ DestType = S.Context.getFunctionType(DestType,
+ proto->arg_type_begin(),
+ proto->getNumArgs(),
+ proto->getExtProtoInfo());
+
+ // Strip the resolve cast when recursively rebuilding.
+ return Visit(ice->getSubExpr());
+ }
+
+ Expr *VisitDeclRefExpr(DeclRefExpr *ref) {
+ ExprValueKind valueKind = VK_LValue;
+ if (!S.getLangOptions().CPlusPlus && DestType->isFunctionType())
+ valueKind = VK_RValue;
+
+ return ImplicitCastExpr::Create(S.Context, DestType,
+ CK_ResolveUnknownAnyType,
+ ref, 0, valueKind);
+ }
+ };
+}
+
+/// Check a cast of an unknown-any type. We intentionally only
+/// trigger this for C-style casts.
+bool Sema::checkUnknownAnyCast(SourceRange typeRange, QualType castType,
+ Expr *&castExpr, CastKind &castKind,
+ ExprValueKind &VK, CXXCastPath &path) {
+ VK = Expr::getValueKindForType(castType);
+
+ // Rewrite the casted expression from scratch.
+ castExpr = RebuildUnknownAnyExpr(*this, castType).Visit(castExpr);
+
+ return CheckCastTypes(typeRange, castType, castExpr, castKind, VK, path);
+}
+
+static ExprResult diagnoseUnknownAnyExpr(Sema &S, Expr *e) {
+ Expr *orig = e;
+ while (true) {
+ e = e->IgnoreParenImpCasts();
+ if (CallExpr *call = dyn_cast<CallExpr>(e))
+ e = call->getCallee();
+ else
+ break;
+ }
+
+ assert(isa<DeclRefExpr>(e) && "unexpected form of unknown-any expression");
+ DeclRefExpr *ref = cast<DeclRefExpr>(e);
+ S.Diag(ref->getLocation(), diag::err_bad_use_of_unknown_any)
+ << ref->getDecl() << orig->getSourceRange();
+
+ // Never recoverable.
+ return ExprError();
+}
+
/// Check for operands with placeholder types and complain if found.
/// Returns true if there was an error and no recovery was possible.
ExprResult Sema::CheckPlaceholderExpr(Expr *E, SourceLocation Loc) {
- const BuiltinType *BT = E->getType()->getAs<BuiltinType>();
- if (!BT || !BT->isPlaceholderType()) return Owned(E);
+ // Placeholder types are always *exactly* the appropriate builtin type.
+ QualType type = E->getType();
- // If this is overload, check for a single overload.
- assert(BT->getKind() == BuiltinType::Overload);
- return ResolveAndFixSingleFunctionTemplateSpecialization(E, false, true,
+ // Overloaded expressions.
+ if (type == Context.OverloadTy)
+ return ResolveAndFixSingleFunctionTemplateSpecialization(E, false, true,
E->getSourceRange(),
- QualType(),
- diag::err_ovl_unresolvable);
+ QualType(),
+ diag::err_ovl_unresolvable);
+
+ // Expressions of unknown type.
+ if (type == Context.UnknownAnyTy)
+ return diagnoseUnknownAnyExpr(*this, E);
+
+ assert(!type->isPlaceholderType());
+ return Owned(E);
}
diff --git a/lib/Serialization/ASTCommon.cpp b/lib/Serialization/ASTCommon.cpp
index 5e94f59ad4..b5bbe74ce3 100644
--- a/lib/Serialization/ASTCommon.cpp
+++ b/lib/Serialization/ASTCommon.cpp
@@ -51,6 +51,7 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) {
case BuiltinType::Char32: ID = PREDEF_TYPE_CHAR32_ID; break;
case BuiltinType::Overload: ID = PREDEF_TYPE_OVERLOAD_ID; break;
case BuiltinType::Dependent: ID = PREDEF_TYPE_DEPENDENT_ID; break;
+ case BuiltinType::UnknownAny: ID = PREDEF_TYPE_UNKNOWN_ANY; break;
case BuiltinType::ObjCId: ID = PREDEF_TYPE_OBJC_ID; break;
case BuiltinType::ObjCClass: ID = PREDEF_TYPE_OBJC_CLASS; break;
case BuiltinType::ObjCSel: ID = PREDEF_TYPE_OBJC_SEL; break;
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 1b55f71c36..4cbb81d1ac 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -3622,6 +3622,7 @@ QualType ASTReader::GetType(TypeID ID) {
case PREDEF_TYPE_LONGDOUBLE_ID: T = Context->LongDoubleTy; break;
case PREDEF_TYPE_OVERLOAD_ID: T = Context->OverloadTy; break;
case PREDEF_TYPE_DEPENDENT_ID: T = Context->DependentTy; break;
+ case PREDEF_TYPE_UNKNOWN_ANY: T = Context->UnknownAnyTy; break;
case PREDEF_TYPE_NULLPTR_ID: T = Context->NullPtrTy; break;
case PREDEF_TYPE_CHAR16_ID: T = Context->Char16Ty; break;
case PREDEF_TYPE_CHAR32_ID: T = Context->Char32Ty; break;
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index a422428b1b..2fd7b3b88a 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -2170,7 +2170,8 @@ void ExprEngine::VisitCast(const CastExpr *CastE, const Expr *Ex,
continue;
}
// Various C++ casts that are not handled yet.
- case CK_Dynamic:
+ case CK_ResolveUnknownAnyType:
+ case CK_Dynamic:
case CK_ToUnion:
case CK_BaseToDerived:
case CK_NullToMemberPointer: