本文整理汇总了C++中StructType::setBody方法的典型用法代码示例。如果您正苦于以下问题:C++ StructType::setBody方法的具体用法?C++ StructType::setBody怎么用?C++ StructType::setBody使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类StructType
的用法示例。
在下文中一共展示了StructType::setBody方法的14个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: createFunctionType
FunctionType* ArgumentRecovery::createFunctionType(TargetInfo& info, const CallInformation& callInfo, llvm::Module& module, StringRef returnTypeName, SmallVectorImpl<string>& parameterNames)
{
LLVMContext& ctx = module.getContext();
Type* integer = Type::getIntNTy(ctx, info.getPointerSize() * CHAR_BIT);
SmallVector<Type*, 8> parameterTypes;
for (const auto& param : callInfo.parameters())
{
if (param.type == ValueInformation::IntegerRegister)
{
parameterTypes.push_back(integer);
parameterNames.push_back(param.registerInfo->name);
}
else if (param.type == ValueInformation::Stack)
{
parameterTypes.push_back(integer);
parameterNames.emplace_back();
raw_string_ostream(parameterNames.back()) << "sp" << param.frameBaseOffset;
}
else
{
llvm_unreachable("not implemented");
}
}
SmallVector<Type*, 2> returnTypes;
for (const auto& ret : callInfo.returns())
{
if (ret.type == ValueInformation::IntegerRegister)
{
returnTypes.push_back(integer);
}
else
{
llvm_unreachable("not implemented");
}
}
Type* returnType;
if (returnTypes.size() == 0)
{
returnType = Type::getVoidTy(ctx);
}
else if (returnTypes.size() == 1)
{
returnType = returnTypes.front();
}
else
{
StructType* structTy = StructType::create(ctx, returnTypeName);
structTy->setBody(returnTypes);
md::setRecoveredReturnFieldNames(module, *structTy, callInfo);
returnType = structTy;
}
assert(!callInfo.isVararg() && "not implemented");
return FunctionType::get(returnType, parameterTypes, false);
}
示例2: linkDefinedTypeBodies
void TypeMapTy::linkDefinedTypeBodies() {
SmallVector<Type *, 16> Elements;
for (StructType *SrcSTy : SrcDefinitionsToResolve) {
StructType *DstSTy = cast<StructType>(MappedTypes[SrcSTy]);
assert(DstSTy->isOpaque());
// Map the body of the source type over to a new body for the dest type.
Elements.resize(SrcSTy->getNumElements());
for (unsigned I = 0, E = Elements.size(); I != E; ++I)
Elements[I] = get(SrcSTy->getElementType(I));
DstSTy->setBody(Elements, SrcSTy->isPacked());
DstStructTypesSet.switchToNonOpaque(DstSTy);
}
SrcDefinitionsToResolve.clear();
DstResolvedOpaqueTypes.clear();
}
示例3: main
int main(int argc, char **argv)
{
InitializeNativeTarget();
LLVMContext &Context = getGlobalContext();
Module *m = new Module("test", Context);
Type *intTy = Type::getInt64Ty(Context);
StructType* structTy = StructType::create(Context, "struct.list");
std::vector<Type*> fields;
fields.push_back(intTy);
fields.push_back(PointerType::get(structTy, 0));
if (structTy->isOpaque()) {
structTy->setBody(fields, false);
}
/*
* int f1(struct x *p) { return p->next->l1; }
*/
std::vector<Type*> args_type;
args_type.push_back(PointerType::get(structTy, 0));
FunctionType *fnTy = FunctionType::get(intTy, args_type, false);
Function *func = Function::Create(fnTy,
GlobalValue::ExternalLinkage, "f1", m);
Value *v = func->arg_begin();
BasicBlock *bb = BasicBlock::Create(Context, "EntryBlock", func);
IRBuilder<> *builder = new IRBuilder<>(bb);
v = builder->CreateStructGEP(v, 1);
v = builder->CreateLoad(v, "load0");
v = builder->CreateStructGEP(v, 0);
v = builder->CreateLoad(v, "load1");
builder->CreateRet(v);
(*m).dump();
{
ExecutionEngine *ee = EngineBuilder(m).
setEngineKind(EngineKind::JIT).create();
void *f = ee->getPointerToFunction(func);
typedef int (*func_t) (struct x *);
struct x o = {10, NULL}, v = {};
v.next = &o;
std::cout << ((func_t)f)(&v) << std::endl;
}
return 0;
}
示例4: Key
StructType *StructType::get(LLVMContext &Context, ArrayRef<Type*> ETypes,
bool isPacked) {
LLVMContextImpl *pImpl = Context.pImpl;
AnonStructTypeKeyInfo::KeyTy Key(ETypes, isPacked);
auto I = pImpl->AnonStructTypes.find_as(Key);
StructType *ST;
if (I == pImpl->AnonStructTypes.end()) {
// Value not found. Create a new type!
ST = new (Context.pImpl->TypeAllocator) StructType(Context);
ST->setSubclassData(SCDB_IsLiteral); // Literal struct.
ST->setBody(ETypes, isPacked);
Context.pImpl->AnonStructTypes.insert(ST);
} else {
ST = *I;
}
return ST;
}
示例5: expandGlobal
void Preparer::expandGlobal(Module &M, GlobalVariable *GV) {
if (GV->isDeclaration()) return;
if (GV->getLinkage() == GlobalValue::AppendingLinkage) return;
Type *OrigType = GV->getType()->getTypeAtIndex((unsigned)0);
StructType *NewType = StructType::create(GV->getContext(), "pad_global_type");
NewType->setBody(OrigType, IntegerType::get(GV->getContext(), 8), NULL);
// FIXME: AddressSpace?
GlobalVariable *NewGV;
Constant *NewInit = NULL;
if (GV->hasInitializer()) {
assert(GV->getInitializer()->getType() == OrigType);
NewInit = ConstantStruct::get(NewType, GV->getInitializer(),
ConstantInt::get(IntegerType::get(GV->getContext(), 8), 0), NULL);
}
NewGV = new GlobalVariable(M, NewType, GV->isConstant(), GV->getLinkage(),
NewInit, "pad_global", GV, GV->isThreadLocal(), 0);
Constant *NewValue = ConstantExpr::getBitCast(NewGV, GV->getType());
assert(NewValue->getType() == GV->getType());
GV->replaceAllUsesWith(NewValue);
}
示例6: runOnModule
bool PNaClSjLjEH::runOnModule(Module &M) {
Type *JmpBufTy = ArrayType::get(Type::getInt8Ty(M.getContext()),
kPNaClJmpBufSize);
// Define "struct ExceptionFrame".
StructType *ExceptionFrameTy = StructType::create(M.getContext(),
"ExceptionFrame");
Type *ExceptionFrameFields[] = {
JmpBufTy, // jmp_buf
ExceptionFrameTy->getPointerTo(), // struct ExceptionFrame *next
Type::getInt32Ty(M.getContext()) // Exception info (clause list ID)
};
ExceptionFrameTy->setBody(ExceptionFrameFields);
ExceptionInfoWriter ExcInfoWriter(&M.getContext());
for (Module::iterator Func = M.begin(), E = M.end(); Func != E; ++Func) {
FuncRewriter Rewriter(ExceptionFrameTy, &ExcInfoWriter, Func);
Rewriter.expandFunc();
}
ExcInfoWriter.defineGlobalVariables(&M);
return true;
}
示例7: linkDefinedTypeBodies
/// linkDefinedTypeBodies - Produce a body for an opaque type in the dest
/// module from a type definition in the source module.
void TypeMapTy::linkDefinedTypeBodies() {
SmallVector<Type*, 16> Elements;
SmallString<16> TmpName;
// Note that processing entries in this loop (calling 'get') can add new
// entries to the SrcDefinitionsToResolve vector.
while (!SrcDefinitionsToResolve.empty()) {
StructType *SrcSTy = SrcDefinitionsToResolve.pop_back_val();
StructType *DstSTy = cast<StructType>(MappedTypes[SrcSTy]);
// TypeMap is a many-to-one mapping, if there were multiple types that
// provide a body for DstSTy then previous iterations of this loop may have
// already handled it. Just ignore this case.
if (!DstSTy->isOpaque()) continue;
assert(!SrcSTy->isOpaque() && "Not resolving a definition?");
// Map the body of the source type over to a new body for the dest type.
Elements.resize(SrcSTy->getNumElements());
for (unsigned i = 0, e = Elements.size(); i != e; ++i)
Elements[i] = getImpl(SrcSTy->getElementType(i));
DstSTy->setBody(Elements, SrcSTy->isPacked());
// If DstSTy has no name or has a longer name than STy, then viciously steal
// STy's name.
if (!SrcSTy->hasName()) continue;
StringRef SrcName = SrcSTy->getName();
if (!DstSTy->hasName() || DstSTy->getName().size() > SrcName.size()) {
TmpName.insert(TmpName.end(), SrcName.begin(), SrcName.end());
SrcSTy->setName("");
DstSTy->setName(TmpName.str());
TmpName.clear();
}
}
DstResolvedOpaqueTypes.clear();
}
示例8: create
StructType *StructType::create(LLVMContext &Context, ArrayRef<Type*> Elements,
StringRef Name, bool isPacked) {
StructType *ST = create(Context, Name);
ST->setBody(Elements, isPacked);
return ST;
}
示例9: runOnModule
bool AllocateDataSegment::runOnModule(Module &M) {
DataLayout DL(&M);
Type *I8 = Type::getInt8Ty(M.getContext());
Type *I32 = Type::getInt32Ty(M.getContext());
Type *IntPtrType = DL.getIntPtrType(M.getContext());
// First, we do a pass over the global variables, in which we compute
// the amount of required padding between them and consequently their
// addresses relative to the memory base of the sandbox. References to each
// global are then replaced with direct memory pointers.
uint32_t VarOffset = 0;
DenseMap<GlobalVariable*, uint32_t> VarPadding;
for (Module::global_iterator GV = M.global_begin(), E = M.global_end();
GV != E; ++GV) {
assert(GV->hasInitializer());
uint32_t Padding = getPadding(VarOffset, GV, DL);
VarPadding[GV] = Padding;
VarOffset += Padding;
GV->replaceAllUsesWith(
ConstantExpr::getIntToPtr(
ConstantInt::get(IntPtrType,
DataSegmentBaseAddress + VarOffset),
GV->getType()));
VarOffset += DL.getTypeStoreSize(GV->getType()->getPointerElementType());
}
// Using the offsets computed above, we prepare the layout and the contents
// of the desired data structure. After the type and initializer of each
// global is copied, the global is not needed any more and it is erased.
SmallVector<Type*, 10> TemplateLayout;
SmallVector<Constant*, 10> TemplateData;
for (Module::global_iterator It = M.global_begin(), E = M.global_end();
It != E; ) {
GlobalVariable *GV = It++;
uint32_t Padding = VarPadding[GV];
if (Padding > 0) {
Type *PaddingType = ArrayType::get(I8, Padding);
TemplateLayout.push_back(PaddingType);
TemplateData.push_back(ConstantAggregateZero::get(PaddingType));
}
TemplateLayout.push_back(GV->getType()->getPointerElementType());
TemplateData.push_back(GV->getInitializer());
GV->eraseFromParent();
}
// Finally, we create the struct and size global variables.
StructType *TemplateType =
StructType::create(M.getContext(), ExternalSymName_DataSegment);
TemplateType->setBody(TemplateLayout, /*isPacked=*/true);
Constant *Template = ConstantStruct::get(TemplateType, TemplateData);
new GlobalVariable(M, Template->getType(), /*isConstant=*/true,
GlobalVariable::ExternalLinkage, Template,
ExternalSymName_DataSegment);
Constant *TemplateSize =
ConstantInt::get(I32, DL.getTypeAllocSize(TemplateType));
new GlobalVariable(M, TemplateSize->getType(), /*isConstant=*/true,
GlobalVariable::ExternalLinkage, TemplateSize,
ExternalSymName_DataSegmentSize);
return true;
}
示例10: doGlobalInit
void doGlobalInit(Module *M) {
//create the "reg" struct type
StructType *regs = StructType::create(M->getContext(), "struct.regs");
vector<Type *> regFields;
initInstructionDispatch();
//UPDATEREGS -- when we add something to 'regs', add it here
//GPRs
regFields.push_back(IntegerType::get(M->getContext(), 32)); // EAX // 0
regFields.push_back(IntegerType::get(M->getContext(), 32)); // EBX // 1
regFields.push_back(IntegerType::get(M->getContext(), 32)); // ECX // 2
regFields.push_back(IntegerType::get(M->getContext(), 32)); // EDX // 3
regFields.push_back(IntegerType::get(M->getContext(), 32)); // ESI // 4
regFields.push_back(IntegerType::get(M->getContext(), 32)); // EDI // 5
regFields.push_back(IntegerType::get(M->getContext(), 32)); // ESP // 6
regFields.push_back(IntegerType::get(M->getContext(), 32)); // EBP // 7
// 32 bytes
//flags
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // CF // 8
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // PF // 9
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // AF // 10
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // ZF // 11
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // SF // 12
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // OF // 13
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // DF // 14
// 28 bytes
// FPU
ArrayType *fpu_regs = ArrayType::get(Type::getX86_FP80Ty(M->getContext()), 8);
regFields.push_back(fpu_regs); // 80 bytes // 15
// FPU Status Word
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU BUSY // 16
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Condition Code C3 // 17
regFields.push_back(IntegerType::get(M->getContext(), 3)); // TOP OF STACK // 18
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Condition Code C2 // 19
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Condition Code C1 // 20
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Condition Code C0 // 21
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Error Summary Status // 22
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Stack Fault // 23
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Precision Flag // 24
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Underflow Flag // 25
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Overflow Flag // 26
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // ZeroDivide Flag // 27
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Denormalized Operand Flag // 28
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Invalid Operation Flag // 29
// 56 bytes
// 80 + 56 + 28 + 32 = 196 bytes
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU Infinity Flag // 30
regFields.push_back(IntegerType::get(M->getContext(), 2)); // FPU Rounding Control // 31
regFields.push_back(IntegerType::get(M->getContext(), 2)); // FPU Precision Control // 32
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU Precision Mask // 33
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU Underflow Mask // 34
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU Overflow Mask // 35
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU Zero Divide Mask // 36
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU Denormal Operand Mask // 37
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU Invalid Operation Mask // 38
// FPU tag word; 8 element array of 2-bit entries
ArrayType *fpu_tag_word = ArrayType::get(Type::getIntNTy(M->getContext(), 8), 8);
regFields.push_back(fpu_tag_word); // 80 bytes // 39
regFields.push_back(IntegerType::getInt16Ty(M->getContext())); // Last Instruction Ptr Segment 40
regFields.push_back(IntegerType::getInt32Ty(M->getContext())); // Last Instruction Ptr Offset 41
regFields.push_back(IntegerType::getInt16Ty(M->getContext())); // Last Data Ptr Segment 42
regFields.push_back(IntegerType::getInt32Ty(M->getContext())); // Last Data Ptr Offset 43
regFields.push_back(IntegerType::get(M->getContext(), 11)); // FPU FOPCODE 44
// vector registers
regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM0 45
regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM1 46
regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM2 47
regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM3 48
regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM4 49
regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM5 50
regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM6 51
regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM7 52
// non-register values in structRegs
regFields.push_back(IntegerType::getInt32Ty(M->getContext())); // 53: stack base (biggest value)
regFields.push_back(IntegerType::getInt32Ty(M->getContext())); // 54: stack limit (smallest value)
PointerType *ptrToRegs = PointerType::get(regs, 0);
regs->setBody(regFields, true);
vector<Type*> callValArgs;
callValArgs.push_back(Type::getInt32Ty(M->getContext()));
callValArgs.push_back(ptrToRegs);
FunctionType *callVal = FunctionType::get(
Type::getVoidTy(M->getContext()),
callValArgs,
false);
//.........这里部分代码省略.........
示例11: getSimpleFuncType
// Transforms any type that could transitively reference a function pointer
// into a simplified type.
// We enter this function trying to determine the mapping of a type. Because
// of how structs are handled (not interned by llvm - see further comments
// below) we may be working with temporary types - types (pointers, for example)
// transitively referencing "tentative" structs. For that reason, we do not
// memoize anything here, except for structs. The latter is so that we avoid
// unnecessary repeated creation of types (pointers, function types, etc),
// as we try to map a given type.
SimplifiedFuncTypeMap::MappingResult
SimplifiedFuncTypeMap::getSimpleAggregateTypeInternal(LLVMContext &Ctx,
Type *Ty,
StructMap &Tentatives) {
// Leverage the map for types we encounter on the way.
auto Found = MappedTypes.find(Ty);
if (Found != MappedTypes.end()) {
return {Found->second, Found->second != Ty};
}
if (auto *OldFnTy = dyn_cast<FunctionType>(Ty)) {
return getSimpleFuncType(Ctx, Tentatives, OldFnTy);
}
if (auto PtrTy = dyn_cast<PointerType>(Ty)) {
auto NewTy = getSimpleAggregateTypeInternal(
Ctx, PtrTy->getPointerElementType(), Tentatives);
return {NewTy->getPointerTo(PtrTy->getAddressSpace()), NewTy.isChanged()};
}
if (auto ArrTy = dyn_cast<ArrayType>(Ty)) {
auto NewTy = getSimpleAggregateTypeInternal(
Ctx, ArrTy->getArrayElementType(), Tentatives);
return {ArrayType::get(NewTy, ArrTy->getArrayNumElements()),
NewTy.isChanged()};
}
if (auto VecTy = dyn_cast<VectorType>(Ty)) {
auto NewTy = getSimpleAggregateTypeInternal(
Ctx, VecTy->getVectorElementType(), Tentatives);
return {VectorType::get(NewTy, VecTy->getVectorNumElements()),
NewTy.isChanged()};
}
// LLVM doesn't intern identified structs (the ones with a name). This,
// together with the fact that such structs can be recursive,
// complicates things a bit. We want to make sure that we only change
// "unsimplified" structs (those that somehow reference funcs that
// are not simple).
// We don't want to change "simplified" structs, otherwise converting
// instruction types will become trickier.
if (auto StructTy = dyn_cast<StructType>(Ty)) {
ParamTypeVector ElemTypes;
if (!StructTy->isLiteral()) {
// Literals - struct without a name - cannot be recursive, so we
// don't need to form tentatives.
auto Found = Tentatives.find(StructTy);
// Having a tentative means we are in a recursion trying to map this
// particular struct, so arriving back to it is not a change.
// We will determine if this struct is actually
// changed by checking its other fields.
if (Found != Tentatives.end()) {
return {Found->second, false};
}
// We have never seen this struct, so we start a tentative.
std::string NewName = StructTy->getStructName();
NewName += ".simplified";
StructType *Tentative = StructType::create(Ctx, NewName);
Tentatives[StructTy] = Tentative;
bool Changed = isChangedStruct(Ctx, StructTy, ElemTypes, Tentatives);
Tentatives.erase(StructTy);
// We can now decide the mapping of the struct. We will register it
// early with MappedTypes, to avoid leaking tentatives unnecessarily.
// We are leaking the created struct here, but there is no way to
// correctly delete it.
if (!Changed) {
return {MappedTypes[StructTy] = StructTy, false};
} else {
Tentative->setBody(ElemTypes, StructTy->isPacked());
return {MappedTypes[StructTy] = Tentative, true};
}
} else {
bool Changed = isChangedStruct(Ctx, StructTy, ElemTypes, Tentatives);
return {MappedTypes[StructTy] =
StructType::get(Ctx, ElemTypes, StructTy->isPacked()),
Changed};
}
}
// Anything else stays the same.
return {Ty, false};
}
示例12: main
int main() {
InitializeNativeTarget();
LLVMContext& Context = getGlobalContext();
Module *M = new Module("test C++ exception handling ", Context);
StructType* MyStructType = StructType::create(Context, "struct.MyStruct");
Type* MyStructFields[] = {
Type::getInt32Ty(Context),
Type::getInt32Ty(Context)
};
MyStructType->setBody(MyStructFields);
GlobalValue* throwFunc = cast<GlobalValue>(M->getOrInsertFunction("throwMyStruct", Type::getVoidTy(Context), NULL));
GlobalValue* MyStructTypeInfo = cast<GlobalValue>(M->getOrInsertGlobal("MyStructTypeInfo", Type::getInt8Ty(Context)));
Function* gxx_personality = Function::Create(FunctionType::get(Type::getInt32Ty(Context), true), Function::ExternalLinkage, "__gxx_personality_v0", M);
Function* begin_catch = Function::Create(FunctionType::get(Type::getInt8PtrTy(Context), Type::getInt8PtrTy(Context), false), Function::ExternalLinkage, "__cxa_begin_catch", M);
Function* end_catch = Function::Create(FunctionType::get(Type::getVoidTy(Context), false), Function::ExternalLinkage, "__cxa_end_catch", M);
Function* testExceptions = cast<Function>(M->getOrInsertFunction("testExceptions", Type::getInt32Ty(Context), NULL));
BasicBlock* entryBB = BasicBlock::Create(Context, "", testExceptions);
BasicBlock* landPadBB = BasicBlock::Create(Context, "landPad", testExceptions);
BasicBlock* noErrorBB = BasicBlock::Create(Context, "noError", testExceptions);
IRBuilder<> builder(entryBB);
Value* invokeThrow = builder.CreateInvoke(throwFunc, noErrorBB, landPadBB);
builder.SetInsertPoint(noErrorBB);
builder.CreateRet( builder.getInt32(666) ); // should never happen
//writing landingpad! <<<<<<<
builder.SetInsertPoint(landPadBB);
Value* gxx_personality_i8 = builder.CreateBitCast(gxx_personality, Type::getInt8PtrTy(Context));
Type* caughtType = StructType::get(builder.getInt8PtrTy(), builder.getInt32Ty(), NULL);
LandingPadInst* caughtResult = builder.CreateLandingPad(caughtType, gxx_personality_i8, 1);
// we can catch any C++ exception we want
// but now we are catching MyStruct
caughtResult->addClause(MyStructTypeInfo);
//we are sure to catch MyStruct so no other checks are needed
//if throwMyStruct() throws anything but MyStruct it won't pass to the current landingpad BB
Value* thrownExctn = builder.CreateExtractValue(caughtResult, 0);
Value* thrownObject = builder.CreateCall(begin_catch, thrownExctn);
Value* object = builder.CreateBitCast(thrownObject, MyStructType->getPointerTo());
Value* resultPtr = builder.CreateStructGEP(object, 1);
Value* result = builder.CreateLoad(resultPtr);
builder.CreateCall(end_catch);
builder.CreateRet( result ); // << z.y
TargetOptions Opts;
Opts.JITExceptionHandling = true; // DO NOT FORGET THIS OPTION !!!!!!11
ExecutionEngine* EE = EngineBuilder(M)
.setEngineKind(EngineKind::JIT)
.setTargetOptions(Opts)
.create();
EE->addGlobalMapping(throwFunc, reinterpret_cast<void*>(&throwMyStruct));
EE->addGlobalMapping(MyStructTypeInfo, MyStruct::getTypeInfo());
verifyFunction(*testExceptions);
outs() << *testExceptions;
std::vector<GenericValue> noArgs;
GenericValue gv = EE->runFunction(testExceptions, noArgs);
outs() << "\ntestExceptions result: " << gv.IntVal << "\n";
delete EE;
llvm_shutdown();
return 0;
}
示例13: doGlobalInit
//.........这里部分代码省略.........
// FPU Status Word
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU BUSY // 25
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Condition Code C3 // 26
regFields.push_back(IntegerType::get(M->getContext(), 3)); // TOP OF STACK // 27
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Condition Code C2 // 28
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Condition Code C1 // 29
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Condition Code C0 // 30
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Error Summary Status // 31
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Stack Fault // 32
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Precision Flag // 33
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Underflow Flag // 34
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Overflow Flag // 35
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // ZeroDivide Flag // 36
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Denormalized Operand Flag // 37
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // Invalid Operation Flag // 38
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU Infinity Flag // 39
regFields.push_back(IntegerType::get(M->getContext(), 2)); // FPU Rounding Control // 40
regFields.push_back(IntegerType::get(M->getContext(), 2)); // FPU Precision Control // 41
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU Precision Mask // 42
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU Underflow Mask // 43
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU Overflow Mask // 44
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU Zero Divide Mask // 45
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU Denormal Operand Mask // 46
regFields.push_back(IntegerType::getInt1Ty(M->getContext())); // FPU Invalid Operation Mask // 47
// FPU tag word; 8 element array of 2-bit entries
ArrayType *fpu_tag_word = ArrayType::get(Type::getIntNTy(M->getContext(), 8), 8);
regFields.push_back(fpu_tag_word); // 48
regFields.push_back(IntegerType::getInt16Ty(M->getContext())); // Last Instruction Ptr Segment 49
regFields.push_back(IntegerType::getIntNTy(M->getContext(), regWidth)); // Last Instruction Ptr Offset 50
regFields.push_back(IntegerType::getInt16Ty(M->getContext())); // Last Data Ptr Segment 51
regFields.push_back(IntegerType::getIntNTy(M->getContext(), regWidth)); // Last Data Ptr Offset 52
regFields.push_back(IntegerType::get(M->getContext(), 11)); // FPU FOPCODE 53
// vector registers
regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM0 54
regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM1 55
regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM2 56
regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM3 57
regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM4 58
regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM5 59
regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM6 60
regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM7 61
if(getSystemArch(M) == _X86_64_){
regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM8 62
regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM9 63
regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM10 64
regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM11 65
regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM12 66
regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM13 67
regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM14 68
regFields.push_back(IntegerType::getIntNTy(M->getContext(), 128)); // XMM15 69
}
// non-register values in structRegs
regFields.push_back(IntegerType::getIntNTy(M->getContext(), regWidth)); // 70: stack base (biggest value)
regFields.push_back(IntegerType::getIntNTy(M->getContext(), regWidth)); // 71: stack limit (smallest value)
PointerType *ptrToRegs = PointerType::get(regs, 0);
regs->setBody(regFields, true);
vector<Type*> callValArgs;
callValArgs.push_back(Type::getIntNTy(M->getContext(), regWidth));
callValArgs.push_back(ptrToRegs);
FunctionType *callVal = FunctionType::get(
Type::getVoidTy(M->getContext()),
callValArgs,
false);
//GlobalVariable* g_StateBackup =
// new GlobalVariable(*M, regs, false, GlobalValue::ExternalLinkage, 0, "state.backup");
Type *intType = IntegerType::getIntNTy(M->getContext(), regWidth);
g_StateBackup = new GlobalVariable(*M, intType,
false,
GlobalValue::PrivateLinkage,
0,
"state.backup");
g_StateBackup->setThreadLocalMode(GlobalVariable::GeneralDynamicTLSModel);
Constant *zero = ConstantInt::get(intType, 0, false);
g_StateBackup->setInitializer(zero);
g_RegStruct = regs;
g_PRegStruct = ptrToRegs;
archAddCallValue(M);
return;
}
示例14: State
static PointerType *buildTlsTemplate(Module &M, std::vector<VarInfo> *TlsVars) {
std::vector<Type*> FieldBssTypes;
std::vector<Type*> FieldInitTypes;
std::vector<Constant*> FieldInitValues;
PassState State(&M);
for (Module::global_iterator GV = M.global_begin();
GV != M.global_end();
++GV) {
if (GV->isThreadLocal()) {
if (!GV->hasInitializer()) {
// Since this is a whole-program transformation, "extern" TLS
// variables are not allowed at this point.
report_fatal_error(std::string("TLS variable without an initializer: ")
+ GV->getName());
}
if (!GV->getInitializer()->isNullValue()) {
addVarToTlsTemplate(&State, &FieldInitTypes,
&FieldInitValues, GV);
VarInfo Info;
Info.TlsVar = GV;
Info.IsBss = false;
Info.TemplateIndex = FieldInitTypes.size() - 1;
TlsVars->push_back(Info);
}
}
}
// Handle zero-initialized TLS variables in a second pass, because
// these should follow non-zero-initialized TLS variables.
for (Module::global_iterator GV = M.global_begin();
GV != M.global_end();
++GV) {
if (GV->isThreadLocal() && GV->getInitializer()->isNullValue()) {
addVarToTlsTemplate(&State, &FieldBssTypes, NULL, GV);
VarInfo Info;
Info.TlsVar = GV;
Info.IsBss = true;
Info.TemplateIndex = FieldBssTypes.size() - 1;
TlsVars->push_back(Info);
}
}
// Add final alignment padding so that
// (struct tls_struct *) __nacl_read_tp() - 1
// gives the correct, aligned start of the TLS variables given the
// x86-style layout we are using. This requires some more bytes to
// be memset() to zero at runtime. This wastage doesn't seem
// important gives that we're not trying to optimize packing by
// reordering to put similarly-aligned variables together.
padToAlignment(&State, &FieldBssTypes, NULL, State.Alignment);
// We create the TLS template structs as "packed" because we insert
// alignment padding ourselves, and LLVM's implicit insertion of
// padding would interfere with ours. tls_bss_template can start at
// a non-aligned address immediately following the last field in
// tls_init_template.
StructType *InitTemplateType =
StructType::create(M.getContext(), "tls_init_template");
InitTemplateType->setBody(FieldInitTypes, /*isPacked=*/true);
StructType *BssTemplateType =
StructType::create(M.getContext(), "tls_bss_template");
BssTemplateType->setBody(FieldBssTypes, /*isPacked=*/true);
StructType *TemplateType = StructType::create(M.getContext(), "tls_struct");
SmallVector<Type*, 2> TemplateTopFields;
TemplateTopFields.push_back(InitTemplateType);
TemplateTopFields.push_back(BssTemplateType);
TemplateType->setBody(TemplateTopFields, /*isPacked=*/true);
PointerType *TemplatePtrType = PointerType::get(TemplateType, 0);
// We define the following symbols, which are the same as those
// defined by NaCl's original customized binutils linker scripts:
// __tls_template_start
// __tls_template_tdata_end
// __tls_template_end
// We also define __tls_template_alignment, which was not defined by
// the original linker scripts.
const char *StartSymbol = "__tls_template_start";
Constant *TemplateData = ConstantStruct::get(InitTemplateType,
FieldInitValues);
GlobalVariable *TemplateDataVar =
new GlobalVariable(M, InitTemplateType, /*isConstant=*/true,
GlobalValue::InternalLinkage, TemplateData);
setGlobalVariableValue(M, StartSymbol, TemplateDataVar);
TemplateDataVar->setName(StartSymbol);
Constant *TdataEnd = ConstantExpr::getGetElementPtr(
TemplateDataVar,
ConstantInt::get(M.getContext(), APInt(32, 1)));
setGlobalVariableValue(M, "__tls_template_tdata_end", TdataEnd);
Constant *TotalEnd = ConstantExpr::getGetElementPtr(
ConstantExpr::getBitCast(TemplateDataVar, TemplatePtrType),
ConstantInt::get(M.getContext(), APInt(32, 1)));
setGlobalVariableValue(M, "__tls_template_end", TotalEnd);
const char *AlignmentSymbol = "__tls_template_alignment";
Type *i32 = Type::getInt32Ty(M.getContext());
GlobalVariable *AlignmentVar = new GlobalVariable(
M, i32, /*isConstant=*/true,
//.........这里部分代码省略.........