aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CodeGenFunction.h
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2008-08-04 16:51:22 +0000
committerDaniel Dunbar <daniel@zuster.org>2008-08-04 16:51:22 +0000
commit0ffb125996336fc7602b162c0a9e392f1a93060f (patch)
tree69ebef4f15bf86bc743f22e598ae9d6a9b87cd39 /lib/CodeGen/CodeGenFunction.h
parentc63a1f276f7b324fd9a4be82098b1c8f7bf30733 (diff)
Add CodeGen support for indirect goto.
- Follows emission scheme used by llvm-gcc, i.e. invent an id for each label whose address is taken and replace each indirect goto by a switch to each possible target. - Currently we emit a switch for each indirect goto instead of merging them as llvm-gcc does. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@54318 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CodeGenFunction.h')
-rw-r--r--lib/CodeGen/CodeGenFunction.h25
1 files changed, 24 insertions, 1 deletions
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 38e10e90ce..374cdf6cd7 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -22,6 +22,7 @@
#include "clang/AST/ExprObjC.h"
#include <vector>
+#include <map>
namespace llvm {
class Module;
@@ -240,11 +241,21 @@ public:
/// AllocaInsertPoint - This is an instruction in the entry block before which
/// we prefer to insert allocas.
llvm::Instruction *AllocaInsertPt;
-
+
const llvm::Type *LLVMIntTy;
uint32_t LLVMPointerWidth;
private:
+ /// LabelIDs - Track arbitrary ids assigned to labels for use in
+ /// implementing the GCC address-of-label extension and indirect
+ /// goto. IDs are assigned to labels inside getIDForAddrOfLabel().
+ std::map<const LabelStmt*, unsigned> LabelIDs;
+
+ /// IndirectSwitches - Record the list of switches for indirect
+ /// gotos. Emission of the actual switching code needs to be delayed
+ /// until all AddrLabelExprs have been seen.
+ std::vector<llvm::SwitchInst*> IndirectSwitches;
+
/// LocalDeclMap - This keeps track of the LLVM allocas or globals for local C
/// decls.
llvm::DenseMap<const Decl*, llvm::Value*> LocalDeclMap;
@@ -342,6 +353,8 @@ public:
/// the input field number being accessed.
static unsigned getAccessedFieldNo(unsigned Idx, const llvm::Constant *Elts);
+ unsigned GetIDForAddrOfLabel(const LabelStmt *L);
+
//===--------------------------------------------------------------------===//
// Declaration Emission
//===--------------------------------------------------------------------===//
@@ -363,6 +376,7 @@ public:
void EmitLabel(const LabelStmt &S); // helper for EmitLabelStmt.
void EmitLabelStmt(const LabelStmt &S);
void EmitGotoStmt(const GotoStmt &S);
+ void EmitIndirectGotoStmt(const IndirectGotoStmt &S);
void EmitIfStmt(const IfStmt &S);
void EmitWhileStmt(const WhileStmt &S);
void EmitDoStmt(const DoStmt &S);
@@ -502,6 +516,15 @@ public:
llvm::GlobalValue *GenerateStaticBlockVarDecl(const VarDecl &D,
bool NoInit,
const char *Separator);
+
+ //===--------------------------------------------------------------------===//
+ // Internal Helpers
+ //===--------------------------------------------------------------------===//
+
+private:
+ /// EmitIndirectSwitches - Emit code for all of the switch
+ /// instructions in IndirectSwitches.
+ void EmitIndirectSwitches();
};
} // end namespace CodeGen
} // end namespace clang