From 119db5a9164397cf8896ea9788a2138c3b610c3a Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Wed, 19 Aug 2009 08:56:35 +0000 Subject: [PATCH] Definition vs. declaration for static variables, bug 286259. --- .../core/parser/tests/ast2/AST2CPPTests.java | 48 +++++++++++++++++++ .../core/dom/parser/cpp/CPPASTDeclarator.java | 27 +++++++---- 2 files changed, 66 insertions(+), 9 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 269566c45f7..ad4d48d1bea 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 @@ -45,6 +45,7 @@ import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression; import org.eclipse.cdt.core.dom.ast.IASTLabelStatement; import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression; import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNameOwner; import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTProblemDeclaration; import org.eclipse.cdt.core.dom.ast.IASTReturnStatement; @@ -7363,4 +7364,51 @@ public class AST2CPPTests extends AST2BaseTest { public void testTypeLookupWithMultipleInheritance_286213() throws Exception { parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP); } + + // int v1; + // static int v2; + // extern int v3; + // int v4= 12; + // static int v5= 1; + // class X { + // int v6; + // static const int v7; + // static const int v8= 1; + // }; + // const int X::v7= 1; + public void testVariableDefVsDecl_286259() throws Exception { + String[] declNames= {"v3"}; + String[] defNames= {"v1", "v2", "v4", "v5", "X::v7"}; + IASTTranslationUnit tu= parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP); + checkDeclDef(declNames, defNames, tu.getDeclarations()); + + declNames= new String[] {"v7"}; + defNames= new String[] {"v6", "v8"}; + IASTCompositeTypeSpecifier cls= getCompositeType(tu, 5); + checkDeclDef(declNames, defNames, cls.getMembers()); + } + + private void checkDeclDef(String[] declNames, String[] defNames, IASTDeclaration[] decls) { + int i=0, j=0; + for (IASTDeclaration decl : decls) { + final IASTDeclarator[] dtors = ((IASTSimpleDeclaration) decl).getDeclarators(); + for (IASTDeclarator dtor : dtors) { + final String name = dtor.getName().toString(); + switch (dtor.getRoleForName(dtor.getName())) { + case IASTNameOwner.r_declaration: + assertTrue("Unexpected decl " + name, i < declNames.length); + assertEquals(declNames[i++], name); + break; + case IASTNameOwner.r_definition: + assertTrue("Unexpected decl " + name, i < defNames.length); + assertEquals(defNames[j++], name); + break; + default: + assertTrue(name, false); + } + } + } + assertEquals(declNames.length, i); + assertEquals(defNames.length, j); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeclarator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeclarator.java index a651bfacf1a..7b80479a2f2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeclarator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeclarator.java @@ -24,9 +24,11 @@ import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.IASTPointerOperator; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IASTTypeId; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTQueries; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; /** * C++ specific declarator. @@ -169,15 +171,22 @@ public class CPPASTDeclarator extends ASTNode implements IASTDeclarator { if (getParent instanceof IASTDeclaration) { if (getParent instanceof IASTFunctionDefinition) return r_definition; - if (getParent instanceof IASTSimpleDeclaration) { - final int storage = ((IASTSimpleDeclaration) getParent).getDeclSpecifier().getStorageClass(); - if (getInitializer() != null || storage == IASTDeclSpecifier.sc_typedef) - return r_definition; - - if (storage == IASTDeclSpecifier.sc_extern || storage == IASTDeclSpecifier.sc_static) { - return r_declaration; - } - } + if (getParent instanceof IASTSimpleDeclaration) { + final int storage = ((IASTSimpleDeclaration) getParent).getDeclSpecifier().getStorageClass(); + + if (getInitializer() != null || storage == IASTDeclSpecifier.sc_typedef) + return r_definition; + if (storage == IASTDeclSpecifier.sc_extern) { + return r_declaration; + } + + // static member variables without initializer are declarations + if (!fnDtor && storage == IASTDeclSpecifier.sc_static) { + if (CPPVisitor.getContainingScope(getParent) instanceof ICPPClassScope) { + return r_declaration; + } + } + } return fnDtor ? r_declaration : r_definition; } if (getParent instanceof IASTTypeId)