зеркало из https://github.com/microsoft/clang.git
Add (explicit) AST support for implicit casts. This should simplify the
code generator. Source translation tools can simply ignore this node. - Added a new Expr node, ImplicitCastExpr. - Changed UsualUnaryConversions/UsualArithmeticConversions to take references to Expr *'s. This will allow these routines to instantiate the new AST node and pass it back. - Changed all clients of UsualUnary/UsualArithmetic (lot's of diff's). - Changed some names in CheckConditionalOperands. Several variables where only distinguished by their case (e.g. Cond, cond). Yuck (what was I thinking). - Removed an old/crufty constructor in CastExpr (cleanup). This check-in does not actually create the new AST node. I wanted to separate the mechanical changes from the semantic changes. In addition, I need to coordinate with Chris, since the semantic change will break the code generator. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@39814 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
8a6a237817
Коммит
49b4526992
|
@ -386,6 +386,9 @@ void StmtPrinter::VisitCastExpr(CastExpr *Node) {
|
|||
OS << "(" << Node->getDestType().getAsString() << ")";
|
||||
PrintExpr(Node->getSubExpr());
|
||||
}
|
||||
void StmtPrinter::VisitImplicitCastExpr(ImplicitCastExpr *Node) {
|
||||
// No need to print anything.
|
||||
}
|
||||
void StmtPrinter::VisitBinaryOperator(BinaryOperator *Node) {
|
||||
PrintExpr(Node->getLHS());
|
||||
OS << " " << BinaryOperator::getOpcodeStr(Node->getOpcode()) << " ";
|
||||
|
|
30
Sema/Sema.h
30
Sema/Sema.h
|
@ -270,13 +270,13 @@ public:
|
|||
private:
|
||||
// UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts
|
||||
// functions and arrays to their respective pointers (C99 6.3.2.1)
|
||||
QualType UsualUnaryConversions(QualType t);
|
||||
QualType UsualUnaryConversions(Expr *&expr);
|
||||
// UsualArithmeticConversions - performs the UsualUnaryConversions on it's
|
||||
// operands and then handles various conversions that are common to binary
|
||||
// operators (C99 6.3.1.8). If both operands aren't arithmetic, this
|
||||
// routine returns the first non-arithmetic type found. The client is
|
||||
// responsible for emitting appropriate error diagnostics.
|
||||
QualType UsualArithmeticConversions(QualType &t1, QualType &t2);
|
||||
QualType UsualArithmeticConversions(Expr *&lExpr, Expr *&rExpr);
|
||||
// DefaultFunctionArrayConversion - converts functions and arrays
|
||||
// to their respective pointers (C99 6.3.2.1). If the type isn't a function
|
||||
// or array, this routine simply returns the input type (unmodified).
|
||||
|
@ -302,35 +302,35 @@ private:
|
|||
/// or a null QualType (indicating an error diagnostic was issued).
|
||||
|
||||
/// type checking binary operators (subroutines of ParseBinOp).
|
||||
inline void InvalidOperands(SourceLocation l, Expr *lex, Expr *rex);
|
||||
inline QualType CheckVectorOperands(SourceLocation l, Expr *lex, Expr *rex);
|
||||
inline void InvalidOperands(SourceLocation l, Expr *&lex, Expr *&rex);
|
||||
inline QualType CheckVectorOperands(SourceLocation l, Expr *&lex, Expr *&rex);
|
||||
inline QualType CheckMultiplyDivideOperands( // C99 6.5.5
|
||||
Expr *lex, Expr *rex, SourceLocation OpLoc);
|
||||
Expr *&lex, Expr *&rex, SourceLocation OpLoc);
|
||||
inline QualType CheckRemainderOperands( // C99 6.5.5
|
||||
Expr *lex, Expr *rex, SourceLocation OpLoc);
|
||||
Expr *&lex, Expr *&rex, SourceLocation OpLoc);
|
||||
inline QualType CheckAdditionOperands( // C99 6.5.6
|
||||
Expr *lex, Expr *rex, SourceLocation OpLoc);
|
||||
Expr *&lex, Expr *&rex, SourceLocation OpLoc);
|
||||
inline QualType CheckSubtractionOperands( // C99 6.5.6
|
||||
Expr *lex, Expr *rex, SourceLocation OpLoc);
|
||||
Expr *&lex, Expr *&rex, SourceLocation OpLoc);
|
||||
inline QualType CheckShiftOperands( // C99 6.5.7
|
||||
Expr *lex, Expr *rex, SourceLocation OpLoc);
|
||||
Expr *&lex, Expr *&rex, SourceLocation OpLoc);
|
||||
inline QualType CheckRelationalOperands( // C99 6.5.8
|
||||
Expr *lex, Expr *rex, SourceLocation OpLoc);
|
||||
Expr *&lex, Expr *&rex, SourceLocation OpLoc);
|
||||
inline QualType CheckEqualityOperands( // C99 6.5.9
|
||||
Expr *lex, Expr *rex, SourceLocation OpLoc);
|
||||
Expr *&lex, Expr *&rex, SourceLocation OpLoc);
|
||||
inline QualType CheckBitwiseOperands( // C99 6.5.[10...12]
|
||||
Expr *lex, Expr *rex, SourceLocation OpLoc);
|
||||
Expr *&lex, Expr *&rex, SourceLocation OpLoc);
|
||||
inline QualType CheckLogicalOperands( // C99 6.5.[13,14]
|
||||
Expr *lex, Expr *rex, SourceLocation OpLoc);
|
||||
Expr *&lex, Expr *&rex, SourceLocation OpLoc);
|
||||
// CheckAssignmentOperands is used for both simple and compound assignment.
|
||||
// For simple assignment, pass both expressions and a null converted type.
|
||||
// For compound assignment, pass both expressions and the converted type.
|
||||
inline QualType CheckAssignmentOperands( // C99 6.5.16.[1,2]
|
||||
Expr *lex, Expr *rex, SourceLocation OpLoc, QualType convertedType);
|
||||
inline QualType CheckCommaOperands( // C99 6.5.17
|
||||
Expr *lex, Expr *rex, SourceLocation OpLoc);
|
||||
Expr *&lex, Expr *&rex, SourceLocation OpLoc);
|
||||
inline QualType CheckConditionalOperands( // C99 6.5.15
|
||||
Expr *cond, Expr *lhs, Expr *rhs, SourceLocation questionLoc);
|
||||
Expr *&cond, Expr *&lhs, Expr *&rhs, SourceLocation questionLoc);
|
||||
|
||||
/// type checking unary operators (subroutines of ParseUnaryOp).
|
||||
/// C99 6.5.3.1, 6.5.3.2, 6.5.3.4
|
||||
|
|
|
@ -311,7 +311,7 @@ Sema::ParseDeclarator(Scope *S, Declarator &D, ExprTy *init,
|
|||
assert(Init == 0 && "Can't have an initializer for a functiondecl!");
|
||||
QualType R = GetTypeForDeclarator(D, S);
|
||||
if (R.isNull()) return 0; // FIXME: "auto func();" passes through...
|
||||
|
||||
|
||||
FunctionDecl::StorageClass SC;
|
||||
switch (D.getDeclSpec().getStorageClassSpec()) {
|
||||
default: assert(0 && "Unknown storage class!");
|
||||
|
|
|
@ -375,7 +375,7 @@ ParseCallExpr(ExprTy *Fn, SourceLocation LParenLoc,
|
|||
Expr *funcExpr = (Expr *)Fn;
|
||||
assert(funcExpr && "no function call expression");
|
||||
|
||||
QualType qType = UsualUnaryConversions(funcExpr->getType());
|
||||
QualType qType = UsualUnaryConversions(funcExpr);
|
||||
assert(!qType.isNull() && "no type for function call expression");
|
||||
|
||||
// C99 6.5.2.2p1 - "The expression that denotes the called function shall have
|
||||
|
@ -482,62 +482,62 @@ ParseCastExpr(SourceLocation LParenLoc, TypeTy *Ty,
|
|||
}
|
||||
|
||||
inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
|
||||
Expr *Cond, Expr *LHS, Expr *RHS, SourceLocation questionLoc) {
|
||||
QualType cond = Cond->getType();
|
||||
QualType lhs = LHS->getType();
|
||||
QualType rhs = RHS->getType();
|
||||
Expr *&cond, Expr *&lex, Expr *&rex, SourceLocation questionLoc) {
|
||||
QualType condT = cond->getType();
|
||||
QualType lexT = lex->getType();
|
||||
QualType rexT = rex->getType();
|
||||
|
||||
assert(!cond.isNull() && "ParseConditionalOp(): no conditional type");
|
||||
assert(!lhs.isNull() && "ParseConditionalOp(): no lhs type");
|
||||
assert(!rhs.isNull() && "ParseConditionalOp(): no rhs type");
|
||||
assert(!condT.isNull() && "ParseConditionalOp(): no conditional type");
|
||||
assert(!lexT.isNull() && "ParseConditionalOp(): no lhs type");
|
||||
assert(!rexT.isNull() && "ParseConditionalOp(): no rhs type");
|
||||
|
||||
cond = UsualUnaryConversions(cond);
|
||||
lhs = UsualUnaryConversions(lhs);
|
||||
rhs = UsualUnaryConversions(rhs);
|
||||
condT = UsualUnaryConversions(cond);
|
||||
lexT = UsualUnaryConversions(lex);
|
||||
rexT = UsualUnaryConversions(rex);
|
||||
|
||||
// first, check the condition.
|
||||
if (!cond->isScalarType()) { // C99 6.5.15p2
|
||||
Diag(Cond->getLocStart(), diag::err_typecheck_cond_expect_scalar,
|
||||
cond.getAsString());
|
||||
if (!condT->isScalarType()) { // C99 6.5.15p2
|
||||
Diag(cond->getLocStart(), diag::err_typecheck_cond_expect_scalar,
|
||||
condT.getAsString());
|
||||
return QualType();
|
||||
}
|
||||
// now check the two expressions.
|
||||
if (lhs->isArithmeticType() && rhs->isArithmeticType()) // C99 6.5.15p3,5
|
||||
return UsualArithmeticConversions(lhs, rhs);
|
||||
if (lexT->isArithmeticType() && rexT->isArithmeticType()) // C99 6.5.15p3,5
|
||||
return UsualArithmeticConversions(lex, rex);
|
||||
|
||||
if ((lhs->isStructureType() && rhs->isStructureType()) || // C99 6.5.15p3
|
||||
(lhs->isUnionType() && rhs->isUnionType())) {
|
||||
TagType *lTag = cast<TagType>(lhs.getCanonicalType());
|
||||
TagType *rTag = cast<TagType>(rhs.getCanonicalType());
|
||||
if ((lexT->isStructureType() && rexT->isStructureType()) || // C99 6.5.15p3
|
||||
(lexT->isUnionType() && rexT->isUnionType())) {
|
||||
TagType *lTag = cast<TagType>(lexT.getCanonicalType());
|
||||
TagType *rTag = cast<TagType>(rexT.getCanonicalType());
|
||||
|
||||
if (lTag->getDecl()->getIdentifier() == rTag->getDecl()->getIdentifier())
|
||||
return lhs;
|
||||
return lexT;
|
||||
else {
|
||||
Diag(questionLoc, diag::err_typecheck_cond_incompatible_operands,
|
||||
lhs.getAsString(), rhs.getAsString(),
|
||||
LHS->getSourceRange(), RHS->getSourceRange());
|
||||
lexT.getAsString(), rexT.getAsString(),
|
||||
lex->getSourceRange(), rex->getSourceRange());
|
||||
return QualType();
|
||||
}
|
||||
}
|
||||
if (lhs->isPointerType() && RHS->isNullPointerConstant()) // C99 6.5.15p3
|
||||
return lhs;
|
||||
if (rhs->isPointerType() && LHS->isNullPointerConstant())
|
||||
return rhs;
|
||||
if (lexT->isPointerType() && rex->isNullPointerConstant()) // C99 6.5.15p3
|
||||
return lexT;
|
||||
if (rexT->isPointerType() && lex->isNullPointerConstant())
|
||||
return rexT;
|
||||
|
||||
if (lhs->isPointerType() && rhs->isPointerType()) { // C99 6.5.15p3,6
|
||||
if (lexT->isPointerType() && rexT->isPointerType()) { // C99 6.5.15p3,6
|
||||
QualType lhptee, rhptee;
|
||||
|
||||
// get the "pointed to" type
|
||||
lhptee = cast<PointerType>(lhs.getCanonicalType())->getPointeeType();
|
||||
rhptee = cast<PointerType>(rhs.getCanonicalType())->getPointeeType();
|
||||
lhptee = cast<PointerType>(lexT.getCanonicalType())->getPointeeType();
|
||||
rhptee = cast<PointerType>(rexT.getCanonicalType())->getPointeeType();
|
||||
|
||||
// ignore qualifiers on void (C99 6.5.15p3, clause 6)
|
||||
if (lhptee.getUnqualifiedType()->isVoidType() &&
|
||||
(rhptee->isObjectType() || rhptee->isIncompleteType()))
|
||||
return lhs;
|
||||
return lexT;
|
||||
if (rhptee.getUnqualifiedType()->isVoidType() &&
|
||||
(lhptee->isObjectType() || lhptee->isIncompleteType()))
|
||||
return rhs;
|
||||
return rexT;
|
||||
|
||||
// FIXME: C99 6.5.15p6: If both operands are pointers to compatible types
|
||||
// *or* to differently qualified versions of compatible types, the result
|
||||
|
@ -546,17 +546,17 @@ inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
|
|||
if (!Type::typesAreCompatible(lhptee.getUnqualifiedType(),
|
||||
rhptee.getUnqualifiedType())) {
|
||||
Diag(questionLoc, diag::ext_typecheck_cond_incompatible_pointers,
|
||||
lhs.getAsString(), rhs.getAsString(),
|
||||
LHS->getSourceRange(), RHS->getSourceRange());
|
||||
return lhs; // FIXME: this is an _ext - is this return o.k?
|
||||
lexT.getAsString(), rexT.getAsString(),
|
||||
lex->getSourceRange(), rex->getSourceRange());
|
||||
return lexT; // FIXME: this is an _ext - is this return o.k?
|
||||
}
|
||||
}
|
||||
if (lhs->isVoidType() && rhs->isVoidType()) // C99 6.5.15p3
|
||||
return lhs;
|
||||
if (lexT->isVoidType() && rexT->isVoidType()) // C99 6.5.15p3
|
||||
return lexT;
|
||||
|
||||
Diag(questionLoc, diag::err_typecheck_cond_incompatible_operands,
|
||||
lhs.getAsString(), rhs.getAsString(),
|
||||
LHS->getSourceRange(), RHS->getSourceRange());
|
||||
lexT.getAsString(), rexT.getAsString(),
|
||||
lex->getSourceRange(), rex->getSourceRange());
|
||||
return QualType();
|
||||
}
|
||||
|
||||
|
@ -566,8 +566,8 @@ Action::ExprResult Sema::ParseConditionalOp(SourceLocation QuestionLoc,
|
|||
SourceLocation ColonLoc,
|
||||
ExprTy *Cond, ExprTy *LHS,
|
||||
ExprTy *RHS) {
|
||||
QualType result = CheckConditionalOperands((Expr *)Cond, (Expr *)LHS,
|
||||
(Expr *)RHS, QuestionLoc);
|
||||
QualType result = CheckConditionalOperands((Expr *&)Cond, (Expr *&)LHS,
|
||||
(Expr *&)RHS, QuestionLoc);
|
||||
if (result.isNull())
|
||||
return true;
|
||||
return new ConditionalOperator((Expr*)Cond, (Expr*)LHS, (Expr*)RHS, result);
|
||||
|
@ -586,7 +586,8 @@ QualType Sema::DefaultFunctionArrayConversion(QualType t) {
|
|||
/// sometimes surpressed. For example, the array->pointer conversion doesn't
|
||||
/// apply if the array is an argument to the sizeof or address (&) operators.
|
||||
/// In these instances, this routine should *not* be called.
|
||||
QualType Sema::UsualUnaryConversions(QualType t) {
|
||||
QualType Sema::UsualUnaryConversions(Expr *&expr) {
|
||||
QualType t = expr->getType();
|
||||
assert(!t.isNull() && "UsualUnaryConversions - missing type");
|
||||
|
||||
if (t->isPromotableIntegerType()) // C99 6.3.1.1p2
|
||||
|
@ -598,9 +599,9 @@ QualType Sema::UsualUnaryConversions(QualType t) {
|
|||
/// binary operators (C99 6.3.1.8). If both operands aren't arithmetic, this
|
||||
/// routine returns the first non-arithmetic type found. The client is
|
||||
/// responsible for emitting appropriate error diagnostics.
|
||||
QualType Sema::UsualArithmeticConversions(QualType &lhs, QualType &rhs) {
|
||||
lhs = UsualUnaryConversions(lhs);
|
||||
rhs = UsualUnaryConversions(rhs);
|
||||
QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr) {
|
||||
QualType lhs = UsualUnaryConversions(lhsExpr);
|
||||
QualType rhs = UsualUnaryConversions(rhsExpr);
|
||||
|
||||
// If both types are identical, no conversion is needed.
|
||||
if (lhs == rhs)
|
||||
|
@ -737,14 +738,14 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) {
|
|||
return Incompatible;
|
||||
}
|
||||
|
||||
inline void Sema::InvalidOperands(SourceLocation loc, Expr *lex, Expr *rex) {
|
||||
inline void Sema::InvalidOperands(SourceLocation loc, Expr *&lex, Expr *&rex) {
|
||||
Diag(loc, diag::err_typecheck_invalid_operands,
|
||||
lex->getType().getAsString(), rex->getType().getAsString(),
|
||||
lex->getSourceRange(), rex->getSourceRange());
|
||||
}
|
||||
|
||||
inline QualType Sema::CheckVectorOperands(SourceLocation loc, Expr *lex,
|
||||
Expr *rex) {
|
||||
inline QualType Sema::CheckVectorOperands(SourceLocation loc, Expr *&lex,
|
||||
Expr *&rex) {
|
||||
QualType lhsType = lex->getType(), rhsType = rex->getType();
|
||||
|
||||
// make sure the vector types are identical.
|
||||
|
@ -758,13 +759,12 @@ inline QualType Sema::CheckVectorOperands(SourceLocation loc, Expr *lex,
|
|||
}
|
||||
|
||||
inline QualType Sema::CheckMultiplyDivideOperands(
|
||||
Expr *lex, Expr *rex, SourceLocation loc)
|
||||
Expr *&lex, Expr *&rex, SourceLocation loc)
|
||||
{
|
||||
QualType lhsType = lex->getType(), rhsType = rex->getType();
|
||||
|
||||
if (lhsType->isVectorType() || rhsType->isVectorType())
|
||||
if (lex->getType()->isVectorType() || rex->getType()->isVectorType())
|
||||
return CheckVectorOperands(loc, lex, rex);
|
||||
QualType resType = UsualArithmeticConversions(lhsType, rhsType);
|
||||
|
||||
QualType resType = UsualArithmeticConversions(lex, rex);
|
||||
|
||||
if (resType->isArithmeticType())
|
||||
return resType;
|
||||
|
@ -773,10 +773,9 @@ inline QualType Sema::CheckMultiplyDivideOperands(
|
|||
}
|
||||
|
||||
inline QualType Sema::CheckRemainderOperands(
|
||||
Expr *lex, Expr *rex, SourceLocation loc)
|
||||
Expr *&lex, Expr *&rex, SourceLocation loc)
|
||||
{
|
||||
QualType lhsType = lex->getType(), rhsType = rex->getType();
|
||||
QualType resType = UsualArithmeticConversions(lhsType, rhsType);
|
||||
QualType resType = UsualArithmeticConversions(lex, rex);
|
||||
|
||||
if (resType->isIntegerType())
|
||||
return resType;
|
||||
|
@ -785,13 +784,14 @@ inline QualType Sema::CheckRemainderOperands(
|
|||
}
|
||||
|
||||
inline QualType Sema::CheckAdditionOperands( // C99 6.5.6
|
||||
Expr *lex, Expr *rex, SourceLocation loc)
|
||||
Expr *&lex, Expr *&rex, SourceLocation loc)
|
||||
{
|
||||
QualType lhsType = lex->getType(), rhsType = rex->getType();
|
||||
|
||||
if (lhsType->isVectorType() || rhsType->isVectorType())
|
||||
return CheckVectorOperands(loc, lex, rex);
|
||||
QualType resType = UsualArithmeticConversions(lhsType, rhsType);
|
||||
return CheckVectorOperands(loc, lex, rex);
|
||||
|
||||
QualType resType = UsualArithmeticConversions(lex, rex);
|
||||
|
||||
// handle the common case first (both operands are arithmetic).
|
||||
if (resType->isArithmeticType())
|
||||
|
@ -805,13 +805,13 @@ inline QualType Sema::CheckAdditionOperands( // C99 6.5.6
|
|||
}
|
||||
|
||||
inline QualType Sema::CheckSubtractionOperands( // C99 6.5.6
|
||||
Expr *lex, Expr *rex, SourceLocation loc)
|
||||
Expr *&lex, Expr *&rex, SourceLocation loc)
|
||||
{
|
||||
QualType lhsType = lex->getType(), rhsType = rex->getType();
|
||||
|
||||
if (lhsType->isVectorType() || rhsType->isVectorType())
|
||||
return CheckVectorOperands(loc, lex, rex);
|
||||
QualType resType = UsualArithmeticConversions(lhsType, rhsType);
|
||||
QualType resType = UsualArithmeticConversions(lex, rex);
|
||||
|
||||
// handle the common case first (both operands are arithmetic).
|
||||
if (resType->isArithmeticType())
|
||||
|
@ -825,12 +825,12 @@ inline QualType Sema::CheckSubtractionOperands( // C99 6.5.6
|
|||
}
|
||||
|
||||
inline QualType Sema::CheckShiftOperands( // C99 6.5.7
|
||||
Expr *lex, Expr *rex, SourceLocation loc)
|
||||
Expr *&lex, Expr *&rex, SourceLocation loc)
|
||||
{
|
||||
// FIXME: Shifts don't perform usual arithmetic conversions. This is wrong
|
||||
// for int << longlong -> the result type should be int, not long long.
|
||||
QualType lhsType = lex->getType(), rhsType = rex->getType();
|
||||
QualType resType = UsualArithmeticConversions(lhsType, rhsType);
|
||||
QualType resType = UsualArithmeticConversions(lex, rex);
|
||||
|
||||
if (resType->isIntegerType())
|
||||
return resType;
|
||||
|
@ -839,10 +839,10 @@ inline QualType Sema::CheckShiftOperands( // C99 6.5.7
|
|||
}
|
||||
|
||||
inline QualType Sema::CheckRelationalOperands( // C99 6.5.8
|
||||
Expr *lex, Expr *rex, SourceLocation loc)
|
||||
Expr *&lex, Expr *&rex, SourceLocation loc)
|
||||
{
|
||||
QualType lType = UsualUnaryConversions(lex->getType());
|
||||
QualType rType = UsualUnaryConversions(rex->getType());
|
||||
QualType lType = UsualUnaryConversions(lex);
|
||||
QualType rType = UsualUnaryConversions(rex);
|
||||
|
||||
if (lType->isRealType() && rType->isRealType())
|
||||
return Context.IntTy;
|
||||
|
@ -869,10 +869,10 @@ inline QualType Sema::CheckRelationalOperands( // C99 6.5.8
|
|||
}
|
||||
|
||||
inline QualType Sema::CheckEqualityOperands( // C99 6.5.9
|
||||
Expr *lex, Expr *rex, SourceLocation loc)
|
||||
Expr *&lex, Expr *&rex, SourceLocation loc)
|
||||
{
|
||||
QualType lType = UsualUnaryConversions(lex->getType());
|
||||
QualType rType = UsualUnaryConversions(rex->getType());
|
||||
QualType lType = UsualUnaryConversions(lex);
|
||||
QualType rType = UsualUnaryConversions(rex);
|
||||
|
||||
if (lType->isArithmeticType() && rType->isArithmeticType())
|
||||
return Context.IntTy;
|
||||
|
@ -899,13 +899,13 @@ inline QualType Sema::CheckEqualityOperands( // C99 6.5.9
|
|||
}
|
||||
|
||||
inline QualType Sema::CheckBitwiseOperands(
|
||||
Expr *lex, Expr *rex, SourceLocation loc)
|
||||
Expr *&lex, Expr *&rex, SourceLocation loc)
|
||||
{
|
||||
QualType lhsType = lex->getType(), rhsType = rex->getType();
|
||||
|
||||
if (lhsType->isVectorType() || rhsType->isVectorType())
|
||||
return CheckVectorOperands(loc, lex, rex);
|
||||
QualType resType = UsualArithmeticConversions(lhsType, rhsType);
|
||||
QualType resType = UsualArithmeticConversions(lex, rex);
|
||||
|
||||
if (resType->isIntegerType())
|
||||
return resType;
|
||||
|
@ -914,10 +914,10 @@ inline QualType Sema::CheckBitwiseOperands(
|
|||
}
|
||||
|
||||
inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14]
|
||||
Expr *lex, Expr *rex, SourceLocation loc)
|
||||
Expr *&lex, Expr *&rex, SourceLocation loc)
|
||||
{
|
||||
QualType lhsType = UsualUnaryConversions(lex->getType());
|
||||
QualType rhsType = UsualUnaryConversions(rex->getType());
|
||||
QualType lhsType = UsualUnaryConversions(lex);
|
||||
QualType rhsType = UsualUnaryConversions(rex);
|
||||
|
||||
if (lhsType->isScalarType() || rhsType->isScalarType())
|
||||
return Context.IntTy;
|
||||
|
@ -1007,13 +1007,14 @@ inline QualType Sema::CheckAssignmentOperands( // C99 6.5.16.1
|
|||
}
|
||||
|
||||
inline QualType Sema::CheckCommaOperands( // C99 6.5.17
|
||||
Expr *lex, Expr *rex, SourceLocation loc) {
|
||||
return UsualUnaryConversions(rex->getType());
|
||||
Expr *&lex, Expr *&rex, SourceLocation loc) {
|
||||
return UsualUnaryConversions(rex);
|
||||
}
|
||||
|
||||
/// CheckIncrementDecrementOperand - unlike most "Check" methods, this routine
|
||||
/// doesn't need to call UsualUnaryConversions or UsualArithmeticConversions.
|
||||
QualType Sema::CheckIncrementDecrementOperand(Expr *op, SourceLocation OpLoc) {
|
||||
QualType lhsType = op->getType(), rhsType = Context.IntTy;
|
||||
QualType resType = UsualArithmeticConversions(lhsType, rhsType);
|
||||
QualType resType = op->getType();
|
||||
assert(!resType.isNull() && "no type for increment/decrement expression");
|
||||
|
||||
// C99 6.5.2.4p1
|
||||
|
@ -1100,7 +1101,7 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
|
|||
}
|
||||
|
||||
QualType Sema::CheckIndirectionOperand(Expr *op, SourceLocation OpLoc) {
|
||||
QualType qType = UsualUnaryConversions(op->getType());
|
||||
QualType qType = UsualUnaryConversions(op);
|
||||
|
||||
assert(!qType.isNull() && "no type for * expression");
|
||||
|
||||
|
@ -1307,13 +1308,13 @@ Action::ExprResult Sema::ParseUnaryOp(SourceLocation OpLoc, tok::TokenKind Op,
|
|||
break;
|
||||
case UnaryOperator::Plus:
|
||||
case UnaryOperator::Minus:
|
||||
resultType = UsualUnaryConversions(Input->getType());
|
||||
resultType = UsualUnaryConversions(Input);
|
||||
if (!resultType->isArithmeticType()) // C99 6.5.3.3p1
|
||||
return Diag(OpLoc, diag::err_typecheck_unary_expr,
|
||||
resultType.getAsString());
|
||||
break;
|
||||
case UnaryOperator::Not: // bitwise complement
|
||||
resultType = UsualUnaryConversions(Input->getType());
|
||||
resultType = UsualUnaryConversions(Input);
|
||||
if (!resultType->isIntegerType()) // C99 6.5.3.3p1
|
||||
return Diag(OpLoc, diag::err_typecheck_unary_expr,
|
||||
resultType.getAsString());
|
||||
|
|
|
@ -426,6 +426,24 @@ public:
|
|||
static bool classof(const MemberExpr *) { return true; }
|
||||
};
|
||||
|
||||
/// ImplicitCastExpr - Allows us to explicitly represent implicit type
|
||||
/// conversions. For example: converting T[]->T*, void f()->void (*f)(),
|
||||
/// float->double, short->int, etc.
|
||||
///
|
||||
class ImplicitCastExpr : public Expr {
|
||||
QualType Ty;
|
||||
Expr *Op;
|
||||
public:
|
||||
ImplicitCastExpr(QualType ty, Expr *op) :
|
||||
Expr(ImplicitCastExprClass, ty), Ty(ty), Op(op) {}
|
||||
|
||||
virtual void visit(StmtVisitor &Visitor);
|
||||
static bool classof(const Stmt *T) {
|
||||
return T->getStmtClass() == ImplicitCastExprClass;
|
||||
}
|
||||
static bool classof(const ImplicitCastExpr *) { return true; }
|
||||
};
|
||||
|
||||
/// CastExpr - [C99 6.5.4] Cast Operators.
|
||||
///
|
||||
class CastExpr : public Expr {
|
||||
|
@ -435,9 +453,7 @@ class CastExpr : public Expr {
|
|||
public:
|
||||
CastExpr(QualType ty, Expr *op, SourceLocation l) :
|
||||
Expr(CastExprClass, ty), Ty(ty), Op(op), Loc(l) {}
|
||||
CastExpr(StmtClass SC, QualType ty, Expr *op) :
|
||||
Expr(SC, QualType()), Ty(ty), Op(op), Loc(SourceLocation()) {}
|
||||
|
||||
|
||||
SourceLocation getLParenLoc() const { return Loc; }
|
||||
|
||||
QualType getDestType() const { return Ty; }
|
||||
|
|
|
@ -58,14 +58,15 @@ STMT(43, MemberExpr , Expr)
|
|||
STMT(44, CastExpr , Expr)
|
||||
STMT(45, BinaryOperator , Expr)
|
||||
STMT(46, ConditionalOperator , Expr)
|
||||
STMT(47, ImplicitCastExpr , Expr)
|
||||
|
||||
// GNU Extensions.
|
||||
STMT(47, AddrLabel , Expr)
|
||||
STMT(48, AddrLabel , Expr)
|
||||
|
||||
// C++ Expressions.
|
||||
STMT(48, CXXCastExpr , Expr)
|
||||
STMT(49, CXXBoolLiteralExpr , Expr)
|
||||
LAST_EXPR(49)
|
||||
STMT(49, CXXCastExpr , Expr)
|
||||
STMT(50, CXXBoolLiteralExpr , Expr)
|
||||
LAST_EXPR(50)
|
||||
|
||||
#undef STMT
|
||||
#undef FIRST_STMT
|
||||
|
|
Загрузка…
Ссылка в новой задаче