⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 support.c

📁 cg编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
                    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(&params->loc, ERROR_S_PARAM_NAME_TWICE,
                          GetAtomString(atable, params->name));
        } else {
            lSymb = AddSymbol(&params->loc, fScope, params->name,
                              GetTypePointer(&params->loc, &params->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(&params->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(&params->loc, &params->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 + -