From 1186bf1350145474bb7f0ab4d38ec33dae5c79d2 Mon Sep 17 00:00:00 2001
From: Nick Lewycky <nicholas@mxc.ca>
Date: Sun, 4 Jan 2009 22:54:40 +0000
Subject: [PATCH] Add a mechanism to specify attributes in getOrInsertFunction.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@61645 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/llvm/Module.h |  9 ++++++++-
 lib/VMCore/Module.cpp | 33 ++++++++++++++++++++++++++++++---
 2 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/include/llvm/Module.h b/include/llvm/Module.h
index 09eba81b4eb..af687c84c30 100644
--- a/include/llvm/Module.h
+++ b/include/llvm/Module.h
@@ -194,6 +194,9 @@ public:
   ///      the existing function.
   ///   4. Finally, the function exists but has the wrong prototype: return the
   ///      function with a constantexpr cast to the right prototype.
+  Constant *getOrInsertFunction(const std::string &Name, const FunctionType *T,
+                                AttrListPtr AttributeList);
+
   Constant *getOrInsertFunction(const std::string &Name, const FunctionType *T);
 
   /// getOrInsertFunction - Look up the specified function in the module symbol
@@ -203,7 +206,11 @@ public:
   /// named function has a different type.  This version of the method takes a
   /// null terminated list of function arguments, which makes it easier for
   /// clients to use.
-  Constant *getOrInsertFunction(const std::string &Name, const Type *RetTy,...)
+  Constant *getOrInsertFunction(const std::string &Name,
+                                AttrListPtr AttributeList,
+                                const Type *RetTy, ...)  END_WITH_NULL;
+
+  Constant *getOrInsertFunction(const std::string &Name, const Type *RetTy, ...)
     END_WITH_NULL;
 
   /// getFunction - Look up the specified function in the module symbol table.
diff --git a/lib/VMCore/Module.cpp b/lib/VMCore/Module.cpp
index b7bb49184b0..d5b48c0a73b 100644
--- a/lib/VMCore/Module.cpp
+++ b/lib/VMCore/Module.cpp
@@ -137,7 +137,8 @@ Module::PointerSize Module::getPointerSize() const {
 // the symbol table directly for this common task.
 //
 Constant *Module::getOrInsertFunction(const std::string &Name,
-                                      const FunctionType *Ty) {
+                                      const FunctionType *Ty,
+                                      AttrListPtr AttributeList) {
   ValueSymbolTable &SymTab = getValueSymbolTable();
 
   // See if we have a definition for the specified function already.
@@ -145,6 +146,8 @@ Constant *Module::getOrInsertFunction(const std::string &Name,
   if (F == 0) {
     // Nope, add it
     Function *New = Function::Create(Ty, GlobalVariable::ExternalLinkage, Name);
+    if (!New->isIntrinsic())       // Intrinsics get attrs set on construction
+      New->setAttributes(AttributeList);
     FunctionList.push_back(New);
     return New;                    // Return the new prototype.
   }
@@ -168,11 +171,35 @@ Constant *Module::getOrInsertFunction(const std::string &Name,
   return F;  
 }
 
+Constant *Module::getOrInsertFunction(const std::string &Name,
+                                      const FunctionType *Ty) {
+  AttrListPtr AttributeList = AttrListPtr::get((AttributeWithIndex *)0, 0);
+  return getOrInsertFunction(Name, Ty, AttributeList);
+}
+
 // getOrInsertFunction - Look up the specified function in the module symbol
 // table.  If it does not exist, add a prototype for the function and return it.
 // This version of the method takes a null terminated list of function
 // arguments, which makes it easier for clients to use.
 //
+Constant *Module::getOrInsertFunction(const std::string &Name,
+                                      AttrListPtr AttributeList,
+                                      const Type *RetTy, ...) {
+  va_list Args;
+  va_start(Args, RetTy);
+
+  // Build the list of argument types...
+  std::vector<const Type*> ArgTys;
+  while (const Type *ArgTy = va_arg(Args, const Type*))
+    ArgTys.push_back(ArgTy);
+
+  va_end(Args);
+
+  // Build the function type and chain to the other getOrInsertFunction...
+  return getOrInsertFunction(Name, FunctionType::get(RetTy, ArgTys, false),
+                             AttributeList);
+}
+
 Constant *Module::getOrInsertFunction(const std::string &Name,
                                       const Type *RetTy, ...) {
   va_list Args;
@@ -186,10 +213,10 @@ Constant *Module::getOrInsertFunction(const std::string &Name,
   va_end(Args);
 
   // Build the function type and chain to the other getOrInsertFunction...
-  return getOrInsertFunction(Name, FunctionType::get(RetTy, ArgTys, false));
+  return getOrInsertFunction(Name, FunctionType::get(RetTy, ArgTys, false),
+                             AttrListPtr::get((AttributeWithIndex *)0, 0));
 }
 
-
 // getFunction - Look up the specified function in the module symbol table.
 // If it does not exist, return null.
 //