1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-06 17:26:01 +02:00

Merge remote-tracking branch 'cdt/master' into sd90

This commit is contained in:
Andrew Gvozdev 2012-07-11 12:01:16 -04:00
commit 747755991f
104 changed files with 3136 additions and 780 deletions

View file

@ -127,6 +127,14 @@ public class MingwEnvironmentVariableSupplier implements IConfigurationEnvironme
return mingwBinDir;
}
// Check for MinGW-w64 on Windows 64 bit, see http://mingw-w64.sourceforge.net/
if (Platform.ARCH_X86_64.equals(Platform.getOSArch())) {
IPath gcc64Loc = PathUtil.findProgramLocation("x86_64-w64-mingw32-gcc.exe", envPathValueCached); //$NON-NLS-1$
if (gcc64Loc != null) {
return gcc64Loc.removeLastSegments(1);
}
}
// Look in PATH values. Look for mingw32-gcc.exe
// TODO: Since this dir is already in the PATH, why are we adding it here?
// This is really only to support isToolchainAvail. Must be a better way.

View file

@ -68,6 +68,7 @@ import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.window.Window;
@ -132,6 +133,17 @@ public class BuildOptionSettingsUI extends AbstractToolSettingUI {
try {
treeRoot = option.getTreeRoot();
TreeSelectionDialog dlg = new TreeSelectionDialog(getShell(), treeRoot, nameStr, contextId);
String name = getStringValue();
if (name != null) {
String treeId = option.getId(name);
if (treeId != null) {
ITreeOption node = treeRoot.findNode(treeId);
if (node != null) {
dlg.setSelection(node);
}
}
}
if (dlg.open() == Window.OK) {
ITreeOption selected = dlg.getSelection();
return selected.getName();
@ -1073,7 +1085,7 @@ public class BuildOptionSettingsUI extends AbstractToolSettingUI {
}
/**
* @since 8.1
* @since 8.2
*/
public static class TreeSelectionDialog extends TitleAreaDialog {
private final ITreeRoot treeRoot;
@ -1081,6 +1093,7 @@ public class BuildOptionSettingsUI extends AbstractToolSettingUI {
private final String name;
private String contextId;
private String baseMessage = ""; //$NON-NLS-1$
private TreeViewer viewer;
public TreeSelectionDialog(Shell parentShell, ITreeRoot root, String name, String contextId) {
super(parentShell);
@ -1117,7 +1130,7 @@ public class BuildOptionSettingsUI extends AbstractToolSettingUI {
FilteredTree tree = new FilteredTree(control,
SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER,
filter, true);
final TreeViewer viewer = tree.getViewer();
viewer = tree.getViewer();
viewer.setContentProvider(new ITreeContentProvider() {
@Override
@ -1275,10 +1288,42 @@ public class BuildOptionSettingsUI extends AbstractToolSettingUI {
return control;
}
@Override
public void create() {
super.create();
// Need to update selection after the dialog has been created
// so that we trigger the listener and correctly update the label
// and buttons
setUISelection();
}
public ITreeOption getSelection() {
return selected;
}
public void setSelection(ITreeOption option) {
if (treeRoot == getRoot(option)) { // only work in the same tree
selected = option;
setUISelection();
}
}
private void setUISelection() {
if (viewer != null && selected != null) viewer.setSelection(new StructuredSelection(selected), true);
}
private static ITreeRoot getRoot(ITreeOption option) {
if (option != null) {
ITreeOption parent = option.getParent();
while (parent != null) {
option = parent;
parent = option.getParent();
}
return option instanceof ITreeRoot? (ITreeRoot) option : null;
}
return null;
}
private Image createImage(String icon) {
if (icon != null) {

View file

@ -1,11 +1,11 @@
/*******************************************************************************
* Copyright (c) 2004, 2009 IBM Corporation 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
* http://www.eclipse.org/legal/epl-v10.html
* Copyright (c) 2004, 2009 IBM Corporation 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Contributors:
* Andrew Niefer (IBM Corporation) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
@ -18,22 +18,19 @@ package org.eclipse.cdt.core.dom.ast;
* @noinstantiate This class is not intended to be instantiated by clients.
*/
public class DOMException extends Exception {
private static final long serialVersionUID = 0;
IProblemBinding problemBinding;
/**
* @param problem
* binding for throwing
*
* @param problem the binding for throwing
*/
public DOMException(IProblemBinding problem) {
problemBinding = problem;
}
/**
* Get the problem associated w/this exception.
* Returns the problem associated w/this exception.
*
* @return problem
*/

View file

@ -6,22 +6,20 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
/**
* C++ specific initializer clause
* C++ specific initializer clause.
* @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients.
* @since 5.5
*/
public interface ICPPASTInitializerClause extends IASTInitializerClause {
/**
* Returns the evaluation object for this expression.
* @noreference This method is not intended to be referenced by clients.

View file

@ -6,11 +6,10 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
* IBM - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
/**
* Base interface for methods, also used for constructors.
*
@ -18,7 +17,7 @@ package org.eclipse.cdt.core.dom.ast.cpp;
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface ICPPMethod extends ICPPFunction, ICPPMember {
public static final ICPPMethod [] EMPTY_CPPMETHOD_ARRAY = new ICPPMethod[0];
public static final ICPPMethod[] EMPTY_CPPMETHOD_ARRAY = {};
/**
* Returns whether this method is declared to be virtual. Does not detect whether
@ -27,9 +26,9 @@ public interface ICPPMethod extends ICPPFunction, ICPPMember {
public boolean isVirtual();
/**
* is this a destructor
* Is this a destructor?
*
* returns true if its name starts with '~'
* Returns true if its name starts with '~'
*/
public boolean isDestructor();

View file

@ -21,12 +21,12 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
*/
public interface ICPPNamespace extends ICPPBinding {
/**
* get the scope object associated with this namespace
* Returns the scope object associated with this namespace
*/
public ICPPNamespaceScope getNamespaceScope();
/**
* get an array of the all the bindings declared in this namespace.
* Returns an array of the all the bindings declared in this namespace.
*/
public IBinding[] getMemberBindings();

View file

@ -17,10 +17,8 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface ICPPNamespaceAlias extends ICPPNamespace {
/**
* get the binding of the original namespace.
* Returns the binding of the original namespace.
*/
public IBinding getBinding();
}

View file

@ -11,7 +11,6 @@
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
/**
* A namespace scope is either a block-scope or a namespace-scope or global scope.
*
@ -19,7 +18,6 @@ package org.eclipse.cdt.core.dom.ast.cpp;
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface ICPPNamespaceScope extends ICPPScope {
/**
* @since 5.3
*/

View file

@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Andrew Niefer (IBM) - Initial API and implementation
* Markus Schorn (Wind River Systems)
* Andrew Niefer (IBM) - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
@ -18,7 +18,6 @@ import org.eclipse.cdt.core.dom.ast.IParameter;
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface ICPPParameter extends IParameter, ICPPVariable {
/**
* @since 5.2
*/

View file

@ -21,7 +21,6 @@ import org.eclipse.cdt.core.dom.ast.IType;
* @since 5.2
*/
public interface ICPPParameterPackType extends IType {
/**
* Returns the pattern for the pack-expansion
*/

View file

@ -18,7 +18,6 @@ import org.eclipse.cdt.core.dom.ast.IType;
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface ICPPReferenceType extends IType {
/**
* Returns the type that this is a reference of
*/

View file

@ -17,5 +17,4 @@ import org.eclipse.cdt.core.dom.ast.IScope;
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface ICPPScope extends IScope {
}

View file

@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Andrew Niefer (IBM) - Initial API and implementation
* Markus Schorn (Wind River Systems)
* Andrew Niefer (IBM) - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;

View file

@ -6,12 +6,11 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
* IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
/**
* Base interface for all template definitions including explicit (partial) specializations.
*
@ -19,7 +18,6 @@ package org.eclipse.cdt.core.dom.ast.cpp;
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface ICPPTemplateDefinition extends ICPPBinding {
/**
* Returns an array of the template parameters.
* In the case of a specialization, the array will be empty,

View file

@ -1,15 +1,14 @@
/*******************************************************************************
* Copyright (c) 2005, 2010 IBM Corporation 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
* http://www.eclipse.org/legal/epl-v10.html
* Copyright (c) 2005, 2010 IBM Corporation 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
* Contributors:
* IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.IType;

View file

@ -1,13 +1,13 @@
/*******************************************************************************
* Copyright (c) 2004, 2009 IBM Corporation 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
* http://www.eclipse.org/legal/epl-v10.html
* Copyright (c) 2004, 2009 IBM Corporation 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Doug Schaefer (IBM) - Initial API and implementation
* Markus Schorn (Wind River Systems)
* Contributors:
* Doug Schaefer (IBM) - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
@ -20,7 +20,6 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression;
* @noextend This interface is not intended to be extended by clients.
*/
public interface ICPPTemplateNonTypeParameter extends ICPPTemplateParameter, ICPPVariable {
/**
* @deprecated, use {@link ICPPTemplateParameter#getDefaultValue()}.
*/

View file

@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Doug Schaefer (IBM) - Initial API and implementation
* Markus Schorn (Wind River Systems)
* Doug Schaefer (IBM) - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
@ -18,7 +18,7 @@ package org.eclipse.cdt.core.dom.ast.cpp;
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface ICPPTemplateParameter extends ICPPBinding {
public static final ICPPTemplateParameter[] EMPTY_TEMPLATE_PARAMETER_ARRAY = new ICPPTemplateParameter[0];
public static final ICPPTemplateParameter[] EMPTY_TEMPLATE_PARAMETER_ARRAY = {};
/**
* Returns the zero-based position of this parameter within the template parameter list it belongs to.

View file

@ -6,11 +6,10 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
/**
* Models the mapping of template parameters to values, or pack-expansions.
*
@ -19,7 +18,6 @@ package org.eclipse.cdt.core.dom.ast.cpp;
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface ICPPTemplateParameterMap {
/**
* Returns the value for the template parameter with the given id.
* @see ICPPTemplateParameter#getParameterID()
@ -32,7 +30,6 @@ public interface ICPPTemplateParameterMap {
*/
public ICPPTemplateArgument getArgument(ICPPTemplateParameter param);
/**
* Returns the values for the template parameter pack with the given id in the map,
* or <code>null</code> if the parameter is not mapped or is not a parameter pack.

View file

@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
* IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;

View file

@ -20,7 +20,6 @@ import org.eclipse.cdt.core.dom.ast.IType;
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface ICPPTemplateTemplateParameter extends ICPPTemplateParameter, ICPPClassTemplate {
@Override
public ICPPTemplateParameter[] getTemplateParameters();

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Doug Schaefer (IBM) - Initial API and implementation
* Doug Schaefer (IBM) - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp;
@ -18,17 +18,15 @@ import org.eclipse.cdt.core.dom.ast.IType;
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface ICPPTemplateTypeParameter extends ICPPTemplateParameter, IType {
/**
* The default type for this parameter. May be null
*
* The default type for this parameter. May be {@code null}.
*/
public IType getDefault() throws DOMException;
/**
* Types containing template parameters need to be compared even before it is known to which
* binding the template parameter belongs to. Therefore {@link #isSameType(IType)} compares the
* kind and the parameter position of the template parameter, only. The name and the owner
* binding the template parameter belongs to. Therefore {@link #isSameType(IType)} compares
* the kind and the parameter position of the template parameter, only. The name and the owner
* is ignored.
*
* @since 5.1

View file

@ -22,8 +22,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
* @noextend This interface is not intended to be extended by clients.
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface ICPPUsingDeclaration extends ICPPBinding {
public interface ICPPUsingDeclaration extends ICPPBinding {
/**
* Return an array of bindings that were declared by this using declaration.
* Each of these bindings delegates to some previously declared binding to which it

View file

@ -23,7 +23,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface ICPPUsingDirective {
ICPPUsingDirective[] EMPTY_ARRAY = new ICPPUsingDirective[0];
ICPPUsingDirective[] EMPTY_ARRAY = {};
/**
* Returns the scope of the namespace that is nominated by this

View file

@ -18,7 +18,6 @@ import org.eclipse.cdt.core.dom.ast.IVariable;
* @noimplement This interface is not intended to be implemented by clients.
*/
public interface ICPPVariable extends IVariable, ICPPBinding {
/**
* does this variable have the mutable storage class specifier
*/

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
@ -17,7 +17,6 @@ import org.eclipse.cdt.core.dom.ast.IASTNameOwner;
* Provides additional methods for internal use by the name resolution.
*/
public interface IASTInternalNameOwner extends IASTNameOwner {
/**
* Get the role for the name. If the name needs to be resolved to determine that and
* <code>allowResolution</code> is set to <code>false</code>, then {@link IASTNameOwner#r_unclear}

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
@ -17,7 +17,6 @@ import org.eclipse.cdt.core.dom.ast.IVariable;
* Internal interface for bindings in the ast that have values.
*/
public interface IInternalVariable extends IVariable {
/**
* Returns the value of the variable, or <code>null</code>.
* If the recursion depth is reached {@link Value#UNKNOWN} will be returned.

View file

@ -6,13 +6,12 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
import org.eclipse.core.runtime.CoreException;
/**
* Interface for marshalling types for storage in the index.
*/

View file

@ -6,13 +6,12 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
import org.eclipse.core.runtime.CoreException;
/**
* Interface for marshalling types for storage in the index.
*/

View file

@ -18,12 +18,12 @@ import org.eclipse.cdt.core.dom.ast.IType;
*/
public interface ITypeContainer extends IType {
/**
* get the type this contains
* Returns the type this container contains.
*/
IType getType();
/**
* set the type this contains
* Sets the type this container contains.
*/
void setType(IType type);
}

View file

@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
import org.eclipse.cdt.core.dom.ast.IBinding;
@ -30,7 +30,7 @@ public interface ITypeMarshalBuffer {
final static byte PROBLEM_TYPE= 9;
final static byte VALUE= 10;
final static byte DEPENDENT_EXPRESSION_TYPE= 11;
final static byte
EVAL_BINARY= 1,
EVAL_BINARY_TYPE_ID = 2,
@ -47,22 +47,23 @@ public interface ITypeMarshalBuffer {
EVAL_TYPE_ID= 13,
EVAL_UNARY= 14,
EVAL_UNARY_TYPE_ID = 15;
static final byte KIND_MASK= 15;
final static int FLAG1 = 0x10;
final static int FLAG2 = 0x20;
final static int FLAG3 = 0x40;
final static int FLAG4 = 0x80;
CoreException unmarshallingError();
IType unmarshalType() throws CoreException;
IValue unmarshalValue() throws CoreException;
IBinding unmarshalBinding() throws CoreException;
ISerializableEvaluation unmarshalEvaluation() throws CoreException;
int getByte() throws CoreException;
int getShort() throws CoreException;
int getInt() throws CoreException;
long getLong() throws CoreException;
char[] getCharArray() throws CoreException;
@ -72,6 +73,7 @@ public interface ITypeMarshalBuffer {
void marshalEvaluation(ISerializableEvaluation eval, boolean includeValue) throws CoreException;
void putByte(byte data);
void putShort(short data);
void putInt(int data);
void putLong(long data);
void putCharArray(char[] data);
}

View file

@ -6,16 +6,14 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
import org.eclipse.cdt.core.parser.AbstractParserLogService;
import org.eclipse.cdt.core.parser.IParserLogService;
public class ParserLogServiceWrapper extends AbstractParserLogService {
private IParserLogService fDelegate;
public ParserLogServiceWrapper(IParserLogService log) {

View file

@ -16,7 +16,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType;
import org.eclipse.core.runtime.CoreException;
/**
* Implementation of problem types.
*/

View file

@ -8,7 +8,7 @@
* Contributors:
* Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
import java.util.ArrayList;
@ -45,15 +45,15 @@ import org.eclipse.cdt.internal.core.pdom.db.TypeMarshalBuffer;
import org.eclipse.core.runtime.CoreException;
/**
* Represents values of variables, enumerators or expressions. The primary purpose of the representation
* is to support instantiation of templates with non-type template parameters.
* Represents values of variables, enumerators or expressions. The primary purpose of
* the representation is to support instantiation of templates with non-type template parameters.
*/
public class Value implements IValue {
public static final int MAX_RECURSION_DEPTH = 25;
public final static IValue UNKNOWN= new Value("<unknown>".toCharArray(), ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY); //$NON-NLS-1$
public final static IValue NOT_INITIALIZED= new Value("<__>".toCharArray(), ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY); //$NON-NLS-1$
private static final int[] NO_INT = {};
private static final String SCOPE_OP = "::"; //$NON-NLS-1$
private static final char UNIQUE_CHAR = '_';
private static final char TEMPLATE_PARAM_CHAR = '#';
@ -62,23 +62,23 @@ public class Value implements IValue {
private static final char UNARY_OP_CHAR = '$';
private static final char BINARY_OP_CHAR = '@';
private static final char CONDITIONAL_CHAR= '?';
private static final char SEPARATOR = ',';
private final static IValue[] TYPICAL= {
new Value(new char[] {'0'}, ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY),
new Value(new char[] {'1'}, ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY),
new Value(new char[] {'2'}, ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY),
new Value(new char[] {'3'}, ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY),
new Value(new char[] {'4'}, ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY),
new Value(new char[] {'5'}, ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY),
new Value(new char[] {'0'}, ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY),
new Value(new char[] {'1'}, ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY),
new Value(new char[] {'2'}, ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY),
new Value(new char[] {'3'}, ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY),
new Value(new char[] {'4'}, ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY),
new Value(new char[] {'5'}, ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY),
new Value(new char[] {'6'}, ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY)};
private static class Reevaluation {
public final char[] fExpression;
private final int fPackOffset;
public int pos=0;
public int pos= 0;
public final Map<String, Integer> fUnknownSigs;
public final List<ICPPUnknownBinding> fUnknowns;
public final IBinding[] fResolvedUnknown;
@ -94,7 +94,7 @@ public class Value implements IValue {
fMap= map;
}
public void nextSeperator() throws UnknownValueException {
public void nextSeparator() throws UnknownValueException {
final char[] expression = fExpression;
final int len = expression.length;
int idx = pos;
@ -113,13 +113,13 @@ public class Value implements IValue {
private final char[] fExpression;
private final ICPPUnknownBinding[] fUnknownBindings;
private char[] fSignature;
private Value(char[] rep, ICPPUnknownBinding[] unknown) {
assert rep != null;
fExpression= rep;
fUnknownBindings= unknown;
}
@Override
public char[] getInternalExpression() {
return fExpression;
@ -129,7 +129,7 @@ public class Value implements IValue {
public IBinding[] getUnknownBindings() {
return fUnknownBindings;
}
@Override
public char[] getSignature() {
if (fSignature == null) {
@ -152,13 +152,13 @@ public class Value implements IValue {
}
return fSignature;
}
@Override
public Long numericalValue() {
return parseLong(fExpression);
}
public void marshall(TypeMarshalBuffer buf) throws CoreException {
public void marshall(ITypeMarshalBuffer buf) throws CoreException {
if (UNKNOWN == this) {
buf.putByte((byte) (ITypeMarshalBuffer.VALUE | ITypeMarshalBuffer.FLAG1));
} else {
@ -182,12 +182,12 @@ public class Value implements IValue {
}
}
}
public static IValue unmarshal(TypeMarshalBuffer buf) throws CoreException {
public static IValue unmarshal(ITypeMarshalBuffer buf) throws CoreException {
int firstByte= buf.getByte();
if (firstByte == TypeMarshalBuffer.NULL_TYPE)
return null;
if ((firstByte & ITypeMarshalBuffer.FLAG1) != 0)
if ((firstByte & ITypeMarshalBuffer.FLAG1) != 0)
return Value.UNKNOWN;
if ((firstByte & ITypeMarshalBuffer.FLAG2) != 0) {
int val= buf.getInt();
@ -197,7 +197,7 @@ public class Value implements IValue {
long val= buf.getLong();
return Value.create(val);
}
char[] expr = buf.getCharArray();
final int len= buf.getShort();
ICPPUnknownBinding[] unknowns= new ICPPUnknownBinding[len];
@ -215,7 +215,7 @@ public class Value implements IValue {
public int hashCode() {
return CharArrayUtils.hash(fExpression);
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof IValue)) {
@ -224,11 +224,11 @@ public class Value implements IValue {
final IValue rhs = (IValue) obj;
if (!CharArrayUtils.equals(fExpression, rhs.getInternalExpression()))
return false;
IBinding[] rhsUnknowns= rhs.getUnknownBindings();
if (fUnknownBindings.length != rhsUnknowns.length)
return false;
for (int i = 0; i < rhsUnknowns.length; i++) {
final IBinding rhsUnknown = rhsUnknowns[i];
if (rhsUnknown instanceof ICPPUnknownBinding) {
@ -241,7 +241,7 @@ public class Value implements IValue {
}
return true;
}
@Override
public String toString() {
return new String(getSignature());
@ -255,7 +255,7 @@ public class Value implements IValue {
return TYPICAL[(int) value];
return new Value(toCharArray(value), ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY);
}
/**
* Creates a value representing the given template parameter.
*/
@ -272,7 +272,7 @@ public class Value implements IValue {
}
/**
* Tests whether the value is a template parameter (or parameter pack),
* Tests whether the value is a template parameter (or parameter pack),
* returns the parameter id of the parameter, or <code>-1</code> if it is not a template parameter.
*/
public static int isTemplateParameter(IValue tval) {
@ -292,7 +292,7 @@ public class Value implements IValue {
}
return -1;
}
/**
* Tests whether the value directly references some template parameter.
*/
@ -351,7 +351,7 @@ public class Value implements IValue {
}
if (result != -1)
return new int[] {result};
return NO_INT;
}
@ -365,7 +365,7 @@ public class Value implements IValue {
Object obj= evaluate(expr, unknownSigs, unknown, maxRecursionDepth);
if (obj instanceof Number)
return create(((Number) obj).longValue());
ICPPUnknownBinding[] ua;
if (unknown.isEmpty()) {
ua= ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY;
@ -377,18 +377,18 @@ public class Value implements IValue {
}
return UNKNOWN;
}
/**
* Creates a value off its canonical representation.
*/
public static IValue fromInternalRepresentation(char[] rep, ICPPUnknownBinding[] unknown) {
if (CharArrayUtils.equals(rep, UNKNOWN.getInternalExpression()))
return UNKNOWN;
Long l= parseLong(rep);
if (l != null)
if (l != null)
return create(l.longValue());
return new Value(rep, unknown);
}
@ -399,11 +399,11 @@ public class Value implements IValue {
StringBuilder buf= new StringBuilder(10);
buf.append(UNIQUE_CHAR);
buf.append(++sUnique);
return new Value(extractChars(buf), ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY);
return new Value(extractChars(buf), ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY);
}
/**
* Computes the canonical representation of the value of the expression.
* Computes the canonical representation of the value of the expression.
* Returns a {@code Number} for numerical values or a {@code String}, otherwise.
* @throws UnknownValueException
*/
@ -411,7 +411,7 @@ public class Value implements IValue {
List<ICPPUnknownBinding> unknowns, int maxdepth) throws UnknownValueException {
if (maxdepth < 0 || e == null)
throw UNKNOWN_EX;
if (e instanceof IASTArraySubscriptExpression) {
throw UNKNOWN_EX;
}
@ -465,7 +465,7 @@ public class Value implements IValue {
case IASTLiteralExpression.lk_char_constant:
try {
final char[] image= litEx.getValue();
if (image.length > 1 && image[0] == 'L')
if (image.length > 1 && image[0] == 'L')
return ExpressionEvaluator.getChar(image, 2);
return ExpressionEvaluator.getChar(image, 1);
} catch (EvalException e1) {
@ -489,7 +489,7 @@ public class Value implements IValue {
}
throw UNKNOWN_EX;
}
/**
* Extract a value off a binding.
*/
@ -502,11 +502,11 @@ public class Value implements IValue {
final ICPPTemplateNonTypeParameter tp = (ICPPTemplateNonTypeParameter) b;
return createTemplateParamExpression(tp.getParameterID(), tp.isParameterPack());
}
if (b instanceof ICPPUnknownBinding) {
return createReference((ICPPUnknownBinding) b, unknownSigs, unknowns);
}
IValue value= null;
if (b instanceof IInternalVariable) {
value= ((IInternalVariable) b).getInitialValue(maxdepth - 1);
@ -514,10 +514,10 @@ public class Value implements IValue {
value= ((IVariable) b).getInitialValue();
} else if (b instanceof IEnumerator) {
value= ((IEnumerator) b).getValue();
}
}
if (value != null)
return evaluateValue(value, unknownSigs, unknowns);
throw UNKNOWN_EX;
}
@ -532,21 +532,21 @@ public class Value implements IValue {
}
return "" + REFERENCE_CHAR + idx.toString(); //$NON-NLS-1$
}
private static Object evaluateValue(IValue cv, Map<String, Integer> unknownSigs,
List<ICPPUnknownBinding> unknowns) throws UnknownValueException {
if (cv == Value.UNKNOWN)
if (cv == Value.UNKNOWN)
throw UNKNOWN_EX;
Long lv= cv.numericalValue();
if (lv != null)
return lv;
final IBinding[] oldUnknowns = cv.getUnknownBindings();
final char[] expr= cv.getInternalExpression();
if (oldUnknowns.length == 0)
return new String(expr);
StringBuilder buf= new StringBuilder(expr.length);
boolean skipToSeparator= false;
for (int i = 0; i < expr.length; i++) {
@ -557,7 +557,7 @@ public class Value implements IValue {
if (idx >= oldUnknowns.length)
throw UNKNOWN_EX;
final IBinding old = oldUnknowns[idx];
if (!(old instanceof ICPPUnknownBinding))
if (!(old instanceof ICPPUnknownBinding))
throw UNKNOWN_EX;
buf.append(createReference((ICPPUnknownBinding) old, unknownSigs, unknowns));
@ -576,7 +576,7 @@ public class Value implements IValue {
}
return buf.toString();
}
private static Object evaluateUnaryExpression(IASTUnaryExpression ue,
Map<String, Integer> unknownSigs, List<ICPPUnknownBinding> unknowns, int maxdepth)
throws UnknownValueException {
@ -599,11 +599,11 @@ public class Value implements IValue {
unaryOp == IASTUnaryExpression.op_sizeofParameterPack) {
throw UNKNOWN_EX;
}
final Object value= evaluate(ue.getOperand(), unknownSigs, unknowns, maxdepth);
return combineUnary(unaryOp, value);
return combineUnary(unaryOp, value);
}
private static Object combineUnary(final int unaryOp, final Object value) throws UnknownValueException {
switch (unaryOp) {
case IASTUnaryExpression.op_bracketedPrimary:
@ -628,8 +628,8 @@ public class Value implements IValue {
return v == 0 ? 1 : 0;
}
throw UNKNOWN_EX;
}
}
switch (unaryOp) {
case IASTUnaryExpression.op_prefixIncr:
case IASTUnaryExpression.op_postFixIncr:
@ -643,7 +643,7 @@ public class Value implements IValue {
throw UNKNOWN_EX;
}
private static Object evaluateBinaryExpression(IASTBinaryExpression be,
private static Object evaluateBinaryExpression(IASTBinaryExpression be,
Map<String, Integer> unknownSigs, List<ICPPUnknownBinding> unknowns, int maxdepth)
throws UnknownValueException {
final Object o1= evaluate(be.getOperand1(), unknownSigs, unknowns, maxdepth);
@ -652,7 +652,7 @@ public class Value implements IValue {
final int op= be.getOperator();
return combineBinary(op, o1, o2);
}
private static Object combineBinary(final int op, final Object o1, final Object o2)
throws UnknownValueException {
if (o1 instanceof Number && o2 instanceof Number) {
@ -737,10 +737,10 @@ public class Value implements IValue {
default:
throw UNKNOWN_EX;
}
return "" + BINARY_OP_CHAR + op + SEPARATOR + o1.toString() + SEPARATOR + o2.toString(); //$NON-NLS-1$
}
public static IValue reevaluate(IValue val, int packOffset, IBinding[] resolvedUnknowns,
ICPPTemplateParameterMap map, int maxdepth) {
try {
@ -752,10 +752,10 @@ public class Value implements IValue {
Object obj= reevaluate(reeval, maxdepth);
if (reeval.pos != reeval.fExpression.length)
return UNKNOWN;
if (obj instanceof Number)
return create(((Number) obj).longValue());
ICPPUnknownBinding[] ua;
if (unknown.isEmpty()) {
ua= ICPPUnknownBinding.EMPTY_UNKNOWN_BINDING_ARRAY;
@ -768,7 +768,7 @@ public class Value implements IValue {
return UNKNOWN;
}
private static Object reevaluate(Reevaluation reeval, int maxdepth)
private static Object reevaluate(Reevaluation reeval, int maxdepth)
throws UnknownValueException {
if (maxdepth < 0)
throw UNKNOWN_EX;
@ -778,22 +778,22 @@ public class Value implements IValue {
final int length = buf.length;
if (idx >= length)
throw UNKNOWN_EX;
final char c= buf[idx];
switch (c) {
case BINARY_OP_CHAR:
case BINARY_OP_CHAR:
int op= parseNonNegative(buf, idx + 1);
reeval.nextSeperator();
reeval.nextSeparator();
Object o1= reevaluate(reeval, maxdepth);
Object o2= reevaluate(reeval, maxdepth);
return combineBinary(op, o1, o2);
case UNARY_OP_CHAR:
case UNARY_OP_CHAR:
op= parseNonNegative(buf, idx + 1);
reeval.nextSeperator();
reeval.nextSeparator();
o1= reevaluate(reeval, maxdepth);
return combineUnary(op, o1);
case CONDITIONAL_CHAR:
reeval.nextSeperator();
reeval.nextSeparator();
Object cond= reevaluate(reeval, maxdepth);
Object po= reevaluate(reeval, maxdepth);
Object neg= reevaluate(reeval, maxdepth);
@ -806,17 +806,17 @@ public class Value implements IValue {
}
return "" + CONDITIONAL_CHAR + SEPARATOR + cond.toString() + SEPARATOR + //$NON-NLS-1$
po.toString() + SEPARATOR + neg.toString();
case REFERENCE_CHAR:
case REFERENCE_CHAR:
int num= parseNonNegative(buf, idx + 1);
final IBinding[] resolvedUnknowns= reeval.fResolvedUnknown;
if (num >= resolvedUnknowns.length)
throw UNKNOWN_EX;
reeval.nextSeperator();
reeval.nextSeparator();
return evaluateBinding(resolvedUnknowns[num], reeval.fUnknownSigs, reeval.fUnknowns, maxdepth);
case TEMPLATE_PARAM_CHAR:
num= parseHex(buf, idx + 1);
reeval.nextSeperator();
reeval.nextSeparator();
ICPPTemplateArgument arg = reeval.fMap.getArgument(num);
if (arg != null) {
IValue val= arg.getNonTypeValue();
@ -825,10 +825,10 @@ public class Value implements IValue {
return evaluateValue(val, reeval.fUnknownSigs, reeval.fUnknowns);
}
return createTemplateParamExpression(num, false);
case TEMPLATE_PARAM_PACK_CHAR:
num= parseHex(buf, idx + 1);
reeval.nextSeperator();
reeval.nextSeparator();
arg= null;
if (reeval.fPackOffset >= 0) {
ICPPTemplateArgument[] args= reeval.fMap.getPackExpansion(num);
@ -843,9 +843,9 @@ public class Value implements IValue {
return evaluateValue(val, reeval.fUnknownSigs, reeval.fUnknowns);
}
return createTemplateParamExpression(num, true);
default:
reeval.nextSeperator();
reeval.nextSeparator();
return parseLong(buf, idx);
}
}
@ -858,13 +858,13 @@ public class Value implements IValue {
final int len= value.length;
int result = 0;
boolean ok= false;
for(; offset < len; offset++) {
for (; offset < len; offset++) {
final int digit= (value[offset] - '0');
if (digit < 0 || digit > 9)
break;
if (result > maxvalue)
return -1;
result= result * 10 + digit;
ok= true;
}
@ -880,7 +880,7 @@ public class Value implements IValue {
int result = 0;
boolean ok= false;
final int len= value.length;
for(; offset < len; offset++) {
for (; offset < len; offset++) {
int digit= (value[offset] - '0');
if (digit < 0 || digit > 9) {
digit += '0' - 'a' + 10;
@ -893,13 +893,13 @@ public class Value implements IValue {
}
if ((result & 0xf0000000) != 0)
throw UNKNOWN_EX;
result= (result << 4) + digit;
ok= true;
}
if (!ok)
throw UNKNOWN_EX;
return result;
}
@ -911,26 +911,26 @@ public class Value implements IValue {
final int len= value.length;
boolean negative= false;
long result = 0;
boolean ok= false;
if (offset < len && value[offset] == '-') {
negative = true;
offset++;
}
for(; offset < len; offset++) {
for (; offset < len; offset++) {
final int digit= (value[offset] - '0');
if (digit < 0 || digit > 9)
break;
if (result > maxvalue)
throw UNKNOWN_EX;
result= result * 10 + digit;
ok= true;
}
if (!ok)
throw UNKNOWN_EX;
return negative ? -result : result;
}
@ -943,18 +943,18 @@ public class Value implements IValue {
boolean negative= false;
long result = 0;
int i= 0;
if (len > 0 && value[0] == '-') {
negative = true;
i++;
}
if (i == len)
return null;
for(; i < len; i++) {
for (; i < len; i++) {
if (result > maxvalue)
return null;
final int digit= (value[i] - '0');
if (digit < 0 || digit > 9)
return null;
@ -993,7 +993,7 @@ public class Value implements IValue {
}
public static IValue create(ICPPEvaluation eval, IASTNode point) {
// compute value of evaluation
// Compute value of evaluation
return Value.UNKNOWN;
}
}

View file

@ -274,10 +274,10 @@ public class CPPASTFieldReference extends ASTNode
IASTName[] ns= ((ICPPASTQualifiedName) n).getNames();
if (ns.length < 2)
return EvalFixed.INCOMPLETE;
qualifier= ns[ns.length-2].resolveBinding();
qualifier= ns[ns.length - 2].resolveBinding();
if (qualifier instanceof IProblemBinding)
return EvalFixed.INCOMPLETE;
n= ns[ns.length-1];
n= ns[ns.length - 1];
}
if (n instanceof ICPPASTTemplateId) {
args= CPPTemplates.createTemplateArgumentArray((ICPPASTTemplateId) n);

View file

@ -59,13 +59,9 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx
@Override
public CPPASTLiteralExpression copy(CopyStyle style) {
CPPASTLiteralExpression copy = new CPPASTLiteralExpression(kind,
value == null ? null : value.clone());
copy.setOffsetAndLength(this);
if (style == CopyStyle.withLocations) {
copy.setCopyLocation(this);
}
return copy;
CPPASTLiteralExpression copy =
new CPPASTLiteralExpression(kind, value == null ? null : value.clone());
return copy(copy, style);
}
@Override
@ -250,7 +246,7 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx
case lk_float_constant:
return new EvalFixed(classifyTypeOfFloatLiteral(), PRVALUE, Value.UNKNOWN);
case lk_integer_constant:
return new EvalFixed(classifyTypeOfIntLiteral(),PRVALUE, createIntValue());
return new EvalFixed(classifyTypeOfIntLiteral(), PRVALUE, createIntValue());
case lk_string_literal:
IType type = new CPPBasicType(getCharType(), 0, this);
type = new CPPQualifierType(type, true, false);

View file

@ -57,11 +57,11 @@ public class CPPClassSpecialization extends CPPSpecialization
private ObjectMap specializationMap= ObjectMap.EMPTY_MAP;
private final ThreadLocal<Set<IBinding>> fInProgress= new ThreadLocal<Set<IBinding>>();
public CPPClassSpecialization(ICPPClassType specialized, IBinding owner, ICPPTemplateParameterMap argumentMap) {
public CPPClassSpecialization(ICPPClassType specialized, IBinding owner,
ICPPTemplateParameterMap argumentMap) {
super(specialized, owner, argumentMap);
}
@Override
public ICPPClassType getSpecializedBinding() {
return (ICPPClassType) super.getSpecializedBinding();
@ -75,7 +75,7 @@ public class CPPClassSpecialization extends CPPSpecialization
@Override
public IBinding specializeMember(IBinding original, IASTNode point) {
Set<IBinding> set;
synchronized(this) {
synchronized (this) {
IBinding result= (IBinding) specializationMap.get(original);
if (result != null)
return result;
@ -91,7 +91,7 @@ public class CPPClassSpecialization extends CPPSpecialization
IBinding result= CPPTemplates.createSpecialization(this, original, point);
set.remove(original);
synchronized(this) {
synchronized (this) {
IBinding concurrent= (IBinding) specializationMap.get(original);
if (concurrent != null)
return concurrent;
@ -233,9 +233,6 @@ public class CPPClassSpecialization extends CPPSpecialization
return specScope;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IType#isSameType(org.eclipse.cdt.core.dom.ast.IType)
*/
@Override
public boolean isSameType(IType type) {
if (type == this)
@ -251,7 +248,6 @@ public class CPPClassSpecialization extends CPPSpecialization
@Override
public Object clone() {
// TODO Auto-generated method stub
return this;
}

View file

@ -6,9 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
@ -24,10 +23,40 @@ public interface ICPPEvaluation extends ISerializableEvaluation {
boolean isInitializerList();
boolean isFunctionSet();
/**
* Returns {@code true} if the type of the expression depends on template parameters.
*/
boolean isTypeDependent();
/**
* Returns {@code true} if the value of the expression depends on template parameters.
*/
boolean isValueDependent();
/**
* TODO Add description
*
* @param point determines the scope for name lookups
*/
IType getTypeOrFunctionSet(IASTNode point);
/**
* TODO Add description
*
* @param point determines the scope for name lookups
*/
IValue getValue(IASTNode point);
/**
* TODO Add description
*
* @param point determines the scope for name lookups
*/
ValueCategory getValueCategory(IASTNode point);
/**
* Returns a signature uniquely identifying the evaluation. Two evaluations with identical
* signatures are guaranteed to produce the same results.
*/
char[] getSignature();
}

View file

@ -0,0 +1,228 @@
/*******************************************************************************
* Copyright (c) 2012 Google, Inc 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Sergey Prigogin (Google) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableType;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.core.runtime.CoreException;
public abstract class CPPEvaluation implements ICPPEvaluation {
private static class SignatureBuilder implements ITypeMarshalBuffer {
private static final byte NULL_TYPE= 0;
private static final byte UNSTORABLE_TYPE= (byte) -1;
private static final char[] HEX_DIGITS =
{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
private final StringBuilder fBuffer;
private boolean hexMode;
/**
* Constructor for input buffer.
*/
public SignatureBuilder() {
fBuffer= new StringBuilder();
}
@Override
public String toString() {
return fBuffer.toString();
}
@Override
public void marshalBinding(IBinding binding) throws CoreException {
if (binding instanceof ISerializableType) {
((ISerializableType) binding).marshal(this);
} else if (binding == null) {
putByte(NULL_TYPE);
} else {
appendSeparator();
IBinding owner= binding.getOwner();
if (owner instanceof IType) {
ASTTypeUtil.appendType((IType) owner, true, fBuffer);
fBuffer.append("::"); //$NON-NLS-1$
}
fBuffer.append(binding.getName());
}
}
@Override
public void marshalType(IType type) throws CoreException {
if (type instanceof ISerializableType) {
((ISerializableType) type).marshal(this);
} else if (type == null) {
putByte(NULL_TYPE);
} else if (type instanceof IBinding) {
marshalBinding((IBinding) type);
} else {
assert false : "Cannot serialize " + ASTTypeUtil.getType(type) + " (" + type.getClass().getName() + ")"; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
putByte(UNSTORABLE_TYPE);
}
}
@Override
public void marshalEvaluation(ISerializableEvaluation eval, boolean includeValues) throws CoreException {
if (eval == null) {
putByte(NULL_TYPE);
} else {
eval.marshal(this, includeValues);
}
}
@Override
public void marshalValue(IValue value) throws CoreException {
if (value instanceof Value) {
((Value) value).marshall(this);
} else {
putByte(NULL_TYPE);
}
}
@Override
public void putByte(byte b) {
appendHexDigit(b >> 4);
appendHexDigit(b);
}
@Override
public void putShort(short value) {
appendHexDigit(value >> 12);
appendHexDigit(value >> 8);
appendHexDigit(value >> 4);
appendHexDigit(value);
}
@Override
public void putInt(int value) {
appendHexDigit(value >> 28);
appendHexDigit(value >> 24);
appendHexDigit(value >> 20);
appendHexDigit(value >> 16);
appendHexDigit(value >> 12);
appendHexDigit(value >> 8);
appendHexDigit(value >> 4);
appendHexDigit(value);
}
@Override
public void putLong(long value) {
appendHexDigit((int) (value >> 60));
appendHexDigit((int) (value >> 56));
appendHexDigit((int) (value >> 52));
appendHexDigit((int) (value >> 48));
appendHexDigit((int) (value >> 44));
appendHexDigit((int) (value >> 40));
appendHexDigit((int) (value >> 36));
appendHexDigit((int) (value >> 32));
appendHexDigit((int) (value >> 28));
appendHexDigit((int) (value >> 24));
appendHexDigit((int) (value >> 20));
appendHexDigit((int) (value >> 16));
appendHexDigit((int) (value >> 12));
appendHexDigit((int) (value >> 8));
appendHexDigit((int) (value >> 4));
appendHexDigit((int) value);
}
@Override
public void putCharArray(char[] chars) {
appendSeparator();
for (char c : chars) {
fBuffer.append(c);
}
}
private void appendHexDigit(int val) {
if (hexMode) {
appendSeparator();
fBuffer.append("0x"); //$NON-NLS-1$
hexMode = true;
}
fBuffer.append(HEX_DIGITS[val & 0xF]);
}
private void appendSeparator() {
if (fBuffer.length() != 0)
fBuffer.append(' ');
hexMode = false;
}
@Override
public IBinding unmarshalBinding() throws CoreException {
throw new UnsupportedOperationException();
}
@Override
public IType unmarshalType() throws CoreException {
throw new UnsupportedOperationException();
}
@Override
public ISerializableEvaluation unmarshalEvaluation() throws CoreException {
throw new UnsupportedOperationException();
}
@Override
public IValue unmarshalValue() throws CoreException {
throw new UnsupportedOperationException();
}
@Override
public int getByte() throws CoreException {
throw new UnsupportedOperationException();
}
@Override
public CoreException unmarshallingError() {
throw new UnsupportedOperationException();
}
@Override
public int getShort() throws CoreException {
throw new UnsupportedOperationException();
}
@Override
public int getInt() throws CoreException {
throw new UnsupportedOperationException();
}
@Override
public long getLong() throws CoreException {
throw new UnsupportedOperationException();
}
@Override
public char[] getCharArray() throws CoreException {
throw new UnsupportedOperationException();
}
}
@Override
public char[] getSignature() {
SignatureBuilder buf = new SignatureBuilder();
try {
marshal(buf, true);
} catch (CoreException e) {
CCorePlugin.log(e);
return new char[] { '?' };
}
return buf.toString().toCharArray();
}
}

View file

@ -1,10 +1,13 @@
/*
* CPPFunctionSet.java
* Created on Sep 13, 2010
/*******************************************************************************
* Copyright (c) 2010 Wind River Systems, Inc. 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Copyright 2010 Wind River Systems, Inc. All rights reserved.
*/
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import org.eclipse.cdt.core.dom.ILinkage;
@ -25,7 +28,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPTwoPhaseBinding;
* The actual function can be resolved in certain contexts.
*/
public class CPPFunctionSet implements ICPPTwoPhaseBinding {
private final ICPPFunction[] fBindings;
private final IASTName fName;
private final ICPPTemplateArgument[] fTemplateArguments;

View file

@ -6,9 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
@ -44,13 +43,13 @@ import org.eclipse.core.runtime.CoreException;
/**
* Performs evaluation of an expression.
*/
public class EvalBinary implements ICPPEvaluation {
public class EvalBinary extends CPPEvaluation {
public final static int op_arrayAccess= Byte.MAX_VALUE;
private final int fOperator;
private final ICPPEvaluation fArg1;
private final ICPPEvaluation fArg2;
private ICPPFunction fOverload= CPPFunction.UNINITIALIZED_FUNCTION;
private IType fType;
@ -81,7 +80,7 @@ public class EvalBinary implements ICPPEvaluation {
public boolean isFunctionSet() {
return false;
}
@Override
public IType getTypeOrFunctionSet(IASTNode point) {
if (fType == null) {
@ -121,11 +120,11 @@ public class EvalBinary implements ICPPEvaluation {
@Override
public ValueCategory getValueCategory(IASTNode point) {
if (isTypeDependent())
if (isTypeDependent())
return ValueCategory.PRVALUE;
ICPPFunction overload = getOverload(point);
if (overload != null)
if (overload != null)
return ExpressionTypes.valueCategoryFromFunctionCall(overload);
switch (fOperator) {
@ -144,12 +143,12 @@ public class EvalBinary implements ICPPEvaluation {
return LVALUE;
case IASTBinaryExpression.op_pmdot:
if (!(getTypeOrFunctionSet(point) instanceof ICPPFunctionType))
if (!(getTypeOrFunctionSet(point) instanceof ICPPFunctionType))
return fArg1.getValueCategory(point);
break;
case IASTBinaryExpression.op_pmarrow:
if (!(getTypeOrFunctionSet(point) instanceof ICPPFunctionType))
if (!(getTypeOrFunctionSet(point) instanceof ICPPFunctionType))
return LVALUE;
break;
}
@ -186,15 +185,15 @@ public class EvalBinary implements ICPPEvaluation {
public IType computeType(IASTNode point) {
// Check for overloaded operator.
ICPPFunction o= getOverload(point);
if (o != null)
if (o != null)
return typeFromFunctionCall(o);
final IType originalType1 = fArg1.getTypeOrFunctionSet(point);
final IType type1 = prvalueTypeWithResolvedTypedefs(originalType1);
if (type1 instanceof ISemanticProblem) {
return type1;
}
final IType originalType2 = fArg2.getTypeOrFunctionSet(point);
final IType type2 = prvalueTypeWithResolvedTypedefs(originalType2);
if (type2 instanceof ISemanticProblem) {
@ -206,7 +205,6 @@ public class EvalBinary implements ICPPEvaluation {
return ExpressionTypes.restoreTypedefs(type, originalType1, originalType2);
}
switch (fOperator) {
case op_arrayAccess:
if (type1 instanceof IPointerType) {
@ -216,7 +214,7 @@ public class EvalBinary implements ICPPEvaluation {
return glvalueType(((IPointerType) type2).getType());
}
return ProblemType.UNKNOWN_FOR_EXPRESSION;
case IASTBinaryExpression.op_lessEqual:
case IASTBinaryExpression.op_lessThan:
case IASTBinaryExpression.op_greaterEqual:
@ -230,10 +228,10 @@ public class EvalBinary implements ICPPEvaluation {
case IASTBinaryExpression.op_plus:
if (type1 instanceof IPointerType) {
return ExpressionTypes.restoreTypedefs(type1, originalType1);
}
}
if (type2 instanceof IPointerType) {
return ExpressionTypes.restoreTypedefs(type2, originalType2);
}
}
break;
case IASTBinaryExpression.op_minus:
@ -268,7 +266,7 @@ public class EvalBinary implements ICPPEvaluation {
buffer.marshalEvaluation(fArg1, includeValue);
buffer.marshalEvaluation(fArg2, includeValue);
}
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
int op= buffer.getByte();
ICPPEvaluation arg1= (ICPPEvaluation) buffer.unmarshalEvaluation();

View file

@ -6,9 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
@ -24,19 +23,18 @@ import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.core.runtime.CoreException;
/**
* Performs evaluation of an expression.
*/
public class EvalBinaryTypeId implements ICPPEvaluation {
public class EvalBinaryTypeId extends CPPEvaluation {
private final Operator fOperator;
private final IType fType1, fType2;
private boolean fCheckedValueDependent;
private boolean fIsValueDependent;
public EvalBinaryTypeId(Operator kind, IType type1, IType type2) {
fOperator= kind;
fType1= type1;
@ -105,7 +103,7 @@ public class EvalBinaryTypeId implements ICPPEvaluation {
buffer.marshalType(fType1);
buffer.marshalType(fType2);
}
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
int op= buffer.getByte();
IType arg1= buffer.unmarshalType();

View file

@ -6,9 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType;
@ -28,14 +27,13 @@ import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
import org.eclipse.core.runtime.CoreException;
public class EvalBinding implements ICPPEvaluation {
public class EvalBinding extends CPPEvaluation {
private final IBinding fBinding;
private final boolean fFixedType;
private IType fType;
private boolean fCheckedIsValueDependent;
private boolean fIsValueDependent;
@ -56,7 +54,7 @@ public class EvalBinding implements ICPPEvaluation {
public IType getFixedType() {
return fFixedType ? fType : null;
}
@Override
public boolean isInitializerList() {
return false;
@ -75,9 +73,9 @@ public class EvalBinding implements ICPPEvaluation {
}
return fIsTypeDependent;
}
private boolean computeIsTypeDependent() {
if (fBinding instanceof ICPPUnknownBinding)
if (fBinding instanceof ICPPUnknownBinding)
return true;
IType t= null;
@ -105,26 +103,26 @@ public class EvalBinding implements ICPPEvaluation {
}
return fIsValueDependent;
}
private boolean computeIsValueDependent() {
if (fBinding instanceof IEnumerator) {
return Value.isDependentValue(((IEnumerator) fBinding).getValue());
}
}
if (fBinding instanceof ICPPTemplateNonTypeParameter) {
return true;
}
if (fBinding instanceof IVariable) {
return Value.isDependentValue(((IVariable) fBinding).getInitialValue());
}
}
if (fBinding instanceof IFunction) {
return false;
}
}
if (fBinding instanceof ICPPUnknownBinding) {
return true;
}
}
return false;
}
@Override
public IType getTypeOrFunctionSet(IASTNode point) {
if (fType == null) {
@ -132,42 +130,42 @@ public class EvalBinding implements ICPPEvaluation {
}
return fType;
}
private IType computeType(IASTNode point) {
if (fBinding instanceof IEnumerator) {
return ((IEnumerator) fBinding).getType();
}
}
if (fBinding instanceof ICPPTemplateNonTypeParameter) {
IType type= ((ICPPTemplateNonTypeParameter) fBinding).getType();
if (CPPTemplates.isDependentType(type))
return new TypeOfDependentExpression(this);
return prvalueType(type);
}
}
if (fBinding instanceof IVariable) {
final IType type = ((IVariable) fBinding).getType();
if (CPPTemplates.isDependentType(type))
return new TypeOfDependentExpression(this);
return SemanticUtil.mapToAST(glvalueType(type), point);
}
}
if (fBinding instanceof IFunction) {
final IFunctionType type = ((IFunction) fBinding).getType();
if (CPPTemplates.isDependentType(type))
return new TypeOfDependentExpression(this);
return SemanticUtil.mapToAST(type, point);
}
}
return ProblemType.UNKNOWN_FOR_EXPRESSION;
}
@Override
public IValue getValue(IASTNode point) {
return Value.create(this, point);
}
@Override
public ValueCategory getValueCategory(IASTNode point) {
if (fBinding instanceof ICPPTemplateNonTypeParameter)
return ValueCategory.PRVALUE;
if (fBinding instanceof IVariable || fBinding instanceof IFunction) {
return ValueCategory.LVALUE;
}
@ -180,7 +178,7 @@ public class EvalBinding implements ICPPEvaluation {
buffer.marshalBinding(fBinding);
buffer.marshalType(fFixedType ? fType : null);
}
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
IBinding binding= buffer.unmarshalBinding();
IType type= buffer.unmarshalType();

View file

@ -6,9 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromFunctionCall;
@ -26,14 +25,14 @@ import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.core.runtime.CoreException;
public class EvalComma implements ICPPEvaluation {
public class EvalComma extends CPPEvaluation {
private static final ICPPFunction[] NO_FUNCTIONS = {};
private final ICPPEvaluation[] fArguments;
private ICPPFunction[] fOverloads;
private IType fType;
public EvalComma(ICPPEvaluation[] evals) {
fArguments= evals;
}
@ -54,9 +53,9 @@ public class EvalComma implements ICPPEvaluation {
@Override
public boolean isTypeDependent() {
if (fType != null)
if (fType != null)
return fType instanceof TypeOfDependentExpression;
for (ICPPEvaluation arg : fArguments) {
if (arg.isTypeDependent())
return true;
@ -83,12 +82,12 @@ public class EvalComma implements ICPPEvaluation {
private ICPPFunction[] computeOverloads(IASTNode point) {
if (fArguments.length < 2)
return NO_FUNCTIONS;
if (isTypeDependent())
return NO_FUNCTIONS;
ICPPFunction[] overloads = new ICPPFunction[fArguments.length - 1];
ICPPEvaluation e1= fArguments[0];
ICPPEvaluation e1= fArguments[0];
for (int i = 1; i < fArguments.length; i++) {
ICPPEvaluation e2 = fArguments[i];
ICPPFunction overload = CPPSemantics.findOverloadedOperatorComma(point, e1, e2);
@ -99,7 +98,7 @@ public class EvalComma implements ICPPEvaluation {
e1= new EvalFixed(typeFromFunctionCall(overload), valueCategoryFromFunctionCall(overload), Value.UNKNOWN);
if (e1.getTypeOrFunctionSet(point) instanceof ISemanticProblem) {
e1= e2;
}
}
}
}
return overloads;
@ -112,11 +111,11 @@ public class EvalComma implements ICPPEvaluation {
}
return fType;
}
private IType computeType(IASTNode point) {
if (isTypeDependent()) {
return new TypeOfDependentExpression(this);
}
}
ICPPFunction[] overloads = getOverloads(point);
if (overloads.length > 0) {
ICPPFunction last = overloads[overloads.length - 1];
@ -126,7 +125,7 @@ public class EvalComma implements ICPPEvaluation {
}
return fArguments[fArguments.length-1].getTypeOrFunctionSet(point);
}
@Override
public IValue getValue(IASTNode point) {
return Value.create(this, point);
@ -152,7 +151,7 @@ public class EvalComma implements ICPPEvaluation {
buffer.marshalEvaluation(arg, includeValue);
}
}
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
int len= buffer.getShort();
ICPPEvaluation[] args = new ICPPEvaluation[len];

View file

@ -6,9 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
@ -26,7 +25,7 @@ import org.eclipse.core.runtime.CoreException;
/**
* Performs evaluation of an expression.
*/
public class EvalCompound implements ICPPEvaluation {
public class EvalCompound extends CPPEvaluation {
private final ICPPEvaluation fDelegate;
public EvalCompound(ICPPEvaluation delegate) {
@ -77,7 +76,7 @@ public class EvalCompound implements ICPPEvaluation {
buffer.putByte(ITypeMarshalBuffer.EVAL_COMPOUND);
buffer.marshalEvaluation(fDelegate, includeValue);
}
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
ICPPEvaluation arg= (ICPPEvaluation) buffer.unmarshalEvaluation();
return new EvalCompound(arg);

View file

@ -6,9 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
@ -42,15 +41,15 @@ import org.eclipse.core.runtime.CoreException;
/**
* Performs evaluation of an expression.
*/
public class EvalConditional implements ICPPEvaluation {
public class EvalConditional extends CPPEvaluation {
private final ICPPEvaluation fCondition, fPositive, fNegative;
private final boolean fPositiveThrows, fNegativeThrows;
private ValueCategory fValueCategory;
private IType fType;
private ICPPFunction fOverload;
public EvalConditional(ICPPEvaluation arg1, ICPPEvaluation arg2, ICPPEvaluation arg3,
boolean positiveThrows, boolean negativeThrows) {
// Gnu-extension: Empty positive expression is replaced by condition.
@ -85,7 +84,7 @@ public class EvalConditional implements ICPPEvaluation {
public boolean isInitializerList() {
return false;
}
@Override
public boolean isFunctionSet() {
return false;
@ -95,7 +94,7 @@ public class EvalConditional implements ICPPEvaluation {
evaluate(point);
return fOverload;
}
@Override
public IType getTypeOrFunctionSet(IASTNode point) {
evaluate(point);
@ -106,36 +105,36 @@ public class EvalConditional implements ICPPEvaluation {
public IValue getValue(IASTNode point) {
return Value.create(this, point);
}
@Override
public ValueCategory getValueCategory(IASTNode point) {
evaluate(point);
return fValueCategory;
}
@Override
public boolean isTypeDependent() {
final ICPPEvaluation positive = fPositive == null ? fCondition : fPositive;
return positive.isTypeDependent() || fNegative.isTypeDependent();
}
@Override
public boolean isValueDependent() {
return fCondition.isValueDependent() || (fPositive != null && fPositive.isValueDependent())
|| fNegative.isValueDependent();
}
private void evaluate(IASTNode point) {
if (fValueCategory != null)
return;
fValueCategory= PRVALUE;
final ICPPEvaluation positive = fPositive == null ? fCondition : fPositive;
IType t2 = positive.getTypeOrFunctionSet(point);
IType t3 = fNegative.getTypeOrFunctionSet(point);
final IType uqt2= getNestedType(t2, TDEF | REF | CVTYPE);
final IType uqt3= getNestedType(t3, TDEF | REF | CVTYPE);
if (uqt2 instanceof ISemanticProblem || uqt2 instanceof ICPPUnknownType) {
@ -146,7 +145,7 @@ public class EvalConditional implements ICPPEvaluation {
fType= uqt3;
return;
}
final boolean void2= isVoidType(uqt2);
final boolean void3= isVoidType(uqt3);
@ -163,7 +162,7 @@ public class EvalConditional implements ICPPEvaluation {
}
return;
}
final ValueCategory vcat2= positive.getValueCategory(point);
final ValueCategory vcat3= fNegative.getValueCategory(point);
@ -177,8 +176,8 @@ public class EvalConditional implements ICPPEvaluation {
fValueCategory= PRVALUE;
}
return;
}
}
final boolean isClassType2 = uqt2 instanceof ICPPClassType;
final boolean isClassType3 = uqt3 instanceof ICPPClassType;
@ -211,7 +210,7 @@ public class EvalConditional implements ICPPEvaluation {
}
return;
}
// 5.16-5: At least one class type but no conversion
if (isClassType2 || isClassType3) {
fOverload = CPPSemantics.findOverloadedConditionalOperator(point, positive, fNegative);
@ -293,13 +292,13 @@ public class EvalConditional implements ICPPEvaluation {
firstByte |= ITypeMarshalBuffer.FLAG1;
if (fNegativeThrows)
firstByte |= ITypeMarshalBuffer.FLAG2;
buffer.putByte((byte) firstByte);
buffer.marshalEvaluation(fCondition, includeValue);
buffer.marshalEvaluation(fPositive, includeValue);
buffer.marshalEvaluation(fNegative, includeValue);
}
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
boolean pth= (firstByte & ITypeMarshalBuffer.FLAG1) != 0;
boolean nth= (firstByte & ITypeMarshalBuffer.FLAG2) != 0;

View file

@ -6,9 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
@ -29,10 +28,10 @@ import org.eclipse.core.runtime.CoreException;
/**
* Performs evaluation of an expression.
*/
public class EvalFixed implements ICPPEvaluation {
public static final ICPPEvaluation INCOMPLETE = new EvalFixed(
ProblemType.UNKNOWN_FOR_EXPRESSION, PRVALUE, Value.UNKNOWN);
public class EvalFixed extends CPPEvaluation {
public static final ICPPEvaluation INCOMPLETE =
new EvalFixed(ProblemType.UNKNOWN_FOR_EXPRESSION, PRVALUE, Value.UNKNOWN);
private final IType fType;
private final IValue fValue;
private final ValueCategory fValueCategory;
@ -108,7 +107,7 @@ public class EvalFixed implements ICPPEvaluation {
int firstByte = ITypeMarshalBuffer.EVAL_FIXED;
if (includeValue)
firstByte |= ITypeMarshalBuffer.FLAG1;
switch(fValueCategory) {
switch (fValueCategory) {
case LVALUE:
firstByte |= ITypeMarshalBuffer.FLAG2;
break;
@ -118,30 +117,30 @@ public class EvalFixed implements ICPPEvaluation {
default:
break;
}
buffer.putByte((byte) firstByte);
buffer.marshalType(fType);
if (includeValue) {
buffer.marshalValue(fValue);
}
}
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
final boolean readValue= (firstByte & ITypeMarshalBuffer.FLAG1) != 0;
IValue value;
ValueCategory cat;
switch (firstByte & (ITypeMarshalBuffer.FLAG2 | ITypeMarshalBuffer.FLAG3)) {
case ITypeMarshalBuffer.FLAG2:
cat= LVALUE;
break;
case ITypeMarshalBuffer.FLAG3:
cat= PRVALUE;
break;
default:
cat= XVALUE;
break;
case ITypeMarshalBuffer.FLAG2:
cat= LVALUE;
break;
case ITypeMarshalBuffer.FLAG3:
cat= PRVALUE;
break;
default:
cat= XVALUE;
break;
}
IType type= buffer.unmarshalType();
value= readValue ? buffer.unmarshalValue() : Value.UNKNOWN;
return new EvalFixed(type, cat, value);

View file

@ -6,9 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromReturnType;
@ -37,11 +36,11 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics.LookupMode;
import org.eclipse.core.runtime.CoreException;
public class EvalFunctionCall implements ICPPEvaluation {
public class EvalFunctionCall extends CPPEvaluation {
private final ICPPEvaluation[] fArguments;
private ICPPFunction fOverload= CPPFunction.UNINITIALIZED_FUNCTION;
private IType fType;
public EvalFunctionCall(ICPPEvaluation[] args) {
fArguments= args;
}
@ -88,36 +87,36 @@ public class EvalFunctionCall implements ICPPEvaluation {
private ICPPFunction computeOverload(IASTNode point) {
if (isTypeDependent())
return null;
IType t= SemanticUtil.getNestedType(fArguments[0].getTypeOrFunctionSet(point), TDEF|REF|CVTYPE);
if (t instanceof ICPPClassType) {
return CPPSemantics.findOverloadedOperator(point, fArguments, t, OverloadableOperator.PAREN, LookupMode.NO_GLOBALS);
}
return null;
}
@Override
public IType getTypeOrFunctionSet(IASTNode point) {
if (fType == null)
if (fType == null)
fType= computeType(point);
return fType;
}
private IType computeType(IASTNode point) {
if (isTypeDependent())
if (isTypeDependent())
return new TypeOfDependentExpression(this);
ICPPFunction overload = getOverload(point);
if (overload != null)
if (overload != null)
return ExpressionTypes.typeFromFunctionCall(overload);
final ICPPEvaluation arg0 = fArguments[0];
IType t= SemanticUtil.getNestedType(arg0.getTypeOrFunctionSet(point), TDEF|REF|CVTYPE);
if (t instanceof ICPPClassType) {
return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
}
if (t instanceof IPointerType) {
t= SemanticUtil.getNestedType(((IPointerType) t).getType(), TDEF | REF | CVTYPE);
}
@ -142,7 +141,7 @@ public class EvalFunctionCall implements ICPPEvaluation {
if (overload != null)
return valueCategoryFromFunctionCall(overload);
IType t= fArguments[0].getTypeOrFunctionSet(point);
if (t instanceof IPointerType) {
t= SemanticUtil.getNestedType(((IPointerType) t).getType(), TDEF | REF | CVTYPE);
@ -161,7 +160,7 @@ public class EvalFunctionCall implements ICPPEvaluation {
buffer.marshalEvaluation(arg, includeValue);
}
}
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
int len= buffer.getShort();
ICPPEvaluation[] args = new ICPPEvaluation[len];

View file

@ -6,9 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
@ -22,17 +21,16 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
import org.eclipse.core.runtime.CoreException;
/**
* Performs evaluation of an expression.
*/
public class EvalFunctionSet implements ICPPEvaluation {
public class EvalFunctionSet extends CPPEvaluation {
private final CPPFunctionSet fFunctionSet;
private final boolean fAddressOf;
public EvalFunctionSet(CPPFunctionSet set, boolean addressOf) {
fFunctionSet= set;
fAddressOf= addressOf;
@ -101,7 +99,7 @@ public class EvalFunctionSet implements ICPPEvaluation {
firstByte |= ITypeMarshalBuffer.FLAG1;
if (args != null)
firstByte |= ITypeMarshalBuffer.FLAG2;
buffer.putByte((byte) firstByte);
buffer.putShort((short) bindings.length);
for (ICPPFunction binding : bindings) {
@ -111,7 +109,7 @@ public class EvalFunctionSet implements ICPPEvaluation {
// mstodo marshall arguments
}
}
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
final boolean addressOf= (firstByte & ITypeMarshalBuffer.FLAG1) != 0;
int bindingCount= buffer.getShort();

View file

@ -6,9 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
@ -44,7 +43,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
import org.eclipse.core.runtime.CoreException;
public class EvalID implements ICPPEvaluation {
public class EvalID extends CPPEvaluation {
private final ICPPEvaluation fFieldOwner;
private final char[] fName;
private final IBinding fNameOwner;
@ -60,7 +59,7 @@ public class EvalID implements ICPPEvaluation {
fQualified= qualified;
fTemplateArgs= templateArgs;
}
public ICPPEvaluation getFieldOwner() {
return fFieldOwner;
}
@ -68,7 +67,7 @@ public class EvalID implements ICPPEvaluation {
public IBinding getNameOwner() {
return fNameOwner;
}
public char[] getName() {
return fName;
}
@ -80,11 +79,11 @@ public class EvalID implements ICPPEvaluation {
public boolean isQualified() {
return fQualified;
}
public ICPPTemplateArgument[] getTemplateArgs() {
return fTemplateArgs;
}
@Override
public boolean isInitializerList() {
return false;
@ -99,22 +98,22 @@ public class EvalID implements ICPPEvaluation {
public boolean isTypeDependent() {
return true;
}
@Override
public boolean isValueDependent() {
return true;
}
@Override
public IType getTypeOrFunctionSet(IASTNode point) {
return new TypeOfDependentExpression(this);
}
@Override
public IValue getValue(IASTNode point) {
return Value.create(this, point);
}
@Override
public ValueCategory getValueCategory(IASTNode point) {
return PRVALUE;
@ -129,7 +128,7 @@ public class EvalID implements ICPPEvaluation {
firstByte |= ITypeMarshalBuffer.FLAG2;
if (fTemplateArgs != null)
firstByte |= ITypeMarshalBuffer.FLAG3;
buffer.putByte((byte) firstByte);
buffer.marshalEvaluation(fFieldOwner, false);
buffer.putCharArray(fName);
@ -138,7 +137,7 @@ public class EvalID implements ICPPEvaluation {
// mstodo marshall arguments
}
}
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
final boolean addressOf= (firstByte & ITypeMarshalBuffer.FLAG1) != 0;
final boolean qualified= (firstByte & ITypeMarshalBuffer.FLAG2) != 0;
@ -155,7 +154,7 @@ public class EvalID implements ICPPEvaluation {
public static ICPPEvaluation create(IASTIdExpression expr) {
final IASTName name = expr.getName();
IBinding binding = name.resolvePreBinding();
if (binding instanceof IProblemBinding || binding instanceof IType || binding instanceof ICPPConstructor)
if (binding instanceof IProblemBinding || binding instanceof IType || binding instanceof ICPPConstructor)
return EvalFixed.INCOMPLETE;
if (binding instanceof CPPFunctionSet) {
return new EvalFunctionSet((CPPFunctionSet) binding, isAddressOf(expr));
@ -164,7 +163,7 @@ public class EvalID implements ICPPEvaluation {
IBinding owner = binding.getOwner();
if (owner instanceof IProblemBinding)
return EvalFixed.INCOMPLETE;
ICPPEvaluation fieldOwner= null;
IType fieldOwnerType= withinNonStaticMethod(expr);
if (fieldOwnerType != null) {
@ -175,20 +174,20 @@ public class EvalID implements ICPPEvaluation {
if (lastName instanceof ICPPASTTemplateId) {
templateArgs= CPPTemplates.createTemplateArgumentArray((ICPPASTTemplateId) lastName);
}
return new EvalID(fieldOwner, owner, name.getSimpleID(), isAddressOf(expr),
return new EvalID(fieldOwner, owner, name.getSimpleID(), isAddressOf(expr),
name instanceof ICPPASTQualifiedName, templateArgs);
}
/**
* 9.3.1-3 Transformation to class member access within a non-static member function.
* 9.3.1-3 Transformation to class member access within a non-static member function.
*/
if (binding instanceof ICPPMember && !(binding instanceof IType)
if (binding instanceof ICPPMember && !(binding instanceof IType)
&& !(binding instanceof ICPPConstructor) &&!((ICPPMember) binding).isStatic()) {
IType fieldOwnerType= withinNonStaticMethod(expr);
if (fieldOwnerType != null) {
return new EvalMemberAccess(fieldOwnerType, LVALUE, binding, true);
}
}
if (binding instanceof IEnumerator) {
IType type= ((IEnumerator) binding).getType();
if (type instanceof ICPPEnumeration) {
@ -206,7 +205,7 @@ public class EvalID implements ICPPEvaluation {
}
}
return new EvalBinding(binding, null);
}
}
if (binding instanceof ICPPTemplateNonTypeParameter || binding instanceof IVariable
|| binding instanceof IFunction) {
return new EvalBinding(binding, null);
@ -239,7 +238,7 @@ public class EvalID implements ICPPEvaluation {
e= unary.getOperand();
} else {
return op == IASTUnaryExpression.op_amper;
}
}
}
return false;
}

View file

@ -6,9 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
@ -26,13 +25,13 @@ import org.eclipse.core.runtime.CoreException;
/**
* Performs evaluation of an expression.
*/
public class EvalInitList implements ICPPEvaluation {
public class EvalInitList extends CPPEvaluation {
private final ICPPEvaluation[] fClauses;
public EvalInitList(ICPPEvaluation[] clauses) {
fClauses= clauses;
}
public ICPPEvaluation[] getClauses() {
return fClauses;
}
@ -88,7 +87,7 @@ public class EvalInitList implements ICPPEvaluation {
buffer.marshalEvaluation(arg, includeValue);
}
}
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
int len= buffer.getShort();
ICPPEvaluation[] args = new ICPPEvaluation[len];

View file

@ -6,9 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
@ -47,7 +46,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics.LookupMode;
import org.eclipse.core.runtime.CoreException;
public class EvalMemberAccess implements ICPPEvaluation {
public class EvalMemberAccess extends CPPEvaluation {
private final IType fOwnerType;
private final IBinding fMember;
private final ValueCategory fOwnerValueCategory;
@ -70,7 +69,7 @@ public class EvalMemberAccess implements ICPPEvaluation {
public IType getOwnerType() {
return fOwnerType;
}
public ValueCategory getOwnerValueCategory() {
return fOwnerValueCategory;
}
@ -101,7 +100,7 @@ public class EvalMemberAccess implements ICPPEvaluation {
}
return fIsTypeDependent;
}
private boolean computeIsTypeDependent() {
IType t;
if (fMember instanceof ICPPUnknownBinding) {
@ -126,71 +125,71 @@ public class EvalMemberAccess implements ICPPEvaluation {
}
return fIsValueDependent;
}
private boolean computeIsValueDependent() {
if (fMember instanceof ICPPUnknownBinding) {
return true;
}
}
if (fMember instanceof IEnumerator) {
return Value.isDependentValue(((IEnumerator) fMember).getValue());
}
}
if (fMember instanceof IVariable) {
return Value.isDependentValue(((IVariable) fMember).getInitialValue());
}
}
if (fMember instanceof IFunction) {
return false;
}
}
return false;
}
public static IType getFieldOwnerType(IType fieldOwnerExpressionType, boolean isDeref, IASTNode point, Collection<ICPPFunction> functionBindings,
boolean returnUnnamed) {
IType type= fieldOwnerExpressionType;
if (!isDeref)
return type;
// Bug 205964: as long as the type is a class type, recurse.
// Bug 205964: as long as the type is a class type, recurse.
// Be defensive and allow a max of 20 levels.
for (int j = 0; j < 20; j++) {
IType classType= getUltimateTypeUptoPointers(type);
if (!(classType instanceof ICPPClassType))
if (!(classType instanceof ICPPClassType))
break;
IScope scope = ((ICPPClassType) classType).getCompositeScope();
if (scope == null || scope instanceof ICPPInternalUnknownScope)
break;
/*
* 13.5.6-1: An expression x->m is interpreted as (x.operator->())->m for a
* class object x of type T
*
*
* Construct an AST fragment for x.operator-> which the lookup routines can
* examine for type information.
*/
ICPPEvaluation[] args= {new EvalFixed(type, LVALUE, Value.UNKNOWN)};
ICPPFunction op= CPPSemantics.findOverloadedOperator(point, args, classType, OverloadableOperator.ARROW, LookupMode.NO_GLOBALS);
if (op == null)
if (op == null)
break;
if (functionBindings != null)
functionBindings.add(op);
type= typeFromFunctionCall(op);
type= SemanticUtil.mapToAST(type, point);
}
IType prValue= prvalueTypeWithResolvedTypedefs(type);
if (prValue instanceof IPointerType) {
return glvalueType(((IPointerType) prValue).getType());
}
if (CPPTemplates.isDependentType(type))
return returnUnnamed ? CPPUnknownClass.createUnnamedInstance() : null;
return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
}
@Override
public IType getTypeOrFunctionSet(IASTNode point) {
if (fType == null) {
@ -198,14 +197,14 @@ public class EvalMemberAccess implements ICPPEvaluation {
}
return fType;
}
private IType computeType(IASTNode point) {
if (fMember instanceof ICPPUnknownBinding) {
return new TypeOfDependentExpression(this);
}
if (fMember instanceof IEnumerator) {
return ((IEnumerator) fMember).getType();
}
}
if (fMember instanceof IVariable) {
IType e2 = ((IVariable) fMember).getType();
e2= SemanticUtil.getNestedType(e2, TDEF);
@ -220,15 +219,15 @@ public class EvalMemberAccess implements ICPPEvaluation {
} else {
e2= glvalueType(e2);
}
}
}
return SemanticUtil.mapToAST(e2, point);
}
}
if (fMember instanceof IFunction) {
return SemanticUtil.mapToAST(((IFunction) fMember).getType(), point);
}
return ProblemType.UNKNOWN_FOR_EXPRESSION;
}
private IType addQualifiersForAccess(ICPPField field, IType fieldType, IType ownerType) {
CVQualifier cvq1 = SemanticUtil.getCVQualifier(ownerType);
CVQualifier cvq2 = SemanticUtil.getCVQualifier(fieldType);
@ -248,7 +247,7 @@ public class EvalMemberAccess implements ICPPEvaluation {
public IValue getValue(IASTNode point) {
return Value.create(this, point);
}
@Override
public ValueCategory getValueCategory(IASTNode point) {
if (fMember instanceof IVariable) {
@ -256,7 +255,7 @@ public class EvalMemberAccess implements ICPPEvaluation {
e2= SemanticUtil.getNestedType(e2, TDEF);
if (e2 instanceof ICPPReferenceType) {
return LVALUE;
}
}
if (fMember instanceof ICPPField && !((ICPPField) fMember).isStatic()) {
if (fIsPointerDeref)
return LVALUE;
@ -264,7 +263,7 @@ public class EvalMemberAccess implements ICPPEvaluation {
return fOwnerValueCategory;
}
return LVALUE;
}
}
if (fMember instanceof IFunction) {
return LVALUE;
}
@ -281,12 +280,12 @@ public class EvalMemberAccess implements ICPPEvaluation {
} else if (fOwnerValueCategory == XVALUE) {
firstByte |= ITypeMarshalBuffer.FLAG3;
}
buffer.putByte((byte) firstByte);
buffer.marshalType(fOwnerType);
buffer.marshalBinding(fMember);
}
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
boolean isDeref= (firstByte & ITypeMarshalBuffer.FLAG1) != 0;
ValueCategory ownerValueCat;
@ -297,7 +296,7 @@ public class EvalMemberAccess implements ICPPEvaluation {
} else {
ownerValueCat= PRVALUE;
}
IType ownerType= buffer.unmarshalType();
IBinding member= buffer.unmarshalBinding();
return new EvalMemberAccess(ownerType, ownerValueCat, member, isDeref);

View file

@ -6,9 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromReturnType;
@ -27,11 +26,11 @@ import org.eclipse.core.runtime.CoreException;
/**
* Performs evaluation of an expression.
*/
public class EvalTypeId implements ICPPEvaluation {
public class EvalTypeId extends CPPEvaluation {
private final IType fInputType;
private final ICPPEvaluation[] fArguments;
private IType fOutputType;
public EvalTypeId(IType type, ICPPEvaluation... argument) {
fInputType= type;
fArguments= argument;
@ -44,7 +43,7 @@ public class EvalTypeId implements ICPPEvaluation {
public ICPPEvaluation[] getArguments() {
return fArguments;
}
@Override
public boolean isInitializerList() {
return false;
@ -62,7 +61,7 @@ public class EvalTypeId implements ICPPEvaluation {
}
return fOutputType;
}
private IType computeType() {
if (CPPTemplates.isDependentType(fInputType))
return new TypeOfDependentExpression(this);
@ -103,7 +102,7 @@ public class EvalTypeId implements ICPPEvaluation {
int firstByte = ITypeMarshalBuffer.EVAL_TYPE_ID;
if (includeValue)
firstByte |= ITypeMarshalBuffer.FLAG1;
buffer.putByte((byte) firstByte);
buffer.marshalType(fInputType);
if (includeValue) {
@ -113,7 +112,7 @@ public class EvalTypeId implements ICPPEvaluation {
}
}
}
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
IType type= buffer.unmarshalType();
ICPPEvaluation[] args= null;

View file

@ -6,9 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
@ -40,14 +39,14 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics.LookupMode;
import org.eclipse.core.runtime.CoreException;
public class EvalUnary implements ICPPEvaluation {
public class EvalUnary extends CPPEvaluation {
private static final ICPPEvaluation ZERO_EVAL = new EvalFixed(CPPSemantics.INT_TYPE, PRVALUE, Value.create(0));
private final int fOperator;
private final ICPPEvaluation fArgument;
private ICPPFunction fOverload= CPPFunction.UNINITIALIZED_FUNCTION;
private IType fType;
public EvalUnary(int operator, ICPPEvaluation operand) {
fOperator= operator;
fArgument= operand;
@ -60,7 +59,7 @@ public class EvalUnary implements ICPPEvaluation {
public ICPPEvaluation getArgument() {
return fArgument;
}
@Override
public boolean isInitializerList() {
return false;
@ -73,7 +72,7 @@ public class EvalUnary implements ICPPEvaluation {
@Override
public boolean isTypeDependent() {
if (fType != null)
if (fType != null)
return fType instanceof TypeOfDependentExpression;
switch(fOperator) {
@ -115,10 +114,10 @@ public class EvalUnary implements ICPPEvaluation {
OverloadableOperator op = OverloadableOperator.fromUnaryExpression(fOperator);
if (op == null)
return null;
if (fArgument.isTypeDependent())
return null;
IType type = fArgument.getTypeOrFunctionSet(point);
type = SemanticUtil.getNestedType(type, TDEF | REF | CVTYPE);
if (!CPPSemantics.isUserDefined(type))
@ -132,20 +131,20 @@ public class EvalUnary implements ICPPEvaluation {
}
return CPPSemantics.findOverloadedOperator(point, args, type, op, LookupMode.LIMITED_GLOBALS);
}
@Override
public IType getTypeOrFunctionSet(IASTNode point) {
if (fType == null)
if (fType == null)
fType= computeType(point);
return fType;
}
private IType computeType(IASTNode point) {
if (isTypeDependent())
if (isTypeDependent())
return new TypeOfDependentExpression(this);
ICPPFunction overload = getOverload(point);
if (overload != null)
if (overload != null)
return ExpressionTypes.typeFromFunctionCall(overload);
switch (fOperator) {
@ -163,7 +162,7 @@ public class EvalUnary implements ICPPEvaluation {
type = prvalueTypeWithResolvedTypedefs(type);
if (type instanceof IPointerType) {
return glvalueType(((IPointerType) type).getType());
}
}
if (type instanceof ISemanticProblem) {
return type;
}
@ -212,7 +211,7 @@ public class EvalUnary implements ICPPEvaluation {
buffer.putByte((byte) fOperator);
buffer.marshalEvaluation(fArgument, includeValue);
}
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
int op= buffer.getByte();
ICPPEvaluation arg= (ICPPEvaluation) buffer.unmarshalEvaluation();

View file

@ -6,9 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
@ -24,14 +23,13 @@ import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.core.runtime.CoreException;
public class EvalUnaryTypeID implements ICPPEvaluation {
public class EvalUnaryTypeID extends CPPEvaluation {
private final int fOperator;
private final IType fOrigType;
private IType fType;
public EvalUnaryTypeID(int operator, IType type) {
fOperator= operator;
fOrigType= type;
@ -44,7 +42,7 @@ public class EvalUnaryTypeID implements ICPPEvaluation {
public IType getArgument() {
return fOrigType;
}
@Override
public boolean isInitializerList() {
return false;
@ -82,7 +80,7 @@ public class EvalUnaryTypeID implements ICPPEvaluation {
case op_is_polymorphic:
case op_is_union:
return CPPTemplates.isDependentType(fOrigType);
case op_typeid:
case op_typeof:
return false;
@ -92,11 +90,11 @@ public class EvalUnaryTypeID implements ICPPEvaluation {
@Override
public IType getTypeOrFunctionSet(IASTNode point) {
if (fType == null)
if (fType == null)
fType= computeType(point);
return fType;
}
private IType computeType(IASTNode point) {
switch (fOperator) {
case op_sizeof:
@ -120,7 +118,7 @@ public class EvalUnaryTypeID implements ICPPEvaluation {
case op_is_union:
return CPPBasicType.BOOLEAN;
case op_typeof:
if (isTypeDependent())
if (isTypeDependent())
return new TypeOfDependentExpression(this);
return fOrigType;
}
@ -143,7 +141,7 @@ public class EvalUnaryTypeID implements ICPPEvaluation {
buffer.putByte((byte) fOperator);
buffer.marshalType(fType);
}
public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException {
int op= buffer.getByte();
IType arg= buffer.unmarshalType();

View file

@ -6,13 +6,16 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates.TypeSelection.PARAMETERS;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates.TypeSelection.RETURN_TYPE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;

View file

@ -1,10 +1,13 @@
/*
* FunctionSetType.java
* Created on Sep 14, 2010
/*******************************************************************************
* Copyright (c) 2010 Wind River Systems, Inc. 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Copyright 2010 Wind River Systems, Inc. All rights reserved.
*/
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
@ -22,7 +25,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.Rank;
* Used during overload resolution as a place-holder for function sets.
*/
public class FunctionSetType implements IType {
private final CPPFunctionSet fFunctionSet;
private final boolean fPointerType;

View file

@ -6,7 +6,7 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;

View file

@ -6,11 +6,11 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
* Bryan Wilkinson (QNX)
* Andrew Ferguson (Symbian)
* Sergey Prigogin (Google)
* IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
* Bryan Wilkinson (QNX)
* Andrew Ferguson (Symbian)
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;

View file

@ -6,8 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
* Markus Schorn - initial API and implementation
* Sergey Prigogin (Google)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
@ -33,7 +33,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPASTInternalScope;
* Utility class to populate scope with friend declarations hidden in nested classes
*/
class NamespaceTypeCollector extends ASTVisitor {
private final ICPPASTInternalScope fScope;
public NamespaceTypeCollector(ICPPASTInternalScope scope) {

View file

@ -6,12 +6,18 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.ALLCVQ;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getCVQualifier;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getSimplifiedType;
import java.util.ArrayList;
import java.util.Arrays;
@ -69,9 +75,8 @@ public class TemplateArgumentDeduction {
* @param point
*/
static ICPPTemplateArgument[] deduceForFunctionCall(ICPPFunctionTemplate template,
ICPPTemplateArgument[] tmplArgs, List<IType> fnArgs, List<ValueCategory> argIsLValue, CPPTemplateParameterMap map, IASTNode point)
throws DOMException {
ICPPTemplateArgument[] tmplArgs, List<IType> fnArgs, List<ValueCategory> argIsLValue,
CPPTemplateParameterMap map, IASTNode point) throws DOMException {
final ICPPTemplateParameter[] tmplParams = template.getTemplateParameters();
if (tmplArgs != null && !addExplicitArguments(tmplParams, tmplArgs, map, point))
@ -87,13 +92,14 @@ public class TemplateArgumentDeduction {
* Deduces the mapping for the template parameters from the function parameters,
* returns <code>false</code> if there is no mapping.
*/
static boolean deduceFromFunctionArgs(ICPPFunctionTemplate template, List<IType> fnArgs, List<ValueCategory> argCats,
CPPTemplateParameterMap map, IASTNode point) {
static boolean deduceFromFunctionArgs(ICPPFunctionTemplate template, List<IType> fnArgs,
List<ValueCategory> argCats, CPPTemplateParameterMap map, IASTNode point) {
try {
IType[] fnPars = template.getType().getParameterTypes();
final int fnParCount = fnPars.length;
final ICPPTemplateParameter[] tmplPars = template.getTemplateParameters();
TemplateArgumentDeduction deduct= new TemplateArgumentDeduction(tmplPars, map, new CPPTemplateParameterMap(fnParCount), 0);
TemplateArgumentDeduction deduct=
new TemplateArgumentDeduction(tmplPars, map, new CPPTemplateParameterMap(fnParCount), 0);
IType fnParPack= null;
argLoop: for (int j= 0; j < fnArgs.size(); j++) {
IType par;
@ -474,7 +480,6 @@ public class TemplateArgumentDeduction {
return result.toArray(new ICPPTemplateArgument[result.size()]);
}
/**
* 14.8.2.1.3 If P is a class and has the form template-id, then A can be a derived class of the deduced A.
*/
@ -543,7 +548,9 @@ public class TemplateArgumentDeduction {
* Deduces the template parameter mapping from pairs of template arguments.
* @param point
*/
public static boolean fromTemplateArguments(final ICPPTemplateParameter[] pars, final ICPPTemplateArgument[] p, final ICPPTemplateArgument[] a, CPPTemplateParameterMap map, IASTNode point) throws DOMException {
public static boolean fromTemplateArguments(final ICPPTemplateParameter[] pars,
final ICPPTemplateArgument[] p, final ICPPTemplateArgument[] a, CPPTemplateParameterMap map,
IASTNode point) throws DOMException {
TemplateArgumentDeduction deduct= new TemplateArgumentDeduction(pars, null, map, 0);
final int len= a.length;
if (p == null || p.length != len) {
@ -663,7 +670,6 @@ public class TemplateArgumentDeduction {
return fromType(p.getTypeValue(), a.getTypeValue(), false, point);
}
private boolean fromType(IType p, IType a, boolean allowCVQConversion, IASTNode point) throws DOMException {
while (p != null) {
while (a instanceof ITypedef)

View file

@ -6,9 +6,8 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import org.eclipse.cdt.core.dom.ast.IType;

View file

@ -1,10 +1,13 @@
/*
* UniqueType.java
* Created on 04.10.2010
/*******************************************************************************
* Copyright (c) 2010 Wind River Systems, Inc. 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Copyright 2010 Wind River Systems, Inc. All rights reserved.
*/
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import org.eclipse.cdt.core.dom.ast.IType;
@ -13,7 +16,6 @@ import org.eclipse.cdt.core.dom.ast.IType;
* Used for computing the partial ordering of function templates.
*/
class UniqueType implements IType {
private boolean fForParameterPack;
public UniqueType(boolean forParameterPack) {

View file

@ -7,7 +7,7 @@
*
* Contributors:
* Markus Schorn - initial API and implementation
*******************************************************************************/
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.db;
import org.eclipse.cdt.core.CCorePlugin;
@ -29,13 +29,13 @@ import org.eclipse.core.runtime.CoreException;
* For marshalling types to byte arrays.
*/
public class TypeMarshalBuffer implements ITypeMarshalBuffer {
public final static byte[] EMPTY= { 0, 0, 0, 0, 0, 0 };
public final static byte NULL_TYPE= 0;
public final static byte INDIRECT_TYPE= (byte) -1;
public final static byte BINDING_TYPE= (byte) -2;
public final static byte UNSTORABLE_TYPE= (byte) -3;
public final static IType UNSTORABLE_TYPE_PROBLEM = new ProblemType(ISemanticProblem.TYPE_NOT_PERSISTED);
public static final byte[] EMPTY= { 0, 0, 0, 0, 0, 0 };
public static final byte NULL_TYPE= 0;
public static final byte INDIRECT_TYPE= (byte) -1;
public static final byte BINDING_TYPE= (byte) -2;
public static final byte UNSTORABLE_TYPE= (byte) -3;
public static final IType UNSTORABLE_TYPE_PROBLEM = new ProblemType(ISemanticProblem.TYPE_NOT_PERSISTED);
static {
assert EMPTY.length == Database.TYPE_SIZE;
@ -83,14 +83,14 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer {
putByte((byte) 0);
putRecordPointer(pb.getRecord());
}
}
}
}
@Override
public IBinding unmarshalBinding() throws CoreException {
if (fPos >= fBuffer.length)
throw unmarshallingError();
byte firstByte= fBuffer[fPos];
if (firstByte == BINDING_TYPE) {
fPos+= 2;
@ -99,12 +99,12 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer {
} else if (firstByte == NULL_TYPE || firstByte == UNSTORABLE_TYPE) {
fPos++;
return null;
}
}
IType type= fLinkage.unmarshalType(this);
if (type == null || type instanceof IBinding)
return (IBinding) type;
throw unmarshallingError();
}
@ -117,7 +117,7 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer {
} else if (type instanceof IBinding) {
marshalBinding((IBinding) type);
} else {
assert false : "Cannot serialize " + ASTTypeUtil.getType(type) + "(" + type.getClass().getName() + ")"; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
assert false : "Cannot serialize " + ASTTypeUtil.getType(type) + " (" + type.getClass().getName() + ")"; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
putByte(UNSTORABLE_TYPE);
}
}
@ -126,10 +126,10 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer {
public IType unmarshalType() throws CoreException {
if (fPos >= fBuffer.length)
throw unmarshallingError();
byte firstByte= fBuffer[fPos];
if (firstByte == BINDING_TYPE) {
fPos+= 2;
fPos += 2;
long rec= getRecordPointer();
return (IType) fLinkage.getNode(rec);
} else if (firstByte == NULL_TYPE) {
@ -139,7 +139,7 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer {
fPos++;
return UNSTORABLE_TYPE_PROBLEM;
}
return fLinkage.unmarshalType(this);
}
@ -150,18 +150,18 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer {
} else {
eval.marshal(this, includeValues);
}
}
}
@Override
public ISerializableEvaluation unmarshalEvaluation() throws CoreException {
if (fPos >= fBuffer.length)
throw unmarshallingError();
byte firstByte= fBuffer[fPos];
if (firstByte == NULL_TYPE) {
fPos++;
return null;
}
}
return fLinkage.unmarshalEvaluation(this);
}
@ -171,14 +171,14 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer {
((Value) value).marshall(this);
} else {
putByte(NULL_TYPE);
}
}
}
@Override
public IValue unmarshalValue() throws CoreException {
if (fPos >= fBuffer.length)
throw unmarshallingError();
return Value.unmarshal(this);
}
@ -209,7 +209,7 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer {
@Override
public int getByte() throws CoreException {
if (fPos+1 > fBuffer.length)
if (fPos + 1 > fBuffer.length)
throw unmarshallingError();
return 0xff & fBuffer[fPos++];
}
@ -218,6 +218,7 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer {
public CoreException unmarshallingError() {
return new CoreException(CCorePlugin.createStatus("Unmarshalling error")); //$NON-NLS-1$
}
public CoreException marshallingError() {
return new CoreException(CCorePlugin.createStatus("Marshalling error")); //$NON-NLS-1$
}
@ -225,31 +226,33 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer {
@Override
public void putShort(short value) {
request(2);
fBuffer[fPos++]= (byte)(value >> 8);
fBuffer[fPos++]= (byte)(value);
fBuffer[fPos++]= (byte) (value >> 8);
fBuffer[fPos++]= (byte) (value);
}
@Override
public int getShort() throws CoreException {
if (fPos+2 > fBuffer.length)
if (fPos + 2 > fBuffer.length)
throw unmarshallingError();
final int byte1 = 0xff & fBuffer[fPos++];
final int byte2 = 0xff & fBuffer[fPos++];
return (((byte1 << 8) | (byte2 & 0xff)));
}
@Override
public void putInt(int value) {
request(4);
fPos += 4;
int p= fPos;
fBuffer[--p]= (byte)(value); value >>= 8;
fBuffer[--p]= (byte)(value); value >>= 8;
fBuffer[--p]= (byte)(value); value >>= 8;
fBuffer[--p]= (byte)(value);
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value);
}
@Override
public int getInt() throws CoreException {
if (fPos+4 > fBuffer.length)
if (fPos + 4 > fBuffer.length)
throw unmarshallingError();
int result= 0;
result |= fBuffer[fPos++] & 0xff; result <<= 8;
@ -264,19 +267,19 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer {
request(8);
fPos += 8;
int p= fPos;
fBuffer[--p]= (byte)(value); value >>= 8;
fBuffer[--p]= (byte)(value); value >>= 8;
fBuffer[--p]= (byte)(value); value >>= 8;
fBuffer[--p]= (byte)(value); value >>= 8;
fBuffer[--p]= (byte)(value); value >>= 8;
fBuffer[--p]= (byte)(value); value >>= 8;
fBuffer[--p]= (byte)(value); value >>= 8;
fBuffer[--p]= (byte)(value);
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value); value >>= 8;
fBuffer[--p]= (byte) (value);
}
@Override
public long getLong() throws CoreException {
if (fPos+8 > fBuffer.length)
if (fPos + 8 > fBuffer.length)
throw unmarshallingError();
long result= 0;
result |= fBuffer[fPos++] & 0xff; result <<= 8;
@ -293,7 +296,7 @@ public class TypeMarshalBuffer implements ITypeMarshalBuffer {
private void putRecordPointer(long record) {
request(Database.PTR_SIZE);
Chunk.putRecPtr(record, fBuffer, fPos);
fPos+= Database.PTR_SIZE;
fPos += Database.PTR_SIZE;
}
private long getRecordPointer() throws CoreException {

View file

@ -13,11 +13,6 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom.cpp;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
@ -119,6 +114,11 @@ import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
import org.eclipse.core.runtime.CoreException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
/**
* Container for c++-entities.
*/
@ -127,15 +127,15 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
public final static int CACHE_BASES= 1;
public final static int CACHE_INSTANCES= 2;
public final static int CACHE_INSTANCE_SCOPE= 3;
private final static int FIRST_NAMESPACE_CHILD_OFFSET= PDOMLinkage.RECORD_SIZE;
@SuppressWarnings("hiding")
private final static int RECORD_SIZE= FIRST_NAMESPACE_CHILD_OFFSET + Database.PTR_SIZE;
// Only used when writing to database, which is single-threaded
private final LinkedList<Runnable> postProcesses = new LinkedList<Runnable>();
private final LinkedList<Runnable> postProcesses = new LinkedList<Runnable>();
public PDOMCPPLinkage(PDOM pdom, long record) {
super(pdom, record);
}
@ -168,13 +168,13 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
class ConfigureTemplateParameters implements Runnable {
private final IPDOMCPPTemplateParameter[] fPersisted;
private final ICPPTemplateParameter[] fOriginal;
public ConfigureTemplateParameters(ICPPTemplateParameter[] original, IPDOMCPPTemplateParameter[] params) {
fOriginal= original;
fPersisted= params;
postProcesses.add(this);
}
@Override
public void run() {
for (int i = 0; i < fOriginal.length; i++) {
@ -184,18 +184,18 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
}
}
}
class ConfigurePartialSpecialization implements Runnable {
IPDOMPartialSpecialization partial;
ICPPClassTemplatePartialSpecialization binding;
public ConfigurePartialSpecialization(IPDOMPartialSpecialization partial,
ICPPClassTemplatePartialSpecialization binding) {
this.partial = partial;
this.binding = binding;
postProcesses.add(this);
}
@Override
public void run() {
try {
@ -209,7 +209,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
}
}
}
class ConfigureFunctionTemplate implements Runnable {
private final PDOMCPPFunctionTemplate fTemplate;
private final IPDOMCPPTemplateParameter[] fTemplateParameters;
@ -217,7 +217,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
private final ICPPFunctionType fOriginalFunctionType;
private final ICPPParameter[] fOriginalParameters;
private final IType[] fOriginalExceptionSpec;
public ConfigureFunctionTemplate(ICPPFunctionTemplate original, PDOMCPPFunctionTemplate template) throws DOMException {
fTemplate = template;
fTemplateParameters= template.getTemplateParameters();
@ -227,7 +227,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
fOriginalExceptionSpec= template.extractExceptionSpec(original);
postProcesses.add(this);
}
@Override
public void run() {
for (int i = 0; i < fOriginalTemplateParameters.length; i++) {
@ -238,7 +238,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
fTemplate.initData(fOriginalFunctionType, fOriginalParameters, fOriginalExceptionSpec);
}
}
/**
* Adds or returns existing binding for the given name.
*/
@ -255,7 +255,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
addImplicitMethods(pdomBinding, (ICPPClassType) binding);
}
}
handlePostProcesses();
return pdomBinding;
}
@ -277,18 +277,18 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
if (cannotAdapt(inputBinding)) {
return null;
}
PDOMBinding pdomBinding= attemptFastAdaptBinding(inputBinding);
if (pdomBinding == null) {
// assign names to anonymous types.
IBinding binding= PDOMASTAdapter.getAdapterForAnonymousASTBinding(inputBinding);
if (binding == null)
if (binding == null)
return null;
final PDOMNode parent= adaptOrAddParent(true, binding);
if (parent == null)
return null;
long fileLocalRec[]= {0};
pdomBinding = adaptBinding(parent, binding, fileLocalRec);
if (pdomBinding != null) {
@ -349,9 +349,9 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
PDOMNode parent2= null;
// template parameters are created directly by their owners.
if (binding instanceof ICPPTemplateParameter)
if (binding instanceof ICPPTemplateParameter)
return null;
if (binding instanceof ICPPSpecialization) {
IBinding specialized = ((ICPPSpecialization) binding).getSpecializedBinding();
PDOMBinding pdomSpecialized= addBinding(specialized, null);
@ -427,7 +427,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
insertIntoNestedBindingsIndex(pdomBinding);
}
}
return pdomBinding;
}
@ -438,8 +438,8 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
((PDOMCPPNamespace) node).addToList(record + FIRST_NAMESPACE_CHILD_OFFSET);
}
}
private PDOMBinding createSpecialization(PDOMNode parent, PDOMBinding orig, IBinding special)
private PDOMBinding createSpecialization(PDOMNode parent, PDOMBinding orig, IBinding special)
throws CoreException, DOMException {
PDOMBinding result= null;
if (special instanceof ICPPDeferredClassInstance) {
@ -465,7 +465,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
result= new PDOMCPPFieldSpecialization(this, parent, (ICPPField) special, orig);
} else if (special instanceof ICPPFunctionTemplate) {
if (special instanceof ICPPConstructor) {
result= new PDOMCPPConstructorTemplateSpecialization( this, parent, (ICPPConstructor) special, orig);
result= new PDOMCPPConstructorTemplateSpecialization( this, parent, (ICPPConstructor) special, orig);
} else if (special instanceof ICPPMethod) {
result= new PDOMCPPMethodTemplateSpecialization( this, parent, (ICPPMethod) special, orig);
} else if (special instanceof ICPPFunction) {
@ -486,10 +486,10 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
} else if (special instanceof ICPPUsingDeclaration) {
result= new PDOMCPPUsingDeclarationSpecialization(this, parent, (ICPPUsingDeclaration) special, orig);
}
return result;
}
private void addImplicitMethods(PDOMBinding type, ICPPClassType binding) throws CoreException {
try {
final long fileLocalRec= type.getLocalToFileRec();
@ -537,7 +537,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
} else if (binding instanceof ICPPFunction) {
return CPP_FUNCTION_INSTANCE;
} else if (binding instanceof ICPPClassType) {
return CPP_CLASS_INSTANCE;
return CPP_CLASS_INSTANCE;
}
} else if (binding instanceof ICPPClassTemplatePartialSpecialization) {
if (binding instanceof ICPPClassTemplatePartialSpecializationSpecialization)
@ -619,7 +619,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
} else if (binding instanceof ITypedef) {
return CPPTYPEDEF;
}
return 0;
}
@ -682,7 +682,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
if (fileLocalRecHolder == null)
return glob;
final long loc= getLocalToFileRec(parent, binding, glob);
if (loc == 0)
if (loc == 0)
return glob;
fileLocalRecHolder[0]= loc;
return CPPFindBinding.findBinding(getIndex(), this, binding, loc);
@ -693,7 +693,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
if (fileLocalRecHolder == null)
return glob;
final long loc= getLocalToFileRec(parent, binding, glob);
if (loc == 0)
if (loc == 0)
return glob;
fileLocalRecHolder[0]= loc;
return CPPFindBinding.findBinding(btree, this, binding, loc);
@ -705,7 +705,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
if (parent instanceof IPDOMMemberOwner) {
PDOMBinding glob= CPPFindBinding.findBinding(parent, this, binding, 0);
final long loc= getLocalToFileRec(parent, binding, glob);
if (loc == 0)
if (loc == 0)
return glob;
fileLocalRecHolder[0]= loc;
return CPPFindBinding.findBinding(parent, this, binding, loc);
@ -714,7 +714,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
}
/**
* Adapts the parent of the given binding to an object contained in this linkage. May return
* Adapts the parent of the given binding to an object contained in this linkage. May return
* <code>null</code> if the binding cannot be adapted or the binding does not exist and addParent
* is set to <code>false</code>.
* @param binding the binding to adapt
@ -747,7 +747,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
owner= owner.getOwner();
}
}
if (owner == null)
return this;
@ -766,7 +766,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
postProcesses.removeFirst().run();
}
}
@Override
public PDOMNode getNode(long record, int nodeType) throws CoreException {
switch (nodeType) {
@ -863,7 +863,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
@Override
public void onCreateName(PDOMFile file, IASTName name, PDOMName pdomName) throws CoreException {
super.onCreateName(file, name, pdomName);
IASTNode parentNode= name.getParent();
if (parentNode instanceof ICPPASTQualifiedName) {
if (name != ((ICPPASTQualifiedName) parentNode).getLastName())
@ -897,7 +897,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
IScope container= CPPVisitor.getContainingScope(name);
boolean doit= false;
PDOMCPPNamespace containerNS= null;
IASTNode node= ASTInternal.getPhysicalNodeOfScope(container);
if (node instanceof IASTTranslationUnit) {
doit= true;
@ -931,7 +931,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
}
}
}
} else if (parentNode instanceof ICPPASTFunctionDeclarator) {
} else if (parentNode instanceof ICPPASTFunctionDeclarator) {
if (parentNode.getParent() instanceof IASTSimpleDeclaration) {
IASTSimpleDeclaration grandparentNode = (IASTSimpleDeclaration) parentNode.getParent();
if (grandparentNode.getDeclSpecifier() instanceof ICPPASTDeclSpecifier) {
@ -974,7 +974,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
@Override
public void onDeleteName(PDOMName pdomName) throws CoreException {
super.onDeleteName(pdomName);
if (pdomName.isBaseSpecifier()) {
PDOMName derivedClassName= (PDOMName) pdomName.getEnclosingDefinition();
if (derivedClassName != null) {
@ -1031,22 +1031,22 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
if (file != null) {
return file;
}
}
}
if (binding instanceof ICPPMember) {
return null;
}
return super.getLocalToFile(binding, glob);
}
@Override
@Override
public PDOMBinding addTypeBinding(IBinding type) throws CoreException {
return addBinding(type, null);
}
@Override
public IType unmarshalType(ITypeMarshalBuffer buffer) throws CoreException {
int firstByte= buffer.getByte();
switch((firstByte & ITypeMarshalBuffer.KIND_MASK)) {
switch ((firstByte & ITypeMarshalBuffer.KIND_MASK)) {
case ITypeMarshalBuffer.ARRAY_TYPE:
return CPPArrayType.unmarshal(firstByte, buffer);
case ITypeMarshalBuffer.BASIC_TYPE:
@ -1068,14 +1068,14 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
case ITypeMarshalBuffer.DEPENDENT_EXPRESSION_TYPE:
return TypeOfDependentExpression.unmarshal(firstByte, buffer);
}
throw new CoreException(CCorePlugin.createStatus("Cannot unmarshal a type, first byte=" + firstByte)); //$NON-NLS-1$
}
@Override
public ISerializableEvaluation unmarshalEvaluation(ITypeMarshalBuffer buffer) throws CoreException {
int firstByte= buffer.getByte();
switch((firstByte & ITypeMarshalBuffer.KIND_MASK)) {
switch ((firstByte & ITypeMarshalBuffer.KIND_MASK)) {
case ITypeMarshalBuffer.EVAL_BINARY:
return EvalBinary.unmarshal(firstByte, buffer);
case ITypeMarshalBuffer.EVAL_BINARY_TYPE_ID:

View file

@ -470,10 +470,15 @@ public class CMainTab extends CAbstractMainTab {
if (exePath.isAbsolute()) {
// For absolute paths, we don't need a project, we can debug the binary directly
// as long as it exists
if (!exePath.toFile().exists()) {
File executable = exePath.toFile();
if (!executable.exists()) {
setErrorMessage(LaunchMessages.getString("CMainTab.Program_does_not_exist")); //$NON-NLS-1$
return false;
}
if (!executable.isFile()) {
setErrorMessage(LaunchMessages.getString("CMainTab.Selection_must_be_file")); //$NON-NLS-1$
return false;
}
} else {
// For relative paths, we need a proper project
String projectName = fProjText.getText().trim();

View file

@ -0,0 +1,848 @@
/*******************************************************************************
* Copyright (c) 2012 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc Khouzam (Ericsson) - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.gdb.service;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.cdt.core.IAddress;
import org.eclipse.cdt.dsf.concurrent.CountingRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.ImmediateDataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.ImmediateRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.RequestMonitor;
import org.eclipse.cdt.dsf.datamodel.CompositeDMContext;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.ICachingService;
import org.eclipse.cdt.dsf.debug.service.IExpressions;
import org.eclipse.cdt.dsf.debug.service.IExpressions2;
import org.eclipse.cdt.dsf.debug.service.IExpressions3;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues;
import org.eclipse.cdt.dsf.debug.service.IRegisters;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterDMContext;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterGroupDMContext;
import org.eclipse.cdt.dsf.debug.service.IStack;
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
import org.eclipse.cdt.dsf.debug.service.IStack.IVariableDMContext;
import org.eclipse.cdt.dsf.debug.service.IStack.IVariableDMData;
import org.eclipse.cdt.dsf.gdb.internal.GdbPlugin;
import org.eclipse.cdt.dsf.mi.service.IGDBPatternMatchingExpressions;
import org.eclipse.cdt.dsf.mi.service.IMIExpressions;
import org.eclipse.cdt.dsf.mi.service.MIRegisters.MIRegisterDMC;
import org.eclipse.cdt.dsf.service.AbstractDsfService;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.osgi.framework.BundleContext;
import com.ibm.icu.text.MessageFormat;
/**
* Expressions service added as a layer above the standard Expressions service.
* This layer allows to support group-expressions and glob-pattern matching.
* Group-expressions give the user the ability to create a comma-separated
* list of expressions in a single entry.
* Glob-patterns are a way to specify a set of expressions that match the
* pattern.
* @since 4.2
*/
public class GDBPatternMatchingExpressions extends AbstractDsfService implements IGDBPatternMatchingExpressions, ICachingService {
/**
* A regex representing each character that can be used to separate
* the different expressions contained in a group-expression.
* The [] are not part the characters, but are used in the regex format.
* Note that we don't allow a space separator because spaces are valid within
* an expression (e.g., i + 1)
*/
private final static String GROUP_EXPRESSION_SEPARATORS_REGEXP = "[,;]"; //$NON-NLS-1$
/**
* A group-expression is an expression that requires expansion into a (potentially empty)
* list of sub-expressions. Using a group-expression allows the user to create groups
* of expressions very quickly.
*
* We support two aspects for group-expressions:
* 1- The glob syntax (http://www.kernel.org/doc/man-pages/online/pages/man7/glob.7.html)
* This allows to user to specify glob-patterns to match different expressions.
* 2- Comma-separated expressions, each potentially using the glob-syntax
*/
protected static class GroupExpressionDMC implements IExpressionDMContext {
/**
* The expression context, as created by the main Expression service.
* We delegate the handling of the expression to it.
*/
private IExpressionDMContext fExprDelegate;
/**
* The set of expressions making up the group expression.
* This list is the result of splitting the original expression
* and then trimming each resulting expression.
*/
private List<String> fExpressionsInGroup = null;
public GroupExpressionDMC(IExpressionDMContext exprDmc) {
fExprDelegate = exprDmc;
}
@Override
public String getExpression() {
return fExprDelegate.getExpression();
}
/**
* Returns an array representing the different expressions
* that make up this group-expression.
*/
public List<String> getExpressionsInGroup() {
if (fExpressionsInGroup == null) {
// Split the list
String[] splitExpressions = getExpression().split(GROUP_EXPRESSION_SEPARATORS_REGEXP);
// Remove any extra whitespace from each resulting expression,
// and ignore any empty expressions.
fExpressionsInGroup = new ArrayList<String>(splitExpressions.length);
for (String expr : splitExpressions) {
expr = expr.trim();
if (!expr.isEmpty()) {
fExpressionsInGroup.add(expr);
}
}
}
return fExpressionsInGroup;
}
@Override
public String getSessionId() {
return fExprDelegate.getSessionId();
}
@Override
public IDMContext[] getParents() {
return fExprDelegate.getParents();
};
@SuppressWarnings("rawtypes")
@Override
public Object getAdapter(Class adapterType) {
return fExprDelegate.getAdapter(adapterType);
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof GroupExpressionDMC)) return false;
return ((GroupExpressionDMC)obj).fExprDelegate.equals(fExprDelegate);
}
@Override
public int hashCode() {
return fExprDelegate.hashCode();
}
}
/**
* The model data interface for group-expressions
*/
protected static class GroupExpressionDMData implements IExpressionDMDataExtension {
private final String fRelativeExpression;
private final int fNumChildren;
public GroupExpressionDMData(String expr, int numChildren) {
assert expr != null;
fRelativeExpression = expr;
fNumChildren = numChildren;
}
@Override
public String getName() {
return fRelativeExpression;
}
@Override
public BasicType getBasicType() {
return IExpressionDMData.BasicType.array;
}
@Override
public String getTypeName() {
return Messages.GroupPattern;
}
@Override
public String getEncoding() {
return null;
}
@Override
public String getTypeId() {
return null;
}
@Override
public Map<String, Integer> getEnumerations() {
return new HashMap<String, Integer>();
}
@Override
public IRegisterDMContext getRegister() {
return null;
}
@Override
public boolean hasChildren() {
return fNumChildren > 0;
}
@Override
public boolean equals(Object other) {
if (this == other) return true;
if (!(other instanceof GroupExpressionDMData)) return false;
return fRelativeExpression.equals(((GroupExpressionDMData)other).fRelativeExpression);
}
@Override
public int hashCode() {
return fRelativeExpression.hashCode();
}
@Override
public String toString() {
return "GroupExpr: " + fRelativeExpression; //$NON-NLS-1$
}
}
/**
* The base expression service to which we delegate all non-group-expression logic.
*/
private IMIExpressions fDelegate;
public GDBPatternMatchingExpressions(DsfSession session, IExpressions delegate) {
super(session);
fDelegate = (IMIExpressions)delegate;
}
@Override
public void initialize(final RequestMonitor requestMonitor) {
super.initialize(
new ImmediateRequestMonitor(requestMonitor) {
@Override
public void handleSuccess() {
doInitialize(requestMonitor);
}});
}
private void doInitialize(final RequestMonitor requestMonitor) {
// Our delegate should not be initialized yet, as we have no
// good way to unregister it.
assert !fDelegate.isRegistered();
// We must first register this service to let the original
// expression service know that it should not register itself.
register(new String[] { IExpressions.class.getName(),
IExpressions2.class.getName(),
IExpressions3.class.getName(),
IMIExpressions.class.getName() },
new Hashtable<String, String>());
// Second, we initialize the delegate so it can perform its duties
fDelegate.initialize(requestMonitor);
}
@Override
public void shutdown(final RequestMonitor requestMonitor) {
fDelegate.shutdown(new RequestMonitor(getExecutor(), requestMonitor) {
@Override
protected void handleSuccess() {
unregister();
GDBPatternMatchingExpressions.super.shutdown(requestMonitor);
}
});
}
@Override
protected BundleContext getBundleContext() {
return GdbPlugin.getBundleContext();
}
@Override
public IExpressionDMContext createExpression(IDMContext ctx, String expression) {
IExpressionDMContext expressionDmc = fDelegate.createExpression(ctx, expression);
if (isGroupExpression(expression)) {
return new GroupExpressionDMC(expressionDmc);
} else {
return expressionDmc;
}
}
@Override
public ICastedExpressionDMContext createCastedExpression(IExpressionDMContext context, CastInfo castInfo) {
// Cannot cast a GroupExpression
assert (!(context instanceof GroupExpressionDMC));
return fDelegate.createCastedExpression(context, castInfo);
}
@Override
public void getExpressionDataExtension(final IExpressionDMContext dmc, final DataRequestMonitor<IExpressionDMDataExtension> rm) {
if (dmc instanceof GroupExpressionDMC) {
getSubExpressionCount(dmc, new ImmediateDataRequestMonitor<Integer>(rm) {
@Override
protected void handleSuccess() {
rm.done(new GroupExpressionDMData(((GroupExpressionDMC)dmc).getExpression(), getData()));
}
});
return;
}
fDelegate.getExpressionDataExtension(dmc, rm);
}
@Override
public void getExpressionData(final IExpressionDMContext dmc, final DataRequestMonitor<IExpressionDMData> rm) {
if (dmc instanceof GroupExpressionDMC) {
getSubExpressionCount(dmc, new ImmediateDataRequestMonitor<Integer>(rm) {
@Override
protected void handleSuccess() {
rm.done(new GroupExpressionDMData(((GroupExpressionDMC)dmc).getExpression(), getData()));
}
});
return;
}
fDelegate.getExpressionData(dmc, rm);
}
@Override
public void getExpressionAddressData(IExpressionDMContext dmc, DataRequestMonitor<IExpressionDMAddress> rm) {
// A GroupExpression does not have an address
if (dmc instanceof GroupExpressionDMC) {
rm.done(new IExpressionDMLocation() {
@Override
public IAddress getAddress() {
return IExpressions.IExpressionDMLocation.INVALID_ADDRESS;
}
@Override
public int getSize() {
return 0;
}
@Override
public String getLocation() {
return ""; //$NON-NLS-1$
}
});
return;
}
fDelegate.getExpressionAddressData(dmc, rm);
}
@Override
public void getSubExpressions(IExpressionDMContext exprCtx, DataRequestMonitor<IExpressionDMContext[]> rm) {
if (exprCtx instanceof GroupExpressionDMC) {
matchGroupExpression((GroupExpressionDMC)exprCtx, -1, -1, rm);
} else {
fDelegate.getSubExpressions(exprCtx, rm);
}
}
@Override
public void getSubExpressions(IExpressionDMContext exprCtx, int startIndex, int length, DataRequestMonitor<IExpressionDMContext[]> rm) {
if (exprCtx instanceof GroupExpressionDMC) {
matchGroupExpression((GroupExpressionDMC)exprCtx, startIndex, length, rm);
} else {
fDelegate.getSubExpressions(exprCtx, startIndex, length, rm);
}
}
@Override
public void getSubExpressionCount(IExpressionDMContext dmc, final DataRequestMonitor<Integer> rm) {
if (dmc instanceof GroupExpressionDMC) {
matchGroupExpression((GroupExpressionDMC)dmc, -1, -1, new ImmediateDataRequestMonitor<IExpressionDMContext[]>(rm) {
@Override
protected void handleSuccess() {
rm.done(getData().length);
}
});
} else {
fDelegate.getSubExpressionCount(dmc, rm);
}
}
@Override
public void getSubExpressionCount(IExpressionDMContext dmc, int maxNumberOfChildren, final DataRequestMonitor<Integer> rm) {
if (dmc instanceof GroupExpressionDMC) {
// No need to worry about maxNumberOfChildren for the case of a group-expression, since there won't be
// a very large amount of them.
matchGroupExpression((GroupExpressionDMC)dmc, -1, -1, new ImmediateDataRequestMonitor<IExpressionDMContext[]>(rm) {
@Override
protected void handleSuccess() {
rm.done(getData().length);
}
});
} else {
fDelegate.getSubExpressionCount(dmc, maxNumberOfChildren, rm);
}
}
@Override
public void getBaseExpressions(IExpressionDMContext exprContext, DataRequestMonitor<IExpressionDMContext[]> rm) {
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, NOT_SUPPORTED, "Not supported", null)); //$NON-NLS-1$
}
@Override
public void canWriteExpression(IExpressionDMContext dmc, DataRequestMonitor<Boolean> rm) {
// A GroupExpression's value cannot be modified
if (dmc instanceof GroupExpressionDMC) {
rm.done(false);
return;
}
fDelegate.canWriteExpression(dmc, rm);
}
@Override
public void writeExpression(IExpressionDMContext dmc, String expressionValue, String formatId, RequestMonitor rm) {
// A GroupExpression's value cannot be modified
assert !(dmc instanceof GroupExpressionDMC);
fDelegate.writeExpression(dmc, expressionValue, formatId, rm);
}
@Override
public void getAvailableFormats(IFormattedDataDMContext dmc, DataRequestMonitor<String[]> rm) {
//For a group expression, we only show the NATURAL format
if (dmc instanceof GroupExpressionDMC) {
rm.done(new String[] { IFormattedValues.NATURAL_FORMAT });
return;
}
fDelegate.getAvailableFormats(dmc, rm);
}
@Override
public FormattedValueDMContext getFormattedValueContext(IFormattedDataDMContext dmc, String formatId) {
// No special handling for GroupExpressions
return fDelegate.getFormattedValueContext(dmc, formatId);
}
@Override
public void getFormattedExpressionValue(FormattedValueDMContext dmc, final DataRequestMonitor<FormattedValueDMData> rm) {
GroupExpressionDMC groupExpr = DMContexts.getAncestorOfType(dmc, GroupExpressionDMC.class);
if (groupExpr != null) {
getSubExpressionCount(groupExpr, new ImmediateDataRequestMonitor<Integer>(rm) {
@Override
protected void handleSuccess() {
int numChildren = getData();
String value;
if (numChildren == 0) {
value = Messages.NoMatches;
} else if (numChildren == 1) {
value = MessageFormat.format(Messages.UniqueMatch, numChildren);
} else {
value = MessageFormat.format(Messages.UniqueMatches, numChildren);
}
rm.done(new FormattedValueDMData(value));
}
});
return;
}
fDelegate.getFormattedExpressionValue(dmc, rm);
}
@Override
public void safeToAskForAllSubExpressions(IExpressionDMContext dmc, DataRequestMonitor<Boolean> rm) {
// Always safe to ask for all sub-expression of a group expression, since we don't expect large
// amounts of children
if (dmc instanceof GroupExpressionDMC) {
rm.done(true);
return;
}
fDelegate.safeToAskForAllSubExpressions(dmc, rm);
}
@Override
public void flushCache(IDMContext context) {
if (fDelegate instanceof ICachingService) {
((ICachingService)fDelegate).flushCache(context);
}
}
/**
* Verify if we are dealing with a group expression.
* @param expr The expression to verify
* @return True if expr is a group expression. A group
* expression is either a comma-separated list of
* expressions, or an expression using a glob-pattern
*/
protected boolean isGroupExpression(String expr) {
// First check for a comma separated list of expression
// We want to re-use the regex that defines our separators, and we need to check
// if the expression contains that regex. I didn't find a method that
// checks if a string contains a regex, so instead we all any character before
// and after the regex, which achieves what we want.
// Note that checking if expr.split(regex) is bigger than 1, will not notice
// an expression that has a separator only at the end.
if (expr.matches(".*" + GROUP_EXPRESSION_SEPARATORS_REGEXP +".*")) { //$NON-NLS-1$ //$NON-NLS-2$
// We are dealing with a group expression.
// It may not be a valid one, but it is one nonetheless.
return true;
}
// Not a comma-separated list. Check if we are dealing with a glob-pattern.
return isGlobPattern(expr);
}
/**
* Verify if we are dealing with a glob-pattern.
* We support the expression * which will match all local variables.
* We support glob-patterns for registers (must start with $)
* @param expr The expression to verify
* @return True if expr is a glob-pattern we support.
*/
protected boolean isGlobPattern(String expr) {
// Get rid of useless whitespace
expr = expr.trim();
// We support the glob-pattern '*' to indicate all local variables
if (expr.equals("*")) { //$NON-NLS-1$
return true;
}
// We only support glob-expressions for registers at this time
if (expr.startsWith("$")) { //$NON-NLS-1$
// see: 'man glob'
if (expr.indexOf('*') != -1 || expr.indexOf('?') != -1 || expr.indexOf('[') != -1) {
return true;
}
}
return false;
}
/**
* Find all expressions that match the specified group-expression.
* This method retains the order of the expressions in the group-expression, to show them
* in the same order as the one specified by the user. The match of each expression in the group
* is sorted alphabetically however.
*
* @param groupExprDmc The group-expression context for which we want the matches (sub-expressions)
* @param startIndex The beginning of the range of matches (-1 means all matches)
* @param length The length of the range of matches (-1 means all matches)
* @param rm RequestMonitor that will contain the range of found matches.
*/
protected void matchGroupExpression(final GroupExpressionDMC groupExprDmc, int startIndex, int length,
final DataRequestMonitor<IExpressionDMContext[]> rm) {
// First separate the group into different expressions.
// We need to create a new list, as we will modify it during our processing.
final List<String> exprList = new ArrayList<String>(groupExprDmc.getExpressionsInGroup());
// List to store the final result, which is all the sub-expressions of this group
final ArrayList<IExpressionDMContext> subExprList = new ArrayList<IExpressionDMContext>();
final int startIndex1 = (startIndex < 0) ? 0 : startIndex;
final int length1 = (length < 0) ? Integer.MAX_VALUE : length;
matchExpressionList(exprList, subExprList, groupExprDmc, new ImmediateRequestMonitor(rm) {
@Override
protected void handleSuccess() {
// It would be nice to allow identical elements, so that the user
// can control their positioning. For example, the pattern $eax, $*, would show
// the $eax first, followed by all other registers sorted alphabetically. In that case
// $eax will be shown again within $*, but that would be ok.
// However, the platform does not handle the same element being there twice.
// Not only does selecting the element jump back and forth between the duplicates,
// but children of duplicated elements are not always right. Because of this, we
// remove all duplicates here.
LinkedHashSet<IExpressionDMContext> uniqueSubExprSet = new LinkedHashSet<IExpressionDMContext>(subExprList);
subExprList.clear();
subExprList.addAll(uniqueSubExprSet);
// Extract the range of interest from the final list
int endIndex = Math.min(startIndex1 + length1, subExprList.size());
List<IExpressionDMContext> subExprRangeList = subExprList.subList(startIndex1, endIndex);
IExpressionDMContext[] subExprRange = subExprRangeList.toArray(new IExpressionDMContext[subExprRangeList.size()]);
rm.done(subExprRange);
}
});
}
/**
* We use this recursive method to serialize the request for matches. Once one request is done,
* we create a new one. This allows us to guarantee that the resulting matches will
* be ordered in the same way every time.
*/
private void matchExpressionList(final List<String> exprList, final List<IExpressionDMContext> subExprList, final IDMContext parentDmc,
final RequestMonitor rm) {
// We've finished parsing the list
if (exprList.isEmpty()) {
rm.done();
return;
}
// Remove the next element from the list and process it. We handle glob-pattern matching if needed
// and sort the result alphabetically in that case.
String expr = exprList.remove(0);
if (isGlobPattern(expr)) {
IExpressionDMContext exprDmc = createExpression(parentDmc, expr);
matchGlobExpression(exprDmc, new ImmediateDataRequestMonitor<List<IExpressionDMContext>>(rm) {
@Override
protected void handleSuccess() {
List<IExpressionDMContext> matches = getData();
// Sort the matches to be more user-friendly
Collections.sort(matches, new Comparator<IExpressionDMContext>() {
@Override
public int compare(IExpressionDMContext o1, IExpressionDMContext o2) {
return o1.getExpression().compareTo(o2.getExpression());
}
});
subExprList.addAll(matches);
// Match the next expression from the list
matchExpressionList(exprList, subExprList, parentDmc, rm);
}
});
} else {
// Just a normal expression
subExprList.add(createExpression(parentDmc, expr));
// Match the next expression from the list
matchExpressionList(exprList, subExprList, parentDmc, rm);
}
}
/**
* Find all expressions that match the specified glob-pattern.
*
* @param exprDmc The expression context for which we want the matches (sub-expressions)
* @param rm RequestMonitor that will contain the matches.
*/
protected void matchGlobExpression(final IExpressionDMContext exprDmc, final DataRequestMonitor<List<IExpressionDMContext>> rm) {
final String fullExpr = exprDmc.getExpression().trim();
if (fullExpr.equals("*")) { //$NON-NLS-1$
matchLocals(exprDmc, rm);
return;
}
// Currently, we only support glob-expressions for registers, so
// we only need to match the glob-expression with register names.
// We should not arrive here if we are not handling a register
assert fullExpr.startsWith("$"); //$NON-NLS-1$
final IRegisters registerService = getServicesTracker().getService(IRegisters.class);
if (registerService == null) {
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Register service unavailable", null)); //$NON-NLS-1$
return;
}
registerService.getRegisterGroups(exprDmc, new ImmediateDataRequestMonitor<IRegisterGroupDMContext[]>(rm) {
@Override
protected void handleSuccess() {
registerService.getRegisters(
new CompositeDMContext(new IDMContext[] { getData()[0], exprDmc } ),
new ImmediateDataRequestMonitor<IRegisterDMContext[]>(rm) {
@Override
protected void handleSuccess() {
assert getData() instanceof MIRegisterDMC[];
ArrayList<IExpressionDMContext> matches = new ArrayList<IExpressionDMContext>();
for (MIRegisterDMC register : (MIRegisterDMC[])getData()) {
String potentialMatch = "$"+register.getName(); //$NON-NLS-1$
if (globMatches(fullExpr, potentialMatch)) {
matches.add(createExpression(exprDmc, potentialMatch));
}
}
rm.done(matches);
}
});
}
});
}
/**
* Find all local variables that match the specified glob-pattern.
* We currently only support matching all local variables using the '*' pattern.
*
* @param globDmc The glob-expression context for which we want the matches (sub-expressions)
* @param rm RequestMonitor that will contain the matches.
*/
protected void matchLocals(final IExpressionDMContext globDmc, final DataRequestMonitor<List<IExpressionDMContext>> rm) {
// We only support '*' for local variables at this time
assert globDmc.getExpression().equals("*"); //$NON-NLS-1$
final IStack stackService = getServicesTracker().getService(IStack.class);
if (stackService == null) {
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Stack service unavailable", null)); //$NON-NLS-1$
return;
}
IFrameDMContext frameCtx = DMContexts.getAncestorOfType(globDmc, IFrameDMContext.class);
if (frameCtx == null) {
rm.done(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE, "Stack frame unavailable", null)); //$NON-NLS-1$
return;
}
stackService.getLocals(frameCtx, new ImmediateDataRequestMonitor<IVariableDMContext[]>(rm) {
@Override
protected void handleSuccess() {
IVariableDMContext[] localsDMCs = getData();
final IVariableDMData[] localsDMData = new IVariableDMData[localsDMCs.length];
final CountingRequestMonitor crm = new CountingRequestMonitor(getExecutor(), rm) {
@Override
public void handleSuccess() {
ArrayList<IExpressionDMContext> expressionDMCs = new ArrayList<IExpressionDMContext>(localsDMData.length);
for (IVariableDMData localDMData : localsDMData) {
expressionDMCs.add(createExpression(globDmc, localDMData.getName()));
}
rm.done(expressionDMCs);
}
};
int countRM = 0;
for (int index=0; index < localsDMCs.length; index++) {
final int finalIndex = index;
stackService.getVariableData(localsDMCs[finalIndex], new ImmediateDataRequestMonitor<IVariableDMData>(crm) {
@Override
public void handleSuccess() {
localsDMData[finalIndex] = getData();
crm.done();
}
});
countRM++;
}
crm.setDoneCount(countRM);
}
});
}
/**
* Verify if the potentialMatch variable matches the glob-pattern.
*
* @param globPattern The glob-pattern to match
* @param potentialMatch The string that must match globPattern.
* @return True of potentialMatch does match globPattern.
*/
protected boolean globMatches(String globPattern, String potentialMatch) {
// Convert the glob-pattern into java regex to do the matching
boolean inBrackets = false;
char[] patternArray = globPattern.toCharArray();
char[] resultArray = new char[patternArray.length * 2 + 2];
int pos = 0;
// Must match from the very beginning
resultArray[pos++] = '^';
for (int i = 0; i < patternArray.length; i++) {
switch(patternArray[i]) {
case '?':
if (inBrackets) {
resultArray[pos++] = '?';
} else {
resultArray[pos++] = '.';
}
break;
case '*':
if (!inBrackets) {
resultArray[pos++] = '.';
}
resultArray[pos++] = '*';
break;
case '-':
if (!inBrackets) {
resultArray[pos++] = '\\';
}
resultArray[pos++] = '-';
break;
case '[':
inBrackets = true;
resultArray[pos++] = '[';
if (i < patternArray.length - 1) {
switch (patternArray[i+1]) {
case '!':
case '^':
resultArray[pos++] = '^';
i++;
break;
case ']':
resultArray[pos++] = ']';
i++;
break;
}
}
break;
case ']':
resultArray[pos++] = ']';
inBrackets = false;
break;
case '\\':
if (i == 0 && patternArray.length > 1 && patternArray[1] == '~') {
resultArray[pos++] = '~';
++i;
} else {
resultArray[pos++] = '\\';
if (i < patternArray.length - 1 && "*?[]".indexOf(patternArray[i+1]) != -1) { //$NON-NLS-1$
resultArray[pos++] = patternArray[++i];
} else {
resultArray[pos++] = '\\';
}
}
break;
default:
// We must escape characters that are not digits or arrays
// specifically, "^$.{}()+|<>"
if (!Character.isLetterOrDigit(patternArray[i])) {
resultArray[pos++] = '\\';
}
resultArray[pos++] = patternArray[i];
break;
}
}
// Must match until the very end
resultArray[pos++] = '$';
try {
Pattern pattern = Pattern.compile(new String(resultArray, 0, pos), Pattern.CASE_INSENSITIVE);
Matcher matcher = pattern.matcher(potentialMatch);
return matcher.find();
} catch(Exception e) {
// If the user put an invalid pattern, we just ignore it
return false;
}
}
}

View file

@ -102,7 +102,7 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
return (V)createHardwareAndOSService(session, (ILaunchConfiguration)arg);
}
}
}
}
return super.createService(clazz, session);
}
@ -151,7 +151,12 @@ public class GdbDebugServicesFactory extends AbstractDsfDebugServicesFactory {
@Override
protected IExpressions createExpressionService(DsfSession session) {
return new MIExpressions(session);
// Replace the standard Expressions service with a version that supports pattern matching.
// Pass in the original service which will be used as a delegate.
// This way of doing things allows to keep the pattern matching aspect isolated
// and easy to remove.
IExpressions originialExpressionService = new MIExpressions(session);
return new GDBPatternMatchingExpressions(session, originialExpressionService);
}
@Override

View file

@ -20,6 +20,10 @@ class Messages extends NLS {
public static String Tracing_not_supported_error;
public static String Invalid_post_mortem_type_error;
public static String Cannot_get_post_mortem_file_path_error;
public static String GroupPattern;
public static String NoMatches;
public static String UniqueMatch;
public static String UniqueMatches;
static {
// initialize resource bundle

View file

@ -11,4 +11,8 @@
Tracing_not_supported_error=Tracing not supported
Invalid_post_mortem_type_error=Invalid post-mortem type
Cannot_get_post_mortem_file_path_error=Cannot get post mortem file path
Cannot_get_post_mortem_file_path_error=Cannot get post mortem file path
GroupPattern=Group-pattern
NoMatches=No matches
UniqueMatch={0} unique match
UniqueMatches={0} unique matches

View file

@ -0,0 +1,20 @@
/*******************************************************************************
* Copyright (c) 2012 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc Khouzam (Ericsson) - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.dsf.mi.service;
/**
* Interface that will indicate that the implementing service supports
* Glob-style expression pattern matching.
* @since 4.2
*/
public interface IGDBPatternMatchingExpressions extends IMIExpressions {
}

View file

@ -30,6 +30,7 @@ import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.ICachingService;
import org.eclipse.cdt.dsf.debug.service.IExpressions;
import org.eclipse.cdt.dsf.debug.service.IExpressions2;
import org.eclipse.cdt.dsf.debug.service.IExpressions3;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues;
import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryChangedEvent;
import org.eclipse.cdt.dsf.debug.service.IMemory.IMemoryDMContext;
@ -836,12 +837,18 @@ public class MIExpressions extends AbstractDsfService implements IMIExpressions,
// Register to receive service events for this session.
getSession().addServiceEventListener(this, null);
// Register this service.
register(new String[] { IExpressions.class.getName(),
IExpressions2.class.getName(),
MIExpressions.class.getName() },
new Hashtable<String, String>());
// Register this service, but only if we don't already have an
// IExpression service present. This allows another expression
// service to be used, while delegating calls to this service.
if (getServicesTracker().getService(IExpressions.class) == null) {
register(new String[] { IExpressions.class.getName(),
IExpressions2.class.getName(),
IExpressions3.class.getName(),
IMIExpressions.class.getName(),
MIExpressions.class.getName() },
new Hashtable<String, String>());
}
// Create the expressionService-specific CommandControl which is our
// variable object manager.
// It will deal with the meta-commands, before sending real MI commands

View file

@ -0,0 +1,18 @@
int foo(int firstarg, bool secondarg) {
bool firstvar = true;
int secondvar = 18;
return 0;
}
int main (int argc, char *argv[])
{
int intvar = 80;
bool boolvar = true;
char chararray[201];
foo(15, true);
return 0;
}

View file

@ -0,0 +1,914 @@
/*******************************************************************************
* Copyright (c) 2012 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc Khouzam (Ericsson) - Initial Implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.tests;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.cdt.debug.core.ICDTLaunchConfigurationConstants;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.ImmediateDataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.Query;
import org.eclipse.cdt.dsf.datamodel.CompositeDMContext;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.IExpressions;
import org.eclipse.cdt.dsf.debug.service.IExpressions.IExpressionDMAddress;
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.IExpressions.IExpressionDMLocation;
import org.eclipse.cdt.dsf.debug.service.IExpressions3.IExpressionDMDataExtension;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMContext;
import org.eclipse.cdt.dsf.debug.service.IFormattedValues.FormattedValueDMData;
import org.eclipse.cdt.dsf.debug.service.IRegisters;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterDMContext;
import org.eclipse.cdt.dsf.debug.service.IRegisters.IRegisterGroupDMContext;
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.ClassAccessor.MIExpressionDMCAccessor;
import org.eclipse.cdt.dsf.mi.service.IGDBPatternMatchingExpressions;
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
import org.eclipse.cdt.dsf.mi.service.IMIExpressions;
import org.eclipse.cdt.dsf.mi.service.MIRegisters.MIRegisterDMC;
import org.eclipse.cdt.dsf.mi.service.command.events.MIStoppedEvent;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.cdt.tests.dsf.gdb.framework.BackgroundRunner;
import org.eclipse.cdt.tests.dsf.gdb.framework.BaseTestCase;
import org.eclipse.cdt.tests.dsf.gdb.framework.SyncUtil;
import org.eclipse.cdt.tests.dsf.gdb.launching.TestsPlugin;
import org.eclipse.core.runtime.Platform;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(BackgroundRunner.class)
public class GDBPatternMatchingExpressionsTest extends BaseTestCase {
private DsfSession fSession;
private DsfServicesTracker fServicesTracker;
protected IMIExpressions fExpService;
protected IRegisters fRegService;
@Override
protected void setLaunchAttributes() {
super.setLaunchAttributes();
setLaunchAttribute(ICDTLaunchConfigurationConstants.ATTR_PROGRAM_NAME, "data/launch/bin/PatternMatchingExpressionsTestApp.exe");
}
@Override
public void doBeforeTest() throws Exception {
super.doBeforeTest();
fSession = getGDBLaunch().getSession();
Runnable runnable = new Runnable() {
@Override
public void run() {
fServicesTracker = new DsfServicesTracker(TestsPlugin.getBundleContext(), fSession.getId());
fExpService = fServicesTracker.getService(IMIExpressions.class);
assertTrue(fExpService instanceof IGDBPatternMatchingExpressions);
fRegService = fServicesTracker.getService(IRegisters.class);
}
};
fSession.getExecutor().submit(runnable).get();
}
@Override
public void doAfterTest() throws Exception {
super.doAfterTest();
fExpService = null;
fServicesTracker.dispose();
}
//**************************************************************************************
// Utility methods
//**************************************************************************************
protected List<String> get_X86_REGS() {
// Because we are dealing with expressions for the registers, we must prefix them with '$'
List<String> list = new LinkedList<String>(Arrays.asList("$eax","$ecx","$edx","$ebx","$esp","$ebp","$esi","$edi","$eip","$eflags",
"$cs","$ss","$ds","$es","$fs","$gs","$st0","$st1","$st2","$st3",
"$st4","$st5","$st6","$st7","$fctrl","$fstat","$ftag","$fiseg","$fioff","$foseg",
"$fooff","$fop","$xmm0","$xmm1","$xmm2","$xmm3","$xmm4","$xmm5","$xmm6","$xmm7",
"$mxcsr","$orig_eax","$mm0","$mm1","$mm2","$mm3","$mm4","$mm5","$mm6","$mm7"));
// On Windows, gdb doesn't report "orig_eax" as a register. Apparently it does on Linux
if (Platform.getOS().equals(Platform.OS_WIN32)) {
list.remove("$orig_eax");
}
return list;
}
protected void checkChildrenCount(final IExpressionDMContext parentDmc, final int expectedCount) throws Throwable {
Query<Integer> query = new Query<Integer>() {
@Override
protected void execute(final DataRequestMonitor<Integer> rm) {
fExpService.getSubExpressionCount(parentDmc, rm);
}
};
fSession.getExecutor().execute(query);
int count = query.get();
assertTrue(String.format("Expected %d but got %d", expectedCount, count), count == expectedCount);
}
protected String getRegisterValue(final String regName, final IMIExecutionDMContext threadDmc) throws Exception {
Query<String> query = new Query<String>() {
@Override
protected void execute(final DataRequestMonitor<String> rm) {
fRegService.getRegisterGroups(threadDmc, new ImmediateDataRequestMonitor<IRegisterGroupDMContext[]>(rm) {
@Override
protected void handleSuccess() {
fRegService.getRegisters(
new CompositeDMContext(new IDMContext[] { getData()[0], threadDmc } ),
new ImmediateDataRequestMonitor<IRegisterDMContext[]>(rm) {
@Override
protected void handleSuccess() {
assert getData() instanceof MIRegisterDMC[];
for (MIRegisterDMC register : (MIRegisterDMC[])getData()) {
if (register.getName().equals(regName)) {
final FormattedValueDMContext valueDmc = fRegService.getFormattedValueContext(register, IFormattedValues.HEX_FORMAT);
fRegService.getFormattedExpressionValue(valueDmc, new ImmediateDataRequestMonitor<FormattedValueDMData>(rm) {
@Override
protected void handleSuccess() {
rm.done(getData().getFormattedValue());
};
});
return;
}
}
// If we get here, we didn't find the register!
assertTrue("Invalid register: " + regName, false);
}
});
}
});
}
};
fSession.getExecutor().execute(query);
return query.get();
}
protected String getExpressionValue(final IExpressionDMContext exprDmc) throws Throwable
{
Query<String> query = new Query<String>() {
@Override
protected void execute(final DataRequestMonitor<String> rm) {
final FormattedValueDMContext valueDmc =
fExpService.getFormattedValueContext(exprDmc, IFormattedValues.HEX_FORMAT);
fExpService.getFormattedExpressionValue(valueDmc,
new ImmediateDataRequestMonitor<FormattedValueDMData>(rm) {
@Override
protected void handleSuccess() {
rm.done(getData().getFormattedValue());
}
});
}
};
fSession.getExecutor().execute(query);
return query.get();
}
// This method tests IExpressions.getSubExpressions(IExpressionDMC, int, int, DRM);
protected IExpressionDMContext[] checkChildren(final IExpressionDMContext parentDmc, final int startIndex, final int length,
String[] expectedValues) throws Throwable {
Query<IExpressionDMContext[]> query = new Query<IExpressionDMContext[]>() {
@Override
protected void execute(final DataRequestMonitor<IExpressionDMContext[]> rm) {
fExpService.getSubExpressions(parentDmc, startIndex, length, rm);
}
};
fSession.getExecutor().execute(query);
IExpressionDMContext[] childDmcs = query.get();
String[] childExpressions = new String[childDmcs.length];
MIExpressionDMCAccessor[] childDmcsAccessor = new MIExpressionDMCAccessor[childDmcs.length];
// Convert to a MIExpressionDMCAccessor to be able to call getRelativeExpression
// Also convert to String[] to be able to use Arrays.toString()
for (int i = 0; i < childExpressions.length; i++) {
childDmcsAccessor[i] = new MIExpressionDMCAccessor(childDmcs[i]);
childExpressions[i] = childDmcsAccessor[i].getRelativeExpression();
}
assertTrue("Expected " + Arrays.toString(expectedValues) + " but got " + Arrays.toString(childExpressions),
expectedValues.length == childExpressions.length);
for (int i = 0; i < childDmcsAccessor.length; i++) {
assertEquals(childDmcsAccessor[i].getRelativeExpression(), expectedValues[i]);
}
return childDmcs;
}
//**************************************************************************************
// Tests methods
//**************************************************************************************
/**
* Test that we can access a single register
*/
@Test
public void testMatchSingleReg() throws Throwable {
final String regName = "esp";
SyncUtil.runToLocation("foo");
MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
IMIExecutionDMContext threadDmc = DMContexts.getAncestorOfType(frameDmc, IMIExecutionDMContext.class);
final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, "$"+regName);
checkChildrenCount(exprDmc, 0);
// get value of expression and compare with register
assertEquals(getRegisterValue(regName, threadDmc), getExpressionValue(exprDmc));
}
/**
* Test that we can access a single variable, without using groups or patterns
*/
@Test
public void testMatchSingleLocal() throws Throwable {
SyncUtil.runToLocation("foo");
MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, "secondvar");
checkChildrenCount(exprDmc, 0);
// get value of expression and compare with register
assertEquals(getExpressionValue(exprDmc), "0x12");
}
/**
* Test that we can create the all-register match
*/
@Test
public void testMatchAllRegs() throws Throwable {
final String exprString = "$*";
List<String> regList = get_X86_REGS();
Collections.sort(regList);
final String[] children = regList.toArray(new String[0]);
SyncUtil.runToLocation("foo");
MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString);
checkChildren(exprDmc, -1, -1, children);
checkChildrenCount(exprDmc, children.length);
}
/**
* Test that we can create the all-locals match
*/
@Test
public void testMatchAllLocals() throws Throwable {
final String exprString = "*";
final String[] children = new String[] { "firstarg", "firstvar", "secondarg", "secondvar" };
SyncUtil.runToLocation("foo");
MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString);
checkChildren(exprDmc, -1, -1, children);
checkChildrenCount(exprDmc, children.length);
}
/**
* Test that we can create the all-locals match for another frame
*/
@Test
public void testMatchAllLocalsOtherFrame() throws Throwable {
final String exprString = "*";
final String[] children = new String[] { "argc", "argv", "boolvar", "chararray", "intvar" };
SyncUtil.runToLocation("foo");
MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 1);
final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString);
checkChildren(exprDmc, -1, -1, children);
checkChildrenCount(exprDmc, children.length);
}
/**
* Test that registers can be matched using '*'
*/
@Test
public void testMatchRegWithStar() throws Throwable {
final String exprString = "$e*";
final String[] children = new String[] { "$eax","$ebp","$ebx","$ecx","$edi","$edx","$eflags","$eip","$es", "$esi","$esp" };
SyncUtil.runToLocation("foo");
MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString);
checkChildren(exprDmc, -1, -1, children);
checkChildrenCount(exprDmc, children.length);
}
/**
* Test that registers can be matched using '?'
*/
@Test
public void testMatchRegWithQuestionMark() throws Throwable {
final String exprString = "$e??";
final String[] children = new String[] { "$eax","$ebp","$ebx","$ecx","$edi","$edx","$eip", "$esi","$esp" };
SyncUtil.runToLocation("foo");
MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString);
checkChildren(exprDmc, -1, -1, children);
checkChildrenCount(exprDmc, children.length);
}
/**
* Test that registers can be matched using [] with a single index
*/
@Test
public void testMatchRegWithBracketsOneDigit() throws Throwable {
final String exprString = "$st[4]";
final String[] children = new String[] { "$st4" };
SyncUtil.runToLocation("foo");
MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString);
checkChildren(exprDmc, -1, -1, children);
checkChildrenCount(exprDmc, children.length);
}
/**
* Test that registers can be matched using '[]' using a range
*/
@Test
public void testMatchRegWithBracketsRange() throws Throwable {
final String exprString = "$st[2-5]";
final String[] children = new String[] { "$st2","$st3", "$st4","$st5" };
SyncUtil.runToLocation("foo");
MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString);
checkChildren(exprDmc, -1, -1, children);
checkChildrenCount(exprDmc, children.length);
}
/**
* Test that all registers and all locals can be matched at the same time
*/
@Test
public void testGroupAllRegsAllLocals() throws Throwable {
final String exprString = "$*, *";
List<String> list = get_X86_REGS();
Collections.sort(list);
list.addAll(Arrays.asList(new String[] { "firstarg", "firstvar", "secondarg", "secondvar" }));
final String[] children = list.toArray(new String[list.size()]);
SyncUtil.runToLocation("foo");
MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString);
checkChildren(exprDmc, -1, -1, children);
checkChildrenCount(exprDmc, children.length);
}
/**
* Test that all local and all registers can be matched at the same time. This
* is the reverse order than the previous test.
*/
@Test
public void testGroupAllLocalsAllRegs() throws Throwable {
final String exprString = "*, $*";
List<String> list = get_X86_REGS();
Collections.sort(list);
list.addAll(0, Arrays.asList(new String[] { "firstarg", "firstvar", "secondarg", "secondvar" }));
final String[] children = list.toArray(new String[list.size()]);
SyncUtil.runToLocation("foo");
MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString);
checkChildren(exprDmc, -1, -1, children);
checkChildrenCount(exprDmc, children.length);
}
/**
* Test that we can match a range
*/
@Test
public void testGroupSubExprRange() throws Throwable {
final String exprString = "$eax, $es, *";
final String[] children = new String[] { "$es", "firstarg", "firstvar", "secondarg" };
SyncUtil.runToLocation("foo");
MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString);
// Check four children starting at position 1
checkChildren(exprDmc, 1, 4, children);
}
/**
* Test that we can group a local with all registers
*/
@Test
public void testGroupOneLocalAllReg() throws Throwable {
final String exprString = "firstvar, $*";
List<String> list = get_X86_REGS();
Collections.sort(list);
list.addAll(0, Arrays.asList(new String[] { "firstvar" }));
final String[] children = list.toArray(new String[list.size()]);
SyncUtil.runToLocation("foo");
MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString);
checkChildren(exprDmc, -1, -1, children);
checkChildrenCount(exprDmc, children.length);
}
/**
* Test that we only return a single instance of a duplicate
* register when using a pattern that matches the register
* more than once.
*/
@Test
public void testUniqueWhenOverlapReg() throws Throwable {
final String exprString = "$eax, $e?x, $eb?";
final String[] children = new String[] { "$eax","$ebx","$ecx","$edx", "$ebp" };
SyncUtil.runToLocation("foo");
MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString);
checkChildren(exprDmc, -1, -1, children);
checkChildrenCount(exprDmc, children.length);
}
/**
* Test that we only return a single instance of a duplicate
* variable when using a pattern that matches the variable
* more than once.
*/
@Test
public void testUniqueWhenOverlapLocal() throws Throwable {
final String exprString = "firstvar,*,firstvar";
final String[] children = new String[] { "firstvar", "firstarg", "secondarg", "secondvar" };
SyncUtil.runToLocation("foo");
MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString);
checkChildren(exprDmc, -1, -1, children);
checkChildrenCount(exprDmc, children.length);
}
/**
* Test that the all-register pattern is sorted alphabetically
*/
@Test
public void testSortedAllReg() throws Throwable {
final String exprString = "$*";
List<String> regList = get_X86_REGS();
Collections.sort(regList);
final String[] children = regList.toArray(new String[0]);
SyncUtil.runToLocation("foo");
MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString);
checkChildren(exprDmc, -1, -1, children);
checkChildrenCount(exprDmc, children.length);
}
/**
* Test that the all-local pattern is sorted alphabetically
*/
@Test
public void testSortedAllLocals() throws Throwable {
final String exprString = "*";
List<String> list = Arrays.asList(new String[] { "firstarg", "firstvar", "secondarg", "secondvar" });
Collections.sort(list);
final String[] children = list.toArray(new String[list.size()]);
SyncUtil.runToLocation("foo");
MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString);
checkChildren(exprDmc, -1, -1, children);
checkChildrenCount(exprDmc, children.length);
}
/**
* Test that individual expressions within a group-expression
* are not sorted between each other, but that each part of the
* group is kept in the user-specified order and sorted within
* itself.
*/
@Test
public void testSeparatlySorted() throws Throwable {
final String exprString = "$*, *";
List<String> list = get_X86_REGS();
Collections.sort(list);
List<String> localsList = Arrays.asList(new String[] { "firstarg", "firstvar", "secondarg", "secondvar" });
Collections.sort(localsList);
list.addAll(localsList);
final String[] children = list.toArray(new String[list.size()]);
SyncUtil.runToLocation("foo");
MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString);
checkChildren(exprDmc, -1, -1, children);
checkChildrenCount(exprDmc, children.length);
}
/**
* Test that group-expression can use a comma as a separator
*/
@Test
public void testCommaSeparation() throws Throwable {
final String exprString = "firstvar,$eax";
final String[] children = new String[] { "firstvar","$eax" };
SyncUtil.runToLocation("foo");
MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString);
checkChildren(exprDmc, -1, -1, children);
checkChildrenCount(exprDmc, children.length);
}
/**
* Test that group-expression can use a semi-colon as a separator
*/
@Test
public void testSemiColonSeparation() throws Throwable {
final String exprString = "firstvar;$eax";
final String[] children = new String[] { "firstvar","$eax" };
SyncUtil.runToLocation("foo");
MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString);
checkChildren(exprDmc, -1, -1, children);
checkChildrenCount(exprDmc, children.length);
}
/**
* Test that group-expression can use a comma and a semi-colon as a
* separator at the same time
*/
@Test
public void testCommaAndSemiColonSeparation() throws Throwable {
final String exprString = "firstvar,$eax;$es";
final String[] children = new String[] { "firstvar","$eax","$es" };
SyncUtil.runToLocation("foo");
MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString);
checkChildren(exprDmc, -1, -1, children);
checkChildrenCount(exprDmc, children.length);
}
/**
* Test that group-expression can have empty terms with commas.
*/
@Test
public void testGroupCommaEmptyTerm() throws Throwable {
final String exprString = ",,firstvar,,$eax,,";
final String[] children = new String[] { "firstvar","$eax" };
SyncUtil.runToLocation("foo");
MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString);
checkChildren(exprDmc, -1, -1, children);
checkChildrenCount(exprDmc, children.length);
}
/**
* Test that group-expression can have empty terms with semi-colon.
*/
@Test
public void testGroupSemiColonEmptyTerm() throws Throwable {
final String exprString = ";;firstvar;;$eax;;";
final String[] children = new String[] { "firstvar","$eax" };
SyncUtil.runToLocation("foo");
MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString);
checkChildren(exprDmc, -1, -1, children);
checkChildrenCount(exprDmc, children.length);
}
/**
* Test that group-expression clean up extra spaces
*/
@Test
public void testExtraSpaces() throws Throwable {
final String exprString = " firstvar , $eax , , ";
final String[] children = new String[] { "firstvar","$eax" };
SyncUtil.runToLocation("foo");
MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString);
checkChildren(exprDmc, -1, -1, children);
checkChildrenCount(exprDmc, children.length);
}
/**
* Test the expression data associated with group-expressions.
*/
@Test
public void testGroupExpressionData() throws Throwable {
final String exprString = "$eax,*";
// final String[] children = new String[] { "$eax", "firstarg", "firstvar", "secondarg", "secondvar" };
SyncUtil.runToLocation("foo");
MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString);
Query<IExpressionDMData> query = new Query<IExpressionDMData>() {
@Override
protected void execute(final DataRequestMonitor<IExpressionDMData> rm) {
fExpService.getExpressionData(exprDmc, rm);
}
};
fSession.getExecutor().execute(query);
IExpressionDMData data = query.get();
Query<IExpressionDMDataExtension> query2 = new Query<IExpressionDMDataExtension>() {
@Override
protected void execute(final DataRequestMonitor<IExpressionDMDataExtension> rm) {
fExpService.getExpressionDataExtension(exprDmc, rm);
}
};
fSession.getExecutor().execute(query2);
IExpressionDMDataExtension dataExt = query2.get();
// Make sure the two different ways to get the group-expression data return
// teh same thing, to make sure we didn't forget to update one of the two.
assertEquals(data, dataExt);
assertEquals(exprString, dataExt.getName());
assertEquals(IExpressionDMData.BasicType.array, dataExt.getBasicType());
assertEquals("Group-pattern", dataExt.getTypeName());
assertTrue("IExpressionDMDataExtension.HasChildren should have been true", dataExt.hasChildren());
assertEquals("Group-pattern", dataExt.getTypeName());
}
/**
* Test the expression address data associated with group-expressions.
*/
@Test
public void testGroupExpressionAddressData() throws Throwable {
final String exprString = "$eax,*";
// final String[] children = new String[] { "$eax", "firstarg", "firstvar", "secondarg", "secondvar" };
SyncUtil.runToLocation("foo");
MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString);
Query<IExpressionDMAddress> query = new Query<IExpressionDMAddress>() {
@Override
protected void execute(final DataRequestMonitor<IExpressionDMAddress> rm) {
fExpService.getExpressionAddressData(exprDmc, rm);
}
};
fSession.getExecutor().execute(query);
IExpressionDMAddress data = query.get();
assertTrue("The address data shoudl be of type IExpressionDMLocation", data instanceof IExpressionDMLocation);
assertEquals(IExpressions.IExpressionDMLocation.INVALID_ADDRESS, data.getAddress());
assertEquals(0, data.getSize());
assertEquals("", ((IExpressionDMLocation)data).getLocation());
}
/**
* Test the call to IExpressions.getSubExpressions(IExpressionDMC, DRM);
* which is not tested by the method checkChildren() used by our other tests
*/
@Test
public void testGroupGetSubExpressions() throws Throwable {
final String exprString = "$eax,*";
final String[] children = new String[] { "$eax", "firstarg", "firstvar", "secondarg", "secondvar" };
SyncUtil.runToLocation("foo");
MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString);
Query<IExpressionDMContext[]> query = new Query<IExpressionDMContext[]>() {
@Override
protected void execute(final DataRequestMonitor<IExpressionDMContext[]> rm) {
fExpService.getSubExpressions(exprDmc, rm);
}
};
fSession.getExecutor().execute(query);
IExpressionDMContext[] childDmcs = query.get();
String[] childExpressions = new String[childDmcs.length];
MIExpressionDMCAccessor[] childDmcsAccessor = new MIExpressionDMCAccessor[childDmcs.length];
// Convert to a MIExpressionDMCAccessor to be able to call getRelativeExpression
// Also convert to String[] to be able to use Arrays.toString()
for (int i = 0; i < childExpressions.length; i++) {
childDmcsAccessor[i] = new MIExpressionDMCAccessor(childDmcs[i]);
childExpressions[i] = childDmcsAccessor[i].getRelativeExpression();
}
assertTrue("Expected " + Arrays.toString(children) + " but got " + Arrays.toString(childExpressions),
children.length == childExpressions.length);
for (int i = 0; i < childDmcsAccessor.length; i++) {
assertEquals(childDmcsAccessor[i].getRelativeExpression(), children[i]);
}
}
/**
* Test we cannot modify the value of a group-expression
*/
@Test
public void testGroupExpressionNotModifiable() throws Throwable {
final String exprString = "$eax,*";
// final String[] children = new String[] { "$eax", "firstarg", "firstvar", "secondarg", "secondvar" };
SyncUtil.runToLocation("foo");
MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString);
Query<Boolean> query = new Query<Boolean>() {
@Override
protected void execute(final DataRequestMonitor<Boolean> rm) {
fExpService.canWriteExpression(exprDmc, rm);
}
};
fSession.getExecutor().execute(query);
boolean canWrite = query.get();
assertFalse("Should not be able to modify the value of a group-expression", canWrite);
}
/**
* Test the only available format for the value of a group-expression is NATURAL
*/
@Test
public void testGroupExpressionAvailableFormats() throws Throwable {
final String exprString = "$eax,*";
// final String[] children = new String[] { "$eax", "firstarg", "firstvar", "secondarg", "secondvar" };
SyncUtil.runToLocation("foo");
MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
final IExpressionDMContext exprDmc = SyncUtil.createExpression(frameDmc, exprString);
Query<String[]> query = new Query<String[]>() {
@Override
protected void execute(final DataRequestMonitor<String[]> rm) {
fExpService.getAvailableFormats(exprDmc, rm);
}
};
fSession.getExecutor().execute(query);
String[] formats = query.get();
assertEquals(1, formats.length);
assertEquals(IFormattedValues.NATURAL_FORMAT, formats[0]);
}
/**
* Test the different values returned by a group-expression
*/
@Test
public void testGroupExpressionValue() throws Throwable {
final String noMatchExpr = "$zzz*";
final String singleMatchExpr = "$eax,";
final String doubleMatchExpr = "$eax,$ebx";
SyncUtil.runToLocation("foo");
MIStoppedEvent stoppedEvent = SyncUtil.step(2, StepType.STEP_OVER);
IFrameDMContext frameDmc = SyncUtil.getStackFrame(stoppedEvent.getDMContext(), 0);
final IExpressionDMContext noMatchExprDmc = SyncUtil.createExpression(frameDmc, noMatchExpr);
final IExpressionDMContext singleMatchExprDmc = SyncUtil.createExpression(frameDmc, singleMatchExpr);
final IExpressionDMContext doubleMatchExprDmc = SyncUtil.createExpression(frameDmc, doubleMatchExpr);
assertEquals("No matches", getExpressionValue(noMatchExprDmc));
assertEquals("1 unique match", getExpressionValue(singleMatchExprDmc));
assertEquals("2 unique matches", getExpressionValue(doubleMatchExprDmc));
}
}

View file

@ -0,0 +1,24 @@
/*******************************************************************************
* Copyright (c) 2012 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc Khouzam (Ericsson) - Initial Implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.tests.tests_6_6;
import org.eclipse.cdt.tests.dsf.gdb.framework.BackgroundRunner;
import org.eclipse.cdt.tests.dsf.gdb.tests.GDBPatternMatchingExpressionsTest;
import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants;
import org.junit.runner.RunWith;
@RunWith(BackgroundRunner.class)
public class GDBPatternMatchingExpressionsTest_6_6 extends GDBPatternMatchingExpressionsTest {
@Override
protected void setGdbVersion() {
setGdbProgramNamesLaunchAttributes(ITestConstants.SUFFIX_GDB_6_6);
}
}

View file

@ -33,6 +33,7 @@ import org.junit.runners.Suite;
MIRunControlTest_6_6.class,
MIRunControlTargetAvailableTest_6_6.class,
MIExpressionsTest_6_6.class,
GDBPatternMatchingExpressionsTest_6_6.class,
MIMemoryTest_6_6.class,
MIBreakpointsTest_6_6.class,
MICatchpointsTest_6_6.class,

View file

@ -34,6 +34,7 @@ import org.junit.runners.Suite;
MIRunControlTest_6_6.class,
MIRunControlTargetAvailableTest_6_6.class,
MIExpressionsTest_6_6.class,
GDBPatternMatchingExpressionsTest_6_6.class,
MIMemoryTest_6_6.class,
MIBreakpointsTest_6_6.class,
MICatchpointsTest_6_6.class,

View file

@ -0,0 +1,24 @@
/*******************************************************************************
* Copyright (c) 2012 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc Khouzam (Ericsson) - Initial Implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.tests.tests_6_7;
import org.eclipse.cdt.tests.dsf.gdb.framework.BackgroundRunner;
import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants;
import org.eclipse.cdt.tests.dsf.gdb.tests.tests_6_6.GDBPatternMatchingExpressionsTest_6_6;
import org.junit.runner.RunWith;
@RunWith(BackgroundRunner.class)
public class GDBPatternMatchingExpressionsTest_6_7 extends GDBPatternMatchingExpressionsTest_6_6 {
@Override
protected void setGdbVersion() {
setGdbProgramNamesLaunchAttributes(ITestConstants.SUFFIX_GDB_6_7);
}
}

View file

@ -33,6 +33,7 @@ import org.junit.runners.Suite;
MIRunControlTest_6_7.class,
MIRunControlTargetAvailableTest_6_7.class,
MIExpressionsTest_6_7.class,
GDBPatternMatchingExpressionsTest_6_7.class,
MIMemoryTest_6_7.class,
MIBreakpointsTest_6_7.class,
MICatchpointsTest_6_7.class,

View file

@ -34,6 +34,7 @@ import org.junit.runners.Suite;
MIRunControlTest_6_7.class,
MIRunControlTargetAvailableTest_6_7.class,
MIExpressionsTest_6_7.class,
GDBPatternMatchingExpressionsTest_6_7.class,
MIMemoryTest_6_7.class,
MIBreakpointsTest_6_7.class,
MICatchpointsTest_6_7.class,

View file

@ -0,0 +1,24 @@
/*******************************************************************************
* Copyright (c) 2012 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc Khouzam (Ericsson) - Initial Implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.tests.tests_6_8;
import org.eclipse.cdt.tests.dsf.gdb.framework.BackgroundRunner;
import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants;
import org.eclipse.cdt.tests.dsf.gdb.tests.tests_6_7.GDBPatternMatchingExpressionsTest_6_7;
import org.junit.runner.RunWith;
@RunWith(BackgroundRunner.class)
public class GDBPatternMatchingExpressionsTest_6_8 extends GDBPatternMatchingExpressionsTest_6_7 {
@Override
protected void setGdbVersion() {
setGdbProgramNamesLaunchAttributes(ITestConstants.SUFFIX_GDB_6_8);
}
}

View file

@ -33,6 +33,7 @@ import org.junit.runners.Suite;
MIRunControlTest_6_8.class,
MIRunControlTargetAvailableTest_6_8.class,
MIExpressionsTest_6_8.class,
GDBPatternMatchingExpressionsTest_6_8.class,
MIMemoryTest_6_8.class,
MIBreakpointsTest_6_8.class,
MICatchpointsTest_6_8.class,

View file

@ -34,6 +34,7 @@ import org.junit.runners.Suite;
MIRunControlTest_6_8.class,
MIRunControlTargetAvailableTest_6_8.class,
MIExpressionsTest_6_8.class,
GDBPatternMatchingExpressionsTest_6_8.class,
MIMemoryTest_6_8.class,
MIBreakpointsTest_6_8.class,
MICatchpointsTest_6_8.class,

View file

@ -0,0 +1,24 @@
/*******************************************************************************
* Copyright (c) 2012 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc Khouzam (Ericsson) - Initial Implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_0;
import org.eclipse.cdt.tests.dsf.gdb.framework.BackgroundRunner;
import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants;
import org.eclipse.cdt.tests.dsf.gdb.tests.tests_6_8.GDBPatternMatchingExpressionsTest_6_8;
import org.junit.runner.RunWith;
@RunWith(BackgroundRunner.class)
public class GDBPatternMatchingExpressionsTest_7_0 extends GDBPatternMatchingExpressionsTest_6_8 {
@Override
protected void setGdbVersion() {
setGdbProgramNamesLaunchAttributes(ITestConstants.SUFFIX_GDB_7_0);
}
}

View file

@ -34,6 +34,7 @@ import org.junit.runners.Suite;
MIRunControlTargetAvailableTest_7_0.class,
MIRunControlNonStopTargetAvailableTest_7_0.class,
MIExpressionsTest_7_0.class,
GDBPatternMatchingExpressionsTest_7_0.class,
MIMemoryTest_7_0.class,
MIBreakpointsTest_7_0.class,
MICatchpointsTest_7_0.class,

View file

@ -36,6 +36,7 @@ import org.junit.runners.Suite;
MIRunControlNonStopTargetAvailableTest_7_0.class,
MIRunControlTest_7_0.class,
MIExpressionsTest_7_0.class,
GDBPatternMatchingExpressionsTest_7_0.class,
MIMemoryTest_7_0.class,
MIBreakpointsTest_7_0.class,
MICatchpointsTest_7_0.class,

View file

@ -0,0 +1,24 @@
/*******************************************************************************
* Copyright (c) 2012 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc Khouzam (Ericsson) - Initial Implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_1;
import org.eclipse.cdt.tests.dsf.gdb.framework.BackgroundRunner;
import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants;
import org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_0.GDBPatternMatchingExpressionsTest_7_0;
import org.junit.runner.RunWith;
@RunWith(BackgroundRunner.class)
public class GDBPatternMatchingExpressionsTest_7_1 extends GDBPatternMatchingExpressionsTest_7_0 {
@Override
protected void setGdbVersion() {
setGdbProgramNamesLaunchAttributes(ITestConstants.SUFFIX_GDB_7_1);
}
}

View file

@ -34,6 +34,7 @@ import org.junit.runners.Suite;
MIRunControlTargetAvailableTest_7_1.class,
MIRunControlNonStopTargetAvailableTest_7_1.class,
MIExpressionsTest_7_1.class,
GDBPatternMatchingExpressionsTest_7_1.class,
MIMemoryTest_7_1.class,
MIBreakpointsTest_7_1.class,
MICatchpointsTest_7_1.class,

View file

@ -36,6 +36,7 @@ import org.junit.runners.Suite;
MIRunControlNonStopTargetAvailableTest_7_1.class,
MIRunControlTest_7_1.class,
MIExpressionsTest_7_1.class,
GDBPatternMatchingExpressionsTest_7_1.class,
MIMemoryTest_7_1.class,
MIBreakpointsTest_7_1.class,
MICatchpointsTest_7_1.class,

View file

@ -0,0 +1,48 @@
/*******************************************************************************
* Copyright (c) 2012 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc Khouzam (Ericsson) - Initial Implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_2;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.cdt.tests.dsf.gdb.framework.BackgroundRunner;
import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants;
import org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_1.GDBPatternMatchingExpressionsTest_7_1;
import org.eclipse.core.runtime.Platform;
import org.junit.runner.RunWith;
@RunWith(BackgroundRunner.class)
public class GDBPatternMatchingExpressionsTest_7_2 extends GDBPatternMatchingExpressionsTest_7_1 {
@Override
protected void setGdbVersion() {
setGdbProgramNamesLaunchAttributes(ITestConstants.SUFFIX_GDB_7_2);
}
// GDB's list of registers is different with GDB 7.2
@Override
protected List<String> get_X86_REGS() {
// Because we are dealing with expressions for the registers, we must prefix them with '$'
List<String> list = new LinkedList<String>(Arrays.asList("$eax","$ecx","$edx","$ebx","$esp","$ebp","$esi","$edi","$eip","$eflags",
"$cs","$ss","$ds","$es","$fs","$gs","$st0","$st1","$st2","$st3",
"$st4","$st5","$st6","$st7","$fctrl","$fstat","$ftag","$fiseg","$fioff","$foseg",
"$fooff","$fop","$xmm0","$xmm1","$xmm2","$xmm3","$xmm4","$xmm5","$xmm6","$xmm7",
"$mxcsr",/*"","","","","","","","",*/"$orig_eax",
"$al","$cl","$dl","$bl","$ah","$ch","$dh","$bh","$ax","$cx",
"$dx","$bx",/*"",*/"$bp","$si","$di","$mm0","$mm1","$mm2","$mm3",
"$mm4","$mm5","$mm6","$mm7"));
// On Windows, gdb doesn't report "orig_eax" as a register. Apparently it does on Linux
if (Platform.getOS().equals(Platform.OS_WIN32)) {
list.remove("$orig_eax");
}
return list;
}
}

View file

@ -34,6 +34,7 @@ import org.junit.runners.Suite;
MIRunControlTargetAvailableTest_7_2.class,
MIRunControlNonStopTargetAvailableTest_7_2.class,
MIExpressionsTest_7_2.class,
GDBPatternMatchingExpressionsTest_7_2.class,
MIMemoryTest_7_2.class,
MIBreakpointsTest_7_2.class,
MICatchpointsTest_7_2.class,

View file

@ -36,6 +36,7 @@ import org.junit.runners.Suite;
MIRunControlTargetAvailableTest_7_2.class,
MIRunControlNonStopTargetAvailableTest_7_2.class,
MIExpressionsTest_7_2.class,
GDBPatternMatchingExpressionsTest_7_2.class,
MIMemoryTest_7_2.class,
MIBreakpointsTest_7_2.class,
MICatchpointsTest_7_2.class,

View file

@ -0,0 +1,24 @@
/*******************************************************************************
* Copyright (c) 2012 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc Khouzam (Ericsson) - Initial Implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_3;
import org.eclipse.cdt.tests.dsf.gdb.framework.BackgroundRunner;
import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants;
import org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_2.GDBPatternMatchingExpressionsTest_7_2;
import org.junit.runner.RunWith;
@RunWith(BackgroundRunner.class)
public class GDBPatternMatchingExpressionsTest_7_3 extends GDBPatternMatchingExpressionsTest_7_2 {
@Override
protected void setGdbVersion() {
setGdbProgramNamesLaunchAttributes(ITestConstants.SUFFIX_GDB_7_3);
}
}

View file

@ -34,6 +34,7 @@ import org.junit.runners.Suite;
MIRunControlTargetAvailableTest_7_3.class,
MIRunControlNonStopTargetAvailableTest_7_3.class,
MIExpressionsTest_7_3.class,
GDBPatternMatchingExpressionsTest_7_3.class,
MIMemoryTest_7_3.class,
MIBreakpointsTest_7_3.class,
MICatchpointsTest_7_3.class,

View file

@ -36,6 +36,7 @@ import org.junit.runners.Suite;
MIRunControlTargetAvailableTest_7_3.class,
MIRunControlNonStopTargetAvailableTest_7_3.class,
MIExpressionsTest_7_3.class,
GDBPatternMatchingExpressionsTest_7_3.class,
MIMemoryTest_7_3.class,
MIBreakpointsTest_7_3.class,
MICatchpointsTest_7_3.class,

View file

@ -0,0 +1,24 @@
/*******************************************************************************
* Copyright (c) 2012 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Marc Khouzam (Ericsson) - Initial Implementation
*******************************************************************************/
package org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_4;
import org.eclipse.cdt.tests.dsf.gdb.framework.BackgroundRunner;
import org.eclipse.cdt.tests.dsf.gdb.tests.ITestConstants;
import org.eclipse.cdt.tests.dsf.gdb.tests.tests_7_3.GDBPatternMatchingExpressionsTest_7_3;
import org.junit.runner.RunWith;
@RunWith(BackgroundRunner.class)
public class GDBPatternMatchingExpressionsTest_7_4 extends GDBPatternMatchingExpressionsTest_7_3 {
@Override
protected void setGdbVersion() {
setGdbProgramNamesLaunchAttributes(ITestConstants.SUFFIX_GDB_7_4);
}
}

View file

@ -34,6 +34,7 @@ import org.junit.runners.Suite;
MIRunControlTargetAvailableTest_7_4.class,
MIRunControlNonStopTargetAvailableTest_7_4.class,
MIExpressionsTest_7_4.class,
GDBPatternMatchingExpressionsTest_7_4.class,
MIMemoryTest_7_4.class,
MIBreakpointsTest_7_4.class,
MICatchpointsTest_7_4.class,

View file

@ -36,6 +36,7 @@ import org.junit.runners.Suite;
MIRunControlTargetAvailableTest_7_4.class,
MIRunControlNonStopTargetAvailableTest_7_4.class,
MIExpressionsTest_7_4.class,
GDBPatternMatchingExpressionsTest_7_4.class,
MIMemoryTest_7_4.class,
MIBreakpointsTest_7_4.class,
MICatchpointsTest_7_4.class,

Some files were not shown because too many files have changed in this diff Show more