Change DefaultFunctionArrayConversions and UsualUnaryConversions to return void. The caller
needs to query the expression for the type. Since both these functions guarantee the expression contains a valid type, removed old/vacuous asserts (from code calling both of these routines). llvm-svn: 39930
This commit is contained in:
		
							parent
							
								
									7fcaaadf1c
								
							
						
					
					
						commit
						3109001c19
					
				| 
						 | 
				
			
			@ -269,8 +269,12 @@ public:
 | 
			
		|||
                                         tok::TokenKind Kind);
 | 
			
		||||
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(Expr *&expr); 
 | 
			
		||||
  // functions and arrays to their respective pointers (C99 6.3.2.1). 
 | 
			
		||||
  void UsualUnaryConversions(Expr *&expr); 
 | 
			
		||||
  
 | 
			
		||||
  // DefaultFunctionArrayConversion - converts functions and arrays
 | 
			
		||||
  // to their respective pointers (C99 6.3.2.1). 
 | 
			
		||||
  void DefaultFunctionArrayConversion(Expr *&expr);
 | 
			
		||||
  
 | 
			
		||||
  // UsualArithmeticConversions - performs the UsualUnaryConversions on it's
 | 
			
		||||
  // operands and then handles various conversions that are common to binary
 | 
			
		||||
