Beispiel #1
0
void StructTypeDecl::setOpaqueMembers() {
    for (unsigned i=0; i<numMembers(); i++) {
        Decl* D = members[i];
        D->setPublic(false);
        StructTypeDecl* subStruct = dyncast<StructTypeDecl>(D);
        if (subStruct) subStruct->setOpaqueMembers();
    }
}
Beispiel #2
0
void C2Sema::ActOnAttr(Decl* D, const char* name, SourceRange range, Expr* arg) {
#ifdef SEMA_DEBUG
    std::cerr << COL_SEMA << "SEMA: attribute " << name << ANSI_NORMAL"\n";
#endif
    AttrKind kind = Attr::name2kind(name);
    if (kind == ATTR_UNKNOWN) {
        Diag(range.getBegin(), diag::err_attribute_unknown) << name << range;
        return;
    }
    const AttrInfo& ai = Attr::getInfo(kind);
    // check if allowed for type of Decl
    if (isa<TypeDecl>(D) && !ai.isAllowedInType()) {
        Diag(range.getBegin(), diag::err_attribute_invalid_decl) << name << 0 << range;
        return;
    }
    if (isa<FunctionDecl>(D) && !ai.isAllowedInFunction()) {
        Diag(range.getBegin(), diag::err_attribute_invalid_decl) << name << 1 << range;
        return;
    }
    if (isa<VarDecl>(D) && !ai.isAllowedInVar()) {
        Diag(range.getBegin(), diag::err_attribute_invalid_decl) << name << 2 << range;
        return;
    }

    // check if it requires an argument or has argument while not needing one
    if (arg) {
        if (!ai.requiresArgument) {
            Diag(range.getBegin(), diag::err_attribute_wrong_number_arguments) << name << 0 << range;
            return;
        }
    } else {
        if (ai.requiresArgument) {
            Diag(range.getBegin(), diag::err_attribute_wrong_number_arguments) << name << 1 << range;
            return;
        }
    }

    // check for duplicates
    if (ast.hasAttribute(D, kind)) {
        Diag(range.getBegin(), diag::warn_duplicate_attribute_exact) << name << range;
        return;
    }

    D->setHasAttributes();
    ast.addAttribute(D, new Attr(kind, range, arg));

    // Fixup opaque structs; members are not public!
    if (kind == ATTR_OPAQUE && isa<StructTypeDecl>(D)) {
        StructTypeDecl* S = cast<StructTypeDecl>(D);
        S->setOpaqueMembers();
    }
}
Beispiel #3
0
Decl* StructTypeDecl::find(const char* name_) const {
    // normal members
    for (unsigned i=0; i<numMembers(); i++) {
        Decl* D = members[i];
        if (strcmp(D->getName(), name_) == 0) return D;
        if (D->hasEmptyName()) {      // empty string
            assert(isa<StructTypeDecl>(D));
            StructTypeDecl* sub = cast<StructTypeDecl>(D);
            D = sub->find(name_);
            if (D) return D;
        }
    }

    return findFunction(name_);
}
Beispiel #4
0
unsigned ComponentAnalyser::analyse(bool print1, bool print2, bool print3, bool printLib) {
    unsigned errors = 0;
    const size_t count = analysers.size();

    for (unsigned i=0; i<count; i++) {
        analysers[i]->addImports();
    }

    for (unsigned i=0; i<count; i++) {
        analysers[i]->resolveTypes();
    }
    if (Diags.hasErrorOccurred()) return 1;

    for (unsigned i=0; i<count; i++) {
        errors += analysers[i]->resolveTypeCanonicals();
    }
    if (errors) return errors;

    for (unsigned i=0; i<count; i++) {
        errors += analysers[i]->resolveStructMembers();
    }
    if (print1) printASTs(printLib);
    if (errors) return errors;

    for (unsigned i=0; i<count; i++) {
        errors += analysers[i]->resolveVars();
    }
    if (errors) return errors;

    for (unsigned i=0; i<count; i++) {
        errors += analysers[i]->resolveEnumConstants();
    }
    if (errors) return errors;

    IncrementalArrayVals ia_values;
    for (unsigned i=0; i<count; i++) {
        errors += analysers[i]->checkArrayValues(ia_values);
    }
    if (errors) return errors;

    // Set ArrayValues
    for (IncrementalArrayValsIter iter = ia_values.begin(); iter != ia_values.end(); ++iter) {
        VarDecl* D = iter->first;
        unsigned numValues = iter->second.size();
        assert(numValues);
        // NOTE: incremenal array is given InitListExpr in resolveVars()
        Expr* I = D->getInitValue();
        assert(I);
        assert(dyncast<InitListExpr>(I));
        InitListExpr* ILE = cast<InitListExpr>(I);
        Expr** values = (Expr**)context.Allocate(sizeof(Expr*)*numValues);
        memcpy(values, &iter->second[0], sizeof(Expr*)*numValues);
        ILE->setValues(values, numValues);
    }
    ia_values.clear();

    StructFunctionList structFuncs;
    for (unsigned i=0; i<count; i++) {
        errors += analysers[i]->checkFunctionProtos(structFuncs);
    }
    if (errors) return errors;
    // Set StructFunctions
    // NOTE: since these are linked anyways, just use special ASTContext from Builder
    for (StructFunctionListIter iter = structFuncs.begin(); iter != structFuncs.end(); ++iter) {
        StructTypeDecl* S = iter->first;
        const StructFunctionEntries& entries = iter->second;
        unsigned numFuncs = entries.size();
        FunctionDecl** funcs = (FunctionDecl**)context.Allocate(sizeof(FunctionDecl*)*numFuncs);
        memcpy(funcs, &entries[0], sizeof(FunctionDecl*)*numFuncs);
        S->setStructFuncs(funcs, numFuncs);
    }

    for (unsigned i=0; i<count; i++) {
        analysers[i]->checkVarInits();
    }
    if (print2) printASTs(printLib);
    if (Diags.hasErrorOccurred()) return 1;

    for (unsigned i=0; i<count; i++) {
        analysers[i]->checkFunctionBodies();
    }
    if (Diags.hasErrorOccurred()) return 1;

    for (unsigned i=0; i<count; i++) {
        analysers[i]->checkDeclsForUsed();
    }

    if (print3) printASTs(printLib);
    return errors;
}