Skip to content

Commit

Permalink
Correct support of the preprocessor for the #pragma once directive
Browse files Browse the repository at this point in the history
  • Loading branch information
aJanker committed Apr 28, 2016
1 parent 32096e3 commit b233933
Showing 1 changed file with 26 additions and 12 deletions.
Expand Up @@ -155,7 +155,7 @@ protected MacroContext<MacroData> getMacros() {
PreprocessorListener listener;

private List<MacroConstraint> macroConstraints = new ArrayList<MacroConstraint>();
private Map<VirtualFile, FeatureExpr> includedFileMap;
private Map<String, FeatureExpr> includedPragmaOnceFiles;

public Preprocessor(MacroFilter macroFilter, FeatureModel fm) {
this.featureModel = fm;
Expand All @@ -177,7 +177,7 @@ public Preprocessor(MacroFilter macroFilter, FeatureModel fm) {
this.warnings = EnumSet.noneOf(Warning.class);
this.filesystem = new JavaFileSystem();
this.listener = null;
this.includedFileMap = new HashMap<VirtualFile, FeatureExpr>();
this.includedPragmaOnceFiles = new HashMap<String, FeatureExpr>();
}

public Preprocessor() {
Expand Down Expand Up @@ -1534,19 +1534,21 @@ private boolean include(VirtualFile file) throws IOException,
if (getFeature(Feature.DEBUG_VERBOSE))
System.err.println("pp: including " + file);

// include the file only if we have NOT already included the file under a condition
// which contains also the current condition
FeatureExpr condition = this.includedFileMap.get(file);
FeatureExpr currentCondition = this.state.getFullPresenceCondition();
if (this.includedPragmaOnceFiles.containsKey(file.getPath())) {
// This file has already been included once with the preprocessor directive #pragma once
// We include the file only if we have NOT already included the file under a condition
// which contains also the current condition
FeatureExpr condition = this.includedPragmaOnceFiles.get(file.getPath());
FeatureExpr currentCondition = this.state.getFullPresenceCondition();

if (condition == null) {
sourceManager.push_source(file.getSource(), true);
this.includedFileMap.put(file, currentCondition);
} else if (currentCondition.andNot(condition).isSatisfiable()) {
if (currentCondition.andNot(condition).isSatisfiable())
sourceManager.push_source(file.getSource(), true);

} else {
sourceManager.push_source(file.getSource(), true);
this.includedFileMap.put(file, currentCondition.or(condition));
}


return true;
}

Expand Down Expand Up @@ -1717,10 +1719,22 @@ private Token parse_include(boolean next) throws IOException,
protected void pragma(Token nameTok, List<Token> value) throws IOException,
LexerException {
String pragmaName = nameTok.getText();
if (!"pack".equals(pragmaName))

// found directive #pragma once -> add the current file with the current condition to a map containing all headers
// already included with the directive #pragma once to avoid duplicate header inclusion
if (pragmaName.equalsIgnoreCase("once"))
updateIncludedPragmaOnceFiles(sourceManager.getSource().getPath(), this.state.getFullPresenceCondition());
else if (!"pack".equals(pragmaName))
warning(nameTok, "Unknown #" + "pragma: " + pragmaName);
}

private void updateIncludedPragmaOnceFiles(String path, FeatureExpr condition) {
if (this.includedPragmaOnceFiles.containsKey(path))
this.includedPragmaOnceFiles.put(path, condition.or(this.includedPragmaOnceFiles.get(path)));
else
this.includedPragmaOnceFiles.put(path, condition);
}

private Token parse_pragma() throws IOException, LexerException {
Token name;

Expand Down

0 comments on commit b233933

Please sign in to comment.