forked from OSchip/llvm-project
Add support for __builtin_type_compatible_p, enums, etc.
llvm-svn: 53500
This commit is contained in:
parent
9941570ce9
commit
7174bf3722
|
@ -226,8 +226,25 @@ public:
|
||||||
|
|
||||||
bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
|
bool VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
|
||||||
|
|
||||||
|
bool VisitIntegerLiteral(const IntegerLiteral *E) {
|
||||||
|
Result = E->getValue();
|
||||||
|
Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool VisitCharacterLiteral(const CharacterLiteral *E) {
|
||||||
|
Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
|
||||||
|
Result = E->getValue();
|
||||||
|
Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool VisitTypesCompatibleExpr(const TypesCompatibleExpr *E) {
|
||||||
|
Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
|
||||||
|
Result = Info.Ctx.typesAreCompatible(E->getArgType1(), E->getArgType2());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool VisitDeclRefExpr(const DeclRefExpr *E);
|
||||||
|
bool VisitCallExpr(const CallExpr *E);
|
||||||
bool VisitBinaryOperator(const BinaryOperator *E);
|
bool VisitBinaryOperator(const BinaryOperator *E);
|
||||||
|
|
||||||
bool VisitUnaryOperator(const UnaryOperator *E);
|
bool VisitUnaryOperator(const UnaryOperator *E);
|
||||||
|
|
||||||
bool VisitCastExpr(const CastExpr* E) {
|
bool VisitCastExpr(const CastExpr* E) {
|
||||||
|
@ -241,17 +258,6 @@ public:
|
||||||
E->getType());
|
E->getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VisitIntegerLiteral(const IntegerLiteral *E) {
|
|
||||||
Result = E->getValue();
|
|
||||||
Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool VisitCharacterLiteral(const CharacterLiteral *E) {
|
|
||||||
Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
|
|
||||||
Result = E->getValue();
|
|
||||||
Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
private:
|
private:
|
||||||
bool HandleCast(const Expr* SubExpr, QualType DestType);
|
bool HandleCast(const Expr* SubExpr, QualType DestType);
|
||||||
bool EvaluateSizeAlignOf(bool isSizeOf, QualType SrcTy, QualType DstTy);
|
bool EvaluateSizeAlignOf(bool isSizeOf, QualType SrcTy, QualType DstTy);
|
||||||
|
@ -262,6 +268,26 @@ static bool EvaluateInteger(const Expr* E, APSInt &Result, EvalInfo &Info) {
|
||||||
return IntExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E));
|
return IntExprEvaluator(Info, Result).Visit(const_cast<Expr*>(E));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IntExprEvaluator::VisitDeclRefExpr(const DeclRefExpr *E) {
|
||||||
|
// Enums are integer constant exprs.
|
||||||
|
if (const EnumConstantDecl *D = dyn_cast<EnumConstantDecl>(E->getDecl())) {
|
||||||
|
Result = D->getInitVal();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, random variable references are not constants.
|
||||||
|
return Error(E->getLocStart(), diag::err_expr_not_constant);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) {
|
||||||
|
Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
|
||||||
|
// __builtin_type_compatible_p is a constant.
|
||||||
|
if (E->isBuiltinClassifyType(Result))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return Error(E->getLocStart(), diag::err_expr_not_constant);
|
||||||
|
}
|
||||||
|
|
||||||
bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
|
bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
|
||||||
// The LHS of a constant expr is always evaluated and needed.
|
// The LHS of a constant expr is always evaluated and needed.
|
||||||
|
@ -395,7 +421,10 @@ bool IntExprEvaluator::EvaluateSizeAlignOf(bool isSizeOf, QualType SrcTy,
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
|
bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
|
||||||
|
// Special case unary operators that do not need their subexpression
|
||||||
|
// evaluated. offsetof/sizeof/alignof are all special.
|
||||||
if (E->isOffsetOfOp()) {
|
if (E->isOffsetOfOp()) {
|
||||||
|
Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
|
||||||
Result = E->evaluateOffsetOf(Info.Ctx);
|
Result = E->evaluateOffsetOf(Info.Ctx);
|
||||||
Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
|
Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
|
||||||
return true;
|
return true;
|
||||||
|
@ -410,10 +439,10 @@ bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
switch (E->getOpcode()) {
|
switch (E->getOpcode()) {
|
||||||
|
default:
|
||||||
// Address, indirect, pre/post inc/dec, etc are not valid constant exprs.
|
// Address, indirect, pre/post inc/dec, etc are not valid constant exprs.
|
||||||
// See C99 6.6p3.
|
// See C99 6.6p3.
|
||||||
default:
|
return Error(E->getOperatorLoc(), diag::err_expr_not_constant);
|
||||||
return false;
|
|
||||||
case UnaryOperator::LNot: {
|
case UnaryOperator::LNot: {
|
||||||
bool Val = Result == 0;
|
bool Val = Result == 0;
|
||||||
Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
|
Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
|
||||||
|
@ -421,8 +450,10 @@ bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case UnaryOperator::Extension:
|
case UnaryOperator::Extension:
|
||||||
|
// FIXME: Should extension allow i-c-e extension expressions in its scope?
|
||||||
|
// If so, we could clear the diagnostic ID.
|
||||||
case UnaryOperator::Plus:
|
case UnaryOperator::Plus:
|
||||||
// The result is always just the subexpr
|
// The result is always just the subexpr.
|
||||||
break;
|
break;
|
||||||
case UnaryOperator::Minus:
|
case UnaryOperator::Minus:
|
||||||
Result = -Result;
|
Result = -Result;
|
||||||
|
|
Loading…
Reference in New Issue