| 
						 | 
				
			
			@ -279,12 +283,6 @@ private:
 | 
			
		|||
  // responsible for emitting appropriate error diagnostics.
 | 
			
		||||
  QualType UsualArithmeticConversions(Expr *&lExpr, Expr *&rExpr,
 | 
			
		||||
                                      QualType &lhs, QualType &rhs);                                      
 | 
			
		||||
                                      
 | 
			
		||||
  // 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).
 | 
			
		||||
  QualType DefaultFunctionArrayConversion(Expr *&expr);
 | 
			
		||||
  
 | 
			
		||||
  enum AssignmentCheckResult {
 | 
			
		||||
    Compatible,
 | 
			
		||||
    Incompatible,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -286,7 +286,6 @@ ParseArraySubscriptExpr(ExprTy *Base, SourceLocation LLoc,
 | 
			
		|||
  DefaultFunctionArrayConversion(RHSExp);
 | 
			
		||||
  
 | 
			
		||||
  QualType LHSTy = LHSExp->getType(), RHSTy = RHSExp->getType();
 | 
			
		||||
  assert(!LHSTy.isNull() && !RHSTy.isNull() && "missing types");
 | 
			
		||||
 | 
			
		||||
  // C99 6.5.2.1p2: the expression e1[e2] is by definition precisely equivalent
 | 
			
		||||
  // to the expression *((e1)+(e2)). This means the array "Base" may actually be 
 | 
			
		||||
| 
						 | 
				
			
			@ -374,13 +373,13 @@ ParseCallExpr(ExprTy *Fn, SourceLocation LParenLoc,
 | 
			
		|||
  Expr *funcExpr = (Expr *)Fn;
 | 
			
		||||
  assert(funcExpr && "no function call expression");
 | 
			
		||||
  
 | 
			
		||||
  QualType qType = UsualUnaryConversions(funcExpr);
 | 
			
		||||
  assert(!qType.isNull() && "no type for function call expression");
 | 
			
		||||
  UsualUnaryConversions(funcExpr);
 | 
			
		||||
  QualType funcType = funcExpr->getType();
 | 
			
		||||
 | 
			
		||||
  // C99 6.5.2.2p1 - "The expression that denotes the called function shall have
 | 
			
		||||
  // type pointer to function".
 | 
			
		||||
  const PointerType *PT = dyn_cast<PointerType>(qType);
 | 
			
		||||
  if (PT == 0) PT = dyn_cast<PointerType>(qType.getCanonicalType());
 | 
			
		||||
  const PointerType *PT = dyn_cast<PointerType>(funcType);
 | 
			
		||||
  if (PT == 0) PT = dyn_cast<PointerType>(funcType.getCanonicalType());
 | 
			
		||||
  
 | 
			
		||||
  if (PT == 0)
 | 
			
		||||
    return Diag(funcExpr->getLocStart(), diag::err_typecheck_call_not_function,
 | 
			
		||||
| 
						 | 
				
			
			@ -482,9 +481,12 @@ ParseCastExpr(SourceLocation LParenLoc, TypeTy *Ty,
 | 
			
		|||
 | 
			
		||||
inline QualType Sema::CheckConditionalOperands( // C99 6.5.15
 | 
			
		||||
  Expr *&cond, Expr *&lex, Expr *&rex, SourceLocation questionLoc) {
 | 
			
		||||
  QualType condT = UsualUnaryConversions(cond);
 | 
			
		||||
  QualType lexT = UsualUnaryConversions(lex);
 | 
			
		||||
  QualType rexT = UsualUnaryConversions(rex);
 | 
			
		||||
  UsualUnaryConversions(cond);
 | 
			
		||||
  UsualUnaryConversions(lex);
 | 
			
		||||
  UsualUnaryConversions(rex);
 | 
			
		||||
  QualType condT = cond->getType();
 | 
			
		||||
  QualType lexT = lex->getType();
 | 
			
		||||
  QualType rexT = rex->getType();
 | 
			
		||||
 | 
			
		||||
  // first, check the condition.
 | 
			
		||||
  if (!condT->isScalarType()) { // C99 6.5.15p2
 | 
			
		||||
| 
						 | 
				
			
			@ -578,15 +580,14 @@ static QualType promoteExprToType(Expr *&expr, QualType type) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
/// DefaultFunctionArrayConversion (C99 6.3.2.1p3, C99 6.3.2.1p4).
 | 
			
		||||
QualType Sema::DefaultFunctionArrayConversion(Expr *&e) {
 | 
			
		||||
void Sema::DefaultFunctionArrayConversion(Expr *&e) {
 | 
			
		||||
  QualType t = e->getType();
 | 
			
		||||
  assert(!t.isNull() && "DefaultFunctionArrayConversion - missing type");
 | 
			
		||||
  
 | 
			
		||||
  if (t->isFunctionType())
 | 
			
		||||
    return promoteExprToType(e, Context.getPointerType(t));
 | 
			
		||||
  if (const ArrayType *ary = dyn_cast<ArrayType>(t.getCanonicalType()))
 | 
			
		||||
    return promoteExprToType(e, Context.getPointerType(ary->getElementType())); 
 | 
			
		||||
  return t;
 | 
			
		||||
    promoteExprToType(e, Context.getPointerType(t));
 | 
			
		||||
  else if (const ArrayType *ary = dyn_cast<ArrayType>(t.getCanonicalType()))
 | 
			
		||||
    promoteExprToType(e, Context.getPointerType(ary->getElementType()));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// UsualUnaryConversion - Performs various conversions that are common to most
 | 
			
		||||
| 
						 | 
				
			
			@ -594,13 +595,14 @@ QualType Sema::DefaultFunctionArrayConversion(Expr *&e) {
 | 
			
		|||
/// 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(Expr *&expr) {
 | 
			
		||||
void Sema::UsualUnaryConversions(Expr *&expr) {
 | 
			
		||||
  QualType t = expr->getType();
 | 
			
		||||
  assert(!t.isNull() && "UsualUnaryConversions - missing type");
 | 
			
		||||
  
 | 
			
		||||
  if (t->isPromotableIntegerType()) // C99 6.3.1.1p2
 | 
			
		||||
    return promoteExprToType(expr, Context.IntTy);
 | 
			
		||||
  return DefaultFunctionArrayConversion(expr);
 | 
			
		||||
    promoteExprToType(expr, Context.IntTy);
 | 
			
		||||
  else
 | 
			
		||||
    DefaultFunctionArrayConversion(expr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// UsualArithmeticConversions - Performs various conversions that are common to 
 | 
			
		||||
| 
						 | 
				
			
			@ -609,8 +611,12 @@ QualType Sema::UsualUnaryConversions(Expr *&expr) {
 | 
			
		|||
/// responsible for emitting appropriate error diagnostics.
 | 
			
		||||
QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,
 | 
			
		||||
                                          QualType &lhs, QualType &rhs) {
 | 
			
		||||
  lhs = UsualUnaryConversions(lhsExpr);
 | 
			
		||||
  rhs = UsualUnaryConversions(rhsExpr);
 | 
			
		||||
  UsualUnaryConversions(lhsExpr);
 | 
			
		||||
  UsualUnaryConversions(rhsExpr);
 | 
			
		||||
  
 | 
			
		||||
  // FIXME: get rid of these reference parameters.
 | 
			
		||||
  lhs = lhsExpr->getType();
 | 
			
		||||
  rhs = rhsExpr->getType();
 | 
			
		||||
  
 | 
			
		||||
  // If both types are identical, no conversion is needed.
 | 
			
		||||
  if (lhs == rhs) 
 | 
			
		||||
| 
						 | 
				
			
			@ -757,9 +763,9 @@ Sema::CheckSingleAssignmentConstraints(QualType lhsType, Expr *&rExpr) {
 | 
			
		|||
  // conversion of functions/arrays. If the conversion were done for all
 | 
			
		||||
  // DeclExpr's (created by ParseIdentifierExpr), it would mess up the unary
 | 
			
		||||
  // expressions that surpress this implicit conversion (&, sizeof).
 | 
			
		||||
  QualType rhsType = DefaultFunctionArrayConversion(rExpr);
 | 
			
		||||
  DefaultFunctionArrayConversion(rExpr);
 | 
			
		||||
  
 | 
			
		||||
  return CheckAssignmentConstraints(lhsType, rhsType);
 | 
			
		||||
  return CheckAssignmentConstraints(lhsType, rExpr->getType());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Sema::AssignmentCheckResult
 | 
			
		||||
| 
						 | 
				
			
			@ -875,8 +881,10 @@ inline QualType Sema::CheckShiftOperands( // C99 6.5.7
 | 
			
		|||
inline QualType Sema::CheckRelationalOperands( // C99 6.5.8
 | 
			
		||||
  Expr *&lex, Expr *&rex, SourceLocation loc)
 | 
			
		||||
{
 | 
			
		||||
  QualType lType = UsualUnaryConversions(lex);
 | 
			
		||||
  QualType rType = UsualUnaryConversions(rex);
 | 
			
		||||
  UsualUnaryConversions(lex);
 | 
			
		||||
  UsualUnaryConversions(rex);
 | 
			
		||||
  QualType lType = lex->getType();
 | 
			
		||||
  QualType rType = rex->getType();
 | 
			
		||||
  
 | 
			
		||||
  if (lType->isRealType() && rType->isRealType())
 | 
			
		||||
    return Context.IntTy;
 | 
			
		||||
| 
						 | 
				
			
			@ -905,8 +913,10 @@ inline QualType Sema::CheckRelationalOperands( // C99 6.5.8
 | 
			
		|||
inline QualType Sema::CheckEqualityOperands( // C99 6.5.9
 | 
			
		||||
  Expr *&lex, Expr *&rex, SourceLocation loc)
 | 
			
		||||
{
 | 
			
		||||
  QualType lType = UsualUnaryConversions(lex);
 | 
			
		||||
  QualType rType = UsualUnaryConversions(rex);
 | 
			
		||||
  UsualUnaryConversions(lex);
 | 
			
		||||
  UsualUnaryConversions(rex);
 | 
			
		||||
  QualType lType = lex->getType();
 | 
			
		||||
  QualType rType = rex->getType();
 | 
			
		||||
  
 | 
			
		||||
  if (lType->isArithmeticType() && rType->isArithmeticType())
 | 
			
		||||
    return Context.IntTy;
 | 
			
		||||
| 
						 | 
				
			
			@ -951,8 +961,10 @@ inline QualType Sema::CheckBitwiseOperands(
 | 
			
		|||
inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14]
 | 
			
		||||
  Expr *&lex, Expr *&rex, SourceLocation loc) 
 | 
			
		||||
{
 | 
			
		||||
  QualType lhsType = UsualUnaryConversions(lex);
 | 
			
		||||
  QualType rhsType = UsualUnaryConversions(rex);
 | 
			
		||||
  UsualUnaryConversions(lex);
 | 
			
		||||
  UsualUnaryConversions(rex);
 | 
			
		||||
  QualType lhsType = lex->getType();
 | 
			
		||||
  QualType rhsType = rex->getType();
 | 
			
		||||
  
 | 
			
		||||
  if (lhsType->isScalarType() || rhsType->isScalarType())
 | 
			
		||||
    return Context.IntTy;
 | 
			
		||||
| 
						 | 
				
			
			@ -1048,7 +1060,8 @@ 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);
 | 
			
		||||
  UsualUnaryConversions(rex);
 | 
			
		||||
  return rex->getType();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// CheckIncrementDecrementOperand - unlike most "Check" methods, this routine
 | 
			
		||||
| 
						 | 
				
			
			@ -1141,9 +1154,8 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
QualType Sema::CheckIndirectionOperand(Expr *op, SourceLocation OpLoc) {
 | 
			
		||||
  QualType qType = UsualUnaryConversions(op);
 | 
			
		||||
  
 | 
			
		||||
  assert(!qType.isNull() && "no type for * expression");
 | 
			
		||||
  UsualUnaryConversions(op);
 | 
			
		||||
  QualType qType = op->getType();
 | 
			
		||||
  
 | 
			
		||||
  if (PointerType *PT = dyn_cast<PointerType>(qType.getCanonicalType())) {
 | 
			
		||||
    QualType ptype = PT->getPointeeType();
 | 
			
		||||
| 
						 | 
				
			
			@ -1348,20 +1360,23 @@ Action::ExprResult Sema::ParseUnaryOp(SourceLocation OpLoc, tok::TokenKind Op,
 | 
			
		|||
    break;
 | 
			
		||||
  case UnaryOperator::Plus:
 | 
			
		||||
  case UnaryOperator::Minus:
 | 
			
		||||
    resultType = UsualUnaryConversions(Input);
 | 
			
		||||
    UsualUnaryConversions(Input);
 | 
			
		||||
    resultType = Input->getType();
 | 
			
		||||
    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);
 | 
			
		||||
    UsualUnaryConversions(Input);
 | 
			
		||||
    resultType = Input->getType();
 | 
			
		||||
    if (!resultType->isIntegerType())  // C99 6.5.3.3p1
 | 
			
		||||
      return Diag(OpLoc, diag::err_typecheck_unary_expr,
 | 
			
		||||
                  resultType.getAsString());
 | 
			
		||||
    break;
 | 
			
		||||
  case UnaryOperator::LNot: // logical negation
 | 
			
		||||
    // Unlike +/-/~, integer promotions aren't done here (C99 6.5.3.3p5).
 | 
			
		||||
    resultType = DefaultFunctionArrayConversion(Input);
 | 
			
		||||
    DefaultFunctionArrayConversion(Input);
 | 
			
		||||
    resultType = Input->getType();
 | 
			
		||||
    if (!resultType->isScalarType()) // C99 6.5.3.3p1
 | 
			
		||||
      return Diag(OpLoc, diag::err_typecheck_unary_expr,
 | 
			
		||||
                  resultType.getAsString());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -107,8 +107,8 @@ Sema::ParseIfStmt(SourceLocation IfLoc, ExprTy *CondVal,
 | 
			
		|||
  Expr *condExpr = (Expr *)CondVal;
 | 
			
		||||
  assert(condExpr && "ParseIfStmt(): missing expression");
 | 
			
		||||
  
 | 
			
		||||
  QualType condType = DefaultFunctionArrayConversion(condExpr);
 | 
			
		||||
  assert(!condType.isNull() && "ParseIfStmt(): missing expression type");
 | 
			
		||||
  DefaultFunctionArrayConversion(condExpr);
 | 
			
		||||
  QualType condType = condExpr->getType();
 | 
			
		||||
  
 | 
			
		||||
  if (!condType->isScalarType()) // C99 6.8.4.1p1
 | 
			
		||||
    return Diag(IfLoc, diag::err_typecheck_statement_requires_scalar,
 | 
			
		||||
| 
						 | 
				
			
			@ -127,8 +127,8 @@ Sema::ParseWhileStmt(SourceLocation WhileLoc, ExprTy *Cond, StmtTy *Body) {
 | 
			
		|||
  Expr *condExpr = (Expr *)Cond;
 | 
			
		||||
  assert(condExpr && "ParseWhileStmt(): missing expression");
 | 
			
		||||
  
 | 
			
		||||
  QualType condType = DefaultFunctionArrayConversion(condExpr);
 | 
			
		||||
  assert(!condType.isNull() && "ParseWhileStmt(): missing expression type");
 | 
			
		||||
  DefaultFunctionArrayConversion(condExpr);
 | 
			
		||||
  QualType condType = condExpr->getType();
 | 
			
		||||
  
 | 
			
		||||
  if (!condType->isScalarType()) // C99 6.8.5p2
 | 
			
		||||
    return Diag(WhileLoc, diag::err_typecheck_statement_requires_scalar,
 | 
			
		||||
| 
						 | 
				
			
			@ -143,8 +143,8 @@ Sema::ParseDoStmt(SourceLocation DoLoc, StmtTy *Body,
 | 
			
		|||
  Expr *condExpr = (Expr *)Cond;
 | 
			
		||||
  assert(condExpr && "ParseDoStmt(): missing expression");
 | 
			
		||||
  
 | 
			
		||||
  QualType condType = DefaultFunctionArrayConversion(condExpr);
 | 
			
		||||
  assert(!condType.isNull() && "ParseDoStmt(): missing expression type");
 | 
			
		||||
  DefaultFunctionArrayConversion(condExpr);
 | 
			
		||||
  QualType condType = condExpr->getType();
 | 
			
		||||
  
 | 
			
		||||
  if (!condType->isScalarType()) // C99 6.8.5p2
 | 
			
		||||
    return Diag(DoLoc, diag::err_typecheck_statement_requires_scalar,
 | 
			
		||||
| 
						 | 
				
			
			@ -164,8 +164,8 @@ Sema::ParseForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
 | 
			
		|||
  }
 | 
			
		||||
  if (Second) {
 | 
			
		||||
    Expr *testExpr = (Expr *)Second;
 | 
			
		||||
    QualType testType = DefaultFunctionArrayConversion(testExpr);
 | 
			
		||||
    assert(!testType.isNull() && "ParseForStmt(): missing test expression type");
 | 
			
		||||
    DefaultFunctionArrayConversion(testExpr);
 | 
			
		||||
    QualType testType = testExpr->getType();
 | 
			
		||||
    
 | 
			
		||||
    if (!testType->isScalarType()) // C99 6.8.5p2
 | 
			
		||||
      return Diag(ForLoc, diag::err_typecheck_statement_requires_scalar,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -189,7 +189,7 @@
 | 
			
		|||
		1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LiteralSupport.cpp; sourceTree = "<group>"; };
 | 
			
		||||
		84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AttributeList.cpp; path = Parse/AttributeList.cpp; sourceTree = "<group>"; };
 | 
			
		||||
		84D9A88B0C1A581300AC7ABC /* AttributeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AttributeList.h; path = clang/Parse/AttributeList.h; sourceTree = "<group>"; };
 | 
			
		||||
		8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "compiled.mach-o.executable"; path = clang; sourceTree = BUILT_PRODUCTS_DIR; };
 | 
			
		||||
		8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = clang; sourceTree = BUILT_PRODUCTS_DIR; };
 | 
			
		||||
		DE01DA480B12ADA300AC22CE /* PPCallbacks.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PPCallbacks.h; sourceTree = "<group>"; };
 | 
			
		||||
		DE06756B0C051CFE00EBBFD8 /* ParseExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseExprCXX.cpp; path = Parse/ParseExprCXX.cpp; sourceTree = "<group>"; };
 | 
			
		||||
		DE06B73D0A8307640050E87E /* LangOptions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LangOptions.h; sourceTree = "<group>"; };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue