Browse Source

cppparser: Fix slow parser performance

rdb 1 year ago
parent
commit
04a9264e68

+ 0 - 31
dtool/src/cppparser/cppFile.cxx

@@ -31,37 +31,6 @@ CPPFile(const Filename &filename, const Filename &filename_as_referenced,
   _filename_as_referenced.set_text();
 }
 
-
-/**
- *
- */
-CPPFile::
-CPPFile(const CPPFile &copy) :
-  _filename(copy._filename),
-  _filename_as_referenced(copy._filename_as_referenced),
-  _source(copy._source),
-  _pragma_once(copy._pragma_once)
-{
-}
-
-/**
- *
- */
-void CPPFile::
-operator = (const CPPFile &copy) {
-  _filename = copy._filename;
-  _filename_as_referenced = copy._filename_as_referenced;
-  _source = copy._source;
-  _pragma_once = copy._pragma_once;
-}
-
-/**
- *
- */
-CPPFile::
-~CPPFile() {
-}
-
 /**
  * Returns true if the file appears to be a C or C++ source code file based on
  * its extension.  That is, returns true if the filename ends in .c, .C, .cc,

+ 0 - 3
dtool/src/cppparser/cppFile.h

@@ -34,9 +34,6 @@ public:
   CPPFile(const Filename &filename = "",
           const Filename &filename_as_referenced = "",
           Source source = S_none);
-  CPPFile(const CPPFile &copy);
-  void operator = (const CPPFile &copy);
-  ~CPPFile();
 
   bool is_c_or_i_file() const;
   static bool is_c_or_i_file(const Filename &filename);

+ 5 - 5
dtool/src/cppparser/cppManifest.cxx

@@ -325,8 +325,8 @@ extract_args(vector_string &args, const string &expr, size_t &p) const {
  *
  */
 string CPPManifest::
