From e7bf61cfb48e1f71268121db2b351dedf12206c8 Mon Sep 17 00:00:00 2001
From: Wolfgang Beck <wolfgang.beck@nokia.com>
Date: Fri, 29 Jan 2010 15:06:03 +1000
Subject: [PATCH] Add new unit test to check the icheck build.

---
 tests/auto/auto.pro                        |    3 +-
 tests/auto/icheckbuild/ParseManager.cpp    | 1385 ++++++++++++++++++++
 tests/auto/icheckbuild/ParseManager.h      |  304 +++++
 tests/auto/icheckbuild/icheckbuild.pro     |   25 +
 tests/auto/icheckbuild/ichecklib.cpp       |   60 +
 tests/auto/icheckbuild/ichecklib.h         |   20 +
 tests/auto/icheckbuild/ichecklib.pri       |  114 ++
 tests/auto/icheckbuild/ichecklib_global.h  |   17 +
 tests/auto/icheckbuild/tst_icheckbuild.cpp |   49 +
 9 files changed, 1976 insertions(+), 1 deletion(-)
 create mode 100644 tests/auto/icheckbuild/ParseManager.cpp
 create mode 100644 tests/auto/icheckbuild/ParseManager.h
 create mode 100644 tests/auto/icheckbuild/icheckbuild.pro
 create mode 100644 tests/auto/icheckbuild/ichecklib.cpp
 create mode 100644 tests/auto/icheckbuild/ichecklib.h
 create mode 100644 tests/auto/icheckbuild/ichecklib.pri
 create mode 100644 tests/auto/icheckbuild/ichecklib_global.h
 create mode 100644 tests/auto/icheckbuild/tst_icheckbuild.cpp

diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index 413628194b8..fdb18d0f2ce 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -6,7 +6,8 @@ SUBDIRS += \
     fakevim \
 #    profilereader \
     aggregation \
