c2c/Analyser/FunctionAnalyser.cpp
// We have an expression of the type .foo
// Return true to continue analysis, false to exit.
We have an expression of the type .foo
Return true to continue analysis, false to exit.
We have an expression of the type . foo Return true to continue analysis false to exit .
bool FunctionAnalyser::analyseFieldInDesignatedInitExpr(DesignatedInitExpr* D,
                                                        StructTypeDecl* STD,
                                                        QualType Q,
                                                        Fields &fields,
                                                        Expr* value,
                                                        bool &haveDesignators) {
    IdentifierExpr* field = cast<IdentifierExpr>(D->getField());
    int memberIndex = STD->findIndex(field->getName());
    int anonUnionIndex = -1;
    StructTypeDecl *anonUnionDecl;
    if (memberIndex == -1) {
        memberIndex = STD->findIndex("");
        if (memberIndex > -1) {
            anonUnionDecl = dyncast<StructTypeDecl>(STD->getMember((unsigned)memberIndex));
            if (anonUnionDecl) {
                anonUnionIndex = anonUnionDecl->findIndex(field->getName());
            } else {
                memberIndex = -1;
            }
        }
    }
    if (memberIndex == -1) {
        StringBuilder fname(MAX_LEN_VARNAME);
        AnalyserUtils::quotedField(fname, field);
        StringBuilder tname(MAX_LEN_TYPENAME);
        Q.DiagName(tname);
        Diag(D->getLocation(), diag::err_field_designator_unknown) << fname << tname;
        return true;
    }
    Expr* existing = fields[memberIndex];
    if (existing) {
        StringBuilder fname(MAX_LEN_VARNAME);
        AnalyserUtils::quotedField(fname, field);
        Diag(D->getLocation(), diag::err_duplicate_field_init) << fname;
        Diag(existing->getLocation(), diag::note_previous_initializer) << 0 << 0;
        return true;
    }
    fields[memberIndex] = value;
    VarDecl* VD;
    if (anonUnionIndex > -1) {
        field->setDecl(anonUnionDecl, AnalyserUtils::globalDecl2RefKind(anonUnionDecl));
        VD = dyncast<VarDecl>(anonUnionDecl->getMember((unsigned)anonUnionIndex));
    } else {
        VD = dyncast<VarDecl>(STD->getMember((unsigned)memberIndex));
    }
    if (!VD) {
        TODO;
        assert(VD && "TEMP don't support sub-struct member inits");
    }
    field->setDecl(VD, AnalyserUtils::globalDecl2RefKind(VD));
    analyseInitExpr(D->getInitValue(), VD->getType());
    if (anonUnionIndex < 0 && isa<DesignatedInitExpr>(value) != haveDesignators) {
        Diag(value->getLocation(), diag::err_mixed_field_designator);
        return false;
    }
    return true;
}
bool FunctionAnalyser :: analyseFieldInDesignatedInitExpr ( DesignatedInitExpr * D , StructTypeDecl * STD , QualType Q , Fields & fields , Expr * value , bool & haveDesignators ) { IdentifierExpr * field = cast < IdentifierExpr > ( D -> getField ( ) ) ; int memberIndex = STD -> findIndex ( field -> getName ( ) ) ; int anonUnionIndex = -1 ; StructTypeDecl * anonUnionDecl ; if ( memberIndex == -1 ) { memberIndex = STD -> findIndex ( " " ) ; if ( memberIndex > -1 ) { anonUnionDecl = dyncast < StructTypeDecl > ( STD -> getMember ( ( unsigned ) memberIndex ) ) ; if ( anonUnionDecl ) { anonUnionIndex = anonUnionDecl -> findIndex ( field -> getName ( ) ) ; } else { memberIndex = -1 ; } } } if ( memberIndex == -1 ) { StringBuilder fname ( MAX_LEN_VARNAME ) ; AnalyserUtils :: quotedField ( fname , field ) ; StringBuilder tname ( MAX_LEN_TYPENAME ) ; Q . DiagName ( tname ) ; Diag ( D -> getLocation ( ) , diag :: err_field_designator_unknown ) << fname << tname ; return true ; } Expr * existing = fields [ memberIndex ] ; if ( existing ) { StringBuilder fname ( MAX_LEN_VARNAME ) ; AnalyserUtils :: quotedField ( fname , field ) ; Diag ( D -> getLocation ( ) , diag :: err_duplicate_field_init ) << fname ; Diag ( existing -> getLocation ( ) , diag :: note_previous_initializer ) << 0 << 0 ; return true ; } fields [ memberIndex ] = value ; VarDecl * VD ; if ( anonUnionIndex > -1 ) { field -> setDecl ( anonUnionDecl , AnalyserUtils :: globalDecl2RefKind ( anonUnionDecl ) ) ; VD = dyncast < VarDecl > ( anonUnionDecl -> getMember ( ( unsigned ) anonUnionIndex ) ) ; } else { VD = dyncast < VarDecl > ( STD -> getMember ( ( unsigned ) memberIndex ) ) ; } if ( ! VD ) { TODO ; assert ( VD && " " ) ; } field -> setDecl ( VD , AnalyserUtils :: globalDecl2RefKind ( VD ) ) ; analyseInitExpr ( D -> getInitValue ( ) , VD -> getType ( ) ) ; if ( anonUnionIndex < 0 && isa < DesignatedInitExpr > ( value ) != haveDesignators ) { Diag ( value -> getLocation ( ) , diag :: err_mixed_field_designator ) ; return false ; } return true ; }
We have an expression of the type .foo
Return true to continue analysis, false to exit.
We have an expression of the type . foo Return true to continue analysis false to exit .
// TODO can by member of anonymous sub-struct/union // Check for matching a sub field of an anonymous union. // Let's get the anon field if available. // Goto analysis of sub field. // No match of direct value or anon union.