[cfe-commits] r39409 - in /cfe/cfe/trunk: AST/SemaExpr.cpp AST/Type.cpp Sema/SemaExpr.cpp include/clang/AST/ExprCXX.h include/clang/AST/Type.h include/clang/Basic/DiagnosticKinds.def
Steve Naroff
snaroff at apple.com
Wed Jul 11 09:44:04 PDT 2007
Author: snaroff
Date: Wed Jul 11 11:44:03 2007
New Revision: 39409
URL: http://llvm.org/viewvc/llvm-project?rev=39409&view=rev
Log:
Bug #:
Submitted by:
Reviewed by:
- Added Type::isPromotableIntegerType().
- The unary operators are now largely complete (Sema::ParseUnaryOp and friends).
- Implemented ImplicitConversion hook (was a stub).
Modified:
cfe/cfe/trunk/AST/SemaExpr.cpp
cfe/cfe/trunk/AST/Type.cpp
cfe/cfe/trunk/Sema/SemaExpr.cpp
cfe/cfe/trunk/include/clang/AST/ExprCXX.h
cfe/cfe/trunk/include/clang/AST/Type.h
cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
Modified: cfe/cfe/trunk/AST/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaExpr.cpp?rev=39409&r1=39408&r2=39409&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/AST/SemaExpr.cpp Wed Jul 11 11:44:03 2007
@@ -180,9 +180,42 @@
return CheckAddressOfOperand((Expr *)Input, OpLoc, Opc);
else if (Opc == UnaryOperator::Deref)
return CheckIndirectionOperand((Expr *)Input, OpLoc, Opc);
-
- // when all the check functions are written, this will go away...
- return new UnaryOperator((Expr*)Input, Opc, QualType());
+ else {
+ // handle the arithmetic unary operators (C99 6.5.3.3)
+ QualType opType = ImplicitConversion((Expr *)Input)->getType();
+ assert(!opType.isNull() && "no type for arithmetic unary expression");
+ QualType resultType = opType;
+
+ switch (Opc) {
+ case UnaryOperator::Plus:
+ case UnaryOperator::Minus:
+ if (!opType->isArithmeticType()) // C99 6.5.3.3p1
+ return Diag(OpLoc, diag::err_typecheck_unary_expr, opType);
+
+ if (opType->isPromotableIntegerType()) // C99 6.5.3.3p2
+ resultType = Context.IntTy;
+ break;
+ case UnaryOperator::Not: // bitwise complement
+ if (!opType->isIntegralType()) // C99 6.5.3.3p1
+ return Diag(OpLoc, diag::err_typecheck_unary_expr, opType);
+
+ if (opType->isPromotableIntegerType()) // C99 6.5.3.3p2
+ resultType = Context.IntTy;
+ break;
+ case UnaryOperator::LNot: // logical negation
+ if (!opType->isScalarType()) // C99 6.5.3.3p1
+ return Diag(OpLoc, diag::err_typecheck_unary_expr, opType);
+
+ if (opType->isPromotableIntegerType()) // C99 6.5.3.3p2
+ resultType = Context.IntTy;
+ break;
+ case UnaryOperator::SizeOf: // C99 6.5.3.4 TODO
+ break;
+ default:
+ break;
+ }
+ return new UnaryOperator((Expr*)Input, Opc, resultType);
+ }
}
Action::ExprResult Sema::
@@ -392,12 +425,21 @@
return new ConditionalOperator((Expr*)Cond, (Expr*)LHS, (Expr*)RHS);
}
+/// ImplicitConversion - Performs various conversions that are common to most
+/// operators. At present, this routine only handles conversions that require
+/// synthesizing an expression/type. Arithmetic type promotions are done locally,
+/// since they don't require a new expression.
Expr *Sema::ImplicitConversion(Expr *E) {
-#if 0
QualType t = E->getType();
- if (t != 0) t.dump();
- else printf("no type for expr %s\n", E->getStmtClassName());
-#endif
+ assert(!t.isNull() && "no type for implicit conversion");
+
+ if (t->isFunctionType()) // C99 6.3.2.1p4
+ return new UnaryOperator(E, UnaryOperator::AddrOf, Context.getPointerType(t));
+ else if (t->isArrayType()) { // C99 6.3.2.1p3
+ QualType elt = cast<ArrayType>(t)->getElementType();
+ QualType convertedType = Context.getPointerType(elt);
+ return new UnaryOperator(E, UnaryOperator::AddrOf, convertedType);
+ }
return E;
}
Modified: cfe/cfe/trunk/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Type.cpp?rev=39409&r1=39408&r2=39409&view=diff
==============================================================================
--- cfe/cfe/trunk/AST/Type.cpp (original)
+++ cfe/cfe/trunk/AST/Type.cpp Wed Jul 11 11:44:03 2007
@@ -199,6 +199,24 @@
return false;
}
+bool Type::isPromotableIntegerType() const {
+ if (CanonicalType->getTypeClass() == Builtin) {
+ const BuiltinType *BT = static_cast<BuiltinType*>(CanonicalType.getTypePtr());
+ switch (BT->getKind()) {
+ case BuiltinType::Bool:
+ case BuiltinType::Char:
+ case BuiltinType::SChar:
+ case BuiltinType::UChar:
+ case BuiltinType::Short:
+ case BuiltinType::UShort:
+ return true;
+ default:
+ return false;
+ }
+ }
+ return false;
+}
+
/// isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type,
/// does not have an incomplete type, does not have a const-qualified type, and
/// if it is a structure or union, does not have any member (including,
Modified: cfe/cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaExpr.cpp?rev=39409&r1=39408&r2=39409&view=diff
==============================================================================
--- cfe/cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaExpr.cpp Wed Jul 11 11:44:03 2007
@@ -180,9 +180,42 @@
return CheckAddressOfOperand((Expr *)Input, OpLoc, Opc);
else if (Opc == UnaryOperator::Deref)
return CheckIndirectionOperand((Expr *)Input, OpLoc, Opc);
-
- // when all the check functions are written, this will go away...
- return new UnaryOperator((Expr*)Input, Opc, QualType());
+ else {
+ // handle the arithmetic unary operators (C99 6.5.3.3)
+ QualType opType = ImplicitConversion((Expr *)Input)->getType();
+ assert(!opType.isNull() && "no type for arithmetic unary expression");
+ QualType resultType = opType;
+
+ switch (Opc) {
+ case UnaryOperator::Plus:
+ case UnaryOperator::Minus:
+ if (!opType->isArithmeticType()) // C99 6.5.3.3p1
+ return Diag(OpLoc, diag::err_typecheck_unary_expr, opType);
+
+ if (opType->isPromotableIntegerType()) // C99 6.5.3.3p2
+ resultType = Context.IntTy;
+ break;
+ case UnaryOperator::Not: // bitwise complement
+ if (!opType->isIntegralType()) // C99 6.5.3.3p1
+ return Diag(OpLoc, diag::err_typecheck_unary_expr, opType);
+
+ if (opType->isPromotableIntegerType()) // C99 6.5.3.3p2
+ resultType = Context.IntTy;
+ break;
+ case UnaryOperator::LNot: // logical negation
+ if (!opType->isScalarType()) // C99 6.5.3.3p1
+ return Diag(OpLoc, diag::err_typecheck_unary_expr, opType);
+
+ if (opType->isPromotableIntegerType()) // C99 6.5.3.3p2
+ resultType = Context.IntTy;
+ break;
+ case UnaryOperator::SizeOf: // C99 6.5.3.4 TODO
+ break;
+ default:
+ break;
+ }
+ return new UnaryOperator((Expr*)Input, Opc, resultType);
+ }
}
Action::ExprResult Sema::
@@ -392,12 +425,21 @@
return new ConditionalOperator((Expr*)Cond, (Expr*)LHS, (Expr*)RHS);
}
+/// ImplicitConversion - Performs various conversions that are common to most
+/// operators. At present, this routine only handles conversions that require
+/// synthesizing an expression/type. Arithmetic type promotions are done locally,
+/// since they don't require a new expression.
Expr *Sema::ImplicitConversion(Expr *E) {
-#if 0
QualType t = E->getType();
- if (t != 0) t.dump();
- else printf("no type for expr %s\n", E->getStmtClassName());
-#endif
+ assert(!t.isNull() && "no type for implicit conversion");
+
+ if (t->isFunctionType()) // C99 6.3.2.1p4
+ return new UnaryOperator(E, UnaryOperator::AddrOf, Context.getPointerType(t));
+ else if (t->isArrayType()) { // C99 6.3.2.1p3
+ QualType elt = cast<ArrayType>(t)->getElementType();
+ QualType convertedType = Context.getPointerType(elt);
+ return new UnaryOperator(E, UnaryOperator::AddrOf, convertedType);
+ }
return E;
}
Modified: cfe/cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/ExprCXX.h?rev=39409&r1=39408&r2=39409&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/cfe/trunk/include/clang/AST/ExprCXX.h Wed Jul 11 11:44:03 2007
@@ -51,8 +51,6 @@
CXXBoolLiteralExpr(bool val) :
Expr(CXXBoolLiteralExprClass, QualType()), Value(val) {}
- virtual Expr *getPrimaryExpr() { return this; }
-
virtual void visit(StmtVisitor &Visitor);
};
Modified: cfe/cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Type.h?rev=39409&r1=39408&r2=39409&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Type.h Wed Jul 11 11:44:03 2007
@@ -226,6 +226,9 @@
bool isAggregateType() const; // C99 6.2.5p21 (arrays, structures)
bool isLvalue() const; // C99 6.3.2.1
+
+ /// Type Conversions/Promotions
+ bool isPromotableIntegerType() const; // C99 6.3.1.1p2
private:
// this forces clients to use isModifiableLvalue on QualType, the class that
// knows if the type is const. This predicate is a helper to QualType.
Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=39409&r1=39408&r2=39409&view=diff
==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:44:03 2007
@@ -533,6 +533,8 @@
"address of register variable requested")
DIAG(err_typecheck_invalid_lvalue_addrof, ERROR,
"invalid lvalue in address expression")
+DIAG(err_typecheck_unary_expr, ERROR,
+ "invalid argument type to unary expression '%s'")
// Statements.
DIAG(err_continue_not_in_loop, ERROR,
More information about the cfe-commits
mailing list