adding const to Atomic::Void type
This commit is contained in:
6
ctx.cpp
6
ctx.cpp
@@ -276,7 +276,7 @@ FunctionEmitContext::FunctionEmitContext(Function *func, Symbol *funSym,
|
|||||||
disableGSWarningCount = 0;
|
disableGSWarningCount = 0;
|
||||||
|
|
||||||
const Type *returnType = function->GetReturnType();
|
const Type *returnType = function->GetReturnType();
|
||||||
if (!returnType || Type::Equal(returnType, AtomicType::Void))
|
if (!returnType || returnType->IsVoidType())
|
||||||
returnValuePtr = NULL;
|
returnValuePtr = NULL;
|
||||||
else {
|
else {
|
||||||
llvm::Type *ftype = returnType->LLVMType(g->ctx);
|
llvm::Type *ftype = returnType->LLVMType(g->ctx);
|
||||||
@@ -1244,7 +1244,7 @@ FunctionEmitContext::GetLabels() {
|
|||||||
void
|
void
|
||||||
FunctionEmitContext::CurrentLanesReturned(Expr *expr, bool doCoherenceCheck) {
|
FunctionEmitContext::CurrentLanesReturned(Expr *expr, bool doCoherenceCheck) {
|
||||||
const Type *returnType = function->GetReturnType();
|
const Type *returnType = function->GetReturnType();
|
||||||
if (Type::Equal(returnType, AtomicType::Void)) {
|
if (returnType->IsVoidType()) {
|
||||||
if (expr != NULL)
|
if (expr != NULL)
|
||||||
Error(expr->pos, "Can't return non-void type \"%s\" from void function.",
|
Error(expr->pos, "Can't return non-void type \"%s\" from void function.",
|
||||||
expr->GetType()->GetString().c_str());
|
expr->GetType()->GetString().c_str());
|
||||||
@@ -3516,7 +3516,7 @@ FunctionEmitContext::ReturnInst() {
|
|||||||
rinst = llvm::ReturnInst::Create(*g->ctx, retVal, bblock);
|
rinst = llvm::ReturnInst::Create(*g->ctx, retVal, bblock);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
AssertPos(currentPos, Type::Equal(function->GetReturnType(), AtomicType::Void));
|
AssertPos(currentPos, function->GetReturnType()->IsVoidType());
|
||||||
rinst = llvm::ReturnInst::Create(*g->ctx, bblock);
|
rinst = llvm::ReturnInst::Create(*g->ctx, bblock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
16
decl.cpp
16
decl.cpp
@@ -80,19 +80,19 @@ lApplyTypeQualifiers(int typeQualifiers, const Type *type, SourcePos pos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((typeQualifiers & TYPEQUAL_UNIFORM) != 0) {
|
if ((typeQualifiers & TYPEQUAL_UNIFORM) != 0) {
|
||||||
if (Type::Equal(type, AtomicType::Void))
|
if (type->IsVoidType())
|
||||||
Error(pos, "\"uniform\" qualifier is illegal with \"void\" type.");
|
Error(pos, "\"uniform\" qualifier is illegal with \"void\" type.");
|
||||||
else
|
else
|
||||||
type = type->GetAsUniformType();
|
type = type->GetAsUniformType();
|
||||||
}
|
}
|
||||||
else if ((typeQualifiers & TYPEQUAL_VARYING) != 0) {
|
else if ((typeQualifiers & TYPEQUAL_VARYING) != 0) {
|
||||||
if (Type::Equal(type, AtomicType::Void))
|
if (type->IsVoidType())
|
||||||
Error(pos, "\"varying\" qualifier is illegal with \"void\" type.");
|
Error(pos, "\"varying\" qualifier is illegal with \"void\" type.");
|
||||||
else
|
else
|
||||||
type = type->GetAsVaryingType();
|
type = type->GetAsVaryingType();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (Type::Equal(type, AtomicType::Void) == false)
|
if (type->IsVoidType() == false)
|
||||||
type = type->GetAsUnboundVariabilityType();
|
type = type->GetAsUnboundVariabilityType();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -392,7 +392,7 @@ Declarator::InitFromType(const Type *baseType, DeclSpecs *ds) {
|
|||||||
type = refType;
|
type = refType;
|
||||||
}
|
}
|
||||||
else if (kind == DK_ARRAY) {
|
else if (kind == DK_ARRAY) {
|
||||||
if (Type::Equal(baseType, AtomicType::Void)) {
|
if (baseType->IsVoidType()) {
|
||||||
Error(pos, "Arrays of \"void\" type are illegal.");
|
Error(pos, "Arrays of \"void\" type are illegal.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -454,7 +454,7 @@ Declarator::InitFromType(const Type *baseType, DeclSpecs *ds) {
|
|||||||
"function parameter declaration for parameter \"%s\".",
|
"function parameter declaration for parameter \"%s\".",
|
||||||
lGetStorageClassName(d->declSpecs->storageClass),
|
lGetStorageClassName(d->declSpecs->storageClass),
|
||||||
decl->name.c_str());
|
decl->name.c_str());
|
||||||
if (Type::Equal(decl->type, AtomicType::Void)) {
|
if (decl->type->IsVoidType()) {
|
||||||
Error(decl->pos, "Parameter with type \"void\" illegal in function "
|
Error(decl->pos, "Parameter with type \"void\" illegal in function "
|
||||||
"parameter list.");
|
"parameter list.");
|
||||||
decl->type = NULL;
|
decl->type = NULL;
|
||||||
@@ -625,7 +625,7 @@ Declaration::GetVariableDeclarations() const {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Type::Equal(decl->type, AtomicType::Void))
|
if (decl->type->IsVoidType())
|
||||||
Error(decl->pos, "\"void\" type variable illegal in declaration.");
|
Error(decl->pos, "\"void\" type variable illegal in declaration.");
|
||||||
else if (CastType<FunctionType>(decl->type) == NULL) {
|
else if (CastType<FunctionType>(decl->type) == NULL) {
|
||||||
decl->type = decl->type->ResolveUnboundVariability(Variability::Varying);
|
decl->type = decl->type->ResolveUnboundVariability(Variability::Varying);
|
||||||
@@ -689,7 +689,7 @@ GetStructTypesNamesPositions(const std::vector<StructDeclaration *> &sd,
|
|||||||
// FIXME: making this fake little DeclSpecs here is really
|
// FIXME: making this fake little DeclSpecs here is really
|
||||||
// disgusting
|
// disgusting
|
||||||
DeclSpecs ds(type);
|
DeclSpecs ds(type);
|
||||||
if (Type::Equal(type, AtomicType::Void) == false) {
|
if (type->IsVoidType() == false) {
|
||||||
if (type->IsUniformType())
|
if (type->IsUniformType())
|
||||||
ds.typeQualifiers |= TYPEQUAL_UNIFORM;
|
ds.typeQualifiers |= TYPEQUAL_UNIFORM;
|
||||||
else if (type->IsVaryingType())
|
else if (type->IsVaryingType())
|
||||||
@@ -703,7 +703,7 @@ GetStructTypesNamesPositions(const std::vector<StructDeclaration *> &sd,
|
|||||||
Declarator *d = (*sd[i]->declarators)[j];
|
Declarator *d = (*sd[i]->declarators)[j];
|
||||||
d->InitFromDeclSpecs(&ds);
|
d->InitFromDeclSpecs(&ds);
|
||||||
|
|
||||||
if (Type::Equal(d->type, AtomicType::Void))
|
if (d->type->IsVoidType())
|
||||||
Error(d->pos, "\"void\" type illegal for struct member.");
|
Error(d->pos, "\"void\" type illegal for struct member.");
|
||||||
|
|
||||||
elementTypes->push_back(d->type);
|
elementTypes->push_back(d->type);
|
||||||
|
|||||||
21
expr.cpp
21
expr.cpp
@@ -209,14 +209,14 @@ lDoTypeConv(const Type *fromType, const Type *toType, Expr **expr,
|
|||||||
if (Type::Equal(toType, fromType))
|
if (Type::Equal(toType, fromType))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (Type::Equal(fromType, AtomicType::Void)) {
|
if (fromType->IsVoidType()) {
|
||||||
if (!failureOk)
|
if (!failureOk)
|
||||||
Error(pos, "Can't convert from \"void\" to \"%s\" for %s.",
|
Error(pos, "Can't convert from \"void\" to \"%s\" for %s.",
|
||||||
toType->GetString().c_str(), errorMsgBase);
|
toType->GetString().c_str(), errorMsgBase);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Type::Equal(toType, AtomicType::Void)) {
|
if (toType->IsVoidType()) {
|
||||||
if (!failureOk)
|
if (!failureOk)
|
||||||
Error(pos, "Can't convert type \"%s\" to \"void\" for %s.",
|
Error(pos, "Can't convert type \"%s\" to \"void\" for %s.",
|
||||||
fromType->GetString().c_str(), errorMsgBase);
|
fromType->GetString().c_str(), errorMsgBase);
|
||||||
@@ -342,7 +342,8 @@ lDoTypeConv(const Type *fromType, const Type *toType, Expr **expr,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (PointerType::IsVoidPointer(toPointerType)) {
|
else if (PointerType::IsVoidPointer(toPointerType)) {
|
||||||
if (fromPointerType->GetBaseType()->IsConstType()) {
|
if (fromPointerType->GetBaseType()->IsConstType() &&
|
||||||
|
!(toPointerType->GetBaseType()->IsConstType())) {
|
||||||
if (!failureOk)
|
if (!failureOk)
|
||||||
Error(pos, "Can't convert pointer to const \"%s\" to void pointer.",
|
Error(pos, "Can't convert pointer to const \"%s\" to void pointer.",
|
||||||
fromPointerType->GetString().c_str());
|
fromPointerType->GetString().c_str());
|
||||||
@@ -3611,7 +3612,7 @@ FunctionCallExpr::GetValue(FunctionEmitContext *ctx) const {
|
|||||||
|
|
||||||
const FunctionType *ft = lGetFunctionType(func);
|
const FunctionType *ft = lGetFunctionType(func);
|
||||||
AssertPos(pos, ft != NULL);
|
AssertPos(pos, ft != NULL);
|
||||||
bool isVoidFunc = Type::Equal(ft->GetReturnType(), AtomicType::Void);
|
bool isVoidFunc = ft->GetReturnType()->IsVoidType();
|
||||||
|
|
||||||
// Automatically convert function call args to references if needed.
|
// Automatically convert function call args to references if needed.
|
||||||
// FIXME: this should move to the TypeCheck() method... (but the
|
// FIXME: this should move to the TypeCheck() method... (but the
|
||||||
@@ -3898,7 +3899,7 @@ FunctionCallExpr::TypeCheck() {
|
|||||||
|
|
||||||
if (fptrType->IsVaryingType()) {
|
if (fptrType->IsVaryingType()) {
|
||||||
const Type *retType = funcType->GetReturnType();
|
const Type *retType = funcType->GetReturnType();
|
||||||
if (Type::Equal(retType, AtomicType::Void) == false &&
|
if (retType->IsVoidType() == false &&
|
||||||
retType->IsUniformType()) {
|
retType->IsUniformType()) {
|
||||||
Error(pos, "Illegal to call a varying function pointer that "
|
Error(pos, "Illegal to call a varying function pointer that "
|
||||||
"points to a function with a uniform return type \"%s\".",
|
"points to a function with a uniform return type \"%s\".",
|
||||||
@@ -4606,7 +4607,7 @@ IndexExpr::TypeCheck() {
|
|||||||
|
|
||||||
if (!CastType<SequentialType>(baseExprType->GetReferenceTarget())) {
|
if (!CastType<SequentialType>(baseExprType->GetReferenceTarget())) {
|
||||||
if (const PointerType *pt = CastType<PointerType>(baseExprType)) {
|
if (const PointerType *pt = CastType<PointerType>(baseExprType)) {
|
||||||
if (Type::Equal(AtomicType::Void, pt->GetBaseType())) {
|
if (pt->GetBaseType()->IsVoidType()) {
|
||||||
Error(pos, "Illegal to dereference void pointer type \"%s\".",
|
Error(pos, "Illegal to dereference void pointer type \"%s\".",
|
||||||
baseExprType->GetString().c_str());
|
baseExprType->GetString().c_str());
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -6800,7 +6801,7 @@ TypeCastExpr::GetValue(FunctionEmitContext *ctx) const {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Type::Equal(toType, AtomicType::Void)) {
|
if (toType->IsVoidType()) {
|
||||||
// emit the code for the expression in case it has side-effects but
|
// emit the code for the expression in case it has side-effects but
|
||||||
// then we're done.
|
// then we're done.
|
||||||
(void)expr->GetValue(ctx);
|
(void)expr->GetValue(ctx);
|
||||||
@@ -7163,10 +7164,10 @@ TypeCastExpr::TypeCheck() {
|
|||||||
toType = lDeconstifyType(toType);
|
toType = lDeconstifyType(toType);
|
||||||
|
|
||||||
// Anything can be cast to void...
|
// Anything can be cast to void...
|
||||||
if (Type::Equal(toType, AtomicType::Void))
|
if (toType->IsVoidType())
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
if (Type::Equal(fromType, AtomicType::Void) ||
|
if (fromType->IsVoidType() ||
|
||||||
(fromType->IsVaryingType() && toType->IsUniformType())) {
|
(fromType->IsVaryingType() && toType->IsUniformType())) {
|
||||||
Error(pos, "Can't type cast from type \"%s\" to type \"%s\"",
|
Error(pos, "Can't type cast from type \"%s\" to type \"%s\"",
|
||||||
fromType->GetString().c_str(), toType->GetString().c_str());
|
fromType->GetString().c_str(), toType->GetString().c_str());
|
||||||
@@ -7589,7 +7590,7 @@ PtrDerefExpr::TypeCheck() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (const PointerType *pt = CastType<PointerType>(type)) {
|
if (const PointerType *pt = CastType<PointerType>(type)) {
|
||||||
if (Type::Equal(AtomicType::Void, pt->GetBaseType())) {
|
if (pt->GetBaseType()->IsVoidType()) {
|
||||||
Error(pos, "Illegal to dereference void pointer type \"%s\".",
|
Error(pos, "Illegal to dereference void pointer type \"%s\".",
|
||||||
type->GetString().c_str());
|
type->GetString().c_str());
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
2
func.cpp
2
func.cpp
@@ -427,7 +427,7 @@ Function::emitCode(FunctionEmitContext *ctx, llvm::Function *function,
|
|||||||
// issue a warning. Also need to warn if it's the entry block for
|
// issue a warning. Also need to warn if it's the entry block for
|
||||||
// the function (in which case it will not have predeccesors but is
|
// the function (in which case it will not have predeccesors but is
|
||||||
// still reachable.)
|
// still reachable.)
|
||||||
if (Type::Equal(type->GetReturnType(), AtomicType::Void) == false &&
|
if (type->GetReturnType()->IsVoidType() == false &&
|
||||||
(pred_begin(ec.bblock) != pred_end(ec.bblock) || (ec.bblock == entryBBlock)))
|
(pred_begin(ec.bblock) != pred_end(ec.bblock) || (ec.bblock == entryBBlock)))
|
||||||
Warning(sym->pos, "Missing return statement in function returning \"%s\".",
|
Warning(sym->pos, "Missing return statement in function returning \"%s\".",
|
||||||
type->rType->GetString().c_str());
|
type->rType->GetString().c_str());
|
||||||
|
|||||||
@@ -426,7 +426,7 @@ Module::AddGlobalVariable(const std::string &name, const Type *type, Expr *initE
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Type::Equal(type, AtomicType::Void)) {
|
if (type->IsVoidType()) {
|
||||||
Error(pos, "\"void\" type global variable is illegal.");
|
Error(pos, "\"void\" type global variable is illegal.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -818,7 +818,7 @@ Module::AddFunctionDeclaration(const std::string &name,
|
|||||||
"exported function \"%s\"", name.c_str());
|
"exported function \"%s\"", name.c_str());
|
||||||
|
|
||||||
if (functionType->isTask &&
|
if (functionType->isTask &&
|
||||||
Type::Equal(functionType->GetReturnType(), AtomicType::Void) == false)
|
functionType->GetReturnType()->IsVoidType() == false)
|
||||||
Error(pos, "Task-qualified functions must have void return type.");
|
Error(pos, "Task-qualified functions must have void return type.");
|
||||||
|
|
||||||
if (functionType->isExported || functionType->isExternC)
|
if (functionType->isExported || functionType->isExternC)
|
||||||
|
|||||||
8
parse.yy
8
parse.yy
@@ -617,7 +617,7 @@ rate_qualified_type_specifier
|
|||||||
{
|
{
|
||||||
if ($2 == NULL)
|
if ($2 == NULL)
|
||||||
$$ = NULL;
|
$$ = NULL;
|
||||||
else if (Type::Equal($2, AtomicType::Void)) {
|
else if ($2->IsVoidType()) {
|
||||||
Error(@1, "\"uniform\" qualifier is illegal with \"void\" type.");
|
Error(@1, "\"uniform\" qualifier is illegal with \"void\" type.");
|
||||||
$$ = NULL;
|
$$ = NULL;
|
||||||
}
|
}
|
||||||
@@ -628,7 +628,7 @@ rate_qualified_type_specifier
|
|||||||
{
|
{
|
||||||
if ($2 == NULL)
|
if ($2 == NULL)
|
||||||
$$ = NULL;
|
$$ = NULL;
|
||||||
else if (Type::Equal($2, AtomicType::Void)) {
|
else if ($2->IsVoidType()) {
|
||||||
Error(@1, "\"varying\" qualifier is illegal with \"void\" type.");
|
Error(@1, "\"varying\" qualifier is illegal with \"void\" type.");
|
||||||
$$ = NULL;
|
$$ = NULL;
|
||||||
}
|
}
|
||||||
@@ -1081,7 +1081,7 @@ specifier_qualifier_list
|
|||||||
{
|
{
|
||||||
if ($2 != NULL) {
|
if ($2 != NULL) {
|
||||||
if ($1 == TYPEQUAL_UNIFORM) {
|
if ($1 == TYPEQUAL_UNIFORM) {
|
||||||
if (Type::Equal($2, AtomicType::Void)) {
|
if ($2->IsVoidType()) {
|
||||||
Error(@1, "\"uniform\" qualifier is illegal with \"void\" type.");
|
Error(@1, "\"uniform\" qualifier is illegal with \"void\" type.");
|
||||||
$$ = NULL;
|
$$ = NULL;
|
||||||
}
|
}
|
||||||
@@ -1089,7 +1089,7 @@ specifier_qualifier_list
|
|||||||
$$ = $2->GetAsUniformType();
|
$$ = $2->GetAsUniformType();
|
||||||
}
|
}
|
||||||
else if ($1 == TYPEQUAL_VARYING) {
|
else if ($1 == TYPEQUAL_VARYING) {
|
||||||
if (Type::Equal($2, AtomicType::Void)) {
|
if ($2->IsVoidType()) {
|
||||||
Error(@1, "\"varying\" qualifier is illegal with \"void\" type.");
|
Error(@1, "\"varying\" qualifier is illegal with \"void\" type.");
|
||||||
$$ = NULL;
|
$$ = NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
14
type.cpp
14
type.cpp
@@ -228,7 +228,7 @@ Type::IsReferenceType() const {
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
Type::IsVoidType() const {
|
Type::IsVoidType() const {
|
||||||
return this == AtomicType::Void;
|
return EqualIgnoringConst(this, AtomicType::Void);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -290,7 +290,7 @@ AtomicType::GetAsUnsignedType() const {
|
|||||||
|
|
||||||
const AtomicType *
|
const AtomicType *
|
||||||
AtomicType::GetAsConstType() const {
|
AtomicType::GetAsConstType() const {
|
||||||
if (basicType == TYPE_VOID || isConst == true)
|
if (isConst == true)
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
if (asOtherConstType == NULL) {
|
if (asOtherConstType == NULL) {
|
||||||
@@ -303,7 +303,7 @@ AtomicType::GetAsConstType() const {
|
|||||||
|
|
||||||
const AtomicType *
|
const AtomicType *
|
||||||
AtomicType::GetAsNonConstType() const {
|
AtomicType::GetAsNonConstType() const {
|
||||||
if (basicType == TYPE_VOID || isConst == false)
|
if (isConst == false)
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
if (asOtherConstType == NULL) {
|
if (asOtherConstType == NULL) {
|
||||||
@@ -380,8 +380,8 @@ AtomicType::ResolveUnboundVariability(Variability v) const {
|
|||||||
std::string
|
std::string
|
||||||
AtomicType::GetString() const {
|
AtomicType::GetString() const {
|
||||||
std::string ret;
|
std::string ret;
|
||||||
|
if (isConst) ret += "const ";
|
||||||
if (basicType != TYPE_VOID) {
|
if (basicType != TYPE_VOID) {
|
||||||
if (isConst) ret += "const ";
|
|
||||||
ret += variability.GetString();
|
ret += variability.GetString();
|
||||||
ret += " ";
|
ret += " ";
|
||||||
}
|
}
|
||||||
@@ -1167,7 +1167,7 @@ PointerType::LLVMType(llvm::LLVMContext *ctx) const {
|
|||||||
if (ftype != NULL)
|
if (ftype != NULL)
|
||||||
ptype = llvm::PointerType::get(ftype->LLVMFunctionType(ctx), 0);
|
ptype = llvm::PointerType::get(ftype->LLVMFunctionType(ctx), 0);
|
||||||
else {
|
else {
|
||||||
if (baseType == AtomicType::Void)
|
if (baseType->IsVoidType())
|
||||||
ptype = LLVMTypes::VoidPointerType;
|
ptype = LLVMTypes::VoidPointerType;
|
||||||
else
|
else
|
||||||
ptype = llvm::PointerType::get(baseType->LLVMType(ctx), 0);
|
ptype = llvm::PointerType::get(baseType->LLVMType(ctx), 0);
|
||||||
@@ -1235,7 +1235,7 @@ ArrayType::ArrayType(const Type *c, int a)
|
|||||||
: SequentialType(ARRAY_TYPE), child(c), numElements(a) {
|
: SequentialType(ARRAY_TYPE), child(c), numElements(a) {
|
||||||
// 0 -> unsized array.
|
// 0 -> unsized array.
|
||||||
Assert(numElements >= 0);
|
Assert(numElements >= 0);
|
||||||
Assert(Type::Equal(c, AtomicType::Void) == false);
|
Assert(c->IsVoidType() == false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -3015,7 +3015,7 @@ FunctionType::LLVMFunctionType(llvm::LLVMContext *ctx, bool removeMask) const {
|
|||||||
Assert(m->errorCount > 0);
|
Assert(m->errorCount > 0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
Assert(Type::Equal(paramTypes[i], AtomicType::Void) == false);
|
Assert(paramTypes[i]->IsVoidType() == false);
|
||||||
|
|
||||||
llvm::Type *t = paramTypes[i]->LLVMType(ctx);
|
llvm::Type *t = paramTypes[i]->LLVMType(ctx);
|
||||||
if (t == NULL) {
|
if (t == NULL) {
|
||||||
|
|||||||
Reference in New Issue
Block a user