diff --git a/build/org.eclipse.cdt.make.core/META-INF/MANIFEST.MF b/build/org.eclipse.cdt.make.core/META-INF/MANIFEST.MF
index 6e2661348b6..73460367377 100644
--- a/build/org.eclipse.cdt.make.core/META-INF/MANIFEST.MF
+++ b/build/org.eclipse.cdt.make.core/META-INF/MANIFEST.MF
@@ -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
diff --git a/build/org.eclipse.cdt.make.core/pom.xml b/build/org.eclipse.cdt.make.core/pom.xml
index 4d1672ade83..d08b032e0f2 100644
--- a/build/org.eclipse.cdt.make.core/pom.xml
+++ b/build/org.eclipse.cdt.make.core/pom.xml
@@ -11,7 +11,7 @@
../../pom.xml
- 7.1.0-SNAPSHOT
+ 7.2.0-SNAPSHOT
org.eclipse.cdt.make.core
eclipse-plugin
diff --git a/build/org.eclipse.cdt.make.ui/META-INF/MANIFEST.MF b/build/org.eclipse.cdt.make.ui/META-INF/MANIFEST.MF
index 93a2f997d19..12ec26eac40 100644
--- a/build/org.eclipse.cdt.make.ui/META-INF/MANIFEST.MF
+++ b/build/org.eclipse.cdt.make.ui/META-INF/MANIFEST.MF
@@ -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
diff --git a/build/org.eclipse.cdt.make.ui/pom.xml b/build/org.eclipse.cdt.make.ui/pom.xml
index fd326bffe93..0b0c6bf0e9e 100644
--- a/build/org.eclipse.cdt.make.ui/pom.xml
+++ b/build/org.eclipse.cdt.make.ui/pom.xml
@@ -11,7 +11,7 @@
../../pom.xml
- 7.1.0-SNAPSHOT
+ 7.2.0-SNAPSHOT
org.eclipse.cdt.make.ui
eclipse-plugin
diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/META-INF/MANIFEST.MF b/build/org.eclipse.cdt.managedbuilder.core.tests/META-INF/MANIFEST.MF
index 9e1f0f53352..d3fff01f782 100644
--- a/build/org.eclipse.cdt.managedbuilder.core.tests/META-INF/MANIFEST.MF
+++ b/build/org.eclipse.cdt.managedbuilder.core.tests/META-INF/MANIFEST.MF
@@ -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
diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/pom.xml b/build/org.eclipse.cdt.managedbuilder.core.tests/pom.xml
index 80e995957c6..d6ddcd803f3 100644
--- a/build/org.eclipse.cdt.managedbuilder.core.tests/pom.xml
+++ b/build/org.eclipse.cdt.managedbuilder.core.tests/pom.xml
@@ -11,7 +11,7 @@
../../pom.xml
- 8.0.0-SNAPSHOT
+ 8.1.0-SNAPSHOT
org.eclipse.cdt.managedbuilder.core.tests
eclipse-test-plugin
diff --git a/build/org.eclipse.cdt.managedbuilder.core/META-INF/MANIFEST.MF b/build/org.eclipse.cdt.managedbuilder.core/META-INF/MANIFEST.MF
index 82725b3865c..bb7b599b93c 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/META-INF/MANIFEST.MF
+++ b/build/org.eclipse.cdt.managedbuilder.core/META-INF/MANIFEST.MF
@@ -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
diff --git a/build/org.eclipse.cdt.managedbuilder.core/pom.xml b/build/org.eclipse.cdt.managedbuilder.core/pom.xml
index 767d5bcaf5f..b57ca1be5cd 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/pom.xml
+++ b/build/org.eclipse.cdt.managedbuilder.core/pom.xml
@@ -11,7 +11,7 @@
../../pom.xml
- 8.0.0-SNAPSHOT
+ 8.1.0-SNAPSHOT
org.eclipse.cdt.managedbuilder.core
eclipse-plugin
diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/InputType.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/InputType.java
index 946068c736f..01015f00d66 100644
--- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/InputType.java
+++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/InputType.java
@@ -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;
}
diff --git a/build/org.eclipse.cdt.managedbuilder.gnu.ui/META-INF/MANIFEST.MF b/build/org.eclipse.cdt.managedbuilder.gnu.ui/META-INF/MANIFEST.MF
index e6b672a87f6..1ef142e316c 100644
--- a/build/org.eclipse.cdt.managedbuilder.gnu.ui/META-INF/MANIFEST.MF
+++ b/build/org.eclipse.cdt.managedbuilder.gnu.ui/META-INF/MANIFEST.MF
@@ -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
diff --git a/build/org.eclipse.cdt.managedbuilder.gnu.ui/pom.xml b/build/org.eclipse.cdt.managedbuilder.gnu.ui/pom.xml
index 068bba6ee0b..60ca3e7f7af 100644
--- a/build/org.eclipse.cdt.managedbuilder.gnu.ui/pom.xml
+++ b/build/org.eclipse.cdt.managedbuilder.gnu.ui/pom.xml
@@ -11,7 +11,7 @@
../../pom.xml
- 8.0.0-SNAPSHOT
+ 8.1.0-SNAPSHOT
org.eclipse.cdt.managedbuilder.gnu.ui
eclipse-plugin
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCBindingResolutionBugs.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCBindingResolutionBugs.java
index 307f11347ff..c2210a5712e 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCBindingResolutionBugs.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCBindingResolutionBugs.java
@@ -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);
+ }
}
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java
index 94c82852431..a5e8f536a17 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java
@@ -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 */
/* ##################################################################### */
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/LanguageManager.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/LanguageManager.java
index 6f0b6dea97f..fad740bbfd5 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/LanguageManager.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/LanguageManager.java
@@ -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 map = new HashMap();
Map> cache = getContentTypeToDescriptorCache();
- for (Iterator>> iter = cache.entrySet().iterator(); iter.hasNext();) {
- Entry> entry = iter.next();
+ for (Entry> entry : cache.entrySet()) {
List list = entry.getValue();
if (list.size() > 0) {
ILanguageDescriptor[] dess = list.toArray(new ILanguageDescriptor[list.size()]);
@@ -136,13 +135,10 @@ public class LanguageManager {
Map dc = getDescriptorCache();
List list;
- IContentType type;
String id;
- for (Iterator 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 null
+ * @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);
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java
index 56598d75ef4..ef1504c09e4 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java
@@ -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();
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
index e720e48d894..3bfade24d91 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
@@ -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 allowFunction
* is true
, enclosing the declaration the provided node belongs to and returns
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java
index bd116b09816..66844f2ad24 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/indexer/PDOMIndexerTask.java
@@ -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) {
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/ASTManager.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/ASTManager.java
index af94f751362..4c5afdbf40f 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/ASTManager.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/rename/ASTManager.java
@@ -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 childPathRm =
- new DataRequestMonitor(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 childPathRm =
+ new DataRequestMonitor(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(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;
+ }
}
diff --git a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/MIExpressionsTest.java b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/MIExpressionsTest.java
index f196d3dbbdd..6686606254e 100644
--- a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/MIExpressionsTest.java
+++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/MIExpressionsTest.java
@@ -61,7 +61,7 @@ public class MIExpressionsTest extends BaseTestCase {
private DsfServicesTracker fServicesTracker;
- private IExpressions fExpService;
+ protected IExpressions fExpService;
private int fExprChangedEventCount = 0;
diff --git a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/tests_6_6/MIExpressionsTest_6_6.java b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/tests_6_6/MIExpressionsTest_6_6.java
index 7486fa2d403..0f574abace8 100644
--- a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/tests_6_6/MIExpressionsTest_6_6.java
+++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/tests_6_6/MIExpressionsTest_6_6.java
@@ -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
diff --git a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/tests_7_3/MIExpressionsTest_7_3.java b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/tests_7_3/MIExpressionsTest_7_3.java
index 6da31bc02bf..2b39678630a 100644
--- a/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/tests_7_3/MIExpressionsTest_7_3.java
+++ b/dsf-gdb/org.eclipse.cdt.tests.dsf.gdb/src/org/eclipse/cdt/tests/dsf/gdb/tests/tests_7_3/MIExpressionsTest_7_3.java
@@ -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(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(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(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(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();
+
+ }
}
diff --git a/xlc/org.eclipse.cdt.make.xlc.core/META-INF/MANIFEST.MF b/xlc/org.eclipse.cdt.make.xlc.core/META-INF/MANIFEST.MF
index 7dc27019ea0..31f7d607657 100644
--- a/xlc/org.eclipse.cdt.make.xlc.core/META-INF/MANIFEST.MF
+++ b/xlc/org.eclipse.cdt.make.xlc.core/META-INF/MANIFEST.MF
@@ -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,
diff --git a/xlc/org.eclipse.cdt.make.xlc.core/pom.xml b/xlc/org.eclipse.cdt.make.xlc.core/pom.xml
index 2cfb29eae96..a7cc50754d9 100644
--- a/xlc/org.eclipse.cdt.make.xlc.core/pom.xml
+++ b/xlc/org.eclipse.cdt.make.xlc.core/pom.xml
@@ -11,7 +11,7 @@
../../pom.xml
- 5.1.0-SNAPSHOT
+ 5.2.0-SNAPSHOT
org.eclipse.cdt.make.xlc.core
eclipse-plugin
diff --git a/xlc/org.eclipse.cdt.managedbuilder.xlc.ui/META-INF/MANIFEST.MF b/xlc/org.eclipse.cdt.managedbuilder.xlc.ui/META-INF/MANIFEST.MF
index 81bc979751f..fa0af12ec86 100644
--- a/xlc/org.eclipse.cdt.managedbuilder.xlc.ui/META-INF/MANIFEST.MF
+++ b/xlc/org.eclipse.cdt.managedbuilder.xlc.ui/META-INF/MANIFEST.MF
@@ -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,
diff --git a/xlc/org.eclipse.cdt.managedbuilder.xlc.ui/pom.xml b/xlc/org.eclipse.cdt.managedbuilder.xlc.ui/pom.xml
index 937117fbd61..349e9a0df69 100644
--- a/xlc/org.eclipse.cdt.managedbuilder.xlc.ui/pom.xml
+++ b/xlc/org.eclipse.cdt.managedbuilder.xlc.ui/pom.xml
@@ -11,7 +11,7 @@
../../pom.xml
- 6.3.0-SNAPSHOT
+ 6.4.0-SNAPSHOT
org.eclipse.cdt.managedbuilder.xlc.ui
eclipse-plugin