cppparser: Minor performance improvements

This commit is contained in:
rdb 2024-03-29 16:04:04 +01:00
parent 12a188b116
commit 4430f16cda
2 changed files with 125 additions and 91 deletions

View File

@ -439,10 +439,11 @@ get_verbose() const {
*/
void CPPPreprocessor::
copy_filepos(const CPPPreprocessor &other) {
assert(!_files.empty());
_files.back()._file = other.get_file();
_files.back()._line_number = other.get_line_number();
_files.back()._col_number = other.get_col_number();
InputFile *infile = _infile;
assert(infile != nullptr);
infile->_file = other.get_file();
infile->_line_number = other.get_line_number();
infile->_col_number = other.get_col_number();
}
/**
@ -450,10 +451,12 @@ copy_filepos(const CPPPreprocessor &other) {
*/
CPPFile CPPPreprocessor::
get_file() const {
if (_files.empty()) {
InputFile *infile = _infile;
if (infile != nullptr) {
return infile->_file;
} else {
return CPPFile("");
}
return _files.back()._file;
}
/**
@ -461,10 +464,12 @@ get_file() const {
*/
int CPPPreprocessor::
get_line_number() const {
if (_files.empty()) {
InputFile *infile = _infile;
if (infile != nullptr) {
return infile->_line_number;
} else {
return 0;
}
return _files.back()._line_number;
}
/**
@ -472,10 +477,12 @@ get_line_number() const {
*/
int CPPPreprocessor::
get_col_number() const {
if (_files.empty()) {
InputFile *infile = _infile;
if (infile != nullptr) {
return infile->_col_number;
} else {
return 0;
}
return _files.back()._col_number;
}
/**
@ -486,7 +493,7 @@ get_next_token() {
#ifdef CPP_VERBOSE_LEX
CPPToken tok = get_next_token0();
indent(cerr, _files.size() * 2)
indent(cerr, get_file_depth() * 2)
<< _token_index++ << ". " << tok << "\n";
return tok;
}
@ -668,7 +675,7 @@ void CPPPreprocessor::
warning(const string &message, const YYLTYPE &loc) const {
if (_verbose >= 2) {
if (_verbose >= 3) {
indent(cerr, _files.size() * 2);
indent(cerr, get_file_depth() * 2);
}
if (!loc.file.empty()) {
@ -717,7 +724,7 @@ error(const string &message, const YYLTYPE &loc) const {
if (_verbose >= 1) {
if (_verbose >= 3) {
indent(cerr, _files.size() * 2);
indent(cerr, get_file_depth() * 2);
}
if (!loc.file.empty()) {
@ -734,31 +741,31 @@ error(const string &message, const YYLTYPE &loc) const {
cerr << " error: " << message << "\n";
show_line(loc);
if (!_files.empty() && !loc.file.empty()) {
Files::const_reverse_iterator rit;
for (rit = _files.rbegin();
rit != _files.rend() && (*rit)._file == loc.file && (*rit)._manifest != nullptr;
++rit) {
InputFile *infile = _infile;
if (infile != nullptr && !loc.file.empty()) {
// Add all the expansions to a vector for easy reverse iteration.
std::vector<InputFile *> infiles;
while (infile != nullptr && infile->_file == loc.file && infile->_manifest != nullptr) {
infiles.push_back(infile);
infile = infile->_parent;
}
if (rit != _files.rbegin() && rit != _files.rend()) {
--rit;
const InputFile &infile = *rit;
if (!infiles.empty()) {
auto rit = infiles.rbegin();
if (_verbose >= 3) {
cerr << "Expansion of " << infile._manifest->_name << ":\n";
cerr << " -> " << trim_blanks(infile._input) << "\n";
while (rit != _files.rbegin()) {
--rit;
const InputFile &infile = *rit;
cerr << " -> " << trim_blanks(infile._input) << "\n";
cerr << "Expansion of " << (*rit)->_manifest->_name << ":\n";
while (rit != infiles.rend()) {
cerr << " -> " << trim_blanks((*rit)->_input) << "\n";
++rit;
}
}
else {
cerr << "with " << infile._manifest->_name;
if (infile._manifest->_has_parameters) {
cerr << "with " << (*rit)->_manifest->_name;
if ((*rit)->_manifest->_has_parameters) {
cerr << "()";
}
cerr << " expanded to: " << trim_blanks(_files.back()._input) << "\n";
cerr << " expanded to: " << trim_blanks(_infile->_input) << "\n";
}
cerr << std::endl;
}
}
@ -781,7 +788,7 @@ show_line(const YYLTYPE &loc) const {
int indent_level = 0;
if (_verbose >= 3) {
indent_level = _files.size() * 2;
indent_level = get_file_depth() * 2;
}
// Seek to the offending line in the file.
@ -940,25 +947,26 @@ init_type(const string &type) {
bool CPPPreprocessor::
push_file(const CPPFile &file) {
if (_verbose >= 3) {
indent(cerr, _files.size() * 2)
indent(cerr, get_file_depth() * 2)
<< "Reading " << file << "\n";
}
assert(_last_c == 0);
_files.push_back(InputFile());
InputFile &infile = _files.back();
InputFile *infile = new InputFile;
if (infile->open(file)) {
infile->_parent = _infile;
_infile = infile;
if (infile.open(file)) {
// Record the fact that we opened the file for the benefit of user code.
_parsed_files.insert(file);
infile._prev_last_c = _last_c;
infile->_prev_last_c = _last_c;
_last_c = '\0';
_start_of_line = true;
return true;
}
_files.pop_back();
delete infile;
return false;
}
@ -968,25 +976,26 @@ push_file(const CPPFile &file) {
bool CPPPreprocessor::
push_string(const string &input) {
#ifdef CPP_VERBOSE_LEX
indent(cerr, _files.size() * 2)
indent(cerr, get_file_depth() * 2)
<< "Pushing to string \"" << input
<< "\"\n";
#endif
_files.push_back(InputFile());
InputFile &infile = _files.back();
if (infile.connect_input(input)) {
infile._prev_last_c = _last_c;
InputFile *infile = new InputFile;
if (infile->connect_input(input)) {
infile->_prev_last_c = _last_c;
infile->_parent = _infile;
_infile = infile;
_last_c = '\0';
return true;
}
#ifdef CPP_VERBOSE_LEX
indent(cerr, _files.size() * 2)
indent(cerr, get_file_depth() * 2)
<< "Unable to read string\n";
#endif
_files.pop_back();
delete infile;
return false;
}
@ -996,37 +1005,38 @@ push_string(const string &input) {
bool CPPPreprocessor::
push_expansion(const string &input, const CPPManifest *manifest, const YYLTYPE &loc) {
#ifdef CPP_VERBOSE_LEX
indent(cerr, _files.size() * 2)
indent(cerr, get_file_depth() * 2)
<< "Pushing to expansion \"" << input
<< "\"\n";
#endif
_files.push_back(InputFile());
InputFile &infile = _files.back();
if (infile.connect_input(input)) {
infile._manifest = manifest;
infile._file = loc.file;
infile._line_number = loc.first_line;
infile._col_number = loc.first_column;
infile._lock_position = true;
InputFile *infile = new InputFile;
if (infile->connect_input(input)) {
infile->_manifest = manifest;
infile->_file = loc.file;
infile->_line_number = loc.first_line;
infile->_col_number = loc.first_column;
infile->_lock_position = true;
if (!manifest->_has_parameters) {
// If the manifest does not use arguments, then disallow recursive
// expansion.
infile._ignore_manifest = true;
infile->_ignore_manifest = true;
}
infile._prev_last_c = _last_c;
infile->_prev_last_c = _last_c;
infile->_parent = _infile;
_infile = infile;
_last_c = '\0';
return true;
}
#ifdef CPP_VERBOSE_LEX
indent(cerr, _files.size() * 2)
indent(cerr, get_file_depth() * 2)
<< "Unable to read expansion\n";
#endif
_files.pop_back();
delete infile;
return false;
}
@ -1647,7 +1657,7 @@ process_directive(int c) {
loc.last_column = 0;
#ifdef CPP_VERBOSE_LEX
indent(cerr, _files.size() * 2)
indent(cerr, get_file_depth() * 2)
<< "#" << command << " " << args << "\n";
#endif
@ -1870,7 +1880,7 @@ handle_include_directive(const string &args, const YYLTYPE &loc) {
if (expr[0] == '"' && expr[expr.size() - 1] == '"') {
filename = expr.substr(1, expr.size() - 2);
if (_files.size() == 1) {
if (_infile->_parent == nullptr) {
// If we're currently processing a top-level file, record the include
// directive. We don't need to record includes from included files.
_quote_includes.insert(filename);
@ -1884,7 +1894,7 @@ handle_include_directive(const string &args, const YYLTYPE &loc) {
angle_quotes = true;
}
if (_files.size() == 1) {
if (_infile->_parent == nullptr) {
// If we're currently processing a top-level file, record the include
// directive. We don't need to record includes from included files.
_angle_includes.insert(filename);
@ -2470,17 +2480,19 @@ expand_manifest(const CPPManifest *manifest, const YYLTYPE &loc) {
CPPManifest::Ignores ignores;
ignores.insert(manifest);
for (const InputFile &infile : _files) {
if (infile._ignore_manifest) {
ignores.insert(infile._manifest);
InputFile *infile = _infile;
while (infile != nullptr) {
if (infile->_ignore_manifest) {
ignores.insert(infile->_manifest);
}
infile = infile->_parent;
}
string expanded = " " + manifest->expand(args, false, ignores) + " ";
push_expansion(expanded, manifest, loc);
#ifdef CPP_VERBOSE_LEX
indent(cerr, _files.size() * 2)
indent(cerr, get_file_depth() * 2)
<< "Expanding " << manifest->_name << " to " << expanded << "\n";
#endif
@ -3006,10 +3018,12 @@ scan_raw(int c) {
*/
bool CPPPreprocessor::
should_ignore_manifest(const CPPManifest *manifest) const {
for (const InputFile &infile : _files) {
if (infile._ignore_manifest && infile._manifest == manifest) {
InputFile *infile = _infile;
while (infile != nullptr) {
if (infile->_ignore_manifest && infile->_manifest == manifest) {
return true;
}
infile = infile->_parent;
}
return false;
@ -3021,10 +3035,12 @@ should_ignore_manifest(const CPPManifest *manifest) const {
*/
bool CPPPreprocessor::
should_ignore_preprocessor() const {
for (const InputFile &infile : _files) {
if (infile._ignore_manifest) {
InputFile *infile = _infile;
while (infile != nullptr) {
if (infile->_ignore_manifest) {
return true;
}
infile = infile->_parent;
}
return false;
@ -3041,18 +3057,21 @@ get() {
return c;
}
if (_files.empty()) {
if (UNLIKELY(_infile == nullptr)) {
return EOF;
}
int c = _files.back().get();
int c = _infile->get();
while (c == EOF && !_files.empty()) {
while (UNLIKELY(c == EOF && _infile != nullptr)) {
#ifdef CPP_VERBOSE_LEX
indent(cerr, _files.size() * 2)
indent(cerr, get_file_depth() * 2)
<< "End of input stream, restoring to previous input\n";
#endif
_files.pop_back();
// Pop the last file off the end.
InputFile *infile = _infile;
_infile = infile->_parent;
delete infile;
// Synthesize a newline, just in case the file doesn't already end with
// one.
@ -3077,21 +3096,21 @@ peek() {
return _unget;
}
if (_files.empty()) {
InputFile *infile = _infile;
if (UNLIKELY(infile == nullptr)) {
return EOF;
}
Files::reverse_iterator it = _files.rbegin();
int c = (*it).peek();
int c = infile->peek();
while (c == EOF && it != _files.rend()) {
int last_c = (*it)._prev_last_c;
++it;
while (UNLIKELY(c == EOF && infile != nullptr)) {
int last_c = infile->_prev_last_c;
infile = infile->_parent;
if (last_c != '\0') {
c = last_c;
} else if (it != _files.rend()) {
c = (*it).peek();
} else if (infile != nullptr) {
c = infile->peek();
}
}
@ -3117,7 +3136,7 @@ unget(int c) {
CPPTemplateParameterList *CPPPreprocessor::
nested_parse_template_instantiation(CPPTemplateScope *scope) {
#ifdef CPP_VERBOSE_LEX
indent(cerr, _files.size() * 2)
indent(cerr, get_file_depth() * 2)
<< "Beginning nested parse\n";
#endif
assert(scope != nullptr);
@ -3206,7 +3225,7 @@ nested_parse_template_instantiation(CPPTemplateScope *scope) {
_parsing_template_params = old_parsing_params;
#ifdef CPP_VERBOSE_LEX
indent(cerr, _files.size() * 2)
indent(cerr, get_file_depth() * 2)
<< "Ending nested parse\n";
#endif
return actual_params;
@ -3222,7 +3241,7 @@ nested_parse_template_instantiation(CPPTemplateScope *scope) {
void CPPPreprocessor::
skip_to_end_nested() {
#ifdef CPP_VERBOSE_LEX
indent(cerr, _files.size() * 2)
indent(cerr, get_file_depth() * 2)
<< "Skipping tokens:\n";
#endif
@ -3236,7 +3255,7 @@ skip_to_end_nested() {
}
#ifdef CPP_VERBOSE_LEX
indent(cerr, _files.size() * 2)
indent(cerr, get_file_depth() * 2)
<< "Done skipping tokens.\n";
#endif
}
@ -3249,7 +3268,7 @@ skip_to_end_nested() {
void CPPPreprocessor::
skip_to_angle_bracket() {
#ifdef CPP_VERBOSE_LEX
indent(cerr, _files.size() * 2)
indent(cerr, get_file_depth() * 2)
<< "Skipping tokens:\n";
#endif
@ -3266,7 +3285,21 @@ skip_to_angle_bracket() {
}
#ifdef CPP_VERBOSE_LEX
indent(cerr, _files.size() * 2)
indent(cerr, get_file_depth() * 2)
<< "Done skipping tokens.\n";
#endif
}
/**
* Returns the number of files on the _infile list.
*/
int CPPPreprocessor::
get_file_depth() const{
int depth = 0;
InputFile *infile = _infile;
while (infile != nullptr) {
++depth;
infile = infile->_parent;
}
return depth;
}

View File

@ -182,6 +182,8 @@ private:
void skip_to_end_nested();
void skip_to_angle_bracket();
int get_file_depth() const;
class InputFile {
public:
InputFile();
@ -203,12 +205,11 @@ private:
bool _lock_position;
bool _ignore_manifest;
int _prev_last_c;
InputFile *_parent = nullptr;
};
// This must be a list and not a vector because we don't have a good copy
// constructor defined for InputFile.
typedef std::list<InputFile> Files;
Files _files;
InputFile *_infile = nullptr;
enum State {
S_normal, S_eof, S_nested, S_end_nested