예제 #1
0
// Note: Callgrind sometimes gives different IDs for same file
// (when references to same source file come from different ELF objects)
TraceFile* CachegrindLoader::compressedFile(const QString& name)
{
    if ((name[0] != '(') || !name[1].isDigit()) return _data->file(checkUnknown(name));

    // compressed format using _fileVector
    int p = name.indexOf(')');
    if (p<2) {
        error(QStringLiteral("Invalid compressed file ('%1')").arg(name));
        return 0;
    }
    int index = name.midRef(1, p-1).toUInt();
    TraceFile* f = 0;
    p++;
    while((name.length()>p) && name.at(p).isSpace()) p++;
    if (name.length()>p) {
        if (_fileVector.size() <= index) {
            int newSize = index * 2;
#if TRACE_LOADER
            qDebug() << " CachegrindLoader::fileVector enlarged to "
                     << newSize;
#endif
            _fileVector.resize(newSize);
        }

        QString realName = checkUnknown(name.mid(p));
        f = (TraceFile*) _fileVector.at(index);
        if (f && (f->name() != realName)) {
            error(QStringLiteral("Redefinition of compressed file index %1 (was '%2') to %3")
                  .arg(index).arg(f->name()).arg(realName));
        }

        f = _data->file(realName);
        _fileVector.replace(index, f);
    }
    else {
        if ((_fileVector.size() <= index) ||
            ( (f=(TraceFile*)_fileVector.at(index)) == 0)) {
            error(QStringLiteral("Undefined compressed file index %1").arg(index));
            return 0;
        }
    }

    return f;
}
예제 #2
0
TraceObject* CachegrindLoader::compressedObject(const QString& name)
{
    if ((name[0] != '(') || !name[1].isDigit()) return _data->object(checkUnknown(name));

    // compressed format using _objectVector
    int p = name.indexOf(')');
    if (p<2) {
        error(QStringLiteral("Invalid compressed ELF object ('%1')").arg(name));
        return 0;
    }
    int index = name.midRef(1, p-1).toInt();
    TraceObject* o = 0;
    p++;
    while((name.length()>p) && name.at(p).isSpace()) p++;
    if (name.length()>p) {
        if (_objectVector.size() <= index) {
            int newSize = index * 2;
#if TRACE_LOADER
            qDebug() << " CachegrindLoader: objectVector enlarged to "
                     << newSize;
#endif
            _objectVector.resize(newSize);
        }

        QString realName = checkUnknown(name.mid(p));
        o = (TraceObject*) _objectVector.at(index);
        if (o && (o->name() != realName)) {
            error(QStringLiteral("Redefinition of compressed ELF object index %1 (was '%2') to %3")
                  .arg(index).arg(o->name()).arg(realName));
        }

        o = _data->object(realName);
        _objectVector.replace(index, o);
    }
    else {
        if ((_objectVector.size() <= index) ||
            ( (o=(TraceObject*)_objectVector.at(index)) == 0)) {
            error(QStringLiteral("Undefined compressed ELF object index %1").arg(index));
            return 0;
        }
    }

    return o;
}
예제 #3
0
void SymbolCheckVisitor::visit(ASTLocalVariable& ast)
{
   ASTVariable& var = ast.getVariable();
   checkUnknown(var.getType());
   checkVarInit(var);

   mpFunction->addLocal(var.getType().clone());

   ScopeVariable* pvariable = ScopeVariable::fromVariable(ast.getVariable());
   mScopeStack.add(pvariable);
}
예제 #4
0
void SymbolCheckVisitor::checkReturn(const ASTFunction& function)
{
   checkUnknown(function.getType());

   if ( !function.getType().isVoid() )
   {
      // ensure that we have a return statement
      bool hasunreachablecode = false;
      if ( !function.getBody().hasReturn(hasunreachablecode) )
      {
         error(E0045, UTEXT("Function ") + function.getName() + UTEXT(" should return a value of type ") + function.getType().toString(), function.getPosition());
      }
      else if ( hasunreachablecode )
      {
         warning(W0003, UTEXT("Unreachable code in ") + function.getName(), function.getPosition());
      }
   }
}
예제 #5
0
void SymbolCheckVisitor::visit(ASTInstanceOf& ast)
{
   mCurrentType.clear();

   checkUnknown(ast.getInstanceType());

   ast.getObject().accept(*this);

   if ( !(mCurrentType.isObject() || mCurrentType.isArray()) )
   {
      error(E0027, UTEXT("Operator instanceof can only be called against objects/arrays."), ast);
   }
   else if ( !mCurrentType.isDerivedFrom(ast.getInstanceType()) )
   {
      error(E0028, UTEXT("Instanceof operator can never be true for ") + mCurrentType.toString() + UTEXT(" and ") + ast.getInstanceType().toString(), ast);
   }

   mCurrentType = ASTType(ASTType::eBoolean);
}
예제 #6
0
// Note: Callgrind gives different IDs even for same function
// when parts of the function are from different source files.
// Thus, it is no error when multiple indexes map to same function.
TraceFunction* CachegrindLoader::compressedFunction(const QString& name,
                                                    TraceFile* file,
                                                    TraceObject* object)
{
    if ((name[0] != '(') || !name[1].isDigit())
        return _data->function(checkUnknown(name), file, object);

    // compressed format using _functionVector
    int p = name.indexOf(')');
    if (p<2) {
        error(QStringLiteral("Invalid compressed function ('%1')").arg(name));
        return 0;
    }


    int index = name.midRef(1, p-1).toUInt();
    TraceFunction* f = 0;
    p++;
    while((name.length()>p) && name.at(p).isSpace()) p++;
    if (name.length()>p) {
        if (_functionVector.size() <= index) {
            int newSize = index * 2;
#if TRACE_LOADER
            qDebug() << " CachegrindLoader::functionVector enlarged to "
                     << newSize;
#endif
            _functionVector.resize(newSize);
        }

        QString realName = checkUnknown(name.mid(p));
        f = (TraceFunction*) _functionVector.at(index);
        if (f && (f->name() != realName)) {
            error(QStringLiteral("Redefinition of compressed function index %1 (was '%2') to %3")
                  .arg(index).arg(f->name()).arg(realName));
        }

        f = _data->function(realName, file, object);
        _functionVector.replace(index, f);

#if TRACE_LOADER
        qDebug() << "compressedFunction: Inserted at Index " << index
                 << "\n  " << f->fullName()
                 << "\n  in " << f->cls()->fullName()
                 << "\n  in " << f->file()->fullName()
                 << "\n  in " << f->object()->fullName();
#endif
    }
    else {
        if ((_functionVector.size() <= index) ||
            ( (f=(TraceFunction*)_functionVector.at(index)) == 0)) {
            error(QStringLiteral("Undefined compressed function index %1").arg(index));
            return 0;
        }

        // there was a check if the used function (returned from KCachegrinds
        // model) has the same object and file as here given to us, but that was wrong:
        // that holds only if we make this assumption on the model...
    }


    return f;
}
예제 #7
0
void SymbolCheckVisitor::visit(ASTNew& ast)
{
   switch ( ast.getKind() )
   {
      case ASTNew::eObject:
         {
            ASTType before = mCurrentType;

            ASTSignature signature;
            ASTNodes& arguments = ast.getArguments();
            for ( int index = 0; index < arguments.size(); index++ )
            {
               ASTExpression& expr = dynamic_cast<ASTExpression&>(arguments[index]);
               expr.accept(*this);

               signature.append(mCurrentType.clone());
            }

            checkUnknown(ast.getType());

            if ( ast.getType().hasObjectClass() )
            {
               const ASTClass& newclass = ast.getType().getObjectClass();
               const ASTFunction* pfunction = newclass.findBestMatch(newclass.getName(), signature, before.getTypeArguments());

               if ( pfunction == NULL )
               {
                  String arguments = UTEXT("(") + signature.toString() + ')';
                  error(E0029, UTEXT("No matching constructor ") + newclass.getFullName() + arguments + UTEXT(" defined."), ast);
               }
               else
               {
                  ast.setConstructor(*pfunction);
               }
            }

            mCurrentType = ast.getType();
         }
         break;

      case ASTNew::eArray:
         {
            ASTNodes& arguments = ast.getArguments();
            for ( int index = 0; index < arguments.size(); index++ )
            {
               ASTExpression& expr = dynamic_cast<ASTExpression&>(arguments[index]);
               expr.accept(*this);

               if ( !mCurrentType.isInt() )
               {
                  error(E0030, UTEXT("Array size expression should be of type int."), ast);
               }
            }

            mCurrentType = ast.getType();
         }
         break;
         
      case ASTNew::eInvalid:
         error(E0001, UTEXT("Invalid compiler state!"), ast);
         break;
   }
}
예제 #8
0
void SymbolCheckVisitor::visit(ASTProperty& ast)
{
   checkUnknown(ast.getType());
}
예제 #9
0
void SymbolCheckVisitor::visit(ASTField& ast)
{
   ASTVariable& var = ast.getVariable();
   checkUnknown(var.getType());
   checkVarInit(var);
}