diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java index d955457d1c3..158faea8471 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java @@ -5650,6 +5650,58 @@ public class AST2Tests extends AST2BaseTest { } catch (ExpansionOverlapsBoundaryException e) {} } + + // #define IF if + // #define IF_P if ( + // #define IF_P_T if (1 + // #define SEMI_IF ; if + // #define IF_COND if (1) + // void test() { + public void testSyntax_Bug250251() throws Exception { + String code= getAboveComment(); + + IASTTranslationUnit tu= parseAndCheckBindings(code + "if (1) {};}"); + IASTFunctionDefinition f= getDeclaration(tu, 0); + IASTIfStatement x = getStatement(f, 0); + IToken syntax= x.getSyntax(); + checkToken(syntax, "if", 0); syntax= syntax.getNext(); + checkToken(syntax, "(", 3); syntax= syntax.getNext(); + checkToken(syntax, "1", 4); syntax= syntax.getNext(); + checkToken(syntax, ")", 5); syntax= syntax.getNext(); + checkToken(syntax, "{", 7); syntax= syntax.getNext(); + checkToken(syntax, "}", 8); syntax= syntax.getNext(); + assertNull(syntax); + + tu= parseAndCheckBindings(code + "if( 1) {}}"); + f= getDeclaration(tu, 0); x= getStatement(f, 0); + syntax= x.getSyntax(); + checkToken(syntax, "if", 0); syntax= syntax.getNext(); + checkToken(syntax, "(", 2); syntax= syntax.getNext(); + checkToken(syntax, "1", 5); syntax= syntax.getNext(); + checkToken(syntax, ")", 6); syntax= syntax.getNext(); + checkToken(syntax, "{", 8); syntax= syntax.getNext(); + checkToken(syntax, "}", 9); syntax= syntax.getNext(); + assertNull(syntax); + + tu= parseAndCheckBindings(code + "IF(1) {}}"); + f= getDeclaration(tu, 0); x= getStatement(f, 0); + syntax= x.getSyntax(); + checkToken(syntax, "IF", 0); syntax= syntax.getNext(); + checkToken(syntax, "(", 2); syntax= syntax.getNext(); + checkToken(syntax, "1", 3); syntax= syntax.getNext(); + checkToken(syntax, ")", 4); syntax= syntax.getNext(); + checkToken(syntax, "{", 6); syntax= syntax.getNext(); + checkToken(syntax, "}", 7); syntax= syntax.getNext(); + assertNull(syntax); + + tu= parseAndCheckBindings(code + "SEMI_IF (1) {}}"); + f= getDeclaration(tu, 0); x= getStatement(f, 1); + try { + syntax= x.getSyntax(); + fail(); + } catch (ExpansionOverlapsBoundaryException e) {} + } + private void checkToken(IToken token, String image, int offset) { assertEquals(image, token.getImage()); assertEquals(offset, token.getOffset()); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTNode.java index cc86a5a3302..eaae0d04daa 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTNode.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTNode.java @@ -185,6 +185,19 @@ public interface IASTNode { */ public IToken getTrailingSyntax() throws ExpansionOverlapsBoundaryException, UnsupportedOperationException; + /** + * Returns the tokens that make up this node. The tokens are obtained from the lexer, + * no preprocessing is performed. + * The offsets of the tokens are relative to the file-offset of the beginning of this node. + *
For examples see {@link #getLeadingSyntax()}.
+ * @return a chain of tokens or null
, if there are none.
+ * @throws ExpansionOverlapsBoundaryException if one of the boundaries of the node is
+ * overlapped by a macro-expansion.
+ * @throws UnsupportedOperationException if invoked on preprocessor nodes, or nodes that are not
+ * part of a translation unit.
+ * @since 5.1
+ */
+ public IToken getSyntax() throws ExpansionOverlapsBoundaryException;
/**
* Returns true if this node is frozen, false otherwise.
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java
index 18baaf6b0eb..fe7a16cdeea 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java
@@ -222,6 +222,10 @@ public abstract class ASTNode implements IASTNode {
return false;
}
+ public IToken getSyntax() throws ExpansionOverlapsBoundaryException {
+ return getSyntax(offset, offset+length, 0);
+ }
+
public IToken getLeadingSyntax() throws ExpansionOverlapsBoundaryException {
int left= getBoundary(-1);
return getSyntax(left, offset, -1);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/ASTLiteralNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/ASTLiteralNode.java
index 7cdd2adddfe..37282bb2748 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/ASTLiteralNode.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/ASTLiteralNode.java
@@ -84,6 +84,10 @@ public class ASTLiteralNode implements IASTNode {
public void setPropertyInParent(ASTNodeProperty property) {
}
+ public IToken getSyntax() {
+ throw new UnsupportedOperationException();
+ }
+
public IToken getLeadingSyntax() {
throw new UnsupportedOperationException();
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java
index e611b5c74ec..799c85f28aa 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java
@@ -195,6 +195,11 @@ public class PDOMASTAdapter {
return this;
}
+ public IToken getSyntax() throws ExpansionOverlapsBoundaryException,
+ UnsupportedOperationException {
+ return fDelegate.getSyntax();
+ }
+
public IToken getLeadingSyntax() throws ExpansionOverlapsBoundaryException,
UnsupportedOperationException {
return fDelegate.getLeadingSyntax();