aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGCall.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2011-03-09 04:27:21 +0000
committerJohn McCall <rjmccall@apple.com>2011-03-09 04:27:21 +0000
commitd26bc76c98006609002d9930f8840490e88ac5b5 (patch)
treef2a0c8ea750e38c4e98b006f171b137a0625f0f9 /lib/CodeGen/CGCall.cpp
parenteecf5fa12d5426637c47d7072f0c193a8d7ff68b (diff)
Use the "undergoes default argument promotion" bit on parameters to
simplify the logic of initializing function parameters so that we don't need both a variable declaration and a type in FunctionArgList. This also means that we need to propagate the CGFunctionInfo down in a lot of places rather than recalculating it from the FAL. There's more we can do to eliminate redundancy here, and I've left FIXMEs behind to do it. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127314 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGCall.cpp')
-rw-r--r--lib/CodeGen/CGCall.cpp55
1 files changed, 38 insertions, 17 deletions
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index bd14d1be09..1ed3f63da1 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -223,10 +223,15 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy,
llvm::SmallVector<CanQualType, 16> ArgTys;
for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end();
i != e; ++i)
- ArgTys.push_back(Context.getCanonicalParamType(i->second));
+ ArgTys.push_back(Context.getCanonicalParamType((*i)->getType()));
return getFunctionInfo(GetReturnType(ResTy), ArgTys, Info);
}
+const CGFunctionInfo &CodeGenTypes::getNullaryFunctionInfo() {
+ llvm::SmallVector<CanQualType, 1> args;
+ return getFunctionInfo(getContext().VoidTy, args, FunctionType::ExtInfo());
+}
+
const CGFunctionInfo &CodeGenTypes::getFunctionInfo(CanQualType ResTy,
const llvm::SmallVectorImpl<CanQualType> &ArgTys,
const FunctionType::ExtInfo &Info,
@@ -826,6 +831,26 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
PAL.push_back(llvm::AttributeWithIndex::get(~0, FuncAttrs));
}
+/// An argument came in as a promoted argument; demote it back to its
+/// declared type.
+static llvm::Value *emitArgumentDemotion(CodeGenFunction &CGF,
+ const VarDecl *var,
+ llvm::Value *value) {
+ const llvm::Type *varType = CGF.ConvertType(var->getType());
+
+ // This can happen with promotions that actually don't change the
+ // underlying type, like the enum promotions.
+ if (value->getType() == varType) return value;
+
+ assert((varType->isIntegerTy() || varType->isFloatingPointTy())
+ && "unexpected promotion type");
+
+ if (isa<llvm::IntegerType>(varType))
+ return CGF.Builder.CreateTrunc(value, varType, "arg.unpromote");
+
+ return CGF.Builder.CreateFPCast(value, varType, "arg.unpromote");
+}
+
void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
llvm::Function *Fn,
const FunctionArgList &Args) {
@@ -860,10 +885,13 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
CGFunctionInfo::const_arg_iterator info_it = FI.arg_begin();
for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end();
i != e; ++i, ++info_it, ++ArgNo) {
- const VarDecl *Arg = i->first;
+ const VarDecl *Arg = *i;
QualType Ty = info_it->type;
const ABIArgInfo &ArgI = info_it->info;
+ bool isPromoted =
+ isa<ParmVarDecl>(Arg) && cast<ParmVarDecl>(Arg)->isKNRPromoted();
+
switch (ArgI.getKind()) {
case ABIArgInfo::Indirect: {
llvm::Value *V = AI;
@@ -893,11 +921,9 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
// Load scalar value from indirect argument.
CharUnits Alignment = getContext().getTypeAlignInChars(Ty);
V = EmitLoadOfScalar(V, false, Alignment.getQuantity(), Ty);
- if (!getContext().typesAreCompatible(Ty, Arg->getType())) {
- // This must be a promotion, for something like
- // "void a(x) short x; {..."
- V = EmitScalarConversion(V, Ty, Arg->getType());
- }
+
+ if (isPromoted)
+ V = emitArgumentDemotion(*this, Arg, V);
}
EmitParmDecl(*Arg, V, ArgNo);
break;
@@ -915,11 +941,9 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
if (Arg->getType().isRestrictQualified())
AI->addAttr(llvm::Attribute::NoAlias);
- if (!getContext().typesAreCompatible(Ty, Arg->getType())) {
- // This must be a promotion, for something like
- // "void a(x) short x; {..."
- V = EmitScalarConversion(V, Ty, Arg->getType());
- }
+ if (isPromoted)
+ V = emitArgumentDemotion(*this, Arg, V);
+
EmitParmDecl(*Arg, V, ArgNo);
break;
}
@@ -969,11 +993,8 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
// Match to what EmitParmDecl is expecting for this type.
if (!CodeGenFunction::hasAggregateLLVMType(Ty)) {
V = EmitLoadOfScalar(V, false, AlignmentToUse, Ty);
- if (!getContext().typesAreCompatible(Ty, Arg->getType())) {
- // This must be a promotion, for something like
- // "void a(x) short x; {..."
- V = EmitScalarConversion(V, Ty, Arg->getType());
- }
+ if (isPromoted)
+ V = emitArgumentDemotion(*this, Arg, V);
}
EmitParmDecl(*Arg, V, ArgNo);
continue; // Skip ++AI increment, already done.