mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Merge remote branch 'cdt/master' into sd90
This commit is contained in:
commit
51c3ece9b3
26 changed files with 449 additions and 51 deletions
|
@ -2,7 +2,7 @@ Manifest-Version: 1.0
|
|||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: %pluginName
|
||||
Bundle-SymbolicName: org.eclipse.cdt.make.core; singleton:=true
|
||||
Bundle-Version: 7.1.0.qualifier
|
||||
Bundle-Version: 7.2.0.qualifier
|
||||
Bundle-Activator: org.eclipse.cdt.make.core.MakeCorePlugin
|
||||
Bundle-Vendor: %providerName
|
||||
Bundle-Localization: plugin
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<version>7.1.0-SNAPSHOT</version>
|
||||
<version>7.2.0-SNAPSHOT</version>
|
||||
<artifactId>org.eclipse.cdt.make.core</artifactId>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
</project>
|
||||
|
|
|
@ -2,7 +2,7 @@ Manifest-Version: 1.0
|
|||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: %pluginName
|
||||
Bundle-SymbolicName: org.eclipse.cdt.make.ui; singleton:=true
|
||||
Bundle-Version: 7.1.0.qualifier
|
||||
Bundle-Version: 7.2.0.qualifier
|
||||
Bundle-Activator: org.eclipse.cdt.make.internal.ui.MakeUIPlugin
|
||||
Bundle-Vendor: %providerName
|
||||
Bundle-Localization: plugin
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<version>7.1.0-SNAPSHOT</version>
|
||||
<version>7.2.0-SNAPSHOT</version>
|
||||
<artifactId>org.eclipse.cdt.make.ui</artifactId>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
</project>
|
||||
|
|
|
@ -2,7 +2,7 @@ Manifest-Version: 1.0
|
|||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Tests
|
||||
Bundle-SymbolicName: org.eclipse.cdt.managedbuilder.core.tests; singleton:=true
|
||||
Bundle-Version: 8.0.0.qualifier
|
||||
Bundle-Version: 8.1.0.qualifier
|
||||
Bundle-Activator: org.eclipse.cdt.managedbuilder.testplugin.CTestPlugin
|
||||
Bundle-Vendor: Eclipse CDT
|
||||
Bundle-Localization: plugin
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<version>8.0.0-SNAPSHOT</version>
|
||||
<version>8.1.0-SNAPSHOT</version>
|
||||
<artifactId>org.eclipse.cdt.managedbuilder.core.tests</artifactId>
|
||||
<packaging>eclipse-test-plugin</packaging>
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ Manifest-Version: 1.0
|
|||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: %pluginName
|
||||
Bundle-SymbolicName: org.eclipse.cdt.managedbuilder.core; singleton:=true
|
||||
Bundle-Version: 8.0.0.qualifier
|
||||
Bundle-Version: 8.1.0.qualifier
|
||||
Bundle-Activator: org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin
|
||||
Bundle-Vendor: %providerName
|
||||
Bundle-Localization: plugin
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<version>8.0.0-SNAPSHOT</version>
|
||||
<version>8.1.0-SNAPSHOT</version>
|
||||
<artifactId>org.eclipse.cdt.managedbuilder.core</artifactId>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
</project>
|
||||
|
|
|
@ -18,6 +18,8 @@ import java.util.StringTokenizer;
|
|||
import java.util.Vector;
|
||||
|
||||
import org.eclipse.cdt.core.language.settings.providers.ScannerDiscoveryLegacySupport;
|
||||
import org.eclipse.cdt.core.model.ILanguage;
|
||||
import org.eclipse.cdt.core.model.LanguageManager;
|
||||
import org.eclipse.cdt.core.settings.model.ICStorageElement;
|
||||
import org.eclipse.cdt.core.settings.model.util.CDataUtil;
|
||||
import org.eclipse.cdt.internal.core.SafeStringInterner;
|
||||
|
@ -1701,6 +1703,15 @@ public class InputType extends BuildObject implements IInputType {
|
|||
langId = getLanguageIdAttribute();
|
||||
}
|
||||
|
||||
if(langId == null){
|
||||
IContentType contentType = getSourceContentType();
|
||||
if (contentType!=null) {
|
||||
ILanguage language = LanguageManager.getInstance().getLanguage(contentType);
|
||||
if (language!=null)
|
||||
langId = language.getId();
|
||||
}
|
||||
}
|
||||
|
||||
return langId;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ Manifest-Version: 1.0
|
|||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: %pluginName
|
||||
Bundle-SymbolicName: org.eclipse.cdt.managedbuilder.gnu.ui; singleton:=true
|
||||
Bundle-Version: 8.0.0.qualifier
|
||||
Bundle-Version: 8.1.0.qualifier
|
||||
Bundle-Activator: org.eclipse.cdt.managedbuilder.gnu.ui.GnuUIPlugin
|
||||
Bundle-Vendor: %providerName
|
||||
Bundle-Localization: plugin
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<version>8.0.0-SNAPSHOT</version>
|
||||
<version>8.1.0-SNAPSHOT</version>
|
||||
<artifactId>org.eclipse.cdt.managedbuilder.gnu.ui</artifactId>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
</project>
|
||||
|
|
|
@ -464,4 +464,15 @@ public class IndexCBindingResolutionBugs extends IndexBindingResolutionTestBase
|
|||
getBindingFromASTName("f255", 0);
|
||||
getBindingFromASTName("f256", 0);
|
||||
}
|
||||
|
||||
// struct B {
|
||||
// float f;
|
||||
// };
|
||||
|
||||
// struct B b = {
|
||||
// .f = 3.1
|
||||
// };
|
||||
public void testDesignatedInitializer_Bug210019() throws Exception {
|
||||
IField f= getBindingFromASTName("f", 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1584,6 +1584,19 @@ public abstract class IndexCPPBindingResolutionTest extends IndexBindingResoluti
|
|||
getBindingFromASTName("g(1)", 1);
|
||||
}
|
||||
|
||||
// namespace ns {
|
||||
// void fun();
|
||||
// }
|
||||
|
||||
// namespace alias = ns;
|
||||
// void alias::fun() {
|
||||
// }
|
||||
public void testNamespaceAliasAsQualifier_356493() throws Exception {
|
||||
IFunction ref= getBindingFromASTName("fun", 0);
|
||||
assertEquals("ns", ref.getOwner().getName());
|
||||
}
|
||||
|
||||
|
||||
/* CPP assertion helpers */
|
||||
/* ##################################################################### */
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2005, 2009 QNX Software Systems and others.
|
||||
* Copyright (c) 2005, 2011 QNX Software Systems and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -118,8 +118,7 @@ public class LanguageManager {
|
|||
HashMap<String, ILanguageDescriptor[]> map = new HashMap<String, ILanguageDescriptor[]>();
|
||||
Map<String, List<ILanguageDescriptor>> cache = getContentTypeToDescriptorCache();
|
||||
|
||||
for (Iterator<Entry<String, List<ILanguageDescriptor>>> iter = cache.entrySet().iterator(); iter.hasNext();) {
|
||||
Entry<String, List<ILanguageDescriptor>> entry = iter.next();
|
||||
for (Entry<String, List<ILanguageDescriptor>> entry : cache.entrySet()) {
|
||||
List<ILanguageDescriptor> list = entry.getValue();
|
||||
if (list.size() > 0) {
|
||||
ILanguageDescriptor[] dess = list.toArray(new ILanguageDescriptor[list.size()]);
|
||||
|
@ -136,13 +135,10 @@ public class LanguageManager {
|
|||
Map<String, ILanguageDescriptor> dc = getDescriptorCache();
|
||||
|
||||
List<ILanguageDescriptor> list;
|
||||
IContentType type;
|
||||
String id;
|
||||
for (Iterator<ILanguageDescriptor> iter = dc.values().iterator(); iter.hasNext();) {
|
||||
ILanguageDescriptor des = iter.next();
|
||||
for (ILanguageDescriptor des : dc.values()) {
|
||||
IContentType types[] = des.getContentTypes();
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
type = types[i];
|
||||
for (IContentType type : types) {
|
||||
id = type.getId();
|
||||
list = map.get(id);
|
||||
if (list == null) {
|
||||
|
@ -326,8 +322,7 @@ public class LanguageManager {
|
|||
|
||||
// read configuration
|
||||
IConfigurationElement[] configs= Platform.getExtensionRegistry().getConfigurationElementsFor(LANGUAGE_EXTENSION_POINT_ID);
|
||||
for (int i = 0; i < configs.length; i++) {
|
||||
final IConfigurationElement element = configs[i];
|
||||
for (final IConfigurationElement element : configs) {
|
||||
if (ELEMENT_PDOM_LINKAGE_FACTORY.equals(element.getName())) {
|
||||
SafeRunner.run(new ISafeRunnable() {
|
||||
public void handleException(Throwable exception) {
|
||||
|
@ -616,8 +611,8 @@ public class LanguageManager {
|
|||
public void notifyLanguageChangeListeners(ILanguageMappingChangeEvent event) {
|
||||
Object[] listeners = fLanguageChangeListeners.getListeners();
|
||||
|
||||
for (int i= 0; i < listeners.length; i++) {
|
||||
ILanguageMappingChangeListener listener = (ILanguageMappingChangeListener) listeners[i];
|
||||
for (Object obj : listeners) {
|
||||
ILanguageMappingChangeListener listener = (ILanguageMappingChangeListener) obj;
|
||||
listener.handleLanguageMappingChangeEvent(event);
|
||||
}
|
||||
}
|
||||
|
@ -645,4 +640,47 @@ public class LanguageManager {
|
|||
event.setFile(file);
|
||||
notifyLanguageChangeListeners(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns language binding to a particular content type for given project.
|
||||
* This method will check project settings, workspace settings and default
|
||||
* bindings (in that order)
|
||||
*
|
||||
* @param contentType content type of the file
|
||||
* @param project C/C++ workspace project
|
||||
* @return CDT language object
|
||||
* @since 5.4
|
||||
*/
|
||||
public ILanguage getLanguage(IContentType contentType, IProject project) {
|
||||
return getLanguage(contentType, project, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns language binding to a particular content type for given project.
|
||||
* This method will check project settings, workspace settings and default
|
||||
* bindings (in that order)
|
||||
*
|
||||
* @param contentType content type of the file
|
||||
* @param project C/C++ workspace project
|
||||
* @param configurationDescription build configuration or <code>null</code>
|
||||
* @return CDT language object
|
||||
* @since 5.4
|
||||
*/
|
||||
public ILanguage getLanguage(IContentType contentType,
|
||||
IProject project, ICConfigurationDescription configurationDescription) {
|
||||
try {
|
||||
final ProjectLanguageConfiguration projectConfig = getLanguageConfiguration(project);
|
||||
final String contentTypeId = contentType.getId();
|
||||
String langId = projectConfig.getLanguageForContentType(configurationDescription,
|
||||
contentTypeId);
|
||||
if (langId == null) {
|
||||
WorkspaceLanguageConfiguration wsConfig = getWorkspaceLanguageConfiguration();
|
||||
langId = wsConfig.getLanguageForContentType(contentTypeId);
|
||||
}
|
||||
return langId != null ? getLanguage(langId) : getLanguage(contentType);
|
||||
} catch (CoreException e) {
|
||||
// Fall through to default language mapping
|
||||
}
|
||||
return getLanguage(contentType);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -887,8 +887,8 @@ public class CVisitor extends ASTQueries {
|
|||
else if (simpleDecl.getDeclSpecifier() instanceof IASTCompositeTypeSpecifier)
|
||||
struct = ((IASTCompositeTypeSpecifier) simpleDecl.getDeclSpecifier()).getName().resolveBinding();
|
||||
|
||||
if (struct instanceof CStructure) {
|
||||
return ((CStructure) struct).findField(((ICASTFieldDesignator) node).getName().toString());
|
||||
if (struct instanceof ICompositeType) {
|
||||
return ((ICompositeType) struct).findField(((ICASTFieldDesignator) node).getName().toString());
|
||||
} else if (struct instanceof ITypeContainer) {
|
||||
IType type;
|
||||
type = ((ITypeContainer) struct).getType();
|
||||
|
|
|
@ -137,6 +137,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceAlias;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
|
||||
|
@ -2319,7 +2320,7 @@ public class CPPVisitor extends ASTQueries {
|
|||
}
|
||||
if (--i < 0)
|
||||
break;
|
||||
return qn[i].resolveBinding();
|
||||
return bindingToOwner(qn[i].resolveBinding());
|
||||
}
|
||||
name= (IASTName) node;
|
||||
node= node.getParent();
|
||||
|
@ -2327,6 +2328,20 @@ public class CPPVisitor extends ASTQueries {
|
|||
return findDeclarationOwner(node, allowFunction);
|
||||
}
|
||||
|
||||
private static IBinding bindingToOwner(IBinding b) {
|
||||
if (b instanceof ITypedef) {
|
||||
IType t= SemanticUtil.getNestedType((IType) b, TDEF);
|
||||
if (t instanceof IBinding)
|
||||
return (IBinding) t;
|
||||
|
||||
return b;
|
||||
}
|
||||
while (b instanceof ICPPNamespaceAlias) {
|
||||
b= ((ICPPNamespaceAlias) b).getBinding();
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for the first class, namespace, or function, if <code>allowFunction</code>
|
||||
* is <code>true</code>, enclosing the declaration the provided node belongs to and returns
|
||||
|
|
|
@ -166,9 +166,10 @@ public abstract class PDOMIndexerTask extends AbstractIndexerTask implements IPD
|
|||
|
||||
@Override
|
||||
protected AbstractLanguage[] getLanguages(String filename) {
|
||||
IContentType ct= CCorePlugin.getContentType(getProject().getProject(), filename);
|
||||
IProject project = getProject().getProject();
|
||||
IContentType ct= CCorePlugin.getContentType(project, filename);
|
||||
if (ct != null) {
|
||||
ILanguage l = LanguageManager.getInstance().getLanguage(ct);
|
||||
ILanguage l = LanguageManager.getInstance().getLanguage(ct, project);
|
||||
if (l instanceof AbstractLanguage) {
|
||||
if (filename.indexOf('.') >= 0 && ct.getId().equals(CCorePlugin.CONTENT_TYPE_CXXHEADER) &&
|
||||
l.getLinkageID() == ILinkage.CPP_LINKAGE_ID) {
|
||||
|
|
|
@ -98,6 +98,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter;
|
||||
import org.eclipse.cdt.core.index.IIndex;
|
||||
import org.eclipse.cdt.core.index.IIndexBinding;
|
||||
import org.eclipse.cdt.core.index.IIndexName;
|
||||
import org.eclipse.cdt.core.model.CoreModel;
|
||||
import org.eclipse.cdt.core.model.ICElement;
|
||||
|
@ -183,13 +184,26 @@ public class ASTManager implements IDisposable {
|
|||
* Returns TRUE, FALSE or UNKNOWN.
|
||||
* @throws DOMException
|
||||
*/
|
||||
public static int isSameBinding(IBinding b1, IBinding b2) throws DOMException {
|
||||
public static int isSameBinding(IIndex index, IBinding b1, IBinding b2) throws DOMException {
|
||||
if (b1 == null || b2 == null) {
|
||||
return UNKNOWN;
|
||||
}
|
||||
if (b1.equals(b2)) {
|
||||
return TRUE;
|
||||
}
|
||||
if (b1 instanceof IIndexBinding || b2 instanceof IIndexBinding) {
|
||||
if (index != null) {
|
||||
IIndexBinding b11 = index.adaptBinding(b1);
|
||||
if (b11 != null)
|
||||
b1= b11;
|
||||
IIndexBinding b21 = index.adaptBinding(b2);
|
||||
if (b21 != null)
|
||||
b2= b21;
|
||||
if (b1.equals(b2))
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
String n1= b1.getName();
|
||||
String n2= b2.getName();
|
||||
if (n1 == null || n2 == null) {
|
||||
|
@ -1191,9 +1205,11 @@ public class ASTManager implements IDisposable {
|
|||
if (problemInQualifier) {
|
||||
cmp= UNKNOWN;
|
||||
} else {
|
||||
final IASTTranslationUnit tu = name.getTranslationUnit();
|
||||
final IIndex index= tu != null ? tu.getIndex() : null;
|
||||
for (IBinding renameBinding : fValidBindings) {
|
||||
try {
|
||||
int cmp0= isSameBinding(binding, renameBinding);
|
||||
int cmp0= isSameBinding(index, binding, renameBinding);
|
||||
if (cmp0 != FALSE) {
|
||||
cmp= cmp0;
|
||||
}
|
||||
|
@ -1486,7 +1502,7 @@ public class ASTManager implements IDisposable {
|
|||
for (int i = 0; !isAboveOrEqual && i<newBindingsAboverOrEqual.length; i++) {
|
||||
IBinding aboveBinding = newBindingsAboverOrEqual[i];
|
||||
try {
|
||||
if (isSameBinding(aboveBinding, conflictingBinding) == TRUE) {
|
||||
if (isSameBinding(tu.getIndex(), aboveBinding, conflictingBinding) == TRUE) {
|
||||
isAboveOrEqual= true;
|
||||
}
|
||||
} catch (DOMException e) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008, 2010 Monta Vista and others.
|
||||
* Copyright (c) 2008, 2011 Monta Vista and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
@ -12,6 +12,7 @@
|
|||
* Ericsson - Major re-factoring to deal with children
|
||||
* Axel Mueller - Bug 306555 - Add support for cast to type / view as array (IExpressions2)
|
||||
* Jens Elmenthaler (Verigy) - Added Full GDB pretty-printing support (bug 302121)
|
||||
* Axel Mueller - Workaround for GDB bug where -var-info-path-expression gives invalid result (Bug 320277)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.dsf.mi.service;
|
||||
|
||||
|
@ -64,6 +65,7 @@ import org.eclipse.cdt.dsf.mi.service.command.output.ExprMetaGetChildCountInfo;
|
|||
import org.eclipse.cdt.dsf.mi.service.command.output.ExprMetaGetChildrenInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.ExprMetaGetValueInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.ExprMetaGetVarInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIDataEvaluateExpressionInfo;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIDisplayHint;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIDisplayHint.GdbDisplayHint;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.output.MIInfo;
|
||||
|
@ -378,6 +380,15 @@ public class MIVariableManager implements ICommandControl {
|
|||
|
||||
private boolean fetchingChildren = false;
|
||||
|
||||
|
||||
/**
|
||||
* In case of base class variables that are accessed in a derived class
|
||||
* we cannot trust var-info-path-expression because of a bug in gdb.
|
||||
* We have to use a workaround and apply it to the complete hierarchy of this varObject.
|
||||
* Bug 320277
|
||||
*/
|
||||
private boolean hasCastToBaseClassWorkaround = false;
|
||||
|
||||
public MIVariableObject(VariableObjectId id, MIVariableObject parentObj) {
|
||||
this(id, parentObj, false);
|
||||
}
|
||||
|
@ -1352,15 +1363,43 @@ public class MIVariableManager implements ICommandControl {
|
|||
|
||||
numSubRequests++;
|
||||
|
||||
final DataRequestMonitor<String> childPathRm =
|
||||
new DataRequestMonitor<String>(fSession.getExecutor(), countingRm) {
|
||||
// Class to keep track of the child's full expression, but also
|
||||
// if that child had to use the CastToBaseClassWorkaround,
|
||||
// which needs to be propagated to its own children.
|
||||
class ChildFullExpressionInfo {
|
||||
private String childFullExpression;
|
||||
private boolean childHasCastToBaseClassWorkaround;
|
||||
|
||||
public ChildFullExpressionInfo(String path) {
|
||||
this(path, false);
|
||||
}
|
||||
|
||||
public ChildFullExpressionInfo(String path, boolean hasWorkaround) {
|
||||
childFullExpression = path == null ? "" : path; //$NON-NLS-1$
|
||||
childHasCastToBaseClassWorkaround = hasWorkaround;
|
||||
}
|
||||
|
||||
public String getChildPath() { return childFullExpression; }
|
||||
public boolean getChildHasCastToBaseClassWorkaround() { return childHasCastToBaseClassWorkaround; }
|
||||
};
|
||||
|
||||
final DataRequestMonitor<ChildFullExpressionInfo> childPathRm =
|
||||
new DataRequestMonitor<ChildFullExpressionInfo>(fSession.getExecutor(), countingRm) {
|
||||
@Override
|
||||
protected void handleSuccess() {
|
||||
final String childPath = getData().getChildPath();
|
||||
// The child varObj we are about to create should have hasCastToBaseClassWorkaround
|
||||
// set in two conditions:
|
||||
// 1- if its parent was set (which is the current varObj)
|
||||
// 2- if the workaround was used for the child itself, which is part of ChildFullExpressionInfo
|
||||
final boolean childHasCastToBaseClassWorkaround =
|
||||
hasCastToBaseClassWorkaround || getData().getChildHasCastToBaseClassWorkaround();
|
||||
|
||||
// For children that do not map to a real expression (such as f.public)
|
||||
// GDB returns an empty string. In this case, we can use another unique
|
||||
// name, such as the variable name
|
||||
final boolean fakeChild = (getData().length() == 0);
|
||||
final String childFullExpression = fakeChild ? child.getVarName() : getData();
|
||||
final boolean fakeChild = (childPath.length() == 0);
|
||||
final String childFullExpression = fakeChild ? child.getVarName() : childPath;
|
||||
|
||||
// Now try to see if we already have this variable object in our Map
|
||||
// Since our map names use the expression, and not the GDB given
|
||||
|
@ -1395,6 +1434,8 @@ public class MIVariableManager implements ICommandControl {
|
|||
var = createChild(childId, childFullExpression, indexInParent, child);
|
||||
}
|
||||
|
||||
var.hasCastToBaseClassWorkaround = childHasCastToBaseClassWorkaround;
|
||||
|
||||
if (fakeChild) {
|
||||
|
||||
addRealChildrenOfFake(var, exprDmc, realChildren,
|
||||
|
@ -1425,6 +1466,8 @@ public class MIVariableManager implements ICommandControl {
|
|||
if (childVar == null) {
|
||||
childVar = createChild(childId, childFullExpression, indexInParent, child);
|
||||
|
||||
childVar.hasCastToBaseClassWorkaround = childHasCastToBaseClassWorkaround;
|
||||
|
||||
if (fakeChild) {
|
||||
|
||||
addRealChildrenOfFake(childVar, exprDmc, realChildren,
|
||||
|
@ -1442,14 +1485,21 @@ public class MIVariableManager implements ICommandControl {
|
|||
if (isAccessQualifier(child.getExp())) {
|
||||
// This is just a qualifier level of C++, so we don't need
|
||||
// to call -var-info-path-expression for real, but just pretend we did.
|
||||
childPathRm.setData(""); //$NON-NLS-1$
|
||||
childPathRm.setData(new ChildFullExpressionInfo("")); //$NON-NLS-1$
|
||||
childPathRm.done();
|
||||
} else if (isDynamic() || exprInfo.hasDynamicAncestor()) {
|
||||
// Equivalent to (which can't be implemented): child.hasDynamicAncestor
|
||||
// The new child has a dynamic ancestor. Such children don't support
|
||||
// var-info-path-expression. Build the expression ourselves.
|
||||
childPathRm.setData(buildChildExpression(exprDmc.getExpression(), child.getExp()));
|
||||
childPathRm.setData(new ChildFullExpressionInfo(buildChildExpression(exprDmc.getExpression(), child.getExp())));
|
||||
childPathRm.done();
|
||||
} else if (hasCastToBaseClassWorkaround) {
|
||||
// We had to use the "CastToBaseClass" workaround in the hierarchy, so we
|
||||
// know -var-info-path-expression won't work in this case. We have to
|
||||
// build the expression ourselves again to keep the workaround as part
|
||||
// of the child's expression.
|
||||
childPathRm.setData(new ChildFullExpressionInfo(buildChildExpression(exprDmc.getExpression(), child.getExp())));
|
||||
childPathRm.done();
|
||||
} else {
|
||||
// To build the child id, we need the fully qualified expression which we
|
||||
// can get from -var-info-path-expression starting from GDB 6.7
|
||||
|
@ -1459,14 +1509,55 @@ public class MIVariableManager implements ICommandControl {
|
|||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (isSuccess()) {
|
||||
childPathRm.setData(getData().getFullExpression());
|
||||
final String expression = getData().getFullExpression();
|
||||
|
||||
if (needFixForGDBBug320277() && child.getExp().equals(child.getType()) && !isAccessQualifier(getExpressionInfo().getRelExpr())) {
|
||||
// Special handling for a derived class that is cast to its base class (see bug 320277)
|
||||
//
|
||||
// If the name of a child equals its type then it could be a base class.
|
||||
// The exception is when the name of the actual variable is identical with the type name (bad coding style :-))
|
||||
// The only way to tell the difference is to check if the parent is a fake (public/private/protected).
|
||||
//
|
||||
// What we could do instead, is make sure we are using C++ (using -var-info-expression). That would
|
||||
// be safer. However, at this time, there does not seem to be a way to create a variable with the same
|
||||
// name and type using plain C, so we are safe.
|
||||
//
|
||||
// When we know we are dealing with derived class that is cast to its base class
|
||||
// -var-info-path-expression returns (*(testbase*) this) and in some cases
|
||||
// this expression will fail when being evaluated in GDB because of a GDB bug.
|
||||
// Instead, we need (*(struct testbase*) this).
|
||||
//
|
||||
// To check if GDB actually has this bug we call -data-evaluate-expression with the return value
|
||||
// of -var-info-path-expression
|
||||
IExpressionDMContext exprDmcMIData = fExpressionService.createExpression(exprDmc, expression);
|
||||
fCommandControl.queueCommand(
|
||||
fCommandFactory.createMIDataEvaluateExpression(exprDmcMIData),
|
||||
new DataRequestMonitor<MIDataEvaluateExpressionInfo>(fSession.getExecutor(), childPathRm) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (isSuccess()) {
|
||||
childPathRm.setData(new ChildFullExpressionInfo(expression));
|
||||
childPathRm.done();
|
||||
} else {
|
||||
// We build the expression ourselves
|
||||
// We must also indicate that this workaround has been used for this child
|
||||
// so that we know to keep using it for further descendants.
|
||||
childPathRm.setData(new ChildFullExpressionInfo(buildDerivedChildExpression(exprDmc.getExpression(), child.getExp()), true));
|
||||
childPathRm.done();
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
childPathRm.setData(new ChildFullExpressionInfo(expression));
|
||||
childPathRm.done();
|
||||
}
|
||||
} else {
|
||||
// If we don't have var-info-path-expression
|
||||
// build the expression ourselves
|
||||
// Note that this does not work well yet
|
||||
childPathRm.setData(buildChildExpression(exprDmc.getExpression(), child.getExp()));
|
||||
childPathRm.setData(new ChildFullExpressionInfo(buildChildExpression(exprDmc.getExpression(), child.getExp())));
|
||||
childPathRm.done();
|
||||
}
|
||||
childPathRm.done();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -1582,27 +1673,65 @@ public class MIVariableManager implements ICommandControl {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Method performing special handling for a derived class that is cast to its base class (see bug 320277).
|
||||
* The command '-var-info-path-expression' returns (*(testbase*) this) but we need (*(struct testbase*) this).
|
||||
* Also, in case of a namespace this method adds additional backticks:
|
||||
* (*(struct 'namespace::testbase'*) this)
|
||||
*/
|
||||
private String buildDerivedChildExpression(String parentExp, String childExpr) {
|
||||
|
||||
final String CAST_PREFIX = "struct "; //$NON-NLS-1$
|
||||
|
||||
// Before doing the cast, let's surround the child expression (base class name) with quotes
|
||||
// if it contains a :: which indicates a namespace
|
||||
String childNameForCast = childExpr.contains("::") ? "'" + childExpr + "'" : childExpr; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
String childFullExpression;
|
||||
if (isPointer()) {
|
||||
// casting to pointer base class requires a slightly different format
|
||||
childFullExpression = "*(" + CAST_PREFIX + childNameForCast + "*)(" + parentExp + ")";//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
|
||||
} else {
|
||||
// casting to base class
|
||||
childFullExpression = "(" + CAST_PREFIX + childNameForCast + ")" + parentExp;//$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
|
||||
return childFullExpression;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method builds a child expression based on its parent's expression.
|
||||
* It is a fallback solution for when GDB doesn't support the var-info-path-expression.
|
||||
*
|
||||
* Currently, this does not support inherited class such as
|
||||
* This method does not take care of inherited classes such as
|
||||
* class foo : bar {
|
||||
* ...
|
||||
* }
|
||||
* because we'll create foo.bar instead of (bar)foo.
|
||||
* that case is hanlded by buildDerivedChildExpression
|
||||
*/
|
||||
private String buildChildExpression(String parentExp, String childExp) {
|
||||
String childFullExpression;
|
||||
|
||||
// If the current varObj is a fake object, we obtain the proper parent
|
||||
// expression from the parent of the varObj.
|
||||
if (isAccessQualifier(exprInfo.getRelExpr())) {
|
||||
parentExp = getParent().getExpression();
|
||||
}
|
||||
|
||||
// For pointers, the child expression is already contained in the parent,
|
||||
// so we must simply prefix with *
|
||||
// See Bug219179 for more information.
|
||||
if (!isDynamic() && !exprInfo.hasDynamicAncestor() && isPointer()) {
|
||||
return "*("+parentExp+")"; //$NON-NLS-1$//$NON-NLS-2$
|
||||
childFullExpression = "*("+parentExp+")"; //$NON-NLS-1$//$NON-NLS-2$
|
||||
} else {
|
||||
// We must surround the parentExp with parentheses because it
|
||||
// may be a casted expression.
|
||||
childFullExpression = "("+parentExp+")." + childExp; //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
|
||||
return parentExp + "." + childExp; //$NON-NLS-1$
|
||||
|
||||
// No need for a special case for arrays since we deal with arrays differently
|
||||
// and don't call this method for them
|
||||
|
||||
return childFullExpression;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2894,4 +3023,24 @@ public class MIVariableManager implements ICommandControl {
|
|||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GDB has a bug which makes -data-evaluate-expression fail when using
|
||||
* the return value of -var-info-path-expression in the case of derived classes.
|
||||
* To work around this bug, we don't use -var-info-path-expression for some derived
|
||||
* classes and all their descendants.
|
||||
*
|
||||
* This method can be overridden to easily disable the workaround, for versions
|
||||
* of GDB that no longer have the bug.
|
||||
*
|
||||
* See http://sourceware.org/bugzilla/show_bug.cgi?id=11912
|
||||
* and Bug 320277.
|
||||
*
|
||||
* The bug was fixed in GDB 7.3.1.
|
||||
*
|
||||
* @since 4.1
|
||||
*/
|
||||
protected boolean needFixForGDBBug320277() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ public class MIExpressionsTest extends BaseTestCase {
|
|||
|
||||
private DsfServicesTracker fServicesTracker;
|
||||
|
||||
private IExpressions fExpService;
|
||||
protected IExpressions fExpService;
|
||||
|
||||
private int fExprChangedEventCount = 0;
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2009, 2010 Ericsson and others.
|
||||
* Copyright (c) 2009, 2011 Ericsson and others.
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
|
|
|
@ -7,13 +7,29 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Ericsson - Initial Implementation
|
||||
* Marc Khouzam (Ericsson) - Modify testDeleteChildren() for GDB output
|
||||
* change (Bug 320277)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_3;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMContext;
|
||||
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMData;
|
||||
import org.eclipse.cdt.dsf.debug.service.IRunControl.StepType;
|
||||
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
|
||||
import org.eclipse.cdt.dsf.mi.service.command.events.MIStoppedEvent;
|
||||
import org.eclipse.cdt.tests.dsf.gdb.framework.AsyncCompletionWaitor;
|
||||
import org.eclipse.cdt.tests.dsf.gdb.framework.BackgroundRunner;
|
||||
import org.eclipse.cdt.tests.dsf.gdb.framework.SyncUtil;
|
||||
import org.eclipse.cdt.tests.dsf.gdb.launching.TestsPlugin;
|
||||
import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants;
|
||||
import org.eclipse.cdt.tests.dsf.gdb.tests.MIExpressionsTest;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
@RunWith(BackgroundRunner.class)
|
||||
|
@ -22,4 +38,132 @@ public class MIExpressionsTest_7_3 extends MIExpressionsTest {
|
|||
public static void beforeClassMethod_7_3() {
|
||||
setGdbProgramNamesLaunchAttributes(ITestConstants.SUFFIX_GDB_7_3);
|
||||
}
|
||||
|
||||
// Slight change in GDB output to fix a bug, so we must change the test a little
|
||||
// Bug 320277
|
||||
@Override
|
||||
@Test
|
||||
public void testDeleteChildren() throws Throwable {
|
||||
SyncUtil.runToLocation("testDeleteChildren");
|
||||
MIStoppedEvent stoppedEvent = SyncUtil.step(1, StepType.STEP_OVER);
|
||||
final IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
|
||||
|
||||
final AsyncCompletionWaitor wait = new AsyncCompletionWaitor();
|
||||
|
||||
fExpService.getExecutor().submit(new Runnable() {
|
||||
public void run() {
|
||||
|
||||
// First create the var object and all its children
|
||||
IExpressionDMContext parentDmc = fExpService.createExpression(frameDmc, "f");
|
||||
|
||||
fExpService.getSubExpressions(
|
||||
parentDmc,
|
||||
new DataRequestMonitor<IExpressionDMContext[]>(fExpService.getExecutor(), null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (!isSuccess()) {
|
||||
wait.waitFinished(getStatus());
|
||||
} else {
|
||||
if (getData().length != 5) {
|
||||
wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID,
|
||||
"Failed getting children; expecting 5 got " + getData().length, null));
|
||||
} else {
|
||||
String childStr = "((class bar) f)";
|
||||
if (!getData()[0].getExpression().equals(childStr)) {
|
||||
wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID,
|
||||
"Got child " + getData()[0].getExpression() + " instead of " + childStr, null));
|
||||
} else {
|
||||
// Now list the children of the first element
|
||||
fExpService.getSubExpressions(
|
||||
getData()[0],
|
||||
new DataRequestMonitor<IExpressionDMContext[]>(fExpService.getExecutor(), null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (!isSuccess()) {
|
||||
wait.waitFinished(getStatus());
|
||||
} else {
|
||||
if (getData().length != 2) {
|
||||
wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID,
|
||||
"Failed getting children; expecting 2 got " + getData().length, null));
|
||||
} else {
|
||||
String childStr = "((((class bar) f)).d)";
|
||||
if (!getData()[0].getExpression().equals(childStr)) {
|
||||
wait.waitFinished(new Status(IStatus.ERROR, TestsPlugin.PLUGIN_ID,
|
||||
"Got child " + getData()[0].getExpression() + " instead of " + childStr, null));
|
||||
} else {
|
||||
wait.setReturnInfo(getData()[0]);
|
||||
wait.waitFinished();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
|
||||
assertTrue(wait.getMessage(), wait.isOK());
|
||||
final IExpressionDMContext deletedChildDmc = (IExpressionDMContext)wait.getReturnInfo();
|
||||
|
||||
wait.waitReset();
|
||||
|
||||
fExpService.getExecutor().submit(new Runnable() {
|
||||
public void run() {
|
||||
|
||||
// Now create more than 1000 expressions to trigger the deletion of the children
|
||||
// that were created above
|
||||
for (int i=0; i<1100; i++) {
|
||||
IExpressionDMContext dmc = fExpService.createExpression(frameDmc, "a[" + i + "]");
|
||||
|
||||
wait.increment();
|
||||
fExpService.getExpressionData(
|
||||
dmc,
|
||||
new DataRequestMonitor<IExpressionDMData>(fExpService.getExecutor(), null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (!isSuccess()) {
|
||||
wait.waitFinished(getStatus());
|
||||
} else {
|
||||
wait.waitFinished();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
|
||||
assertTrue(wait.getMessage(), wait.isOK());
|
||||
wait.waitReset();
|
||||
|
||||
fExpService.getExecutor().submit(new Runnable() {
|
||||
public void run() {
|
||||
|
||||
// Evaluate the expression of a child that we know is deleted to make sure
|
||||
// the expression service can handle that
|
||||
fExpService.getExpressionData(
|
||||
deletedChildDmc,
|
||||
new DataRequestMonitor<IExpressionDMData>(fExpService.getExecutor(), null) {
|
||||
@Override
|
||||
protected void handleCompleted() {
|
||||
if (!isSuccess()) {
|
||||
wait.waitFinished(getStatus());
|
||||
} else {
|
||||
wait.waitFinished();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
wait.waitUntilDone(AsyncCompletionWaitor.WAIT_FOREVER);
|
||||
assertTrue(wait.getMessage(), wait.isOK());
|
||||
wait.waitReset();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ Manifest-Version: 1.0
|
|||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: %pluginName
|
||||
Bundle-SymbolicName: org.eclipse.cdt.make.xlc.core;singleton:=true
|
||||
Bundle-Version: 5.1.0.qualifier
|
||||
Bundle-Version: 5.2.0.qualifier
|
||||
Bundle-Vendor: %providerName
|
||||
Bundle-Localization: plugin
|
||||
Require-Bundle: org.eclipse.cdt.make.core,
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<version>5.1.0-SNAPSHOT</version>
|
||||
<version>5.2.0-SNAPSHOT</version>
|
||||
<artifactId>org.eclipse.cdt.make.xlc.core</artifactId>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
</project>
|
||||
|
|
|
@ -2,7 +2,7 @@ Manifest-Version: 1.0
|
|||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: %pluginName
|
||||
Bundle-SymbolicName: org.eclipse.cdt.managedbuilder.xlc.ui; singleton := true
|
||||
Bundle-Version: 6.3.0.qualifier
|
||||
Bundle-Version: 6.4.0.qualifier
|
||||
Bundle-Activator: org.eclipse.cdt.managedbuilder.xlc.ui.XLCUIPlugin
|
||||
Bundle-Localization: plugin
|
||||
Require-Bundle: org.eclipse.ui,
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<version>6.3.0-SNAPSHOT</version>
|
||||
<version>6.4.0-SNAPSHOT</version>
|
||||
<artifactId>org.eclipse.cdt.managedbuilder.xlc.ui</artifactId>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
</project>
|
||||
|
|
Loading…
Add table
Reference in a new issue