1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-31 21:05:37 +02:00

Navigation of fields, bug 292635.

This commit is contained in:
Markus Schorn 2009-10-23 07:27:33 +00:00
parent 6af575f224
commit 037ae1d1b3
7 changed files with 99 additions and 86 deletions

View file

@ -7383,15 +7383,35 @@ public class AST2CPPTests extends AST2BaseTest {
IASTTranslationUnit tu= parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP); IASTTranslationUnit tu= parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP);
checkDeclDef(declNames, defNames, tu.getDeclarations()); checkDeclDef(declNames, defNames, tu.getDeclarations());
declNames= new String[] {"v7"}; declNames= new String[] {"v7", "v8"};
defNames= new String[] {"v6", "v8"}; defNames= new String[] {"v6"};
IASTCompositeTypeSpecifier cls= getCompositeType(tu, 5); IASTCompositeTypeSpecifier cls= getCompositeType(tu, 5);
checkDeclDef(declNames, defNames, cls.getMembers()); checkDeclDef(declNames, defNames, cls.getMembers());
} }
// extern "C" int v1;
// class X {
// static const int v2= 1;
// };
// const int X::v2;
public void testVariableDefVsDecl_292635() throws Exception {
String[] declNames= {"v1"};
String[] defNames= {"X::v2"};
IASTTranslationUnit tu= parseAndCheckBindings(getAboveComment(), ParserLanguage.CPP);
checkDeclDef(declNames, defNames, tu.getDeclarations());
declNames= new String[] {"v2"};
defNames= new String[] {};
IASTCompositeTypeSpecifier cls= getCompositeType(tu, 1);
checkDeclDef(declNames, defNames, cls.getMembers());
}
private void checkDeclDef(String[] declNames, String[] defNames, IASTDeclaration[] decls) { private void checkDeclDef(String[] declNames, String[] defNames, IASTDeclaration[] decls) {
int i= 0, j= 0; int i= 0, j= 0;
for (IASTDeclaration decl : decls) { for (IASTDeclaration decl : decls) {
if (decl instanceof ICPPASTLinkageSpecification) {
decl= ((ICPPASTLinkageSpecification) decl).getDeclarations()[0];
}
final IASTDeclarator[] dtors = ((IASTSimpleDeclaration) decl).getDeclarators(); final IASTDeclarator[] dtors = ((IASTSimpleDeclaration) decl).getDeclarators();
for (IASTDeclarator dtor : dtors) { for (IASTDeclarator dtor : dtors) {
final String name = dtor.getName().toString(); final String name = dtor.getName().toString();
@ -7401,7 +7421,7 @@ public class AST2CPPTests extends AST2BaseTest {
assertEquals(declNames[i++], name); assertEquals(declNames[i++], name);
break; break;
case IASTNameOwner.r_definition: case IASTNameOwner.r_definition:
assertTrue("Unexpected decl " + name, i < defNames.length); assertTrue("Unexpected decl " + name, j < defNames.length);
assertEquals(defNames[j++], name); assertEquals(defNames[j++], name);
break; break;
default: default:

View file

@ -24,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator; import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.parser.util.ArrayUtil; 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.ASTNode;
@ -166,56 +167,60 @@ public class CPPASTDeclarator extends ASTNode implements IASTDeclarator {
public int getRoleForName(IASTName n) { public int getRoleForName(IASTName n) {
IASTNode getParent = getParent(); // 3.1.2
boolean fnDtor = (this instanceof IASTFunctionDeclarator); IASTNode parent = ASTQueries.findOutermostDeclarator(this).getParent();
if (getParent instanceof IASTDeclaration) { if (parent instanceof IASTDeclaration) {
if (getParent instanceof IASTFunctionDefinition) // a declaration is a definition unless ...
if (parent instanceof IASTFunctionDefinition)
return r_definition; return r_definition;
if (getParent instanceof IASTSimpleDeclaration) {
final int storage = ((IASTSimpleDeclaration) getParent).getDeclSpecifier().getStorageClass();
if (getInitializer() != null || storage == IASTDeclSpecifier.sc_typedef) if (parent instanceof IASTSimpleDeclaration) {
return r_definition; final IASTSimpleDeclaration sdecl = (IASTSimpleDeclaration) parent;
if (storage == IASTDeclSpecifier.sc_extern) {
return r_declaration;
}
// static member variables without initializer are declarations // unless it declares a function without body
if (!fnDtor && storage == IASTDeclSpecifier.sc_static) { if (this instanceof IASTFunctionDeclarator) {
if (CPPVisitor.getContainingScope(getParent) instanceof ICPPClassScope) { return r_declaration;
return r_declaration; }
}
} final int storage = sdecl.getDeclSpecifier().getStorageClass();
} // unless it contains the extern specifier or a linkage-specification and neither initializer nor function-body
return fnDtor ? r_declaration : r_definition; if (getInitializer() == null && (storage == IASTDeclSpecifier.sc_extern || isSimpleLinkageSpec(sdecl))) {
} return r_declaration;
if (getParent instanceof IASTTypeId) }
return r_reference; // unless it declares a static data member in a class declaration
if (getParent instanceof IASTDeclarator) { if (storage == IASTDeclSpecifier.sc_static && CPPVisitor.getContainingScope(parent) instanceof ICPPClassScope) {
IASTNode t = getParent; return r_declaration;
while (t instanceof IASTDeclarator) }
t = t.getParent(); // unless it is a class name declaration: no declarator in this case
if (t instanceof IASTDeclaration) { // unless it is a typedef declaration
if (getParent instanceof IASTFunctionDefinition) if (storage == IASTDeclSpecifier.sc_typedef)
return r_definition; return r_definition; // should actually be a declaration
if (getParent instanceof IASTSimpleDeclaration) {
if (getInitializer() != null) // unless it is a using-declaration or using-directive: no declarator in this case
return r_definition;
IASTSimpleDeclaration sd = (IASTSimpleDeclaration) getParent;
int storage = sd.getDeclSpecifier().getStorageClass();
if (storage == IASTDeclSpecifier.sc_extern || storage == IASTDeclSpecifier.sc_typedef ||
storage == IASTDeclSpecifier.sc_static) {
return r_declaration;
}
}
return fnDtor ? r_declaration : r_definition;
} }
if (t instanceof IASTTypeId)
return r_reference; // all other cases
return r_definition;
} }
if (getParent instanceof IASTParameterDeclaration)
if (parent instanceof IASTTypeId)
return r_reference;
if (parent instanceof IASTParameterDeclaration)
return (n.getLookupKey().length > 0) ? r_definition : r_declaration; return (n.getLookupKey().length > 0) ? r_definition : r_declaration;
return r_unclear; return r_unclear;
} }
private boolean isSimpleLinkageSpec(IASTSimpleDeclaration sdecl) {
IASTNode parent= sdecl.getParent();
if (parent instanceof ICPPASTLinkageSpecification) {
ICPPASTLinkageSpecification spec= (ICPPASTLinkageSpecification) parent;
// todo distinction between braced enclose and simple linkage specification
if (spec.getDeclarations().length == 1) {
return true;
}
}
return false;
}
} }

View file

@ -11,7 +11,6 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
@ -116,9 +115,4 @@ public class CPPBuiltinVariable extends CPPVariable {
public IBinding getOwner() throws DOMException { public IBinding getOwner() throws DOMException {
return null; return null;
} }
@Override
protected boolean isDefinition(IASTName name) {
return false;
}
} }

View file

@ -29,7 +29,6 @@ import org.eclipse.cdt.core.dom.ast.IPointerType;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope;
@ -94,7 +93,7 @@ public class CPPVariable extends PlatformObject implements ICPPVariable, ICPPInt
private IType type = null; private IType type = null;
public CPPVariable(IASTName name) { public CPPVariable(IASTName name) {
boolean isDef = isDefinition(name); boolean isDef = name == null ? false : name.isDefinition();
if (name instanceof ICPPASTQualifiedName) { if (name instanceof ICPPASTQualifiedName) {
IASTName[] ns = ((ICPPASTQualifiedName)name).getNames(); IASTName[] ns = ((ICPPASTQualifiedName)name).getNames();
name = ns[ns.length - 1]; name = ns[ns.length - 1];
@ -113,28 +112,6 @@ public class CPPVariable extends PlatformObject implements ICPPVariable, ICPPInt
} }
} }
protected boolean isDefinition(IASTName name) {
IASTDeclarator dtor= findDeclarator(name);
if (dtor == null) {
return false;
}
IASTSimpleDeclaration simpleDecl = (IASTSimpleDeclaration) dtor.getParent();
IASTDeclSpecifier declSpec = simpleDecl.getDeclSpecifier();
// (3.1-1) A declaration is a definition unless ...
// it contains the extern specifier or a linkage-spec and does not contain an initializer
if (dtor.getInitializer() == null && declSpec.getStorageClass() == IASTDeclSpecifier.sc_extern)
return false;
// or it declares a static data member in a class declaration
if (simpleDecl.getParent() instanceof ICPPASTCompositeTypeSpecifier &&
declSpec.getStorageClass() == IASTDeclSpecifier.sc_static) {
return false;
}
return true;
}
private IASTDeclarator findDeclarator(IASTName name) { private IASTDeclarator findDeclarator(IASTName name) {
IASTNode node = name.getParent(); IASTNode node = name.getParent();
if (node instanceof ICPPASTQualifiedName) if (node instanceof ICPPASTQualifiedName)
@ -154,7 +131,7 @@ public class CPPVariable extends PlatformObject implements ICPPVariable, ICPPInt
if (!(node instanceof IASTName)) if (!(node instanceof IASTName))
return; return;
IASTName name = (IASTName) node; IASTName name = (IASTName) node;
if (isDefinition(name)) { if (name.isDefinition()) {
definition = name; definition = name;
} else if (declarations == null) { } else if (declarations == null) {
declarations = new IASTName[] { name }; declarations = new IASTName[] { name };
@ -316,8 +293,8 @@ public class CPPVariable extends PlatformObject implements ICPPVariable, ICPPInt
} }
IASTNode[] ds= getDeclarations(); IASTNode[] ds= getDeclarations();
if (ds != null) { if (ds != null) {
for (int i = 0; i < ds.length; i++) { for (IASTNode element : ds) {
if (CPPVisitor.isExternC(ds[i])) { if (CPPVisitor.isExternC(element)) {
return true; return true;
} }
} }

View file

@ -68,6 +68,8 @@ public final class CSearchMessages extends NLS {
public static String PDOMSearchQuery_refs_result_label; public static String PDOMSearchQuery_refs_result_label;
public static String PDOMSearchQuery_defs_result_label; public static String PDOMSearchQuery_defs_result_label;
public static String PDOMSearchQuery_decls_result_label; public static String PDOMSearchQuery_decls_result_label;
public static String PDOMSearchQuery_decldefs_result_label;
public static String PDOMSearchQuery_occurrences_result_label;
public static String PDOMSearchElementQuery_something; public static String PDOMSearchElementQuery_something;
public static String PDOMSearchPatternQuery_PatternQuery_labelPatternInScope; public static String PDOMSearchPatternQuery_PatternQuery_labelPatternInScope;
public static String PDOMSearch_query_pattern_error; public static String PDOMSearch_query_pattern_error;

View file

@ -70,9 +70,12 @@ ProjectScope = Project
PDOMSearchQuery_refs_label = Search references PDOMSearchQuery_refs_label = Search references
PDOMSearchQuery_defs_label = Search definitions PDOMSearchQuery_defs_label = Search definitions
PDOMSearchQuery_decls_label = Search declarations PDOMSearchQuery_decls_label = Search declarations
PDOMSearchQuery_refs_result_label = References to {0} PDOMSearchQuery_refs_result_label = References to ''{0}''
PDOMSearchQuery_defs_result_label = Definitions of {0} PDOMSearchQuery_defs_result_label = Definitions of ''{0}''
PDOMSearchQuery_decls_result_label = Declarations of {0} PDOMSearchQuery_decls_result_label = Declarations of ''{0}''
PDOMSearchQuery_decldefs_result_label = Declarations and definitions of ''{0}''
PDOMSearchQuery_occurrences_result_label = Occurrences of ''{0}''
PDOMSearchElementQuery_something = something PDOMSearchElementQuery_something = something
PDOMSearchPatternQuery_PatternQuery_labelPatternInScope={0} in {1} PDOMSearchPatternQuery_PatternQuery_labelPatternInScope={0} in {1}
PDOMSearchTreeContentProvider_IndexerNotEnabledWarning=(unknown results: indexer is not enabled) PDOMSearchTreeContentProvider_IndexerNotEnabledWarning=(unknown results: indexer is not enabled)

View file

@ -151,12 +151,24 @@ public abstract class PDOMSearchQuery implements ISearchQuery {
public String getResultLabel(String pattern, int matchCount) { public String getResultLabel(String pattern, int matchCount) {
// Report pattern and number of matches // Report pattern and number of matches
String label; String label;
if ((flags & FIND_REFERENCES) != 0) final int kindFlags= flags & FIND_ALL_OCCURANCES;
switch(kindFlags) {
case FIND_REFERENCES:
label = NLS.bind(CSearchMessages.PDOMSearchQuery_refs_result_label, pattern); label = NLS.bind(CSearchMessages.PDOMSearchQuery_refs_result_label, pattern);
else if ((flags & FIND_DECLARATIONS) != 0) break;
case FIND_DECLARATIONS:
label = NLS.bind(CSearchMessages.PDOMSearchQuery_decls_result_label, pattern); label = NLS.bind(CSearchMessages.PDOMSearchQuery_decls_result_label, pattern);
else break;
case FIND_DEFINITIONS:
label = NLS.bind(CSearchMessages.PDOMSearchQuery_defs_result_label, pattern); label = NLS.bind(CSearchMessages.PDOMSearchQuery_defs_result_label, pattern);
break;
case FIND_DECLARATIONS_DEFINITIONS:
label = NLS.bind(CSearchMessages.PDOMSearchQuery_decldefs_result_label, pattern);
break;
default:
label = NLS.bind(CSearchMessages.PDOMSearchQuery_occurrences_result_label, pattern);
break;
}
String countLabel = Messages.format(CSearchMessages.CSearchResultCollector_matches, new Integer( String countLabel = Messages.format(CSearchMessages.CSearchResultCollector_matches, new Integer(
matchCount)); matchCount));
return label + " " + countLabel; //$NON-NLS-1$ return label + " " + countLabel; //$NON-NLS-1$