diff options
author | John McCall <rjmccall@apple.com> | 2011-09-13 23:05:03 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2011-09-13 23:05:03 +0000 |
commit | a45680b7e7c49ea9893c6cff585984f3e4120366 (patch) | |
tree | 0f2ea940c7aabddba908ed89e0d9f77510d9769a /lib/CodeGen/CGBuiltin.cpp | |
parent | 36f37b6f578249c20d7a3b3aa77f0a00069ca9ac (diff) |
Correctly generate IR for casted "builtin" functions, where
the builtin is really just a predefined declaration. These are
totally valid to cast.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139657 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGBuiltin.cpp')
-rw-r--r-- | lib/CodeGen/CGBuiltin.cpp | 48 |
1 files changed, 41 insertions, 7 deletions
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index 271fe66ffe..ca2450a8b5 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -27,6 +27,30 @@ using namespace clang; using namespace CodeGen; using namespace llvm; +/// getBuiltinLibFunction - Given a builtin id for a function like +/// "__builtin_fabsf", return a Function* for "fabsf". +llvm::Value *CodeGenModule::getBuiltinLibFunction(const FunctionDecl *FD, + unsigned BuiltinID) { + assert(Context.BuiltinInfo.isLibFunction(BuiltinID)); + + // Get the name, skip over the __builtin_ prefix (if necessary). + StringRef Name; + GlobalDecl D(FD); + + // If the builtin has been declared explicitly with an assembler label, + // use the mangled name. This differs from the plain label on platforms + // that prefix labels. + if (FD->hasAttr<AsmLabelAttr>()) + Name = getMangledName(D); + else + Name = Context.BuiltinInfo.GetName(BuiltinID) + 10; + + llvm::FunctionType *Ty = + cast<llvm::FunctionType>(getTypes().ConvertType(FD->getType())); + + return GetOrCreateLLVMFunction(Name, Ty, D, /*ForVTable=*/false); +} + /// Emit the conversions required to turn the given value into an /// integer of the given size. static Value *EmitToInt(CodeGenFunction &CGF, llvm::Value *V, @@ -142,6 +166,12 @@ static Value *EmitFAbs(CodeGenFunction &CGF, Value *V, QualType ValTy) { return CGF.Builder.CreateCall(Fn, V, "abs"); } +static RValue emitLibraryCall(CodeGenFunction &CGF, const FunctionDecl *Fn, + const CallExpr *E, llvm::Value *calleeValue) { + return CGF.EmitCall(E->getCallee()->getType(), calleeValue, + ReturnValueSlot(), E->arg_begin(), E->arg_end(), Fn); +} + RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, unsigned BuiltinID, const CallExpr *E) { // See if we can constant fold this builtin. If so, don't emit it at all. @@ -1005,13 +1035,17 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, } } - // If this is an alias for a libm function (e.g. __builtin_sin) turn it into - // that function. - if (getContext().BuiltinInfo.isLibFunction(BuiltinID) || - getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID)) - return EmitCall(E->getCallee()->getType(), - CGM.getBuiltinLibFunction(FD, BuiltinID), - ReturnValueSlot(), E->arg_begin(), E->arg_end(), FD); + // If this is an alias for a lib function (e.g. __builtin_sin), emit + // the call using the normal call path, but using the unmangled + // version of the function name. + if (getContext().BuiltinInfo.isLibFunction(BuiltinID)) + return emitLibraryCall(*this, FD, E, + CGM.getBuiltinLibFunction(FD, BuiltinID)); + + // If this is a predefined lib function (e.g. malloc), emit the call + // using exactly the normal call path. + if (getContext().BuiltinInfo.isPredefinedLibFunction(BuiltinID)) + return emitLibraryCall(*this, FD, E, EmitScalarExpr(E->getCallee())); // See if we have a target specific intrinsic. const char *Name = getContext().BuiltinInfo.GetName(BuiltinID); |