forked from OSchip/llvm-project
Clean up the RebuildUnknownAnyExpr visitor in SemaExpr.cpp. Mainly swapped around variable names so that this visitor be more like other visitors in clang.
llvm-svn: 139351
This commit is contained in:
parent
9becef691d
commit
10162ab7ed
|
@ -9645,76 +9645,76 @@ namespace {
|
||||||
return ExprError();
|
return ExprError();
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprResult VisitExpr(Expr *expr) {
|
ExprResult VisitExpr(Expr *E) {
|
||||||
S.Diag(expr->getExprLoc(), diag::err_unsupported_unknown_any_call)
|
S.Diag(E->getExprLoc(), diag::err_unsupported_unknown_any_call)
|
||||||
<< expr->getSourceRange();
|
<< E->getSourceRange();
|
||||||
return ExprError();
|
return ExprError();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rebuild an expression which simply semantically wraps another
|
/// Rebuild an expression which simply semantically wraps another
|
||||||
/// expression which it shares the type and value kind of.
|
/// expression which it shares the type and value kind of.
|
||||||
template <class T> ExprResult rebuildSugarExpr(T *expr) {
|
template <class T> ExprResult rebuildSugarExpr(T *E) {
|
||||||
ExprResult subResult = Visit(expr->getSubExpr());
|
ExprResult SubResult = Visit(E->getSubExpr());
|
||||||
if (subResult.isInvalid()) return ExprError();
|
if (SubResult.isInvalid()) return ExprError();
|
||||||
|
|
||||||
Expr *subExpr = subResult.take();
|
Expr *SubExpr = SubResult.take();
|
||||||
expr->setSubExpr(subExpr);
|
E->setSubExpr(SubExpr);
|
||||||
expr->setType(subExpr->getType());
|
E->setType(SubExpr->getType());
|
||||||
expr->setValueKind(subExpr->getValueKind());
|
E->setValueKind(SubExpr->getValueKind());
|
||||||
assert(expr->getObjectKind() == OK_Ordinary);
|
assert(E->getObjectKind() == OK_Ordinary);
|
||||||
return expr;
|
return E;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprResult VisitParenExpr(ParenExpr *paren) {
|
ExprResult VisitParenExpr(ParenExpr *E) {
|
||||||
return rebuildSugarExpr(paren);
|
return rebuildSugarExpr(E);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprResult VisitUnaryExtension(UnaryOperator *op) {
|
ExprResult VisitUnaryExtension(UnaryOperator *E) {
|
||||||
return rebuildSugarExpr(op);
|
return rebuildSugarExpr(E);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprResult VisitUnaryAddrOf(UnaryOperator *op) {
|
ExprResult VisitUnaryAddrOf(UnaryOperator *E) {
|
||||||
ExprResult subResult = Visit(op->getSubExpr());
|
ExprResult SubResult = Visit(E->getSubExpr());
|
||||||
if (subResult.isInvalid()) return ExprError();
|
if (SubResult.isInvalid()) return ExprError();
|
||||||
|
|
||||||
Expr *subExpr = subResult.take();
|
Expr *SubExpr = SubResult.take();
|
||||||
op->setSubExpr(subExpr);
|
E->setSubExpr(SubExpr);
|
||||||
op->setType(S.Context.getPointerType(subExpr->getType()));
|
E->setType(S.Context.getPointerType(SubExpr->getType()));
|
||||||
assert(op->getValueKind() == VK_RValue);
|
assert(E->getValueKind() == VK_RValue);
|
||||||
assert(op->getObjectKind() == OK_Ordinary);
|
assert(E->getObjectKind() == OK_Ordinary);
|
||||||
return op;
|
return E;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprResult resolveDecl(Expr *expr, ValueDecl *decl) {
|
ExprResult resolveDecl(Expr *E, ValueDecl *VD) {
|
||||||
if (!isa<FunctionDecl>(decl)) return VisitExpr(expr);
|
if (!isa<FunctionDecl>(VD)) return VisitExpr(E);
|
||||||
|
|
||||||
expr->setType(decl->getType());
|
E->setType(VD->getType());
|
||||||
|
|
||||||
assert(expr->getValueKind() == VK_RValue);
|
assert(E->getValueKind() == VK_RValue);
|
||||||
if (S.getLangOptions().CPlusPlus &&
|
if (S.getLangOptions().CPlusPlus &&
|
||||||
!(isa<CXXMethodDecl>(decl) &&
|
!(isa<CXXMethodDecl>(VD) &&
|
||||||
cast<CXXMethodDecl>(decl)->isInstance()))
|
cast<CXXMethodDecl>(VD)->isInstance()))
|
||||||
expr->setValueKind(VK_LValue);
|
E->setValueKind(VK_LValue);
|
||||||
|
|
||||||
return expr;
|
return E;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprResult VisitMemberExpr(MemberExpr *mem) {
|
ExprResult VisitMemberExpr(MemberExpr *E) {
|
||||||
return resolveDecl(mem, mem->getMemberDecl());
|
return resolveDecl(E, E->getMemberDecl());
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprResult VisitDeclRefExpr(DeclRefExpr *ref) {
|
ExprResult VisitDeclRefExpr(DeclRefExpr *E) {
|
||||||
return resolveDecl(ref, ref->getDecl());
|
return resolveDecl(E, E->getDecl());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Given a function expression of unknown-any type, try to rebuild it
|
/// Given a function expression of unknown-any type, try to rebuild it
|
||||||
/// to have a function type.
|
/// to have a function type.
|
||||||
static ExprResult rebuildUnknownAnyFunction(Sema &S, Expr *fn) {
|
static ExprResult rebuildUnknownAnyFunction(Sema &S, Expr *FunctionExpr) {
|
||||||
ExprResult result = RebuildUnknownAnyFunction(S).Visit(fn);
|
ExprResult Result = RebuildUnknownAnyFunction(S).Visit(FunctionExpr);
|
||||||
if (result.isInvalid()) return ExprError();
|
if (Result.isInvalid()) return ExprError();
|
||||||
return S.DefaultFunctionArrayConversion(result.take());
|
return S.DefaultFunctionArrayConversion(Result.take());
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -9730,80 +9730,80 @@ namespace {
|
||||||
/// The current destination type.
|
/// The current destination type.
|
||||||
QualType DestType;
|
QualType DestType;
|
||||||
|
|
||||||
RebuildUnknownAnyExpr(Sema &S, QualType castType)
|
RebuildUnknownAnyExpr(Sema &S, QualType CastType)
|
||||||
: S(S), DestType(castType) {}
|
: S(S), DestType(CastType) {}
|
||||||
|
|
||||||
ExprResult VisitStmt(Stmt *S) {
|
ExprResult VisitStmt(Stmt *S) {
|
||||||
llvm_unreachable("unexpected statement!");
|
llvm_unreachable("unexpected statement!");
|
||||||
return ExprError();
|
return ExprError();
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprResult VisitExpr(Expr *expr) {
|
ExprResult VisitExpr(Expr *E) {
|
||||||
S.Diag(expr->getExprLoc(), diag::err_unsupported_unknown_any_expr)
|
S.Diag(E->getExprLoc(), diag::err_unsupported_unknown_any_expr)
|
||||||
<< expr->getSourceRange();
|
<< E->getSourceRange();
|
||||||
return ExprError();
|
return ExprError();
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprResult VisitCallExpr(CallExpr *call);
|
ExprResult VisitCallExpr(CallExpr *E);
|
||||||
ExprResult VisitObjCMessageExpr(ObjCMessageExpr *message);
|
ExprResult VisitObjCMessageExpr(ObjCMessageExpr *E);
|
||||||
|
|
||||||
/// Rebuild an expression which simply semantically wraps another
|
/// Rebuild an expression which simply semantically wraps another
|
||||||
/// expression which it shares the type and value kind of.
|
/// expression which it shares the type and value kind of.
|
||||||
template <class T> ExprResult rebuildSugarExpr(T *expr) {
|
template <class T> ExprResult rebuildSugarExpr(T *E) {
|
||||||
ExprResult subResult = Visit(expr->getSubExpr());
|
ExprResult SubResult = Visit(E->getSubExpr());
|
||||||
if (subResult.isInvalid()) return ExprError();
|
if (SubResult.isInvalid()) return ExprError();
|
||||||
Expr *subExpr = subResult.take();
|
Expr *SubExpr = SubResult.take();
|
||||||
expr->setSubExpr(subExpr);
|
E->setSubExpr(SubExpr);
|
||||||
expr->setType(subExpr->getType());
|
E->setType(SubExpr->getType());
|
||||||
expr->setValueKind(subExpr->getValueKind());
|
E->setValueKind(SubExpr->getValueKind());
|
||||||
assert(expr->getObjectKind() == OK_Ordinary);
|
assert(E->getObjectKind() == OK_Ordinary);
|
||||||
return expr;
|
return E;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprResult VisitParenExpr(ParenExpr *paren) {
|
ExprResult VisitParenExpr(ParenExpr *E) {
|
||||||
return rebuildSugarExpr(paren);
|
return rebuildSugarExpr(E);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprResult VisitUnaryExtension(UnaryOperator *op) {
|
ExprResult VisitUnaryExtension(UnaryOperator *E) {
|
||||||
return rebuildSugarExpr(op);
|
return rebuildSugarExpr(E);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprResult VisitUnaryAddrOf(UnaryOperator *op) {
|
ExprResult VisitUnaryAddrOf(UnaryOperator *E) {
|
||||||
const PointerType *ptr = DestType->getAs<PointerType>();
|
const PointerType *Ptr = DestType->getAs<PointerType>();
|
||||||
if (!ptr) {
|
if (!Ptr) {
|
||||||
S.Diag(op->getOperatorLoc(), diag::err_unknown_any_addrof)
|
S.Diag(E->getOperatorLoc(), diag::err_unknown_any_addrof)
|
||||||
<< op->getSourceRange();
|
<< E->getSourceRange();
|
||||||
return ExprError();
|
return ExprError();
|
||||||
}
|
}
|
||||||
assert(op->getValueKind() == VK_RValue);
|
assert(E->getValueKind() == VK_RValue);
|
||||||
assert(op->getObjectKind() == OK_Ordinary);
|
assert(E->getObjectKind() == OK_Ordinary);
|
||||||
op->setType(DestType);
|
E->setType(DestType);
|
||||||
|
|
||||||
// Build the sub-expression as if it were an object of the pointee type.
|
// Build the sub-expression as if it were an object of the pointee type.
|
||||||
DestType = ptr->getPointeeType();
|
DestType = Ptr->getPointeeType();
|
||||||
ExprResult subResult = Visit(op->getSubExpr());
|
ExprResult SubResult = Visit(E->getSubExpr());
|
||||||
if (subResult.isInvalid()) return ExprError();
|
if (SubResult.isInvalid()) return ExprError();
|
||||||
op->setSubExpr(subResult.take());
|
E->setSubExpr(SubResult.take());
|
||||||
return op;
|
return E;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprResult VisitImplicitCastExpr(ImplicitCastExpr *ice);
|
ExprResult VisitImplicitCastExpr(ImplicitCastExpr *E);
|
||||||
|
|
||||||
ExprResult resolveDecl(Expr *expr, ValueDecl *decl);
|
ExprResult resolveDecl(Expr *E, ValueDecl *VD);
|
||||||
|
|
||||||
ExprResult VisitMemberExpr(MemberExpr *mem) {
|
ExprResult VisitMemberExpr(MemberExpr *E) {
|
||||||
return resolveDecl(mem, mem->getMemberDecl());
|
return resolveDecl(E, E->getMemberDecl());
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprResult VisitDeclRefExpr(DeclRefExpr *ref) {
|
ExprResult VisitDeclRefExpr(DeclRefExpr *E) {
|
||||||
return resolveDecl(ref, ref->getDecl());
|
return resolveDecl(E, E->getDecl());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rebuilds a call expression which yielded __unknown_anytype.
|
/// Rebuilds a call expression which yielded __unknown_anytype.
|
||||||
ExprResult RebuildUnknownAnyExpr::VisitCallExpr(CallExpr *call) {
|
ExprResult RebuildUnknownAnyExpr::VisitCallExpr(CallExpr *E) {
|
||||||
Expr *callee = call->getCallee();
|
Expr *CalleeExpr = E->getCallee();
|
||||||
|
|
||||||
enum FnKind {
|
enum FnKind {
|
||||||
FK_MemberFunction,
|
FK_MemberFunction,
|
||||||
|
@ -9811,49 +9811,49 @@ ExprResult RebuildUnknownAnyExpr::VisitCallExpr(CallExpr *call) {
|
||||||
FK_BlockPointer
|
FK_BlockPointer
|
||||||
};
|
};
|
||||||
|
|
||||||
FnKind kind;
|
FnKind Kind;
|
||||||
QualType type = callee->getType();
|
QualType CalleeType = CalleeExpr->getType();
|
||||||
if (type == S.Context.BoundMemberTy) {
|
if (CalleeType == S.Context.BoundMemberTy) {
|
||||||
assert(isa<CXXMemberCallExpr>(call) || isa<CXXOperatorCallExpr>(call));
|
assert(isa<CXXMemberCallExpr>(E) || isa<CXXOperatorCallExpr>(E));
|
||||||
kind = FK_MemberFunction;
|
Kind = FK_MemberFunction;
|
||||||
type = Expr::findBoundMemberType(callee);
|
CalleeType = Expr::findBoundMemberType(CalleeExpr);
|
||||||
} else if (const PointerType *ptr = type->getAs<PointerType>()) {
|
} else if (const PointerType *Ptr = CalleeType->getAs<PointerType>()) {
|
||||||
type = ptr->getPointeeType();
|
CalleeType = Ptr->getPointeeType();
|
||||||
kind = FK_FunctionPointer;
|
Kind = FK_FunctionPointer;
|
||||||
} else {
|
} else {
|
||||||
type = type->castAs<BlockPointerType>()->getPointeeType();
|
CalleeType = CalleeType->castAs<BlockPointerType>()->getPointeeType();
|
||||||
kind = FK_BlockPointer;
|
Kind = FK_BlockPointer;
|
||||||
}
|
}
|
||||||
const FunctionType *fnType = type->castAs<FunctionType>();
|
const FunctionType *FnType = CalleeType->castAs<FunctionType>();
|
||||||
|
|
||||||
// Verify that this is a legal result type of a function.
|
// Verify that this is a legal result type of a function.
|
||||||
if (DestType->isArrayType() || DestType->isFunctionType()) {
|
if (DestType->isArrayType() || DestType->isFunctionType()) {
|
||||||
unsigned diagID = diag::err_func_returning_array_function;
|
unsigned diagID = diag::err_func_returning_array_function;
|
||||||
if (kind == FK_BlockPointer)
|
if (Kind == FK_BlockPointer)
|
||||||
diagID = diag::err_block_returning_array_function;
|
diagID = diag::err_block_returning_array_function;
|
||||||
|
|
||||||
S.Diag(call->getExprLoc(), diagID)
|
S.Diag(E->getExprLoc(), diagID)
|
||||||
<< DestType->isFunctionType() << DestType;
|
<< DestType->isFunctionType() << DestType;
|
||||||
return ExprError();
|
return ExprError();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, go ahead and set DestType as the call's result.
|
// Otherwise, go ahead and set DestType as the call's result.
|
||||||
call->setType(DestType.getNonLValueExprType(S.Context));
|
E->setType(DestType.getNonLValueExprType(S.Context));
|
||||||
call->setValueKind(Expr::getValueKindForType(DestType));
|
E->setValueKind(Expr::getValueKindForType(DestType));
|
||||||
assert(call->getObjectKind() == OK_Ordinary);
|
assert(E->getObjectKind() == OK_Ordinary);
|
||||||
|
|
||||||
// Rebuild the function type, replacing the result type with DestType.
|
// Rebuild the function type, replacing the result type with DestType.
|
||||||
if (const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(fnType))
|
if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FnType))
|
||||||
DestType = S.Context.getFunctionType(DestType,
|
DestType = S.Context.getFunctionType(DestType,
|
||||||
proto->arg_type_begin(),
|
Proto->arg_type_begin(),
|
||||||
proto->getNumArgs(),
|
Proto->getNumArgs(),
|
||||||
proto->getExtProtoInfo());
|
Proto->getExtProtoInfo());
|
||||||
else
|
else
|
||||||
DestType = S.Context.getFunctionNoProtoType(DestType,
|
DestType = S.Context.getFunctionNoProtoType(DestType,
|
||||||
fnType->getExtInfo());
|
FnType->getExtInfo());
|
||||||
|
|
||||||
// Rebuild the appropriate pointer-to-function type.
|
// Rebuild the appropriate pointer-to-function type.
|
||||||
switch (kind) {
|
switch (Kind) {
|
||||||
case FK_MemberFunction:
|
case FK_MemberFunction:
|
||||||
// Nothing to do.
|
// Nothing to do.
|
||||||
break;
|
break;
|
||||||
|
@ -9868,106 +9868,106 @@ ExprResult RebuildUnknownAnyExpr::VisitCallExpr(CallExpr *call) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finally, we can recurse.
|
// Finally, we can recurse.
|
||||||
ExprResult calleeResult = Visit(callee);
|
ExprResult CalleeResult = Visit(CalleeExpr);
|
||||||
if (!calleeResult.isUsable()) return ExprError();
|
if (!CalleeResult.isUsable()) return ExprError();
|
||||||
call->setCallee(calleeResult.take());
|
E->setCallee(CalleeResult.take());
|
||||||
|
|
||||||
// Bind a temporary if necessary.
|
// Bind a temporary if necessary.
|
||||||
return S.MaybeBindToTemporary(call);
|
return S.MaybeBindToTemporary(E);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprResult RebuildUnknownAnyExpr::VisitObjCMessageExpr(ObjCMessageExpr *msg) {
|
ExprResult RebuildUnknownAnyExpr::VisitObjCMessageExpr(ObjCMessageExpr *E) {
|
||||||
// Verify that this is a legal result type of a call.
|
// Verify that this is a legal result type of a call.
|
||||||
if (DestType->isArrayType() || DestType->isFunctionType()) {
|
if (DestType->isArrayType() || DestType->isFunctionType()) {
|
||||||
S.Diag(msg->getExprLoc(), diag::err_func_returning_array_function)
|
S.Diag(E->getExprLoc(), diag::err_func_returning_array_function)
|
||||||
<< DestType->isFunctionType() << DestType;
|
<< DestType->isFunctionType() << DestType;
|
||||||
return ExprError();
|
return ExprError();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rewrite the method result type if available.
|
// Rewrite the method result type if available.
|
||||||
if (ObjCMethodDecl *method = msg->getMethodDecl()) {
|
if (ObjCMethodDecl *Method = E->getMethodDecl()) {
|
||||||
assert(method->getResultType() == S.Context.UnknownAnyTy);
|
assert(Method->getResultType() == S.Context.UnknownAnyTy);
|
||||||
method->setResultType(DestType);
|
Method->setResultType(DestType);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change the type of the message.
|
// Change the type of the message.
|
||||||
msg->setType(DestType.getNonReferenceType());
|
E->setType(DestType.getNonReferenceType());
|
||||||
msg->setValueKind(Expr::getValueKindForType(DestType));
|
E->setValueKind(Expr::getValueKindForType(DestType));
|
||||||
|
|
||||||
return S.MaybeBindToTemporary(msg);
|
return S.MaybeBindToTemporary(E);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprResult RebuildUnknownAnyExpr::VisitImplicitCastExpr(ImplicitCastExpr *ice) {
|
ExprResult RebuildUnknownAnyExpr::VisitImplicitCastExpr(ImplicitCastExpr *E) {
|
||||||
// The only case we should ever see here is a function-to-pointer decay.
|
// The only case we should ever see here is a function-to-pointer decay.
|
||||||
assert(ice->getCastKind() == CK_FunctionToPointerDecay);
|
assert(E->getCastKind() == CK_FunctionToPointerDecay);
|
||||||
assert(ice->getValueKind() == VK_RValue);
|
assert(E->getValueKind() == VK_RValue);
|
||||||
assert(ice->getObjectKind() == OK_Ordinary);
|
assert(E->getObjectKind() == OK_Ordinary);
|
||||||
|
|
||||||
ice->setType(DestType);
|
E->setType(DestType);
|
||||||
|
|
||||||
// Rebuild the sub-expression as the pointee (function) type.
|
// Rebuild the sub-expression as the pointee (function) type.
|
||||||
DestType = DestType->castAs<PointerType>()->getPointeeType();
|
DestType = DestType->castAs<PointerType>()->getPointeeType();
|
||||||
|
|
||||||
ExprResult result = Visit(ice->getSubExpr());
|
ExprResult Result = Visit(E->getSubExpr());
|
||||||
if (!result.isUsable()) return ExprError();
|
if (!Result.isUsable()) return ExprError();
|
||||||
|
|
||||||
ice->setSubExpr(result.take());
|
E->setSubExpr(Result.take());
|
||||||
return S.Owned(ice);
|
return S.Owned(E);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprResult RebuildUnknownAnyExpr::resolveDecl(Expr *expr, ValueDecl *decl) {
|
ExprResult RebuildUnknownAnyExpr::resolveDecl(Expr *E, ValueDecl *VD) {
|
||||||
ExprValueKind valueKind = VK_LValue;
|
ExprValueKind ValueKind = VK_LValue;
|
||||||
QualType type = DestType;
|
QualType Type = DestType;
|
||||||
|
|
||||||
// We know how to make this work for certain kinds of decls:
|
// We know how to make this work for certain kinds of decls:
|
||||||
|
|
||||||
// - functions
|
// - functions
|
||||||
if (FunctionDecl *fn = dyn_cast<FunctionDecl>(decl)) {
|
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(VD)) {
|
||||||
if (const PointerType *ptr = type->getAs<PointerType>()) {
|
if (const PointerType *Ptr = Type->getAs<PointerType>()) {
|
||||||
DestType = ptr->getPointeeType();
|
DestType = Ptr->getPointeeType();
|
||||||
ExprResult result = resolveDecl(expr, decl);
|
ExprResult Result = resolveDecl(E, VD);
|
||||||
if (result.isInvalid()) return ExprError();
|
if (Result.isInvalid()) return ExprError();
|
||||||
return S.ImpCastExprToType(result.take(), type,
|
return S.ImpCastExprToType(Result.take(), Type,
|
||||||
CK_FunctionToPointerDecay, VK_RValue);
|
CK_FunctionToPointerDecay, VK_RValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!type->isFunctionType()) {
|
if (!Type->isFunctionType()) {
|
||||||
S.Diag(expr->getExprLoc(), diag::err_unknown_any_function)
|
S.Diag(E->getExprLoc(), diag::err_unknown_any_function)
|
||||||
<< decl << expr->getSourceRange();
|
<< VD << E->getSourceRange();
|
||||||
return ExprError();
|
return ExprError();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CXXMethodDecl *method = dyn_cast<CXXMethodDecl>(fn))
|
if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD))
|
||||||
if (method->isInstance()) {
|
if (MD->isInstance()) {
|
||||||
valueKind = VK_RValue;
|
ValueKind = VK_RValue;
|
||||||
type = S.Context.BoundMemberTy;
|
Type = S.Context.BoundMemberTy;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function references aren't l-values in C.
|
// Function references aren't l-values in C.
|
||||||
if (!S.getLangOptions().CPlusPlus)
|
if (!S.getLangOptions().CPlusPlus)
|
||||||
valueKind = VK_RValue;
|
ValueKind = VK_RValue;
|
||||||
|
|
||||||
// - variables
|
// - variables
|
||||||
} else if (isa<VarDecl>(decl)) {
|
} else if (isa<VarDecl>(VD)) {
|
||||||
if (const ReferenceType *refTy = type->getAs<ReferenceType>()) {
|
if (const ReferenceType *RefTy = Type->getAs<ReferenceType>()) {
|
||||||
type = refTy->getPointeeType();
|
Type = RefTy->getPointeeType();
|
||||||
} else if (type->isFunctionType()) {
|
} else if (Type->isFunctionType()) {
|
||||||
S.Diag(expr->getExprLoc(), diag::err_unknown_any_var_function_type)
|
S.Diag(E->getExprLoc(), diag::err_unknown_any_var_function_type)
|
||||||
<< decl << expr->getSourceRange();
|
<< VD << E->getSourceRange();
|
||||||
return ExprError();
|
return ExprError();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - nothing else
|
// - nothing else
|
||||||
} else {
|
} else {
|
||||||
S.Diag(expr->getExprLoc(), diag::err_unsupported_unknown_any_decl)
|
S.Diag(E->getExprLoc(), diag::err_unsupported_unknown_any_decl)
|
||||||
<< decl << expr->getSourceRange();
|
<< VD << E->getSourceRange();
|
||||||
return ExprError();
|
return ExprError();
|
||||||
}
|
}
|
||||||
|
|
||||||
decl->setType(DestType);
|
VD->setType(DestType);
|
||||||
expr->setType(type);
|
E->setType(Type);
|
||||||
expr->setValueKind(valueKind);
|
E->setValueKind(ValueKind);
|
||||||
return S.Owned(expr);
|
return S.Owned(E);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check a cast of an unknown-any type. We intentionally only
|
/// Check a cast of an unknown-any type. We intentionally only
|
||||||
|
|
Loading…
Reference in New Issue