diff gen/irstate.h @ 315:a9697749e898 trunk

[svn r336] Made sure calls within a landing pad area are invokes. Nested trys still need some consideration.
author ChristianK
date Thu, 03 Jul 2008 22:05:45 +0200
parents 8d98e42ece93
children e9c93739bc4c
line wrap: on
line diff
--- a/gen/irstate.h	Wed Jul 02 22:20:18 2008 +0200
+++ b/gen/irstate.h	Thu Jul 03 22:05:45 2008 +0200
@@ -89,6 +89,42 @@
     std::vector<Identifier*> internalLabels;
 };
 
+// llvm::CallInst and llvm::InvokeInst don't share a common base
+// but share common functionality. to avoid duplicating code for
+// adjusting these common properties these structs are made
+struct CallOrInvoke
+{
+    virtual void setParamAttrs(const llvm::PAListPtr& Attrs) = 0;
+    virtual void setCallingConv(unsigned CC) = 0;
+    virtual llvm::Instruction* get() = 0;
+};
+
+struct CallOrInvoke_Call : public CallOrInvoke
+{
+    llvm::CallInst* inst;
+    CallOrInvoke_Call(llvm::CallInst* call) : inst(call) {}
+
+    virtual void setParamAttrs(const llvm::PAListPtr& Attrs)
+    { inst->setParamAttrs(Attrs); }
+    virtual void setCallingConv(unsigned CC)
+    { inst->setCallingConv(CC); }
+    virtual llvm::Instruction* get()
+    { return inst; }
+};
+
+struct CallOrInvoke_Invoke : public CallOrInvoke
+{
+    llvm::InvokeInst* inst;
+    CallOrInvoke_Invoke(llvm::InvokeInst* invoke) : inst(invoke) {}
+
+    virtual void setParamAttrs(const llvm::PAListPtr& Attrs)
+    { inst->setParamAttrs(Attrs); }
+    virtual void setCallingConv(unsigned CC)
+    { inst->setCallingConv(CC); }
+    virtual llvm::Instruction* get()
+    { return inst; }
+};
+
 // represents the module
 struct IRState
 {
@@ -140,6 +176,16 @@
     typedef std::vector<llvm::BasicBlock*> BBVec;
     BBVec landingPads;
 
+    // create a call or invoke, depending on the landing pad info
+    // the template function is defined further down in this file
+    template <typename InputIterator>
+    CallOrInvoke* CreateCallOrInvoke(LLValue* Callee, InputIterator ArgBegin, InputIterator ArgEnd, const char* Name="");
+    CallOrInvoke* CreateCallOrInvoke(LLValue* Callee, const char* Name="");
+    CallOrInvoke* CreateCallOrInvoke(LLValue* Callee, LLValue* Arg1, const char* Name="");
+    CallOrInvoke* CreateCallOrInvoke2(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, const char* Name="");
+    CallOrInvoke* CreateCallOrInvoke3(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, LLValue* Arg3, const char* Name="");
+    CallOrInvoke* CreateCallOrInvoke4(LLValue* Callee, LLValue* Arg1, LLValue* Arg2,  LLValue* Arg3, LLValue* Arg4, const char* Name="");
+
     // loop blocks
     typedef std::vector<IRLoopScope> LoopScopeVec;
     LoopScopeVec loopbbs;
@@ -180,4 +226,18 @@
     LLGlobalVariable* dwarfGVs;
 };
 
+template <typename InputIterator>
+CallOrInvoke* IRState::CreateCallOrInvoke(LLValue* Callee, InputIterator ArgBegin, InputIterator ArgEnd, const char* Name)
+{
+    if(landingPads.empty())
+        return new CallOrInvoke_Call(ir->CreateCall(Callee, ArgBegin, ArgEnd, Name));
+    else
+    {
+        llvm::BasicBlock* postinvoke = llvm::BasicBlock::Create("postinvoke", topfunc(), scopeend());
+        llvm::InvokeInst* invoke = ir->CreateInvoke(Callee, postinvoke, *landingPads.rbegin(), ArgBegin, ArgEnd, Name);
+        scope() = IRScope(postinvoke, scopeend());
+        return new CallOrInvoke_Invoke(invoke);
+    }
+}
+
 #endif // LLVMDC_GEN_IRSTATE_H