|
28 | 28 | #include "settings.h" |
29 | 29 | #include "standards.h" |
30 | 30 | #include "suppressions.h" |
31 | | -#include "token.h" |
32 | 31 | #include "utils.h" |
33 | 32 |
|
34 | 33 | #include <algorithm> |
@@ -902,123 +901,40 @@ simplecpp::TokenList Preprocessor::preprocess(const std::string &cfgStr, std::ve |
902 | 901 | return tokens2; |
903 | 902 | } |
904 | 903 |
|
905 | | -static const simplecpp::Token* qtPropertyAttributes(const simplecpp::Token* tok) |
906 | | -{ |
907 | | - while (tok && (tok->str() == "const" || tok->str() == "volatile")) |
908 | | - tok = tok->next; |
909 | | - if (!tok) |
910 | | - return nullptr; |
911 | | - if (Token::isStandardType(tok->str())) { |
912 | | - do { |
913 | | - tok = tok->next; |
914 | | - } while (tok && Token::isStandardType(tok->str())); |
915 | | - } else { |
916 | | - if (tok->str() == "::") |
917 | | - tok = tok->next; |
918 | | - if (!tok || !tok->name) |
919 | | - return nullptr; |
920 | | - for (;;) { |
921 | | - tok = tok->next; |
922 | | - if (tok && tok->str() == "<") { |
923 | | - unsigned int depth = 1; |
924 | | - unsigned int parentheses = 0; |
925 | | - do { |
926 | | - tok = tok->next; |
927 | | - if (!tok) |
928 | | - return nullptr; |
929 | | - if (tok->str() == "(") |
930 | | - ++parentheses; |
931 | | - else if (tok->str() == ")" && parentheses) |
932 | | - --parentheses; |
933 | | - else if (!parentheses) { |
934 | | - if (tok->str() == "<") |
935 | | - ++depth; |
936 | | - else if (tok->str() == ">") |
937 | | - --depth; |
938 | | - else if (tok->str() == ">>") { |
939 | | - if (depth < 2) |
940 | | - return nullptr; |
941 | | - depth -= 2; |
942 | | - } |
943 | | - } |
944 | | - } while (depth); |
945 | | - tok = tok->next; |
946 | | - } |
947 | | - if (!tok || tok->str() != "::" || !tok->next || !tok->next->name) |
948 | | - break; |
949 | | - tok = tok->next; |
950 | | - } |
951 | | - } |
952 | | - while (tok && (tok->str() == "*" || tok->str() == "&" || tok->str() == "&&" || |
953 | | - tok->str() == "const" || tok->str() == "volatile")) |
954 | | - tok = tok->next; |
955 | | - // The property name is not a function reference. |
956 | | - return tok && tok->name ? tok->next : nullptr; |
957 | | -} |
958 | | - |
959 | | -static std::set<std::string> qtPropertyFunctions(const simplecpp::Token* tok, const Library& library) |
| 904 | +static std::set<std::string> exporterFunctions(const simplecpp::Token* tok, const std::string& exporter, const Library& library) |
960 | 905 | { |
| 906 | + // Match configured exporter keywords without parsing library-specific grammar. |
961 | 907 | std::set<std::string> functions; |
962 | | - tok = qtPropertyAttributes(tok); |
963 | | - while (tok && tok->str() != ")") { |
964 | | - const std::string& attribute = tok->str(); |
965 | | - tok = tok->next; |
966 | | - if (attribute == "CONSTANT" || attribute == "FINAL" || attribute == "REQUIRED" || |
967 | | - attribute == "VIRTUAL" || attribute == "OVERRIDE") |
968 | | - continue; |
969 | | - if (!tok) |
970 | | - return {}; |
971 | | - if (attribute == "REVISION") { |
972 | | - if (tok->number) |
973 | | - tok = tok->next; |
974 | | - else if (tok->str() == "(") { |
975 | | - do { |
976 | | - tok = tok->next; |
977 | | - } while (tok && (tok->number || tok->str() == ",")); |
978 | | - if (!tok || tok->str() != ")") |
979 | | - return {}; |
980 | | - tok = tok->next; |
981 | | - } else |
982 | | - return {}; |
983 | | - } else if (attribute == "MEMBER") { |
984 | | - if (!tok->name) |
985 | | - return {}; |
986 | | - tok = tok->next; |
987 | | - } else if (library.isexportedprefix("Q_PROPERTY", attribute)) { |
988 | | - const bool parenthesized = tok->str() == "("; |
| 908 | + unsigned int depth = 0; |
| 909 | + for (; tok; tok = tok->next) { |
| 910 | + if (tok->str() == "(") |
| 911 | + ++depth; |
| 912 | + else if (tok->str() == ")") { |
| 913 | + if (depth == 0) |
| 914 | + break; |
| 915 | + --depth; |
| 916 | + } else if (depth == 0) { |
| 917 | + if (library.isexportedsuffix(exporter, tok->str()) && tok->previous && tok->previous->name) |
| 918 | + functions.insert(tok->previous->str()); |
| 919 | + if (!library.isexportedprefix(exporter, tok->str())) |
| 920 | + continue; |
| 921 | + const simplecpp::Token* name = tok->next; |
| 922 | + const bool parenthesized = name && name->str() == "("; |
989 | 923 | if (parenthesized) |
990 | | - tok = tok->next; |
991 | | - if (!tok) |
992 | | - return {}; |
993 | | - if (tok->str() == "::") |
994 | | - tok = tok->next; |
995 | | - if (!tok) |
996 | | - return {}; |
997 | | - if (!tok->name) |
998 | | - return {}; |
999 | | - std::string function = tok->str(); |
1000 | | - tok = tok->next; |
1001 | | - while (tok && tok->str() == "::" && tok->next && tok->next->name) { |
1002 | | - function = tok->next->str(); |
1003 | | - tok = tok->next->next; |
1004 | | - } |
1005 | | - if (function != "true" && function != "false" && function != "default") |
1006 | | - functions.insert(function); |
1007 | | - if (parenthesized) { |
1008 | | - if (!tok || tok->str() != ")") |
1009 | | - return {}; |
1010 | | - tok = tok->next; |
1011 | | - } |
1012 | | - if (tok && tok->str() == "(") { |
1013 | | - tok = tok->next; |
1014 | | - if (!tok || tok->str() != ")") |
1015 | | - return {}; |
1016 | | - tok = tok->next; |
1017 | | - } |
1018 | | - } else |
1019 | | - return {}; |
| 924 | + name = name->next; |
| 925 | + if (name && name->str() == "::") |
| 926 | + name = name->next; |
| 927 | + if (!name || !name->name) |
| 928 | + continue; |
| 929 | + while (name->next && name->next->str() == "::" && name->next->next && name->next->next->name) |
| 930 | + name = name->next->next; |
| 931 | + if (parenthesized && (!name->next || name->next->str() != ")")) |
| 932 | + continue; |
| 933 | + if (name->str() != "true" && name->str() != "false" && name->str() != "default") |
| 934 | + functions.insert(name->str()); |
| 935 | + } |
1020 | 936 | } |
1021 | | - return tok ? functions : std::set<std::string>{}; |
| 937 | + return functions; |
1022 | 938 | } |
1023 | 939 |
|
1024 | 940 | void Preprocessor::readQtAnnotations(simplecpp::TokenList& tokens) |
@@ -1055,7 +971,7 @@ void Preprocessor::readQtAnnotations(simplecpp::TokenList& tokens) |
1055 | 971 | } |
1056 | 972 | const simplecpp::Token* type = tag->next->next; |
1057 | 973 | if (type && type->str() == "qt_property" && type->next && type->next->str() == ",") { |
1058 | | - const auto functions = qtPropertyFunctions(type->next->next, mSettings.library); |
| 974 | + const auto functions = exporterFunctions(type->next->next, "Q_PROPERTY", mSettings.library); |
1059 | 975 | mExportedFunctions.insert(functions.begin(), functions.end()); |
1060 | 976 | mExportedLocations.insert(tok->location); |
1061 | 977 | } |
@@ -1091,25 +1007,8 @@ std::set<std::string> Preprocessor::getExportedFunctions() const |
1091 | 1007 | if (locations.find(tok->location) == locations.end() || |
1092 | 1008 | !mSettings.library.isexporter(tok->str()) || !tok->next || tok->next->str() != "(") |
1093 | 1009 | continue; |
1094 | | - if (tok->str() == "Q_PROPERTY") { |
1095 | | - const auto accessors = qtPropertyFunctions(tok->next->next, mSettings.library); |
1096 | | - functions.insert(accessors.begin(), accessors.end()); |
1097 | | - continue; |
1098 | | - } |
1099 | | - unsigned int depth = 1; |
1100 | | - for (const simplecpp::Token* arg = tok->next->next; arg; arg = arg->next) { |
1101 | | - if (arg->str() == "(") |
1102 | | - ++depth; |
1103 | | - else if (arg->str() == ")") { |
1104 | | - if (--depth == 0) |
1105 | | - break; |
1106 | | - } else if (depth == 1) { |
1107 | | - if (mSettings.library.isexportedprefix(tok->str(), arg->str()) && arg->next && arg->next->name) |
1108 | | - functions.insert(arg->next->str()); |
1109 | | - if (mSettings.library.isexportedsuffix(tok->str(), arg->str()) && arg->previous && arg->previous->name) |
1110 | | - functions.insert(arg->previous->str()); |
1111 | | - } |
1112 | | - } |
| 1010 | + const auto exported = exporterFunctions(tok->next->next, tok->str(), mSettings.library); |
| 1011 | + functions.insert(exported.begin(), exported.end()); |
1113 | 1012 | } |
1114 | 1013 | }; |
1115 | 1014 | collect(mTokens); |
|
0 commit comments