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 81ef7184d5c..a08aa632b61 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 @@ -3877,5 +3877,19 @@ public class AST2Tests extends AST2BaseTest { StringBuffer buffer = getContents(1)[0]; parse( buffer.toString(), ParserLanguage.CPP, false, false, true ); parse( buffer.toString(), ParserLanguage.C, false, false, true ); - } + } + + public void test195943() throws Exception { + final int depth= 100; + StringBuffer buffer = new StringBuffer(); + buffer.append("#define M0 1\n"); + for (int i = 1; i < depth; i++) { + buffer.append("#define M" + i + " (M" + (i-1) + "+1)\n"); + } + buffer.append("int a= M" + (depth-1) + ";\n"); + long time= System.currentTimeMillis(); + parse(buffer.toString(), ParserLanguage.CPP); + parse( buffer.toString(), ParserLanguage.C); + assertTrue(System.currentTimeMillis()-time < 1000); + } } 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 17ca72e4eb1..2e00ec04493 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 @@ -2406,6 +2406,47 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { return false; } + protected boolean canBeTypeSpecifier() throws EndOfFileException { + switch (LT(1)) { + // simple type specifiers: + case IToken.tIDENTIFIER: + case IToken.tCOLONCOLON: + case IToken.t_void: + case IToken.t_char: + case IToken.t_wchar_t: + case IToken.t_bool: + case IToken.t_short: + case IToken.t_int: + case IToken.t_long: + case IToken.t_float: + case IToken.t_double: + case IToken.t__Bool: + case IToken.t__Complex: + case IToken.t__Imaginary: + case IToken.t_signed: + case IToken.t_unsigned: + + // class-specifier: + case IToken.t_class: + case IToken.t_struct: + case IToken.t_union: + + // enum-specifier: + case IToken.t_enum: + + // elaborated type specifier: (together with class, struct, union, enum + case IToken.t_typename: + + // cq-qualifiers + case IToken.t_const: + case IToken.t_volatile: + case IToken.t_restrict: + return true; + } + + return false; + } + /** * Creates the ast node for a comment. * @since 4.0 diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java index 8008635dd9e..18e6a46abc5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java @@ -1265,6 +1265,9 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { } protected IASTTypeId typeId(boolean forNewExpression) throws EndOfFileException { + if (!canBeTypeSpecifier()) { + return null; + } IToken mark = mark(); int startingOffset = mark.getOffset(); IASTDeclSpecifier declSpecifier = null; 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 ae95906461d..971ceda73d9 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 @@ -963,6 +963,9 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { * @throws BacktrackException */ protected IASTTypeId typeId(boolean forNewExpression) throws EndOfFileException { + if (!canBeTypeSpecifier()) { + return null; + } IToken mark = mark(); int startingOffset = mark.getOffset(); IASTDeclSpecifier declSpecifier = null;