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.");
      }
    }
  }
}
示例#2
0
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());
}
示例#3
0
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);
    }
}
示例#4
0
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) ;
}