📄 support.c
字号:
case TYPE_CATEGORY_NONE:
SemanticError(loc, ERROR___INVALID_INITIALIZATION);
break;
case TYPE_CATEGORY_SCALAR:
assert(fExpr->common.kind == BINARY_N && fExpr->bin.op == EXPR_LIST_OP);
if (DontAssign) {
lSymb->details.var.init = fExpr;
} else {
lExpr = (expr *) NewSymbNode(VARIABLE_OP, lSymb);
lStmt = NewSimpleAssignmentStmt(loc, lExpr, fExpr->bin.left, 1);
}
break;
case TYPE_CATEGORY_ARRAY:
if (IsVector(lType, &len) || IsMatrix(lType, &len, &len2)) {
assert(fExpr->common.kind == BINARY_N && fExpr->bin.op == EXPR_LIST_OP);
if (DontAssign) {
lSymb->details.var.init = fExpr;
} else {
lExpr = (expr *) NewSymbNode(VARIABLE_OP, lSymb);
lStmt = NewSimpleAssignmentStmt(loc, lExpr, fExpr->bin.left, 1);
}
} else {
SemanticError(loc, ERROR___ARRAY2_INIT_NOT_DONE);
}
break;
}
}
}
}
if (lSymb->kind == FUNCTION_S) {
lSymb = lSymb->details.fun.params;
while (lSymb) {
if (lSymb->kind == VARIABLE_S) {
if (lSymb->details.var.semantics)
SemanticWarning(loc, WARNING_S_FORWARD_SEMANTICS_IGNORED,
GetAtomString(atable, lSymb->name));
}
lSymb = lSymb->next;
}
}
}
return lStmt;
} // Init_Declarator
/*
* Declarator() - Process a declarator.
*
*/
decl *Declarator(SourceLoc *loc, decl *fDecl, int semantics)
{
Symbol *lSymb, *params;
Scope *lScope;
Type *lType;
if (CurrentScope->InFormalParameters) {
/*
* Don't add formal parameters to the symbol table until we're
* sure that we're in a function declaration.
*
*/
if (fDecl->type.storageClass != SC_UNKNOWN)
SemanticError(&fDecl->loc, ERROR_S_STORAGE_NOT_ALLOWED,
GetAtomString(atable, fDecl->name));
fDecl->semantics = semantics;
} else {
lSymb = LookUpLocalSymbol(CurrentScope, fDecl->name);
if (!lSymb) {
lType = GetTypePointer(&fDecl->loc, &fDecl->type);
if (IsVoid(lType)) {
SemanticError(&fDecl->loc, ERROR_S_VOID_TYPE_INVALID,
GetAtomString(atable, fDecl->name));
}
if (fDecl->type.type.properties & TYPE_MISC_TYPEDEF) {
lSymb = DefineTypedef(loc, CurrentScope, fDecl->name, lType);
if (semantics)
SemanticError(loc, ERROR_S_SEMANTICS_NON_VARIABLE,
GetAtomString(atable, fDecl->name));
if (fDecl->type.storageClass != SC_UNKNOWN)
SemanticError(&fDecl->loc, ERROR_S_STORAGE_NOT_ALLOWED_TYPEDEF,
GetAtomString(atable, fDecl->name));
} else {
if (GetQualifiers(&fDecl->type.type) & TYPE_QUALIFIER_INOUT) {
SemanticError(&fDecl->loc, ERROR_S_IN_OUT_PARAMS_ONLY,
GetAtomString(atable, fDecl->name));
}
if (GetCategory(&fDecl->type.type) == TYPE_CATEGORY_FUNCTION) {
lScope = NewScope();
params = AddFormalParamDecls(lScope, fDecl->params);
lSymb = DeclareFunc(&fDecl->loc, CurrentScope, NULL, fDecl->name, lType, lScope, params);
if (semantics)
SemanticError(loc, ERROR_S_SEMANTICS_NON_VARIABLE,
GetAtomString(atable, fDecl->name));
} else {
if (fDecl->type.type.properties & TYPE_MISC_INTERNAL) {
SemanticError(&fDecl->loc, ERROR_S_INTERNAL_FOR_FUN,
GetAtomString(atable, fDecl->name));
}
if (fDecl->type.type.properties & TYPE_MISC_INLINE) {
SemanticError(&fDecl->loc, ERROR_S_INLINE_FOR_FUN,
GetAtomString(atable, fDecl->name));
}
if (IsUnsizedArray(lType)) {
SemanticError(&fDecl->loc, ERROR_S_UNSIZED_ARRAY,
GetAtomString(atable, fDecl->name));
}
if (IsCategory(lType, TYPE_CATEGORY_ARRAY) && !IsPacked(lType)) {
if (!Cg->theHAL->GetCapsBit(CAPS_INDEXED_ARRAYS)) {
// XYZZY - This test needs to be moved to later to support multiple profiles
SemanticError(&fDecl->loc, ERROR_S_UNPACKED_ARRAY,
GetAtomString(atable, fDecl->name));
}
}
lSymb = DefineVar(loc, CurrentScope, fDecl->name, lType);
lSymb->storageClass = fDecl->type.storageClass;
if (semantics) {
if (CurrentScope->IsStructScope) {
CurrentScope->HasSemantics = 1;
} else {
if (CurrentScope->level > 1) {
SemanticError(&fDecl->loc, ERROR_S_NO_LOCAL_SEMANTICS,
GetAtomString(atable, fDecl->name));
} else if (fDecl->type.storageClass == SC_STATIC) {
SemanticError(&fDecl->loc, ERROR_S_STATIC_CANT_HAVE_SEMANTICS,
GetAtomString(atable, fDecl->name));
#if 000 // RSG -- Not sure if this is true. Do non-static global variables with semantics have to be declared "uniform"?
} else if (GetDomain(&fDecl->type.type) != TYPE_DOMAIN_UNIFORM) {
SemanticError(&fDecl->loc, ERROR_S_NON_STATIC_SEM_NOT_UNIFORM,
GetAtomString(atable, fDecl->name));
#endif // RSG
}
}
lSymb->details.var.semantics = semantics;
}
if (CurrentScope->level == 1) {
if (fDecl->type.storageClass != SC_STATIC &&
GetDomain(&fDecl->type.type) != TYPE_DOMAIN_VARYING)
{
lSymb->properties |= SYMB_NEEDS_BINDING;
}
}
if (CurrentScope->IsStructScope)
AddParameter(CurrentScope, lSymb);
}
}
} else {
if (GetCategory(&fDecl->type.type) == TYPE_CATEGORY_FUNCTION) {
lType = GetTypePointer(&fDecl->loc, &fDecl->type);
lScope = NewScope();
params = AddFormalParamDecls(lScope, fDecl->params);
lSymb = DeclareFunc(&fDecl->loc, CurrentScope, lSymb, fDecl->name, lType, lScope, params);
lSymb->storageClass = fDecl->type.storageClass;
if (semantics)
SemanticError(loc, ERROR_S_SEMANTICS_NON_VARIABLE,
GetAtomString(atable, fDecl->name));
} else {
if (!IsTypeBase(&fDecl->type.type, TYPE_BASE_UNDEFINED_TYPE)) {
SemanticError(&fDecl->loc, ERROR_S_NAME_ALREADY_DEFINED,
GetAtomString(atable, fDecl->name));
}
}
}
fDecl->symb = lSymb;
}
return fDecl;
} // Declarator
/*
* lInsertDimension() - Insert a dimension below dims levels.
*
*/
static int lInsertDimension(SourceLoc *loc, dtype *fDtype, int dims, int fnumels, int Packed)
{
int lnumels, lproperties;
Type *lType, *elType;
if (dims == 0) {
fDtype->IsDerived = 0;
lnumels = fnumels;
} else {
lType = &fDtype->type;
if (IsArray(lType)) {
lnumels = lType->arr.numels;
lproperties = fDtype->type.arr.properties & TYPE_MISC_MASK;
//lsize = lType->arr.size;
elType = lType->arr.eltype;
fDtype->type = *elType;
if (!lInsertDimension(loc, fDtype, dims - 1, fnumels, Packed))
return 0; // error encountered below
fDtype->type.arr.properties |= lproperties;
} else {
return 0;
}
}
lType = GetTypePointer(loc, fDtype);
SetTypeCategory(loc, 0, fDtype, TYPE_CATEGORY_ARRAY, 1);
fDtype->type.arr.eltype = lType;
fDtype->type.arr.numels = lnumels;
fDtype->numNewDims = dims + 1;
if (Packed) {
fDtype->type.properties |= TYPE_MISC_PACKED;
} else {
fDtype->type.properties &= ~TYPE_MISC_PACKED;
}
fDtype->IsDerived = 1;
return 1;
} // lInsertDimension
/*
* Array_Declarator() - Declare an array of this type.
*
*/
decl *Array_Declarator(SourceLoc *loc, decl *fDecl, int size, int Empty)
{
dtype *lDtype;
Type *lType;
int dims;
lDtype = &fDecl->type;
if (size <= 0 && !Empty) {
SemanticError(loc, ERROR___DIMENSION_LT_1);
size = 1;
}
if (IsVoid(&lDtype->type))
SemanticError(loc, ERROR___ARRAY_OF_VOID);
switch (GetCategory(&lDtype->type)) {
case TYPE_CATEGORY_SCALAR:
lType = lDtype->basetype;
SetTypeCategory(loc, 0, lDtype, TYPE_CATEGORY_ARRAY, 1);
lDtype->type.arr.eltype = lType;
lDtype->type.arr.numels = size;
lDtype->numNewDims = 1;
break;
case TYPE_CATEGORY_ARRAY:
dims = lDtype->numNewDims;
lInsertDimension(loc, lDtype, dims, size, lDtype->type.properties & TYPE_MISC_PACKED_KW);
// if (TotalNumberDimensions > MAX_ARRAY_DIMENSIONS)
// SemanticError(loc, ERROR_D_EXCEEDS_MAX_DIMS, MAX_ARRAY_DIMENSIONS);
break;
case TYPE_CATEGORY_FUNCTION:
SemanticError(loc, ERROR___ARRAY_OF_FUNS);
break;
case TYPE_CATEGORY_STRUCT:
lType = GetTypePointer(loc, lDtype);
NewDType(lDtype, lType, TYPE_CATEGORY_ARRAY);
lDtype->type.co.properties |= lType->co.properties & (TYPE_DOMAIN_MASK | TYPE_QUALIFIER_MASK);
lDtype->type.arr.eltype = lType;
lDtype->type.arr.numels = size;
lDtype->numNewDims = 1;
break;
default:
InternalError(loc, 999, "ArrayDeclarator(): unknown category");
break;
}
lDtype->IsDerived = 1;
return fDecl;
} // Array_Declarator
/*
* AddFormalParamDecls() - Add a list of formal parameter declarations to a function
* definition's scope.
*/
Symbol *AddFormalParamDecls(Scope *fScope, decl *params)
{
Symbol *lSymb, *first = NULL, *last;
Type *lType;
while (params) {
lSymb = LookUpLocalSymbol(fScope, params->name);
if (lSymb) {
SemanticError(¶ms->loc, ERROR_S_PARAM_NAME_TWICE,
GetAtomString(atable, params->name));
} else {
lSymb = AddSymbol(¶ms->loc, fScope, params->name,
GetTypePointer(¶ms->loc, ¶ms->type), VARIABLE_S);
lSymb->properties |= SYMB_IS_PARAMETER;
lSymb->details.var.semantics = params->semantics;
lSymb->details.var.init = params->initexpr;
if (first) {
last->next = lSymb;
} else {
first = lSymb;
}
last = lSymb;
lType = lSymb->type;
if (IsCategory(lType, TYPE_CATEGORY_ARRAY) && !IsPacked(lType)) {
if (!Cg->theHAL->GetCapsBit(CAPS_INDEXED_ARRAYS)) {
SemanticError(¶ms->loc, ERROR_S_UNPACKED_ARRAY,
GetAtomString(atable, params->name));
}
}
}
params = params->next;
}
return first;
} // AddFormalParamDecls
/*
* SetFunTypeParams() - Build a list of types and set this function type's abstract parameter types.
*
*/
decl *SetFunTypeParams(Scope *fScope, decl *func, decl *params, decl *actuals)
{
TypeList *formals, *prev, *lType;
fScope->InFormalParameters--;
formals = prev = NULL;
while (params) {
lType = (TypeList *) malloc(sizeof(TypeList));
lType->next = NULL;
lType->type = GetTypePointer(¶ms->loc, ¶ms->type);
if (formals) {
prev->next = lType;
} else {
formals = lType;
}
prev = lType;
params = params->next;
}
if (func && IsCategory(&func->type.type, TYPE_CATEGORY_FUNCTION)) {
func->type.type.fun.paramtypes = formals;
func->type.IsDerived = 1;
}
if (actuals) {
func->params = actuals;
} else {
if (!CurrentScope->HasVoidParameter)
func->type.type.properties |= TYPE_MISC_ABSTRACT_PARAMS;
}
return func;
} // SetFunTypeParams
/*
* FunctionDeclHeader()
*
*/
decl *FunctionDeclHeader(SourceLoc *loc, Scope *fScope, decl *func)
{
Type *rtnType = GetTypePointer(Cg->tokenLoc, &func->type);
if (IsUnsizedArray(rtnType))
SemanticError(loc, ERROR_S_UNSIZED_ARRAY, GetAtomString(atable, func->name));
NewDType(&func->type, NULL, TYPE_CATEGORY_FUNCTION);
CurrentScope->InFormalParameters++;
func->type.type.properties |= rtnType->properties & (TYPE_MISC_INLINE | TYPE_MISC_INTERNAL);
rtnType->properties &= ~(TYPE_MISC_INLINE | TYPE_MISC_INTERNAL);
func->type.type.fun.paramtypes = NULL;
func->type.type.fun.rettype = rtnType;
func->type.IsDerived = 1;
return func;
} // FunctionDeclHeader
/*
* StructHeader() - Process a struct header.
*
*/
Type *StructHeader(SourceLoc *loc, Scope *fScope, int cType, int tag)
{
Symbol *lSymb;
Type *lType;
if (tag) {
lSymb = LookUpTag(fScope, tag);
if (!lSymb) {
lSymb = AddTag(loc, fScope, tag, TYPE_CATEGORY_STRUCT);
lSymb->type->str.tag = tag;
lSymb->type->str.semantics = cType;
lSymb->type->str.variety = CID_NONE_ID;
}
lType = lSymb->type;
if (!IsCategory(lType, TYPE_CATEGORY_STRUCT)) {
SemanticError(loc, ERROR_S_TAG_IS_NOT_A_STRUCT, GetAtomString(atable, tag));
lType = UndefinedType;
}
} else {
lType = NewType(TYPE_CATEGORY_STRUCT, 0);
}
return lType;
} // StructOrConnectorHeader
/*
* DefineVar() - Define a new variable in the current scope.
*
*/
Symbol *DefineVar(SourceLoc *loc, Scope *fScope, int atom, Type *fType)
{
Symbol *lSymb;
lSymb = AddSymbol(loc, fScope, atom, fType, VARIABLE_S);
return lSymb;
} // DefineVar
/*
* DefineTypedef() - Define a new type name in the current scope.
*
*/
Symbol *DefineTypedef(SourceLoc *loc, Scope *fScope, int atom, Type *fType)
{
return AddSymbol(loc, fScope, atom, fType, TYPEDEF_S);
} // DefineTypedef
/*
* DeclareFunc() - Declare an identifier as a function in the scope fScope. If it's already
* in the symbol table check the overloading rules to make sure that it either
* A) matches a previous declaration exactly, or B) is unambiguously resolvable.
*/
Symbol *DeclareFunc(SourceLoc *loc, Scope *fScope, Symbol *fSymb, int atom, Type *fType,
Scope *locals, Symbol *params)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -