Skip to content

Commit cbe0fb0

Browse files
authored
Merge pull request #8621 from diffblue/ansi-c-conditional-keyword
ansi-c: introduce `conditional_keyword(c, t)`
2 parents 854e013 + ce7029f commit cbe0fb0

File tree

1 file changed

+109
-117
lines changed

1 file changed

+109
-117
lines changed

src/ansi-c/scanner.l

+109-117
Original file line numberDiff line numberDiff line change
@@ -149,26 +149,17 @@ int MSC_Keyword(int token)
149149
return make_identifier();
150150
}
151151

152-
int cpp98_keyword(int token)
152+
/// Exits the scanner with the current yytext. If the condition holds,
153+
/// yytext is returned as keyword, and otherwise as an identifier.
154+
int conditional_keyword(bool condition, int token)
153155
{
154-
if(PARSER.cpp98)
156+
if(condition)
155157
{
156158
loc();
157159
return token;
158160
}
159161
else
160-
return make_identifier();
161-
}
162-
163-
int cpp11_keyword(int token)
164-
{
165-
if(PARSER.cpp11)
166-
{
167-
loc();
168-
return token;
169-
}
170-
else
171-
return make_identifier();
162+
return make_identifier();
172163
}
173164

174165
int c17_keyword(int token)
@@ -865,75 +856,73 @@ enable_or_disable ("enable"|"disable")
865856
/* C++ Keywords and Operators */
866857
%}
867858

