summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRenato Filho <renato.filho@openbossa.org>2010-09-01 13:35:40 -0300
committerHugo Parente Lima <hugo.pl@gmail.com>2012-03-09 19:10:09 -0300
commit2d170a0b8b1519befc4cdad57a0a46ccf8d16e0a (patch)
treebd7b63fd5bc1385412f4dea1f3a10cd5a17f599a
parent869b35c10ef573771532c6f2cb017dbfab315e61 (diff)
Fixed function modification propagation.
Now all modifications on base function will be propagate until a new modification was found. Reviewer: Hugo Parente Lima <hugo.pl@gmail.com> Lauro Moura <lauro.neto@openbossa.org>
-rw-r--r--abstractmetalang.cpp5
-rw-r--r--tests/testmodifyfunction.cpp86
-rw-r--r--tests/testmodifyfunction.h1
-rw-r--r--typesystem.cpp31
-rw-r--r--typesystem.h4
5 files changed, 125 insertions, 2 deletions
diff --git a/abstractmetalang.cpp b/abstractmetalang.cpp
index fe6c6b37..da48a315 100644
--- a/abstractmetalang.cpp
+++ b/abstractmetalang.cpp
@@ -690,8 +690,9 @@ FunctionModificationList AbstractMetaFunction::modifications(const AbstractMetaC
FunctionModificationList mods;
while (implementor) {
mods += implementor->typeEntry()->functionModifications(minimalSignature());
- if (implementor == implementor->baseClass() || implementor == implementingClass())
- break;
+ if ((implementor == implementor->baseClass()) ||
+ (implementor == implementingClass() && (mods.size() > 0)))
+ break;
implementor = implementor->baseClass();
}
return mods;
diff --git a/tests/testmodifyfunction.cpp b/tests/testmodifyfunction.cpp
index 95ba16f4..3f92e3e1 100644
--- a/tests/testmodifyfunction.cpp
+++ b/tests/testmodifyfunction.cpp
@@ -79,6 +79,92 @@ void TestModifyFunction::testOwnershipTransfer()
QCOMPARE(func->ownership(func->ownerClass(), TypeSystem::TargetLangCode, 0), TypeSystem::CppOwnership);
}
+
+void TestModifyFunction::invalidateAfterUse()
+{
+ const char* cppCode ="\
+ struct A {\
+ virtual void call(int *a);\
+ };\
+ struct B : A {\
+ };\
+ struct C : B {\
+ virtual void call2(int *a);\
+ };\
+ struct D : C {\
+ virtual void call2(int *a);\
+ };\
+ struct E : D {\
+ };\
+ ";
+ const char* xmlCode = "\
+ <typesystem package='Foo'> \
+ <primitive-type name='int'/>\
+ <object-type name='A'> \
+ <modify-function signature='call(int*)'>\
+ <modify-argument index='1' invalidate-after-use='true'/>\
+ </modify-function>\
+ </object-type>\
+ <object-type name='B' /> \
+ <object-type name='C'> \
+ <modify-function signature='call2(int*)'>\
+ <modify-argument index='1' invalidate-after-use='true'/>\
+ </modify-function>\
+ </object-type>\
+ <object-type name='D'> \
+ <modify-function signature='call2(int*)'>\
+ <modify-argument index='1' invalidate-after-use='true'/>\
+ </modify-function>\
+ </object-type>\
+ <object-type name='E' /> \
+ </typesystem>";
+ TestUtil t(cppCode, xmlCode, false, 0.1);
+ AbstractMetaClassList classes = t.builder()->classes();
+ AbstractMetaClass* classB = classes.findClass("B");
+ const AbstractMetaFunction* func = classB->findFunction("call");
+ QCOMPARE(func->modifications().size(), 1);
+ QCOMPARE(func->modifications().at(0).argument_mods.size(), 1);
+ QVERIFY(func->modifications().at(0).argument_mods.at(0).resetAfterUse);
+
+ AbstractMetaClass* classC = classes.findClass("C");
+ QVERIFY(classC);
+ func = classC->findFunction("call");
+ QCOMPARE(func->modifications().size(), 1);
+ QCOMPARE(func->modifications().at(0).argument_mods.size(), 1);
+ QVERIFY(func->modifications().at(0).argument_mods.at(0).resetAfterUse);
+
+ func = classC->findFunction("call2");
+ QCOMPARE(func->modifications().size(), 1);
+ QCOMPARE(func->modifications().at(0).argument_mods.size(), 1);
+ QVERIFY(func->modifications().at(0).argument_mods.at(0).resetAfterUse);
+
+ AbstractMetaClass* classD = classes.findClass("D");
+ QVERIFY(classD);
+ func = classD->findFunction("call");
+ QCOMPARE(func->modifications().size(), 1);
+ QCOMPARE(func->modifications().at(0).argument_mods.size(), 1);
+ QVERIFY(func->modifications().at(0).argument_mods.at(0).resetAfterUse);
+
+ func = classD->findFunction("call2");
+ QCOMPARE(func->modifications().size(), 1);
+ QCOMPARE(func->modifications().at(0).argument_mods.size(), 1);
+ QVERIFY(func->modifications().at(0).argument_mods.at(0).resetAfterUse);
+
+ AbstractMetaClass* classE = classes.findClass("E");
+ QVERIFY(classE);
+ func = classE->findFunction("call");
+ QVERIFY(func);
+ QCOMPARE(func->modifications().size(), 1);
+ QCOMPARE(func->modifications().at(0).argument_mods.size(), 1);
+ QVERIFY(func->modifications().at(0).argument_mods.at(0).resetAfterUse);
+
+ func = classE->findFunction("call2");
+ QVERIFY(func);
+ QCOMPARE(func->modifications().size(), 1);
+ QCOMPARE(func->modifications().at(0).argument_mods.size(), 1);
+ QVERIFY(func->modifications().at(0).argument_mods.at(0).resetAfterUse);
+}
+
void TestModifyFunction::testWithApiVersion()
{
const char* cppCode ="\
diff --git a/tests/testmodifyfunction.h b/tests/testmodifyfunction.h
index 40adf127..95b7b6a7 100644
--- a/tests/testmodifyfunction.h
+++ b/tests/testmodifyfunction.h
@@ -33,6 +33,7 @@ class TestModifyFunction : public QObject
void testOwnershipTransfer();
void testWithApiVersion();
void testRenameArgument();
+ void invalidateAfterUse();
};
#endif
diff --git a/typesystem.cpp b/typesystem.cpp
index 31c4f547..f92ea01d 100644
--- a/typesystem.cpp
+++ b/typesystem.cpp
@@ -1783,6 +1783,37 @@ QString FunctionModification::toString() const
return str;
}
+bool FunctionModification::operator!=(const FunctionModification& other) const
+{
+ return !(*this == other);
+}
+
+bool FunctionModification::operator==(const FunctionModification& other) const
+{
+ if (signature != other.signature)
+ return false;
+
+ if (association != other.association)
+ return false;
+
+ if (modifiers != other.modifiers)
+ return false;
+
+ if (removal != other.removal)
+ return false;
+
+ if (m_thread != other.m_thread)
+ return false;
+
+ if (m_allowThread != other.m_allowThread)
+ return false;
+
+ if (m_version != other.m_version)
+ return false;
+
+ return true;
+}
+
static AddedFunction::TypeInfo parseType(const QString& signature, int startPos = 0, int* endPos = 0)
{
AddedFunction::TypeInfo result;
diff --git a/typesystem.h b/typesystem.h
index 4a0e6c7c..948479d8 100644
--- a/typesystem.h
+++ b/typesystem.h
@@ -401,6 +401,10 @@ struct APIEXTRACTOR_API FunctionModification: public Modification
return m_version;
}
+ bool operator!=(const FunctionModification& other) const;
+ bool operator==(const FunctionModification& other) const;
+
+
QString toString() const;
QString signature;