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(); } }
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(); } }
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_); }
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; }