Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CxxPreprocessor: unitilize com.sonar.sslr.api.Preprocessor::init() #1660

Merged
merged 1 commit into from
Jan 10, 2019

Conversation

ivangalkin
Copy link
Contributor

@ivangalkin ivangalkin commented Jan 8, 2019

  • the check, if CxxPreprocessor was about to start preprocessing
    a new file, was previously done in CxxPreprocessor::process()

  • Preprocessor::process() is called multiple time per file

  • in the worst case it's called for each Token

  • there is a special initialization method Preprocessor:init(),
    which is called once per file.
    See com.sonar.sslr.impl.Lexer::lex(Reader reader)

  • override this method and put the is-new-file logic to
    CxxPreprocessor::init()

  • we don't break any logic
    we still rely on the current context file, which is set in the
    proper order

    1. org.sonar.squidbridge.AstScanner::scanFiles() set the current
      context file
    2. parser.parse(file) -> lexer.lex(file) -> ... lex(reader)
    3. preprocessor.init();
  • benefits: skip redundant checks, split the code in the more logical way


This change is Reviewable

* the check, if CxxPreprocessor was about to start preprocessing
  a new file was previously done in CxxPreprocessor::process()
* Preprocessor::process() is called multiple time per file
* in the words case it's called for each Token

* there is a special initialization method Preprocessor:init(),
  which is called once per file.
  See com.sonar.sslr.impl.Lexer::lex(Reader reader)
* override this method and put the is-new-file logic to
  CxxPreprocessor::init()

* we don't break any logic
  we still rely on the current context file, which is set in the
  proper order

  1. org.sonar.squidbridge.AstScanner::scanFiles() set the current
     context file
  2. parser.parse(file) -> lexer.lex(file) -> ... lex(reader)
  3. preprocessor.init();
@ivangalkin ivangalkin added this to the 1.2.2 milestone Jan 8, 2019
@ivangalkin ivangalkin self-assigned this Jan 8, 2019
@ivangalkin ivangalkin requested review from Bertk and guwirth January 8, 2019 23:19
@guwirth
Copy link
Collaborator

guwirth commented Jan 10, 2019

@ivangalkin is this init not also the right place to move the CxxPreprocessor ctor code to?

@ivangalkin
Copy link
Contributor Author

ivangalkin commented Jan 10, 2019

is this init not also the right place to move the CxxPreprocessor ctor code to?

no, there are two initialization steps:

  1. initialization of CxxPreprocessor::fixedMacros: those are the macros, which are used by default. This map is immutable. It contains
    a) standard defines (Macro.STANDARD_MACROS, preprocessed)
    b) forced defines (must be parsed)
    b) macros, extracted from forced includes (must be parsed)

CxxPreprocessor::fixedMacros is (more or less) immutable. So it makes sense to create it only once - while construction of CxxPreprocessor.

  1. initialization of CxxPreprocessor::unitMacros: those are the macros, which are unique for some particular C/C++ file. It contains
    a) standard defines (Macro.UNIT_MACROS, preprocessed)
    b) forced defines (must be parsed)
    c) macros, extracted from forced includes (must be parsed)
    d) macros, passed through CxxConfiguration::getCompilationUnitSettings(File) (must be parsed) or from CxxConfiguration::getGlobalCompilationUnitSettings() (must be parsed, relevant only if JSON compilation database used).

CxxPreprocessor::unitMacros contains settings, which are unique for the compilation unit. So we have to re-create it during the CxxPreprocessor::init().

There is something, I don't really like: as you see 2.b, 2.c must be parsed for each file, although they are file-invariant. FixedMacros already have this data (1.b and 1.c). So we could extract forced macros into some dedicated structure and save run-time overhead again. Also the CxxConfiguration::getGlobalCompilationUnitSettings() are file-invariant. Those (if set) could be also parsed only once in constructor. The data could be cached in the similar way, we cache Macro.UNIT_MACROS or Macro.STANDARD_MACROS.

Back to your question: no, it doesn't make sense to move ctor-login into init()... but it makes sense to move parts of the init()-logic to the ctor. Let's consider to implement this optimization in some later PR.

@guwirth guwirth merged commit dc83764 into SonarOpenCommunity:master Jan 10, 2019
@guwirth guwirth mentioned this pull request Feb 8, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

2 participants