diff --git a/cxx-squid/src/main/java/org/sonar/cxx/api/CxxKeyword.java b/cxx-squid/src/main/java/org/sonar/cxx/api/CxxKeyword.java index b12e66a962..4f0897feab 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/api/CxxKeyword.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/api/CxxKeyword.java @@ -91,7 +91,6 @@ public enum CxxKeyword implements TokenType { TRUE("true"), TRY("try"), TYPEDEF("typedef"), - TYPEID("typeid"), TYPENAME("typename"), UNION("union"), UNSIGNED("unsigned"), diff --git a/cxx-squid/src/main/java/org/sonar/cxx/parser/CxxGrammarImpl.java b/cxx-squid/src/main/java/org/sonar/cxx/parser/CxxGrammarImpl.java index e238fb62fa..f0c39088b2 100644 --- a/cxx-squid/src/main/java/org/sonar/cxx/parser/CxxGrammarImpl.java +++ b/cxx-squid/src/main/java/org/sonar/cxx/parser/CxxGrammarImpl.java @@ -471,8 +471,10 @@ private static void expressions(LexerfulGrammarBuilder b) { b.firstOf( b.sequence(simpleTypeSpecifier, "(", b.optional(expressionList), ")"), b.sequence(simpleTypeSpecifier, bracedInitList), + b.sequence(simpleTypeSpecifier, "::", "typeid"), b.sequence(typenameSpecifier, "(", b.optional(expressionList), ")"), b.sequence(typenameSpecifier, bracedInitList), + b.sequence(typenameSpecifier, "::", "typeid"), primaryExpression, @@ -480,8 +482,8 @@ private static void expressions(LexerfulGrammarBuilder b) { b.sequence(CxxKeyword.STATIC_CAST, typeIdEnclosed, "(", expression, ")"), b.sequence(CxxKeyword.REINTERPRET_CAST, typeIdEnclosed, "(", expression, ")"), b.sequence(CxxKeyword.CONST_CAST, typeIdEnclosed, "(", expression, ")"), - b.sequence(CxxKeyword.TYPEID, "(", expression, ")"), - b.sequence(CxxKeyword.TYPEID, "(", typeId, ")") + b.sequence("typeid", "(", expression, ")"), + b.sequence("typeid", "(", typeId, ")") ), // postfixExpression [ expression ] diff --git a/cxx-squid/src/test/java/org/sonar/cxx/api/CxxKeywordTest.java b/cxx-squid/src/test/java/org/sonar/cxx/api/CxxKeywordTest.java index 08a5237374..ad23b9c966 100644 --- a/cxx-squid/src/test/java/org/sonar/cxx/api/CxxKeywordTest.java +++ b/cxx-squid/src/test/java/org/sonar/cxx/api/CxxKeywordTest.java @@ -27,7 +27,7 @@ public class CxxKeywordTest { @Test public void test() { - assertThat(CxxKeyword.values()).hasSize(87); + assertThat(CxxKeyword.values()).hasSize(86); assertThat(CxxKeyword.keywordValues()).hasSize(CxxKeyword.values().length); } diff --git a/cxx-squid/src/test/java/org/sonar/cxx/parser/ExpressionTest.java b/cxx-squid/src/test/java/org/sonar/cxx/parser/ExpressionTest.java index c45a7d4c2b..ab18874a6c 100644 --- a/cxx-squid/src/test/java/org/sonar/cxx/parser/ExpressionTest.java +++ b/cxx-squid/src/test/java/org/sonar/cxx/parser/ExpressionTest.java @@ -171,6 +171,10 @@ public void postfixExpression() { assertThat(p).matches("const_cast < typeId > ( expression )"); assertThat(p).matches("typeid ( expression )"); assertThat(p).matches("typeid ( typeId )"); + + assertThat(p).matches("simpleTypeSpecifier :: typeid"); + assertThat(p).matches("typenameSpecifier :: typeid"); + } @Test @@ -182,6 +186,9 @@ public void postfixExpression_reallife() { assertThat(p).matches("dynamic_cast(myop)->op()"); assertThat(p).matches("::foo()"); assertThat(p).matches("obj.foo()"); + + assertThat(p).matches("G::typeid"); + assertThat(p).matches("int::typeid"); } @Test diff --git a/cxx-squid/src/test/resources/parser/cli/typeid/keyword__typeid.cpp b/cxx-squid/src/test/resources/parser/cli/typeid/keyword__typeid.cpp new file mode 100644 index 0000000000..c5f340ca42 --- /dev/null +++ b/cxx-squid/src/test/resources/parser/cli/typeid/keyword__typeid.cpp @@ -0,0 +1,20 @@ +// keyword__typeid.cpp +// compile with: /clr +using namespace System; + +ref struct G { + int i; +}; + +int main() { + G ^ pG = gcnew G; + Type ^ pType = pG->GetType(); + Type ^ pType2 = G::typeid; + + if (pType == pType2) + Console::WriteLine("typeid and GetType returned the same System::Type"); + Console::WriteLine(G::typeid); + + typedef float* FloatPtr; + Console::WriteLine(FloatPtr::typeid); +} diff --git a/cxx-squid/src/test/resources/parser/cli/typeid/keyword__typeid_2.cpp b/cxx-squid/src/test/resources/parser/cli/typeid/keyword__typeid_2.cpp new file mode 100644 index 0000000000..f03cd6fb64 --- /dev/null +++ b/cxx-squid/src/test/resources/parser/cli/typeid/keyword__typeid_2.cpp @@ -0,0 +1,49 @@ +// keyword__typeid_2.cpp +// compile with: /clr +using namespace System; +using namespace System::Security; +using namespace System::Security::Permissions; + +typedef int ^ handle_to_int; +typedef int * pointer_to_int; + +public ref class MyClass {}; + +class MyClass2 {}; + +[attribute(AttributeTargets::All)] +ref class AtClass { +public: + AtClass(Type ^) { + Console::WriteLine("in AtClass Type ^ constructor"); + } +}; + +[attribute(AttributeTargets::All)] +ref class AtClass2 { +public: + AtClass2() { + Console::WriteLine("in AtClass2 constructor"); + } +}; + +// Apply the AtClass and AtClass2 attributes to class B +[AtClass(MyClass::typeid), AtClass2] +[AttributeUsage(AttributeTargets::All)] +ref class B : Attribute {}; + +int main() { + Type ^ MyType = B::typeid; + + Console::WriteLine(MyType->IsClass); + + array^ MyArray = MyType->GetCustomAttributes(true); + for (int i = 0; i < MyArray->Length; i++) + Console::WriteLine(MyArray[i]); + + if (int::typeid != pointer_to_int::typeid) + Console::WriteLine("int::typeid != pointer_to_int::typeid, as expected"); + + if (int::typeid == handle_to_int::typeid) + Console::WriteLine("int::typeid == handle_to_int::typeid, as expected"); +} \ No newline at end of file