📄 support.c
字号:
int SetTypePacked(SourceLoc *loc, dtype *fType)
{
if (fType) {
if (fType->type.properties & TYPE_MISC_PACKED_KW) {
SemanticError(loc, ERROR___REPEATED_TYPE_ATTRIB);
return 0;
}
fType->type.properties |= TYPE_MISC_PACKED | TYPE_MISC_PACKED_KW;
return 1;
}
return 0;
} // SetTypePacked
/*
* SetStorageClass() - Set the storage class of a type. Issue an error if it's already set to
* a conflicting value.
*
* Returns: TRUE if O.K.
*
*/
int SetStorageClass(SourceLoc *loc, dtype *fType, int storage)
{
fType->type.properties;
if (fType->storageClass == SC_UNKNOWN) {
fType->storageClass = (StorageClass) storage;
} else {
if (fType->storageClass == (StorageClass) storage) {
SemanticError(loc, ERROR___STORAGE_SPECIFIED_TWICE);
return 0;
} else {
SemanticError(loc, ERROR___CONFLICTING_STORAGE);
return 0;
}
}
return 1;
} // SetStorageClass
/********************************** Parser Semantic Rules: ***********************************/
/*
* Initializer() - Create an EXPR_LIST_OP node with an expression argument.
*
*/
expr *Initializer(SourceLoc *loc, expr *fExpr)
{
expr *lExpr;
lExpr = (expr *) NewBinopNode(EXPR_LIST_OP, fExpr, NULL);
return lExpr;
} // Initilaizer
/*
* InitializerList() - Add an expression to a list of expressions. Either can be NULL.
*
* Assumes that the nodes on list are EXPR_LIST_OP binary nodes.
*
*/
expr *InitializerList(SourceLoc *loc, expr *list, expr *last)
{
expr *lExpr;
if (list) {
if (last) {
lExpr = list;
while (lExpr->bin.right)
lExpr = lExpr->bin.right;
lExpr->bin.right = last;
}
return list;
} else {
return last;
}
} // InitializerList
/*
* ArgumentList() - Add an actual argument to a list of parameters.
*
*/
expr *ArgumentList(SourceLoc *loc, expr *flist, expr *fExpr)
{
expr *lExpr, *nExpr;
nExpr = (expr *) NewBinopNode(FUN_ARG_OP, fExpr, NULL);
nExpr->common.type = fExpr->common.type;
nExpr->common.IsLValue = IsLValue(fExpr);
if (GetQualifiers(nExpr->common.type) & TYPE_QUALIFIER_CONST) {
nExpr->common.IsConst = 1;
} else {
nExpr->common.IsConst = 0;
}
if (flist) {
lExpr = flist;
while (lExpr->bin.right)
lExpr = lExpr->bin.right;
lExpr->bin.right = nExpr;
return flist;
} else {
return nExpr;
}
} // ArgumentList
/*
* ExpressionList() - Add an expression to the end of a list of expressions..
*
*/
expr *ExpressionList(SourceLoc *loc, expr *fList, expr *fExpr)
{
expr *lExpr, *nExpr;
nExpr = (expr *) NewBinopNode(EXPR_LIST_OP, fExpr, NULL);
nExpr->common.type = fExpr->common.type;
if (fList) {
lExpr = fList;
while (lExpr->bin.right)
lExpr = lExpr->bin.right;
lExpr->bin.right = nExpr;
return fList;
} else {
return nExpr;
}
} // ExpressionList
/*
* AddDecl() - Add a declaration to a list of declarations. Either can be NULL.
*
*/
decl *AddDecl(decl *first, decl *last)
{
decl *lDecl;
if (first) {
if (last) {
lDecl = first;
while (lDecl->next)
lDecl = lDecl->next;
lDecl->next = last;
}
return first;
} else {
return last;
}
} // AddDecl
/*
* AddStmt() - Add a list of statements to then end of another list. Either can be NULL.
*
*/
stmt *AddStmt(stmt *first, stmt *last)
{
stmt *lStmt;
if (first) {
if (last) {
lStmt = first;
while (lStmt->exprst.next)
lStmt = lStmt->exprst.next;
lStmt->exprst.next = last;
}
return first;
} else {
return last;
}
} // AddStmt
/*
* CheckStatement() - See if this statement is supported by the target profile.
*
*/
stmt *CheckStmt(stmt *fStmt)
{
// Can't do it here. Must wait until we know which functions are being used.
//if (fStmt)
// theHAL->CheckStatement(&fStmt->commonst.loc, fStmt);
return fStmt;
} // CheckStmt
/*
* Function_Definition_Header() - Combine function <declaration_specifiers> and <declarator>.
*
*/
decl *Function_Definition_Header(SourceLoc *loc, decl *fDecl)
{
Symbol *lSymb = fDecl->symb;
Symbol *formals;
int ccount;
int InProgram;
int category, domain, qualifiers;
Type *retType;
if (IsFunction(lSymb)) {
if (fDecl->type.type.properties & TYPE_MISC_ABSTRACT_PARAMS) {
SemanticError(loc, ERROR_S_ABSTRACT_NOT_ALLOWED,
GetAtomString(atable, fDecl->name));
}
if (lSymb->details.fun.statements) {
SemanticError(loc, ERROR_S_FUN_ALREADY_DEFINED,
GetAtomString(atable, fDecl->name));
}
if (Cg->theHAL->entryName == fDecl->name) {
InProgram = 1;
fDecl->type.type.properties |= TYPE_MISC_PROGRAM;
lSymb->details.fun.locals->pid = Cg->theHAL->pid;
} else {
InProgram = 0;
}
retType = lSymb->type->fun.rettype;
ccount = 0;
formals = lSymb->details.fun.params;
while (formals) {
category = GetCategory(formals->type);
domain = GetDomain(formals->type);
qualifiers = GetQualifiers(formals->type);
if (qualifiers & TYPE_QUALIFIER_OUT)
lSymb->details.fun.HasOutParams = 1;
formals = formals->next;
}
#if 000 // Can't warn anymore -- could be writing to a global variable
if (!lSymb->details.fun.HasOutParams && IsVoid(retType)) {
SemanticWarning(loc, WARNING_S_VOID_FUN_HAS_NO_OUT_ARGS,
GetAtomString(atable, fDecl->name));
}
#endif
PushScope(lSymb->details.fun.locals);
} else {
SemanticError(loc, ERROR_S_NOT_A_FUN,
GetAtomString(atable, fDecl->name));
PushScope(NewScope());
}
CurrentScope->funindex = ++NextFunctionIndex;
return fDecl;
} // Function_Definition_Header
/*
* lCheckInitializationData() - Check data in an init_declarator for compatibility
* with variable.
*/
static int lCheckInitializationData(SourceLoc *loc, Type *vType, expr *dExpr, int IsGlobal)
{
int category, base, ii, vlen, subop;
expr *lExpr, *tExpr;
if (!dExpr || !vType)
return 0;
base = GetBase(vType);
category = GetCategory(vType);
switch (category) {
default:
case TYPE_CATEGORY_NONE:
return 0;
case TYPE_CATEGORY_SCALAR:
if (dExpr->common.kind == BINARY_N && dExpr->bin.op == EXPR_LIST_OP) {
lExpr = FoldConstants(dExpr->bin.left);
if (lExpr->common.kind == CONST_N) {
if (ConvertType(lExpr, vType, lExpr->co.type, &tExpr, 1, 0)) {
dExpr->bin.left = tExpr;
return 1;
} else {
SemanticError(loc, ERROR___INVALID_INITIALIZATION);
return 0;
}
} else {
#if 000 // RSG
if (IsGlobal) {
SemanticError(loc, ERROR___NON_CONST_INITIALIZATION);
return 0;
} else {
#endif // RSG
return 1;
#if 000 // RSG
}
#endif // RSG
}
} else {
SemanticError(loc, ERROR___INVALID_INITIALIZATION);
return 0;
}
case TYPE_CATEGORY_ARRAY:
vlen = vType->arr.numels;
if (dExpr->common.kind == BINARY_N && dExpr->bin.op == EXPR_LIST_OP) {
lExpr = dExpr->bin.left;
if (!lExpr) {
SemanticError(loc, ERROR___TOO_LITTLE_DATA);
return 0;
}
if (lExpr->common.kind == BINARY_N && lExpr->bin.op == EXPR_LIST_OP) {
for (ii = 0; ii < vlen; ii++) {
if (lExpr) {
if (lExpr->common.kind == BINARY_N && lExpr->bin.op == EXPR_LIST_OP) {
if (lCheckInitializationData(loc, vType->arr.eltype, lExpr, IsGlobal)) {
/* O.K. */
} else {
return 0;
}
} else {
SemanticError(loc, ERROR___INVALID_INITIALIZATION);
return 0;
}
} else {
SemanticError(loc, ERROR___TOO_LITTLE_DATA);
return 0;
}
lExpr = lExpr->bin.right;
}
if (lExpr) {
SemanticError(loc, ERROR___TOO_MUCH_DATA);
} else {
subop = SUBOP_V(vlen, GetBase(vType));
dExpr->bin.left = (expr *) NewUnopSubNode(VECTOR_V_OP, subop, dExpr->bin.left);
dExpr->bin.left->un.type = GetStandardType(GetBase(vType), vlen, 0);
return 1;
}
} else {
if (ConvertType(lExpr, vType, lExpr->common.type, &tExpr, 0, 0)) {
dExpr->bin.left = tExpr;
return 1;
} else {
SemanticError(loc, ERROR___INCOMPAT_TYPE_INIT);
return 0;
}
}
} else {
SemanticError(loc, ERROR___INVALID_INITIALIZATION);
}
return 0;
case TYPE_CATEGORY_FUNCTION:
case TYPE_CATEGORY_STRUCT:
case TYPE_CATEGORY_CONNECTOR:
SemanticError(loc, ERROR___INVALID_INITIALIZATION);
return 0;
}
} // lCheckInitializationData
/*
* Param_Init_Declarator() - Process a parameter initialization declarator.
*
*/
decl *Param_Init_Declarator(SourceLoc *loc, Scope *fScope, decl *fDecl, expr *fExpr)
{
Type *lType;
if (fDecl) {
lType = &fDecl->type.type;
if (IsVoid(lType)) {
SemanticError(loc, ERROR_S_VOID_TYPE_INVALID,
GetAtomString(atable, fDecl->name));
}
if (GetCategory(lType) == TYPE_CATEGORY_FUNCTION) {
SemanticError(loc, ERROR_S_FUN_TYPE_INVALID,
GetAtomString(atable, fDecl->name));
}
if (fExpr) {
if (GetDomain(lType) != TYPE_DOMAIN_UNIFORM) {
SemanticError(loc, ERROR_S_NON_UNIFORM_PARAM_INIT,
GetAtomString(atable, fDecl->name));
}
if (lCheckInitializationData(loc, lType, fExpr, 0)) {
fDecl->initexpr = fExpr;
}
}
}
return fDecl;
} // Param_Init_Declarator
/*
* Init_Declarator() - Set initial value and/or semantics for this declarator.
*
*/
stmt *Init_Declarator(SourceLoc *loc, Scope *fScope, decl *fDecl, expr *fExpr)
{
int category, len, len2, base;
stmt *lStmt = NULL;
int IsGlobal, IsStatic, IsUniform, IsParam, DontAssign;
Symbol *lSymb;
expr *lExpr;
Type *lType;
if (fDecl) {
lSymb = fDecl->symb;
if (fExpr) {
if (lSymb->kind != VARIABLE_S) {
SemanticError(loc, ERROR_S_INIT_NON_VARIABLE,
GetAtomString(atable, lSymb->name));
} else if (fScope->IsStructScope) {
SemanticError(loc, ERROR_S_INIT_STRUCT_MEMBER,
GetAtomString(atable, lSymb->name));
} else if (lSymb->storageClass == SC_EXTERN) {
SemanticError(loc, ERROR_S_INIT_EXTERN,
GetAtomString(atable, lSymb->name));
} else {
lType = lSymb->type;
IsGlobal = fScope->level <= 1;
IsStatic = lSymb->storageClass == SC_STATIC;
IsUniform = GetDomain(lType) == TYPE_DOMAIN_UNIFORM;
IsParam = lSymb->properties & SYMB_IS_PARAMETER;
if (IsGlobal && !IsStatic) {
DontAssign = 1;
} else if (IsParam) {
DontAssign = 1;
} else {
DontAssign = 0;
}
if (lCheckInitializationData(loc, lType, fExpr, IsGlobal)) {
category = GetCategory(lType);
base = GetBase(lType);
switch (category) {
default:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -