Skip to main content
summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorHansruedi Patzen2018-05-15 11:22:34 -0400
committerNathan Ridge2018-05-24 18:52:08 -0400
commitdd5c8726a7e5e7d3c1e81f812bc5d288728a0aee (patch)
treea4616f114e2c11e936b97e9ee94676a93b7b14c5 /core
parenta7b0a1fe806fa248e8e2c497f144177244e8f7e4 (diff)
downloadorg.eclipse.cdt-dd5c8726a7e5e7d3c1e81f812bc5d288728a0aee.tar.gz
org.eclipse.cdt-dd5c8726a7e5e7d3c1e81f812bc5d288728a0aee.tar.xz
org.eclipse.cdt-dd5c8726a7e5e7d3c1e81f812bc5d288728a0aee.zip
Bug 527954: [C++14] Syntax error when parsing complex udl ""if
With this patch we allow any keyword to be used as a UDL operator, which for example GCC compiles fine with. They are then no longer highlighted as keywords but colored the same as normal text. This can be overridden by coloring overloading operators differently. Change-Id: If80faf0f3dc599ab4f12fe98977c556aaaefe6aa Signed-off-by: Hansruedi Patzen <hansruedi.patzen@hsr.ch>
Diffstat (limited to 'core')
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java12
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java20
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java14
-rw-r--r--core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/SemanticHighlightingTest.java79
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java33
5 files changed, 134 insertions, 24 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
index c20fb76352..d8b931c484 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
@@ -12067,6 +12067,18 @@ public class AST2CPPTests extends AST2CPPTestBase {
checkUserDefinedLiteralIsType(getAboveComment(), "complex");
}
+ // struct complex {
+ // complex(long double real, long double imag);
+ // complex operator+(long double long);
+ // };
+ // complex operator""if(long double imag) {
+ // return complex { 0, imag };
+ // }
+ // auto waldo = 1.0if + 1;
+ public void testComplexFloatNumbersOverriddenCompilerSupport() throws Exception {
+ checkUserDefinedLiteralIsType(getAboveComment(), "complex");
+ }
+
// // Test name lacking a space
// int operator ""X(const char* s) { return 0; }
// int operator ""_X(const char* s) { return 0; }
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java
index 54633cecce..dce940df4d 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java
@@ -2488,16 +2488,22 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
}
}
+ protected boolean isIdentifierOrKeyword(IToken token) {
+ char[] image = token.getCharImage();
+ if (image.length == 0) {
+ return false;
+ }
+ char firstChar = image[0];
+ return Character.isLetter(firstChar) || firstChar == '_';
+ }
+
protected IToken identifierOrKeyword() throws EndOfFileException, BacktrackException {
- IToken t = LA(1);
- char[] image= t.getCharImage();
- if (image.length == 0)
- throw backtrack;
- char firstChar= image[0];
- if (!Character.isLetter(firstChar) && firstChar != '_')
+ IToken token = LA(1);
+ if (!isIdentifierOrKeyword(token)) {
throw backtrack;
+ }
consume();
- return t;
+ return token;
}
/**
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
index a4614670d4..46cee01842 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
@@ -912,14 +912,14 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
if (strOp.getLength() == 2) {
endOffset = strOp.getEndOffset();
- IToken ident = consume(IToken.tIDENTIFIER);
+ IToken udlOperator = identifierOrKeyword();
char[] operatorName = CharArrayUtils.concat(firstToken.getCharImage(), " ".toCharArray()); //$NON-NLS-1$
operatorName = CharArrayUtils.concat(operatorName, strOp.getCharImage());
- operatorName = CharArrayUtils.concat(operatorName, ident.getCharImage());
+ operatorName = CharArrayUtils.concat(operatorName, udlOperator.getCharImage());
IASTName name = getNodeFactory().newOperatorName(operatorName);
- setRange(name, firstToken.getOffset(), ident.getEndOffset());
+ setRange(name, firstToken.getOffset(), udlOperator.getEndOffset());
return name;
}
break;
@@ -2020,13 +2020,13 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
IToken la = LA(1);
int offset = ((ASTNode) literalExprWithRange).getOffset();
int length = ((ASTNode) literalExprWithRange).getLength();
- if (la.getType() == IToken.tIDENTIFIER) {
+ if (isIdentifierOrKeyword(la)) {
if ((offset + length) != la.getOffset()) {
return literalExprWithRange;
}
- IToken opName = consume(IToken.tIDENTIFIER);
- ((CPPASTLiteralExpression) literalExprWithRange).setSuffix(opName.getCharImage());
- setRange(literalExprWithRange, offset, opName.getEndOffset());
+ consume();
+ ((CPPASTLiteralExpression) literalExprWithRange).setSuffix(la.getCharImage());
+ setRange(literalExprWithRange, offset, la.getEndOffset());
}
}
diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/SemanticHighlightingTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/SemanticHighlightingTest.java
index e5fbfb4e44..46abaa0e33 100644
--- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/SemanticHighlightingTest.java
+++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/SemanticHighlightingTest.java
@@ -16,8 +16,10 @@ import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.NullProgressMonitor;
@@ -92,18 +94,25 @@ public class SemanticHighlightingTest extends TestCase {
return dest;
}
- private void enableHighlightingsAndAssignColors() {
+ private void enableHighlightingsAndAssignColors(Set<String> ignoredHighlightings) {
fColorToPreferenceKeyMap = new HashMap<>();
IPreferenceStore store= CUIPlugin.getDefault().getPreferenceStore();
store.setValue(PreferenceConstants.EDITOR_SEMANTIC_HIGHLIGHTING_ENABLED, true);
SemanticHighlighting[] semanticHighlightings= SemanticHighlightings.getSemanticHighlightings();
int blue = 0; // for assigning colors to preferences below
for (SemanticHighlighting semanticHighlighting : semanticHighlightings) {
- // Enable the highlighting.
String enabledPreferenceKey = SemanticHighlightings.getEnabledPreferenceKey(semanticHighlighting);
- if (!store.getBoolean(enabledPreferenceKey))
+ // Make sure ignored highlightings are disabled.
+ if (ignoredHighlightings.contains(semanticHighlighting.getPreferenceKey())) {
+ store.setValue(enabledPreferenceKey, false);
+ continue;
+ }
+
+ // Enable the highlighting.
+ if (!store.getBoolean(enabledPreferenceKey)) {
store.setValue(enabledPreferenceKey, true);
-
+ }
+
// Choose a unique color for the highlighting, and save the mapping
// from the color to the highlighting's preference key .
String colorPreferenceKey = SemanticHighlightings.getColorPreferenceKey(semanticHighlighting);
@@ -129,8 +138,8 @@ public class SemanticHighlightingTest extends TestCase {
// Note: This is not an override of the TestCase.setUp(), but a method called directly
// by the tests, so that they can specify a value for 'isCpp' on a per-test basis.
- private void setup(boolean isCpp) throws Exception {
- enableHighlightingsAndAssignColors();
+ private void setup(boolean isCpp, Set<String> ignoredHighlightings) throws Exception {
+ enableHighlightingsAndAssignColors(ignoredHighlightings);
StringBuilder[] testData = TestSourceReader.getContentsForTest(CTestPlugin.getDefault().getBundle(), "ui", getClass(), getName(), 0);
@@ -217,15 +226,23 @@ public class SemanticHighlightingTest extends TestCase {
assertEqualMaps(actual, expected);
}
- private void makeAssertions(boolean isCpp) throws Exception {
- setup(isCpp);
+ private void makeAssertions(boolean isCpp, Set<String> ignoredHighlightings) throws Exception {
+ setup(isCpp, ignoredHighlightings);
try {
doMakeAssertions();
} finally {
teardown();
}
}
-
+
+ private void makeAssertions(Set<String> ignoredHighlightings) throws Exception {
+ makeAssertions(true, ignoredHighlightings); // default to C++
+ }
+
+ private void makeAssertions(boolean isCpp) throws Exception {
+ makeAssertions(isCpp, new HashSet<String>());
+ }
+
private void makeAssertions() throws Exception {
makeAssertions(true); // default to C++
}
@@ -679,4 +696,48 @@ public class SemanticHighlightingTest extends TestCase {
public void testVariablePassedByNonConstRef_529958() throws Exception {
makeAssertions();
}
+
+ // float operator""if(long double) { //$functionDeclaration
+ // return 1.6f;
+ // }
+ // int main() { //$functionDeclaration
+ // auto k = 1.3if; //$localVariableDeclaration,overloadedOperator
+ // }
+ public void testOverriddenUDLOperatorIfCall_527954() throws Exception {
+ makeAssertions();
+ }
+
+ // float operator""if(long double) { //$functionDeclaration
+ // return 1.6f;
+ // }
+ // int main() { //$functionDeclaration
+ // auto k = 1.3if; //$localVariableDeclaration,c_default
+ // }
+ public void testUDLOperatorIfCall_527954() throws Exception {
+ Set<String> ignoredHighlightings = new HashSet<>();
+ ignoredHighlightings.add(SemanticHighlightings.OVERLOADED_OPERATOR);
+ makeAssertions(ignoredHighlightings);
+ }
+
+ // int operator""int(long double) { //$functionDeclaration
+ // return -1;
+ // }
+ // int main() { //$functionDeclaration
+ // auto k = 1.3int; //$localVariableDeclaration,overloadedOperator
+ // }
+ public void testOverriddenUDLOperatorIntCall_527954() throws Exception {
+ makeAssertions();
+ }
+
+ // int operator""int(long double) { //$functionDeclaration
+ // return -1;
+ // }
+ // int main() { //$functionDeclaration
+ // auto k = 1.3int; //$localVariableDeclaration,c_default
+ // }
+ public void testUDLOperatorIntCall_527954() throws Exception {
+ Set<String> ignoredHighlightings = new HashSet<>();
+ ignoredHighlightings.add(SemanticHighlightings.OVERLOADED_OPERATOR);
+ makeAssertions(ignoredHighlightings);
+ }
}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java
index 1c116510ae..cf20d4668a 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/SemanticHighlightings.java
@@ -56,6 +56,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTClassVirtSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNameSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
@@ -1809,7 +1810,36 @@ public class SemanticHighlightings {
|| token.getNode() instanceof ICPPASTClassVirtSpecifier;
}
}
-
+
+ /**
+ * Semantic highlighting for context-sensitive UDL like operator""if(...).
+ *
+ * This does not get its own color and style; rather, it uses
+ * the color and style of the 'Default' syntactic highlighting.
+ */
+ private static final class ContextSensitiveUDLHighlighting extends SemanticHighlighting {
+ @Override
+ public String getPreferenceKey() {
+ return ICColorConstants.C_DEFAULT;
+ }
+
+ @Override
+ public boolean isEnabledByDefault() {
+ return true;
+ }
+
+ @Override
+ public boolean requiresImplicitNames() {
+ return true;
+ }
+
+ @Override
+ public boolean consumes(ISemanticToken token) {
+ IASTNode node = token.getNode();
+ return node instanceof IASTImplicitName && node.getParent() instanceof ICPPASTLiteralExpression;
+ }
+ }
+
private static boolean heuristicallyResolvesToEnumeration(ICPPUnknownBinding binding) {
IBinding[] resolved = HeuristicResolver.resolveUnknownBinding(binding);
return resolved.length == 1 && resolved[0] instanceof IEnumeration;
@@ -1981,6 +2011,7 @@ public class SemanticHighlightings {
highlightings.put(new Key(230), new EnumeratorHighlighting());
highlightings.put(new Key(240), new ContextSensitiveKeywordHighlighting());
highlightings.put(new Key(250), new VariablePassedByNonconstRefHighlighting());
+ highlightings.put(new Key(260), new ContextSensitiveUDLHighlighting());
}
private static final String ExtensionPoint = "semanticHighlighting"; //$NON-NLS-1$

Back to the top