[cfe-commits] r41558 - in /cfe/trunk/Sema: Sema.h SemaExpr.cpp
Steve Naroff
snaroff at apple.com
Tue Aug 28 16:30:40 PDT 2007
Author: snaroff
Date: Tue Aug 28 18:30:39 2007
New Revision: 41558
URL: http://llvm.org/viewvc/llvm-project?rev=41558&view=rev
Log:
Implement default argument promotions (for old-style function calls and variable argument lists).
[dylan:~/llvm/tools/clang] admin% cat x.c
int printf(const char *, ...);
int oldschool();
void foo() {
float f;
short i;
printf("foo %f", 1.0f);
oldschool(f,i);
}
[dylan:~/llvm/tools/clang] admin% ../../Debug/bin/clang x.c -parse-ast-dump
int printf(char const *, ...);
int oldschool();
void foo()
(CompoundStmt 0x3105f00
(DeclStmt 0x3105ba0
0x3105ce0 "float f")
(DeclStmt 0x3105c90
0x3105d10 "short i")
(CallExpr 0x3105df0 'int'
(ImplicitCastExpr 0x3105dc0 'int (*)(char const *, ...)'
(DeclRefExpr 0x3105c20 'int (char const *, ...)' Decl='printf' 0x3105bd0))
(ImplicitCastExpr 0x3105dd0 'char const *'
(StringLiteral 0x3105d60 'char *' "foo %f"))
(ImplicitCastExpr 0x3105de0 'double'
(FloatingLiteral 0x3105d80 'float' 1.000000)))
(CallExpr 0x3105ed0 'int'
(ImplicitCastExpr 0x3105ea0 'int (*)()'
(DeclRefExpr 0x3105e20 'int ()' Decl='oldschool' 0x3105c40))
(ImplicitCastExpr 0x3105eb0 'double'
(DeclRefExpr 0x3105e40 'float' Decl='f' 0x3105ce0))
(ImplicitCastExpr 0x3105ec0 'int'
(DeclRefExpr 0x3105e60 'short' Decl='i' 0x3105d10))))
Modified:
cfe/trunk/Sema/Sema.h
cfe/trunk/Sema/SemaExpr.cpp
Modified: cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=41558&r1=41557&r2=41558&view=diff
==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Tue Aug 28 18:30:39 2007
@@ -344,6 +344,11 @@
// to their respective pointers (C99 6.3.2.1).
void DefaultFunctionArrayConversion(Expr *&expr);
+ // DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that
+ // do not have a prototype. Integer promotions are performed on each
+ // argument, and arguments that have type float are promoted to double.
+ void DefaultArgumentPromotion(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
Modified: cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaExpr.cpp?rev=41558&r1=41557&r2=41558&view=diff
==============================================================================
--- cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/Sema/SemaExpr.cpp Tue Aug 28 18:30:39 2007
@@ -585,11 +585,31 @@
Fn->getSourceRange(), argExpr->getSourceRange());
}
}
- // Even if the types checked, bail if we had the wrong number of arguments.
- if (NumArgsInCall != NumArgsInProto && !proto->isVariadic())
+ if (NumArgsInCall > NumArgsInProto && proto->isVariadic()) {
+ // Promote the arguments (C99 6.5.2.2p7).
+ for (unsigned i = NumArgsInProto; i < NumArgsInCall; i++) {
+ Expr *argExpr = Args[i];
+ assert(argExpr && "ParseCallExpr(): missing argument expression");
+
+ DefaultArgumentPromotion(argExpr);
+ if (Args[i] != argExpr) // The expression was converted.
+ Args[i] = argExpr; // Make sure we store the converted expression.
+ }
+ } else if (NumArgsInCall != NumArgsInProto && !proto->isVariadic()) {
+ // Even if the types checked, bail if the number of arguments don't match.
return true;
+ }
+ } else if (isa<FunctionTypeNoProto>(funcT)) {
+ // Promote the arguments (C99 6.5.2.2p6).
+ for (unsigned i = 0; i < NumArgsInCall; i++) {
+ Expr *argExpr = Args[i];
+ assert(argExpr && "ParseCallExpr(): missing argument expression");
+
+ DefaultArgumentPromotion(argExpr);
+ if (Args[i] != argExpr) // The expression was converted.
+ Args[i] = argExpr; // Make sure we store the converted expression.
+ }
}
-
// Do special checking on direct calls to functions.
if (ImplicitCastExpr *IcExpr = dyn_cast<ImplicitCastExpr>(Fn))
if (DeclRefExpr *DRExpr = dyn_cast<DeclRefExpr>(IcExpr->getSubExpr()))
@@ -746,6 +766,19 @@
return;
}
+/// DefaultArgumentPromotion (C99 6.5.2.2p6). Used for function calls that
+/// do not have a prototype. Integer promotions are performed on each
+/// argument, and arguments that have type float are promoted to double.
+void Sema::DefaultArgumentPromotion(Expr *&expr) {
+ QualType t = expr->getType();
+ assert(!t.isNull() && "DefaultArgumentPromotion - missing type");
+
+ if (t->isPromotableIntegerType()) // C99 6.3.1.1p2
+ promoteExprToType(expr, Context.IntTy);
+ if (t == Context.FloatTy)
+ promoteExprToType(expr, Context.DoubleTy);
+}
+
/// DefaultFunctionArrayConversion (C99 6.3.2.1p3, C99 6.3.2.1p4).
void Sema::DefaultFunctionArrayConversion(Expr *&e) {
QualType t = e->getType();
More information about the cfe-commits
mailing list