868-
alignas { return cpp11_keyword(TOK_ALIGNAS); } // C++11
869-
alignof { return cpp11_keyword(TOK_ALIGNOF); } // C++11
870-
and { return cpp98_keyword(TOK_ANDAND); }
871-
and_eq { return cpp98_keyword(TOK_ANDASSIGN); }
872-
bool { return cpp98_keyword(TOK_BOOL); }
873-
catch { return cpp98_keyword(TOK_CATCH); }
859+
alignas { return conditional_keyword(PARSER.cpp11, TOK_ALIGNAS); } // C++11
860+
alignof { return conditional_keyword(PARSER.cpp11, TOK_ALIGNOF); } // C++11
861+
and { return conditional_keyword(PARSER.cpp98, TOK_ANDAND); }
862+
and_eq { return conditional_keyword(PARSER.cpp98, TOK_ANDASSIGN); }
863+
bool { return conditional_keyword(PARSER.cpp98, TOK_BOOL); }
864+
catch { return conditional_keyword(PARSER.cpp98, TOK_CATCH); }
874865
char16_t { // C++11, but Visual Studio uses typedefs
875-
if(PARSER.mode == configt::ansi_ct::flavourt::VISUAL_STUDIO)
876-
return make_identifier();
877-
else
878-
return cpp11_keyword(TOK_CHAR16_T);
866+
return conditional_keyword(
867+
PARSER.cpp11 &&
868+
PARSER.mode != configt::ansi_ct::flavourt::VISUAL_STUDIO,
869+
TOK_CHAR16_T);
879870
}
880871
char32_t { // C++11, but Visual Studio uses typedefs
881-
if(PARSER.mode == configt::ansi_ct::flavourt::VISUAL_STUDIO)
882-
return make_identifier();
883-
else
884-
return cpp11_keyword(TOK_CHAR32_T);
872+
return conditional_keyword(
873+
PARSER.cpp11 &&
874+
PARSER.mode != configt::ansi_ct::flavourt::VISUAL_STUDIO,
875+
TOK_CHAR32_T);
885876
}
886-
class { return cpp98_keyword(TOK_CLASS); }
887-
compl { return cpp98_keyword('~'); }
888-
constexpr { return cpp11_keyword(TOK_CONSTEXPR); } // C++11
889-
delete { return cpp98_keyword(TOK_DELETE); }
890-
decltype { return cpp11_keyword(TOK_DECLTYPE); } // C++11
891-
explicit { return cpp98_keyword(TOK_EXPLICIT); }
892-
false { return cpp98_keyword(TOK_FALSE); }
893-
friend { return cpp98_keyword(TOK_FRIEND); }
894-
mutable { return cpp98_keyword(TOK_MUTABLE); }
895-
namespace { return cpp98_keyword(TOK_NAMESPACE); }
896-
new { return cpp98_keyword(TOK_NEW); }
897-
nodiscard { return cpp11_keyword(TOK_NODISCARD); } // C++11
898-
noexcept { return cpp11_keyword(TOK_NOEXCEPT); } // C++11
899-
noreturn { return cpp11_keyword(TOK_NORETURN); } // C++11
900-
not { return cpp98_keyword('!'); }
901-
not_eq { return cpp98_keyword(TOK_NE); }
902-
nullptr { return cpp11_keyword(TOK_NULLPTR); } // C++11
903-
operator { return cpp98_keyword(TOK_OPERATOR); }
904-
or { return cpp98_keyword(TOK_OROR); }
905-
or_eq { return cpp98_keyword(TOK_ORASSIGN); }
906-
private { return cpp98_keyword(TOK_PRIVATE); }
907-
protected { return cpp98_keyword(TOK_PROTECTED); }
908-
public { return cpp98_keyword(TOK_PUBLIC); }
877+
class { return conditional_keyword(PARSER.cpp98, TOK_CLASS); }
878+
compl { return conditional_keyword(PARSER.cpp98, '~'); }
879+
constexpr { return conditional_keyword(PARSER.cpp11, TOK_CONSTEXPR); } // C++11
880+
delete { return conditional_keyword(PARSER.cpp98, TOK_DELETE); }
881+
decltype { return conditional_keyword(PARSER.cpp11, TOK_DECLTYPE); } // C++11
882+
explicit { return conditional_keyword(PARSER.cpp98, TOK_EXPLICIT); }
883+
false { return conditional_keyword(PARSER.cpp98, TOK_FALSE); }
884+
friend { return conditional_keyword(PARSER.cpp98, TOK_FRIEND); }
885+
mutable { return conditional_keyword(PARSER.cpp98, TOK_MUTABLE); }
886+
namespace { return conditional_keyword(PARSER.cpp98, TOK_NAMESPACE); }
887+
new { return conditional_keyword(PARSER.cpp98, TOK_NEW); }
888+
nodiscard { return conditional_keyword(PARSER.cpp11, TOK_NODISCARD); } // C++11
889+
noexcept { return conditional_keyword(PARSER.cpp11, TOK_NOEXCEPT); } // C++11
890+
noreturn { return conditional_keyword(PARSER.cpp11, TOK_NORETURN); } // C++11
891+
not { return conditional_keyword(PARSER.cpp98, '!'); }
892+
not_eq { return conditional_keyword(PARSER.cpp98, TOK_NE); }
893+
nullptr { return conditional_keyword(PARSER.cpp11, TOK_NULLPTR); } // C++11
894+
operator { return conditional_keyword(PARSER.cpp98, TOK_OPERATOR); }
895+
or { return conditional_keyword(PARSER.cpp98, TOK_OROR); }
896+
or_eq { return conditional_keyword(PARSER.cpp98, TOK_ORASSIGN); }
897+
private { return conditional_keyword(PARSER.cpp98, TOK_PRIVATE); }
898+
protected { return conditional_keyword(PARSER.cpp98, TOK_PROTECTED); }
899+
public { return conditional_keyword(PARSER.cpp98, TOK_PUBLIC); }
909900
static_assert { // C++11, but Visual Studio supports it in all modes
910901
// as a keyword, even though the documentation claims
911902
// it's a macro.
912-
if(PARSER.mode == configt::ansi_ct::flavourt::VISUAL_STUDIO)
913-
{
914-
loc(); return TOK_STATIC_ASSERT;
915-
}
916-
else
917-
return cpp11_keyword(TOK_STATIC_ASSERT);
903+
return conditional_keyword(
904+
PARSER.cpp11 ||
905+
PARSER.mode == configt::ansi_ct::flavourt::VISUAL_STUDIO,
906+
TOK_STATIC_ASSERT);
918907
}
919-
template { return cpp98_keyword(TOK_TEMPLATE); }
920-
this { return cpp98_keyword(TOK_THIS); }
921-
thread_local { return cpp11_keyword(TOK_THREAD_LOCAL); } // C++11
922-
throw { return cpp98_keyword(TOK_THROW); }
923-
true { return cpp98_keyword(TOK_TRUE); }
924-
typeid { return cpp98_keyword(TOK_TYPEID); }
925-
typename { return cpp98_keyword(TOK_TYPENAME); }
926-
using { return cpp98_keyword(TOK_USING); }
927-
virtual { return cpp98_keyword(TOK_VIRTUAL); }
908+
template { return conditional_keyword(PARSER.cpp98, TOK_TEMPLATE); }
909+
this { return conditional_keyword(PARSER.cpp98, TOK_THIS); }
910+
thread_local { return conditional_keyword(PARSER.cpp11, TOK_THREAD_LOCAL); } // C++11
911+
throw { return conditional_keyword(PARSER.cpp98, TOK_THROW); }
912+
true { return conditional_keyword(PARSER.cpp98, TOK_TRUE); }
913+
typeid { return conditional_keyword(PARSER.cpp98, TOK_TYPEID); }
914+
typename { return conditional_keyword(PARSER.cpp98, TOK_TYPENAME); }
915+
using { return conditional_keyword(PARSER.cpp98, TOK_USING); }
916+
virtual { return conditional_keyword(PARSER.cpp98, TOK_VIRTUAL); }
928917
wchar_t { // CodeWarrior doesn't have wchar_t built in,
929918
// and MSC has a command-line option to turn it off
930-
if(PARSER.mode==configt::ansi_ct::flavourt::CODEWARRIOR)
931-
return make_identifier();
932-
else
933-
return cpp98_keyword(TOK_WCHAR_T);
919+
return conditional_keyword(
920+
PARSER.cpp98 &&
921+
PARSER.mode!=configt::ansi_ct::flavourt::CODEWARRIOR,
922+
TOK_WCHAR_T);
934923
}
935-
xor { return cpp98_keyword('^'); }
936-
xor_eq { return cpp98_keyword(TOK_XORASSIGN); }
924+
xor { return conditional_keyword(PARSER.cpp98, '^'); }
925+
xor_eq { return conditional_keyword(PARSER.cpp98, TOK_XORASSIGN); }
937926
".*" { return cpp_operator(TOK_DOTPM); }
938927
"->*" { return cpp_operator(TOK_ARROWPM); }
939928
"::" { if(PARSER.cpp98)
@@ -947,12 +936,11 @@ xor_eq { return cpp98_keyword(TOK_XORASSIGN); }
947936
}
948937
}
949938

