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 | 30e4efd4588231f9de0a331e60ea7c7bf9e71033 (patch) | |
tree | ba875515a0308aa501908c3ddcc4456c05881a9f /clang/lib | |
parent | 75461af000d156b89f7c6fd3fae9e536440b65cb (diff) | |
download | bcm5719-llvm-30e4efd4588231f9de0a331e60ea7c7bf9e71033.tar.gz bcm5719-llvm-30e4efd4588231f9de0a331e60ea7c7bf9e71033.zip |
Correctly generate IR for casted "builtin" functions, where
the builtin is really just a predefined declaration. These are
totally valid to cast.
llvm-svn: 139657
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/CGBuiltin.cpp | 48 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 30 |
2 files changed, 41 insertions, 37 deletions
diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 271fe66ffe7..ca2450a8b58 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/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); diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 7a946cb9d5d..19c3b064d65 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -27,7 +27,6 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/Mangle.h" #include "clang/AST/RecordLayout.h" -#include "clang/Basic/Builtins.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" @@ -1611,35 +1610,6 @@ void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) { SetCommonAttributes(D, GA); } -/// 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) || - Context.BuiltinInfo.isPredefinedLibFunction(BuiltinID)) && - "isn't a lib fn"); - - // 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 if (Context.BuiltinInfo.isLibFunction(BuiltinID)) - Name = Context.BuiltinInfo.GetName(BuiltinID) + 10; - else - Name = Context.BuiltinInfo.GetName(BuiltinID); - - - llvm::FunctionType *Ty = - cast<llvm::FunctionType>(getTypes().ConvertType(FD->getType())); - - return GetOrCreateLLVMFunction(Name, Ty, D, /*ForVTable=*/false); -} - llvm::Function *CodeGenModule::getIntrinsic(unsigned IID, ArrayRef<llvm::Type*> Tys) { return llvm::Intrinsic::getDeclaration(&getModule(), (llvm::Intrinsic::ID)IID, |