]> granicus.if.org Git - clang/commitdiff
add the ability to get the llvm function corresponding to a library builtin.
authorChris Lattner <sabre@nondot.org>
Fri, 31 Aug 2007 04:31:45 +0000 (04:31 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 31 Aug 2007 04:31:45 +0000 (04:31 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41633 91177308-0d34-0410-b5e6-96231b3b80d8

CodeGen/CGBuiltin.cpp
CodeGen/CodeGenFunction.h
CodeGen/CodeGenModule.cpp
CodeGen/CodeGenModule.h

index 833b1882d10664a6f0e486317f90477924e1ca6e..a04557bd00cac1ff2ce59fae628abdf1e2bddf65 100644 (file)
@@ -13,6 +13,7 @@
 
 #include "CodeGenFunction.h"
 #include "CodeGenModule.h"
+#include "clang/AST/ASTContext.h"
 #include "clang/AST/Builtins.h"
 #include "clang/AST/Expr.h"
 #include "llvm/Constants.h"
@@ -45,3 +46,9 @@ RValue CodeGenFunction::EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E) {
       
   return RValue::get(0);
 }
+
+RValue CodeGenFunction::EmitBuiltinLibFuncExpr(unsigned BuiltinID, 
+                                               const CallExpr *E) {
+  //llvm::Function *Callee = CGM.getBuiltinLibFunction(BuiltinID);
+  return RValue();
+}
index 3b8d7a20aff03b310d067a63bea0fc77b2d89018..12c227bad9af22ab05742b26f59d5fa3c7eed6f4 100644 (file)
@@ -325,6 +325,7 @@ public:
 
   RValue EmitCallExpr(const CallExpr *E);
   RValue EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E);
+  RValue EmitBuiltinLibFuncExpr(unsigned BuiltinID, const CallExpr *E);
 
   llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E);
 
index 74c7d43e1d2f3dfaa425c31ffbe2313a2e828bbc..a6a887f90fad1b8e7e4d218aaf6fbddbfa3e8c78 100644 (file)
@@ -18,8 +18,7 @@
 #include "clang/Basic/TargetInfo.h"
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
-#include "llvm/Function.h"
-#include "llvm/GlobalVariable.h"
+#include "llvm/Module.h"
 #include "llvm/Intrinsics.h"
 using namespace clang;
 using namespace CodeGen;
@@ -101,6 +100,41 @@ void CodeGenModule::EmitGlobalVarDeclarator(const FileVarDecl *D) {
     EmitGlobalVar(D);
 }
 
+/// getBuiltinLibFunction
+llvm::Function *CodeGenModule::getBuiltinLibFunction(unsigned BuiltinID) {
+  if (BuiltinFunctions.size() <= BuiltinID)
+    BuiltinFunctions.resize(BuiltinID);
+  
+  // Already available?
+  llvm::Function *&FunctionSlot = BuiltinFunctions[BuiltinID];
+  if (FunctionSlot)
+    return FunctionSlot;
+  
+  assert(Context.BuiltinInfo.isLibFunction(BuiltinID) && "isn't a lib fn");
+  
+  // Get the name, skip over the __builtin_ prefix.
+  const char *Name = Context.BuiltinInfo.GetName(BuiltinID)+10;
+  
+  // Get the type for the builtin.
+  QualType Type = Context.BuiltinInfo.GetBuiltinType(BuiltinID, Context);
+  const llvm::FunctionType *Ty = 
+    cast<llvm::FunctionType>(getTypes().ConvertType(Type));
+
+  // FIXME: This has a serious problem with code like this:
+  //  void abs() {}
+  //    ... __builtin_abs(x);
+  // The two versions of abs will collide.  The fix is for the builtin to win,
+  // and for the existing one to be turned into a constantexpr cast of the
+  // builtin.  In the case where the existing one is a static function, it
+  // should just be renamed.
+  assert(getModule().getFunction(Name) == 0 && "FIXME: Name collision");
+
+  // FIXME: param attributes for sext/zext etc.
+  return FunctionSlot = new llvm::Function(Ty, llvm::Function::ExternalLinkage,
+                                           Name, &getModule());
+}
+
+
 llvm::Function *CodeGenModule::getMemCpyFn() {
   if (MemCpyFn) return MemCpyFn;
   llvm::Intrinsic::ID IID;
@@ -114,8 +148,8 @@ llvm::Function *CodeGenModule::getMemCpyFn() {
   return MemCpyFn = llvm::Intrinsic::getDeclaration(&TheModule, IID);
 }
 
-llvm::Constant *CodeGenModule::GetAddrOfConstantCFString(const std::string &str)
-{
+llvm::Constant *CodeGenModule::
+GetAddrOfConstantCFString(const std::string &str) {
   llvm::StringMapEntry<llvm::Constant *> &Entry = 
     CFConstantStringMap.GetOrCreateValue(&str[0], &str[str.length()]);
   
index 97d6a02f47f51ec243acab566644ab0634a7d6ed..af2db808400d3fd961a4fefbd0bf7c127bdd45b8 100644 (file)
@@ -44,6 +44,8 @@ class CodeGenModule {
   
   llvm::StringMap<llvm::Constant*> CFConstantStringMap;
   llvm::Constant *CFConstantStringClassRef;
+  
+  std::vector<llvm::Function *> BuiltinFunctions;
 public:
   CodeGenModule(ASTContext &C, llvm::Module &M);
   
@@ -52,9 +54,15 @@ public:
   CodeGenTypes &getTypes() { return Types; }
   
   llvm::Constant *GetAddrOfGlobalDecl(const Decl *D);
+  
+  /// getBuiltinLibFunction - Given a builtin id for a function like
+  /// "__builtin_fabsf", return a Function* for "fabsf".
+  ///
+  llvm::Function *getBuiltinLibFunction(unsigned BuiltinID);
   llvm::Constant *GetAddrOfConstantCFString(const std::string& str);
   llvm::Function *getMemCpyFn();
   
+  
   void EmitFunction(const FunctionDecl *FD);
   void EmitGlobalVar(const FileVarDecl *D);
   void EmitGlobalVarDeclarator(const FileVarDecl *D);