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 bdfba2e8b17..e9603b47d7c 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 @@ -5993,4 +5993,18 @@ public class AST2Tests extends AST2BaseTest { bh= new BindingAssertionHelper(code, false); bh.assertProblem("TInt; //ref", 4); } + + // typedef int x, y; + // void func(int c) { + // c= sizeof(x(y)); + // x(y); + // } + public void testSizeofFunctionType_252243() throws Exception { + final String code= getAboveComment(); + for (ParserLanguage lang : ParserLanguage.values()) { + BindingAssertionHelper ba= new BindingAssertionHelper(code, lang == ParserLanguage.CPP); + ba.assertProblem("y));", 1); + IVariable v= ba.assertNonProblem("y);", 1); + } + } } 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 2c1f63d2051..b8178ed989e 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 @@ -17,7 +17,6 @@ import org.eclipse.cdt.core.dom.ast.ASTCompletionNode; import org.eclipse.cdt.core.dom.ast.ASTGenericVisitor; import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTASMDeclaration; -import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator; import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; import org.eclipse.cdt.core.dom.ast.IASTBreakStatement; import org.eclipse.cdt.core.dom.ast.IASTCaseStatement; @@ -38,7 +37,6 @@ import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpressionList; import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement; -import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFileLocation; import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; @@ -1776,23 +1774,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { backup(lastTokenOfExpression); consume(); return expressionStatement; } - - // a function call interpreted as declaration: 'func(x);' --> 'func x;' - if (declarators.length == 1) { - IASTName name= ((IASTNamedTypeSpecifier) declspec).getName(); - final IASTDeclarator dtor= declarators[0]; - if (name.contains(declspec)) { - if (dtor.getNestedDeclarator() != null) { - if (dtor instanceof IASTAmbiguousDeclarator == false - && dtor instanceof IASTArrayDeclarator == false - && dtor instanceof IASTFieldDeclarator == false - && dtor instanceof IASTFunctionDeclarator == false) { - backup(lastTokenOfExpression); consume(); - return expressionStatement; - } - } - } - } } } @@ -2090,7 +2071,9 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { consume(IToken.tLPAREN); int typeidOffset= LA(1).getOffset(); typeid= typeId(DeclarationOptions.TYPEID); - if (typeid != null) { + if (!isValidTypeIDForUnaryExpression(unaryExprKind, typeid)) { + typeid= null; + } else { switch(LT(1)) { case IToken.tRPAREN: case IToken.tEOC: @@ -2167,7 +2150,18 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { return ambExpr; } - protected abstract IASTAmbiguousExpression createAmbiguousExpression(); + private boolean isValidTypeIDForUnaryExpression(int unaryExprKind, IASTTypeId typeid) { + if (typeid == null) + return false; + if (unaryExprKind == IASTUnaryExpression.op_sizeof) { + // 5.3.3.1 + if (ASTQueries.findTypeRelevantDeclarator(typeid.getAbstractDeclarator()) instanceof IASTFunctionDeclarator) + return false; + } + return true; + } + + protected abstract IASTAmbiguousExpression createAmbiguousExpression(); protected abstract IASTAmbiguousExpression createAmbiguousBinaryVsCastExpression(IASTBinaryExpression binary, IASTCastExpression castExpr); protected abstract IASTAmbiguousExpression createAmbiguousCastVsFunctionCallExpression(IASTCastExpression castExpr, IASTFunctionCallExpression funcCall); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguityResolver.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguityResolver.java index 40b4192bc8f..8efd4bf19fc 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguityResolver.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguityResolver.java @@ -10,10 +10,8 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; -import java.util.ArrayList; import java.util.HashSet; import java.util.LinkedList; -import java.util.List; import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; @@ -25,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTInitializer; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode; @@ -36,22 +35,10 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; * Visitor to resolve ast ambiguities in the right order */ final class CPPASTAmbiguityResolver extends ASTVisitor { - private static class ClassContext { - ArrayList fDeferredNodes; - final IASTNode fNode; - public ClassContext(IASTNode node) { - fNode= node; - } - public void deferNode(IASTNode node) { - if (fDeferredNodes == null) - fDeferredNodes= new ArrayList(); - fDeferredNodes.add(node); - } - } - private LinkedList fContextStack; - private ClassContext fCurrentContext; private int fSkipInitializers= 0; + private int fDeferFunctions= 1; private HashSet fRepopulate= new HashSet(); + private LinkedList fDeferredNodes= new LinkedList(); public CPPASTAmbiguityResolver() { super(false); @@ -60,6 +47,7 @@ final class CPPASTAmbiguityResolver extends ASTVisitor { shouldVisitDeclarations= true; shouldVisitDeclSpecifiers= true; shouldVisitInitializers= true; + shouldVisitTranslationUnit= true; } @Override @@ -91,13 +79,7 @@ final class CPPASTAmbiguityResolver extends ASTVisitor { @Override public int visit(IASTDeclSpecifier declSpec) { if (declSpec instanceof ICPPASTCompositeTypeSpecifier) { - if (fCurrentContext != null) { - // defer visiting nested classes until the outer class body has been visited. - fCurrentContext.deferNode(declSpec); - return PROCESS_SKIP; - } - pushContext(); - fCurrentContext= new ClassContext(declSpec); + fDeferFunctions++; } return PROCESS_CONTINUE; } @@ -105,46 +87,14 @@ final class CPPASTAmbiguityResolver extends ASTVisitor { @Override public int leave(IASTDeclSpecifier declSpec) { if (declSpec instanceof ICPPASTCompositeTypeSpecifier) { - assert fCurrentContext != null; - assert fCurrentContext.fNode == declSpec; - if (fCurrentContext != null) { - final List deferredNodes = fCurrentContext.fDeferredNodes; - fCurrentContext= null; - if (deferredNodes != null) { - for (IASTNode node : deferredNodes) { - node.accept(this); - } - } - popContext(); - } + fDeferFunctions--; } return PROCESS_CONTINUE; } - private void pushContext() { - if (fCurrentContext==null) { - if (fContextStack != null && !fContextStack.isEmpty()) { - fContextStack.addLast(null); - } - } else { - if (fContextStack == null) { - fContextStack= new LinkedList(); - } - fContextStack.addLast(fCurrentContext); - } - } - - private void popContext() { - if (fContextStack == null || fContextStack.isEmpty()) { - fCurrentContext= null; - } else { - fCurrentContext= fContextStack.removeLast(); - } - } - @Override public int visit(IASTDeclaration decl) { - if (decl instanceof IASTFunctionDefinition) { + if (fDeferFunctions > 0 && decl instanceof IASTFunctionDefinition) { final IASTFunctionDefinition fdef= (IASTFunctionDefinition) decl; // visit the declarator first, it may contain ambiguous template arguments needed @@ -152,13 +102,10 @@ final class CPPASTAmbiguityResolver extends ASTVisitor { fSkipInitializers++; ASTQueries.findOutermostDeclarator(fdef.getDeclarator()).accept(this); fSkipInitializers--; - - if (fCurrentContext != null) { - // defer visiting the body of the function until the class body has been visited. - fdef.getDeclSpecifier().accept(this); - fCurrentContext.deferNode(decl); - return PROCESS_SKIP; - } + fdef.getDeclSpecifier().accept(this); + // defer visiting the body of the function until the class body has been visited. + fDeferredNodes.add(decl); + return PROCESS_SKIP; } return PROCESS_CONTINUE; } @@ -171,6 +118,23 @@ final class CPPASTAmbiguityResolver extends ASTVisitor { return PROCESS_CONTINUE; } + @Override + public int visit(IASTInitializer initializer) { + if (fSkipInitializers > 0) + return PROCESS_SKIP; + + return PROCESS_CONTINUE; + } + + @Override + public int leave(IASTTranslationUnit tu) { + while (!fDeferredNodes.isEmpty()) { + fDeferFunctions= 0; + fDeferredNodes.removeFirst().accept(this); + } + return PROCESS_CONTINUE; + } + private void repopulateScope(IASTDeclaration declaration) { IScope scope= CPPVisitor.getContainingNonTemplateScope(declaration); if (scope instanceof ICPPASTInternalScope) { @@ -183,12 +147,4 @@ final class CPPASTAmbiguityResolver extends ASTVisitor { CPPSemantics.populateCache((ICPPASTInternalScope) scope, declaration); } } - - @Override - public int visit(IASTInitializer initializer) { - if (fSkipInitializers > 0) - return PROCESS_SKIP; - - return PROCESS_CONTINUE; - } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java index 44da197ac59..87d28514db5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java @@ -271,13 +271,15 @@ public class LookupData { return true; } if (p1 instanceof IASTExpression) { + ASTNodeProperty prop = p1.getPropertyInParent(); if (p1 instanceof IASTIdExpression) { p1= p1.getParent(); } while (p1 instanceof IASTUnaryExpression && ((IASTUnaryExpression) p1).getOperator() == IASTUnaryExpression.op_bracketedPrimary) { + prop = p1.getPropertyInParent(); p1= p1.getParent(); } - if (p1 instanceof IASTFunctionCallExpression) { + if (p1 instanceof IASTFunctionCallExpression && prop == IASTFunctionCallExpression.FUNCTION_NAME) { return true; } } else if (p1 instanceof ICPPASTNamedTypeSpecifier && p2 instanceof IASTTypeId) {