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 19cd9a6e033..1e8af1d67be 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 @@ -1249,15 +1249,15 @@ public class AST2CPPTests extends AST2BaseTest { ICPPMethod[] methods = ((ICPPClassScope)A.getCompositeScope()).getImplicitMethods(); assertNotNull(methods); int count=0; - for(int i=0; i", 10); bh.assertNonProblem("numRelays )", 9); } - + + // template + // struct and_ : public integral_constant { + // }; + // template + // struct or_ : public integral_constant { + // }; + // template struct is_pod + // : integral_constant::value || + // is_floating_point::value || + // is_pointer::value)> { }; + // + // typedef base::integral_constant::value && + // base::has_trivial_destructor::value)> + // realloc_ok; + public void testTemplateIDAmbiguity_Bug228118() throws Exception { + parse(getAboveComment(), ParserLanguage.CPP); + } + // namespace ns { // class cl {}; // void func(cl c); 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 08acf4cb9f3..170da467b89 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 @@ -171,6 +171,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { private int templateCount = 0; private int functionBodyCount= 0; private int templateArgListCount= 0; + private int preventLogicalOperatorInTemplateID; protected CPPASTTranslationUnit translationUnit; @@ -331,6 +332,21 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { return list; } + /** + * To disambiguate between logical expressions and template id's in some situations + * we forbid the usage of the logical operators '&&' or '||' within template ids. + * @throws EndOfFileException + * @since 5.0 + */ + protected final ITokenDuple nameWithoutLogicalOperatorInTemplateID() throws BacktrackException, EndOfFileException { + preventLogicalOperatorInTemplateID++; + try { + return name(); + } + finally { + preventLogicalOperatorInTemplateID--; + } + } /** * Parse a name. * name ::= ("::")? name2 ("::" name2)* @@ -415,7 +431,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { @Override protected IASTExpression conditionalExpression() throws BacktrackException, EndOfFileException { final IASTExpression expr= super.conditionalExpression(); - if (templateArgListCount > 0) { + if (templateArgListCount > 0 && preventLogicalOperatorInTemplateID > 0) { // bug 104706, don't allow usage of logical operators in template argument lists. if (expr instanceof IASTConditionalExpression) { final ASTNode node = (ASTNode) expr; @@ -1744,7 +1760,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { protected IASTName idExpression() throws EndOfFileException, BacktrackException { IASTName name = null; try { - name = createName(name()); + name = createName(nameWithoutLogicalOperatorInTemplateID()); } catch (BacktrackException bt) { IToken mark = mark(); if (LT(1) == IToken.tCOLONCOLON || LT(1) == IToken.tIDENTIFIER) {