void FindBadConstructsConsumer::CheckVirtualMethod(const CXXMethodDecl* method, bool warn_on_inline_bodies) { if (!method->isVirtual()) return; if (!method->isVirtualAsWritten()) { SourceLocation loc = method->getTypeSpecStartLoc(); if (isa<CXXDestructorDecl>(method)) loc = method->getInnerLocStart(); SourceManager& manager = instance().getSourceManager(); FullSourceLoc full_loc(loc, manager); SourceLocation spelling_loc = manager.getSpellingLoc(loc); diagnostic().Report(full_loc, diag_method_requires_virtual_) << FixItHint::CreateInsertion(spelling_loc, "virtual "); } // Virtual methods should not have inline definitions beyond "{}". This // only matters for header files. if (warn_on_inline_bodies && method->hasBody() && method->hasInlineBody()) { if (CompoundStmt* cs = dyn_cast<CompoundStmt>(method->getBody())) { if (cs->size()) { emitWarning(cs->getLBracLoc(), "virtual methods with non-empty bodies shouldn't be " "declared inline."); } } } }
void MoveCollectionTask::onSubscribeDone(KJob *job) { if (job->error()) { emitWarning(i18n("Failed to subscribe to the folder '%1' on the IMAP server. " "It will disappear on next sync. Use the subscription dialog to overcome that", collection().name())); } changeCommitted(collection()); }
void AddCollectionTask::onSetMetaDataDone(KJob *job) { if (job->error()) { qCWarning(IMAPRESOURCE_LOG) << "Failed to write annotations: " << job->errorString(); emitWarning(i18n("Failed to write some annotations for '%1' on the IMAP server. %2", collection().name(), job->errorText())); } m_pendingJobs--; if (m_pendingJobs == 0) { changeCommitted(m_collection); } }
void AddCollectionTask::onSubscribeDone(KJob *job) { if (job->error() && isSubscriptionEnabled()) { qCWarning(IMAPRESOURCE_LOG) << "Failed to subscribe to the new folder: " << job->errorString(); emitWarning(i18n("Failed to subscribe to the folder '%1' on the IMAP server. " "It will disappear on next sync. Use the subscription dialog to overcome that", m_collection.name())); } const Akonadi::CollectionAnnotationsAttribute *attribute = m_collection.attribute<Akonadi::CollectionAnnotationsAttribute>(); if (!attribute || !serverSupportsAnnotations()) { // we are finished changeCommitted(m_collection); synchronizeCollectionTree(); return; } QMapIterator<QByteArray, QByteArray> i(attribute->annotations()); while (i.hasNext()) { i.next(); KIMAP::SetMetaDataJob *job = new KIMAP::SetMetaDataJob(m_session); if (serverCapabilities().contains(QStringLiteral("METADATA"))) { job->setServerCapability(KIMAP::MetaDataJobBase::Metadata); } else { job->setServerCapability(KIMAP::MetaDataJobBase::Annotatemore); } job->setMailBox(mailBoxForCollection(m_collection)); if (!i.key().startsWith("/shared") && !i.key().startsWith("/private")) { //Support for legacy annotations that don't include the prefix job->addMetaData(QByteArray("/shared") + i.key(), i.value()); } else { job->addMetaData(i.key(), i.value()); } connect(job, &KIMAP::SetMetaDataJob::result, this, &AddCollectionTask::onSetMetaDataDone); m_pendingJobs++; job->start(); } }
void FindBadConstructsConsumer::CheckCtorDtorWeight( SourceLocation record_location, CXXRecordDecl* record) { // We don't handle anonymous structs. If this record doesn't have a // name, it's of the form: // // struct { // ... // } name_; if (record->getIdentifier() == NULL) return; // Count the number of templated base classes as a feature of whether the // destructor can be inlined. int templated_base_classes = 0; for (CXXRecordDecl::base_class_const_iterator it = record->bases_begin(); it != record->bases_end(); ++it) { if (it->getTypeSourceInfo()->getTypeLoc().getTypeLocClass() == TypeLoc::TemplateSpecialization) { ++templated_base_classes; } } // Count the number of trivial and non-trivial member variables. int trivial_member = 0; int non_trivial_member = 0; int templated_non_trivial_member = 0; for (RecordDecl::field_iterator it = record->field_begin(); it != record->field_end(); ++it) { CountType(it->getType().getTypePtr(), &trivial_member, &non_trivial_member, &templated_non_trivial_member); } // Check to see if we need to ban inlined/synthesized constructors. Note // that the cutoffs here are kind of arbitrary. Scores over 10 break. int dtor_score = 0; // Deriving from a templated base class shouldn't be enough to trigger // the ctor warning, but if you do *anything* else, it should. // // TODO(erg): This is motivated by templated base classes that don't have // any data members. Somehow detect when templated base classes have data // members and treat them differently. dtor_score += templated_base_classes * 9; // Instantiating a template is an insta-hit. dtor_score += templated_non_trivial_member * 10; // The fourth normal class member should trigger the warning. dtor_score += non_trivial_member * 3; int ctor_score = dtor_score; // You should be able to have 9 ints before we warn you. ctor_score += trivial_member; if (ctor_score >= 10) { if (!record->hasUserDeclaredConstructor()) { emitWarning(record_location, "Complex class/struct needs an explicit out-of-line " "constructor."); } else { // Iterate across all the constructors in this file and yell if we // find one that tries to be inline. for (CXXRecordDecl::ctor_iterator it = record->ctor_begin(); it != record->ctor_end(); ++it) { if (it->hasInlineBody()) { if (it->isCopyConstructor() && !record->hasUserDeclaredCopyConstructor()) { emitWarning(record_location, "Complex class/struct needs an explicit out-of-line " "copy constructor."); } else { emitWarning(it->getInnerLocStart(), "Complex constructor has an inlined body."); } } } } } // The destructor side is equivalent except that we don't check for // trivial members; 20 ints don't need a destructor. if (dtor_score >= 10 && !record->hasTrivialDestructor()) { if (!record->hasUserDeclaredDestructor()) { emitWarning(record_location, "Complex class/struct needs an explicit out-of-line " "destructor."); } else if (CXXDestructorDecl* dtor = record->getDestructor()) { if (dtor->hasInlineBody()) { emitWarning(dtor->getInnerLocStart(), "Complex destructor has an inline body."); } } } }
int Trick::MemoryManager::add_attr_info( const std::string & user_type_string , ATTRIBUTES * attr , const char * file_name , unsigned int line_num ) { std::string user_type_name ; std::string sub_attr_name ; std::string enum_attr_name ; std::string sub_attr_init_name ; std::string size_func_name ; size_t spos ; std::string::iterator pos ; ATTRIBUTES* sub_attr = NULL ; ENUM_ATTR* enum_attr = NULL ; void (*init_sub_attr)(void) = NULL ; size_t (*size_func)(void) = NULL ; unsigned int ii ; std::set<std::string>::iterator it ; std::map<std::string,std::string>::iterator mit; /** @par Design Details: */ user_type_name = user_type_string ; // Check if the type is a primitive type. If so, we don't need to continue it = primitive_types.find(user_type_string) ; if ( it != primitive_types.end() ) { return 0 ; } // The user type name may start as const Foo<int>::Bar[4]. We need to convert that to Foo_int___Bar // remove const from the typename if it exists spos = user_type_name.find("const ") ; if ( spos != std::string::npos ) { user_type_name.erase( spos , spos + 6) ; } // remove any brackets /* spos = user_type_name.find("[") ; if ( spos != std::string::npos ) { user_type_name.erase( spos ) ; } */ // replace ":<>,*[]" with '_' std::replace( user_type_name.begin(), user_type_name.end(), ':', '_') ; std::replace( user_type_name.begin(), user_type_name.end(), '<', '_') ; std::replace( user_type_name.begin(), user_type_name.end(), '>', '_') ; std::replace( user_type_name.begin(), user_type_name.end(), ',', '_') ; std::replace( user_type_name.begin(), user_type_name.end(), '*', '_') ; std::replace( user_type_name.begin(), user_type_name.end(), '[', '_') ; std::replace( user_type_name.begin(), user_type_name.end(), ']', '_') ; // remove spaces user_type_name.erase(std::remove_if(user_type_name.begin(), user_type_name.end(), (int(*)(int))std::isspace), user_type_name.end()) ; // Attempt to find an io_src_sizeof function for the named user type. size_func_name = "io_src_sizeof_" + user_type_name ; for ( ii = 0 ; ii < dlhandles.size() && size_func == NULL ; ii++ ) { size_func = (size_t (*)(void))dlsym( dlhandles[ii] , size_func_name.c_str()) ; if ( size_func != NULL ) { attr->size = (*size_func)() ; } } if ( size_func == NULL) { std::stringstream message; message << "(" << file_name << ":" << line_num << "): Couldn't find an io_src_sizeof_ function for type " << user_type_string.c_str() << "[" << size_func_name.c_str() << "()]."; emitWarning(message.str()); } // Attempt to find an attributes list for the named user type. sub_attr_name = "attr" + user_type_name ; for ( ii = 0 ; ii < dlhandles.size() && sub_attr == NULL ; ii++ ) { sub_attr = (ATTRIBUTES *)dlsym( dlhandles[ii] , sub_attr_name.c_str()) ; } if (sub_attr != NULL) { // If attributes for the named type were found ... // Set type and attr of the ATTRIBUTES structure that we're populating. attr->type = TRICK_STRUCTURED ; attr->attr = sub_attr; // Attempt to find the initialization function for the attributes that we just found. sub_attr_init_name = "init_attr" + user_type_name + "_c_intf" ; for ( ii = 0 ; ii < dlhandles.size() && init_sub_attr == NULL ; ii++ ) { init_sub_attr = (void (*)(void))dlsym( dlhandles[ii] , sub_attr_init_name.c_str()) ; } if ( init_sub_attr != NULL ) { // If the initialization function was found, (*init_sub_attr)() ; // then call it. } else { std::stringstream message; message << " ATTRIBUTES init routine for type \"" << user_type_name.c_str() << "\" not found."; emitWarning(message.str()); return(1) ; } } else { // The named user type isn't a structure type. Maybe it's an enumeration type. // Check to see whether the user type name is in the enumeration_map. ENUMERATION_MAP::iterator curr_pos = enumeration_map.find( user_type_name); // If it's not in the enumeration map then if (curr_pos == enumeration_map.end()) { // Construct the name of the enumeration attributes. enum_attr_name = "enum" + user_type_name ; // Attempt to find enumeration attributes for the named user type. for ( ii = 0 ; ii < dlhandles.size() && enum_attr == NULL ; ii++ ) { enum_attr = (ENUM_ATTR *)dlsym( dlhandles[ii] , enum_attr_name.c_str()) ; } // If enumeration attributes for the named type were found then if ( enum_attr != NULL ) { // Put them in the enumeration map. enumeration_map[ user_type_name] = enum_attr; // otherwise ... } else { std::stringstream message; message << "ATTRIBUTES for type \"" << user_type_name.c_str() << "\" not found."; emitWarning(message.str()); return(1) ; } } else { enum_attr = curr_pos->second; } // Set the type information in the ATTRIBUTES structure that we are populating. attr->type = TRICK_ENUMERATED ; attr->attr = enum_attr; } return(0) ; }