本文整理汇总了C++中Type类的典型用法代码示例。如果您正苦于以下问题:C++ Type类的具体用法?C++ Type怎么用?C++ Type使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了Type类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: validate
virtual bool validate(const Type &ref, const Type &row) {
return row.size() == ref.size();
}
示例2: visit
void visit(TypeInfoStructDeclaration *d)
{
//printf("TypeInfoStructDeclaration::toDt() '%s'\n", toChars());
if (global.params.is64bit)
verifyStructSize(Type::typeinfostruct, 17 * Target::ptrsize);
else
verifyStructSize(Type::typeinfostruct, 15 * Target::ptrsize);
dtxoff(pdt, Type::typeinfostruct->toVtblSymbol(), 0); // vtbl for TypeInfo_Struct
dtsize_t(pdt, 0); // monitor
assert(d->tinfo->ty == Tstruct);
TypeStruct *tc = (TypeStruct *)d->tinfo;
StructDeclaration *sd = tc->sym;
if (!sd->members)
return;
/* Put out:
* char[] name;
* void[] init;
* hash_t function(in void*) xtoHash;
* bool function(in void*, in void*) xopEquals;
* int function(in void*, in void*) xopCmp;
* string function(const(void)*) xtoString;
* StructFlags m_flags;
* //xgetMembers;
* xdtor;
* xpostblit;
* uint m_align;
* version (X86_64)
* TypeInfo m_arg1;
* TypeInfo m_arg2;
* xgetRTInfo
*/
const char *name = sd->toPrettyChars();
size_t namelen = strlen(name);
dtsize_t(pdt, namelen);
dtabytes(pdt, 0, namelen + 1, name);
// void[] init;
dtsize_t(pdt, sd->structsize); // init.length
if (sd->zeroInit)
dtsize_t(pdt, 0); // NULL for 0 initialization
else
dtxoff(pdt, sd->toInitializer(), 0); // init.ptr
if (FuncDeclaration *fd = search_toHash(sd))
{
dtxoff(pdt, fd->toSymbol(), 0);
TypeFunction *tf = (TypeFunction *)fd->type;
assert(tf->ty == Tfunction);
/* I'm a little unsure this is the right way to do it. Perhaps a better
* way would to automatically add these attributes to any struct member
* function with the name "toHash".
* So I'm leaving this here as an experiment for the moment.
*/
if (!tf->isnothrow || tf->trust == TRUSTsystem /*|| tf->purity == PUREimpure*/)
warning(fd->loc, "toHash() must be declared as extern (D) size_t toHash() const nothrow @safe, not %s", tf->toChars());
}
else
dtsize_t(pdt, 0);
if (sd->xeq)
dtxoff(pdt, sd->xeq->toSymbol(), 0);
else
dtsize_t(pdt, 0);
if (sd->xcmp)
dtxoff(pdt, sd->xcmp->toSymbol(), 0);
else
dtsize_t(pdt, 0);
if (FuncDeclaration *fd = search_toString(sd))
{
dtxoff(pdt, fd->toSymbol(), 0);
}
else
dtsize_t(pdt, 0);
// StructFlags m_flags;
StructFlags::Type m_flags = 0;
if (tc->hasPointers()) m_flags |= StructFlags::hasPointers;
dtsize_t(pdt, m_flags);
#if 0
// xgetMembers
FuncDeclaration *sgetmembers = sd->findGetMembers();
if (sgetmembers)
dtxoff(pdt, sgetmembers->toSymbol(), 0);
else
dtsize_t(pdt, 0); // xgetMembers
#endif
// xdtor
FuncDeclaration *sdtor = sd->dtor;
if (sdtor)
dtxoff(pdt, sdtor->toSymbol(), 0);
//.........这里部分代码省略.........
示例3: source_name
void source_name(Dsymbol *s)
{
char *name = s->ident->toChars();
TemplateInstance *ti = s->isTemplateInstance();
if (ti)
{
if (!substitute(ti->tempdecl))
{
store(ti->tempdecl);
name = ti->name->toChars();
buf.printf("%d%s", strlen(name), name);
}
buf.writeByte('I');
bool is_var_arg = false;
for (size_t i = 0; i < ti->tiargs->dim; i++)
{
RootObject *o = (RootObject *)(*ti->tiargs)[i];
TemplateParameter *tp = NULL;
TemplateValueParameter *tv = NULL;
TemplateTupleParameter *tt = NULL;
if (!is_var_arg)
{
TemplateDeclaration *td = ti->tempdecl->isTemplateDeclaration();
tp = (*td->parameters)[i];
tv = tp->isTemplateValueParameter();
tt = tp->isTemplateTupleParameter();
}
/*
* <template-arg> ::= <type> # type or template
* ::= <expr-primary> # simple expressions
*/
if (tt)
{
buf.writeByte('I');
is_var_arg = true;
tp = NULL;
}
if (tv)
{
// <expr-primary> ::= L <type> <value number> E # integer literal
if (tv->valType->isintegral())
{
Expression* e = isExpression(o);
assert(e);
buf.writeByte('L');
tv->valType->accept(this);
if (tv->valType->isunsigned())
{
buf.printf("%llu", e->toUInteger());
}
else
{
dinteger_t val = e->toInteger();
if (val < 0)
{
val = -val;
buf.writeByte('n');
}
buf.printf("%lld", val);
}
buf.writeByte('E');
}
else
{
s->error("ICE: C++ %s template value parameter is not supported", tv->valType->toChars());
assert(0);
}
}
else if (!tp || tp->isTemplateTypeParameter())
{
Type *t = isType(o);
assert(t);
t->accept(this);
}
else if (tp->isTemplateAliasParameter())
{
Dsymbol* d = isDsymbol(o);
Expression* e = isExpression(o);
if (!d && !e)
{
s->error("ICE: %s is unsupported parameter for C++ template: (%s)", o->toChars());
assert(0);
}
if (d && d->isFuncDeclaration())
{
bool is_nested = d->toParent() && !d->toParent()->isModule() && ((TypeFunction *)d->isFuncDeclaration()->type)->linkage == LINKcpp;
if (is_nested) buf.writeByte('X');
buf.writeByte('L');
mangle_function(d->isFuncDeclaration());
buf.writeByte('E');
if (is_nested) buf.writeByte('E');
}
else if (e && e->op == TOKvar && ((VarExp*)e)->var->isVarDeclaration())
{
VarDeclaration *vd = ((VarExp*)e)->var->isVarDeclaration();
buf.writeByte('L');
mangle_variable(vd, true);
//.........这里部分代码省略.........
示例4: ComputeValueVTs
/// ComputePHILiveOutRegInfo - Compute LiveOutInfo for a PHI's destination
/// register based on the LiveOutInfo of its operands.
void FunctionLoweringInfo::ComputePHILiveOutRegInfo(const PHINode *PN) {
Type *Ty = PN->getType();
if (!Ty->isIntegerTy() || Ty->isVectorTy())
return;
const TargetLowering *TLI = TM.getSubtargetImpl()->getTargetLowering();
SmallVector<EVT, 1> ValueVTs;
ComputeValueVTs(*TLI, Ty, ValueVTs);
assert(ValueVTs.size() == 1 &&
"PHIs with non-vector integer types should have a single VT.");
EVT IntVT = ValueVTs[0];
if (TLI->getNumRegisters(PN->getContext(), IntVT) != 1)
return;
IntVT = TLI->getTypeToTransformTo(PN->getContext(), IntVT);
unsigned BitWidth = IntVT.getSizeInBits();
unsigned DestReg = ValueMap[PN];
if (!TargetRegisterInfo::isVirtualRegister(DestReg))
return;
LiveOutRegInfo.grow(DestReg);
LiveOutInfo &DestLOI = LiveOutRegInfo[DestReg];
Value *V = PN->getIncomingValue(0);
if (isa<UndefValue>(V) || isa<ConstantExpr>(V)) {
DestLOI.NumSignBits = 1;
APInt Zero(BitWidth, 0);
DestLOI.KnownZero = Zero;
DestLOI.KnownOne = Zero;
return;
}
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
APInt Val = CI->getValue().zextOrTrunc(BitWidth);
DestLOI.NumSignBits = Val.getNumSignBits();
DestLOI.KnownZero = ~Val;
DestLOI.KnownOne = Val;
} else {
assert(ValueMap.count(V) && "V should have been placed in ValueMap when its"
"CopyToReg node was created.");
unsigned SrcReg = ValueMap[V];
if (!TargetRegisterInfo::isVirtualRegister(SrcReg)) {
DestLOI.IsValid = false;
return;
}
const LiveOutInfo *SrcLOI = GetLiveOutRegInfo(SrcReg, BitWidth);
if (!SrcLOI) {
DestLOI.IsValid = false;
return;
}
DestLOI = *SrcLOI;
}
assert(DestLOI.KnownZero.getBitWidth() == BitWidth &&
DestLOI.KnownOne.getBitWidth() == BitWidth &&
"Masks should have the same bit width as the type.");
for (unsigned i = 1, e = PN->getNumIncomingValues(); i != e; ++i) {
Value *V = PN->getIncomingValue(i);
if (isa<UndefValue>(V) || isa<ConstantExpr>(V)) {
DestLOI.NumSignBits = 1;
APInt Zero(BitWidth, 0);
DestLOI.KnownZero = Zero;
DestLOI.KnownOne = Zero;
return;
}
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
APInt Val = CI->getValue().zextOrTrunc(BitWidth);
DestLOI.NumSignBits = std::min(DestLOI.NumSignBits, Val.getNumSignBits());
DestLOI.KnownZero &= ~Val;
DestLOI.KnownOne &= Val;
continue;
}
assert(ValueMap.count(V) && "V should have been placed in ValueMap when "
"its CopyToReg node was created.");
unsigned SrcReg = ValueMap[V];
if (!TargetRegisterInfo::isVirtualRegister(SrcReg)) {
DestLOI.IsValid = false;
return;
}
const LiveOutInfo *SrcLOI = GetLiveOutRegInfo(SrcReg, BitWidth);
if (!SrcLOI) {
DestLOI.IsValid = false;
return;
}
DestLOI.NumSignBits = std::min(DestLOI.NumSignBits, SrcLOI->NumSignBits);
DestLOI.KnownZero &= SrcLOI->KnownZero;
DestLOI.KnownOne &= SrcLOI->KnownOne;
}
}
示例5: DtoFunctionType
llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nesttype, bool ismain)
{
if (Logger::enabled())
Logger::println("DtoFunctionType(%s)", type->toChars());
LOG_SCOPE
// sanity check
assert(type->ty == Tfunction);
TypeFunction* f = (TypeFunction*)type;
TargetABI* abi = (f->linkage == LINKintrinsic ? TargetABI::getIntrinsic() : gABI);
// Tell the ABI we're resolving a new function type
abi->newFunctionType(f);
// Do not modify f->fty yet; this function may be called recursively if any
// of the argument types refer to this type.
IrFuncTy fty;
// llvm idx counter
size_t lidx = 0;
// main needs a little special handling
if (ismain)
{
fty.ret = new IrFuncTyArg(Type::tint32, false);
}
// sane return value
else
{
Type* rt = f->next;
unsigned a = 0;
// sret return
if (abi->returnInArg(f))
{
fty.arg_sret = new IrFuncTyArg(rt, true, StructRet | NoAlias | NoCapture);
rt = Type::tvoid;
lidx++;
}
// sext/zext return
else
{
Type *t = rt;
#if DMDV2
if (f->isref)
t = t->pointerTo();
#endif
if (unsigned se = DtoShouldExtend(t))
a = se;
}
#if DMDV2
fty.ret = new IrFuncTyArg(rt, f->isref, a);
#else
fty.ret = new IrFuncTyArg(rt, false, a);
#endif
}
lidx++;
// member functions
if (thistype)
{
fty.arg_this = new IrFuncTyArg(thistype, thistype->toBasetype()->ty == Tstruct);
lidx++;
}
// and nested functions
else if (nesttype)
{
fty.arg_nest = new IrFuncTyArg(nesttype, false);
lidx++;
}
// vararg functions are special too
if (f->varargs)
{
if (f->linkage == LINKd)
{
// d style with hidden args
// 2 (array) is handled by the frontend
if (f->varargs == 1)
{
// _arguments
fty.arg_arguments = new IrFuncTyArg(Type::typeinfo->type->arrayOf(), false);
lidx++;
// _argptr
fty.arg_argptr = new IrFuncTyArg(Type::tvoid->pointerTo(), false, NoAlias | NoCapture);
lidx++;
}
}
else if (f->linkage == LINKc)
{
fty.c_vararg = true;
}
else
{
type->error(0, "invalid linkage for variadic function");
fatal();
}
}
// if this _Dmain() doesn't have an argument, we force it to have one
//.........这里部分代码省略.........
示例6: Kind
Constraint::Constraint(ConstraintKind Kind, Type First, Type Second,
DeclName Member, ConstraintLocator *locator,
ArrayRef<TypeVariableType *> typeVars)
: Kind(Kind), HasRestriction(false), HasFix(false), IsActive(false),
RememberChoice(false), IsFavored(false), NumTypeVariables(typeVars.size()),
Types { First, Second, Member }, Locator(locator)
{
switch (Kind) {
case ConstraintKind::Bind:
case ConstraintKind::Equal:
case ConstraintKind::BindParam:
case ConstraintKind::Subtype:
case ConstraintKind::Conversion:
case ConstraintKind::ExplicitConversion:
case ConstraintKind::ArgumentConversion:
case ConstraintKind::ArgumentTupleConversion:
case ConstraintKind::OperatorArgumentTupleConversion:
case ConstraintKind::OperatorArgumentConversion:
case ConstraintKind::ConformsTo:
case ConstraintKind::CheckedCast:
case ConstraintKind::SelfObjectOfProtocol:
case ConstraintKind::DynamicTypeOf:
case ConstraintKind::OptionalObject:
assert(!First.isNull());
assert(!Second.isNull());
assert(!Member && "Relational constraint cannot have a member");
break;
case ConstraintKind::ApplicableFunction:
assert(First->is<FunctionType>()
&& "The left-hand side type should be a function type");
assert(!Member && "Relational constraint cannot have a member");
break;
case ConstraintKind::TypeMember:
case ConstraintKind::ValueMember:
case ConstraintKind::UnresolvedValueMember:
assert(Member && "Member constraint has no member");
break;
case ConstraintKind::Archetype:
case ConstraintKind::Class:
case ConstraintKind::BridgedToObjectiveC:
assert(!Member && "Type property cannot have a member");
assert(Second.isNull() && "Type property with second type");
break;
case ConstraintKind::Defaultable:
assert(!First.isNull());
assert(!Second.isNull());
assert(!Member && "Defaultable constraint cannot have a member");
break;
case ConstraintKind::BindOverload:
llvm_unreachable("Wrong constructor for overload binding constraint");
case ConstraintKind::Disjunction:
llvm_unreachable("Disjunction constraints should use create()");
}
std::copy(typeVars.begin(), typeVars.end(), getTypeVariablesBuffer().begin());
}
示例7: halide_type_to_tiramisu_type_str
string halide_type_to_tiramisu_type_str(Type type)
{
if (type.is_uint())
{
if (type.bits() == 8)
{
return "tiramisu::p_uint8";
}
else if (type.bits() == 16)
{
return "tiramisu::p_uint16";
}
else if (type.bits() == 32)
{
return "tiramisu::p_uint32";
}
else
{
return "tiramisu::p_uint64";
}
}
else if (type.is_int())
{
if (type.bits() == 8)
{
return "tiramisu::p_int8";
}
else if (type.bits() == 16)
{
return "tiramisu::p_int16";
}
else if (type.bits() == 32)
{
return "tiramisu::p_int32";
}
else
{
return "tiramisu::p_int64";
}
}
else if (type.is_float())
{
if (type.bits() == 32)
{
return "tiramisu::p_float32";
}
else if (type.bits() == 64)
{
return "tiramisu::p_float64";
}
else
{
tiramisu::error("Floats other than 32 and 64 bits are not suppored in Tiramisu.", true);
}
}
else if (type.is_bool())
{
return "tiramisu::p_boolean";
}
else
{
tiramisu::error("Halide type cannot be translated to Tiramisu type.", true);
}
return "tiramisu::p_none";
}
示例8: dtxoff
void TypeInfoStructDeclaration::toDt(dt_t **pdt)
{
//printf("TypeInfoStructDeclaration::toDt() '%s'\n", toChars());
unsigned offset = Type::typeinfostruct->structsize;
dtxoff(pdt, Type::typeinfostruct->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Struct
dtsize_t(pdt, 0); // monitor
assert(tinfo->ty == Tstruct);
TypeStruct *tc = (TypeStruct *)tinfo;
StructDeclaration *sd = tc->sym;
/* Put out:
* char[] name;
* void[] init;
* hash_t function(in void*) xtoHash;
* bool function(in void*, in void*) xopEquals;
* int function(in void*, in void*) xopCmp;
* string function(const(void)*) xtoString;
* uint m_flags;
* xgetMembers;
* xdtor;
* xpostblit;
* uint m_align;
* version (X86_64)
* TypeInfo m_arg1;
* TypeInfo m_arg2;
*
* name[]
*/
const char *name = sd->toPrettyChars();
size_t namelen = strlen(name);
dtsize_t(pdt, namelen);
//dtabytes(pdt, TYnptr, 0, namelen + 1, name);
dtxoff(pdt, toSymbol(), offset, TYnptr);
offset += namelen + 1;
// void[] init;
dtsize_t(pdt, sd->structsize); // init.length
if (sd->zeroInit)
dtsize_t(pdt, 0); // NULL for 0 initialization
else
dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr
FuncDeclaration *fd;
FuncDeclaration *fdx;
Dsymbol *s;
static TypeFunction *tftohash;
static TypeFunction *tftostring;
if (!tftohash)
{
Scope sc;
/* const hash_t toHash();
*/
tftohash = new TypeFunction(NULL, Type::thash_t, 0, LINKd);
tftohash->mod = MODconst;
tftohash = (TypeFunction *)tftohash->semantic(0, &sc);
tftostring = new TypeFunction(NULL, Type::tchar->invariantOf()->arrayOf(), 0, LINKd);
tftostring = (TypeFunction *)tftostring->semantic(0, &sc);
}
TypeFunction *tfcmpptr;
{
Scope sc;
/* const int opCmp(ref const KeyType s);
*/
Parameters *arguments = new Parameters;
#if STRUCTTHISREF
// arg type is ref const T
Parameter *arg = new Parameter(STCref, tc->constOf(), NULL, NULL);
#else
// arg type is const T*
Parameter *arg = new Parameter(STCin, tc->pointerTo(), NULL, NULL);
#endif
arguments->push(arg);
tfcmpptr = new TypeFunction(arguments, Type::tint32, 0, LINKd);
tfcmpptr->mod = MODconst;
tfcmpptr = (TypeFunction *)tfcmpptr->semantic(0, &sc);
}
s = search_function(sd, Id::tohash);
fdx = s ? s->isFuncDeclaration() : NULL;
if (fdx)
{ fd = fdx->overloadExactMatch(tftohash);
if (fd)
{
dtxoff(pdt, fd->toSymbol(), 0, TYnptr);
TypeFunction *tf = (TypeFunction *)fd->type;
assert(tf->ty == Tfunction);
if (global.params.warnings)
{
//.........这里部分代码省略.........
示例9: Parameter
Expression *createTypeInfoArray(Scope *sc, Expression *exps[], unsigned dim)
{
#if 1
/* Get the corresponding TypeInfo_Tuple and
* point at its elements[].
*/
/* Create the TypeTuple corresponding to the types of args[]
*/
Parameters *args = new Parameters;
args->setDim(dim);
for (size_t i = 0; i < dim; i++)
{ Parameter *arg = new Parameter(STCin, exps[i]->type, NULL, NULL);
args->tdata()[i] = arg;
}
TypeTuple *tup = new TypeTuple(args);
Expression *e = tup->getTypeInfo(sc);
e = e->optimize(WANTvalue);
assert(e->op == TOKsymoff); // should be SymOffExp
#if BREAKABI
/*
* Should just pass a reference to TypeInfo_Tuple instead,
* but that would require existing code to be recompiled.
* Source compatibility can be maintained by computing _arguments[]
* at the start of the called function by offseting into the
* TypeInfo_Tuple reference.
*/
#else
// Advance to elements[] member of TypeInfo_Tuple
SymOffExp *se = (SymOffExp *)e;
se->offset += PTRSIZE + PTRSIZE;
// Set type to TypeInfo[]*
se->type = Type::typeinfo->type->arrayOf()->pointerTo();
// Indirect to get the _arguments[] value
e = new PtrExp(0, se);
e->type = se->type->next;
#endif
return e;
#else
/* Improvements:
* 1) create an array literal instead,
* as it would eliminate the extra dereference of loading the
* static variable.
*/
ArrayInitializer *ai = new ArrayInitializer(0);
VarDeclaration *v;
Type *t;
Expression *e;
OutBuffer buf;
Identifier *id;
char *name;
// Generate identifier for _arguments[]
buf.writestring("_arguments_");
for (int i = 0; i < dim; i++)
{ t = exps[i]->type;
t->toDecoBuffer(&buf);
}
buf.writeByte(0);
id = Lexer::idPool((char *)buf.data);
Module *m = sc->module;
Dsymbol *s = m->symtab->lookup(id);
if (s && s->parent == m)
{ // Use existing one
v = s->isVarDeclaration();
assert(v);
}
else
{ // Generate new one
for (int i = 0; i < dim; i++)
{ t = exps[i]->type;
e = t->getTypeInfo(sc);
ai->addInit(new IntegerExp(i), new ExpInitializer(0, e));
}
t = Type::typeinfo->type->arrayOf();
ai->type = t;
v = new VarDeclaration(0, t, id, ai);
m->members->push(v);
m->symtabInsert(v);
sc = sc->push();
sc->linkage = LINKc;
sc->stc = STCstatic | STCcomdat;
ai->semantic(sc, t);
v->semantic(sc);
v->parent = m;
sc = sc->pop();
}
e = new VarExp(0, v);
e = e->semantic(sc);
return e;
#endif
//.........这里部分代码省略.........
示例10: assert
bool TypeChecker::checkGenericArguments(DeclContext *dc, SourceLoc loc,
SourceLoc noteLoc,
Type owner,
GenericSignature *genericSig,
ArrayRef<Type> genericArgs) {
// Form the set of generic substitutions required
TypeSubstitutionMap substitutions;
auto genericParams = genericSig->getGenericParams();
unsigned count = 0;
// If the type is nested inside a generic function, skip
// substitutions from the outer context.
unsigned start = (genericParams.size() - genericArgs.size());
for (auto gp : genericParams) {
if (count >= start) {
auto gpTy = gp->getCanonicalType()->castTo<GenericTypeParamType>();
substitutions[gpTy] = genericArgs[count - start];
}
count++;
}
// The number of generic type arguments being bound must be equal to the
// total number of generic parameters in the current generic type context.
assert(count - start == genericArgs.size());
// Check each of the requirements.
Module *module = dc->getParentModule();
for (const auto &req : genericSig->getRequirements()) {
Type firstType = req.getFirstType().subst(module, substitutions,
SubstFlags::IgnoreMissing);
if (firstType.isNull()) {
// Another requirement will fail later; just continue.
continue;
}
Type secondType = req.getSecondType();
if (secondType) {
secondType = secondType.subst(module, substitutions,
SubstFlags::IgnoreMissing);
if (secondType.isNull()) {
// Another requirement will fail later; just continue.
continue;
}
}
switch (req.getKind()) {
case RequirementKind::Conformance: {
// Protocol conformance requirements.
auto proto = secondType->castTo<ProtocolType>();
// FIXME: This should track whether this should result in a private
// or non-private dependency.
// FIXME: Do we really need "used" at this point?
// FIXME: Poor location information. How much better can we do here?
if (!conformsToProtocol(firstType, proto->getDecl(), dc,
ConformanceCheckFlags::Used, nullptr, loc)) {
return true;
}
continue;
}
case RequirementKind::Superclass:
// Superclass requirements.
if (!isSubtypeOf(firstType, secondType, dc)) {
// FIXME: Poor source-location information.
diagnose(loc, diag::type_does_not_inherit, owner, firstType,
secondType);
diagnose(noteLoc, diag::type_does_not_inherit_requirement,
req.getFirstType(), req.getSecondType(),
gatherGenericParamBindingsText(
{req.getFirstType(), req.getSecondType()},
genericParams, substitutions));
return true;
}
continue;
case RequirementKind::SameType:
if (!firstType->isEqual(secondType)) {
// FIXME: Better location info for both diagnostics.
diagnose(loc, diag::types_not_equal, owner, firstType, secondType);
diagnose(noteLoc, diag::types_not_equal_requirement,
req.getFirstType(), req.getSecondType(),
gatherGenericParamBindingsText(
{req.getFirstType(), req.getSecondType()},
genericParams, substitutions));
return true;
}
continue;
case RequirementKind::WitnessMarker:
continue;
}
}
//.........这里部分代码省略.........
示例11: assert
/// run - Start execution with the specified function and arguments.
///
GenericValue JIT::runFunction(Function *F,
const std::vector<GenericValue> &ArgValues) {
assert(F && "Function *F was null at entry to run()");
void *FPtr = getPointerToFunction(F);
assert(FPtr && "Pointer to fn's code was null after getPointerToFunction");
FunctionType *FTy = F->getFunctionType();
Type *RetTy = FTy->getReturnType();
assert((FTy->getNumParams() == ArgValues.size() ||
(FTy->isVarArg() && FTy->getNumParams() <= ArgValues.size())) &&
"Wrong number of arguments passed into function!");
assert(FTy->getNumParams() == ArgValues.size() &&
"This doesn't support passing arguments through varargs (yet)!");
// Handle some common cases first. These cases correspond to common `main'
// prototypes.
if (RetTy->isIntegerTy(32) || RetTy->isVoidTy()) {
switch (ArgValues.size()) {
case 3:
if (FTy->getParamType(0)->isIntegerTy(32) &&
FTy->getParamType(1)->isPointerTy() &&
FTy->getParamType(2)->isPointerTy()) {
int (*PF)(int, char **, const char **) =
(int(*)(int, char **, const char **))(intptr_t)FPtr;
// Call the function.
GenericValue rv;
rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
(char **)GVTOP(ArgValues[1]),
(const char **)GVTOP(ArgValues[2])));
return rv;
}
break;
case 2:
if (FTy->getParamType(0)->isIntegerTy(32) &&
FTy->getParamType(1)->isPointerTy()) {
int (*PF)(int, char **) = (int(*)(int, char **))(intptr_t)FPtr;
// Call the function.
GenericValue rv;
rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue(),
(char **)GVTOP(ArgValues[1])));
return rv;
}
break;
case 1:
if (FTy->getParamType(0)->isIntegerTy(32)) {
GenericValue rv;
int (*PF)(int) = (int(*)(int))(intptr_t)FPtr;
rv.IntVal = APInt(32, PF(ArgValues[0].IntVal.getZExtValue()));
return rv;
}
if (FTy->getParamType(0)->isPointerTy()) {
GenericValue rv;
int (*PF)(char *) = (int(*)(char *))(intptr_t)FPtr;
rv.IntVal = APInt(32, PF((char*)GVTOP(ArgValues[0])));
return rv;
}
break;
}
}
// Handle cases where no arguments are passed first.
if (ArgValues.empty()) {
GenericValue rv;
switch (RetTy->getTypeID()) {
default:
llvm_unreachable("Unknown return type for function call!");
case Type::IntegerTyID: {
unsigned BitWidth = cast<IntegerType>(RetTy)->getBitWidth();
if (BitWidth == 1)
rv.IntVal = APInt(BitWidth, ((bool(*)())(intptr_t)FPtr)());
else if (BitWidth <= 8)
rv.IntVal = APInt(BitWidth, ((char(*)())(intptr_t)FPtr)());
else if (BitWidth <= 16)
rv.IntVal = APInt(BitWidth, ((short(*)())(intptr_t)FPtr)());
else if (BitWidth <= 32)
rv.IntVal = APInt(BitWidth, ((int(*)())(intptr_t)FPtr)());
else if (BitWidth <= 64)
rv.IntVal = APInt(BitWidth, ((int64_t(*)())(intptr_t)FPtr)());
else
llvm_unreachable("Integer types > 64 bits not supported");
return rv;
}
case Type::VoidTyID:
rv.IntVal = APInt(32, ((int(*)())(intptr_t)FPtr)());
return rv;
case Type::FloatTyID:
rv.FloatVal = ((float(*)())(intptr_t)FPtr)();
return rv;
case Type::DoubleTyID:
rv.DoubleVal = ((double(*)())(intptr_t)FPtr)();
return rv;
case Type::X86_FP80TyID:
case Type::FP128TyID:
case Type::PPC_FP128TyID:
llvm_unreachable("long double not supported yet");
//.........这里部分代码省略.........
示例12: assert
Value* AMDGPUCodeGenPrepare::expandDivRem32(IRBuilder<> &Builder,
BinaryOperator &I,
Value *Num, Value *Den) const {
Instruction::BinaryOps Opc = I.getOpcode();
assert(Opc == Instruction::URem || Opc == Instruction::UDiv ||
Opc == Instruction::SRem || Opc == Instruction::SDiv);
FastMathFlags FMF;
FMF.setFast();
Builder.setFastMathFlags(FMF);
if (isa<Constant>(Den))
return nullptr; // Keep it for optimization
bool IsDiv = Opc == Instruction::UDiv || Opc == Instruction::SDiv;
bool IsSigned = Opc == Instruction::SRem || Opc == Instruction::SDiv;
Type *Ty = Num->getType();
Type *I32Ty = Builder.getInt32Ty();
Type *F32Ty = Builder.getFloatTy();
if (Ty->getScalarSizeInBits() < 32) {
if (IsSigned) {
Num = Builder.CreateSExt(Num, I32Ty);
Den = Builder.CreateSExt(Den, I32Ty);
} else {
Num = Builder.CreateZExt(Num, I32Ty);
Den = Builder.CreateZExt(Den, I32Ty);
}
}
if (Value *Res = expandDivRem24(Builder, I, Num, Den, IsDiv, IsSigned)) {
Res = Builder.CreateTrunc(Res, Ty);
return Res;
}
ConstantInt *Zero = Builder.getInt32(0);
ConstantInt *One = Builder.getInt32(1);
ConstantInt *MinusOne = Builder.getInt32(~0);
Value *Sign = nullptr;
if (IsSigned) {
ConstantInt *K31 = Builder.getInt32(31);
Value *LHSign = Builder.CreateAShr(Num, K31);
Value *RHSign = Builder.CreateAShr(Den, K31);
// Remainder sign is the same as LHS
Sign = IsDiv ? Builder.CreateXor(LHSign, RHSign) : LHSign;
Num = Builder.CreateAdd(Num, LHSign);
Den = Builder.CreateAdd(Den, RHSign);
Num = Builder.CreateXor(Num, LHSign);
Den = Builder.CreateXor(Den, RHSign);
}
// RCP = URECIP(Den) = 2^32 / Den + e
// e is rounding error.
Value *DEN_F32 = Builder.CreateUIToFP(Den, F32Ty);
Value *RCP_F32 = Builder.CreateFDiv(ConstantFP::get(F32Ty, 1.0), DEN_F32);
Constant *UINT_MAX_PLUS_1 = ConstantFP::get(F32Ty, BitsToFloat(0x4f800000));
Value *RCP_SCALE = Builder.CreateFMul(RCP_F32, UINT_MAX_PLUS_1);
Value *RCP = Builder.CreateFPToUI(RCP_SCALE, I32Ty);
// RCP_LO, RCP_HI = mul(RCP, Den) */
Value *RCP_LO, *RCP_HI;
std::tie(RCP_LO, RCP_HI) = getMul64(Builder, RCP, Den);
// NEG_RCP_LO = -RCP_LO
Value *NEG_RCP_LO = Builder.CreateNeg(RCP_LO);
// ABS_RCP_LO = (RCP_HI == 0 ? NEG_RCP_LO : RCP_LO)
Value *RCP_HI_0_CC = Builder.CreateICmpEQ(RCP_HI, Zero);
Value *ABS_RCP_LO = Builder.CreateSelect(RCP_HI_0_CC, NEG_RCP_LO, RCP_LO);
// Calculate the rounding error from the URECIP instruction
// E = mulhu(ABS_RCP_LO, RCP)
Value *E = getMulHu(Builder, ABS_RCP_LO, RCP);
// RCP_A_E = RCP + E
Value *RCP_A_E = Builder.CreateAdd(RCP, E);
// RCP_S_E = RCP - E
Value *RCP_S_E = Builder.CreateSub(RCP, E);
// Tmp0 = (RCP_HI == 0 ? RCP_A_E : RCP_SUB_E)
Value *Tmp0 = Builder.CreateSelect(RCP_HI_0_CC, RCP_A_E, RCP_S_E);
// Quotient = mulhu(Tmp0, Num)
Value *Quotient = getMulHu(Builder, Tmp0, Num);
// Num_S_Remainder = Quotient * Den
Value *Num_S_Remainder = Builder.CreateMul(Quotient, Den);
// Remainder = Num - Num_S_Remainder
Value *Remainder = Builder.CreateSub(Num, Num_S_Remainder);
// Remainder_GE_Den = (Remainder >= Den ? -1 : 0)
Value *Rem_GE_Den_CC = Builder.CreateICmpUGE(Remainder, Den);
Value *Remainder_GE_Den = Builder.CreateSelect(Rem_GE_Den_CC, MinusOne, Zero);
//.........这里部分代码省略.........
示例13: Builder
// Insert an intrinsic for fast fdiv for safe math situations where we can
// reduce precision. Leave fdiv for situations where the generic node is
// expected to be optimized.
bool AMDGPUCodeGenPrepare::visitFDiv(BinaryOperator &FDiv) {
Type *Ty = FDiv.getType();
if (!Ty->getScalarType()->isFloatTy())
return false;
MDNode *FPMath = FDiv.getMetadata(LLVMContext::MD_fpmath);
if (!FPMath)
return false;
const FPMathOperator *FPOp = cast<const FPMathOperator>(&FDiv);
float ULP = FPOp->getFPAccuracy();
if (ULP < 2.5f)
return false;
FastMathFlags FMF = FPOp->getFastMathFlags();
bool UnsafeDiv = HasUnsafeFPMath || FMF.isFast() ||
FMF.allowReciprocal();
// With UnsafeDiv node will be optimized to just rcp and mul.
if (UnsafeDiv)
return false;
IRBuilder<> Builder(FDiv.getParent(), std::next(FDiv.getIterator()), FPMath);
Builder.setFastMathFlags(FMF);
Builder.SetCurrentDebugLocation(FDiv.getDebugLoc());
Function *Decl = Intrinsic::getDeclaration(Mod, Intrinsic::amdgcn_fdiv_fast);
Value *Num = FDiv.getOperand(0);
Value *Den = FDiv.getOperand(1);
Value *NewFDiv = nullptr;
bool HasDenormals = ST->hasFP32Denormals();
if (VectorType *VT = dyn_cast<VectorType>(Ty)) {
NewFDiv = UndefValue::get(VT);
// FIXME: Doesn't do the right thing for cases where the vector is partially
// constant. This works when the scalarizer pass is run first.
for (unsigned I = 0, E = VT->getNumElements(); I != E; ++I) {
Value *NumEltI = Builder.CreateExtractElement(Num, I);
Value *DenEltI = Builder.CreateExtractElement(Den, I);
Value *NewElt;
if (shouldKeepFDivF32(NumEltI, UnsafeDiv, HasDenormals)) {
NewElt = Builder.CreateFDiv(NumEltI, DenEltI);
} else {
NewElt = Builder.CreateCall(Decl, { NumEltI, DenEltI });
}
NewFDiv = Builder.CreateInsertElement(NewFDiv, NewElt, I);
}
} else {
if (!shouldKeepFDivF32(Num, UnsafeDiv, HasDenormals))
NewFDiv = Builder.CreateCall(Decl, { Num, Den });
}
if (NewFDiv) {
FDiv.replaceAllUsesWith(NewFDiv);
NewFDiv->takeName(&FDiv);
FDiv.eraseFromParent();
}
return !!NewFDiv;
}
示例14: getResultType
void TypeChecker::configureInterfaceType(AbstractFunctionDecl *func) {
Type funcTy;
Type initFuncTy;
auto *sig = func->getGenericSignature();
if (auto fn = dyn_cast<FuncDecl>(func)) {
funcTy = fn->getBodyResultTypeLoc().getType();
if (!funcTy) {
funcTy = TupleType::getEmpty(Context);
} else {
funcTy = getResultType(*this, fn, funcTy);
}
} else if (auto ctor = dyn_cast<ConstructorDecl>(func)) {
auto *dc = ctor->getDeclContext();
funcTy = dc->getSelfInterfaceType();
// Adjust result type for failability.
if (ctor->getFailability() != OTK_None)
funcTy = OptionalType::get(ctor->getFailability(), funcTy);
initFuncTy = funcTy;
} else {
assert(isa<DestructorDecl>(func));
funcTy = TupleType::getEmpty(Context);
}
auto paramLists = func->getParameterLists();
SmallVector<ParameterList*, 4> storedParamLists;
// FIXME: Destructors don't have the '()' pattern in their signature, so
// paste it here.
if (isa<DestructorDecl>(func)) {
assert(paramLists.size() == 1 && "Only the self paramlist");
storedParamLists.push_back(paramLists[0]);
storedParamLists.push_back(ParameterList::createEmpty(Context));
paramLists = storedParamLists;
}
bool hasSelf = func->getDeclContext()->isTypeContext();
for (unsigned i = 0, e = paramLists.size(); i != e; ++i) {
Type argTy;
Type initArgTy;
Type selfTy;
if (i == e-1 && hasSelf) {
selfTy = func->computeInterfaceSelfType(/*isInitializingCtor=*/false);
// Substitute in our own 'self' parameter.
argTy = selfTy;
if (initFuncTy) {
initArgTy = func->computeInterfaceSelfType(/*isInitializingCtor=*/true);
}
} else {
argTy = paramLists[e - i - 1]->getInterfaceType(func);
if (initFuncTy)
initArgTy = argTy;
}
// 'throws' only applies to the innermost function.
AnyFunctionType::ExtInfo info;
if (i == 0 && func->hasThrows())
info = info.withThrows();
assert(!argTy->hasArchetype());
assert(!funcTy->hasArchetype());
if (initFuncTy)
assert(!initFuncTy->hasArchetype());
if (sig && i == e-1) {
funcTy = GenericFunctionType::get(sig, argTy, funcTy, info);
if (initFuncTy)
initFuncTy = GenericFunctionType::get(sig, initArgTy, initFuncTy, info);
} else {
funcTy = FunctionType::get(argTy, funcTy, info);
if (initFuncTy)
initFuncTy = FunctionType::get(initArgTy, initFuncTy, info);
}
}
// Record the interface type.
func->setInterfaceType(funcTy);
if (initFuncTy)
cast<ConstructorDecl>(func)->setInitializerInterfaceType(initFuncTy);
if (func->getGenericParams()) {
// Collect all generic params referenced in parameter types,
// return type or requirements.
SmallPtrSet<GenericTypeParamDecl *, 4> referencedGenericParams;
auto visitorFn = [&referencedGenericParams](Type t) {
if (auto *paramTy = t->getAs<GenericTypeParamType>())
referencedGenericParams.insert(paramTy->getDecl());
};
funcTy->castTo<AnyFunctionType>()->getInput().visit(visitorFn);
//.........这里部分代码省略.........
示例15: while
/// InstCombineStoreToCast - Fold store V, (cast P) -> store (cast V), P
/// when possible. This makes it generally easy to do alias analysis and/or
/// SROA/mem2reg of the memory object.
static Instruction *InstCombineStoreToCast(InstCombiner &IC, StoreInst &SI) {
User *CI = cast<User>(SI.getOperand(1));
Value *CastOp = CI->getOperand(0);
Type *DestPTy = CI->getType()->getPointerElementType();
PointerType *SrcTy = dyn_cast<PointerType>(CastOp->getType());
if (!SrcTy) return nullptr;
Type *SrcPTy = SrcTy->getElementType();
if (!DestPTy->isIntegerTy() && !DestPTy->isPointerTy())
return nullptr;
/// NewGEPIndices - If SrcPTy is an aggregate type, we can emit a "noop gep"
/// to its first element. This allows us to handle things like:
/// store i32 xxx, (bitcast {foo*, float}* %P to i32*)
/// on 32-bit hosts.
SmallVector<Value*, 4> NewGEPIndices;
// If the source is an array, the code below will not succeed. Check to
// see if a trivial 'gep P, 0, 0' will help matters. Only do this for
// constants.
if (SrcPTy->isArrayTy() || SrcPTy->isStructTy()) {
// Index through pointer.
Constant *Zero = Constant::getNullValue(Type::getInt32Ty(SI.getContext()));
NewGEPIndices.push_back(Zero);
while (1) {
if (StructType *STy = dyn_cast<StructType>(SrcPTy)) {
if (!STy->getNumElements()) /* Struct can be empty {} */
break;
NewGEPIndices.push_back(Zero);
SrcPTy = STy->getElementType(0);
} else if (ArrayType *ATy = dyn_cast<ArrayType>(SrcPTy)) {
NewGEPIndices.push_back(Zero);
SrcPTy = ATy->getElementType();
} else {
break;
}
}
SrcTy = PointerType::get(SrcPTy, SrcTy->getAddressSpace());
}
if (!SrcPTy->isIntegerTy() && !SrcPTy->isPointerTy())
return nullptr;
// If the pointers point into different address spaces don't do the
// transformation.
if (SrcTy->getAddressSpace() != CI->getType()->getPointerAddressSpace())
return nullptr;
// If the pointers point to values of different sizes don't do the
// transformation.
if (!IC.getDataLayout() ||
IC.getDataLayout()->getTypeSizeInBits(SrcPTy) !=
IC.getDataLayout()->getTypeSizeInBits(DestPTy))
return nullptr;
// If the pointers point to pointers to different address spaces don't do the
// transformation. It is not safe to introduce an addrspacecast instruction in
// this case since, depending on the target, addrspacecast may not be a no-op
// cast.
if (SrcPTy->isPointerTy() && DestPTy->isPointerTy() &&
SrcPTy->getPointerAddressSpace() != DestPTy->getPointerAddressSpace())
return nullptr;
// Okay, we are casting from one integer or pointer type to another of
// the same size. Instead of casting the pointer before
// the store, cast the value to be stored.
Value *NewCast;
Instruction::CastOps opcode = Instruction::BitCast;
Type* CastSrcTy = DestPTy;
Type* CastDstTy = SrcPTy;
if (CastDstTy->isPointerTy()) {
if (CastSrcTy->isIntegerTy())
opcode = Instruction::IntToPtr;
} else if (CastDstTy->isIntegerTy()) {
if (CastSrcTy->isPointerTy())
opcode = Instruction::PtrToInt;
}
// SIOp0 is a pointer to aggregate and this is a store to the first field,
// emit a GEP to index into its first field.
if (!NewGEPIndices.empty())
CastOp = IC.Builder->CreateInBoundsGEP(CastOp, NewGEPIndices);
Value *SIOp0 = SI.getOperand(0);
NewCast = IC.Builder->CreateCast(opcode, SIOp0, CastDstTy,
SIOp0->getName()+".c");
SI.setOperand(0, NewCast);
SI.setOperand(1, CastOp);
return &SI;
}