-expand(const vector_string &args, const Manifests &manifests, bool expand_undefined) const {
-  return r_expand(_expansion, args, manifests, expand_undefined);
+expand(const vector_string &args, bool expand_undefined, const Ignores &ignores) const {
+  return r_expand(_expansion, args, expand_undefined, ignores);
 }
 
 /**
@@ -601,7 +601,7 @@ save_expansion(Expansion &expansion, const string &exp, const vector_string &par
  */
 string CPPManifest::
 r_expand(const Expansion &expansion, const vector_string &args,
-         const Manifests &manifests, bool expand_undefined) const {
+         bool expand_undefined, const Ignores &ignores) const {
   std::string result;
 
   for (const ExpansionNode &node : expansion) {
@@ -631,7 +631,7 @@ r_expand(const Expansion &expansion, const vector_string &args,
       }
 
       if (node._expand) {
-        _parser.expand_manifests(subst, manifests, expand_undefined);
+        _parser.expand_manifests(subst, expand_undefined, ignores);
       }
 
       if (!subst.empty()) {
@@ -654,7 +654,7 @@ r_expand(const Expansion &expansion, const vector_string &args,
     if (!node._nested.empty()) {
       string nested_result;
       if (node._optional && args.size() >= _num_parameters) {
-        nested_result = r_expand(node._nested, args, manifests, expand_undefined);
+        nested_result = r_expand(node._nested, args, expand_undefined, ignores);
       }
       if (node._stringify) {
         nested_result = stringify(nested_result);

+ 5 - 4
dtool/src/cppparser/cppManifest.h

@@ -21,6 +21,7 @@
 #include "cppBisonDefs.h"
 
 #include "vector_string.h"
+#include <unordered_set>
 
 class CPPExpression;
 class CPPType;
@@ -30,7 +31,7 @@ class CPPType;
  */
 class CPPManifest {
 public:
-  typedef std::map<std::string, CPPManifest *> Manifests;
+  typedef std::unordered_set<const CPPManifest *> Ignores;
 
   CPPManifest(const CPPPreprocessor &parser, const std::string &args, const cppyyltype &loc);
   CPPManifest(const CPPPreprocessor &parser, const std::string &macro, const std::string &definition);
@@ -39,8 +40,8 @@ public:
   static std::string stringify(const std::string &source);
   void extract_args(vector_string &args, const std::string &expr, size_t &p) const;
   std::string expand(const vector_string &args = vector_string(),
-                     const Manifests &manifests = Manifests(),
-                     bool expand_undefined = false) const;
+                     bool expand_undefined = false,
+                     const Ignores &ignores = Ignores()) const;
 
 
   CPPType *determine_type() const;
@@ -86,7 +87,7 @@ private:
                       const vector_string &parameter_names);
 
   std::string r_expand(const Expansion &expansion, const vector_string &args,
-                       const Manifests &manifests, bool expand_undefined) const;
+                       bool expand_undefined, const Ignores &ignores) const;
 
   Expansion _expansion;
 };

+ 17 - 16
dtool/src/cppparser/cppPreprocessor.cxx

@@ -902,7 +902,8 @@ push_expansion(const string &input, const CPPManifest *manifest, const YYLTYPE &
  * Given a string, expand all manifests within the string.
  */
 void CPPPreprocessor::
-expand_manifests(string &expr, const Manifests &manifests, bool expand_undefined) const {
+expand_manifests(string &expr, bool expand_undefined,
+                 const CPPManifest::Ignores &ignores) const {
   size_t p = 0;
   while (p < expr.size()) {
     if (isalpha(expr[p]) || expr[p] == '_') {
@@ -925,8 +926,8 @@ expand_manifests(string &expr, const Manifests &manifests, bool expand_undefined
       }
       else {
         // Is it a manifest?
-        Manifests::const_iterator mi = manifests.find(ident);
-        if (mi != manifests.end()) {
+        Manifests::const_iterator mi = _manifests.find(ident);
+        if (mi != _manifests.end() && ignores.count((*mi).second) == 0) {
           const CPPManifest *manifest = (*mi).second;
           vector_string args;
           if (manifest->_has_parameters) {
@@ -943,11 +944,11 @@ expand_manifests(string &expr, const Manifests &manifests, bool expand_undefined
 
           // Don't consider this manifest when expanding the arguments or
           // result, to prevent recursion.
-          Manifests nested_manifests(manifests);
-          nested_manifests.erase((*mi).first);
+          CPPManifest::Ignores nested_ignores(ignores);
+          nested_ignores.insert(manifest);
 
-          string result = manifest->expand(args);
-          expand_manifests(result, nested_manifests, expand_undefined);
+          string result = manifest->expand(args, expand_undefined, nested_ignores);
+          expand_manifests(result, expand_undefined, nested_ignores);
 
           expr = expr.substr(0, q) + result + expr.substr(p);
           p = q + result.size();
@@ -1008,7 +1009,7 @@ CPPExpression *CPPPreprocessor::
 parse_expr(const string &input_expr, CPPScope *current_scope,
            CPPScope *global_scope, const YYLTYPE &loc) {
   string expr = input_expr;
-  expand_manifests(expr, _manifests, false);
+  expand_manifests(expr, false);
 
   CPPExpressionParser ep(current_scope, global_scope);
   ep._verbose = 0;
@@ -1685,7 +1686,7 @@ void CPPPreprocessor::
 handle_if_directive(const string &args, const YYLTYPE &loc) {
   // When expanding manifests, we should replace unknown macros with 0.
   string expr = args;
-  expand_manifests(expr, _manifests, true);
+  expand_manifests(expr, true);
 
   int expression_result = 0;
   CPPExpressionParser ep(current_scope, global_scope);
@@ -1730,7 +1731,7 @@ handle_include_directive(const string &args, const YYLTYPE &loc) {
   // filter out quotes and angle brackets properly, we'll only expand
   // manifests if we don't begin with a quote or bracket.
   if (!expr.empty() && (expr[0] != '"' && expr[0] != '<')) {
-    expand_manifests(expr, _manifests, false);
+    expand_manifests(expr, false);
   }
 
   if (!expr.empty()) {
@@ -2332,17 +2333,17 @@ expand_manifest(const CPPManifest *manifest, const YYLTYPE &loc) {
                           manifest->_variadic_param, args);
   }
 
-  // Make a copy of the manifests, without the ones we're supposed to ignore.
-  Manifests manifests = _manifests;
-  manifests.erase(manifest->_name);
+  // Keep track of the manifests we're supposed to ignore.
+  CPPManifest::Ignores ignores;
+  ignores.insert(manifest);
 
   for (const InputFile &infile : _files) {
     if (infile._ignore_manifest) {
-      manifests.erase(infile._manifest->_name);
+      ignores.insert(infile._manifest);
     }
   }
 
-  string expanded = " " + manifest->expand(args, manifests, false) + " ";
+  string expanded = " " + manifest->expand(args, false, ignores) + " ";
   push_expansion(expanded, manifest, loc);
 
 #ifdef CPP_VERBOSE_LEX
@@ -2575,7 +2576,7 @@ expand_has_include_function(string &expr, size_t q, size_t &p) const {
   // Only expand if we've encountered unquoted identifier-valid characters,
   // to be on the safe side.
   if (needs_expansion) {
-    expand_manifests(inc, _manifests, false);
+    expand_manifests(inc, false);
   }
 
   Filename filename;

+ 4 - 3
dtool/src/cppparser/cppPreprocessor.h

@@ -27,6 +27,7 @@
 #include <map>
 #include <list>
 #include <vector>
+#include <unordered_map>
 
 class CPPScope;
 class CPPTemplateParameterList;
@@ -71,7 +72,7 @@ public:
   int get_warning_count() const;
   int get_error_count() const;
 
-  typedef CPPManifest::Manifests Manifests;
+  typedef std::unordered_map<std::string, CPPManifest *> Manifests;
   Manifests _manifests;
 
   typedef std::vector<CPPManifest *> ManifestStack;
@@ -119,8 +120,8 @@ protected:
                       const YYLTYPE &loc);
 
 public:
-  void expand_manifests(std::string &expr, const Manifests &manifests,
-                        bool expand_undefined = false) const;
+  void expand_manifests(std::string &expr, bool expand_undefined = false,
+                        const CPPManifest::Ignores &ignores = CPPManifest::Ignores()) const;
   CPPExpression *parse_expr(const std::string &expr, CPPScope *current_scope,
                             CPPScope *global_scope, const YYLTYPE &loc);