950-
__decltype { if(PARSER.cpp98 &&
951-
(PARSER.mode==configt::ansi_ct::flavourt::GCC ||
952-
PARSER.mode==configt::ansi_ct::flavourt::CLANG))
953-
return cpp98_keyword(TOK_DECLTYPE);
954-
else
955-
return make_identifier();
939+
__decltype { return conditional_keyword(
940+
PARSER.cpp98 &&
941+
(PARSER.mode==configt::ansi_ct::flavourt::GCC ||
942+
PARSER.mode==configt::ansi_ct::flavourt::CLANG),
943+
TOK_DECLTYPE);
956944
}
957945

958946
%{
@@ -965,35 +953,35 @@ __decltype { if(PARSER.cpp98 &&
965953
"__has_assign" { loc(); return MSC_cpp_keyword(TOK_UNARY_TYPE_PREDICATE); }
966954
"__has_copy" { loc(); return MSC_cpp_keyword(TOK_UNARY_TYPE_PREDICATE); }
967955
"__has_finalizer" { loc(); return MSC_cpp_keyword(TOK_UNARY_TYPE_PREDICATE); }
968-
"__has_nothrow_assign" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
969-
"__has_nothrow_constructor" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
970-
"__has_nothrow_copy" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
971-
"__has_trivial_assign" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
972-
"__has_trivial_constructor" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
973-
"__has_trivial_copy" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
974-
"__has_trivial_destructor" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
956+
"__has_nothrow_assign" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
957+
"__has_nothrow_constructor" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
958+
"__has_nothrow_copy" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
959+
"__has_trivial_assign" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
960+
"__has_trivial_constructor" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
961+
"__has_trivial_copy" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
962+
"__has_trivial_destructor" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
975963
"__has_user_destructor" { loc(); return MSC_cpp_keyword(TOK_UNARY_TYPE_PREDICATE); }
976-
"__has_virtual_destructor" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
977-
"__is_abstract" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
978-
"__is_base_of" { loc(); return cpp98_keyword(TOK_BINARY_TYPE_PREDICATE); }
979-
"__is_class" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
980-
"__is_convertible_to" { loc(); return cpp98_keyword(TOK_BINARY_TYPE_PREDICATE); }
964+
"__has_virtual_destructor" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
965+
"__is_abstract" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
966+
"__is_base_of" { loc(); return conditional_keyword(PARSER.cpp98, TOK_BINARY_TYPE_PREDICATE); }
967+
"__is_class" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
968+
"__is_convertible_to" { loc(); return conditional_keyword(PARSER.cpp98, TOK_BINARY_TYPE_PREDICATE); }
981969
"__is_delegate" { loc(); return MSC_cpp_keyword(TOK_UNARY_TYPE_PREDICATE); }
982-
"__is_empty" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
983-
"__is_enum" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
984-
"__is_interface_class" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
985-
"__is_pod" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
986-
"__is_polymorphic" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
970+
"__is_empty" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
971+
"__is_enum" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
972+
"__is_interface_class" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
973+
"__is_pod" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
974+
"__is_polymorphic" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
987975
"__is_ref_array" { loc(); return MSC_cpp_keyword(TOK_UNARY_TYPE_PREDICATE); }
988976
"__is_ref_class" { loc(); return MSC_cpp_keyword(TOK_UNARY_TYPE_PREDICATE); }
989977
"__is_sealed" { loc(); return MSC_cpp_keyword(TOK_UNARY_TYPE_PREDICATE); }
990978
"__is_simple_value_class" { loc(); return MSC_cpp_keyword(TOK_UNARY_TYPE_PREDICATE); }
991-
"__is_union" { loc(); return cpp98_keyword(TOK_UNARY_TYPE_PREDICATE); }
979+
"__is_union" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNARY_TYPE_PREDICATE); }
992980
"__is_value_class" { loc(); return MSC_cpp_keyword(TOK_UNARY_TYPE_PREDICATE); }
993981

994982
"__if_exists" { loc(); return MSC_cpp_keyword(TOK_MSC_IF_EXISTS); }
995983
"__if_not_exists" { loc(); return MSC_cpp_keyword(TOK_MSC_IF_NOT_EXISTS); }
996-
"__underlying_type" { loc(); return cpp98_keyword(TOK_UNDERLYING_TYPE); }
984+
"__underlying_type" { loc(); return conditional_keyword(PARSER.cpp98, TOK_UNDERLYING_TYPE); }
997985

998986
"["{ws}"repeatable" |
999987
"["{ws}"source_annotation_attribute" |
@@ -1016,32 +1004,36 @@ __decltype { if(PARSER.cpp98 &&
10161004
}
10171005
}
10181006

1019-
"__char16_t" { if(PARSER.mode==configt::ansi_ct::flavourt::GCC ||
1020-
PARSER.mode==configt::ansi_ct::flavourt::CLANG)
1021-
return cpp98_keyword(TOK_CHAR16_T); // GNU extension
1022-
else
1023-
return make_identifier();
1007+
"__char16_t" { // GNU extension
1008+
return conditional_keyword(
1009+
PARSER.cpp98 &&
1010+
(PARSER.mode==configt::ansi_ct::flavourt::GCC ||
1011+
PARSER.mode==configt::ansi_ct::flavourt::CLANG),
1012+
TOK_CHAR16_T);
10241013
}
10251014

1026-
"__nullptr" { if(PARSER.mode==configt::ansi_ct::flavourt::GCC ||
1027-
PARSER.mode==configt::ansi_ct::flavourt::CLANG)
1028-
return cpp98_keyword(TOK_NULLPTR); // GNU extension
1029-
else
1030-
return make_identifier();
1015+
"__nullptr" { // GNU extension
1016+
return conditional_keyword(
1017+
PARSER.cpp98 &&
1018+
(PARSER.mode==configt::ansi_ct::flavourt::GCC ||
1019+
PARSER.mode==configt::ansi_ct::flavourt::CLANG),
1020+
TOK_NULLPTR);
10311021
}
10321022

1033-
"__null" { if(PARSER.mode==configt::ansi_ct::flavourt::GCC ||
1034-
PARSER.mode==configt::ansi_ct::flavourt::CLANG)
1035-
return cpp98_keyword(TOK_NULLPTR); // GNU extension
1036-
else
1037-
return make_identifier();
1023+
"__null" { // GNU extension
1024+
return conditional_keyword(
1025+
PARSER.cpp98 &&
1026+
(PARSER.mode==configt::ansi_ct::flavourt::GCC ||
1027+
PARSER.mode==configt::ansi_ct::flavourt::CLANG),
1028+
TOK_NULLPTR);
10381029
}
10391030

1040-
"__char32_t" { if(PARSER.mode==configt::ansi_ct::flavourt::GCC ||
1041-
PARSER.mode==configt::ansi_ct::flavourt::CLANG)
1042-
return cpp98_keyword(TOK_CHAR32_T); // GNU extension
1043-
else
1044-
return make_identifier();
1031+
"__char32_t" { // GNU extension
1032+
return conditional_keyword(
1033+
PARSER.cpp98 &&
1034+
(PARSER.mode==configt::ansi_ct::flavourt::GCC ||
1035+
PARSER.mode==configt::ansi_ct::flavourt::CLANG),
1036+
TOK_CHAR32_T);
10451037
}
10461038

10471039
"__declspec" |

0 commit comments

Comments
 (0)