-    changeset
+    changeset \
+	icheckbuild
 
 contains (QT_CONFIG, declarative) {
 SUBDIRS += qml
diff --git a/tests/auto/icheckbuild/ParseManager.cpp b/tests/auto/icheckbuild/ParseManager.cpp
new file mode 100644
index 00000000000..781178b8317
--- /dev/null
+++ b/tests/auto/icheckbuild/ParseManager.cpp
@@ -0,0 +1,1385 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "ParseManager.h"
+#include "cplusplus/CppDocument.h"
+#include "Control.h"
+#include "TranslationUnit.h"
+#include "AST.h"
+#include "Symbols.h"
+#include <QDebug>
+#include "Name.h"
+#include "cpptools/cppmodelmanager.h"
+
+using namespace CppTools;
+using namespace CppTools::Internal;
+
+
+using namespace CPlusPlus;
+
+//<------------------------------------------------------- Compare function for the internal structures
+/**********************************
+Compares function with function
+with return type, function name
+and their arguments and arguments 
+types.
+**********************************/
+bool FUNCTIONITEM::isEqualTo(FUNCTIONITEM *cpfct, bool ignoreName/* = true*/)
+{
+    if(ignoreName)
+        return function->isEqualTo(cpfct->function, true);
+    return function->isEqualTo(cpfct->function);
+}
+
+/*****************************************************************
+Compares two property regarding
+of their function definition, 
+type definition, function arguments 
+and function types.
+
+Q_PROPERTY( ConnectionState state READ state NOTIFY stateChanged);
+******************************************************************/
+bool PROPERTYITEM::isEqualTo(PROPERTYITEM *cpppt)
+{
+    QString thistype = this->trlUnit->spell(this->ast->type_token);
+    QString cppttype = cpppt->trlUnit->spell(cpppt->ast->type_token);
+    
+    if(thistype != cppttype)
+        return false;
+
+    QString thistypename = this->trlUnit->spell(this->ast->type_name_token);
+    QString cppttypename = cpppt->trlUnit->spell(cpppt->ast->type_name_token);
+    if(thistypename != cppttypename)
+        return false;
+
+    if(this->readdefined != cpppt->readdefined)
+        return false;
+    if(this->writedefined != cpppt->writedefined)
+        return false;
+    if(this->resetdefined != cpppt->resetdefined)
+        return false;
+    if(this->notifydefined != cpppt->notifydefined)
+        return false;
+    //check for read function
+    if(this->readdefined){
+        if(!this->readFct || !cpppt->readFct)
+            return false;
+        if(!this->readFct->isEqualTo(cpppt->readFct))
+            return false;
+    }
+    //check for write function
+    if(this->writedefined){
+        if(!this->writeFct || !cpppt->writeFct)
+            return false;
+        if(!this->writeFct->isEqualTo(cpppt->writeFct))
+            return false;
+    }
+    //check for reset function
+    if(this->resetdefined){
+        if(!this->resetFct || !cpppt->resetFct)
+            return false;
+        if(!this->resetFct->isEqualTo(cpppt->resetFct))
+            return false;
+    }
+    //check for notify function
+    if(this->notifydefined){
+        if(!this->notifyFct || !cpppt->notifyFct)
+            return false;
+        if(!this->notifyFct->isEqualTo(cpppt->notifyFct))
+            return false;
+    }
+    return true;
+}
+
+/*****************************************************************
+Compares two enums regarding
+of their values created by the getEnumValueStringList function.
+*****************************************************************/
+bool QENUMITEM::isEqualTo(QENUMITEM *cpenum)
+{
+    if(this->values.count() != cpenum->values.count())
+        return false;
+    foreach(QString str, this->values){
+        if(!cpenum->values.contains(str))
+            return false;
+    }
+    return true;
+}
+
+/*****************************************************************
+Compares two flags regarding
+of their enum definitions and their 
+values created by the getEnumValueStringList function.
+*****************************************************************/
+bool QFLAGITEM::isEqualTo(QFLAGITEM *cpflag)
+{
+    if(this->enumvalues.count() != cpflag->enumvalues.count())
+        return false;
+    foreach(QString str, this->enumvalues){
+        if(!cpflag->enumvalues.contains(str))
+            return false;
+    }
+    return true;
+}
+
+
+
+ParseManager::ParseManager()
+: pCppPreprocessor(0)
+{
+
+}
+
+ParseManager::~ParseManager()
+{
+    if(pCppPreprocessor)
+        delete pCppPreprocessor;
+}
+
+/**************************************
+Function for setting the include
+Paths
+**************************************/
+void ParseManager::setIncludePath(const QStringList &includePath)
+{
+    m_includePaths = includePath;
+}
+
+/**************************************
+public Function that starts the parsing
+all of the files in the sourceFiles 
+string list.
+**************************************/
+void ParseManager::parse(const QStringList &sourceFiles)
+{
+    m_errormsgs.clear();
+    if(pCppPreprocessor){
+        delete pCppPreprocessor;
+        pCppPreprocessor = 0;
+    }
+        
+    if (! sourceFiles.isEmpty()) {
+        m_strHeaderFile = sourceFiles[0];
+        pCppPreprocessor = new CppTools::Internal::CppPreprocessor(QPointer<CPlusPlus::ParseManager>(this));
+        pCppPreprocessor->setIncludePaths(m_includePaths);
+        pCppPreprocessor->setFrameworkPaths(m_frameworkPaths);
+        parse(pCppPreprocessor, sourceFiles);
+    }
+}
+
+/*********************************************
+private function that prepare the filelist
+to parse and starts the parser.
+*********************************************/
+void ParseManager::parse(CppTools::Internal::CppPreprocessor *preproc,
+                            const QStringList &files)
+{
+    if (files.isEmpty())
+        return;
+
+    //check if file is C++ header file
+    QStringList headers;
+    foreach (const QString &file, files) {
+        const QFileInfo fileInfo(file);
+        QString ext = fileInfo.suffix();
+        if (ext.toLower() == "h")
+            headers.append(file);
+    }
+
+    foreach (const QString &file, files) {
+        preproc->snapshot.remove(file);
+    }
+    preproc->setTodo(headers);
+    QString conf = QLatin1String("<configuration>");
+
+    preproc->run(conf);
+    for (int i = 0; i < headers.size(); ++i) {
+        QString fileName = headers.at(i);
+        preproc->run(fileName);
+    }
+}
+
+//This function creates a class list for each class and its base classes in 
+//the header file that needs to be checked.
+//e.g.
+//      Cl1          Cl2
+//     __|__        __|__
+//    |     |      |     |
+//   Cl11  Cl12   Cl21  Cl22
+//
+//==> list[0] = {Cl1, Cl11, Cl12}
+//    list[1] = {Cl2, Cl21, Cl22}
+
+QList<CLASSTREE*> ParseManager::CreateClassLists()
+{
+    QList<CLASSTREE*>ret;
+    QList<CLASSLISTITEM*> classlist;
+    QList<CLASSLISTITEM*> allclasslist;
+
+    //Iteration over all parsed documents
+    if(getPreProcessor()){
+        for (Snapshot::const_iterator it = getPreProcessor()->snapshot.begin()
+            ; it != getPreProcessor()->snapshot.end(); ++it)
+        {
+            Document::Ptr doc = (*it);
+            if(doc){
+                QFileInfo fileinf(doc->fileName());
+                QFileInfo fileinf1(m_strHeaderFile);
+                //Get the Translated unit
+                Control* ctrl = doc->control();
+                TranslationUnit* trlUnit = ctrl->translationUnit();
+                AST* pAst = trlUnit->ast();
+                TranslationUnitAST *ptrAst = 0;
+                if(pAst && (ptrAst = pAst->asTranslationUnit())){
+                    //iteration over all translated declaration in this document
+                    for (DeclarationListAST *pDecllist = ptrAst->declaration_list; pDecllist; pDecllist = pDecllist->next) {
+                        if(pDecllist->value){
+                            SimpleDeclarationAST *pSimpleDec = pDecllist->value->asSimpleDeclaration();
+                            if(pSimpleDec){
+                                //Iteration over class specifier
+                                for (SpecifierListAST *pSimpleDecDecllist = pSimpleDec->decl_specifier_list; pSimpleDecDecllist; pSimpleDecDecllist = pSimpleDecDecllist->next) {
+                                    ClassSpecifierAST * pclassspec = pSimpleDecDecllist->value->asClassSpecifier();
+                                    if(pclassspec){
+                                        CLASSLISTITEM* item = new CLASSLISTITEM();
+                                        item->classspec = pclassspec;
+                                        item->trlUnit = trlUnit;
+                                        allclasslist.push_back(item);
+                                        //We found a class that is defined in the header file that needs to be checked
+                                        if(fileinf.fileName().toLower() == fileinf1.fileName().toLower()){
+                                            CLASSTREE* cltree = new CLASSTREE();
+                                            cltree->highestlevelclass = item;
+                                            cltree->classlist.push_back(item);
+                                            //now add all baseclasses from this class
+                                            ret.push_back(cltree);
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    //after we search for the classes we need to search for the baseclasses
+    foreach(CLASSTREE *cltree, ret){
+        QList<CLASSLISTITEM*> baseclasslist;
+        getBaseClasses(cltree->highestlevelclass, baseclasslist, allclasslist);
+        cltree->classlist.append(baseclasslist);
+    }
+    return ret;
+}
+
+/********************************************
+Gets all the baseclass from a class and 
+add those base classes into the baseclasslist
+********************************************/
+void ParseManager::getBaseClasses(const CLASSLISTITEM* pclass, QList<CLASSLISTITEM*> &baseclasslist, const QList<CLASSLISTITEM*> &allclasslist)
+{
+    //iteration over the base_clause_list of the current class
+    QList<CLASSLISTITEM*>child;
+    for(BaseSpecifierListAST *pBaseSpecList = pclass->classspec->base_clause_list; pBaseSpecList; pBaseSpecList = pBaseSpecList->next)
+    {
+        BaseSpecifierAST *pBaseSpec = pBaseSpecList->value;
+        foreach(CLASSLISTITEM* pclspec, allclasslist)
+        {
+            if(pclspec->classspec->symbol->name()->isEqualTo(pBaseSpec->symbol->name()))
+            {
+                child.push_back(pclspec);
+                baseclasslist.push_back(pclspec);
+                break;
+            }
+        }
+    }
+    //call the function recursive because all the basclasses can have other base classes
+    foreach(CLASSLISTITEM* pchclass, child){
+        getBaseClasses(pchclass, baseclasslist, allclasslist);
+    }
+}
+
+/**************************************************
+This function finds and creates all Elements wich
+are significant for MetaDatas.
+Those element will be added in the aparameter 
+lists.
+**************************************************/
+void ParseManager::getElements(QList<FUNCTIONITEM*> &functionlist
+                               , QList<PROPERTYITEM*> &propertylist
+                               , QList<QENUMITEM*> &qenumlist
+                               , QList<ENUMITEM*> &enumlist
+                               , QList<QFLAGITEM*> &qflaglist
+                               , QList<QDECLAREFLAGSITEM*> &qdeclareflaglist
+                               , const QList<CLASSLISTITEM*> classitems
+                               , const CLASSLISTITEM* highestlevelclass)
+{
+    foreach(CLASSLISTITEM* classitem, classitems){
+        for (DeclarationListAST *pmemberlist = classitem->classspec->member_specifier_list; pmemberlist; pmemberlist = pmemberlist->next) {
+            /**********
+            Functions
+            **********/
+            FunctionDefinitionAST *pfctdef = pmemberlist->value->asFunctionDefinition();
+            if(pfctdef){
+                FUNCTIONITEM* item = new FUNCTIONITEM();
+                item->trlUnit = classitem->trlUnit;
+                item->function = pfctdef->symbol;
+//                item->fctast = pfctdef;
+                item->classAst = classitem->classspec;
+                item->highestlevelclass = highestlevelclass;
+                functionlist.push_back(item);
+            }
+
+            SimpleDeclarationAST *pdecl = pmemberlist->value->asSimpleDeclaration();
+            if(pdecl){
+                for(List<Declaration*>* decllist = pdecl->symbols; decllist; decllist = decllist->next)
+                {
+                    Function* pfct = decllist->value->type()->asFunctionType();
+                    if(pfct){
+                        FUNCTIONITEM* item = new FUNCTIONITEM();
+                        item->trlUnit = classitem->trlUnit;
+                        item->function = pfct;
+//                        item->ast = pdecl;
+                        item->classAst = classitem->classspec;
+                        item->highestlevelclass = highestlevelclass;
+                        functionlist.push_back(item);
+                    }
+                }
+                /******
+                enum
+                ******/
+                for(List<SpecifierAST*>* decllist = pdecl->decl_specifier_list; decllist; decllist = decllist->next)
+                {
+                    EnumSpecifierAST * penum = decllist->value->asEnumSpecifier();
+                    if(penum){
+                        ENUMITEM* item = new ENUMITEM();
+                        item->ast = penum;
+                        item->highestlevelclass = highestlevelclass;
+                        item->trlUnit = classitem->trlUnit;
+                        enumlist.push_back(item);
+                    }
+                }
+            }
+            else{
+                /**********
+                Q_PROPERTY
+                **********/
+                QPropertyDeclarationAST *ppdecl = pmemberlist->value->asQPropertyDeclarationAST();
+                if(ppdecl){
+                    PROPERTYITEM* item = new PROPERTYITEM();
+                    item->ast = ppdecl;
+                    item->highestlevelclass = highestlevelclass;
+                    item->trlUnit = classitem->trlUnit;
+                    item->readdefined = (ppdecl->read_token > 0);
+                    item->writedefined = (ppdecl->write_token > 0);
+                    item->resetdefined = (ppdecl->reset_token > 0);
+                    item->notifydefined = (ppdecl->notify_token > 0);
+                    propertylist.push_back(item);
+                }
+                else{
+                    /**********
+                    Q_ENUM
+                    **********/
+                    QEnumDeclarationAST *pqenum = pmemberlist->value->asQEnumDeclarationAST();
+                    if(pqenum){
+                        QENUMITEM* item = new QENUMITEM();
+                        item->ast = pqenum;
+                        item->highestlevelclass = highestlevelclass;
+                        item->trlUnit = classitem->trlUnit;
+                        qenumlist.push_back(item);
+                    }
+                    else{
+                        /**********
+                        Q_FLAGS
+                        **********/
+                        QFlagsDeclarationAST *pqflags = pmemberlist->value->asQFlagsDeclarationAST();
+                        if(pqflags){
+                            QFLAGITEM* item = new QFLAGITEM();
+                            item->ast = pqflags;
+                            item->highestlevelclass = highestlevelclass;
+                            item->trlUnit = classitem->trlUnit;
+                            qflaglist.push_back(item);
+                        }
+                        else {
+                            /****************
+                            Q_DECLARE_FLAGS
+                            ****************/
+                            QDeclareFlagsDeclarationAST *pqdeclflags = pmemberlist->value->asQDeclareFlagsDeclarationAST();
+                            if(pqdeclflags){
+                                QDECLAREFLAGSITEM* item = new QDECLAREFLAGSITEM();
+                                item->ast = pqdeclflags;
+                                item->highestlevelclass = highestlevelclass;
+                                item->trlUnit = classitem->trlUnit;
+                                qdeclareflaglist.push_back(item);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+/*********************************************
+Function that starts the comare between the 
+parser result and their metadata content.
+*********************************************/
+bool ParseManager::checkAllMetadatas(ParseManager* pInterfaceParserManager)
+{
+    bool ret = true;
+
+    /************************************************
+    Get all elements from the interface header file
+    ************************************************/
+    QList<CLASSTREE*> ilookuplist = pInterfaceParserManager->CreateClassLists();
+    QList<QList<FUNCTIONITEM*> > ifunctionslookuplist;
+    QList<QList<PROPERTYITEM*> > ipropertieslookuplist;
+    QList<QList<QENUMITEM*> > iqenumlookuplist;
+    QList<QList<ENUMITEM*> > ienumlookuplist;
+    QList<QList<QFLAGITEM*> > iqflaglookuplist;
+    QList<QList<QDECLAREFLAGSITEM*> > iqdeclareflaglookuplist;
+    foreach(CLASSTREE* iclasstree, ilookuplist){
+        QList<FUNCTIONITEM*>functionlist;
+        QList<PROPERTYITEM*>propertylist;
+        QList<QENUMITEM*>qenumlist;
+        QList<ENUMITEM*>enumlist;
+        QList<QFLAGITEM*> qflaglist;
+        QList<QDECLAREFLAGSITEM*> qdeclareflag;
+        getElements(functionlist
+            , propertylist
+            , qenumlist
+            , enumlist
+            , qflaglist
+            , qdeclareflag
+            , iclasstree->classlist
+            , iclasstree->highestlevelclass);
+        if(functionlist.size() > 0)
+            ifunctionslookuplist.append(functionlist);
+        if(propertylist.size() > 0)
+            ipropertieslookuplist.append(propertylist);
+        if(qenumlist.size() > 0)
+            iqenumlookuplist.append(qenumlist);
+        if(enumlist.size() > 0)
+            ienumlookuplist.append(enumlist);
+        if(qflaglist.size() > 0)
+            iqflaglookuplist.append(qflaglist);
+        if(qdeclareflag.size() > 0)
+            iqdeclareflaglookuplist.append(qdeclareflag);
+    }
+
+    /************************************************
+    Get all elements from the compare header file
+    ************************************************/
+    QList<CLASSTREE*> lookuplist = CreateClassLists();
+    QList<QList<FUNCTIONITEM*> > functionslookuplist;
+    QList<QList<PROPERTYITEM*> > propertieslookuplist;
+    QList<QList<QENUMITEM*> > qenumlookuplist;
+    QList<QList<ENUMITEM*> > enumlookuplist;
+    QList<QList<QFLAGITEM*> > qflaglookuplist;
+    QList<QList<QDECLAREFLAGSITEM*> > qdeclareflaglookuplist;
+    foreach(CLASSTREE* classtree, lookuplist){
+        QList<FUNCTIONITEM*>functionlist;
+        QList<PROPERTYITEM*>propertylist;
+        QList<QENUMITEM*>qenumlist;
+        QList<ENUMITEM*>enumlist;
+        QList<QFLAGITEM*> qflaglist;
+        QList<QDECLAREFLAGSITEM*> qdeclareflag;
+        getElements(functionlist
+            , propertylist
+            , qenumlist
+            , enumlist
+            , qflaglist
+            , qdeclareflag
+            , classtree->classlist
+            , classtree->highestlevelclass);
+        if(functionlist.size() > 0)
+            functionslookuplist.append(functionlist);
+        if(propertylist.size() > 0)
+            propertieslookuplist.append(propertylist);
+        if(qenumlist.size() > 0)
+            qenumlookuplist.append(qenumlist);
+        if(enumlist.size() > 0)
+            enumlookuplist.append(enumlist);
+        if(qflaglist.size() > 0)
+            qflaglookuplist.append(qflaglist);
+        if(qdeclareflag.size() > 0)
+            qdeclareflaglookuplist.append(qdeclareflag);
+    }
+
+    /******************************
+    Check for function
+    ******************************/
+    QList<FUNCTIONITEM*> missingifcts = checkMetadataFunctions(functionslookuplist, ifunctionslookuplist);
+    if(missingifcts.size() > 0){
+        foreach(FUNCTIONITEM* ifct, missingifcts){
+            m_errormsgs.push_back(getErrorMessage(ifct));
+        }
+        ret =  false;
+    }
+
+    /******************************
+    Check for properies
+    ******************************/
+    QList<PROPERTYITEM*> missingippts = checkMetadataProperties(propertieslookuplist, functionslookuplist, ipropertieslookuplist, ifunctionslookuplist);
+    if(missingippts.size() > 0){
+        foreach(PROPERTYITEM* ippt, missingippts){
+            m_errormsgs.push_back(getErrorMessage(ippt));
+        }
+        ret =  false;
+    }
+
+    /******************************
+    Check for enums
+    ******************************/
+    QList<QENUMITEM*> missingiqenums = checkMetadataEnums(qenumlookuplist, enumlookuplist, iqenumlookuplist, ienumlookuplist);
+    if(missingiqenums.size() > 0){
+        foreach(QENUMITEM* ienum, missingiqenums){
+            m_errormsgs.push_back(getErrorMessage(ienum));
+        }
+        ret =  false;
+    }
+
+    /******************************
+    Check for flags
+    ******************************/
+    QList<QFLAGITEM*> missingiqflags = checkMetadataFlags(qflaglookuplist, qdeclareflaglookuplist, enumlookuplist
+                                                        , iqflaglookuplist, iqdeclareflaglookuplist, ienumlookuplist);
+    if(missingiqflags.size() > 0){
+        foreach(QFLAGITEM* iflags, missingiqflags){
+            m_errormsgs.push_back(getErrorMessage(iflags));
+        }
+        ret =  false;
+    }
+
+    //now delet all Classitems
+    foreach(CLASSTREE* l, ilookuplist){
+        l->classlist.clear();
+    }
+    foreach(CLASSTREE* l, lookuplist){
+        l->classlist.clear();
+    }
+    //delete all functionitems
+    foreach(QList<FUNCTIONITEM*>l, ifunctionslookuplist){
+        l.clear();
+    }
+    foreach(QList<FUNCTIONITEM*>l, functionslookuplist){
+        l.clear();
+    }
+    //delete all properties
+    foreach(QList<PROPERTYITEM*>l, ipropertieslookuplist){
+        l.clear();
+    }
+    foreach(QList<PROPERTYITEM*>l, propertieslookuplist){
+        l.clear();
+    }
+    //delete all qenums
+    foreach(QList<QENUMITEM*>l, iqenumlookuplist){
+        l.clear();
+    }
+    foreach(QList<QENUMITEM*>l, iqenumlookuplist){
+        l.clear();
+    }
+    //delete all enums
+    foreach(QList<ENUMITEM*>l, ienumlookuplist){
+        l.clear();
+    }
+    foreach(QList<ENUMITEM*>l, enumlookuplist){
+        l.clear();
+    }
+    //delete all qflags
+    foreach(QList<QFLAGITEM*>l, iqflaglookuplist){
+        l.clear();
+    }
+    foreach(QList<QFLAGITEM*>l, qflaglookuplist){
+        l.clear();
+    }
+    //delete all qdeclareflags
+    foreach(QList<QDECLAREFLAGSITEM*>l, iqdeclareflaglookuplist){
+        l.clear();
+    }
+    foreach(QList<QDECLAREFLAGSITEM*>l, qdeclareflaglookuplist){
+        l.clear();
+    }
+
+    return ret;
+}
+
+//<-------------------------------------------------------  Start of MetaData functions
+/***********************************
+Function that checks all functions
+which will occur in the MetaData
+***********************************/
+QList<FUNCTIONITEM*> ParseManager::checkMetadataFunctions(const QList<QList<FUNCTIONITEM*> > &classfctlist, const QList<QList<FUNCTIONITEM*> > &iclassfctlist)
+{
+    QList<FUNCTIONITEM*> missingifcts;
+    //Compare each function from interface with function from header (incl. baseclass functions)
+    QList<FUNCTIONITEM*> ifcts;
+    foreach(QList<FUNCTIONITEM*>ifunctionlist, iclassfctlist){
+        ifcts.clear();
+        //check if one header class contains all function from one interface header class
+        if(classfctlist.count() > 0){
+            foreach(QList<FUNCTIONITEM*>functionlist, classfctlist){
+                QList<FUNCTIONITEM*> tmpl = containsAllMetadataFunction(functionlist, ifunctionlist);
+                if(tmpl.size() == 0)
+                    ifcts.clear();
+                else
+                    ifcts.append(tmpl);
+            }
+        }
+        else {
+            foreach(FUNCTIONITEM *pfct, ifunctionlist)
+                pfct->classWichIsNotFound << "<all classes>";
+            ifcts.append(ifunctionlist);
+        }
+        missingifcts.append(ifcts);
+    }
+    return missingifcts;
+}
+
+/*********************************************
+Helper function to check if a function will 
+occure in the MetaData.
+*********************************************/
+bool ParseManager::isMetaObjFunction(FUNCTIONITEM* fct)
+{
+    if(fct->function->isInvokable()
+        || fct->function->isSignal()
+        || fct->function->isSlot())
+        return true;
+    return false;
+}
+
+/****************************************************
+Check if all function from iclassfctlist are defined 
+in the classfctlist as well.
+It will return all the function they are missing.
+****************************************************/
+QList<FUNCTIONITEM*> ParseManager::containsAllMetadataFunction(const QList<FUNCTIONITEM*> &classfctlist, const QList<FUNCTIONITEM*> &iclassfctlist)
+{
+    QList<FUNCTIONITEM*> ret;
+    foreach(FUNCTIONITEM* ifct, iclassfctlist){
+        if(isMetaObjFunction(ifct)){
+            bool found = false;
+            QStringList missingimplinclasses;
+            ClassSpecifierAST* clspec = 0;
+            foreach(FUNCTIONITEM* fct, classfctlist){
+                if(clspec != fct->highestlevelclass->classspec){
+                    clspec = fct->highestlevelclass->classspec;
+                    //get the classname
+                    QString classname = "";
+                    unsigned int firsttoken = clspec->name->firstToken();
+                    classname += fct->trlUnit->spell(firsttoken);
+                    if(missingimplinclasses.indexOf(classname) < 0)
+                        missingimplinclasses.push_back(classname);
+                }
+                //wb
+                //qDebug() << "---------------------------------";
+                //qDebug() << getErrorMessage(ifct);
+                //qDebug() << getErrorMessage(fct);
+                if(fct->isEqualTo(ifct, false)){
+                    found = true;
+                    missingimplinclasses.clear();
+                    break;
+                }
+            }
+            if(!found){
+                ifct->classWichIsNotFound.append(missingimplinclasses);
+                ret.push_back(ifct);
+            }
+        }
+    }
+    return ret;
+}
+
+/************************************
+Function that gives back an error 
+string for a MetaData function
+mismatch.
+************************************/
+QString ParseManager::getErrorMessage(FUNCTIONITEM* fct)
+{
+    QString ret = "";
+    QTextStream out(&ret);
+    QString fctstring = "";
+    QString fcttype = "";
+
+    foreach(QString classname, fct->classWichIsNotFound){
+        if(ret.size() > 0)
+            out << endl;
+
+        fcttype = "";
+        fctstring = classname;
+        fctstring += "::";
+
+        unsigned int token = fct->function->sourceLocation() - 1;
+        if(token >= 0){
+            //tok.isNot(T_EOF_SYMBOL)
+            while(fct->trlUnit->tokenAt(token).isNot(T_EOF_SYMBOL)){
+                fctstring += fct->trlUnit->tokenAt(token).spell();
+                if(*fct->trlUnit->tokenAt(token).spell() == ')')
+                    break;
+                fctstring += " ";
+                token++;
+            }
+        }
+
+        Function* pfct = fct->function;
+        if(pfct){
+            fcttype = "type: ";
+            //Check for private, protected and public
+            if(pfct->isPublic())
+                fcttype = "public ";
+            if(pfct->isProtected())
+                fcttype = "protected ";
+            if(pfct->isPrivate())
+                fcttype = "private ";
+
+            if(pfct->isVirtual())
+                fcttype += "virtual ";
+            if(pfct->isPureVirtual())
+                fcttype += "pure virtual ";
+
+            if(pfct->isSignal())
+                fcttype += "Signal ";
+            if(pfct->isSlot())
+                fcttype += "Slot ";
+            if(pfct->isNormal())
+                fcttype += "Normal ";
+            if(pfct->isInvokable())
+                fcttype += "Invokable ";
+        }
+        out << fcttype << fctstring;
+    }
+    return ret;
+}
+//--->
+
+//<-------------------------------------------------------  Start of Q_PROPERTY checks
+/***********************************
+Function that checks all Property
+which will occur in the MetaData
+***********************************/
+QList<PROPERTYITEM*> ParseManager::checkMetadataProperties(const QList<QList<PROPERTYITEM*> > &classproplist
+                                                                         , const QList<QList<FUNCTIONITEM*> > &classfctlist
+                                                                         , const QList<QList<PROPERTYITEM*> > &iclassproplist
+                                                                         , const QList<QList<FUNCTIONITEM*> > &iclassfctlist)
+{
+    QList<PROPERTYITEM*> missingifcts;
+    //assign the property functions
+    foreach(QList<PROPERTYITEM*>proplist, classproplist){
+        foreach(PROPERTYITEM* prop, proplist){
+            assignPropertyFunctions(prop, classfctlist);
+        }
+    }
+
+    foreach(QList<PROPERTYITEM*>proplist, iclassproplist){
+        foreach(PROPERTYITEM* prop, proplist){
+            assignPropertyFunctions(prop, iclassfctlist);
+        }
+    }
+
+    //Compare each qproperty from interface with qproperty from header (incl. baseclass functions)
+    QList<PROPERTYITEM*> ippts;
+    foreach(QList<PROPERTYITEM*>ipropertylist, iclassproplist){
+        ippts.clear();
+        //check if one header class contains all function from one interface header class
+        if(classproplist.count() > 0){
+            foreach(QList<PROPERTYITEM*>propertylist, classproplist){
+                QList<PROPERTYITEM*> tmpl = containsAllPropertyFunction(propertylist, ipropertylist);
+                if(tmpl.size() == 0)
+                    ippts.clear();
+                else
+                    ippts.append(tmpl);
+            }
+        }
+        else {
+            foreach(PROPERTYITEM *pprop, ipropertylist)
+                pprop->classWichIsNotFound << "<all classes>";
+            ippts.append(ipropertylist);
+        }
+        missingifcts.append(ippts);
+    }
+    return missingifcts;
+}
+
+/**************************************
+Function that resolves the dependensies
+between Q_PROPERTY
+and thier READ, WRITE, NOTIFY and RESET
+functions.
+***************************************/
+void ParseManager::assignPropertyFunctions(PROPERTYITEM* prop, const QList<QList<FUNCTIONITEM*> > &fctlookuplist)
+{
+    //get the name of the needed functions
+    QString type;
+    QString readfctname;
+    QString writefctname;
+    QString resetfctname;
+    QString notifyfctname;
+
+    int needtofind = 0;
+    type = prop->trlUnit->spell(prop->ast->type_token);
+    if(prop->readdefined){
+        readfctname = prop->trlUnit->spell(prop->ast->read_function_token);
+        needtofind++;
+    }
+    if(prop->writedefined){
+        writefctname = prop->trlUnit->spell(prop->ast->write_function_token);
+        needtofind++;
+    }
+    if(prop->resetdefined){
+        resetfctname = prop->trlUnit->spell(prop->ast->reset_function_token);
+        needtofind++;
+    }
+    if(prop->notifydefined){
+        notifyfctname = prop->trlUnit->spell(prop->ast->notify_function_token);
+        needtofind++;
+    }
+    //Now iterate over all function to find all functions wich are defined in the Q_PROPERTY macro
+    if(needtofind > 0){
+        prop->foundalldefinedfct = false;
+        foreach(QList<FUNCTIONITEM*> fctlist, fctlookuplist){
+            foreach(FUNCTIONITEM* pfct, fctlist){
+/*
+                long start = pfct->ast->firstToken();
+                long stop = pfct->ast->lastToken();
+                QString val;
+                for(long i = start; i < stop; i++){
+                    val += pfct->trlUnit->spell(i);
+                    val += " ";
+                }
+                qDebug() << val;
+*/
+                QString fctname = pfct->trlUnit->spell(pfct->function->sourceLocation());
+                //check the function type against the property type
+                QString fcttype =pfct->trlUnit->spell(pfct->function->sourceLocation() - 1);
+
+                if(fctname.length() > 0 && fcttype.length() > 0){
+                    if(prop->readdefined && fctname == readfctname){
+                        if(type != fcttype)
+                            continue;
+                        prop->readFct = pfct;
+                        needtofind--;
+                    }
+                    if(prop->writedefined && fctname == writefctname){
+                        prop->writeFct = pfct;
+                        needtofind--;
+                    }
+                    if(prop->resetdefined && fctname == resetfctname){
+                        prop->resetFct = pfct;
+                        needtofind--;
+                    }
+                    if(prop->notifydefined && fctname == notifyfctname){
+                        prop->notifyFct = pfct;
+                        needtofind--;
+                    }
+                    if(needtofind <= 0){
+                        //a flag that indicates if a function was missing
+                        prop->foundalldefinedfct = true;
+                        return;
+                    }
+                }
+            }
+        }
+    }
+}
+
+/**************************************
+Function that checks if all functions
+dependencies in Q_PROPERTY have the
+same arguments and retunr value.
+***************************************/
+QList<PROPERTYITEM*> ParseManager::containsAllPropertyFunction(const QList<PROPERTYITEM*> &classproplist, const QList<PROPERTYITEM*> &iclassproplist)
+{
+    QList<PROPERTYITEM*> ret;
+    foreach(PROPERTYITEM* ipropt, iclassproplist){
+        if(ipropt->foundalldefinedfct){
+            bool found = false;
+            QStringList missingimplinclasses;
+            ClassSpecifierAST* clspec = 0;
+            foreach(PROPERTYITEM* propt, classproplist){
+                if(clspec != propt->highestlevelclass->classspec){
+                    clspec = propt->highestlevelclass->classspec;
+                    //get the classname
+                    QString classname = "";
+                    unsigned int firsttoken = clspec->name->firstToken();
+                    classname += propt->trlUnit->spell(firsttoken);
+                    if(missingimplinclasses.indexOf(classname) < 0)
+                        missingimplinclasses.push_back(classname);
+                }
+                if(propt->isEqualTo(ipropt)){
+                    found = true;
+                    missingimplinclasses.clear();
+                    break;
+                }
+            }
+            if(!found){
+                ipropt->classWichIsNotFound.append(missingimplinclasses);
+                ret.push_back(ipropt);
+            }
+        }
+        else{
+            ret.push_back(ipropt);
+        }
+    }
+    return ret;
+}
+
+/************************************
+Function that gives back an error 
+string for a Q_PROPERTY mismatch.
+************************************/
+QString ParseManager::getErrorMessage(PROPERTYITEM* ppt)
+{
+    QString ret = "";
+    QTextStream out(&ret);
+    QString pptstring = "";
+    QString ppttype = "";
+
+    if(!ppt->foundalldefinedfct)
+    {
+        unsigned int firsttoken = ppt->highestlevelclass->classspec->name->firstToken();
+        unsigned int lasttoken = ppt->highestlevelclass->classspec->name->lastToken();
+        for(unsigned int i = firsttoken; i < lasttoken; i++){
+            out << ppt->trlUnit->spell(i);
+        }
+        out << "::";
+        firsttoken = ppt->ast->firstToken();
+        lasttoken = ppt->ast->lastToken();
+        for(unsigned int i = firsttoken; i <= lasttoken; i++){
+            out << ppt->trlUnit->spell(i) << " ";
+        }
+        out << endl << " -";
+        if(ppt->readdefined && !ppt->readFct)
+            out << "READ ";
+        if(ppt->writedefined && !ppt->writeFct)
+            out << "WRITE ";
+        if(ppt->resetdefined && !ppt->resetFct)
+            out << "RESET.";
+        if(ppt->notifydefined && !ppt->notifyFct)
+            out << "NOTIFY ";
+        out << "functions missing." << endl;
+    }
+    for(int i = 0; i < ppt->classWichIsNotFound.size(); i++){
+        if(ret.size() > 0)
+            out << endl;
+
+        pptstring = ppt->classWichIsNotFound[i];
+        pptstring += "::";
+
+        unsigned int firsttoken = ppt->ast->firstToken();
+        unsigned int lasttoken = ppt->ast->lastToken();
+        for(unsigned int i = firsttoken; i <= lasttoken; i++){
+            pptstring += ppt->trlUnit->spell(i);
+            pptstring += " ";
+        }
+
+        out << ppttype << pptstring;
+    }
+    return ret;
+}
+//--->
+
+
+//<------------------------------------------------------- Start of Q_ENUMS checks
+/***********************************
+Function that checks all enums
+which will occur in the MetaData
+***********************************/
+QList<QENUMITEM*> ParseManager::checkMetadataEnums(const QList<QList<QENUMITEM*> > &classqenumlist
+                                                , const QList<QList<ENUMITEM*> > &classenumlist
+                                                , const QList<QList<QENUMITEM*> > &iclassqenumlist
+                                                , const QList<QList<ENUMITEM*> > &iclassenumlist)
+{
+    QList<QENUMITEM*> missingiqenums;
+    //assign the property functions
+    foreach(QList<QENUMITEM*>qenumlist, classqenumlist){
+        foreach(QENUMITEM* qenum, qenumlist){
+            assignEnumValues(qenum, classenumlist);
+        }
+    }
+    foreach(QList<QENUMITEM*>qenumlist, iclassqenumlist){
+        foreach(QENUMITEM* qenum, qenumlist){
+            assignEnumValues(qenum, iclassenumlist);
+        }
+    }
+
+    //Compare each qenum from interface with qenum from header (incl. baseclass functions)
+    QList<QENUMITEM*> iqenums;
+    foreach(QList<QENUMITEM*>iqenumlist, iclassqenumlist){
+        iqenums.clear();
+        //check if one header class contains all function from one interface header class
+        if(classqenumlist.count() > 0){
+            foreach(QList<QENUMITEM*>qenumlist, classqenumlist){
+                QList<QENUMITEM*> tmpl = containsAllEnums(qenumlist, iqenumlist);
+                if(tmpl.size() == 0)
+                    iqenums.clear();
+                else
+                    iqenums.append(tmpl);
+
+            }
+        }
+        else {
+            foreach(QENUMITEM *qenum, iqenumlist)
+                qenum->classWichIsNotFound << "<all classes>";
+            iqenums.append(iqenumlist);
+        }
+        missingiqenums.append(iqenums);
+    }
+
+    return missingiqenums;
+}
+
+/*********************************************
+Helper function which creates a string out of
+an enumerator including its values.
+*********************************************/
+QStringList ParseManager::getEnumValueStringList(ENUMITEM *penum, QString mappedenumname/* = ""*/)
+{
+    QStringList ret;
+    EnumSpecifierAST *penumsec = penum->ast;
+    QString enumname = penum->trlUnit->spell(penumsec->name->firstToken());
+    int enumvalue = 0;
+    //now iterrate over all enumitems and create a string like following:
+    //EnumName.EnumItemName.Value
+    //ConnectionState.disconnected.0
+    for (EnumeratorListAST *plist = penum->ast->enumerator_list; plist; plist = plist->next) {
+        QString value = enumname;
+        if(mappedenumname.size() > 0)
+            value = mappedenumname;
+        value += ".";
+        value += penum->trlUnit->spell(plist->value->identifier_token);
+        value += ".";
+        if(plist->value->equal_token > 0 && plist->value->expression){
+            QString v = penum->trlUnit->spell(plist->value->expression->firstToken());
+            bool ch;
+            int newval = enumvalue;
+            if(v.indexOf("0x") >= 0)
+                newval = v.toInt(&ch, 16);
+            else
+                newval = v.toInt(&ch, 10);
+            if(ch)
+                enumvalue = newval;
+        }
+        value += QString::number(enumvalue);
+        enumvalue++;
+        // now add this enumitem string in the VALUE list
+        ret << value;
+    }
+    return ret;
+}
+
+/**************************************
+Function that resolves the dependensies
+between Q_ENUMS and enums.
+***************************************/
+void ParseManager::assignEnumValues(QENUMITEM* qenum, const QList<QList<ENUMITEM*> > &enumlookuplist)
+{
+    QString enumname;
+    for (EnumeratorListAST *plist = qenum->ast->enumerator_list; plist; plist = plist->next) {
+        EnumeratorAST *penum = plist->value->asEnumerator();
+        if(penum){
+            //get the name of the enum definition
+            enumname = qenum->trlUnit->spell(penum->firstToken());
+            //iterate over all enums and find the one with the same name like enumname
+            bool found = false;
+            foreach (QList<ENUMITEM*> penumlist, enumlookuplist) {
+                foreach(ENUMITEM *penum, penumlist){
+                    EnumSpecifierAST *penumsec = penum->ast;
+                    QString enumname1 = penum->trlUnit->spell(penumsec->name->firstToken());
+                    if(enumname == enumname1){
+                        qenum->values << getEnumValueStringList(penum);
+                        found = true;
+                        break;
+                    }
+                }
+                if(!found)
+                    qenum->foundallenums = false;
+            }
+        }
+    }
+}
+
+/***********************************
+Function that checkt if the Q_ENUMS 
+are completed defined and if the
+Enum values are the same.
+***********************************/
+QList<QENUMITEM*> ParseManager::containsAllEnums(const QList<QENUMITEM*> &classqenumlist, const QList<QENUMITEM*> &iclassqenumlist)
+{
+    QList<QENUMITEM*> ret;
+    foreach(QENUMITEM* iqenum, iclassqenumlist){
+        bool found = false;
+        QStringList missingimplinclasses;
+        ClassSpecifierAST* clspec = 0;
+        foreach(QENUMITEM* qenum, classqenumlist){
+            if(clspec != qenum->highestlevelclass->classspec){
+                clspec = qenum->highestlevelclass->classspec;
+                //get the classname
+                QString classname = "";
+                unsigned int firsttoken = clspec->name->firstToken();
+                classname += qenum->trlUnit->spell(firsttoken);
+                if(missingimplinclasses.indexOf(classname) < 0)
+                    missingimplinclasses.push_back(classname);
+            }
+            if(qenum->isEqualTo(iqenum)){
+                found = true;
+                missingimplinclasses.clear();
+                break;
+            }
+        }
+        if(!found){
+            iqenum->classWichIsNotFound.append(missingimplinclasses);
+            ret.push_back(iqenum);
+        }
+    }
+    return ret;
+}
+
+/************************************
+Function that gives back an error 
+string for a Q_ENUMS mismatch.
+************************************/
+QString ParseManager::getErrorMessage(QENUMITEM* qenum)
+{
+    QString ret = "";
+    QTextStream out(&ret);
+
+    if(!qenum->foundallenums)
+    {
+        unsigned int firsttoken = qenum->highestlevelclass->classspec->name->firstToken();
+        unsigned int lasttoken = qenum->highestlevelclass->classspec->name->lastToken();
+        for(unsigned int i = firsttoken; i < lasttoken; i++){
+            out << qenum->trlUnit->spell(i);
+        }
+        out << "::";
+        firsttoken = qenum->ast->firstToken();
+        lasttoken = qenum->ast->lastToken();
+        for(unsigned int i = firsttoken; i <= lasttoken; i++){
+            out << qenum->trlUnit->spell(i) << " ";
+        }
+        out << endl << " - one or more Enums missing." << endl;
+    }
+
+    for(int i = 0; i < qenum->classWichIsNotFound.size(); i++){
+        if(ret.size() > 0)
+            out << endl;
+
+        out << qenum->classWichIsNotFound[i] << "::";
+
+        unsigned int firsttoken = qenum->ast->firstToken();
+        unsigned int lasttoken = qenum->ast->lastToken();
+        for(unsigned int i = firsttoken; i <= lasttoken; i++){
+            out << qenum->trlUnit->spell(i) << " ";
+        }
+    }
+    return ret;
+}
+//--->
+
+//<------------------------------------------------------- Start of Q_FLAGS checks
+/***********************************
+Function that checks all flags
+which will occur in the MetaData
+***********************************/
+QList<QFLAGITEM*> ParseManager::checkMetadataFlags(const QList<QList<QFLAGITEM*> > &classqflaglist
+                                            , const QList<QList<QDECLAREFLAGSITEM*> > &classqdeclareflaglist
+                                            , const QList<QList<ENUMITEM*> > &classenumlist
+                                            , const QList<QList<QFLAGITEM*> > &iclassqflaglist
+                                            , const QList<QList<QDECLAREFLAGSITEM*> > &iclassqdeclareflaglist
+                                            , const QList<QList<ENUMITEM*> > &iclassenumlist)
+{
+    QList<QFLAGITEM*> missingqflags;
+    //assign the enums to the flags
+    foreach(QList<QFLAGITEM*>qflaglist, classqflaglist){
+        foreach(QFLAGITEM* qflag, qflaglist){
+            assignFlagValues(qflag, classqdeclareflaglist, classenumlist);
+        }
+    }
+    foreach(QList<QFLAGITEM*>qflaglist, iclassqflaglist){
+        foreach(QFLAGITEM* qflag, qflaglist){
+            assignFlagValues(qflag, iclassqdeclareflaglist, iclassenumlist);
+        }
+    }
+
+    //Compare each qenum from interface with qenum from header (incl. baseclass functions)
+    QList<QFLAGITEM*> iqflags;
+    foreach(QList<QFLAGITEM*>iqflaglist, iclassqflaglist){
+        iqflags.clear();
+        //check if one header class contains all function from one interface header class
+        if(classqflaglist.count() >0){
+            foreach(QList<QFLAGITEM*>qflaglist, classqflaglist){
+                QList<QFLAGITEM*> tmpl = containsAllFlags(qflaglist, iqflaglist);
+                if(tmpl.size() == 0)
+                    iqflags.clear();
+                else
+                    iqflags.append(tmpl);
+
+            }
+        }
+        else {
+            foreach(QFLAGITEM *pflag, iqflaglist)
+                pflag->classWichIsNotFound << "<all classes>";
+            iqflags.append(iqflaglist);
+        }
+        missingqflags.append(iqflags);
+    }
+    return missingqflags;
+}
+
+/**************************************
+Function that resolves the dependensies
+between Q_FLAG, Q_DECLARE_FLAGS
+and enums.
+***************************************/
+void ParseManager::assignFlagValues(QFLAGITEM* qflags, const QList<QList<QDECLAREFLAGSITEM*> > &qdeclareflagslookuplist, const QList<QList<ENUMITEM*> > &enumlookuplist)
+{
+    QString qflagname;
+    QString enumname;
+    //read the flag names
+    for (EnumeratorListAST *plist = qflags->ast->enumerator_list; plist; plist = plist->next) {
+        EnumeratorAST *pflags = plist->value->asEnumerator();
+        if(pflags){
+            qflagname = qflags->trlUnit->spell(pflags->firstToken());
+            enumname = qflagname;
+            //try to find if there is a deflare flag macro with the same name as in qflagname
+            bool found = false;
+            foreach(QList<QDECLAREFLAGSITEM*> qdeclarelist, qdeclareflagslookuplist){
+                foreach(QDECLAREFLAGSITEM* qdeclare, qdeclarelist){
+                    QString declarename = qdeclare->trlUnit->spell(qdeclare->ast->flag_token);
+                    if(declarename == qflagname){
+                        //now map the right enum name to the flag
+                        enumname = qdeclare->trlUnit->spell(qdeclare->ast->enum_token);
+                        found = true;
+                        break;
+                    }
+                }
+                if(found)
+                    break;
+            }
+            //now we have the right enum name now we need to find the enum
+            found = false;
+            foreach(QList<ENUMITEM*> enumitemlist, enumlookuplist){
+                foreach(ENUMITEM* enumitem, enumitemlist){
+                    EnumSpecifierAST *penumspec = enumitem->ast;
+                    QString enumspecname = enumitem->trlUnit->spell(penumspec->name->firstToken());
+                    if(enumspecname == enumname){
+                        qflags->enumvalues << getEnumValueStringList(enumitem, qflagname);
+                        found = true;
+                        break;
+                    }
+                }
+                if(found)
+                    break;
+            }
+            if(!found)
+                qflags->foundallenums = false;
+        }
+    }
+}
+
+/*****************************************
+Function that compares if all enums
+and flags assigned by using the Q_FLAGS
+are complete defined.
+*****************************************/
+QList<QFLAGITEM*> ParseManager::containsAllFlags(const QList<QFLAGITEM*> &classqflaglist, const QList<QFLAGITEM*> &iclassqflaglist)
+{
+    QList<QFLAGITEM*> ret;
+    foreach(QFLAGITEM* iqflags, iclassqflaglist){
+        if(iqflags->foundallenums){
+            bool found = false;
+            QStringList missingimplinclasses;
+            ClassSpecifierAST* clspec = 0;
+            foreach(QFLAGITEM* qflags, classqflaglist){
+                if(clspec != qflags->highestlevelclass->classspec){
+                    clspec = qflags->highestlevelclass->classspec;
+                    //get the classname
+                    QString classname = "";
+                    unsigned int firsttoken = clspec->name->firstToken();
+                    classname += qflags->trlUnit->spell(firsttoken);
+                    if(missingimplinclasses.indexOf(classname) < 0)
+                        missingimplinclasses.push_back(classname);
+                }
+                if(qflags->isEqualTo(iqflags)){
+                    found = true;
+                    missingimplinclasses.clear();
+                    break;
+                }
+            }
+            if(!found){
+                iqflags->classWichIsNotFound.append(missingimplinclasses);
+                ret.push_back(iqflags);
+            }
+        }
+        else
+            ret.push_back(iqflags);
+    }
+    return ret;
+}
+
+/************************************
+Function that gives back an error 
+string for a Q_FLAGS mismatch.
+************************************/
+QString ParseManager::getErrorMessage(QFLAGITEM* pfg)
+{
+    QString ret = "";
+    QTextStream out(&ret);
+
+    if(!pfg->foundallenums)
+    {
+        unsigned int firsttoken = pfg->highestlevelclass->classspec->name->firstToken();
+        unsigned int lasttoken = pfg->highestlevelclass->classspec->name->lastToken();
+        for(unsigned int i = firsttoken; i < lasttoken; i++){
+            out << pfg->trlUnit->spell(i);
+        }
+        out << "::";
+        firsttoken = pfg->ast->firstToken();
+        lasttoken = pfg->ast->lastToken();
+        for(unsigned int i = firsttoken; i <= lasttoken; i++){
+            out << pfg->trlUnit->spell(i) << " ";
+        }
+        out << endl << " - one or more Enums missing." << endl;
+    }
+    for(int i = 0; i < pfg->classWichIsNotFound.size(); i++){
+        if(ret.size() > 0)
+            out << endl;
+
+        out << pfg->classWichIsNotFound[i] << "::";
+
+        unsigned int firsttoken = pfg->ast->firstToken();
+        unsigned int lasttoken = pfg->ast->lastToken();
+        for(unsigned int i = firsttoken; i <= lasttoken; i++){
+            out << pfg->trlUnit->spell(i) << " ";
+        }
+    }
+    return ret;
+}
+
+#include <moc_ParseManager.cpp>
+//--->
diff --git a/tests/auto/icheckbuild/ParseManager.h b/tests/auto/icheckbuild/ParseManager.h
new file mode 100644
index 00000000000..e56d82dbe13
--- /dev/null
+++ b/tests/auto/icheckbuild/ParseManager.h
@@ -0,0 +1,304 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+** Description:
+**
+** The ParseManager parses and compares to different header files
+** of its metadata. This can be used for checking if an Interface
+** is implemented complete.
+**
+** How to use it:
+**
+**    //Parse the interface header
+**    ParseManager* iParseManager = new ParseManager();
+**    iParseManager->setIncludePath(iIncludepathlist);
+**    iParseManager->parse(iFilelist);
+**
+**    //Parse the header that needs to be compared against the interface header
+**    ParseManager* chParseManager = new ParseManager();
+**    chIncludepathlist << getQTIncludePath();
+**    chParseManager->setIncludePath(chIncludepathlist);
+**    chParseManager->parse(chFilelist);
+**    
+**    if(!chParseManager->checkAllMetadatas(iParseManager)){
+**        cout << "Folowing interface items are missing:" << endl;
+**        QStringList errorlist = chParseManager->getErrorMsg();
+**        foreach(QString msg, errorlist){
+**            cout << (const char *)msg.toLatin1() << endl;
+**        }
+**        return -1;
+**    }
+**    else
+**        cout << "Interface is full defined.";
+**
+**************************************************************************/
+
+
+#ifndef PARSEMANAGER_H
+#define PARSEMANAGER_H
+
+#include <QObject>
+#include <QList>
+#include <QFuture>
+#include <QStringList>
+#include "cplusplus/CppDocument.h"
+
+namespace CppTools{
+    namespace Internal{
+        class CppPreprocessor;
+    }
+}
+
+namespace CPlusPlus {
+    class TranslationUnit;
+    class AST;
+    class ClassSpecifierAST;
+    class QPropertyDeclarationAST;
+    class QEnumDeclarationAST;
+    class QFlagsDeclarationAST;
+    class QDeclareFlagsDeclarationAST;
+    class EnumSpecifierAST;
+    class Function;
+
+    class CLASSLISTITEM
+    {
+    public:
+        CPlusPlus::TranslationUnit* trlUnit;
+        ClassSpecifierAST* classspec;
+    };
+    class CLASSTREE
+    {
+    public:
+        CLASSLISTITEM* highestlevelclass;
+        QList<CLASSLISTITEM*> classlist;
+    };
+    class FUNCTIONITEM
+    {
+    public:
+        const CLASSLISTITEM* highestlevelclass;
+        CPlusPlus::TranslationUnit* trlUnit;
+        ClassSpecifierAST* classAst;
+        QStringList classWichIsNotFound;
+        CPlusPlus::Function* function;
+
+        bool isEqualTo(FUNCTIONITEM* cpfct, bool ignoreName = true);
+        FUNCTIONITEM()
+        {
+            highestlevelclass = 0;
+            trlUnit = 0;
+            classAst = 0;
+            function = 0;
+        }
+    };
+    class PROPERTYITEM
+    {
+    public:
+        const CLASSLISTITEM* highestlevelclass;
+        QStringList classWichIsNotFound;
+        QPropertyDeclarationAST *ast;
+        CPlusPlus::TranslationUnit* trlUnit;
+        bool readdefined;
+        FUNCTIONITEM *readFct;
+        bool writedefined;
+        FUNCTIONITEM *writeFct;
+        bool resetdefined;
+        FUNCTIONITEM *resetFct;
+        bool notifydefined;
+        FUNCTIONITEM *notifyFct;
+        bool foundalldefinedfct;
+
+        bool isEqualTo(PROPERTYITEM* cpppt);
+        PROPERTYITEM()
+        {
+            highestlevelclass = 0;
+            ast = 0;
+            trlUnit = 0;
+            readdefined = false;
+            readFct = 0;
+            writedefined = false;
+            writeFct = 0;
+            resetdefined = false;
+            resetFct = 0;
+            notifydefined = false;
+            notifyFct = 0;
+            foundalldefinedfct = false;
+        }
+    };
+
+    class QENUMITEM
+    {
+    public:
+        const CLASSLISTITEM* highestlevelclass;
+        CPlusPlus::TranslationUnit* trlUnit;
+        QStringList classWichIsNotFound;
+        QEnumDeclarationAST* ast;
+        //an item in this list will be shown like:
+        //EnumName.EnumItemName.Value
+        //ConnectionState.disconnected.0
+        QStringList values;
+        bool foundallenums;
+
+        bool isEqualTo(QENUMITEM *cpenum);
+        QENUMITEM()
+        {
+            highestlevelclass = 0;
+            trlUnit = 0;
+            ast = 0;
+            values.clear();
+            foundallenums = true;
+        }
+    };
+
+    class ENUMITEM
+    {
+    public:
+        const CLASSLISTITEM* highestlevelclass;
+        CPlusPlus::TranslationUnit* trlUnit;
+        QStringList classWichIsNotFound;
+        EnumSpecifierAST* ast;
+
+        ENUMITEM()
+        {
+            highestlevelclass = 0;
+            trlUnit = 0;
+            ast = 0;
+        }
+    };
+
+    class QFLAGITEM
+    {
+    public:
+        const CLASSLISTITEM* highestlevelclass;
+        CPlusPlus::TranslationUnit* trlUnit;
+        QStringList classWichIsNotFound;
+        QFlagsDeclarationAST* ast;
+        QStringList enumvalues;
+        bool foundallenums;
+
+        bool isEqualTo(QFLAGITEM *cpflag);
+        QFLAGITEM()
+        {
+            highestlevelclass = 0;
+            trlUnit = 0;
+            ast = 0;
+            enumvalues.clear();
+            foundallenums = true;
+        }
+    };
+
+    class QDECLAREFLAGSITEM
+    {
+    public:
+        const CLASSLISTITEM* highestlevelclass;
+        CPlusPlus::TranslationUnit* trlUnit;
+        QStringList classWichIsNotFound;
+        QDeclareFlagsDeclarationAST* ast;
+
+        QDECLAREFLAGSITEM()
+        {
+            highestlevelclass = 0;
+            trlUnit = 0;
+            ast = 0;
+        }
+    };
+
+    class ParseManager : public QObject
+    {
+        Q_OBJECT
+    public:
+        ParseManager();
+        virtual ~ParseManager();
+        void setIncludePath(const QStringList &includePath);
+        void parse(const QStringList &sourceFiles);
+        bool checkAllMetadatas(ParseManager* pInterfaceParserManager);
+        CppTools::Internal::CppPreprocessor *getPreProcessor() { return pCppPreprocessor; }
+        QList<CLASSTREE*> CreateClassLists();
+        QStringList getErrorMsg() { return m_errormsgs; }
+
+    private:
+        void parse(CppTools::Internal::CppPreprocessor *preproc, const QStringList &files);
+        void getBaseClasses(const CLASSLISTITEM* pclass, QList<CLASSLISTITEM*> &baseclasslist, const QList<CLASSLISTITEM*> &allclasslist);
+        void getElements(QList<FUNCTIONITEM*> &functionlist
+            , QList<PROPERTYITEM*> &propertylist
+            , QList<QENUMITEM*> &qenumlist
+            , QList<ENUMITEM*> &enumlist
+            , QList<QFLAGITEM*> &qflaglist
+            , QList<QDECLAREFLAGSITEM*> &qdeclareflaglist
+            , const QList<CLASSLISTITEM*> classitems
+            , const CLASSLISTITEM* highestlevelclass);
+
+        //<--- for Metadata functions checks
+        QList<FUNCTIONITEM*> checkMetadataFunctions(const QList<QList<FUNCTIONITEM*> > &classfctlist, const QList<QList<FUNCTIONITEM*> > &iclassfctlist);
+        bool isMetaObjFunction(FUNCTIONITEM* fct);
+        QList<FUNCTIONITEM*> containsAllMetadataFunction(const QList<FUNCTIONITEM*> &classfctlist, const QList<FUNCTIONITEM*> &iclassfctlist);
+        QString getErrorMessage(FUNCTIONITEM* fct);
+        //--->
+
+        //<--- for Q_PROPERTY functions checks
+        QList<PROPERTYITEM*> checkMetadataProperties(const QList<QList<PROPERTYITEM*> > &classproplist
+            , const QList<QList<FUNCTIONITEM*> > &classfctlist
+            , const QList<QList<PROPERTYITEM*> > &iclassproplist
+            , const QList<QList<FUNCTIONITEM*> > &iclassfctlist);
+        void assignPropertyFunctions(PROPERTYITEM* prop, const QList<QList<FUNCTIONITEM*> > &fctlookuplist);
+        QList<PROPERTYITEM*> containsAllPropertyFunction(const QList<PROPERTYITEM*> &classproplist, const QList<PROPERTYITEM*> &iclassproplist);
+        QString getErrorMessage(PROPERTYITEM* ppt);
+        //--->
+
+        //<--- for Q_ENUMS checks
+        QList<QENUMITEM*> checkMetadataEnums(const QList<QList<QENUMITEM*> > &classqenumlist
+            , const QList<QList<ENUMITEM*> > &classenumlist
+            , const QList<QList<QENUMITEM*> > &iclassqenumlist
+            , const QList<QList<ENUMITEM*> > &iclassenumlist);
+        QStringList getEnumValueStringList(ENUMITEM *penum, QString mappedenumname = "");
+        void assignEnumValues(QENUMITEM* qenum, const QList<QList<ENUMITEM*> > &enumlookuplist);
+        QList<QENUMITEM*> containsAllEnums(const QList<QENUMITEM*> &classqenumlist, const QList<QENUMITEM*> &iclassqenumlist);
+        QString getErrorMessage(QENUMITEM* qenum);
+        //--->
+
+        //<--- for QFlags checks --->
+        QList<QFLAGITEM*> checkMetadataFlags(const QList<QList<QFLAGITEM*> > &classqflaglist
+            , const QList<QList<QDECLAREFLAGSITEM*> > &classqdeclareflaglist
+            , const QList<QList<ENUMITEM*> > &classenumlist
+            , const QList<QList<QFLAGITEM*> > &iclassqflaglist
+            , const QList<QList<QDECLAREFLAGSITEM*> > &iclassqdeclareflaglist
+            , const QList<QList<ENUMITEM*> > &iclassenumlist);
+        void assignFlagValues(QFLAGITEM* qflags, const QList<QList<QDECLAREFLAGSITEM*> > &qdeclareflagslookuplist, const QList<QList<ENUMITEM*> > &enumlookuplist);
+        QList<QFLAGITEM*> containsAllFlags(const QList<QFLAGITEM*> &classqflaglist, const QList<QFLAGITEM*> &iclassqflaglist);
+        QString getErrorMessage(QFLAGITEM* pfg);
+        //--->
+
+    private:
+        // cache
+        QStringList m_includePaths;
+        QStringList m_frameworkPaths;
+        QByteArray m_definedMacros;
+        CppTools::Internal::CppPreprocessor* pCppPreprocessor;
+        QString m_strHeaderFile;
+        QStringList m_errormsgs;
+    };
+}
+#endif // PARSEMANAGER_H
diff --git a/tests/auto/icheckbuild/icheckbuild.pro b/tests/auto/icheckbuild/icheckbuild.pro
new file mode 100644
index 00000000000..532b63a19e8
--- /dev/null
+++ b/tests/auto/icheckbuild/icheckbuild.pro
@@ -0,0 +1,25 @@
+REL_PATH_TO_SRC = ../../../src
+
+QT += testlib
+
+SOURCES += \
+        tst_icheckbuild.cpp
+
+DEFINES += ICHECK_BUILD ICHECK_APP_BUILD
+
+INCLUDEPATH += . \
+    $$REL_PATH_TO_SRC/../ \
+    $$REL_PATH_TO_SRC/global \
+    $$REL_PATH_TO_SRC/plugins \
+    $$REL_PATH_TO_SRC/libs \
+    $$REL_PATH_TO_SRC/shared/cplusplus \
+    $$REL_PATH_TO_SRC/libs/cplusplus
+
+TARGET=tst_$$TARGET
+
+include(./ichecklib.pri)
+HEADERS += ./ichecklib.h \
+           ./ichecklib_global.h \
+           ./ParseManager.h
+SOURCES += ./ichecklib.cpp \
+           ./ParseManager.cpp
diff --git a/tests/auto/icheckbuild/ichecklib.cpp b/tests/auto/icheckbuild/ichecklib.cpp
new file mode 100644
index 00000000000..9a1a5bfcafb
--- /dev/null
+++ b/tests/auto/icheckbuild/ichecklib.cpp
@@ -0,0 +1,60 @@
+#include "ichecklib.h"
+#include "ParseManager.h"
+#include <QtCore/QCoreApplication>
+#include <QString>
+#include <QStringList>
+#include <iostream>
+#include <QDebug>
+#include <QDir>
+#include <QFile>
+#include <QFileInfo>
+#include <QProcess>
+
+QStringList getQTIncludePath()
+{
+    QStringList ret;
+    QStringList processevironment = QProcess::systemEnvironment();
+    foreach(QString item, processevironment){
+        if(item.indexOf("QTDIR=") == 0){
+            QString qtpath = item.remove("QTDIR=");
+            ret << qtpath + "/include/QtCore";
+            break;
+        }
+    }
+    return ret;
+}
+
+ICheckLib::ICheckLib()
+: pParseManager(0)
+{
+}
+
+void ICheckLib::ParseHeader(const QStringList& includePath, const QStringList& filelist)
+{
+    if(pParseManager)
+        delete pParseManager;
+    pParseManager = 0;
+    pParseManager = new CPlusPlus::ParseManager();
+    pParseManager->setIncludePath(includePath);
+    pParseManager->parse(filelist);
+}
+
+bool ICheckLib::check(const ICheckLib& ichecklib /*ICheckLib from interface header*/)
+{
+    if(pParseManager){
+        CPlusPlus::ParseManager* cpparsemanager = ichecklib.pParseManager;
+        return pParseManager->checkAllMetadatas(cpparsemanager);
+    }
+    return false;
+}
+
+QStringList ICheckLib::getErrorMsg()
+{
+    QStringList ret;
+    if(pParseManager){
+        ret.append(pParseManager->getErrorMsg());
+    }
+    else
+        ret << "no file was parsed.";
+    return ret;
+}
diff --git a/tests/auto/icheckbuild/ichecklib.h b/tests/auto/icheckbuild/ichecklib.h
new file mode 100644
index 00000000000..ed433fdc57b
--- /dev/null
+++ b/tests/auto/icheckbuild/ichecklib.h
@@ -0,0 +1,20 @@
+#ifndef ICHECKLIB_H
+#define ICHECKLIB_H
+
+#include <QStringList>
+#include "ichecklib_global.h"
+
+namespace CPlusPlus{
+    class ParseManager;
+}
+class ICHECKLIBSHARED_EXPORT ICheckLib {
+public:
+    ICheckLib();
+    void ParseHeader(const QStringList& includePath, const QStringList& filelist);
+    bool check(const ICheckLib& ichecklib /*ICheckLib from interface header*/);
+    QStringList getErrorMsg();
+private:
+    CPlusPlus::ParseManager* pParseManager;
+};
+
+#endif // ICHECKLIB_H
diff --git a/tests/auto/icheckbuild/ichecklib.pri b/tests/auto/icheckbuild/ichecklib.pri
new file mode 100644
index 00000000000..e20a2e04f3d
--- /dev/null
+++ b/tests/auto/icheckbuild/ichecklib.pri
@@ -0,0 +1,114 @@
+# ----------------------------------------------------
+# This file is generated by the Qt Visual Studio Add-in.
+# ------------------------------------------------------
+HEADERS += $$REL_PATH_TO_SRC/shared/cplusplus/Array.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/AST.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/ASTMatcher.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/ASTVisitor.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/CheckDeclaration.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/CheckDeclarator.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/CheckExpression.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/CheckName.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/CheckSpecifier.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/CheckStatement.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/Control.h \
+    $$REL_PATH_TO_SRC/plugins/coreplugin/core_global.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/CoreTypes.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/CPlusPlusForwardDeclarations.h \
+    $$REL_PATH_TO_SRC/libs/cplusplus/CppBindings.h \
+    $$REL_PATH_TO_SRC/libs/cplusplus/CppDocument.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/DiagnosticClient.h \
+    $$REL_PATH_TO_SRC/libs/cplusplus/FastPreprocessor.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/FullySpecifiedType.h \
+    $$REL_PATH_TO_SRC/libs/cplusplus/CheckUndefinedSymbols.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/ASTfwd.h \
+    $$REL_PATH_TO_SRC/libs/cplusplus/LookupContext.h \
+    $$REL_PATH_TO_SRC/libs/cplusplus/ResolveExpression.h \
+    $$REL_PATH_TO_SRC/libs/cplusplus/GenTemplateInstance.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/Lexer.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/Literals.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/LiteralTable.h \
+    $$REL_PATH_TO_SRC/libs/cplusplus/Macro.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/MemoryPool.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/Name.h \
+    $$REL_PATH_TO_SRC/libs/cplusplus/NamePrettyPrinter.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/Names.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/NameVisitor.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/ObjectiveCTypeQualifiers.h \
+    $$REL_PATH_TO_SRC/libs/cplusplus/Overview.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/Parser.h \
+    $$REL_PATH_TO_SRC/libs/cplusplus/pp-cctype.h \
+    $$REL_PATH_TO_SRC/libs/cplusplus/pp-engine.h \
+    $$REL_PATH_TO_SRC/libs/cplusplus/pp-macro-expander.h \
+    $$REL_PATH_TO_SRC/libs/cplusplus/pp-scanner.h \
+    $$REL_PATH_TO_SRC/libs/cplusplus/pp.h \
+    $$REL_PATH_TO_SRC/libs/cplusplus/PreprocessorClient.h \
+    $$REL_PATH_TO_SRC/libs/cplusplus/PreprocessorEnvironment.h \
+    $$REL_PATH_TO_SRC/libs/utils/qtcassert.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/Scope.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/Semantic.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/SemanticCheck.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/Symbol.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/Symbols.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/SymbolVisitor.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/Token.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/TranslationUnit.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/Type.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/TypeMatcher.h \
+    $$REL_PATH_TO_SRC/libs/cplusplus/TypePrettyPrinter.h \
+    $$REL_PATH_TO_SRC/shared/cplusplus/TypeVisitor.h
+SOURCES += $$REL_PATH_TO_SRC/shared/cplusplus/Array.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/AST.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/ASTMatch0.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/ASTMatcher.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/ASTVisit.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/ASTVisitor.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/CheckDeclaration.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/CheckDeclarator.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/CheckExpression.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/CheckName.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/CheckSpecifier.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/CheckStatement.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/Control.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/CoreTypes.cpp \
+    $$REL_PATH_TO_SRC/libs/cplusplus/CppBindings.cpp \
+    $$REL_PATH_TO_SRC/libs/cplusplus/CppDocument.cpp \
+    $$REL_PATH_TO_SRC/plugins/cpptools/cppmodelmanager.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/DiagnosticClient.cpp \
+    $$REL_PATH_TO_SRC/libs/cplusplus/FastPreprocessor.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/FullySpecifiedType.cpp \
+    $$REL_PATH_TO_SRC/libs/cplusplus/CheckUndefinedSymbols.cpp \
+    $$REL_PATH_TO_SRC/libs/cplusplus/LookupContext.cpp \
+    $$REL_PATH_TO_SRC/libs/cplusplus/ResolveExpression.cpp \
+    $$REL_PATH_TO_SRC/libs/cplusplus/GenTemplateInstance.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/Keywords.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/Lexer.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/Literals.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/LiteralTable.cpp \
+    $$REL_PATH_TO_SRC/libs/cplusplus/Macro.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/MemoryPool.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/Name.cpp \
+    $$REL_PATH_TO_SRC/libs/cplusplus/NamePrettyPrinter.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/Names.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/NameVisitor.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/ObjectiveCAtKeywords.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/ObjectiveCTypeQualifiers.cpp \
+    $$REL_PATH_TO_SRC/libs/cplusplus/Overview.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/Parser.cpp \
+    $$REL_PATH_TO_SRC/libs/cplusplus/pp-engine.cpp \
+    $$REL_PATH_TO_SRC/libs/cplusplus/pp-macro-expander.cpp \
+    $$REL_PATH_TO_SRC/libs/cplusplus/pp-scanner.cpp \
+    $$REL_PATH_TO_SRC/libs/cplusplus/PreprocessorClient.cpp \
+    $$REL_PATH_TO_SRC/libs/cplusplus/PreprocessorEnvironment.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/Scope.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/Semantic.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/SemanticCheck.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/Symbol.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/Symbols.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/SymbolVisitor.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/Token.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/TranslationUnit.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/Type.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/TypeMatcher.cpp \
+    $$REL_PATH_TO_SRC/libs/cplusplus/TypePrettyPrinter.cpp \
+    $$REL_PATH_TO_SRC/shared/cplusplus/TypeVisitor.cpp
diff --git a/tests/auto/icheckbuild/ichecklib_global.h b/tests/auto/icheckbuild/ichecklib_global.h
new file mode 100644
index 00000000000..cf2bbdc7f37
--- /dev/null
+++ b/tests/auto/icheckbuild/ichecklib_global.h
@@ -0,0 +1,17 @@
+#ifndef ICHECKLIB_GLOBAL_H
+#define ICHECKLIB_GLOBAL_H
+
+#include <QtCore/qglobal.h>
+
+
+#ifdef ICHECK_APP_BUILD
+#  define ICHECKLIBSHARED_EXPORT
+#else
+#  if defined(ICHECKLIB_LIBRARY)
+#    define ICHECKLIBSHARED_EXPORT Q_DECL_EXPORT
+#  else
+#    define ICHECKLIBSHARED_EXPORT Q_DECL_IMPORT
+#  endif
+#endif
+
+#endif // ICHECKLIB_GLOBAL_H
diff --git a/tests/auto/icheckbuild/tst_icheckbuild.cpp b/tests/auto/icheckbuild/tst_icheckbuild.cpp
new file mode 100644
index 00000000000..826265839e7
--- /dev/null
+++ b/tests/auto/icheckbuild/tst_icheckbuild.cpp
@@ -0,0 +1,49 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include <QtTest/QtTest>
+#include "ichecklib.h"
+#include <QDebug>
+
+class tst_icheckbuild : public QObject
+{
+    Q_OBJECT
+
+private slots:
+    void doTests();
+};
+
+void tst_icheckbuild::doTests()
+{
+    qDebug() << "icheck build was successful";
+}
+
+QTEST_MAIN(tst_icheckbuild)
+
+#include "tst_icheckbuild.moc"
-- 
GitLab