From fad6fcfe015c5df5fb387ef69553ec1d591e7233 Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Thu, 31 May 2012 16:07:46 +0200 Subject: [PATCH] Bug 299911: Introduce ICPPEvaluation --- .../tests/IndexCPPTemplateResolutionTest.java | 9 +- .../eclipse/cdt/core/dom/ast/ASTTypeUtil.java | 20 +- .../eclipse/cdt/core/dom/ast/IEnumerator.java | 2 +- .../org/eclipse/cdt/core/dom/ast/IScope.java | 109 ++- .../cpp/ICPPASTArraySubscriptExpression.java | 12 + .../dom/ast/cpp/ICPPASTFieldReference.java | 6 + .../dom/ast/cpp/ICPPASTInitializerClause.java | 4 +- .../dom/ast/cpp/ICPPClassSpecialization.java | 10 +- .../core/dom/parser/ASTAmbiguousNode.java | 4 + .../cdt/internal/core/dom/parser/ASTNode.java | 4 - .../ASTTypeIdInitializerExpression.java | 2 +- ...Type.java => ISerializableEvaluation.java} | 15 +- .../core/dom/parser/ITypeMarshalBuffer.java | 43 +- .../core/dom/parser/ProblemBinding.java | 14 +- .../internal/core/dom/parser/ProblemType.java | 2 + .../cdt/internal/core/dom/parser/Value.java | 9 +- .../core/dom/parser/c/CASTIdExpression.java | 27 +- .../core/dom/parser/c/CArrayType.java | 2 +- .../core/dom/parser/c/CPointerType.java | 2 +- .../core/dom/parser/c/CQualifierType.java | 2 +- .../internal/core/dom/parser/c/CScope.java | 33 +- .../internal/core/dom/parser/c/CVisitor.java | 17 +- .../AbstractCPPClassSpecializationScope.java | 56 +- ...CPPASTAmbiguousBinaryVsCastExpression.java | 3 +- ...AmbiguousCastVsFunctionCallExpression.java | 4 +- .../parser/cpp/CPPASTAmbiguousExpression.java | 3 +- .../cpp/CPPASTArraySubscriptExpression.java | 124 +-- .../parser/cpp/CPPASTBinaryExpression.java | 193 +---- .../cpp/CPPASTBinaryTypeIdExpression.java | 40 +- .../dom/parser/cpp/CPPASTCastExpression.java | 56 +- .../CPPASTCompoundStatementExpression.java | 33 +- .../cpp/CPPASTConditionalExpression.java | 256 +----- .../parser/cpp/CPPASTDeleteExpression.java | 14 +- .../dom/parser/cpp/CPPASTExpressionList.java | 121 +-- .../dom/parser/cpp/CPPASTFieldReference.java | 238 ++--- .../cpp/CPPASTFunctionCallExpression.java | 224 ++--- .../dom/parser/cpp/CPPASTIdExpression.java | 179 +--- .../dom/parser/cpp/CPPASTInitializerList.java | 37 +- .../parser/cpp/CPPASTLambdaExpression.java | 25 +- .../parser/cpp/CPPASTLiteralExpression.java | 129 ++- .../dom/parser/cpp/CPPASTNewExpression.java | 26 +- .../cpp/CPPASTPackExpansionExpression.java | 34 +- .../parser/cpp/CPPASTProblemExpression.java | 24 +- .../cpp/CPPASTRangeBasedForStatement.java | 2 +- ...CPPASTSimpleTypeConstructorExpression.java | 51 +- .../parser/cpp/CPPASTTemplateIDAmbiguity.java | 7 +- .../dom/parser/cpp/CPPASTTranslationUnit.java | 5 +- .../parser/cpp/CPPASTTypeIdExpression.java | 63 +- .../CPPASTTypeIdInitializerExpression.java | 41 +- .../dom/parser/cpp/CPPASTUnaryExpression.java | 271 +++--- .../core/dom/parser/cpp/CPPArrayType.java | 2 +- .../core/dom/parser/cpp/CPPClassScope.java | 22 +- .../parser/cpp/CPPClassSpecialization.java | 32 +- ...tePartialSpecializationSpecialization.java | 22 +- .../cpp/CPPClassTemplateSpecialization.java | 4 +- .../core/dom/parser/cpp/CPPClosureType.java | 23 +- .../parser/cpp/CPPConstructorInstance.java | 6 +- .../cpp/CPPConstructorSpecialization.java | 6 +- .../CPPConstructorTemplateSpecialization.java | 6 +- .../parser/cpp/CPPFieldSpecialization.java | 27 +- .../core/dom/parser/cpp/CPPFunction.java | 2 + .../dom/parser/cpp/CPPFunctionInstance.java | 6 +- .../parser/cpp/CPPFunctionSpecialization.java | 58 +- .../CPPFunctionTemplateSpecialization.java | 6 +- .../dom/parser/cpp/CPPMethodInstance.java | 6 +- .../parser/cpp/CPPMethodSpecialization.java | 5 +- .../cpp/CPPMethodTemplateSpecialization.java | 6 +- .../dom/parser/cpp/CPPParameterPackType.java | 2 +- .../cpp/CPPParameterSpecialization.java | 8 +- .../parser/cpp/CPPPointerToMemberType.java | 2 +- .../core/dom/parser/cpp/CPPPointerType.java | 2 +- .../core/dom/parser/cpp/CPPQualifierType.java | 2 +- .../core/dom/parser/cpp/CPPReferenceType.java | 2 +- .../core/dom/parser/cpp/CPPScope.java | 62 +- .../core/dom/parser/cpp/CPPScopeMapper.java | 18 +- .../dom/parser/cpp/CPPSpecialization.java | 49 +- .../parser/cpp/CPPTypedefSpecialization.java | 70 +- .../dom/parser/cpp/CPPUnknownBinding.java | 2 - .../dom/parser/cpp/CPPUnknownFunction.java | 9 +- .../core/dom/parser/cpp/CPPUnknownScope.java | 154 +--- .../dom/parser/cpp/CPPUnknownTypeScope.java | 178 ++++ .../CPPUsingDeclarationSpecialization.java | 39 +- .../dom/parser/cpp/ICPPASTInternalScope.java | 11 - ...useEvaluation.java => ICPPEvaluation.java} | 13 +- .../dom/parser/cpp/OverloadableOperator.java | 8 +- .../parser/cpp/semantics/AccessContext.java | 6 +- .../parser/cpp/semantics/BaseClassLookup.java | 17 +- .../cpp/semantics/BuiltinOperators.java | 24 +- .../parser/cpp/semantics/CPPFunctionSet.java | 30 +- .../parser/cpp/semantics/CPPSemantics.java | 820 ++++++++---------- .../parser/cpp/semantics/CPPTemplates.java | 358 ++++---- .../dom/parser/cpp/semantics/CPPVisitor.java | 131 ++- .../dom/parser/cpp/semantics/Conversions.java | 106 ++- .../dom/parser/cpp/semantics/EvalBinary.java | 276 ++++++ .../cpp/semantics/EvalBinaryTypeId.java | 115 +++ .../dom/parser/cpp/semantics/EvalBinding.java | 189 ++++ .../dom/parser/cpp/semantics/EvalComma.java | 164 ++++ .../parser/cpp/semantics/EvalCompound.java | 85 ++ .../parser/cpp/semantics/EvalConditional.java | 311 +++++++ .../dom/parser/cpp/semantics/EvalFixed.java | 149 ++++ .../cpp/semantics/EvalFunctionCall.java | 168 ++++ .../parser/cpp/semantics/EvalFunctionSet.java | 128 +++ .../core/dom/parser/cpp/semantics/EvalID.java | 246 ++++++ .../parser/cpp/semantics/EvalInitList.java | 100 +++ .../cpp/semantics/EvalMemberAccess.java | 307 +++++++ .../dom/parser/cpp/semantics/EvalTypeId.java | 129 +++ .../dom/parser/cpp/semantics/EvalUnary.java | 222 +++++ .../parser/cpp/semantics/EvalUnaryTypeID.java | 152 ++++ .../parser/cpp/semantics/ExpressionTypes.java | 51 +- .../parser/cpp/semantics/FunctionCost.java | 20 +- .../parser/cpp/semantics/FunctionSetType.java | 27 +- .../cpp/semantics/InitializerListType.java | 53 +- .../dom/parser/cpp/semantics/LookupData.java | 389 ++++----- .../parser/cpp/semantics/SemanticUtil.java | 2 +- .../semantics/TemplateArgumentDeduction.java | 123 +-- .../semantics/TypeOfDependentExpression.java | 64 ++ .../core/index/composite/CompositeScope.java | 2 +- .../composite/c/CompositeCCompositeScope.java | 9 +- .../composite/c/CompositeCEnumerator.java | 3 +- .../composite/cpp/CPPCompositesFactory.java | 217 ++++- .../composite/cpp/CompositeCPPClassScope.java | 9 +- .../cpp/CompositeCPPClassSpecialization.java | 25 +- .../CompositeCPPClassSpecializationScope.java | 9 +- .../composite/cpp/CompositeCPPEnumScope.java | 9 +- .../composite/cpp/CompositeCPPEnumerator.java | 3 +- .../cpp/CompositeCPPNamespaceScope.java | 9 +- .../composite/cpp/TemplateInstanceUtil.java | 2 + .../core/pdom/db/TypeMarshalBuffer.java | 29 +- .../internal/core/pdom/dom/PDOMBinding.java | 10 +- .../internal/core/pdom/dom/PDOMLinkage.java | 2 + .../core/pdom/dom/c/PDOMCEnumerator.java | 3 +- .../core/pdom/dom/c/PDOMCLinkage.java | 13 +- .../core/pdom/dom/c/PDOMCStructure.java | 11 +- .../core/pdom/dom/cpp/PDOMCPPClassScope.java | 19 +- .../dom/cpp/PDOMCPPClassSpecialization.java | 26 +- .../PDOMCPPClassTemplateSpecialization.java | 4 +- .../core/pdom/dom/cpp/PDOMCPPEnumScope.java | 15 +- .../core/pdom/dom/cpp/PDOMCPPEnumerator.java | 3 +- .../core/pdom/dom/cpp/PDOMCPPLinkage.java | 72 +- .../core/pdom/dom/cpp/PDOMCPPNamespace.java | 20 +- .../dom/cpp/PDOMCPPTypedefSpecialization.java | 22 +- .../pdom/dom/cpp/PDOMCPPUnknownClassType.java | 7 +- .../pdom/dom/cpp/PDOMCPPUnknownScope.java | 2 +- .../refactoring/RefactoringTestBase.java | 5 +- .../ui/typehierarchy/TypeHierarchyUI.java | 23 +- .../cdt/internal/ui/viewsupport/IndexUI.java | 3 +- .../dom/lrparser/c99/bindings/C99Scope.java | 8 + 147 files changed, 5751 insertions(+), 3282 deletions(-) rename core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/{cpp/CPPUnknownFunctionType.java => ISerializableEvaluation.java} (55%) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownTypeScope.java rename core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/{ICPPInitClauseEvaluation.java => ICPPEvaluation.java} (72%) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinaryTypeId.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalComma.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalCompound.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConditional.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFixed.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalInitList.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalMemberAccess.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeOfDependentExpression.java diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java index 8cca0127195..d49b31b5520 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java @@ -17,6 +17,7 @@ import junit.framework.TestSuite; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.IASTExpression; +import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IBinding; @@ -1544,19 +1545,19 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa // CT v1; public void testUniqueInstance_Bug241641() throws Exception { + IASTName name= findName("v1", 2); ICPPVariable v1= getBindingFromASTName("v1", 2, ICPPVariable.class); - ICPPVariable v2= getBindingFromASTName("v1", 2, ICPPVariable.class); IType t1= v1.getType(); assertInstance(t1, ICPPTemplateInstance.class); ICPPTemplateInstance inst= (ICPPTemplateInstance) t1; final ICPPClassTemplate tmplDef = (ICPPClassTemplate) inst.getTemplateDefinition(); - IBinding inst2= CPPTemplates.instantiate(tmplDef, inst.getTemplateArguments()); + IBinding inst2= CPPTemplates.instantiate(tmplDef, inst.getTemplateArguments(), name); assertSame(inst, inst2); - IBinding charInst1= CPPTemplates.instantiate(tmplDef, new ICPPTemplateArgument[] {new CPPTemplateArgument(new CPPBasicType(Kind.eChar, 0))}); - IBinding charInst2= CPPTemplates.instantiate(tmplDef, new ICPPTemplateArgument[] {new CPPTemplateArgument(new CPPBasicType(Kind.eChar, 0))}); + IBinding charInst1= CPPTemplates.instantiate(tmplDef, new ICPPTemplateArgument[] {new CPPTemplateArgument(new CPPBasicType(Kind.eChar, 0))}, name); + IBinding charInst2= CPPTemplates.instantiate(tmplDef, new ICPPTemplateArgument[] {new CPPTemplateArgument(new CPPBasicType(Kind.eChar, 0))}, name); assertSame(charInst1, charInst2); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java index ac2826999fd..325295bd82d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/ASTTypeUtil.java @@ -610,18 +610,14 @@ public class ASTTypeUtil { IBinding binding = declarator.getName().resolveBinding(); IType type = null; - try { - if (binding instanceof IEnumerator) { - type = ((IEnumerator) binding).getType(); - } else if (binding instanceof IFunction) { - type = ((IFunction) binding).getType(); - } else if (binding instanceof ITypedef) { - type = ((ITypedef) binding).getType(); - } else if (binding instanceof IVariable) { - type = ((IVariable) binding).getType(); - } - } catch (DOMException e) { - return EMPTY_STRING; + if (binding instanceof IEnumerator) { + type = ((IEnumerator)binding).getType(); + } else if (binding instanceof IFunction) { + type = ((IFunction)binding).getType(); + } else if (binding instanceof ITypedef) { + type = ((ITypedef)binding).getType(); + } else if (binding instanceof IVariable) { + type = ((IVariable)binding).getType(); } if (type != null) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IEnumerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IEnumerator.java index 3f4e9bc23ac..813d1146366 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IEnumerator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IEnumerator.java @@ -23,7 +23,7 @@ public interface IEnumerator extends IBinding { * * @return the type of the enumeration */ - public IType getType() throws DOMException; + public IType getType(); /** * Returns the value assigned to this enumerator. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IScope.java index 7ec52b91efc..c935319df4d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IScope.java @@ -13,6 +13,7 @@ package org.eclipse.cdt.core.dom.ast; import org.eclipse.cdt.core.dom.IName; +import org.eclipse.cdt.core.index.IIndex; import org.eclipse.cdt.core.index.IIndexFileSet; /** @@ -87,34 +88,106 @@ public interface IScope { public IBinding getBinding(IASTName name, boolean resolve, IIndexFileSet acceptLocalBindings); /** - * Get the bindings in this scope that the given name or prefix could resolve to. Could - * return null if there is no matching bindings in this scope, if the bindings have not - * yet been cached in this scope, or if resolve == false and the appropriate bindings - * have not yet been resolved. - * - * @param name - * @param resolve : - * whether or not to resolve the matching bindings if they have not - * been so already. - * @param prefixLookup whether the lookup is for a full name or a prefix - * @return : the bindings in this scope that match the name or prefix, or null + * @deprecated Use {@link #getBindings(ScopeLookupData)} instead */ + @Deprecated public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup); + /** + * @deprecated Use {@link #getBindings(ScopeLookupData)} instead + */ + @Deprecated + public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet acceptLocalBindings); + + + /** + * @since 5.4 + * @noextend This class is not intended to be subclassed by clients. + */ + public static class ScopeLookupData { + private char[] fLookupKey; + private final IASTNode fLookupPoint; + private final IASTTranslationUnit fTu; + private final boolean fLookupPointIsName; + private boolean fResolve= true; + private boolean fPrefixLookup= false; + private boolean fIgnorePointOfDeclaration= false; + + public ScopeLookupData(IASTName name, boolean resolve, boolean prefixLookup) { + if (name == null) + throw new IllegalArgumentException(); + fLookupPoint = name; + fLookupPointIsName= true; + fLookupKey= name.getLookupKey(); + fResolve = resolve; + fPrefixLookup = prefixLookup; + fTu= name.getTranslationUnit(); + } + + public ScopeLookupData(char[] name, IASTNode point) { + // To support IScope.find(...) the lookup point may be null. + fLookupPoint= point; + fLookupPointIsName= false; + fLookupKey= name; + fIgnorePointOfDeclaration= true; + if (fLookupPoint == null) { + fTu= null; + fIgnorePointOfDeclaration= true; + } else { + fTu= fLookupPoint.getTranslationUnit(); + } + } + + public void setPrefixLookup(boolean prefixLookup) { + fPrefixLookup = prefixLookup; + } + public void setResolve(boolean resolve) { + fResolve = resolve; + } + public void setIgnorePointOfDeclaration(boolean ignorePointOfDeclaration) { + fIgnorePointOfDeclaration = ignorePointOfDeclaration; + } + public void setLookupKey(char[] key) { + fLookupKey= key; + } + public char[] getLookupKey() { + return fLookupKey; + } + public IASTNode getLookupPoint() { + return fLookupPoint; + } + public boolean isResolve() { + return fResolve; + } + public boolean isPrefixLookup() { + return fPrefixLookup; + } + public boolean isIgnorePointOfDeclaration() { + return fIgnorePointOfDeclaration; + } + public IIndexFileSet getIncludedFiles() { + return fTu == null ? IIndexFileSet.EMPTY : fTu.getIndexFileSet(); + } + public IIndex getIndex() { + return fTu == null ? null : fTu.getIndex(); + } + public IASTName getLookupName() { + return fLookupPointIsName ? (IASTName) fLookupPoint : null; + } + public IASTTranslationUnit getTranslationUnit() { + return fTu; + } + } + /** * Get the bindings in this scope that the given name or prefix could resolve to. Could * return null if there is no matching bindings in this scope, if the bindings have not * yet been cached in this scope, or if resolve == false and the appropriate bindings * have not yet been resolved. * - * @param name - * @param resolve : - * whether or not to resolve the matching bindings if they have not - * been so already. - * @param prefixLookup whether the lookup is for a full name or a prefix - * @param acceptLocalBindings a set of files for which to accept local bindings. * @return : the bindings in this scope that match the name or prefix, or null + * @since 5.4 */ - public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet acceptLocalBindings); + public IBinding[] getBindings(ScopeLookupData lookup); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTArraySubscriptExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTArraySubscriptExpression.java index 2848da489d6..ca43396ec3d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTArraySubscriptExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTArraySubscriptExpression.java @@ -29,4 +29,16 @@ public interface ICPPASTArraySubscriptExpression extends IASTArraySubscriptExpre */ @Override public ICPPASTArraySubscriptExpression copy(CopyStyle style); + + /** + * @since 5.4 + */ + @Override + public ICPPASTExpression getArrayExpression(); + + /** + * @since 5.4 + */ + @Override + public ICPPASTInitializerClause getArgument(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTFieldReference.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTFieldReference.java index 3177ce71b3a..2697932bbe0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTFieldReference.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTFieldReference.java @@ -52,4 +52,10 @@ public interface ICPPASTFieldReference extends IASTFieldReference, ICPPASTExpres * @since 5.4 */ public IType getFieldOwnerType(); + + /** + * @since 5.4 + */ + @Override + public ICPPASTExpression getFieldOwner(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTInitializerClause.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTInitializerClause.java index 12c8ad7b733..80b48a34b53 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTInitializerClause.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTInitializerClause.java @@ -12,7 +12,7 @@ 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.ICPPInitClauseEvaluation; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; /** * C++ specific initializer clause @@ -26,5 +26,5 @@ public interface ICPPASTInitializerClause extends IASTInitializerClause { * Returns the evaluation object for this expression. * @noreference This method is not intended to be referenced by clients. */ - ICPPInitClauseEvaluation getEvaluation(); + ICPPEvaluation getEvaluation(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassSpecialization.java index 597770da991..2fd3cdd2fa8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPClassSpecialization.java @@ -10,6 +10,7 @@ *******************************************************************************/ package org.eclipse.cdt.core.dom.ast.cpp; +import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; /** @@ -24,9 +25,16 @@ public interface ICPPClassSpecialization extends ICPPSpecialization, ICPPClassTy @Override ICPPClassType getSpecializedBinding(); + /** + * @deprecated Specializing a member may require a point of instantiation. + */ + @Deprecated + IBinding specializeMember(IBinding binding); + /** * Creates a specialized binding for a member of the original class. The result is * a member of this class specialization. + * @since 5.4 */ - IBinding specializeMember(IBinding binding); + IBinding specializeMember(IBinding binding, IASTNode point); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTAmbiguousNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTAmbiguousNode.java index 817d4a7d0f1..0a234b35410 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTAmbiguousNode.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTAmbiguousNode.java @@ -21,6 +21,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.parser.util.ArrayUtil; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; /** * Base implementation for all ambiguous nodes. @@ -163,4 +164,7 @@ public abstract class ASTAmbiguousNode extends ASTNode { public final boolean isLValue() { throw new UnsupportedOperationException(); } + public final ICPPEvaluation getEvaluation() { + throw new UnsupportedOperationException(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java index f8e0f8a54a9..ae1b8a78c5e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTNode.java @@ -20,11 +20,9 @@ import org.eclipse.cdt.core.dom.ast.IASTImageLocation; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.parser.IToken; import org.eclipse.cdt.core.parser.OffsetLimitReachedException; import org.eclipse.cdt.core.parser.util.CharArrayUtils; -import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction; import org.eclipse.cdt.internal.core.parser.scanner.ILexerLog; import org.eclipse.cdt.internal.core.parser.scanner.ILocationResolver; import org.eclipse.cdt.internal.core.parser.scanner.Lexer; @@ -35,8 +33,6 @@ import org.eclipse.cdt.internal.core.parser.scanner.Token; * Base class for all non-preprocessor nodes in the AST. */ public abstract class ASTNode implements IASTNode { - protected static final ICPPFunction UNINITIALIZED_FUNCTION = new CPPFunction(null); - private IASTNode parent; private ASTNodeProperty property; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTypeIdInitializerExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTypeIdInitializerExpression.java index 34383d64d22..87d64e1673e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTypeIdInitializerExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ASTTypeIdInitializerExpression.java @@ -100,7 +100,7 @@ public abstract class ASTTypeIdInitializerExpression extends ASTNode implements } @Override - public final ValueCategory getValueCategory() { + public ValueCategory getValueCategory() { return ValueCategory.PRVALUE; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownFunctionType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ISerializableEvaluation.java similarity index 55% rename from core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownFunctionType.java rename to core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ISerializableEvaluation.java index 3e437589fcd..9f3f00f1245 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownFunctionType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ISerializableEvaluation.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008 Wind River Systems, Inc. and others. + * Copyright (c) 2009 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 @@ -8,15 +8,14 @@ * Contributors: * Markus Schorn - initial API and implementation *******************************************************************************/ -package org.eclipse.cdt.internal.core.dom.parser.cpp; +package org.eclipse.cdt.internal.core.dom.parser; + +import org.eclipse.core.runtime.CoreException; -import org.eclipse.cdt.core.dom.ast.IType; /** - * Models the type of an unknown function. + * Interface for marshalling types for storage in the index. */ -public class CPPUnknownFunctionType extends CPPFunctionType implements ICPPUnknownType { - CPPUnknownFunctionType() { - super(CPPUnknownClass.createUnnamedInstance(), IType.EMPTY_TYPE_ARRAY); - } +public interface ISerializableEvaluation { + void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ITypeMarshalBuffer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ITypeMarshalBuffer.java index 8fd181d8a07..b4ead75e4c5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ITypeMarshalBuffer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ITypeMarshalBuffer.java @@ -19,17 +19,36 @@ import org.eclipse.core.runtime.CoreException; * Buffer for marshalling and unmarshalling types. */ public interface ITypeMarshalBuffer { - final static byte BASIC_TYPE= 1; - final static byte POINTER= 2; - final static byte ARRAY= 3; - final static byte CVQUALIFIER= 4; - final static byte FUNCTION_TYPE= 5; - final static byte REFERENCE= 6; - final static byte POINTER_TO_MEMBER= 7; - final static byte PACK_EXPANSION= 8; - final static byte PROBLEM_TYPE= 9; - final static byte VALUE= 10; - static final byte KIND_MASK = 0xf; + final static byte BASIC_TYPE= 1; + final static byte POINTER_TYPE= 2; + final static byte ARRAY_TYPE= 3; + final static byte CVQUALIFIER_TYPE= 4; + final static byte FUNCTION_TYPE= 5; + final static byte REFERENCE_TYPE= 6; + final static byte POINTER_TO_MEMBER_TYPE= 7; + final static byte PACK_EXPANSION_TYPE= 8; + 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, + EVAL_BINDING = 3, + EVAL_COMMA = 4, + EVAL_COMPOUND = 5, + EVAL_CONDITIONAL = 6, + EVAL_FIXED= 7, + EVAL_FUNCTION_CALL= 8, + EVAL_FUNCTION_SET= 9, + EVAL_ID= 10, + EVAL_INIT_LIST= 11, + EVAL_MEMBER_ACCESS= 12, + 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; @@ -41,6 +60,7 @@ public interface ITypeMarshalBuffer { IType unmarshalType() throws CoreException; IValue unmarshalValue() throws CoreException; IBinding unmarshalBinding() throws CoreException; + ISerializableEvaluation unmarshalEvaluation() throws CoreException; int getByte() throws CoreException; int getShort() throws CoreException; long getLong() throws CoreException; @@ -49,6 +69,7 @@ public interface ITypeMarshalBuffer { void marshalType(IType type) throws CoreException; void marshalValue(IValue value) throws CoreException; void marshalBinding(IBinding binding) throws CoreException; + void marshalEvaluation(ISerializableEvaluation eval, boolean includeValue) throws CoreException; void putByte(byte data); void putShort(short data); void putLong(long data); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java index b63128ee0a4..de2eeb7360c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java @@ -209,10 +209,22 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I } /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IScope#getBinding(org.eclipse.cdt.core.dom.ast.IASTName, boolean) + */ + /** + * @deprecated Use {@link #getBindings(ScopeLookupData)} instead + */ + @Deprecated + @Override + public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) { + return getBindings(new ScopeLookupData(name, resolve, prefixLookup)); + } + + /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IScope#getBinding(org.eclipse.cdt.core.dom.ast.IASTName, boolean) */ @Override - public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) { + public IBinding[] getBindings(ScopeLookupData lookup) { return IBinding.EMPTY_BINDING_ARRAY; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemType.java index b125d1f5ae1..92d6ac9ee0b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemType.java @@ -11,6 +11,7 @@ package org.eclipse.cdt.internal.core.dom.parser; import org.eclipse.cdt.core.dom.ast.IProblemType; +import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.internal.core.parser.ParserMessages; import org.eclipse.core.runtime.CoreException; @@ -20,6 +21,7 @@ import org.eclipse.core.runtime.CoreException; */ public class ProblemType implements IProblemType, ISerializableType { public static final IType UNRESOLVED_NAME = new ProblemType(TYPE_UNRESOLVED_NAME); + public static final IType UNKNOWN_FOR_EXPRESSION = new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); private final int fID; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java index 778aab8001b..76c8d107687 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/Value.java @@ -24,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression; +import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression; import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.IBinding; @@ -36,6 +37,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator.SizeAndAlignment; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator; import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator.EvalException; @@ -75,7 +77,7 @@ public class Value implements IValue { private static class Reevaluation { public final char[] fExpression; - private int fPackOffset; + private final int fPackOffset; public int pos=0; public final Map fUnknownSigs; public final List fUnknowns; @@ -989,4 +991,9 @@ public class Value implements IValue { buf.getChars(0, len, result, 0); return result; } + + public static IValue create(ICPPEvaluation eval, IASTNode point) { + // compute value of evaluation + return Value.UNKNOWN; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTIdExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTIdExpression.java index ebe4394c304..d68e1afc32b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTIdExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTIdExpression.java @@ -14,7 +14,6 @@ package org.eclipse.cdt.internal.core.dom.parser.c; import org.eclipse.cdt.core.dom.ast.ASTVisitor; -import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTCompletionContext; import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTName; @@ -105,21 +104,17 @@ public class CASTIdExpression extends ASTNode implements IASTIdExpression, IASTC @Override public IType getExpressionType() { IBinding binding = getName().resolveBinding(); - try { - if (binding instanceof IVariable) { - return ((IVariable)binding).getType(); - } - if (binding instanceof IFunction) { - return ((IFunction)binding).getType(); - } - if (binding instanceof IEnumerator) { - return ((IEnumerator)binding).getType(); - } - if (binding instanceof IProblemBinding) { - return new ProblemType(ISemanticProblem.TYPE_UNRESOLVED_NAME); - } - } catch (DOMException e) { - return e.getProblem(); + if (binding instanceof IVariable) { + return ((IVariable)binding).getType(); + } + if (binding instanceof IFunction) { + return ((IFunction)binding).getType(); + } + if (binding instanceof IEnumerator) { + return ((IEnumerator)binding).getType(); + } + if (binding instanceof IProblemBinding) { + return new ProblemType(ISemanticProblem.TYPE_UNRESOLVED_NAME); } return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CArrayType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CArrayType.java index 45206d6f036..a90f9f3395a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CArrayType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CArrayType.java @@ -160,7 +160,7 @@ public class CArrayType implements ICArrayType, ITypeContainer, ISerializableTyp @Override public void marshal(ITypeMarshalBuffer buffer) throws CoreException { - int firstByte= ITypeMarshalBuffer.ARRAY; + int firstByte= ITypeMarshalBuffer.ARRAY_TYPE; int flags= 0; short nval= -1; IValue val= null; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CPointerType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CPointerType.java index a1be0021568..61b76051203 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CPointerType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CPointerType.java @@ -94,7 +94,7 @@ public class CPointerType implements ICPointerType, ITypeContainer, ISerializabl @Override public void marshal(ITypeMarshalBuffer buffer) throws CoreException { - int firstByte= ITypeMarshalBuffer.POINTER; + int firstByte= ITypeMarshalBuffer.POINTER_TYPE; if (isConst()) firstByte |= ITypeMarshalBuffer.FLAG1; if (isVolatile()) firstByte |= ITypeMarshalBuffer.FLAG2; if (isRestrict()) firstByte |= ITypeMarshalBuffer.FLAG3; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CQualifierType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CQualifierType.java index 1dae663aef2..23ff677f145 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CQualifierType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CQualifierType.java @@ -144,7 +144,7 @@ public class CQualifierType implements ICQualifierType, ITypeContainer, ISeriali @Override public void marshal(ITypeMarshalBuffer buffer) throws CoreException { - int firstByte= ITypeMarshalBuffer.CVQUALIFIER; + int firstByte= ITypeMarshalBuffer.CVQUALIFIER_TYPE; if (isConst()) firstByte |= ITypeMarshalBuffer.FLAG1; if (isVolatile()) firstByte |= ITypeMarshalBuffer.FLAG2; if (isRestrict()) firstByte |= ITypeMarshalBuffer.FLAG3; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CScope.java index 04141c59240..53fe925b25f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CScope.java @@ -247,7 +247,7 @@ public class CScope implements ICScope, IASTInternalScope { @Override public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefix) { - return getBindings(name, resolve, prefix, IIndexFileSet.EMPTY); + return getBindings(new ScopeLookupData(name, resolve, prefix)); } @Override @@ -330,16 +330,28 @@ public class CScope implements ICScope, IASTInternalScope { } /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.c.ICScope#getBinding(org.eclipse.cdt.core.dom.ast.IASTName, boolean) + */ + /** + * @deprecated Use {@link #getBindings(ScopeLookupData)} instead + */ + @Deprecated + @Override + public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) { + return getBindings(new ScopeLookupData(name, resolve, prefixLookup)); + } + + /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.c.ICScope#getBinding(org.eclipse.cdt.core.dom.ast.IASTName, boolean) */ @Override - public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) { - char[] c = name.toCharArray(); + public final IBinding[] getBindings(ScopeLookupData lookup) { + char[] c = lookup.getLookupKey(); Object[] obj = null; populateCache(); for (CharArrayObjectMap map : mapsToNameOrBinding) { - if (prefixLookup) { + if (lookup.isPrefixLookup()) { IContentAssistMatcher matcher = ContentAssistMatcherFactory.getInstance().createMatcher(c); Object[] keys = map.keyArray(); for (Object key2 : keys) { @@ -358,11 +370,12 @@ public class CScope implements ICScope, IASTInternalScope { IIndex index = tu.getIndex(); if (index != null) { try { - IBinding[] bindings = prefixLookup ? - index.findBindingsForContentAssist(name.toCharArray(), true, INDEX_FILTERS[NAMESPACE_TYPE_BOTH], null) : - index.findBindings(name.toCharArray(), INDEX_FILTERS[NAMESPACE_TYPE_BOTH], null); - if (fileSet != null) { - bindings = fileSet.filterFileLocalBindings(bindings); + IBinding[] bindings = lookup.isPrefixLookup() ? + index.findBindingsForContentAssist(lookup.getLookupKey(), true, INDEX_FILTERS[NAMESPACE_TYPE_BOTH], null) : + index.findBindings(lookup.getLookupKey(), INDEX_FILTERS[NAMESPACE_TYPE_BOTH], null); + IIndexFileSet filter = lookup.getIncludedFiles(); + if (filter != null) { + bindings = filter.filterFileLocalBindings(bindings); } obj = ArrayUtil.addAll(Object.class, obj, bindings); @@ -387,7 +400,7 @@ public class CScope implements ICScope, IASTInternalScope { if (n != null) { IBinding b = n.getBinding(); if (b == null) { - if (resolve && n != name) { + if (lookup.isResolve() && n != lookup.getLookupPoint()) { b = n.resolveBinding(); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java index e0ed54d939b..d1f5cf77ea8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java @@ -70,6 +70,7 @@ import org.eclipse.cdt.core.dom.ast.ILabel; import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.IScope.ScopeLookupData; import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; @@ -356,7 +357,7 @@ public class CVisitor extends ASTQueries { public static class CollectReferencesAction extends ASTVisitor { private static final int DEFAULT_LIST_SIZE = 8; private IASTName[] refs; - private IBinding binding; + private final IBinding binding; private int idx = 0; private int kind; @@ -1065,23 +1066,11 @@ public class CVisitor extends ASTQueries { if (scope == null) return null; - IIndexFileSet fileSet= IIndexFileSet.EMPTY; - IASTTranslationUnit tu= name.getTranslationUnit(); - if (tu == null && scope instanceof IASTInternalScope) { - tu= ((IASTInternalScope) scope).getPhysicalNode().getTranslationUnit(); - } - if (tu != null) { - final IIndexFileSet fs= (IIndexFileSet) tu.getAdapter(IIndexFileSet.class); - if (fs != null) { - fileSet= fs; - } - } - IBinding[] result = null; CharArraySet handled= new CharArraySet(1); while (scope != null) { if (!(scope instanceof ICCompositeTypeScope)) { - IBinding[] bindings= scope.getBindings(name, true, true, fileSet); + IBinding[] bindings= scope.getBindings(new ScopeLookupData(name, true, true)); for (IBinding b : bindings) { final char[] n= b.getNameCharArray(); // consider binding only if no binding with the same name was found in another scope. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/AbstractCPPClassSpecializationScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/AbstractCPPClassSpecializationScope.java index d2ce9696302..62ff6bc9ca8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/AbstractCPPClassSpecializationScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/AbstractCPPClassSpecializationScope.java @@ -17,6 +17,7 @@ import org.eclipse.cdt.core.dom.IName; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.EScopeKind; import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IScope; @@ -63,11 +64,11 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat @Override public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefix) { - return getBindings(name, resolve, prefix, IIndexFileSet.EMPTY); + return getBindings(new ScopeLookupData(name, resolve, prefix)); } @Override - public IBinding getBinding(IASTName name, boolean forceResolve, IIndexFileSet fileSet) { + public IBinding getBinding(IASTName name, boolean resolve, IIndexFileSet fileSet) { char[] c = name.getLookupKey(); if (CharArrayUtils.equals(c, specialClass.getNameCharArray()) @@ -77,44 +78,39 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat ICPPClassType specialized = specialClass.getSpecializedBinding(); IScope classScope = specialized.getCompositeScope(); - IBinding[] bindings = classScope != null ? classScope.getBindings(name, forceResolve, false) : null; + IBinding[] bindings = classScope != null ? classScope.getBindings(new ScopeLookupData(name, resolve, false)) : null; if (bindings == null) return null; IBinding[] specs = new IBinding[0]; for (IBinding binding : bindings) { - specs = ArrayUtil.append(IBinding.class, specs, specialClass.specializeMember(binding)); + specs = ArrayUtil.append(IBinding.class, specs, specialClass.specializeMember(binding, name)); } specs = ArrayUtil.trim(IBinding.class, specs); return CPPSemantics.resolveAmbiguities(name, specs); } - @Override - final public IBinding[] getBindings(IASTName name, boolean forceResolve, boolean prefixLookup, + @Deprecated @Override + final public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) { - return getBindings(name, forceResolve, prefixLookup, fileSet, true); + return getBindings(new ScopeLookupData(name, resolve, prefixLookup)); } - public IBinding[] getBindings(IASTName name, boolean forceResolve, boolean prefixLookup, - IIndexFileSet fileSet, boolean checkPointOfDecl) { + @Override + final public IBinding[] getBindings(ScopeLookupData lookup) { ICPPClassType specialized = specialClass.getSpecializedBinding(); IScope classScope = specialized.getCompositeScope(); if (classScope == null) return IBinding.EMPTY_BINDING_ARRAY; - IBinding[] bindings; - if (classScope instanceof ICPPASTInternalScope) { - bindings= ((ICPPASTInternalScope) classScope).getBindings(name, forceResolve, prefixLookup, fileSet, checkPointOfDecl); - } else { - bindings= classScope.getBindings(name, forceResolve, prefixLookup, fileSet); - } + IBinding[] bindings= classScope.getBindings(lookup); IBinding[] result= null; for (IBinding binding : bindings) { if (binding == specialized) { binding= specialClass; } else { - binding= specialClass.specializeMember(binding); + binding= specialClass.specializeMember(binding, lookup.getLookupPoint()); } result = ArrayUtil.append(IBinding.class, result, binding); } @@ -134,11 +130,12 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat if (bases.length == 0) { fBases= bases; } else { + IASTNode point= null; // Instantiation of dependent expression may not work. final ICPPTemplateParameterMap tpmap = specialClass.getTemplateParameterMap(); for (ICPPBase base : bases) { IBinding origClass = base.getBaseClass(); if (origClass instanceof ICPPTemplateParameter && ((ICPPTemplateParameter) origClass).isParameterPack()) { - IType[] specClasses= CPPTemplates.instantiateTypes(new IType[]{new CPPParameterPackType((IType) origClass)}, tpmap, -1, specialClass); + IType[] specClasses= CPPTemplates.instantiateTypes(new IType[]{new CPPParameterPackType((IType) origClass)}, tpmap, -1, specialClass, point); if (specClasses.length == 1 && specClasses[0] instanceof ICPPParameterPackType) { result= ArrayUtil.append(ICPPBase.class, result, base); } else { @@ -155,7 +152,7 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat } if (origClass instanceof IType) { ICPPBase specBase = base.clone(); - IType specClass= CPPTemplates.instantiateType((IType) origClass, tpmap, -1, specialClass); + IType specClass= CPPTemplates.instantiateType((IType) origClass, tpmap, -1, specialClass, point); specClass = SemanticUtil.getUltimateType(specClass, false); if (specClass instanceof IBinding && !(specClass instanceof IProblemBinding)) { specBase.setBaseClass((IBinding) specClass); @@ -172,31 +169,33 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat } @SuppressWarnings("unchecked") - private T[] specializeMembers(T[] array) { + private T[] specializeMembers(T[] array, IASTNode point) { if (array == null || array.length == 0) return array; T[] newArray= array.clone(); for (int i = 0; i < newArray.length; i++) { - newArray[i]= (T) specialClass.specializeMember(array[i]); + newArray[i]= (T) specialClass.specializeMember(array[i], point); } return newArray; } @Override public ICPPField[] getDeclaredFields() { + IASTNode point= null; // Instantiation of dependent expression may not work. ICPPField[] fields= specialClass.getSpecializedBinding().getDeclaredFields(); - return specializeMembers(fields); + return specializeMembers(fields, point); } @Override public ICPPMethod[] getImplicitMethods() { + IASTNode point= null; // Instantiation of dependent expression may not work. ICPPClassScope origClassScope= (ICPPClassScope) specialClass.getSpecializedBinding().getCompositeScope(); if (origClassScope == null) { return ICPPMethod.EMPTY_CPPMETHOD_ARRAY; } ICPPMethod[] methods= origClassScope.getImplicitMethods(); - return specializeMembers(methods); + return specializeMembers(methods, point); } @Override @@ -208,26 +207,31 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat @Override public ICPPConstructor[] getConstructors() { + // mstodo need to pass the point of instantiation + IASTNode point= null; // Instantiation of dependent expression may not work. ICPPConstructor[] ctors= specialClass.getSpecializedBinding().getConstructors(); - return specializeMembers(ctors); + return specializeMembers(ctors, point); } @Override public ICPPMethod[] getDeclaredMethods() { + IASTNode point= null; // Instantiation of dependent expression may not work. ICPPMethod[] bindings = specialClass.getSpecializedBinding().getDeclaredMethods(); - return specializeMembers(bindings); + return specializeMembers(bindings, point); } @Override public ICPPClassType[] getNestedClasses() { + IASTNode point= null; // Instantiation of dependent expression may not work. ICPPClassType[] bindings = specialClass.getSpecializedBinding().getNestedClasses(); - return specializeMembers(bindings); + return specializeMembers(bindings, point); } @Override public IBinding[] getFriends() { + IASTNode point= null; // Instantiation of dependent expression may not work. IBinding[] friends = specialClass.getSpecializedBinding().getFriends(); - return specializeMembers(friends); + return specializeMembers(friends, point); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousBinaryVsCastExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousBinaryVsCastExpression.java index 3f362edc1b4..33e3534b2b3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousBinaryVsCastExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousBinaryVsCastExpression.java @@ -12,9 +12,10 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; import org.eclipse.cdt.core.dom.ast.IASTCastExpression; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousBinaryVsCastExpression; -public class CPPASTAmbiguousBinaryVsCastExpression extends ASTAmbiguousBinaryVsCastExpression { +public class CPPASTAmbiguousBinaryVsCastExpression extends ASTAmbiguousBinaryVsCastExpression implements ICPPASTExpression { public CPPASTAmbiguousBinaryVsCastExpression(IASTBinaryExpression bexp, IASTCastExpression castExpr) { super(bexp, castExpr); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousCastVsFunctionCallExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousCastVsFunctionCallExpression.java index 4645686d4f2..4c08dbe087d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousCastVsFunctionCallExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousCastVsFunctionCallExpression.java @@ -12,9 +12,11 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.IASTCastExpression; import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousCastVsFunctionCallExpression; -public class CPPASTAmbiguousCastVsFunctionCallExpression extends ASTAmbiguousCastVsFunctionCallExpression { +public class CPPASTAmbiguousCastVsFunctionCallExpression extends + ASTAmbiguousCastVsFunctionCallExpression implements ICPPASTExpression { public CPPASTAmbiguousCastVsFunctionCallExpression(IASTCastExpression castExpr, IASTFunctionCallExpression funcCall) { super(castExpr, funcCall); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousExpression.java index 22b6a6175f3..c45715f43aa 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTAmbiguousExpression.java @@ -13,12 +13,13 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousExpression; public class CPPASTAmbiguousExpression extends ASTAmbiguousNode implements - IASTAmbiguousExpression { + IASTAmbiguousExpression, ICPPASTExpression { private IASTExpression [] exp = new IASTExpression[2]; private int expPos=-1; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArraySubscriptExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArraySubscriptExpression.java index 913ca3902f3..111aee3c912 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArraySubscriptExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTArraySubscriptExpression.java @@ -13,42 +13,28 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType; -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 org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTImplicitName; import org.eclipse.cdt.core.dom.ast.IASTInitializerClause; import org.eclipse.cdt.core.dom.ast.IASTNode; -import org.eclipse.cdt.core.dom.ast.IPointerType; -import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTArraySubscriptExpression; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; -import org.eclipse.cdt.internal.core.dom.parser.ProblemType; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinary; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; public class CPPASTArraySubscriptExpression extends ASTNode implements ICPPASTArraySubscriptExpression, IASTAmbiguityParent { - private IASTExpression arrayExpression; - private IASTInitializerClause subscriptExp; - private ICPPFunction overload= UNINITIALIZED_FUNCTION; - + private ICPPASTExpression arrayExpression; + private ICPPASTInitializerClause subscriptExp; + private ICPPEvaluation evaluation; private IASTImplicitName[] implicitNames; - @Override - public ICPPInitClauseEvaluation getEvaluation() { - // mstodo Auto-generated method stub - return null; - } public CPPASTArraySubscriptExpression() { } @@ -76,33 +62,37 @@ public class CPPASTArraySubscriptExpression extends ASTNode } @Override - public IASTExpression getArrayExpression() { + public ICPPASTExpression getArrayExpression() { return arrayExpression; } @Override public void setArrayExpression(IASTExpression expression) { assertNotFrozen(); - arrayExpression = expression; if (expression != null) { + if (!(expression instanceof ICPPASTExpression)) + throw new IllegalArgumentException(expression.getClass().getName()); expression.setParent(this); expression.setPropertyInParent(ARRAY); } + arrayExpression = (ICPPASTExpression) expression; } @Override - public IASTInitializerClause getArgument() { + public ICPPASTInitializerClause getArgument() { return subscriptExp; } @Override public void setArgument(IASTInitializerClause arg) { assertNotFrozen(); - subscriptExp = arg; if (arg != null) { + if (!(arg instanceof ICPPASTInitializerClause)) + throw new IllegalArgumentException(arg.getClass().getName()); arg.setParent(this); arg.setPropertyInParent(SUBSCRIPT); } + subscriptExp = (ICPPASTInitializerClause) arg; } @Override @@ -118,7 +108,7 @@ public class CPPASTArraySubscriptExpression extends ASTNode public void setSubscriptExpression(IASTExpression expression) { setArgument(expression); } - + @Override public IASTImplicitName[] getImplicitNames() { if (implicitNames == null) { @@ -141,20 +131,15 @@ public class CPPASTArraySubscriptExpression extends ASTNode return implicitNames; } - - public ICPPFunction getOverload() { - if (overload == UNINITIALIZED_FUNCTION) { - overload= null; - IType t = getArrayExpression().getExpressionType(); - t= SemanticUtil.getNestedType(t, TDEF | REF | CVTYPE); - if (t instanceof ICPPClassType) { - overload= CPPSemantics.findOverloadedOperator(this); - } - } - return overload; - } - @Override + private ICPPFunction getOverload() { + ICPPEvaluation eval = getEvaluation(); + if (eval instanceof EvalBinary) + return ((EvalBinary) eval).getOverload(this); + return null; + } + + @Override public boolean accept(ASTVisitor action) { if (action.shouldVisitExpressions) { switch (action.visit(this)) { @@ -192,56 +177,41 @@ public class CPPASTArraySubscriptExpression extends ASTNode if (child == subscriptExp) { other.setPropertyInParent(child.getPropertyInParent()); other.setParent(child.getParent()); - subscriptExp = (IASTExpression) other; + subscriptExp = (ICPPASTExpression) other; } if (child == arrayExpression) { other.setPropertyInParent(child.getPropertyInParent()); other.setParent(child.getParent()); - arrayExpression = (IASTExpression) other; + arrayExpression = (ICPPASTExpression) other; } } - + + @Override + public ICPPEvaluation getEvaluation() { + if (evaluation == null) + evaluation= computeEvaluation(); + + return evaluation; + } + + private ICPPEvaluation computeEvaluation() { + if (arrayExpression == null || subscriptExp == null) + return EvalFixed.INCOMPLETE; + return new EvalBinary(EvalBinary.op_arrayAccess, arrayExpression.getEvaluation(), subscriptExp.getEvaluation()); + } + @Override public IType getExpressionType() { - ICPPFunction op = getOverload(); - if (op != null) { - return ExpressionTypes.typeFromFunctionCall(op); - } - IType t1 = getArrayExpression().getExpressionType(); - t1= Conversions.lvalue_to_rvalue(t1, true); - if (t1 instanceof IPointerType) { - t1= ((IPointerType) t1).getType(); - return glvalueType(t1); - } - - IType t2= null; - IASTInitializerClause arg = getArgument(); - if (arg instanceof IASTExpression) { - t2= Conversions.lvalue_to_rvalue(t2, true); - if (t2 instanceof IPointerType) { - t2= ((IPointerType) t2).getType(); - return glvalueType(t2); - } - } - if (t1 instanceof ICPPUnknownType || t2 instanceof ICPPUnknownType) { - // mstodo type of unknown - return CPPUnknownClass.createUnnamedInstance(); - } - - return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); + return getEvaluation().getTypeOrFunctionSet(this); } + @Override + public ValueCategory getValueCategory() { + return getEvaluation().getValueCategory(this); + } + @Override public boolean isLValue() { return getValueCategory() == LVALUE; } - - @Override - public ValueCategory getValueCategory() { - ICPPFunction op = getOverload(); - if (op != null) { - return ExpressionTypes.valueCategoryFromFunctionCall(op); - } - return ValueCategory.LVALUE; - } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java index 7c8150bbb28..e69f6acad4d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryExpression.java @@ -14,9 +14,6 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; -import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.*; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF; import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; @@ -25,33 +22,25 @@ import org.eclipse.cdt.core.dom.ast.IASTImplicitName; import org.eclipse.cdt.core.dom.ast.IASTImplicitNameOwner; import org.eclipse.cdt.core.dom.ast.IASTInitializerClause; import org.eclipse.cdt.core.dom.ast.IASTNode; -import org.eclipse.cdt.core.dom.ast.IPointerType; -import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; -import org.eclipse.cdt.internal.core.dom.parser.ProblemType; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinary; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; + public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpression, IASTAmbiguityParent { private int op; - private IASTExpression operand1; - private IASTInitializerClause operand2; - private IType type; - private ICPPFunction overload= UNINITIALIZED_FUNCTION; + private ICPPASTExpression operand1; + private ICPPASTInitializerClause operand2; + + private ICPPEvaluation evaluation; private IASTImplicitName[] implicitNames = null; - @Override - public ICPPInitClauseEvaluation getEvaluation() { - // mstodo Auto-generated method stub - return null; - } public CPPASTBinaryExpression() { } @@ -107,20 +96,25 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr @Override public void setOperand1(IASTExpression expression) { assertNotFrozen(); - operand1 = expression; if (expression != null) { + if (!(expression instanceof ICPPASTExpression)) + throw new IllegalArgumentException(expression.getClass().getName()); + expression.setParent(this); expression.setPropertyInParent(OPERAND_ONE); } + operand1 = (ICPPASTExpression) expression; } public void setInitOperand2(IASTInitializerClause operand) { assertNotFrozen(); - operand2 = operand; if (operand != null) { + if (!(operand instanceof ICPPASTInitializerClause)) + throw new IllegalArgumentException(operand.getClass().getName()); operand.setParent(this); operand.setPropertyInParent(OPERAND_TWO); } + operand2 = (ICPPASTInitializerClause) operand; } @Override @@ -251,144 +245,51 @@ public class CPPASTBinaryExpression extends ASTNode implements ICPPASTBinaryExpr if (child == operand1) { other.setPropertyInParent(child.getPropertyInParent()); other.setParent(child.getParent()); - operand1 = (IASTExpression) other; + operand1 = (ICPPASTExpression) other; } if (child == operand2) { other.setPropertyInParent(child.getPropertyInParent()); other.setParent(child.getParent()); - operand2 = (IASTInitializerClause) other; + operand2 = (ICPPASTInitializerClause) other; } } - @Override - public IType getExpressionType() { - if (type == null) { - type= createExpressionType(); - } - return type; - } @Override public ICPPFunction getOverload() { - if (overload != UNINITIALIZED_FUNCTION) - return overload; - - return overload = CPPSemantics.findOverloadedOperator(this); - } - - @Override - public ValueCategory getValueCategory() { - ICPPFunction op = getOverload(); - if (op != null) { - return valueCategoryFromFunctionCall(op); - } - switch (getOperator()) { - case op_assign: - case op_binaryAndAssign: - case op_binaryOrAssign: - case op_binaryXorAssign: - case op_divideAssign: - case op_minusAssign: - case op_moduloAssign: - case op_multiplyAssign: - case op_plusAssign: - case op_shiftLeftAssign: - case op_shiftRightAssign: - return LVALUE; - - case op_pmdot: - if (!(getExpressionType() instanceof ICPPFunctionType)) { - return operand1.getValueCategory(); - } - return PRVALUE; - - case op_pmarrow: - if (!(getExpressionType() instanceof ICPPFunctionType)) - return LVALUE; - return PRVALUE; - } - - return PRVALUE; + ICPPEvaluation eval = getEvaluation(); + if (eval instanceof EvalBinary) + return ((EvalBinary) eval).getOverload(this); + return null; } + @Override + public ICPPEvaluation getEvaluation() { + if (evaluation == null) + evaluation= computeEvaluation(); + + return evaluation; + } + + private ICPPEvaluation computeEvaluation() { + if (operand1 == null || operand2 == null) + return EvalFixed.INCOMPLETE; + + return new EvalBinary(op, operand1.getEvaluation(), operand2.getEvaluation()); + } + + @Override + public IType getExpressionType() { + return getEvaluation().getTypeOrFunctionSet(this); + } + + @Override + public ValueCategory getValueCategory() { + return getEvaluation().getValueCategory(this); + } + @Override public boolean isLValue() { return getValueCategory() == LVALUE; } - - private IType createExpressionType() { - IType originalType1 = operand1.getExpressionType(); - IType originalType2 = operand2 instanceof IASTExpression ? - ((IASTExpression) operand2).getExpressionType() : null; - - // Check for overloaded operator. - ICPPFunction o= getOverload(); - if (o != null) { - IType type = typeFromFunctionCall(o); - return restoreTypedefs(type, originalType1, originalType2); - } - - final int op = getOperator(); - IType type1 = prvalueType(originalType1); - if (type1 instanceof ISemanticProblem) { - return type1; - } - - IType type2 = null; - if (originalType2 != null) { - type2= prvalueType(originalType2); - if (type2 instanceof ISemanticProblem) { - return type2; - } - } - - IType type= CPPArithmeticConversion.convertCppOperandTypes(op, type1, type2); - if (type != null) { - return restoreTypedefs(type, originalType1, originalType2); - } - - switch (op) { - case IASTBinaryExpression.op_lessEqual: - case IASTBinaryExpression.op_lessThan: - case IASTBinaryExpression.op_greaterEqual: - case IASTBinaryExpression.op_greaterThan: - case IASTBinaryExpression.op_logicalAnd: - case IASTBinaryExpression.op_logicalOr: - case IASTBinaryExpression.op_equals: - case IASTBinaryExpression.op_notequals: - return CPPBasicType.BOOLEAN; - - case IASTBinaryExpression.op_plus: - if (SemanticUtil.getNestedType(type1, TDEF) instanceof IPointerType) { - return type1; - } - if (SemanticUtil.getNestedType(type2, TDEF) instanceof IPointerType) { - return type2; - } - break; - - case IASTBinaryExpression.op_minus: - if (SemanticUtil.getNestedType(type1, TDEF) instanceof IPointerType) { - if (SemanticUtil.getNestedType(type2, TDEF) instanceof IPointerType) { - return CPPVisitor.getPointerDiffType(this); - } - return type1; - } - break; - - case ICPPASTBinaryExpression.op_pmarrow: - case ICPPASTBinaryExpression.op_pmdot: - if (type2 instanceof ICPPPointerToMemberType) { - IType t= ((ICPPPointerToMemberType) type2).getType(); - if (t instanceof ICPPFunctionType) - return t; - if (op == ICPPASTBinaryExpression.op_pmdot && operand1.getValueCategory() == PRVALUE) { - return prvalueType(t); - } - return glvalueType(t); - } - return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); - } - return restoreTypedefs(type1, originalType1); - } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryTypeIdExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryTypeIdExpression.java index ae0cf9f0fc8..7953101446d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryTypeIdExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTBinaryTypeIdExpression.java @@ -11,28 +11,24 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; -import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTBinaryTypeIdExpression; import org.eclipse.cdt.core.dom.ast.IASTTypeId; -import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; -import org.eclipse.cdt.internal.core.dom.parser.ProblemType; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinaryTypeId; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; public class CPPASTBinaryTypeIdExpression extends ASTNode implements ICPPASTExpression, IASTBinaryTypeIdExpression { private Operator fOperator; private IASTTypeId fOperand1; private IASTTypeId fOperand2; - @Override - public ICPPInitClauseEvaluation getEvaluation() { - // mstodo Auto-generated method stub - return null; - } - + private ICPPEvaluation fEvaluation; + public CPPASTBinaryTypeIdExpression() { } @@ -122,12 +118,26 @@ public class CPPASTBinaryTypeIdExpression extends ASTNode implements ICPPASTExpr } @Override - public IType getExpressionType() { - switch (getOperator()) { - case __is_base_of: - return CPPBasicType.BOOLEAN; + public ICPPEvaluation getEvaluation() { + if (fEvaluation == null) { + if (fOperand1 == null || fOperand2 == null) { + fEvaluation= EvalFixed.INCOMPLETE; + } else { + IType t1= CPPVisitor.createType(fOperand1); + IType t2= CPPVisitor.createType(fOperand1); + if (t1 == null || t2 == null) { + fEvaluation= EvalFixed.INCOMPLETE; + } else { + fEvaluation= new EvalBinaryTypeId(fOperator, t1, t2); + } + } } - return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); + return fEvaluation; + } + + @Override + public IType getExpressionType() { + return getEvaluation().getTypeOrFunctionSet(this); } @Override @@ -137,6 +147,6 @@ public class CPPASTBinaryTypeIdExpression extends ASTNode implements ICPPASTExpr @Override public ValueCategory getValueCategory() { - return isLValue() ? LVALUE : PRVALUE; + return PRVALUE; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCastExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCastExpression.java index bb5cce839c4..f1cf7b966f8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCastExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCastExpression.java @@ -12,34 +12,30 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromReturnType; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCategoryFromReturnType; import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTTypeId; +import org.eclipse.cdt.core.dom.ast.IProblemType; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId; /** * Cast expression for C++ */ public class CPPASTCastExpression extends ASTNode implements ICPPASTCastExpression, IASTAmbiguityParent { private int op; - private IASTExpression operand; + private ICPPASTExpression operand; private IASTTypeId typeId; - private IType fType; - private ValueCategory fValueCategory; - @Override - public ICPPInitClauseEvaluation getEvaluation() { - // mstodo Auto-generated method stub - return null; - } - + private ICPPEvaluation fEvaluation; + public CPPASTCastExpression() { } @@ -102,7 +98,7 @@ public class CPPASTCastExpression extends ASTNode implements ICPPASTCastExpressi @Override public void setOperand(IASTExpression expression) { assertNotFrozen(); - operand = expression; + operand = (ICPPASTExpression) expression; if (expression != null) { expression.setParent(this); expression.setPropertyInParent(OPERAND); @@ -138,26 +134,38 @@ public class CPPASTCastExpression extends ASTNode implements ICPPASTCastExpressi if (child == operand) { other.setPropertyInParent(child.getPropertyInParent()); other.setParent(child.getParent()); - operand = (IASTExpression) other; + operand = (ICPPASTExpression) other; } } + @Override - public IType getExpressionType() { - if (fType == null) { - IType t= CPPVisitor.createType(typeId.getAbstractDeclarator()); - fValueCategory= valueCategoryFromReturnType(t); - fType= typeFromReturnType(t); - } - return fType; + public ICPPEvaluation getEvaluation() { + if (fEvaluation == null) + fEvaluation= computeEvaluation(); + + return fEvaluation; } + + private ICPPEvaluation computeEvaluation() { + if (operand == null) + return EvalFixed.INCOMPLETE; + + IType type= CPPVisitor.createType(getTypeId()); + if (type == null || type instanceof IProblemType) + return EvalFixed.INCOMPLETE; + + return new EvalTypeId(type, operand.getEvaluation()); + } + + @Override + public IType getExpressionType() { + return getEvaluation().getTypeOrFunctionSet(this); + } @Override public ValueCategory getValueCategory() { - if (fValueCategory == null) { - getExpressionType(); // as a side effect fValueCategory is computed - } - return fValueCategory; + return getEvaluation().getValueCategory(this); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCompoundStatementExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCompoundStatementExpression.java index 68e33e4e31a..dad73eb5078 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCompoundStatementExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTCompoundStatementExpression.java @@ -12,18 +12,17 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType; import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement; import org.eclipse.cdt.core.dom.ast.IASTStatement; -import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTCompoundStatementExpression; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; -import org.eclipse.cdt.internal.core.dom.parser.ProblemType; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalCompound; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; /** * Gnu-extension: ({ ... }) @@ -31,14 +30,25 @@ import org.eclipse.cdt.internal.core.dom.parser.ProblemType; public class CPPASTCompoundStatementExpression extends ASTNode implements IGNUASTCompoundStatementExpression, ICPPASTExpression { private IASTCompoundStatement statement; - + private ICPPEvaluation fEval; public CPPASTCompoundStatementExpression() { } @Override - public ICPPInitClauseEvaluation getEvaluation() { - // mstodo Auto-generated method stub - return null; + public ICPPEvaluation getEvaluation() { + if (fEval == null) { + IASTCompoundStatement compound = getCompoundStatement(); + IASTStatement[] statements = compound.getStatements(); + if (statements.length > 0) { + IASTStatement st = statements[statements.length - 1]; + if (st instanceof IASTExpressionStatement) { + fEval= new EvalCompound(((ICPPASTExpression) ((IASTExpressionStatement) st).getExpression()).getEvaluation()); + } + } + if (fEval == null) + fEval= EvalFixed.INCOMPLETE; + } + return fEval; } public CPPASTCompoundStatementExpression(IASTCompoundStatement statement) { @@ -100,14 +110,7 @@ public class CPPASTCompoundStatementExpression extends ASTNode implements IGNUAS @Override public IType getExpressionType() { - IASTCompoundStatement compound = getCompoundStatement(); - IASTStatement[] statements = compound.getStatements(); - if (statements.length > 0) { - IASTStatement st = statements[statements.length - 1]; - if (st instanceof IASTExpressionStatement) - return prvalueType(((IASTExpressionStatement) st).getExpression().getExpressionType()); - } - return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); + return getEvaluation().getTypeOrFunctionSet(this); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConditionalExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConditionalExpression.java index 0904dc97953..e3d05cf340f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConditionalExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConditionalExpression.java @@ -12,54 +12,29 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; -import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; -import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.XVALUE; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*; import org.eclipse.cdt.core.dom.ast.ASTVisitor; -import org.eclipse.cdt.core.dom.ast.DOMException; -import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; import org.eclipse.cdt.core.dom.ast.IASTConditionalExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; -import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; -import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; -import org.eclipse.cdt.internal.core.dom.parser.ProblemType; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CVQualifier; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.Context; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.UDCMode; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.Rank; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalConditional; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; public class CPPASTConditionalExpression extends ASTNode implements IASTConditionalExpression, ICPPASTExpression, IASTAmbiguityParent { - private IASTExpression fCondition; - private IASTExpression fPositive; - private IASTExpression fNegative; - private IType fType; - private ValueCategory fValueCategory; + private ICPPASTExpression fCondition; + private ICPPASTExpression fPositive; + private ICPPASTExpression fNegative; + private ICPPEvaluation fEval; public CPPASTConditionalExpression() { } - @Override - public ICPPInitClauseEvaluation getEvaluation() { - // mstodo Auto-generated method stub - return null; - } - + public CPPASTConditionalExpression(IASTExpression condition, IASTExpression postive, IASTExpression negative) { setLogicalConditionExpression(condition); setPositiveResultExpression(postive); @@ -92,7 +67,7 @@ public class CPPASTConditionalExpression extends ASTNode implements IASTConditio @Override public void setLogicalConditionExpression(IASTExpression expression) { assertNotFrozen(); - fCondition = expression; + fCondition = (ICPPASTExpression) expression; if (expression != null) { expression.setParent(this); expression.setPropertyInParent(LOGICAL_CONDITION); @@ -107,7 +82,7 @@ public class CPPASTConditionalExpression extends ASTNode implements IASTConditio @Override public void setPositiveResultExpression(IASTExpression expression) { assertNotFrozen(); - this.fPositive = expression; + this.fPositive = (ICPPASTExpression) expression; if (expression != null) { expression.setParent(this); expression.setPropertyInParent(POSITIVE_RESULT); @@ -122,7 +97,7 @@ public class CPPASTConditionalExpression extends ASTNode implements IASTConditio @Override public void setNegativeResultExpression(IASTExpression expression) { assertNotFrozen(); - this.fNegative = expression; + this.fNegative = (ICPPASTExpression) expression; if (expression != null) { expression.setParent(this); expression.setPropertyInParent(NEGATIVE_RESULT); @@ -157,159 +132,19 @@ public class CPPASTConditionalExpression extends ASTNode implements IASTConditio if (child == fCondition) { other.setPropertyInParent(child.getPropertyInParent()); other.setParent(child.getParent()); - fCondition = (IASTExpression) other; + fCondition = (ICPPASTExpression) other; } if (child == fPositive) { other.setPropertyInParent(child.getPropertyInParent()); other.setParent(child.getParent()); - fPositive = (IASTExpression) other; + fPositive = (ICPPASTExpression) other; } if (child == fNegative) { other.setPropertyInParent(child.getPropertyInParent()); other.setParent(child.getParent()); - fNegative = (IASTExpression) other; + fNegative = (ICPPASTExpression) other; } } - - @Override - public IType getExpressionType() { - evaluate(); - return fType; - } - - @Override - public ValueCategory getValueCategory() { - evaluate(); - return fValueCategory; - } - - @Override - public boolean isLValue() { - return getValueCategory() == LVALUE; - } - - private void evaluate() { - if (fValueCategory != null) - return; - - fValueCategory= PRVALUE; - - // Gnu-extension: Empty positive expression is replaced by condition. - IASTExpression expr2 = getPositiveResultExpression(); - final IASTExpression expr3 = getNegativeResultExpression(); - if (expr2 == null) { - expr2= getLogicalConditionExpression(); - } - - IType t2 = expr2.getExpressionType(); - IType t3 = expr3.getExpressionType(); - if (t2 == null || t3 == null) { - fType= new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); - return; - } - - final IType uqt2= getNestedType(t2, TDEF | REF | CVTYPE); - final IType uqt3= getNestedType(t3, TDEF | REF | CVTYPE); - if (uqt2 instanceof ISemanticProblem || uqt2 instanceof ICPPUnknownType) { - fType= uqt2; - return; - } - if (uqt3 instanceof ISemanticProblem || uqt3 instanceof ICPPUnknownType) { - fType= uqt3; - return; - } - - final boolean void2= isVoidType(uqt2); - final boolean void3= isVoidType(uqt3); - - // Void types: Either both are void or one is a throw expression. - if (void2 || void3) { - if (isThrowExpression(expr2)) { - fType= Conversions.lvalue_to_rvalue(t3, false); - } else if (isThrowExpression(expr3)) { - fType= Conversions.lvalue_to_rvalue(t2, false); - } else if (void2 && void3) { - fType= uqt2; - } else { - fType= new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); - } - return; - } - - final ValueCategory vcat2= expr2.getValueCategory(); - final ValueCategory vcat3= expr3.getValueCategory(); - - // Same type - if (t2.isSameType(t3)) { - if (vcat2 == vcat3) { - fType= t2; - fValueCategory= vcat2; - } else { - fType= prvalueType(t2); - fValueCategory= PRVALUE; - } - return; - } - - final boolean isClassType2 = uqt2 instanceof ICPPClassType; - final boolean isClassType3 = uqt3 instanceof ICPPClassType; - - // Different types with at least one class type - if (isClassType2 || isClassType3) { - final Cost cost2= convertToMatch(t2, vcat2, uqt2, t3, vcat3, uqt3); // sets fType and fValueCategory - final Cost cost3= convertToMatch(t3, vcat3, uqt3, t2, vcat2, uqt2); // sets fType and fValueCategory - if (cost2.converts() || cost3.converts()) { - if (cost2.converts()) { - if (cost3.converts() || cost2.isAmbiguousUDC()) { - fType= new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); - } - } else if (cost3.isAmbiguousUDC()) { - fType= new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); - } - return; - } - } else if (vcat2 == vcat3 && vcat2.isGLValue() && uqt2.isSameType(uqt3)) { - // Two lvalues or two xvalues with same type up to qualification. - final CVQualifier cv2 = SemanticUtil.getCVQualifier(t2); - final CVQualifier cv3 = SemanticUtil.getCVQualifier(t3); - if (cv2.isAtLeastAsQualifiedAs(cv3)) { - fType= t2; - fValueCategory= vcat2; - } else if (cv3.isAtLeastAsQualifiedAs(cv2)) { - fType= t3; - fValueCategory= vcat3; - } else { - fType= new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); - } - return; - } - - // 5.16-5: At least one class type but no conversion - if (isClassType2 || isClassType3) { - ICPPFunction builtin = CPPSemantics.findOverloadedConditionalOperator(expr2, expr3); - if (builtin != null) { - fType= ExpressionTypes.typeFromFunctionCall(builtin); - } else { - fType= new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); - } - return; - } - - // 5.16-6 - t2= Conversions.lvalue_to_rvalue(t2, false); - t3= Conversions.lvalue_to_rvalue(t3, false); - if (t2.isSameType(t3)) { - fType= t2; - } else { - fType= CPPArithmeticConversion.convertCppOperandTypes(IASTBinaryExpression.op_plus, t2, t3); - if (fType == null) { - fType= Conversions.compositePointerType(t2, t3); - if (fType == null) { - fType= new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); - } - } - } - } private boolean isThrowExpression(IASTExpression expr) { while (expr instanceof IASTUnaryExpression) { @@ -326,50 +161,33 @@ public class CPPASTConditionalExpression extends ASTNode implements IASTConditio return false; } - private Cost convertToMatch(IType t1, ValueCategory vcat1, IType uqt1, IType t2, ValueCategory vcat2, IType uqt2) { - // E2 is an lvalue or E2 is an xvalue - try { - if (vcat2.isGLValue()) { - IType target= new CPPReferenceType(t2, vcat2 == XVALUE); - Cost c= Conversions.checkImplicitConversionSequence(target, t1, vcat1, UDCMode.ALLOWED, Context.REQUIRE_DIRECT_BINDING); - if (c.converts()) { - fType= t2; - fValueCategory= vcat2; - return c; - } + @Override + public ICPPEvaluation getEvaluation() { + if (fEval == null) { + if (fCondition == null || fNegative == null) { + fEval= EvalFixed.INCOMPLETE; + } else { + final ICPPEvaluation condEval = fCondition.getEvaluation(); + final ICPPEvaluation posEval = fPositive == null ? null : fPositive.getEvaluation(); + fEval= new EvalConditional(condEval, posEval, fNegative.getEvaluation(), + isThrowExpression(fPositive), isThrowExpression(fNegative)); } - // Both are class types and one derives from the other - if (uqt1 instanceof ICPPClassType && uqt2 instanceof ICPPClassType) { - int dist= SemanticUtil.calculateInheritanceDepth(uqt1, uqt2); - if (dist >= 0) { - CVQualifier cv1 = SemanticUtil.getCVQualifier(t1); - CVQualifier cv2 = SemanticUtil.getCVQualifier(t2); - if (cv2.isAtLeastAsQualifiedAs(cv1)) { - fType= t2; - fValueCategory= PRVALUE; - return new Cost(t1, t2, Rank.IDENTITY); - } - return Cost.NO_CONVERSION; - } - if (SemanticUtil.calculateInheritanceDepth(uqt2, uqt1) >= 0) - return Cost.NO_CONVERSION; - } - // Unrelated class types or just one class: - if (vcat2 != PRVALUE) { - t2= Conversions.lvalue_to_rvalue(t2, false); - } - Cost c= Conversions.checkImplicitConversionSequence(t2, t1, vcat1, UDCMode.ALLOWED, Context.ORDINARY); - if (c.converts()) { - fType= t2; - fValueCategory= PRVALUE; - return c; - } - } catch (DOMException e) { } - return Cost.NO_CONVERSION; + return fEval; } + + @Override + public IType getExpressionType() { + return getEvaluation().getTypeOrFunctionSet(this); + } + + @Override + public ValueCategory getValueCategory() { + return getEvaluation().getValueCategory(this); + } - private boolean isVoidType(IType t) { - return t instanceof ICPPBasicType && ((ICPPBasicType) t).getKind() == Kind.eVoid; + @Override + public boolean isLValue() { + return getValueCategory() == LVALUE; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeleteExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeleteExpression.java index 5b50b21455a..0603d0c2ed7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeleteExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTDeleteExpression.java @@ -23,20 +23,19 @@ import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; +import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpression { + private static final ICPPEvaluation EVALUATION = new EvalFixed(CPPSemantics.VOID_TYPE, PRVALUE, Value.UNKNOWN); + private IASTExpression operand; private boolean isGlobal; private boolean isVectored; private IASTImplicitName[] implicitNames = null; - @Override - public ICPPInitClauseEvaluation getEvaluation() { - // mstodo Auto-generated method stub - return null; - } public CPPASTDeleteExpression() { } @@ -172,6 +171,11 @@ public class CPPASTDeleteExpression extends ASTNode implements ICPPASTDeleteExpr return true; } + @Override + public ICPPEvaluation getEvaluation() { + return EVALUATION; + } + @Override public IType getExpressionType() { return CPPSemantics.VOID_TYPE; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTExpressionList.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTExpressionList.java index 338dde0d46e..17a3cde3860 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTExpressionList.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTExpressionList.java @@ -13,30 +13,22 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; -import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.*; -import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTExpression; -import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.IASTImplicitName; import org.eclipse.cdt.core.dom.ast.IASTNode; -import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.IType; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpressionList; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; -import org.eclipse.cdt.internal.core.dom.parser.ProblemType; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalComma; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionList, IASTAmbiguityParent { - private static final ICPPFunction[] NO_FUNCTIONS = {}; private IASTExpression[] expressions = new IASTExpression[2]; @@ -45,13 +37,8 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi * @see CPPASTExpressionList#computeImplicitNames */ private IASTImplicitName[] implicitNames; - private ICPPFunction[] overloads; - - @Override - public ICPPInitClauseEvaluation getEvaluation() { - // mstodo Auto-generated method stub - return null; - } + + private ICPPEvaluation fEvaluation; @Override public CPPASTExpressionList copy() { @@ -155,42 +142,11 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi } private ICPPFunction[] getOverloads() { - if (overloads == null) { - IASTExpression[] exprs = getExpressions(); - if (exprs.length < 2) - return overloads = NO_FUNCTIONS; - - ASTNodeProperty prop = getPropertyInParent(); - if (prop == IASTFunctionCallExpression.ARGUMENT || - prop == ICPPASTConstructorChainInitializer.INITIALIZER || - prop == ICPPASTConstructorInitializer.ARGUMENT || - prop == ICPPASTNewExpression.NEW_INITIALIZER) - return overloads = NO_FUNCTIONS; - - overloads = new ICPPFunction[exprs.length - 1]; - IType lookupType = typeOrFunctionSet(exprs[0]); - ValueCategory vcat= valueCat(exprs[0]); - - for (int i = 1; i < exprs.length; i++) { - IASTExpression e1 = exprs[i - 1], e2 = exprs[i]; - ICPPFunction overload = CPPSemantics.findOverloadedOperatorComma(e1, lookupType, vcat, e2); - if (overload == null) { - lookupType = typeOrFunctionSet(e2); - vcat= valueCat(e2); - } else { - overloads[i - 1] = overload; - lookupType = overload.getType().getReturnType(); - vcat= valueCategoryFromReturnType(lookupType); - lookupType= typeFromReturnType(lookupType); - if (lookupType instanceof ISemanticProblem) { - lookupType = typeOrFunctionSet(e2); - vcat= valueCat(e2); - } - } - } + ICPPEvaluation eval = getEvaluation(); + if (eval instanceof EvalComma) { + return ((EvalComma) eval).getOverloads(this); } - - return overloads; + return null; } @Override @@ -206,42 +162,35 @@ public class CPPASTExpressionList extends ASTNode implements ICPPASTExpressionLi } @Override - public IType getExpressionType() { - ICPPFunction[] overloads = getOverloads(); - if (overloads.length > 0) { - ICPPFunction last = overloads[overloads.length - 1]; - if (last != null) { - return typeFromFunctionCall(last); - } - } - - for (int i = expressions.length - 1; i >= 0; i--) { - IASTExpression expr = expressions[i]; - if (expr != null) - return expr.getExpressionType(); - } + public ICPPEvaluation getEvaluation() { + if (fEvaluation == null) + fEvaluation= computeEvaluation(); - return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); - } - - @Override - public ValueCategory getValueCategory() { - ICPPFunction[] overloads = getOverloads(); - if (overloads.length > 0) { - ICPPFunction last = overloads[overloads.length - 1]; - if (last != null) { - return valueCategoryFromFunctionCall(last); - } - } - - for (int i = expressions.length-1; i >= 0; i--) { - IASTExpression expr= expressions[i]; - if (expr != null) - return expr.getValueCategory(); - } - return PRVALUE; + return fEvaluation; } + private ICPPEvaluation computeEvaluation() { + final IASTExpression[] exprs = getExpressions(); + if (exprs.length < 2) + return EvalFixed.INCOMPLETE; + + ICPPEvaluation[] evals= new ICPPEvaluation[exprs.length]; + for (int i = 0; i < evals.length; i++) { + evals[i]= ((ICPPASTExpression) exprs[i]).getEvaluation(); + } + return new EvalComma(evals); + } + + @Override + public IType getExpressionType() { + return getEvaluation().getTypeOrFunctionSet(this); + } + + @Override + public ValueCategory getValueCategory() { + return getEvaluation().getValueCategory(this); + } + @Override public boolean isLValue() { return getValueCategory() == LVALUE; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java index 0792dceece0..3f7f1473b53 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFieldReference.java @@ -14,57 +14,45 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; -import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueTypeWithResolvedTypedefs; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromFunctionCall; -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.getUltimateTypeUptoPointers; import java.util.ArrayList; -import java.util.Collection; import java.util.List; import org.eclipse.cdt.core.dom.ast.ASTVisitor; -import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTImplicitName; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.ICPPASTCompletionContext; -import org.eclipse.cdt.core.dom.ast.IEnumerator; -import org.eclipse.cdt.core.dom.ast.IFunction; -import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IProblemBinding; -import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.IType; -import org.eclipse.cdt.core.dom.ast.IVariable; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; -import org.eclipse.cdt.internal.core.dom.parser.ProblemType; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPFunctionSet; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CVQualifier; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalID; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalMemberAccess; public class CPPASTFieldReference extends ASTNode implements ICPPASTFieldReference, IASTAmbiguityParent, ICPPASTCompletionContext { private boolean isTemplate; - private IASTExpression owner; + private ICPPASTExpression owner; private IASTName name; private boolean isDeref; private IASTImplicitName[] implicitNames; + private ICPPEvaluation fEvaluation; public CPPASTFieldReference() { } @@ -73,11 +61,6 @@ public class CPPASTFieldReference extends ASTNode setFieldName(name); setFieldOwner(owner); } - @Override - public ICPPInitClauseEvaluation getEvaluation() { - // mstodo Auto-generated method stub - return null; - } @Override public CPPASTFieldReference copy() { @@ -110,14 +93,14 @@ public class CPPASTFieldReference extends ASTNode } @Override - public IASTExpression getFieldOwner() { + public ICPPASTExpression getFieldOwner() { return owner; } @Override public void setFieldOwner(IASTExpression expression) { assertNotFrozen(); - owner = expression; + owner = (ICPPASTExpression) expression; if (expression != null) { expression.setParent(this); expression.setPropertyInParent(FIELD_OWNER); @@ -158,7 +141,7 @@ public class CPPASTFieldReference extends ASTNode // Collect the function bindings List functionBindings = new ArrayList(); - getFieldOwnerType(functionBindings); + EvalMemberAccess.getFieldOwnerType(owner.getExpressionType(), isDeref, this, functionBindings, false); if (functionBindings.isEmpty()) return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY; @@ -224,100 +207,10 @@ public class CPPASTFieldReference extends ASTNode if (child == owner) { other.setPropertyInParent(child.getPropertyInParent()); other.setParent(child.getParent()); - owner = (IASTExpression) other; + owner = (ICPPASTExpression) other; } } - @Override - public IType getExpressionType() { - IASTName name= getFieldName(); - IBinding binding = name.resolvePreBinding(); - try { - if (binding instanceof IVariable) { - IType e2= ((IVariable) binding).getType(); - e2= SemanticUtil.getNestedType(e2, TDEF); - if (e2 instanceof ICPPReferenceType) { - e2= glvalueType(e2); - } else if (binding instanceof ICPPField && !((ICPPField) binding).isStatic()) { - IType e1= getFieldOwner().getExpressionType(); - if (isPointerDereference()) { - e1= SemanticUtil.getNestedType(e1, TDEF | REF | CVTYPE); - if (e1 instanceof IPointerType) { - e1= ((IPointerType) e1).getType(); - } - } - e2 = addQualifiersForAccess((ICPPField) binding, e2, e1); - if (!isPointerDereference() && owner.getValueCategory() == PRVALUE) { - e2= prvalueType(e2); - } else { - e2= glvalueType(e2); - } - } - return SemanticUtil.mapToAST(e2, this); - } - if (binding instanceof IEnumerator) { - return ((IEnumerator) binding).getType(); - } - if (binding instanceof IFunction) { - return SemanticUtil.mapToAST(((IFunction) binding).getType(), this); - } - if (binding instanceof ICPPUnknownBinding) { - // mstodo type of unknown. - return CPPUnknownClass.createUnnamedInstance(); - } - if (binding instanceof IProblemBinding) { - return new ProblemType(ISemanticProblem.TYPE_UNRESOLVED_NAME); - } - return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); - } catch (DOMException e) { - return e.getProblem(); - } - } - - public static IType addQualifiersForAccess(ICPPField field, IType fieldType, IType ownerType) { - CVQualifier cvq1 = SemanticUtil.getCVQualifier(ownerType); - CVQualifier cvq2 = SemanticUtil.getCVQualifier(fieldType); - if (field.isMutable()) { - // Remove const, add union of volatile. - if (cvq2.isConst()) { - fieldType= SemanticUtil.getNestedType(fieldType, ALLCVQ | TDEF | REF); - } - fieldType= SemanticUtil.addQualifiers(fieldType, false, cvq1.isVolatile() || cvq2.isVolatile(), cvq2.isRestrict()); - } else { - fieldType= SemanticUtil.addQualifiers(fieldType, cvq1.isConst(), cvq1.isVolatile(), cvq2.isRestrict()); - } - return fieldType; - } - - @Override - public ValueCategory getValueCategory() { - IASTName name= getFieldName(); - IBinding binding = name.resolvePreBinding(); - if (binding instanceof IVariable) { - IType e2= ((IVariable) binding).getType(); - e2= SemanticUtil.getNestedType(e2, TDEF); - if (e2 instanceof ICPPReferenceType) { - return LVALUE; - } - if (binding instanceof ICPPField && !((ICPPField) binding).isStatic()) { - if (isPointerDereference()) - return LVALUE; - - return owner.getValueCategory(); - } - return LVALUE; - } - if (binding instanceof IFunction) { - return LVALUE; - } - return PRVALUE; - } - - @Override - public boolean isLValue() { - return getValueCategory() == LVALUE; - } - @Override public IBinding[] findBindings(IASTName n, boolean isPrefix, String[] namespaces) { IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix, namespaces); @@ -347,56 +240,63 @@ public class CPPASTFieldReference extends ASTNode */ @Override public IType getFieldOwnerType() { - return getFieldOwnerType(null); + return EvalMemberAccess.getFieldOwnerType(owner.getExpressionType(), isDeref, this, null, true); } - /* - * Also collects the function bindings if requested. - */ - private IType getFieldOwnerType(Collection functionBindings) { - final IASTExpression owner = getFieldOwner(); - if (owner == null) - return null; - - IType type= owner.getExpressionType(); - if (!isPointerDereference()) - return type; - - // 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++) { - // for unknown types we cannot determine the overloaded -> operator - IType classType= getUltimateTypeUptoPointers(type); - if (classType instanceof ICPPUnknownType) - return CPPUnknownClass.createUnnamedInstance(); + @Override + public ICPPEvaluation getEvaluation() { + if (fEvaluation == null) { + fEvaluation= createEvaluation(); + } + return fEvaluation; + } + + private ICPPEvaluation createEvaluation() { + ICPPEvaluation ownerEval = owner.getEvaluation(); + if (!ownerEval.isTypeDependent()) { + IType ownerType= EvalMemberAccess.getFieldOwnerType(ownerEval.getTypeOrFunctionSet(this), isDeref, this, null, false); + if (ownerType != null) { + IBinding binding = name.resolvePreBinding(); + if (binding instanceof CPPFunctionSet) + binding= name.resolveBinding(); - if (!(classType instanceof ICPPClassType)) - 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. - */ + if (binding instanceof IProblemBinding || binding instanceof IType || binding instanceof ICPPConstructor) + return EvalFixed.INCOMPLETE; - ICPPFunction op = CPPSemantics.findOverloadedOperator(this, type, (ICPPClassType) classType); - if (op == null) - break; - - if (functionBindings != null) - functionBindings.add(op); - - type= typeFromFunctionCall(op); - type= SemanticUtil.mapToAST(type, owner); - } - - IType prValue= prvalueTypeWithResolvedTypedefs(type); - if (prValue instanceof IPointerType) { - return glvalueType(((IPointerType) prValue).getType()); + return new EvalMemberAccess(ownerType, ownerEval.getValueCategory(this), binding, isDeref); + } } - return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); - } + IBinding qualifier= null; + ICPPTemplateArgument[] args= null; + IASTName n= name; + if (n instanceof ICPPASTQualifiedName) { + IASTName[] ns= ((ICPPASTQualifiedName) n).getNames(); + if (ns.length < 2) + return EvalFixed.INCOMPLETE; + qualifier= ns[ns.length-2].resolveBinding(); + if (qualifier instanceof IProblemBinding) + return EvalFixed.INCOMPLETE; + n= ns[ns.length-1]; + } + if (n instanceof ICPPASTTemplateId) { + args= CPPTemplates.createTemplateArgumentArray((ICPPASTTemplateId) n); + } + return new EvalID(ownerEval, qualifier, name.getSimpleID(), false, qualifier != null, args); + } + + @Override + public IType getExpressionType() { + return getEvaluation().getTypeOrFunctionSet(this); + } + + @Override + public boolean isLValue() { + return getValueCategory() == LVALUE; + } + + @Override + public ValueCategory getValueCategory() { + return getEvaluation().getValueCategory(this); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java index a7465312e31..6ae3b430d93 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTFunctionCallExpression.java @@ -13,17 +13,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; -import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromFunctionCall; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromReturnType; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCategoryFromFunctionCall; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCategoryFromReturnType; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.COND_TDEF; -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 static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*; import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.DOMException; @@ -35,13 +25,9 @@ import org.eclipse.cdt.core.dom.ast.IASTInitializerClause; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; -import org.eclipse.cdt.core.dom.ast.IFunctionType; -import org.eclipse.cdt.core.dom.ast.IPointerType; -import org.eclipse.cdt.core.dom.ast.IProblemBinding; -import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpressionList; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; @@ -49,19 +35,19 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.parser.IToken; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; -import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFunctionCall; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.LookupData; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; public class CPPASTFunctionCallExpression extends ASTNode implements ICPPASTFunctionCallExpression, IASTAmbiguityParent { - private IASTExpression functionName; + private ICPPASTExpression functionName; private IASTInitializerClause[] fArguments; private IASTImplicitName[] implicitNames; - private ICPPFunction overload= UNINITIALIZED_FUNCTION; + private ICPPEvaluation evaluation; public CPPASTFunctionCallExpression() { setArguments(null); @@ -71,11 +57,6 @@ public class CPPASTFunctionCallExpression extends ASTNode setFunctionNameExpression(functionName); setArguments(args); } - @Override - public ICPPInitClauseEvaluation getEvaluation() { - // mstodo Auto-generated method stub - return null; - } @Override public CPPASTFunctionCallExpression copy() { @@ -105,7 +86,7 @@ public class CPPASTFunctionCallExpression extends ASTNode @Override public void setFunctionNameExpression(IASTExpression expression) { assertNotFrozen(); - this.functionName = expression; + this.functionName = (ICPPASTExpression) expression; if (expression != null) { expression.setParent(this); expression.setPropertyInParent(FUNCTION_NAME); @@ -134,11 +115,11 @@ public class CPPASTFunctionCallExpression extends ASTNode @Override public IASTImplicitName[] getImplicitNames() { if (implicitNames == null) { - ICPPFunction overload = getOperator(); + ICPPFunction overload = getOverload(); if (overload == null) return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY; - if (isExplicitTypeConversion() != null) { + if (getEvaluation() instanceof EvalTypeId) { CPPASTImplicitName n1 = new CPPASTImplicitName(overload.getNameCharArray(), this); n1.setOffsetAndLength((ASTNode) functionName); n1.setBinding(overload); @@ -227,7 +208,7 @@ public class CPPASTFunctionCallExpression extends ASTNode if (child == functionName) { other.setPropertyInParent(child.getPropertyInParent()); other.setParent(child.getParent()); - functionName = (IASTExpression) other; + functionName = (ICPPASTExpression) other; } for (int i = 0; i < fArguments.length; ++i) { if (child == fArguments[i]) { @@ -238,113 +219,8 @@ public class CPPASTFunctionCallExpression extends ASTNode } } - public ICPPFunction getOperator() { - if (overload == UNINITIALIZED_FUNCTION) { - overload= null; - IType t= isExplicitTypeConversion(); - if (t != null) { - t = getNestedType(t, TDEF | CVTYPE | REF); - if (t instanceof ICPPClassType && !(t instanceof ICPPUnknownBinding)) { - ICPPClassType cls= (ICPPClassType) t; - LookupData data= CPPSemantics.createLookupData(((IASTIdExpression) functionName).getName()); - try { - IBinding b= CPPSemantics.resolveFunction(data, cls.getConstructors(), true); - if (b instanceof ICPPFunction) - overload= (ICPPFunction) b; - } catch (DOMException e) { - } - } - } else { - t= SemanticUtil.getNestedType(functionName.getExpressionType(), TDEF | REF | CVTYPE); - if (t instanceof ICPPClassType) { - overload = CPPSemantics.findOverloadedOperator(this, (ICPPClassType) t); - } - } - } - return overload; - } - @Override - public IType getExpressionType() { - // Handle explicit type conversion in functional notation. - IType type= isExplicitTypeConversion(); - if (type != null) { - if (type instanceof IProblemBinding) { - return ProblemType.UNRESOLVED_NAME; - } - return prvalueType(type); - } - - type= SemanticUtil.getNestedType(functionName.getExpressionType(), COND_TDEF | REF | CVTYPE); - IType t = SemanticUtil.getNestedType(type, TDEF | REF | CVTYPE); - if (t instanceof ICPPClassType) { - if (overload == UNINITIALIZED_FUNCTION) { - overload = CPPSemantics.findOverloadedOperator(this, (ICPPClassType) t); - } - if (overload != null) { - return typeFromFunctionCall(overload); - } - return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); - } - - if (t instanceof IPointerType) { - t= SemanticUtil.getNestedType(((IPointerType) t).getType(), TDEF | REF | CVTYPE); - } - if (t instanceof IFunctionType) { - type = typeFromReturnType(((IFunctionType) t).getReturnType()); - if (functionName instanceof ICPPASTFieldReference) { - IType ownerType = ((ICPPASTFieldReference) functionName).getFieldOwnerType(); - t = SemanticUtil.substituteTypedef(type, ownerType); - if (t != null) - type = t; - } - return type; - } - if (CPPTemplates.isDependentType(type)) - return CPPUnknownClass.createUnnamedInstance(); - return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); - } - - private IType isExplicitTypeConversion() { - if (functionName instanceof IASTIdExpression) { - final IASTName name = ((IASTIdExpression) functionName).getName(); - IBinding b= name.resolvePreBinding(); - if (b instanceof IType) - return (IType) b; - } - return null; - } - - @Override - public boolean isLValue() { - return getValueCategory() == LVALUE; - } - - @Override - public ValueCategory getValueCategory() { - if (isExplicitTypeConversion() != null) - return PRVALUE; - - IType t= functionName.getExpressionType(); - if (t instanceof ICPPClassType) { - if (overload == UNINITIALIZED_FUNCTION) { - overload = CPPSemantics.findOverloadedOperator(this, (ICPPClassType) t); - } - if (overload != null) { - return valueCategoryFromFunctionCall(overload); - } - } else { - if (t instanceof IPointerType) { - t= SemanticUtil.getNestedType(((IPointerType) t).getType(), TDEF | REF | CVTYPE); - } - if (t instanceof IFunctionType) { - return valueCategoryFromReturnType(((IFunctionType) t).getReturnType()); - } - } - return ValueCategory.PRVALUE; - } - @Override @Deprecated public IASTExpression getParameterExpression() { @@ -380,4 +256,82 @@ public class CPPASTFunctionCallExpression extends ASTNode setArguments(new IASTExpression[] {expression}); } } + + public ICPPFunction getOverload() { + ICPPEvaluation eval = getEvaluation(); + if (eval instanceof EvalFunctionCall) + return ((EvalFunctionCall) eval).getOverload(this); + + if (eval instanceof EvalTypeId) { + if (!eval.isTypeDependent()) { + IType t= getNestedType(((EvalTypeId) eval).getInputType(), TDEF|CVTYPE|REF); + if (t instanceof ICPPClassType && !(t instanceof ICPPUnknownBinding)) { + ICPPClassType cls= (ICPPClassType) t; + LookupData data= CPPSemantics.createLookupData(((IASTIdExpression) functionName).getName()); + try { + IBinding b= CPPSemantics.resolveFunction(data, cls.getConstructors(), true); + if (b instanceof ICPPFunction) + return (ICPPFunction) b; + } catch (DOMException e) { + } + } + } + } + return null; + } + + @Override + public ICPPEvaluation getEvaluation() { + if (evaluation == null) + evaluation= computeEvaluation(); + + return evaluation; + } + + private ICPPEvaluation computeEvaluation() { + if (functionName == null || fArguments == null) + return EvalFixed.INCOMPLETE; + + ICPPEvaluation conversion= checkForExplicitTypeConversion(); + if (conversion != null) + return conversion; + + ICPPEvaluation[] args= new ICPPEvaluation[fArguments.length+1]; + args[0]= functionName.getEvaluation(); + for (int i = 1; i < args.length; i++) { + args[i]= ((ICPPASTExpression) fArguments[i-1]).getEvaluation(); + } + return new EvalFunctionCall(args); + } + + private ICPPEvaluation checkForExplicitTypeConversion() { + if (functionName instanceof IASTIdExpression) { + final IASTName name = ((IASTIdExpression) functionName).getName(); + IBinding b= name.resolvePreBinding(); + if (b instanceof IType) { + ICPPEvaluation[] args= new ICPPEvaluation[fArguments.length]; + for (int i = 1; i < args.length; i++) { + args[i]= ((ICPPASTExpression) fArguments[i]).getEvaluation(); + } + return new EvalTypeId((IType) b, args); + } + } + return null; + } + + + @Override + public IType getExpressionType() { + return getEvaluation().getTypeOrFunctionSet(this); + } + + @Override + public ValueCategory getValueCategory() { + return getEvaluation().getValueCategory(this); + } + + @Override + public boolean isLValue() { + return getValueCategory() == LVALUE; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIdExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIdExpression.java index a20fbc6519a..bd1d7c27e98 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIdExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTIdExpression.java @@ -13,56 +13,28 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType; import org.eclipse.cdt.core.dom.ast.ASTVisitor; -import org.eclipse.cdt.core.dom.ast.DOMException; -import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTIdExpression; -import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression; import org.eclipse.cdt.core.dom.ast.IASTName; -import org.eclipse.cdt.core.dom.ast.IASTNode; -import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.ICPPASTCompletionContext; -import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IFunction; -import org.eclipse.cdt.core.dom.ast.IProblemBinding; -import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.IType; -import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter; -import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ProblemType; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPFunctionSet; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalID; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.FunctionSetType; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; public class CPPASTIdExpression extends ASTNode implements IASTIdExpression, ICPPASTExpression, ICPPASTCompletionContext { - private static final ICPPASTFieldReference NOT_INITIALIZED = new CPPASTFieldReference(); - private IASTName name; - private ICPPASTFieldReference fTransformedExpression= NOT_INITIALIZED; + private ICPPEvaluation fEvaluation; public CPPASTIdExpression() { } - @Override - public ICPPInitClauseEvaluation getEvaluation() { - // mstodo Auto-generated method stub - return null; - } public CPPASTIdExpression(IASTName name) { setName(name); @@ -126,120 +98,6 @@ public class CPPASTIdExpression extends ASTNode implements IASTIdExpression, ICP return r_unclear; } - @Override - public IType getExpressionType() { - IBinding binding = name.resolvePreBinding(); - if (binding instanceof CPPFunctionSet) - binding= name.resolveBinding(); - - if (checkForTransformation(binding)) { - return fTransformedExpression.getExpressionType(); - } - try { - if (binding instanceof IProblemBinding) { - return new ProblemType(ISemanticProblem.TYPE_UNRESOLVED_NAME); - } - if (binding instanceof IType || binding instanceof ICPPConstructor) { - return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); - } - if (binding instanceof IEnumerator) { - IType type= ((IEnumerator) binding).getType(); - if (type instanceof ICPPEnumeration) { - ICPPEnumeration enumType= (ICPPEnumeration) type; - if (enumType.asScope() == CPPVisitor.getContainingScope(this)) { - // C++0x: 7.2-5 - IType fixedType= enumType.getFixedType(); - if (fixedType != null) - return fixedType; - // This is a simplification, the actual type is determined - // - in an implementation dependent manner - by the value - // of the enumerator. - return CPPSemantics.INT_TYPE; - } - } - return type; - } - if (binding instanceof IVariable) { - final IType t = glvalueType(((IVariable) binding).getType()); - return SemanticUtil.mapToAST(t, this); - } - if (binding instanceof IFunction) { - return SemanticUtil.mapToAST(((IFunction) binding).getType(), this); - } - if (binding instanceof ICPPTemplateNonTypeParameter) { - return prvalueType(((ICPPTemplateNonTypeParameter) binding).getType()); - } - if (binding instanceof ICPPUnknownBinding) { - // mstodo typeof unknown binding - return CPPUnknownClass.createUnnamedInstance(); - } - } catch (DOMException e) { - return e.getProblem(); - } - return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); - } - - /** - * 9.3.1-3 Transformation to class member access within the definition of a non-static - * member function. - */ - public boolean checkForTransformation(IBinding binding) { - if (fTransformedExpression == NOT_INITIALIZED) { - fTransformedExpression= null; - if (name instanceof ICPPASTQualifiedName) { - IASTNode parent= name.getParent(); - if (parent instanceof ICPPASTUnaryExpression) { - if (((ICPPASTUnaryExpression) parent).getOperator() == IASTUnaryExpression.op_amper) { - return false; - } - } - } - if (binding instanceof ICPPMember && !(binding instanceof IType) && !(binding instanceof ICPPConstructor) - &&!((ICPPMember) binding).isStatic()) { - IASTNode parent= getParent(); - while (parent != null && !(parent instanceof ICPPASTFunctionDefinition)) { - parent= parent.getParent(); - } - if (parent instanceof ICPPASTFunctionDefinition) { - ICPPASTFunctionDefinition fdef= (ICPPASTFunctionDefinition) parent; - final IBinding methodBinding = fdef.getDeclarator().getName().resolvePreBinding(); - if (methodBinding instanceof ICPPMethod && !((ICPPMethod) methodBinding).isStatic()) { - IASTName nameDummy= new CPPASTName(); - nameDummy.setBinding(binding); - IASTExpression owner= new CPPASTLiteralExpression(IASTLiteralExpression.lk_this, - CharArrayUtils.EMPTY); - owner= new CPPASTUnaryExpression(IASTUnaryExpression.op_star, owner); - fTransformedExpression= new CPPASTFieldReference(nameDummy, owner); - fTransformedExpression.setParent(getParent()); - fTransformedExpression.setPropertyInParent(getPropertyInParent()); - } - } - } - } - - return fTransformedExpression != null; - } - - @Override - public boolean isLValue() { - return getValueCategory() == LVALUE; - } - - @Override - public ValueCategory getValueCategory() { - IBinding binding = name.resolvePreBinding(); - if (checkForTransformation(binding)) { - return fTransformedExpression.getValueCategory(); - } - if (binding instanceof ICPPTemplateNonTypeParameter) - return ValueCategory.PRVALUE; - - if (binding instanceof IVariable || binding instanceof IFunction) { - return ValueCategory.LVALUE; - } - return ValueCategory.PRVALUE; - } - @Override public IBinding[] findBindings(IASTName n, boolean isPrefix, String[] namespaces) { return CPPSemantics.findBindingsForContentAssist(n, isPrefix, namespaces); @@ -254,4 +112,35 @@ public class CPPASTIdExpression extends ASTNode implements IASTIdExpression, ICP public IBinding[] findBindings(IASTName n, boolean isPrefix) { return findBindings(n, isPrefix, null); } + + @Override + public ICPPEvaluation getEvaluation() { + if (fEvaluation == null) { + fEvaluation= EvalID.create(this); + } + return fEvaluation; + } + + @Override + public IType getExpressionType() { + IType type= getEvaluation().getTypeOrFunctionSet(this); + if (type instanceof FunctionSetType) { + IBinding binding= name.resolveBinding(); + if (binding instanceof IFunction) { + return SemanticUtil.mapToAST(((IFunction) binding).getType(), this); + } + return ProblemType.UNKNOWN_FOR_EXPRESSION; + } + return type; + } + + @Override + public boolean isLValue() { + return getValueCategory() == LVALUE; + } + + @Override + public ValueCategory getValueCategory() { + return getEvaluation().getValueCategory(this); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTInitializerList.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTInitializerList.java index 2240ed2d6fe..1556865508f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTInitializerList.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTInitializerList.java @@ -17,29 +17,28 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTInitializer; import org.eclipse.cdt.core.dom.ast.IASTInitializerClause; import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalInitList; /** * e.g.: int a[]= {1,2,3}; */ public class CPPASTInitializerList extends ASTNode implements ICPPASTInitializerList, IASTAmbiguityParent { - private IASTInitializerClause [] initializers; + private static final ICPPASTInitializerClause[] NO_CLAUSES = {}; + private ICPPASTInitializerClause [] initializers; private int initializersPos= -1; private int actualSize; private boolean fIsPackExpansion; + private ICPPEvaluation fEvaluation; @Override public CPPASTInitializerList copy() { return copy(CopyStyle.withoutLocations); } - @Override - public ICPPInitClauseEvaluation getEvaluation() { - // mstodo Auto-generated method stub - return null; - } @Override public CPPASTInitializerList copy(CopyStyle style) { @@ -62,10 +61,10 @@ public class CPPASTInitializerList extends ASTNode implements ICPPASTInitializer } @Override - public IASTInitializerClause[] getClauses() { + public ICPPASTInitializerClause[] getClauses() { if (initializers == null) - return IASTExpression.EMPTY_EXPRESSION_ARRAY; - initializers = ArrayUtil.trimAt(IASTInitializerClause.class, initializers, initializersPos); + return NO_CLAUSES; + initializers = ArrayUtil.trimAt(ICPPASTInitializerClause.class, initializers, initializersPos); return initializers; } @@ -95,7 +94,7 @@ public class CPPASTInitializerList extends ASTNode implements ICPPASTInitializer public void addClause(IASTInitializerClause d) { assertNotFrozen(); if (d != null) { - initializers = ArrayUtil.appendAt( IASTInitializerClause.class, initializers, ++initializersPos, d ); + initializers = ArrayUtil.appendAt(ICPPASTInitializerClause.class, initializers, ++initializersPos, (ICPPASTInitializerClause) d); d.setParent(this); d.setPropertyInParent(NESTED_INITIALIZER); } @@ -154,9 +153,25 @@ public class CPPASTInitializerList extends ASTNode implements ICPPASTInitializer if (child == initializers[i]) { other.setPropertyInParent(child.getPropertyInParent()); other.setParent(child.getParent()); - initializers[i] = (IASTInitializerClause) other; + initializers[i] = (ICPPASTInitializerClause) other; } } } } + + @Override + public ICPPEvaluation getEvaluation() { + if (fEvaluation == null) + fEvaluation= createEvaluation(); + return fEvaluation; + } + + private ICPPEvaluation createEvaluation() { + final ICPPASTInitializerClause[] clauses = getClauses(); + ICPPEvaluation[] evals= new ICPPEvaluation[clauses.length]; + for (int i = 0; i < evals.length; i++) { + evals[i]= clauses[i].getEvaluation(); + } + return new EvalInitList(evals); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLambdaExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLambdaExpression.java index b0e7931abe9..1c6fd852b18 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLambdaExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLambdaExpression.java @@ -10,6 +10,8 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; +import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; + import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; import org.eclipse.cdt.core.dom.ast.IASTImplicitName; @@ -19,6 +21,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; +import org.eclipse.cdt.internal.core.dom.parser.Value; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; /** * Implementation for lambda expressions. @@ -32,18 +36,14 @@ public class CPPASTLambdaExpression extends ASTNode implements ICPPASTLambdaExpr private IASTCompoundStatement fBody; - private CPPClosureType fClosureType; private IASTImplicitName fClosureTypeName; private IASTImplicitName fImplicitFunctionCallName; + private ICPPEvaluation fEvaluation; + public CPPASTLambdaExpression() { fCaptureDefault= CaptureDefault.UNSPECIFIED; } - @Override - public ICPPInitClauseEvaluation getEvaluation() { - // mstodo Auto-generated method stub - return null; - } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IASTExpression#copy() @@ -205,12 +205,17 @@ public class CPPASTLambdaExpression extends ASTNode implements ICPPASTLambdaExpr fDeclarator= dtor; } + @Override + public ICPPEvaluation getEvaluation() { + if (fEvaluation == null) { + fEvaluation= new EvalFixed(new CPPClosureType(this), PRVALUE, Value.UNKNOWN); + } + return fEvaluation; + } + @Override public CPPClosureType getExpressionType() { - if (fClosureType == null) - fClosureType= new CPPClosureType(this); - - return fClosureType; + return (CPPClosureType) getEvaluation().getTypeOrFunctionSet(this); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLiteralExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLiteralExpression.java index 6f068de4f79..a7a6fa62397 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLiteralExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLiteralExpression.java @@ -11,38 +11,41 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; +import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; +import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; + import org.eclipse.cdt.core.dom.ast.ASTVisitor; -import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression; import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IScope; -import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLiteralExpression; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; -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.semantics.CPPVisitor; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; +import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator; +import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator.EvalException; /** * Represents a C++ literal. */ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralExpression { + private static final EvalFixed EVAL_TRUE = new EvalFixed(CPPBasicType.BOOLEAN, PRVALUE, Value.create(1)); + private static final EvalFixed EVAL_FALSE = new EvalFixed(CPPBasicType.BOOLEAN, PRVALUE, Value.create(0)); + private static final EvalFixed EVAL_NULL_PTR = new EvalFixed(CPPBasicType.NULL_PTR, PRVALUE, Value.create(0)); + public static final CPPASTLiteralExpression INT_ZERO = new CPPASTLiteralExpression(lk_integer_constant, new char[] {'0'}); private int kind; private char[] value = CharArrayUtils.EMPTY; + private ICPPEvaluation fEvaluation; public CPPASTLiteralExpression() { } - @Override - public ICPPInitClauseEvaluation getEvaluation() { - // mstodo Auto-generated method stub - return null; - } public CPPASTLiteralExpression(int kind, char[] value) { this.kind = kind; @@ -111,46 +114,6 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx return true; } - @Override - public IType getExpressionType() { - switch (getKind()) { - case lk_this: { - IScope scope = CPPVisitor.getContainingScope(this); - IType type= CPPVisitor.getImpliedObjectType(scope); - if (type == null) { - return new ProblemType(ISemanticProblem.TYPE_UNRESOLVED_NAME); - } - return new CPPPointerType(type); - } - case lk_true: - case lk_false: - return CPPBasicType.BOOLEAN; - case lk_char_constant: - return new CPPBasicType(getCharType(), 0, this); - case lk_float_constant: - return classifyTypeOfFloatLiteral(); - case lk_integer_constant: - return classifyTypeOfIntLiteral(); - case lk_string_literal: - IType type = new CPPBasicType(getCharType(), 0, this); - type = new CPPQualifierType(type, true, false); - return new CPPArrayType(type, getStringLiteralSize()); - case lk_nullptr: - return CPPBasicType.NULL_PTR; - } - return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); - } - - @Override - public boolean isLValue() { - return getKind() == IASTLiteralExpression.lk_string_literal; - } - - @Override - public ValueCategory getValueCategory() { - return isLValue() ? ValueCategory.LVALUE : ValueCategory.PRVALUE; - } - private IValue getStringLiteralSize() { char[] value= getValue(); int length= value.length-1; @@ -261,4 +224,74 @@ public class CPPASTLiteralExpression extends ASTNode implements ICPPASTLiteralEx public CPPASTLiteralExpression(int kind, String value) { this(kind, value.toCharArray()); } + + @Override + public ICPPEvaluation getEvaluation() { + if (fEvaluation == null) + fEvaluation= createEvaluation(); + return fEvaluation; + } + + private ICPPEvaluation createEvaluation() { + switch (kind) { + case lk_this: { + IScope scope = CPPVisitor.getContainingScope(this); + IType type= CPPVisitor.getImpliedObjectType(scope); + if (type == null) + return EvalFixed.INCOMPLETE; + return new EvalFixed(new CPPPointerType(type), PRVALUE, Value.UNKNOWN); + } + case lk_true: + return EVAL_TRUE; + case lk_false: + return EVAL_FALSE; + case lk_char_constant: + return new EvalFixed(new CPPBasicType(getCharType(), 0, this), PRVALUE, createCharValue()); + case lk_float_constant: + return new EvalFixed(classifyTypeOfFloatLiteral(), PRVALUE, Value.UNKNOWN); + case lk_integer_constant: + return new EvalFixed(classifyTypeOfIntLiteral(),PRVALUE, createIntValue()); + case lk_string_literal: + IType type = new CPPBasicType(getCharType(), 0, this); + type = new CPPQualifierType(type, true, false); + return new EvalFixed(new CPPArrayType(type, getStringLiteralSize()), LVALUE, Value.UNKNOWN); + case lk_nullptr: + return EVAL_NULL_PTR; + } + return EvalFixed.INCOMPLETE; + } + + private IValue createCharValue() { + try { + final char[] image= getValue(); + if (image.length > 1 && image[0] == 'L') + return Value.create(ExpressionEvaluator.getChar(image, 2)); + return Value.create(ExpressionEvaluator.getChar(image, 1)); + } catch (EvalException e1) { + return Value.UNKNOWN; + } + } + + private IValue createIntValue() { + try { + return Value.create(ExpressionEvaluator.getNumber(getValue())); + } catch (EvalException e1) { + return Value.UNKNOWN; + } + } + + @Override + public IType getExpressionType() { + return getEvaluation().getTypeOrFunctionSet(this); + } + + @Override + public boolean isLValue() { + return getValueCategory() == LVALUE; + } + + @Override + public ValueCategory getValueCategory() { + return getKind() == lk_string_literal ? LVALUE : PRVALUE; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java index 64fc03339cc..5e91fcc7148 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTNewExpression.java @@ -34,9 +34,11 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTQueries; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; +import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.c.CASTExpressionList; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; import org.eclipse.core.runtime.Assert; @@ -49,6 +51,7 @@ public class CPPASTNewExpression extends ASTNode implements ICPPASTNewExpression private boolean isNewTypeId; private IASTExpression[] cachedArraySizes; + private ICPPEvaluation fEvaluation; public CPPASTNewExpression() { } @@ -58,11 +61,6 @@ public class CPPASTNewExpression extends ASTNode implements ICPPASTNewExpression setTypeId(typeId); setInitializer(initializer); } - @Override - public ICPPInitClauseEvaluation getEvaluation() { - // mstodo Auto-generated method stub - return null; - } @Override public CPPASTNewExpression copy() { @@ -248,13 +246,21 @@ public class CPPASTNewExpression extends ASTNode implements ICPPASTNewExpression } } + @Override + public ICPPEvaluation getEvaluation() { + if (fEvaluation == null) { + IType t= CPPVisitor.createType(getTypeId()); + if (t instanceof IArrayType) { + t= ((IArrayType) t).getType(); + } + fEvaluation= new EvalFixed(new CPPPointerType(t), PRVALUE, Value.UNKNOWN); + } + return fEvaluation; + } + @Override public IType getExpressionType() { - IType t= CPPVisitor.createType(getTypeId()); - if (t instanceof IArrayType) { - t= ((IArrayType) t).getType(); - } - return new CPPPointerType(t); + return getEvaluation().getTypeOrFunctionSet(this); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTPackExpansionExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTPackExpansionExpression.java index 6f5a159fa17..9b115f02e50 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTPackExpansionExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTPackExpansionExpression.java @@ -10,22 +10,25 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; +import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; + import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTNode; -import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPackExpansionExpression; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; -import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; +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.semantics.EvalFixed; /** * Implementation of pack expansion expression. */ public class CPPASTPackExpansionExpression extends ASTNode implements ICPPASTPackExpansionExpression, IASTAmbiguityParent { - private IASTExpression fPattern; + private ICPPEvaluation fEvaluation; public CPPASTPackExpansionExpression(IASTExpression pattern) { setPattern(pattern); @@ -41,11 +44,6 @@ public class CPPASTPackExpansionExpression extends ASTNode implements ICPPASTPac pattern.setPropertyInParent(ICPPASTPackExpansionExpression.PATTERN); } } - @Override - public ICPPInitClauseEvaluation getEvaluation() { - // mstodo Auto-generated method stub - return null; - } @Override public IASTExpression getPattern() { @@ -67,13 +65,23 @@ public class CPPASTPackExpansionExpression extends ASTNode implements ICPPASTPac return copy; } + @Override + public ICPPEvaluation getEvaluation() { + if (fEvaluation == null) { + IType type = fPattern.getExpressionType(); + if (type == null) { + type= ProblemType.UNKNOWN_FOR_EXPRESSION; + } else { + type= new CPPParameterPackType(type); + } + fEvaluation= new EvalFixed(type, PRVALUE, Value.UNKNOWN); + } + return fEvaluation; + } + @Override public IType getExpressionType() { - final IType type = fPattern.getExpressionType(); - if (type == null) - return new ProblemBinding(this, IProblemBinding.SEMANTIC_INVALID_TYPE, getRawSignatureChars()); - - return new CPPParameterPackType(type); + return getEvaluation().getTypeOrFunctionSet(this); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTProblemExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTProblemExpression.java index 1fdd18d82d2..1c581ce9533 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTProblemExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTProblemExpression.java @@ -11,13 +11,14 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; +import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; + import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTProblem; import org.eclipse.cdt.core.dom.ast.IASTProblemExpression; -import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; -import org.eclipse.cdt.internal.core.dom.parser.ProblemType; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; public class CPPASTProblemExpression extends CPPASTProblemOwner implements IASTProblemExpression, ICPPASTExpression { @@ -33,12 +34,6 @@ public class CPPASTProblemExpression extends CPPASTProblemOwner implements IASTP public CPPASTProblemExpression copy() { return copy(CopyStyle.withoutLocations); } - @Override - public ICPPInitClauseEvaluation getEvaluation() { - // mstodo Auto-generated method stub - return null; - } - @Override public CPPASTProblemExpression copy(CopyStyle style) { CPPASTProblemExpression copy = new CPPASTProblemExpression(); @@ -64,19 +59,24 @@ public class CPPASTProblemExpression extends CPPASTProblemOwner implements IASTP } return true; } - + + @Override + public ICPPEvaluation getEvaluation() { + return EvalFixed.INCOMPLETE; + } + @Override public IType getExpressionType() { - return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); + return getEvaluation().getTypeOrFunctionSet(this); } @Override public boolean isLValue() { - return false; + return getValueCategory() == LVALUE; } @Override public ValueCategory getValueCategory() { - return ValueCategory.PRVALUE; + return getEvaluation().getValueCategory(this); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTRangeBasedForStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTRangeBasedForStatement.java index 26c943b68c5..dec522ab979 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTRangeBasedForStatement.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTRangeBasedForStatement.java @@ -125,7 +125,7 @@ public class CPPASTRangeBasedForStatement extends ASTAttributeOwner fImplicitNames= IASTImplicitName.EMPTY_NAME_ARRAY; } else if (type instanceof ICPPClassType) { ICPPClassType ct= (ICPPClassType) type; - if (CPPSemantics.findBindings(ct.getCompositeScope(), CPPVisitor.BEGIN_STR, true).length > 0) { + if (CPPSemantics.findBindings(ct.getCompositeScope(), CPPVisitor.BEGIN, true, this).length > 0) { CPPASTName name = new CPPASTName(CPPVisitor.BEGIN); name.setOffset(position.getOffset()); CPPASTFieldReference fieldRef = new CPPASTFieldReference(name, forInitExpr.copy()); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleTypeConstructorExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleTypeConstructorExpression.java index 4d7d6860789..1d0575f6d22 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleTypeConstructorExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSimpleTypeConstructorExpression.java @@ -11,26 +11,28 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; -import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType; - import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTInitializer; +import org.eclipse.cdt.core.dom.ast.IASTInitializerClause; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeConstructorExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId; public class CPPASTSimpleTypeConstructorExpression extends ASTNode implements ICPPASTSimpleTypeConstructorExpression { private ICPPASTDeclSpecifier fDeclSpec; private IASTInitializer fInitializer; - private IType fType; + private ICPPEvaluation fEvaluation; public CPPASTSimpleTypeConstructorExpression() { } @@ -39,11 +41,6 @@ public class CPPASTSimpleTypeConstructorExpression extends ASTNode implements setDeclSpecifier(declSpec); setInitializer(init); } - @Override - public ICPPInitClauseEvaluation getEvaluation() { - // mstodo Auto-generated method stub - return null; - } @Override public CPPASTSimpleTypeConstructorExpression copy() { @@ -91,13 +88,36 @@ public class CPPASTSimpleTypeConstructorExpression extends ASTNode implements initializer.setPropertyInParent(INITIALIZER); } } + + @Override + public ICPPEvaluation getEvaluation() { + if (fEvaluation == null) { + final IType type = CPPVisitor.createType(fDeclSpec); + ICPPEvaluation[] args= null; + if (fInitializer instanceof ICPPASTConstructorInitializer) { + IASTInitializerClause[] a = ((ICPPASTConstructorInitializer) fInitializer).getArguments(); + args= new ICPPEvaluation[a.length]; + for (int i = 0; i < a.length; i++) { + args[i]= ((ICPPASTInitializerClause) a[i]).getEvaluation(); + } + fEvaluation= new EvalTypeId(type, args); + } else if (fInitializer instanceof ICPPASTInitializerList) { + fEvaluation= new EvalTypeId(type, ((ICPPASTInitializerList) fInitializer).getEvaluation()); + } else { + fEvaluation= EvalFixed.INCOMPLETE; + } + } + return fEvaluation; + } @Override public IType getExpressionType() { - if (fType == null) { - fType= prvalueType(CPPVisitor.createType(fDeclSpec)); - } - return fType; + return getEvaluation().getTypeOrFunctionSet(this); + } + + @Override + public ValueCategory getValueCategory() { + return getEvaluation().getValueCategory(this); } @Override @@ -105,11 +125,6 @@ public class CPPASTSimpleTypeConstructorExpression extends ASTNode implements return false; } - @Override - public ValueCategory getValueCategory() { - return PRVALUE; - } - @Override public boolean accept(ASTVisitor action) { if (action.shouldVisitExpressions) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateIDAmbiguity.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateIDAmbiguity.java index 6ae39e11ae9..959973e4038 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateIDAmbiguity.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateIDAmbiguity.java @@ -23,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IProblemBinding; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate; @@ -40,13 +41,13 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.NameOrTemplateIDVariants.Var /** * Models expression variants for the ambiguity of a template id. */ -public class CPPASTTemplateIDAmbiguity extends ASTAmbiguousNode implements IASTAmbiguousExpression { - +public class CPPASTTemplateIDAmbiguity extends ASTAmbiguousNode implements IASTAmbiguousExpression, + ICPPASTExpression { private BinaryOperator fLastOperator; private IASTInitializerClause fLastExpression; private final BranchPoint fVariants; private IASTNode[] fNodes; - private AbstractGNUSourceCodeParser fParser; + private final AbstractGNUSourceCodeParser fParser; public CPPASTTemplateIDAmbiguity(AbstractGNUSourceCodeParser parser, BinaryOperator lastOperator, IASTInitializerClause expr, BranchPoint variants) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTranslationUnit.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTranslationUnit.java index 047dc89a429..801741e72df 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTranslationUnit.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTranslationUnit.java @@ -13,6 +13,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; @@ -175,8 +176,8 @@ public class CPPASTTranslationUnit extends ASTTranslationUnit implements ICPPAST } // bug 262719: class types from the index have to be mapped back to the AST. - public ICPPClassType mapToAST(ICPPClassType binding) { - return fScopeMapper.mapToAST(binding); + public ICPPClassType mapToAST(ICPPClassType binding, IASTNode point) { + return fScopeMapper.mapToAST(binding, point); } /** diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdExpression.java index c20ee7a1230..934fd0f8d29 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdExpression.java @@ -12,18 +12,21 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; -import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTTypeId; +import org.eclipse.cdt.core.dom.ast.IProblemType; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeIdExpression; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUnaryTypeID; public class CPPASTTypeIdExpression extends ASTNode implements ICPPASTTypeIdExpression { private int op; private IASTTypeId typeId; + private ICPPEvaluation fEvaluation; public CPPASTTypeIdExpression() { } @@ -32,11 +35,6 @@ public class CPPASTTypeIdExpression extends ASTNode implements ICPPASTTypeIdExpr this.op = op; setTypeId(typeId); } - @Override - public ICPPInitClauseEvaluation getEvaluation() { - // mstodo Auto-generated method stub - return null; - } @Override public CPPASTTypeIdExpression copy() { @@ -103,43 +101,30 @@ public class CPPASTTypeIdExpression extends ASTNode implements ICPPASTTypeIdExpr } @Override - public IType getExpressionType() { - switch (getOperator()) { - case op_sizeof: - case op_alignof: - return CPPVisitor.get_SIZE_T(this); - case op_typeid: - return CPPVisitor.get_type_info(this); - case op_has_nothrow_copy: - case op_has_nothrow_constructor: - case op_has_trivial_assign: - case op_has_trivial_constructor: - case op_has_trivial_copy: - case op_has_trivial_destructor: - case op_has_virtual_destructor: - case op_is_abstract: - case op_is_class: - case op_is_empty: - case op_is_enum: - case op_is_pod: - case op_is_polymorphic: - case op_is_union: - return CPPBasicType.BOOLEAN; + public ICPPEvaluation getEvaluation() { + if (fEvaluation == null) { + IType type= CPPVisitor.createType(typeId); + if (type == null || type instanceof IProblemType) { + fEvaluation= EvalFixed.INCOMPLETE; + } else { + fEvaluation= new EvalUnaryTypeID(op, type); + } } - return CPPVisitor.createType(getTypeId()); + return fEvaluation; + } + + @Override + public IType getExpressionType() { + return getEvaluation().getTypeOrFunctionSet(this); + } + + @Override + public ValueCategory getValueCategory() { + return getEvaluation().getValueCategory(this); } @Override public boolean isLValue() { - switch (getOperator()) { - case op_typeid: - return true; - } - return false; - } - - @Override - public ValueCategory getValueCategory() { - return isLValue() ? LVALUE : PRVALUE; + return getValueCategory() == LVALUE; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdInitializerExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdInitializerExpression.java index 842b9c202da..b4c7e7e523d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdInitializerExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTypeIdInitializerExpression.java @@ -10,32 +10,31 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType; - import org.eclipse.cdt.core.dom.ast.IASTInitializer; import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IASTTypeIdInitializerExpression; +import org.eclipse.cdt.core.dom.ast.IProblemType; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause; import org.eclipse.cdt.internal.core.dom.parser.ASTTypeIdInitializerExpression; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId; /** * C++ variant of type id initializer expression. type-id { initializer } */ public class CPPASTTypeIdInitializerExpression extends ASTTypeIdInitializerExpression implements ICPPASTExpression { + private ICPPEvaluation fEvaluation; + private CPPASTTypeIdInitializerExpression() { } public CPPASTTypeIdInitializerExpression(IASTTypeId typeId, IASTInitializer initializer) { super(typeId, initializer); } - @Override - public ICPPInitClauseEvaluation getEvaluation() { - // mstodo Auto-generated method stub - return null; - } @Override public IASTTypeIdInitializerExpression copy() { @@ -50,8 +49,32 @@ public class CPPASTTypeIdInitializerExpression extends ASTTypeIdInitializerExpre } @Override + public ICPPEvaluation getEvaluation() { + if (fEvaluation == null) + fEvaluation= computeEvaluation(); + + return fEvaluation; + } + + private ICPPEvaluation computeEvaluation() { + final IASTInitializer initializer = getInitializer(); + if (!(initializer instanceof ICPPASTInitializerClause)) + return EvalFixed.INCOMPLETE; + + IType type= CPPVisitor.createType(getTypeId()); + if (type == null || type instanceof IProblemType) + return EvalFixed.INCOMPLETE; + + return new EvalTypeId(type, ((ICPPASTInitializerClause) initializer).getEvaluation()); + } + + @Override public IType getExpressionType() { - final IASTTypeId typeId = getTypeId(); - return prvalueType(CPPVisitor.createType(typeId.getAbstractDeclarator())); + return getEvaluation().getTypeOrFunctionSet(this); + } + + @Override + public ValueCategory getValueCategory() { + return getEvaluation().getValueCategory(this); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java index fb3d94f11a6..290015f4052 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTUnaryExpression.java @@ -15,12 +15,6 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueTypeWithResolvedTypedefs; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromFunctionCall; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCategoryFromFunctionCall; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getUltimateTypeUptoPointers; import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.DOMException; @@ -32,42 +26,37 @@ import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IFunction; -import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IProblemBinding; -import org.eclipse.cdt.core.dom.ast.ISemanticProblem; +import org.eclipse.cdt.core.dom.ast.IProblemType; import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; -import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; -import org.eclipse.cdt.internal.core.dom.parser.ProblemType; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; +import org.eclipse.cdt.internal.core.dom.parser.Value; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUnary; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.FunctionSetType; /** * Unary expression in c++ */ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpression, IASTAmbiguityParent { - private int op; - private IASTExpression operand; - - private ICPPFunction overload = UNINITIALIZED_FUNCTION; - private IASTImplicitName[] implicitNames = null; + private int fOperator; + private ICPPASTExpression fOperand; + private IASTImplicitName[] fImplicitNames = null; + private ICPPEvaluation fEvaluation; public CPPASTUnaryExpression() { } - @Override - public ICPPInitClauseEvaluation getEvaluation() { - // mstodo Auto-generated method stub - return null; - } public CPPASTUnaryExpression(int operator, IASTExpression operand) { - op = operator; + fOperator = operator; setOperand(operand); } @@ -78,31 +67,35 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres @Override public CPPASTUnaryExpression copy(CopyStyle style) { - CPPASTUnaryExpression copy = - new CPPASTUnaryExpression(op, operand == null ? null : operand.copy(style)); - return copy(copy, style); + CPPASTUnaryExpression copy = new CPPASTUnaryExpression(fOperator, fOperand == null ? null + : fOperand.copy(style)); + copy.setOffsetAndLength(this); + if (style == CopyStyle.withLocations) { + copy.setCopyLocation(this); + } + return copy; } @Override public int getOperator() { - return op; + return fOperator; } @Override public void setOperator(int operator) { assertNotFrozen(); - op = operator; + fOperator = operator; } @Override public IASTExpression getOperand() { - return operand; + return fOperand; } @Override public void setOperand(IASTExpression expression) { assertNotFrozen(); - operand = expression; + fOperand = (ICPPASTExpression) expression; if (expression != null) { expression.setParent(this); expression.setPropertyInParent(OPERAND); @@ -110,7 +103,7 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres } public boolean isPostfixOperator() { - return op == op_postFixDecr || op == op_postFixIncr; + return fOperator == op_postFixDecr || fOperator == op_postFixIncr; } /** @@ -118,20 +111,20 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres */ @Override public IASTImplicitName[] getImplicitNames() { - if (implicitNames == null) { + if (fImplicitNames == null) { ICPPFunction overload = getOverload(); if (overload == null || overload instanceof CPPImplicitFunction) { - implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY; + fImplicitNames = IASTImplicitName.EMPTY_NAME_ARRAY; } else { CPPASTImplicitName operatorName = new CPPASTImplicitName(overload.getNameCharArray(), this); operatorName.setOperator(true); operatorName.setBinding(overload); - operatorName.computeOperatorOffsets(operand, isPostfixOperator()); - implicitNames = new IASTImplicitName[] { operatorName }; + operatorName.computeOperatorOffsets(fOperand, isPostfixOperator()); + fImplicitNames = new IASTImplicitName[] { operatorName }; } } - return implicitNames; + return fImplicitNames; } @Override @@ -153,7 +146,7 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres } } - if (operand != null && !operand.accept(action)) + if (fOperand != null && !fOperand.accept(action)) return false; if (isPostfix && action.shouldVisitImplicitNames) { @@ -175,27 +168,18 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres @Override public void replace(IASTNode child, IASTNode other) { - if (child == operand) { + if (child == fOperand) { other.setPropertyInParent(child.getPropertyInParent()); other.setParent(child.getParent()); - operand = (IASTExpression) other; + fOperand = (ICPPASTExpression) other; } } - @Override - public ICPPFunction getOverload() { - if (overload != UNINITIALIZED_FUNCTION) - return overload; - - overload = CPPSemantics.findOverloadedOperator(this); - if (overload != null && op == op_amper && computePointerToMemberType() instanceof CPPPointerToMemberType) - overload = null; - - return overload; - } - private IType computePointerToMemberType() { - IASTNode child= operand; + if (fOperator != op_amper) + return null; + + IASTNode child= fOperand; boolean inParenthesis= false; while (child instanceof IASTUnaryExpression && ((IASTUnaryExpression) child).getOperator() == IASTUnaryExpression.op_bracketedPrimary) { child= ((IASTUnaryExpression) child).getOperand(); @@ -203,22 +187,21 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres } if (child instanceof IASTIdExpression) { IASTName name= ((IASTIdExpression) child).getName(); - IBinding b= name.resolveBinding(); - if (b instanceof ICPPMember) { - ICPPMember member= (ICPPMember) b; - try { - if (name instanceof ICPPASTQualifiedName) { - if (!member.isStatic()) { // so if the member is static it will fall through - overload= null; + if (name instanceof ICPPASTQualifiedName) { + IBinding b= name.resolveBinding(); + if (b instanceof ICPPMember) { + ICPPMember member= (ICPPMember) b; + if (!member.isStatic()) { + try { if (!inParenthesis) { return new CPPPointerToMemberType(member.getType(), member.getClassOwner(), false, false, false); } else if (member instanceof IFunction) { - return new ProblemBinding(operand, IProblemBinding.SEMANTIC_INVALID_TYPE, operand.getRawSignature().toCharArray()); + return new ProblemBinding(fOperand, IProblemBinding.SEMANTIC_INVALID_TYPE, fOperand.getRawSignature().toCharArray()); } + } catch (DOMException e) { + return e.getProblem(); } } - } catch (DOMException e) { - return e.getProblem(); } } } @@ -226,113 +209,71 @@ public class CPPASTUnaryExpression extends ASTNode implements ICPPASTUnaryExpres } @Override - public IType getExpressionType() { - final int op= getOperator(); - switch (op) { - case op_sizeof: - case op_sizeofParameterPack: - return CPPVisitor.get_SIZE_T(this); - case op_typeid: - return CPPVisitor.get_type_info(this); - case op_bracketedPrimary: - return getOperand().getExpressionType(); - case op_throw: - return CPPSemantics.VOID_TYPE; - } - - final IASTExpression operand = getOperand(); - - if (op == op_amper) { // check for pointer to member - IType ptm = computePointerToMemberType(); - if (ptm != null) - return ptm; - - ICPPFunction overload = getOverload(); - if (overload != null) - return typeFromFunctionCall(overload); - - return new CPPPointerType(operand.getExpressionType()); - } - - ICPPFunction overload = getOverload(); - if (overload != null) - return typeFromFunctionCall(overload); - - if (op == op_star) { - IType type= operand.getExpressionType(); - type = prvalueTypeWithResolvedTypedefs(type); - if (type instanceof IPointerType) { - type= ((ITypeContainer) type).getType(); - return glvalueType(type); - } - if (type instanceof ISemanticProblem) { - return type; - } - type= getUltimateTypeUptoPointers(type); - if (type instanceof ICPPUnknownType) { - // mstodo Type of unknown - return CPPUnknownClass.createUnnamedInstance(); - } - return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); - } - - IType typeOfOperand= operand.getExpressionType(); - - switch (op) { - case op_not: - return CPPBasicType.BOOLEAN; - case op_postFixDecr: - case op_postFixIncr: - typeOfOperand= prvalueType(typeOfOperand); - break; - case op_minus: - case op_plus: - case op_tilde: - IType t= CPPArithmeticConversion.promoteCppType(prvalueType(typeOfOperand)); - if (t != null) { - return t; - } - break; - } - - if (typeOfOperand instanceof CPPBasicType) { - ((CPPBasicType) typeOfOperand).setFromExpression(this); - } - return typeOfOperand; - } - - @Override - public ValueCategory getValueCategory() { - final int op= getOperator(); - switch (op) { - case op_typeid: - return LVALUE; - case op_sizeof: - case op_sizeofParameterPack: - return PRVALUE; - case op_bracketedPrimary: - return (operand).getValueCategory(); - } - - if (op == op_amper && computePointerToMemberType() != null) { - return PRVALUE; - } - - ICPPFunction overload = getOverload(); - if (overload != null) - return valueCategoryFromFunctionCall(overload); - - switch(op) { - case op_star: - case op_prefixDecr: - case op_prefixIncr: - return LVALUE; - } - return PRVALUE; + public ICPPFunction getOverload() { + ICPPEvaluation eval = getEvaluation(); + if (eval instanceof EvalUnary) + return ((EvalUnary) eval).getOverload(this); + return null; } + @Override + public ICPPEvaluation getEvaluation() { + if (fEvaluation == null) { + if (fOperand == null) + return EvalFixed.INCOMPLETE; + + final ICPPEvaluation arg = fOperand.getEvaluation(); + if (fOperator == op_bracketedPrimary) { + fEvaluation= arg; + } else if (arg.isFunctionSet() && fOperator == op_amper) { + return arg; + } else { + IType type= computePointerToMemberType(); + if (type != null) { + if (type instanceof IProblemType) + return EvalFixed.INCOMPLETE; + fEvaluation= new EvalFixed(type, PRVALUE, Value.UNKNOWN); + } else { + fEvaluation= new EvalUnary(fOperator, fOperand.getEvaluation()); + } + } + } + return fEvaluation; + } + + @Override + public IType getExpressionType() { + IType type= getEvaluation().getTypeOrFunctionSet(this); + if (type instanceof FunctionSetType) { + type= fOperand.getExpressionType(); + if (fOperator == op_amper) { + if (fOperand instanceof IASTIdExpression) { + IASTIdExpression idExpr = (IASTIdExpression) fOperand; + final IASTName name = idExpr.getName(); + if (name instanceof ICPPASTQualifiedName) { + IBinding binding = name.resolveBinding(); + if (binding instanceof ICPPMethod) { + ICPPMethod method = (ICPPMethod) binding; + if (!method.isStatic()) { + return new CPPPointerToMemberType(method.getType(), method.getClassOwner(), false, false, false); + } + } + } + } + return new CPPPointerType(type); + } + } + return type; + } + + @Override + public ValueCategory getValueCategory() { + return getEvaluation().getValueCategory(this); + } + @Override public boolean isLValue() { return getValueCategory() == LVALUE; } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPArrayType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPArrayType.java index 52d9d8e6892..f38210cc2fb 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPArrayType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPArrayType.java @@ -110,7 +110,7 @@ public class CPPArrayType implements IArrayType, ITypeContainer, ISerializableTy @Override public void marshal(ITypeMarshalBuffer buffer) throws CoreException { - final byte firstByte = ITypeMarshalBuffer.ARRAY; + final byte firstByte = ITypeMarshalBuffer.ARRAY_TYPE; IValue val= getSize(); if (val == null) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java index 363a9138ce3..d08793f4d25 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java @@ -226,10 +226,10 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope { } @Override - public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, - IIndexFileSet fileSet, boolean checkPointOfDecl) { - char[] c = name.getLookupKey(); - + public IBinding[] getBindings(ScopeLookupData lookup) { + char[] c = lookup.getLookupKey(); + final boolean prefixLookup= lookup.isPrefixLookup(); + ICPPASTCompositeTypeSpecifier compType = (ICPPASTCompositeTypeSpecifier) getPhysicalNode(); IASTName compName = compType.getName().getLastName(); if (compName instanceof ICPPASTTemplateId) { @@ -238,16 +238,16 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope { IBinding[] result = null; if ((!prefixLookup && CharArrayUtils.equals(c, compName.getLookupKey())) || (prefixLookup && ContentAssistMatcherFactory.getInstance().match(c, compName.getLookupKey()))) { - if (shallReturnConstructors(name, prefixLookup)) { - result = ArrayUtil.addAll(IBinding.class, result, getConstructors(name, resolve)); + final IASTName lookupName = lookup.getLookupName(); + if (shallReturnConstructors(lookupName, prefixLookup)) { + result = ArrayUtil.addAll(IBinding.class, result, getConstructors(lookupName, lookup.isResolve())); } //9.2 ... The class-name is also inserted into the scope of the class itself result = ArrayUtil.append(IBinding.class, result, compName.resolveBinding()); if (!prefixLookup) return ArrayUtil.trim(IBinding.class, result); } - result = ArrayUtil.addAll(IBinding.class, result, - super.getBindings(name, resolve, prefixLookup, fileSet, checkPointOfDecl)); + result = ArrayUtil.addAll(IBinding.class, result, super.getBindings(lookup)); return ArrayUtil.trim(IBinding.class, result); } @@ -325,12 +325,12 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope { } public static boolean shallReturnConstructors(IASTName name, boolean isPrefixLookup) { + if (name == null) + return false; + if (!isPrefixLookup) return CPPVisitor.isConstructorDeclaration(name); - if (name.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) - return false; - IASTNode node = name.getParent(); if (node instanceof ICPPASTTemplateId) return false; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java index 076e0e19155..4a1c7c34e7f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java @@ -12,6 +12,9 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; +import java.util.HashSet; +import java.util.Set; + import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; @@ -33,7 +36,9 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.ObjectMap; +import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; +import org.eclipse.core.runtime.Assert; /** * Specialization of a class. @@ -41,8 +46,16 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; public class CPPClassSpecialization extends CPPSpecialization implements ICPPClassSpecialization, ICPPInternalClassTypeMixinHost { + public final static class RecursionResolvingBinding extends ProblemBinding { + public RecursionResolvingBinding(IASTNode node, char[] arg) { + super(node, IProblemBinding.SEMANTIC_RECURSION_IN_LOOKUP, arg); + Assert.isTrue(CPPASTNameBase.sAllowRecursionBindings, getMessage()); + } + } + private ICPPClassSpecializationScope specScope; private ObjectMap specializationMap= ObjectMap.EMPTY_MAP; + private final ThreadLocal> fInProgress= new ThreadLocal>(); public CPPClassSpecialization(ICPPClassType specialized, IBinding owner, ICPPTemplateParameterMap argumentMap) { super(specialized, owner, argumentMap); @@ -55,14 +68,29 @@ public class CPPClassSpecialization extends CPPSpecialization } @Override - public IBinding specializeMember(IBinding original) { + public IBinding specializeMember(IBinding original) { + return specializeMember(original, null); + } + + @Override + public IBinding specializeMember(IBinding original, IASTNode point) { + Set set; synchronized(this) { IBinding result= (IBinding) specializationMap.get(original); if (result != null) return result; + + set= fInProgress.get(); + if (set == null) { + set= new HashSet(); + fInProgress.set(set); + } + if (!set.add(original)) + return new RecursionResolvingBinding(null, null); } - IBinding result= CPPTemplates.createSpecialization(this, original); + IBinding result= CPPTemplates.createSpecialization(this, original, point); + set.remove(original); synchronized(this) { IBinding concurrent= (IBinding) specializationMap.get(original); if (concurrent != null) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecializationSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecializationSpecialization.java index c638b8f0abb..443fc1218c8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecializationSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecializationSpecialization.java @@ -1,4 +1,4 @@ -/******************************************************************************* + /******************************************************************************* * Copyright (c) 2009, 2011 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 @@ -15,7 +15,6 @@ import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecializationSpecialization; @@ -34,11 +33,14 @@ public class CPPClassTemplatePartialSpecializationSpecialization extends CPPClas private ObjectMap instances = null; private ICPPDeferredClassInstance fDeferredInstance; - private ICPPClassTemplate fClassTemplate; + private final ICPPClassTemplate fClassTemplate; + private final ICPPTemplateArgument[] fArguments; - public CPPClassTemplatePartialSpecializationSpecialization(ICPPClassTemplatePartialSpecialization orig, ICPPClassTemplate template, ICPPTemplateParameterMap argumentMap) throws DOMException { + public CPPClassTemplatePartialSpecializationSpecialization(ICPPClassTemplatePartialSpecialization orig, ICPPTemplateParameterMap argumentMap, ICPPClassTemplate template, + ICPPTemplateArgument[] args) throws DOMException { super(orig, template.getOwner(), argumentMap); fClassTemplate= template; + fArguments= args; } @Override @@ -96,17 +98,7 @@ public class CPPClassTemplatePartialSpecializationSpecialization extends CPPClas @Override public ICPPTemplateArgument[] getTemplateArguments() { - ICPPTemplateArgument[] args = ((ICPPClassTemplatePartialSpecialization) getSpecializedBinding()).getTemplateArguments(); - try { - final IBinding owner = getOwner(); - if (owner instanceof ICPPClassSpecialization) { - return CPPTemplates.instantiateArguments(args, getTemplateParameterMap(), -1, - (ICPPClassSpecialization) owner); - } - return CPPTemplates.instantiateArguments(args, getTemplateParameterMap(), -1, null); - } catch (DOMException e) { - return args; - } + return fArguments; } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplateSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplateSpecialization.java index ca033dceb18..32e50325a8d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplateSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplateSpecialization.java @@ -14,6 +14,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; @@ -42,11 +43,12 @@ public class CPPClassTemplateSpecialization extends CPPClassSpecialization @Override public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() { if (fPartialSpecs == null) { + IASTNode point= null; // Instantiation of dependent expression may not work. ICPPClassTemplate origTemplate= (ICPPClassTemplate) getSpecializedBinding(); ICPPClassTemplatePartialSpecialization[] orig = origTemplate.getPartialSpecializations(); ICPPClassTemplatePartialSpecialization[] spec = new ICPPClassTemplatePartialSpecialization[orig.length]; for (int i = 0; i < orig.length; i++) { - spec[i]= (ICPPClassTemplatePartialSpecialization) specializeMember(orig[i]); + spec[i]= (ICPPClassTemplatePartialSpecialization) specializeMember(orig[i], point); } fPartialSpecs = spec; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java index 5f3e0c7c93d..128614a2610 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClosureType.java @@ -404,18 +404,27 @@ public class CPPClosureType extends PlatformObject implements ICPPClassType, ICP @Override public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup) { - if (name instanceof ICPPASTTemplateId) - return IBinding.EMPTY_BINDING_ARRAY; - - if (prefixLookup) - return getPrefixBindings(name.getSimpleID()); - return getBindings(name.getSimpleID()); + return getBindings(new ScopeLookupData(name, resolve, prefixLookup)); } + /** + * @deprecated Use {@link #getBindings(ScopeLookupData)} instead + */ + @Deprecated @Override public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet acceptLocalBindings) { - return getBindings(name, resolve, prefixLookup); + return getBindings(new ScopeLookupData(name, resolve, prefixLookup)); + } + + @Override + public IBinding[] getBindings(ScopeLookupData lookup) { + if (lookup.getLookupName() instanceof ICPPASTTemplateId) + return IBinding.EMPTY_BINDING_ARRAY; + + if (lookup.isPrefixLookup()) + return getPrefixBindings(lookup.getLookupKey()); + return getBindings(lookup.getLookupKey()); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorInstance.java index e3cba7d043a..552d57b7eb7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorInstance.java @@ -11,8 +11,10 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; +import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; /** @@ -21,7 +23,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; public class CPPConstructorInstance extends CPPMethodInstance implements ICPPConstructor { public CPPConstructorInstance(ICPPConstructor orig, ICPPClassType owner, - CPPTemplateParameterMap tpmap, ICPPTemplateArgument[] args) { - super(orig, owner, tpmap, args); + CPPTemplateParameterMap tpmap, ICPPTemplateArgument[] args, ICPPFunctionType type, IType[] exceptionSpec) { + super(orig, owner, tpmap, args, type, exceptionSpec); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorSpecialization.java index 5e746dc8145..d047475b478 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorSpecialization.java @@ -11,8 +11,10 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; +import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; /** @@ -22,7 +24,7 @@ public class CPPConstructorSpecialization extends CPPMethodSpecialization implements ICPPConstructor { public CPPConstructorSpecialization(ICPPConstructor orig, ICPPClassType owner, - ICPPTemplateParameterMap argMap) { - super(orig, owner, argMap); + ICPPTemplateParameterMap argMap, ICPPFunctionType type, IType[] exceptionSpecs) { + super(orig, owner, argMap, type, exceptionSpecs); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorTemplateSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorTemplateSpecialization.java index fa41772cb27..030f0843401 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorTemplateSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPConstructorTemplateSpecialization.java @@ -11,8 +11,10 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; +import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; /** @@ -22,7 +24,7 @@ public class CPPConstructorTemplateSpecialization extends CPPMethodTemplateSpeci implements ICPPConstructor { public CPPConstructorTemplateSpecialization(ICPPConstructor original, - ICPPClassType owner, ICPPTemplateParameterMap tpmap) { - super(original, owner, tpmap); + ICPPClassType owner, ICPPTemplateParameterMap tpmap, ICPPFunctionType type, IType[] exceptionSpecs) { + super(original, owner, tpmap, type, exceptionSpecs); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFieldSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFieldSpecialization.java index cdc92a2ed4e..929451e7eff 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFieldSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFieldSpecialization.java @@ -18,18 +18,19 @@ import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; -import org.eclipse.cdt.internal.core.dom.parser.IInternalVariable; -import org.eclipse.cdt.internal.core.dom.parser.Value; /** * Binding for a specialization of a field. */ -public class CPPFieldSpecialization extends CPPSpecialization implements ICPPField, IInternalVariable { +public class CPPFieldSpecialization extends CPPSpecialization implements ICPPField { private IType type = null; private IValue value= null; - public CPPFieldSpecialization( IBinding orig, ICPPClassType owner, ICPPTemplateParameterMap tpmap) { + public CPPFieldSpecialization(IBinding orig, ICPPClassType owner, ICPPTemplateParameterMap tpmap, + IType type, IValue value) { super(orig, owner, tpmap); + this.type= type; + this.value= value; } private ICPPField getField() { @@ -48,9 +49,6 @@ public class CPPFieldSpecialization extends CPPSpecialization implements ICPPFie @Override public IType getType() { - if (type == null) { - type= specializeType(getField().getType()); - } return type; } @@ -91,21 +89,6 @@ public class CPPFieldSpecialization extends CPPSpecialization implements ICPPFie @Override public IValue getInitialValue() { - return getInitialValue(Value.MAX_RECURSION_DEPTH); - } - - @Override - public IValue getInitialValue(int maxRecursionDepth) { - if (value == null) { - ICPPField field= getField(); - IValue v; - if (field instanceof IInternalVariable) { - v= ((IInternalVariable) field).getInitialValue(maxRecursionDepth); - } else { - v= getField().getInitialValue(); - } - value= specializeValue(v, maxRecursionDepth); - } return value; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java index ccbff2cd8ca..cd8d776018d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java @@ -59,6 +59,8 @@ import org.eclipse.core.runtime.PlatformObject; * Binding for c++ function */ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInternalFunction { + public static final ICPPFunction UNINITIALIZED_FUNCTION = new CPPFunction(null); + protected IASTDeclarator[] declarations; protected ICPPASTFunctionDeclarator definition; protected ICPPFunctionType type; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionInstance.java index 734cb5fc85a..d87f1996afe 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionInstance.java @@ -26,10 +26,10 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; * The instantiation of a function template. */ public class CPPFunctionInstance extends CPPFunctionSpecialization implements ICPPTemplateInstance { - private ICPPTemplateArgument[] fArguments; + private final ICPPTemplateArgument[] fArguments; - public CPPFunctionInstance(ICPPFunction orig, IBinding owner, CPPTemplateParameterMap argMap, ICPPTemplateArgument[] args) { - super(orig, owner, argMap); + public CPPFunctionInstance(ICPPFunction orig, IBinding owner, CPPTemplateParameterMap argMap, ICPPTemplateArgument[] args, ICPPFunctionType type, IType[] exceptionSpecs) { + super(orig, owner, argMap, type, exceptionSpecs); fArguments = args; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionSpecialization.java index 968a156ab8c..6fa49ac16f6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionSpecialization.java @@ -25,11 +25,9 @@ import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; @@ -41,26 +39,14 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; * also used as base class for function instances. */ public class CPPFunctionSpecialization extends CPPSpecialization implements ICPPFunction, ICPPInternalFunction { - private ICPPFunctionType type; + private final ICPPFunctionType fType; private ICPPParameter[] fParams; - private IType[] specializedExceptionSpec; - private final ICPPClassSpecialization fContext; + private final IType[] fExceptionSpecs; - public CPPFunctionSpecialization(ICPPFunction orig, IBinding owner, ICPPTemplateParameterMap argMap) { - this(orig, owner, argMap, null); - } - - public CPPFunctionSpecialization(ICPPFunction orig, IBinding owner, ICPPTemplateParameterMap argMap, - ICPPClassSpecialization context) { + public CPPFunctionSpecialization(ICPPFunction orig, IBinding owner, ICPPTemplateParameterMap argMap, ICPPFunctionType type, IType[] exceptionSpecs) { super(orig, owner, argMap); - fContext= context; - } - - @Override - protected ICPPClassSpecialization getSpecializationContext() { - if (fContext != null) - return fContext; - return super.getSpecializationContext(); + fType= type; + fExceptionSpecs= exceptionSpecs; } private ICPPFunction getFunction() { @@ -109,12 +95,7 @@ public class CPPFunctionSpecialization extends CPPSpecialization implements ICPP @Override public ICPPFunctionType getType() { - if (type == null) { - ICPPFunction function = (ICPPFunction) getSpecializedBinding(); - type = (ICPPFunctionType) specializeType(function.getType()); - } - - return type; + return fType; } @Override @@ -331,31 +312,6 @@ public class CPPFunctionSpecialization extends CPPSpecialization implements ICPP @Override public IType[] getExceptionSpecification() { - if (specializedExceptionSpec == null) { - ICPPFunction function = (ICPPFunction) getSpecializedBinding(); - IType[] types = function.getExceptionSpecification(); - if (types != null) { - IType[] specializedTypeList = new IType[types.length]; - int j= 0; - for (int i= 0; i < types.length; ++i) { - final IType origType = types[i]; - if (origType instanceof ICPPParameterPackType) { - IType[] specialized= specializeTypePack((ICPPParameterPackType) origType); - if (specialized.length != 1) { - IType[] x= new IType[specializedTypeList.length + specialized.length-1]; - System.arraycopy(specializedTypeList, 0, x, 0, j); - specializedTypeList= x; - } - for (IType iType : specialized) { - specializedTypeList[j++] = iType; - } - } else { - specializedTypeList[j++] = specializeType(origType); - } - } - specializedExceptionSpec= specializedTypeList; - } - } - return specializedExceptionSpec; + return fExceptionSpecs; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplateSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplateSpecialization.java index 01120115dd3..f69032f8028 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplateSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionTemplateSpecialization.java @@ -13,9 +13,11 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; 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.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; @@ -30,8 +32,8 @@ public class CPPFunctionTemplateSpecialization extends CPPFunctionSpecialization private ObjectMap instances = null; - public CPPFunctionTemplateSpecialization(ICPPFunction original, ICPPClassType owner, ICPPTemplateParameterMap argumentMap) { - super(original, owner, argumentMap); + public CPPFunctionTemplateSpecialization(ICPPFunction original, ICPPClassType owner, ICPPTemplateParameterMap argumentMap, ICPPFunctionType type, IType[] exceptionSpecs) { + super(original, owner, argumentMap, type, exceptionSpecs); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodInstance.java index 286b131d745..611539cf565 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodInstance.java @@ -11,7 +11,9 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; +import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; @@ -20,8 +22,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; */ public class CPPMethodInstance extends CPPFunctionInstance implements ICPPMethod { - public CPPMethodInstance(ICPPMethod orig, ICPPClassType owner, CPPTemplateParameterMap tpmap, ICPPTemplateArgument[] args) { - super(orig, owner, tpmap, args); + public CPPMethodInstance(ICPPMethod orig, ICPPClassType owner, CPPTemplateParameterMap tpmap, ICPPTemplateArgument[] args, ICPPFunctionType type, IType[] exceptionSpecs) { + super(orig, owner, tpmap, args, type, exceptionSpecs); } /* (non-Javadoc) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodSpecialization.java index a7eccc21f35..a8baca56672 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodSpecialization.java @@ -18,6 +18,7 @@ import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; @@ -26,8 +27,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; */ public class CPPMethodSpecialization extends CPPFunctionSpecialization implements ICPPMethod { - public CPPMethodSpecialization(ICPPMethod orig, ICPPClassType owner, ICPPTemplateParameterMap argMap) { - super(orig, owner, argMap); + public CPPMethodSpecialization(ICPPMethod orig, ICPPClassType owner, ICPPTemplateParameterMap argMap, ICPPFunctionType type, IType[] exceptionSpec ) { + super(orig, owner, argMap, type, exceptionSpec ); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodTemplateSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodTemplateSpecialization.java index e65a789c68e..f257ba47630 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodTemplateSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPMethodTemplateSpecialization.java @@ -12,7 +12,9 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; @@ -23,8 +25,8 @@ public class CPPMethodTemplateSpecialization extends CPPFunctionTemplateSpeciali implements ICPPMethod { public CPPMethodTemplateSpecialization(ICPPMethod specialized, ICPPClassType owner, - ICPPTemplateParameterMap ctmap) { - super(specialized, owner, ctmap); + ICPPTemplateParameterMap ctmap, ICPPFunctionType type, IType[] exceptionSpecs) { + super(specialized, owner, ctmap, type, exceptionSpecs); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameterPackType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameterPackType.java index 7369fe71858..03bfac229b7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameterPackType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameterPackType.java @@ -72,7 +72,7 @@ public class CPPParameterPackType implements ICPPParameterPackType, ITypeContain @Override public void marshal(ITypeMarshalBuffer buffer) throws CoreException { - int firstByte= ITypeMarshalBuffer.PACK_EXPANSION; + int firstByte= ITypeMarshalBuffer.PACK_EXPANSION_TYPE; buffer.putByte((byte) firstByte); buffer.marshalType(getType()); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameterSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameterSpecialization.java index 93628b1d04d..82c3cfe8e75 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameterSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPParameterSpecialization.java @@ -22,7 +22,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; * Binding for a specialization of a parameter. */ public class CPPParameterSpecialization extends CPPSpecialization implements ICPPParameter { - private IType fType; + private final IType fType; public CPPParameterSpecialization(ICPPParameter orig, IBinding owner, IType type, ICPPTemplateParameterMap tpmap) { super(orig, owner, tpmap); @@ -46,12 +46,6 @@ public class CPPParameterSpecialization extends CPPSpecialization implements ICP return fType instanceof ICPPParameterPackType; } - @Override - public IType specializeType(IType type) { - assert false; - return type; - } - /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IVariable#isStatic() */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPPointerToMemberType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPPointerToMemberType.java index e0ae6bca75f..57ba7226e1e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPPointerToMemberType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPPointerToMemberType.java @@ -97,7 +97,7 @@ public class CPPPointerToMemberType extends CPPPointerType implements ICPPPointe @Override public void marshal(ITypeMarshalBuffer buffer) throws CoreException { - int firstByte= ITypeMarshalBuffer.POINTER_TO_MEMBER; + int firstByte= ITypeMarshalBuffer.POINTER_TO_MEMBER_TYPE; if (isConst()) firstByte |= ITypeMarshalBuffer.FLAG1; if (isVolatile()) firstByte |= ITypeMarshalBuffer.FLAG2; if (isRestrict()) firstByte |= ITypeMarshalBuffer.FLAG3; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPPointerType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPPointerType.java index d5d72de2d9e..47fcc5db617 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPPointerType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPPointerType.java @@ -108,7 +108,7 @@ public class CPPPointerType implements IPointerType, ITypeContainer, ISerializab @Override public void marshal(ITypeMarshalBuffer buffer) throws CoreException { - int firstByte= ITypeMarshalBuffer.POINTER; + int firstByte= ITypeMarshalBuffer.POINTER_TYPE; if (isConst()) firstByte |= ITypeMarshalBuffer.FLAG1; if (isVolatile()) firstByte |= ITypeMarshalBuffer.FLAG2; if (isRestrict()) firstByte |= ITypeMarshalBuffer.FLAG3; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPQualifierType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPQualifierType.java index 7687f116c24..dd10111a8ec 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPQualifierType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPQualifierType.java @@ -92,7 +92,7 @@ public class CPPQualifierType implements IQualifierType, ITypeContainer, ISerial @Override public void marshal(ITypeMarshalBuffer buffer) throws CoreException { - int firstByte= ITypeMarshalBuffer.CVQUALIFIER; + int firstByte= ITypeMarshalBuffer.CVQUALIFIER_TYPE; if (isConst()) firstByte |= ITypeMarshalBuffer.FLAG1; if (isVolatile()) firstByte |= ITypeMarshalBuffer.FLAG2; buffer.putByte((byte) firstByte); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPReferenceType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPReferenceType.java index d25aff00651..a8a64ea435b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPReferenceType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPReferenceType.java @@ -109,7 +109,7 @@ public class CPPReferenceType implements ICPPReferenceType, ITypeContainer, ISer @Override public void marshal(ITypeMarshalBuffer buffer) throws CoreException { - int firstByte= ITypeMarshalBuffer.REFERENCE; + int firstByte= ITypeMarshalBuffer.REFERENCE_TYPE; if (isRValueReference()) { firstByte |= ITypeMarshalBuffer.FLAG1; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java index 2340c7cc814..a3246049bbb 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java @@ -57,7 +57,7 @@ abstract public class CPPScope implements ICPPASTInternalScope { private static final IProgressMonitor NPM = new NullProgressMonitor(); private static final ICPPNamespace UNINITIALIZED = new CPPNamespace.CPPNamespaceProblem(null, 0, null); - private IASTNode physicalNode; + private final IASTNode physicalNode; private boolean isCached = false; protected CharArrayObjectMap bindings; private ICPPNamespace fIndexNamespace= UNINITIALIZED; @@ -121,7 +121,10 @@ abstract public class CPPScope implements ICPPASTInternalScope { @Override public IBinding getBinding(IASTName name, boolean forceResolve, IIndexFileSet fileSet) { - IBinding binding= getBindingInAST(name, forceResolve); + final ScopeLookupData lookup = new ScopeLookupData(name, forceResolve, false); + lookup.setIgnorePointOfDeclaration(true); + IBinding[] bs= getBindingsInAST(lookup); + IBinding binding= CPPSemantics.resolveAmbiguities(name, bs); if (binding == null && forceResolve) { final IASTTranslationUnit tu = name.getTranslationUnit(); IIndex index = tu == null ? null : tu.getIndex(); @@ -169,29 +172,28 @@ abstract public class CPPScope implements ICPPASTInternalScope { return fIndexNamespace; } - public IBinding getBindingInAST(IASTName name, boolean forceResolve) { - IBinding[] bs= getBindingsInAST(name, forceResolve, false, false); - return CPPSemantics.resolveAmbiguities(name, bs); - } - + /** + * @deprecated Use {@link #getBindings(ScopeLookupData)} instead + */ + @Deprecated @Override public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) { - return getBindings(name, resolve, prefixLookup, fileSet, true); + return getBindings(new ScopeLookupData(name, resolve, prefixLookup)); } @Override - public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet, - boolean checkPointOfDecl) { - IBinding[] result = getBindingsInAST(name, resolve, prefixLookup, checkPointOfDecl); - final IASTTranslationUnit tu = name.getTranslationUnit(); + public IBinding[] getBindings(ScopeLookupData lookup) { + IBinding[] result = getBindingsInAST(lookup); + final IASTTranslationUnit tu = lookup.getLookupPoint().getTranslationUnit(); if (tu != null) { IIndex index = tu.getIndex(); if (index != null) { + IIndexFileSet fileSet= lookup.getIncludedFiles(); if (physicalNode instanceof IASTTranslationUnit) { try { IndexFilter filter = IndexFilter.CPP_DECLARED_OR_IMPLICIT_NO_INSTANCE; - final char[] nchars = name.getLookupKey(); - IBinding[] bindings = prefixLookup ? + final char[] nchars = lookup.getLookupKey(); + IBinding[] bindings = lookup.isPrefixLookup() ? index.findBindingsForContentAssist(nchars, true, filter, null) : index.findBindings(nchars, filter, null); if (fileSet != null) { @@ -207,10 +209,7 @@ abstract public class CPPScope implements ICPPASTInternalScope { IIndexBinding binding = index.findBinding(ns.getName()); if (binding instanceof ICPPNamespace) { ICPPNamespaceScope indexNs = ((ICPPNamespace) binding).getNamespaceScope(); - IBinding[] bindings = indexNs.getBindings(name, resolve, prefixLookup); - if (fileSet != null) { - bindings= fileSet.filterFileLocalBindings(bindings); - } + IBinding[] bindings = indexNs.getBindings(lookup); result = ArrayUtil.addAll(IBinding.class, result, bindings); } } catch (CoreException e) { @@ -224,14 +223,13 @@ abstract public class CPPScope implements ICPPASTInternalScope { } - public IBinding[] getBindingsInAST(IASTName name, boolean forceResolve, boolean prefixLookup, - boolean checkPointOfDecl) { + public IBinding[] getBindingsInAST(ScopeLookupData lookup) { populateCache(); - final char[] c = name.getLookupKey(); + final char[] c = lookup.getLookupKey(); IBinding[] result = null; Object obj = null; - if (prefixLookup) { + if (lookup.isPrefixLookup()) { Object[] keys = bindings != null ? bindings.keyArray() : new Object[0]; ObjectSet all= new ObjectSet(16); IContentAssistMatcher matcher = ContentAssistMatcherFactory.getInstance().createMatcher(c); @@ -255,21 +253,21 @@ abstract public class CPPScope implements ICPPASTInternalScope { if (obj instanceof ObjectSet) { ObjectSet os= (ObjectSet) obj; for (int j = 0; j < os.size(); j++) { - result= addCandidate(os.keyAt(j), name, forceResolve, checkPointOfDecl, result); + result= addCandidate(os.keyAt(j), lookup, result); } } else { - result = addCandidate(obj, name, forceResolve, checkPointOfDecl, result); + result = addCandidate(obj, lookup, result); } } return ArrayUtil.trim(IBinding.class, result); } - private IBinding[] addCandidate(Object candidate, IASTName name, boolean forceResolve, - boolean checkPointOfDecl, IBinding[] result) { - if (checkPointOfDecl) { - IASTTranslationUnit tu= name.getTranslationUnit(); - if (!CPPSemantics.declaredBefore(candidate, name, tu != null && tu.getIndex() != null)) { - if (!(this instanceof ICPPClassScope) || !LookupData.checkWholeClassScope(name)) + private IBinding[] addCandidate(Object candidate, ScopeLookupData lookup, IBinding[] result) { + final IASTNode point = lookup.getLookupPoint(); + if (!lookup.isIgnorePointOfDeclaration()) { + IASTTranslationUnit tu= point.getTranslationUnit(); + if (!CPPSemantics.declaredBefore(candidate, point, tu != null && tu.getIndex() != null)) { + if (!(this instanceof ICPPClassScope) || !LookupData.checkWholeClassScope(lookup.getLookupName())) return result; } } @@ -281,7 +279,7 @@ abstract public class CPPScope implements ICPPASTInternalScope { if (simpleName instanceof ICPPASTTemplateId) { simpleName= ((ICPPASTTemplateId) simpleName).getTemplateName(); } - if (forceResolve && candName != name && simpleName != name) { + if (lookup.isResolve() && candName != point && simpleName != point) { candName.resolvePreBinding(); // Make sure to resolve the template-id binding = simpleName.resolvePreBinding(); } else { @@ -377,7 +375,7 @@ abstract public class CPPScope implements ICPPASTInternalScope { @Override public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefix) { - return getBindings(name, resolve, prefix, IIndexFileSet.EMPTY, true); + return getBindings(new ScopeLookupData(name, resolve, prefix)); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScopeMapper.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScopeMapper.java index cf8bb539ebf..634a92280e1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScopeMapper.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScopeMapper.java @@ -26,6 +26,7 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IScope; @@ -104,13 +105,18 @@ public class CPPScopeMapper { public IBinding getBinding(IASTName name, boolean resolve, IIndexFileSet acceptLocalBindings) { return fScope.getBinding(name, resolve, acceptLocalBindings); } - @Override + @Override @Deprecated public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup) { return fScope.getBindings(name, resolve, prefixLookup); } - @Override + @Override @Deprecated public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet acceptLocalBindings) { - return fScope.getBindings(name, resolve, prefixLookup, acceptLocalBindings); + return getBindings(name, resolve, prefixLookup, acceptLocalBindings); + } + + @Override + public IBinding[] getBindings(ScopeLookupData lookup) { + return fScope.getBindings(lookup); } @Override public IScope getParent() throws DOMException { @@ -363,14 +369,14 @@ public class CPPScopeMapper { return scope; } - public ICPPClassType mapToAST(ICPPClassType type) { + public ICPPClassType mapToAST(ICPPClassType type, IASTNode point) { if (type instanceof ICPPTemplateInstance) { ICPPTemplateInstance inst= (ICPPTemplateInstance) type; ICPPTemplateDefinition template= inst.getTemplateDefinition(); if (template instanceof IIndexBinding && template instanceof ICPPClassType) { - IBinding mapped= mapToAST((ICPPClassType) template); + IBinding mapped= mapToAST((ICPPClassType) template, point); if (mapped != template && mapped instanceof ICPPClassType) { - mapped= CPPTemplates.instantiate((ICPPClassTemplate) mapped, inst.getTemplateArguments()); + mapped= CPPTemplates.instantiate((ICPPClassTemplate) mapped, inst.getTemplateArguments(), point); if (mapped instanceof ICPPClassType) return (ICPPClassType) mapped; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSpecialization.java index 5f989523d0b..f43147bdb4e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSpecialization.java @@ -16,14 +16,10 @@ import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IScope; -import org.eclipse.cdt.core.dom.ast.IType; -import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.parser.util.ArrayUtil; @@ -40,9 +36,9 @@ import org.eclipse.core.runtime.PlatformObject; * is a need to synchronize non-final members. */ public abstract class CPPSpecialization extends PlatformObject implements ICPPSpecialization, ICPPInternalBinding { - private IBinding owner; - private IBinding specialized; - private ICPPTemplateParameterMap argumentMap; + private final IBinding owner; + private final IBinding specialized; + private final ICPPTemplateParameterMap argumentMap; protected IASTNode definition; private IASTNode[] declarations; @@ -52,45 +48,6 @@ public abstract class CPPSpecialization extends PlatformObject implements ICPPSp this.argumentMap = argumentMap; } - public IType specializeType(IType type) { - return CPPTemplates.instantiateType(type, getTemplateParameterMap(), -1, getSpecializationContext()); - } - - protected ICPPClassSpecialization getSpecializationContext() { - if (owner instanceof ICPPClassSpecialization) { - ICPPClassSpecialization within = (ICPPClassSpecialization) owner; - ICPPClassType orig = within.getSpecializedBinding(); - for(;;) { - IBinding o1 = within.getOwner(); - IBinding o2 = orig.getOwner(); - if (!(o1 instanceof ICPPClassSpecialization && o2 instanceof ICPPClassType)) - return within; - ICPPClassSpecialization nextWithin = (ICPPClassSpecialization) o1; - orig= (ICPPClassType) o2; - if (orig.isSameType(nextWithin)) - return within; - within= nextWithin; - } - } - return null; - } - - public IType[] specializeTypePack(ICPPParameterPackType type) { - if (owner instanceof ICPPClassSpecialization) { - return CPPTemplates.instantiateTypes(new IType[]{type}, getTemplateParameterMap(), -1, (ICPPClassSpecialization) owner); - } else { - return CPPTemplates.instantiateTypes(new IType[]{type}, getTemplateParameterMap(), -1, null); - } - } - - public IValue specializeValue(IValue value, int maxdepth) { - if (owner instanceof ICPPClassSpecialization) { - return CPPTemplates.instantiateValue(value, getTemplateParameterMap(), -1, (ICPPClassSpecialization) owner, maxdepth); - } else { - return CPPTemplates.instantiateValue(value, getTemplateParameterMap(), -1, null, maxdepth); - } - } - @Override public IBinding getSpecializedBinding() { return specialized; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedefSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedefSpecialization.java index 52f6968bc62..6d9b23bb749 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedefSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedefSpecialization.java @@ -12,91 +12,31 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; -import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; -import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; -import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; -import org.eclipse.core.runtime.Assert; /** * Specialization of a typedef in the context of a class-specialization. */ public class CPPTypedefSpecialization extends CPPSpecialization implements ITypedef, ITypeContainer { - final static class RecursionResolvingBinding extends ProblemBinding { - public RecursionResolvingBinding(IASTNode node, char[] arg) { - super(node, IProblemBinding.SEMANTIC_RECURSION_IN_LOOKUP, arg); - Assert.isTrue(CPPASTNameBase.sAllowRecursionBindings, getMessage()); - } - } - public static final int MAX_RESOLUTION_DEPTH = 5; public static final int MAX_TYPE_NESTING = 60; - private IType type; - private int fResolutionDepth; + private IType fType; - public CPPTypedefSpecialization(IBinding specialized, ICPPClassType owner, - ICPPTemplateParameterMap tpmap) { + public CPPTypedefSpecialization(IBinding specialized, ICPPClassType owner, ICPPTemplateParameterMap tpmap, IType type) { super(specialized, owner, tpmap); + fType= type; } - private ITypedef getTypedef() { - return (ITypedef) getSpecializedBinding(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.ITypedef#getType() - */ @Override public IType getType() { - return getType(MAX_TYPE_NESTING); + return fType; } - - private IType getType(int maxDepth) { - if (type == null) { - try { - if (++fResolutionDepth > MAX_RESOLUTION_DEPTH) { - type = new RecursionResolvingBinding(getDefinition(), getNameCharArray()); - } else { - type= specializeType(getTypedef().getType()); - // A typedef pointing to itself is a sure recipe for an infinite loop -- replace - // with a problem binding. - if (!verifyType(type, maxDepth)) { - type = new RecursionResolvingBinding(getDefinition(), getNameCharArray()); - } - } - } finally { - --fResolutionDepth; - } - } - return type; - } - - private boolean verifyType(IType type, int maxTypeNesting) { - for (;;) { - if (--maxTypeNesting < 0) - return false; - if (equals(type)) - return false; - if (type instanceof CPPTypedefSpecialization) { - type= ((CPPTypedefSpecialization) type).getType(maxTypeNesting); - } else if (type instanceof ITypeContainer) { - type= ((ITypeContainer) type).getType(); - } else { - return true; - } - } - } - - public int incResolutionDepth(int increment) { - fResolutionDepth += increment; - return fResolutionDepth; - } /* (non-Javadoc) * @see java.lang.Object#clone() @@ -134,6 +74,6 @@ public class CPPTypedefSpecialization extends CPPSpecialization implements IType @Override public void setType(IType type) { - this.type = type; + fType = type; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownBinding.java index b99f7bead64..8726f18722f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownBinding.java @@ -23,7 +23,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.internal.core.dom.Linkage; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.core.runtime.PlatformObject; @@ -39,7 +38,6 @@ public class CPPUnknownBinding extends PlatformObject public CPPUnknownBinding(IBinding owner, char[] name) { super(); this.name = new CPPASTName(name); - this.name.setPropertyInParent(CPPSemantics.STRING_LOOKUP_PROPERTY); fOwner= owner; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownFunction.java index f6245270563..9221489b2c3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownFunction.java @@ -19,6 +19,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; +import org.eclipse.cdt.internal.core.dom.parser.ProblemType; /** * Represents a reference to a (member) function (instance), which cannot be resolved because @@ -26,6 +27,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; */ public class CPPUnknownFunction extends CPPUnknownBinding implements ICPPFunction { + private static final ICPPFunctionType FUNCTION_TYPE= new CPPFunctionType(ProblemType.UNKNOWN_FOR_EXPRESSION, IType.EMPTY_TYPE_ARRAY); + public static ICPPFunction createForSample(IFunction sample) throws DOMException { if (sample instanceof ICPPConstructor) return new CPPUnknownConstructor(((ICPPConstructor) sample).getClassOwner()); @@ -33,7 +36,6 @@ public class CPPUnknownFunction extends CPPUnknownBinding implements ICPPFunctio return new CPPUnknownFunction(sample.getOwner(), sample.getNameCharArray()); } - private ICPPFunctionType fType; public CPPUnknownFunction(IBinding owner, char[] name) { super(owner, name); @@ -76,10 +78,7 @@ public class CPPUnknownFunction extends CPPUnknownBinding implements ICPPFunctio @Override public ICPPFunctionType getType() { - if (fType == null) { - fType= new CPPUnknownFunctionType(); - } - return fType; + return FUNCTION_TYPE; } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownScope.java index d32e6cd443d..7ac1111aead 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownScope.java @@ -13,33 +13,17 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; -import org.eclipse.cdt.core.dom.IName; -import org.eclipse.cdt.core.dom.ast.DOMException; -import org.eclipse.cdt.core.dom.ast.EScopeKind; -import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; -import org.eclipse.cdt.core.dom.ast.IScope; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding; -import org.eclipse.cdt.core.index.IIndexFileSet; import org.eclipse.cdt.core.parser.util.CharArrayObjectMap; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; /** * Models the scope represented by an unknown binding such (e.g.: template type parameter). Used within * the context of templates, only. * For safe usage in index bindings, all fields need to be final or used in a thread-safe manner otherwise. */ -public class CPPUnknownScope implements ICPPInternalUnknownScope { - private final ICPPUnknownBinding binding; - private final IASTName scopeName; +public class CPPUnknownScope extends CPPUnknownTypeScope implements ICPPInternalUnknownScope { /** * This field needs to be protected when used in PDOMCPPUnknownScope, * don't use it outside of {@link #getOrCreateBinding(IASTName, int)} @@ -47,164 +31,38 @@ public class CPPUnknownScope implements ICPPInternalUnknownScope { private CharArrayObjectMap map; public CPPUnknownScope(ICPPUnknownBinding binding, IASTName name) { - super(); - this.scopeName = name; - this.binding = binding; + super(name, binding); } - @Override - public EScopeKind getKind() { - return EScopeKind.eClassType; - } - - @Override - public IName getScopeName() { - return scopeName; - } - - @Override - public IScope getParent() throws DOMException { - return binding.getScope(); - } - - @Override - public IBinding[] find(String name) { - return IBinding.EMPTY_BINDING_ARRAY; - } - - @Override - public IASTNode getPhysicalNode() { - return scopeName; - } @Override public void addName(IASTName name) { } @Override - public final IBinding getBinding(IASTName name, boolean resolve) { - return getBinding(name, resolve, IIndexFileSet.EMPTY); - } - - @Override - public IBinding getBinding(final IASTName name, boolean resolve, IIndexFileSet fileSet) { - boolean type= false; - boolean function= false; - - if (name.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) { - type= true; - } else { - IASTName n= name; - IASTNode parent= name.getParent(); - if (parent instanceof ICPPASTTemplateId) { - n= (IASTName) parent; - parent= n.getParent(); - } - if (parent instanceof ICPPASTQualifiedName) { - ICPPASTQualifiedName qname= (ICPPASTQualifiedName) parent; - if (qname.getLastName() != n) { - type= true; - } else { - parent= qname.getParent(); - } - } - if (!type) { - if (parent instanceof ICPPASTBaseSpecifier || - parent instanceof ICPPASTConstructorChainInitializer) { - type= true; - } else if (parent instanceof ICPPASTNamedTypeSpecifier) { - ICPPASTNamedTypeSpecifier nts= (ICPPASTNamedTypeSpecifier) parent; - type= nts.isTypename(); - } else if (parent instanceof ICPPASTUsingDeclaration) { - ICPPASTUsingDeclaration ud= (ICPPASTUsingDeclaration) parent; - type= ud.isTypename(); - } - - if (!type && parent.getPropertyInParent() == IASTFunctionCallExpression.FUNCTION_NAME) { - function= true; - } - } - } - - int idx= type ? 0 : function ? 1 : 2; - - IBinding result = getOrCreateBinding(name, idx); - return result; - } - - protected IBinding getOrCreateBinding(final IASTName name, int idx) { + protected IBinding getOrCreateBinding(final char[] name, int idx) { if (map == null) map = new CharArrayObjectMap(2); - final char[] c = name.getLookupKey(); - IBinding[] o = map.get(c); + IBinding[] o = map.get(name); if (o == null) { o = new IBinding[3]; - map.put(c, o); + map.put(name, o); } IBinding result= o[idx]; if (result == null) { - switch (idx) { - case 0: - result= new CPPUnknownClass(binding, name.getSimpleID()); - break; - case 1: - result= new CPPUnknownFunction(binding, name.getSimpleID()); - break; - case 2: - result= new CPPUnknownBinding(binding, name.getSimpleID()); - break; - } + result= super.getOrCreateBinding(name, idx); o[idx]= result; } return result; } - @Override - public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefix) { - return getBindings(name, resolve, prefix, IIndexFileSet.EMPTY); - } - - @Override - public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) { - return getBindings(name, resolve, prefixLookup, fileSet, true); - } - - @Override - public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet acceptLocalBindings, boolean checkPointOfDecl) { - if (prefixLookup) { - if (binding instanceof ICPPDeferredClassInstance) { - ICPPDeferredClassInstance instance = (ICPPDeferredClassInstance) binding; - IScope scope = instance.getClassTemplate().getCompositeScope(); - if (scope != null) { - return scope.getBindings(name, resolve, prefixLookup, acceptLocalBindings); - } - } - return IBinding.EMPTY_BINDING_ARRAY; - } - - return new IBinding[] {getBinding(name, resolve, acceptLocalBindings)}; - } - @Override public void addBinding(IBinding binding) { // do nothing, this is part of template magic and not a normal scope } - @Override - public ICPPBinding getScopeBinding() { - return binding; - } - - /* (non-Javadoc) - * For debug purposes only - */ - @Override - public String toString() { - return scopeName.toString(); - } - @Override public void populateCache() {} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownTypeScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownTypeScope.java new file mode 100644 index 00000000000..45f1bcdddcb --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUnknownTypeScope.java @@ -0,0 +1,178 @@ +/******************************************************************************* + * Copyright (c) 2004, 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: + * Andrew Niefer (IBM Corporation) - initial API and implementation + * Markus Schorn (Wind River Systems) + * Bryan Wilkinson (QNX) + * Sergey Prigogin (Google) + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.IName; +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.EScopeKind; +import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; +import org.eclipse.cdt.core.index.IIndexFileSet; + +/** + * Models the scope represented by an unknown type (e.g.: typeof(template type parameter)). Used within + * the context of templates, only. + * For safe usage in index bindings, all fields need to be final or used in a thread-safe manner otherwise. + */ +public class CPPUnknownTypeScope implements ICPPScope { + private final IASTName fName; + private final ICPPBinding fScopeBinding; + + public CPPUnknownTypeScope(IASTName name, ICPPBinding scopeBinding) { + fName= name; + fScopeBinding= scopeBinding; + } + + @Override + public EScopeKind getKind() { + return EScopeKind.eClassType; + } + + public IASTNode getPhysicalNode() { + return fName; + } + + @Override + public IName getScopeName() { + return fName; + } + + @Override + public IScope getParent() throws DOMException { + return fScopeBinding == null ? null : fScopeBinding.getScope(); + } + + @Override + public IBinding[] find(String name) { + return IBinding.EMPTY_BINDING_ARRAY; + } + + @Override + public final IBinding getBinding(IASTName name, boolean resolve) { + return getBinding(name, resolve, IIndexFileSet.EMPTY); + } + + @Override + public IBinding getBinding(final IASTName name, boolean resolve, IIndexFileSet fileSet) { + boolean type= false; + boolean function= false; + + if (name.getPropertyInParent() == null) { + type= true; + } else { + IASTName n= name; + IASTNode parent= name.getParent(); + if (parent instanceof ICPPASTTemplateId) { + n= (IASTName) parent; + parent= n.getParent(); + } + if (parent instanceof ICPPASTQualifiedName) { + ICPPASTQualifiedName qname= (ICPPASTQualifiedName) parent; + if (qname.getLastName() != n) { + type= true; + } else { + parent= qname.getParent(); + } + } + if (!type) { + if (parent instanceof ICPPASTBaseSpecifier || + parent instanceof ICPPASTConstructorChainInitializer) { + type= true; + } else if (parent instanceof ICPPASTNamedTypeSpecifier) { + ICPPASTNamedTypeSpecifier nts= (ICPPASTNamedTypeSpecifier) parent; + type= nts.isTypename(); + } else if (parent instanceof ICPPASTUsingDeclaration) { + ICPPASTUsingDeclaration ud= (ICPPASTUsingDeclaration) parent; + type= ud.isTypename(); + } + + if (!type && parent.getPropertyInParent() == IASTFunctionCallExpression.FUNCTION_NAME) { + function= true; + } + } + } + + int idx= type ? 0 : function ? 1 : 2; + + IBinding result = getOrCreateBinding(name.getSimpleID(), idx); + return result; + } + + protected IBinding getOrCreateBinding(final char[] name, int idx) { + IBinding result= null; + switch (idx) { + case 0: + result= new CPPUnknownClass(fScopeBinding, name); + break; + case 1: + result= new CPPUnknownFunction(fScopeBinding, name); + break; + case 2: + result= new CPPUnknownBinding(fScopeBinding, name); + break; + } + return result; + } + + @Override @Deprecated + public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefix) { + return getBindings(name, resolve, prefix, IIndexFileSet.EMPTY); + } + + @Override @Deprecated + public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) { + return getBindings(new ScopeLookupData(name, resolve, prefixLookup)); + } + + @Override + public final IBinding[] getBindings(ScopeLookupData lookup) { + if (lookup.isPrefixLookup()) { + if (fScopeBinding instanceof ICPPDeferredClassInstance) { + ICPPDeferredClassInstance instance = (ICPPDeferredClassInstance) fScopeBinding; + IScope scope = instance.getClassTemplate().getCompositeScope(); + if (scope != null) { + return scope.getBindings(lookup); + } + } + return IBinding.EMPTY_BINDING_ARRAY; + } + IASTName lookupName= lookup.getLookupName(); + if (lookupName != null) + return new IBinding[] {getBinding(lookupName, lookup.isResolve(), lookup.getIncludedFiles())}; + + // When dealing with dependent expressions we always create an unknown class. That is because + // unknown objects are not used within the expressions, they are attached to names only. + return new IBinding[] {getOrCreateBinding(lookup.getLookupKey(), 0)}; + } + + public ICPPBinding getScopeBinding() { + return fScopeBinding; + } + + @Override + public String toString() { + return fName.toString(); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUsingDeclarationSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUsingDeclarationSpecialization.java index 2ac509e168b..2f17485600e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUsingDeclarationSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPUsingDeclarationSpecialization.java @@ -10,58 +10,25 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPFunctionSet; -import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; /** * Specialization of a typedef in the context of a class-specialization. */ public class CPPUsingDeclarationSpecialization extends CPPSpecialization implements ICPPUsingDeclaration { - private IBinding[] fDelegates; + private final IBinding[] fDelegates; public CPPUsingDeclarationSpecialization(ICPPUsingDeclaration specialized, ICPPClassSpecialization owner, - ICPPTemplateParameterMap tpmap) { + ICPPTemplateParameterMap tpmap, IBinding[] delegates) { super(specialized, owner, tpmap); + fDelegates= delegates; } @Override public IBinding[] getDelegates() { - if (fDelegates == null) { - fDelegates= specializeDelegates(); - } return fDelegates; } - - private IBinding[] specializeDelegates() { - IBinding[] origDelegates= ((ICPPUsingDeclaration) getSpecializedBinding()).getDelegates(); - List result= new ArrayList(); - ICPPClassSpecialization owner= (ICPPClassSpecialization) getOwner(); - for (IBinding delegate : origDelegates) { - if (delegate instanceof ICPPUnknownBinding) { - try { - delegate= CPPTemplates.resolveUnknown((ICPPUnknownBinding) delegate, - owner.getTemplateParameterMap(), -1, null); - if (delegate instanceof CPPFunctionSet) { - for (IBinding b : ((CPPFunctionSet) delegate).getBindings()) { - result.add(b); - } - } else if (delegate != null) { - result.add(delegate); - } - } catch (DOMException e) { - } - } else { - result.add(delegate); - } - } - return result.toArray(new IBinding[result.size()]); - } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPASTInternalScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPASTInternalScope.java index 7e22d3b3a52..bf05912d217 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPASTInternalScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPASTInternalScope.java @@ -10,22 +10,11 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; -import org.eclipse.cdt.core.dom.ast.IASTName; -import org.eclipse.cdt.core.dom.ast.IBinding; -import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; -import org.eclipse.cdt.core.index.IIndexFileSet; import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope; /** * Interface for internal c++ scopes */ public interface ICPPASTInternalScope extends IASTInternalScope, ICPPScope { - /** - * Same as {@link IScope#getBindings(IASTName, boolean, boolean, IIndexFileSet)} with the - * possibility to disable checking the point of declaration. The method is used to resolve - * dependent bindings, where the points of declaration may be reversed. - */ - public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, - IIndexFileSet acceptLocalBindings, boolean checkPointOfDecl); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInitClauseEvaluation.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPEvaluation.java similarity index 72% rename from core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInitClauseEvaluation.java rename to core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPEvaluation.java index 255f617f812..c56f4d343ae 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInitClauseEvaluation.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPEvaluation.java @@ -12,19 +12,22 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; +import org.eclipse.cdt.core.dom.ast.IASTNode; 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; /** * Assists in evaluating expressions. */ -public interface ICPPInitClauseEvaluation { - +public interface ICPPEvaluation extends ISerializableEvaluation { boolean isInitializerList(); + boolean isFunctionSet(); + boolean isTypeDependent(); boolean isValueDependent(); - IType getTypeOrFunctionSet(); - IValue getValue(); - ValueCategory getCategory(); + IType getTypeOrFunctionSet(IASTNode point); + IValue getValue(IASTNode point); + ValueCategory getValueCategory(IASTNode point); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/OverloadableOperator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/OverloadableOperator.java index f55bca64d1f..8c4101cc86e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/OverloadableOperator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/OverloadableOperator.java @@ -174,8 +174,8 @@ public enum OverloadableOperator { * * @throws NullPointerException if {@code expression} is {@code null}. */ - public static OverloadableOperator fromBinaryExpression(IASTBinaryExpression expression) { - switch (expression.getOperator()) { + public static OverloadableOperator fromBinaryExpression(int binaryOp) { + switch (binaryOp) { case IASTBinaryExpression.op_binaryAnd: return AMPER; case IASTBinaryExpression.op_binaryAndAssign: return AMPERASSIGN; case IASTBinaryExpression.op_pmarrow: return ARROW; @@ -219,8 +219,8 @@ public enum OverloadableOperator { return null; } - public static OverloadableOperator fromUnaryExpression(IASTUnaryExpression expression) { - switch(expression.getOperator()) { + public static OverloadableOperator fromUnaryExpression(int unaryOp) { + switch(unaryOp) { case IASTUnaryExpression.op_prefixIncr: return INCR; case IASTUnaryExpression.op_prefixDecr: return DECR; case IASTUnaryExpression.op_plus: return PLUS; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AccessContext.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AccessContext.java index af258964bf1..78e1a4b670d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AccessContext.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/AccessContext.java @@ -224,11 +224,11 @@ public class AccessContext { private ICPPClassType getFirstCandidateForNamingClass(IASTName name) throws DOMException { LookupData data = new LookupData(name); - isUnqualifiedLookup= !data.qualified(); + isUnqualifiedLookup= !data.qualified; - ICPPScope scope= CPPSemantics.getLookupScope(name, data); + ICPPScope scope= CPPSemantics.getLookupScope(name); while (scope != null && !(scope instanceof ICPPClassScope)) { - scope = CPPSemantics.getParentScope(scope, data.tu); + scope = CPPSemantics.getParentScope(scope, data.getTranslationUnit()); } if (scope instanceof ICPPClassScope) { return ((ICPPClassScope) scope).getClassType(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BaseClassLookup.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BaseClassLookup.java index 9691f3e476a..8579ae27553 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BaseClassLookup.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BaseClassLookup.java @@ -26,7 +26,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember; -import org.eclipse.cdt.core.index.IIndexFileSet; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.CharArrayObjectMap; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; @@ -41,7 +40,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; * from the graph. */ class BaseClassLookup { - public static void lookupInBaseClasses(LookupData data, ICPPClassScope classScope, IIndexFileSet fileSet) { + public static void lookupInBaseClasses(LookupData data, ICPPClassScope classScope) { if (classScope == null) return; @@ -50,7 +49,7 @@ class BaseClassLookup { return; final HashMap infoMap = new HashMap(); - BaseClassLookup rootInfo= lookupInBaseClass(data, null, false, classType, fileSet, infoMap, 0); + BaseClassLookup rootInfo= lookupInBaseClass(data, null, false, classType, infoMap, 0); if (data.contentAssist) { rootInfo.collectResultForContentAssist(data); } else { @@ -137,7 +136,7 @@ class BaseClassLookup { } static BaseClassLookup lookupInBaseClass(LookupData data, ICPPClassScope baseClassScope, boolean isVirtual, - ICPPClassType root, IIndexFileSet fileSet, HashMap infoMap, int depth) { + ICPPClassType root, HashMap infoMap, int depth) { if (depth++ > CPPSemantics.MAX_INHERITANCE_DEPTH) return null; @@ -164,9 +163,9 @@ class BaseClassLookup { result= new BaseClassLookup(baseClassScope.getClassType()); infoMap.put(baseClassScope, result); try { - IBinding[] members= CPPSemantics.getBindingsFromScope(baseClassScope, fileSet, data); + IBinding[] members= CPPSemantics.getBindingsFromScope(baseClassScope, data); if (members != null && members.length > 0 && members[0] != null) { - if (data.prefixLookup) { + if (data.isPrefixLookup()) { matches= members; } else { result.setResult(members); @@ -227,7 +226,7 @@ class BaseClassLookup { continue; BaseClassLookup baseInfo= lookupInBaseClass(data, (ICPPClassScope) grandBaseScope, - grandBase.isVirtual(), root, fileSet, infoMap, depth); + grandBase.isVirtual(), root, infoMap, depth); if (baseInfo != null) result.addBase(grandBase.isVirtual(), baseInfo); } @@ -335,7 +334,7 @@ class BaseClassLookup { return result; } else { if (fCollectedAsRegularBase && data.problem == null && containsNonStaticMember()) { - data.problem= new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP); + data.problem= new ProblemBinding(data.getLookupName(), IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP); } fCollectedAsRegularBase= true; } @@ -356,7 +355,7 @@ class BaseClassLookup { fBindings[numBindingsToAdd] = null; if (result.length > 0 && numBindingsToAdd > 0 && data.problem == null) { // Matches are found in more than one base class - this is an indication of ambiguity. - data.problem= new ProblemBinding(data.astName, + data.problem= new ProblemBinding(data.getLookupName(), IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, result); } result= ArrayUtil.addAll(result, fBindings); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BuiltinOperators.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BuiltinOperators.java index 259f247bf2c..228047b9233 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BuiltinOperators.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BuiltinOperators.java @@ -10,7 +10,6 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeOrFunctionSet; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*; import java.util.ArrayList; @@ -21,9 +20,7 @@ import java.util.Set; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; -import org.eclipse.cdt.core.dom.ast.IASTExpression; -import org.eclipse.cdt.core.dom.ast.IASTInitializerClause; -import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; import org.eclipse.cdt.core.dom.ast.IEnumeration; @@ -48,6 +45,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBuiltinParameter; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitFunction; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator; /** @@ -59,12 +57,12 @@ class BuiltinOperators { private static final int SECOND = 1; private static final IType PTR_DIFF = new CPPBasicType(Kind.eInt, 0); - public static ICPPFunction[] create(OverloadableOperator operator, IASTInitializerClause[] args, - IASTTranslationUnit tu, Object[] globCandidates) { + public static ICPPFunction[] create(OverloadableOperator operator, ICPPEvaluation[] args, + IASTNode point, Object[] globCandidates) { if (operator == null || args == null || args.length == 0) return EMPTY; - return new BuiltinOperators(operator, args, tu.getScope(), globCandidates).create(); + return new BuiltinOperators(operator, args, point, globCandidates).create(); } private final OverloadableOperator fOperator; @@ -78,20 +76,20 @@ class BuiltinOperators { private Set fSignatures; private Object[] fGlobalCandidates; - BuiltinOperators(OverloadableOperator operator, IASTInitializerClause[] args, IScope fileScope, + BuiltinOperators(OverloadableOperator operator, ICPPEvaluation[] args, IASTNode point, Object[] globCandidates) { - fFileScope= fileScope; + fFileScope= point.getTranslationUnit().getScope(); fOperator= operator; fUnary= args.length<2; fGlobalCandidates= globCandidates; - if (args.length > 0 && args[0] instanceof IASTExpression) { - IType type= typeOrFunctionSet((IASTExpression) args[0]); + if (args.length > 0) { + IType type= args[0].getTypeOrFunctionSet(point); if (!(type instanceof ISemanticProblem)) fType1= type; } - if (args.length > 1 && args[1] instanceof IASTExpression) { - IType type= typeOrFunctionSet((IASTExpression) args[1]); + if (args.length > 1) { + IType type= args[1].getTypeOrFunctionSet(point); if (!(type instanceof ISemanticProblem)) fType2= type; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPFunctionSet.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPFunctionSet.java index c37e3b9b8e7..3cbc6c97799 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPFunctionSet.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPFunctionSet.java @@ -9,12 +9,15 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.internal.core.dom.Linkage; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownFunction; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPTwoPhaseBinding; /** @@ -23,10 +26,14 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPTwoPhaseBinding; */ public class CPPFunctionSet implements ICPPTwoPhaseBinding { - final ICPPFunction[] fBindings; + private final ICPPFunction[] fBindings; + private final IASTName fName; + private final ICPPTemplateArgument[] fTemplateArguments; - public CPPFunctionSet(ICPPFunction[] bindingList) { + public CPPFunctionSet(ICPPFunction[] bindingList, ICPPTemplateArgument[] args, IASTName name) { fBindings = ArrayUtil.removeNulls(bindingList); + fTemplateArguments= args; + fName= name; } @Override @@ -60,10 +67,9 @@ public class CPPFunctionSet implements ICPPTwoPhaseBinding { @Override public IBinding resolveFinalBinding(CPPASTNameBase astName) { - return CPPSemantics.resolveTargetedFunction(astName, fBindings); + return CPPSemantics.resolveTargetedFunction(astName, this); } - @Override @SuppressWarnings("unchecked") public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { @@ -71,4 +77,20 @@ public class CPPFunctionSet implements ICPPTwoPhaseBinding { return this; return null; } + + public ICPPTemplateArgument[] getTemplateArguments() { + return fTemplateArguments; + } + + public void applySelectedFunction(ICPPFunction selectedFunction) { + if (selectedFunction != null && fName != null) { + fName.setBinding(selectedFunction); + } + } + + public void setToUnknown() { + if (fName != null) { + fName.setBinding(new CPPUnknownFunction(null, fName.toCharArray())); + } + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index c84ee84c4b6..358e30115fd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -16,20 +16,7 @@ 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.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeOrFunctionSet; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCat; -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.ARRAY; -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.MPTR; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.PTR; -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.calculateInheritanceDepth; -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.getUltimateTypeUptoPointers; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.isConversionOperator; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*; import java.util.ArrayList; import java.util.Arrays; @@ -44,7 +31,6 @@ import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.EScopeKind; -import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression; import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; import org.eclipse.cdt.core.dom.ast.IASTCastExpression; import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; @@ -91,6 +77,7 @@ import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.IScope.ScopeLookupData; import org.eclipse.cdt.core.dom.ast.ISemanticProblem; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; @@ -105,14 +92,17 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTEnumerationSpecifier; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTForStatement; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLiteralExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; @@ -128,6 +118,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplatedTypeTemplateParameter; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective; @@ -178,18 +169,14 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode; import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTQueries; -import org.eclipse.cdt.internal.core.dom.parser.ASTTranslationUnit; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousDeclarator; import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; +import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression; -import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTLiteralExpression; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase; -import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTQualifiedName; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTranslationUnit; -import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTypeIdExpression; -import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTUnaryExpression; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBuiltinParameter; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPCompositeBinding; @@ -209,6 +196,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVariable; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPASTInternalScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPClassSpecializationScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalNamespaceScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; @@ -230,21 +218,24 @@ public class CPPSemantics { * The maximum depth to search ancestors before assuming infinite looping. */ public static final int MAX_INHERITANCE_DEPTH= 16; - - public static final ASTNodeProperty STRING_LOOKUP_PROPERTY = - new ASTNodeProperty("CPPSemantics.STRING_LOOKUP_PROPERTY - STRING_LOOKUP"); //$NON-NLS-1$ +// +// public static final ASTNodeProperty STRING_LOOKUP_PROPERTY = +// new ASTNodeProperty("CPPSemantics.STRING_LOOKUP_PROPERTY - STRING_LOOKUP"); //$NON-NLS-1$ public static final String EMPTY_NAME = ""; //$NON-NLS-1$ public static final char[] OPERATOR_ = new char[] {'o','p','e','r','a','t','o','r',' '}; - private static final char[] CALL_FUNCTION = "call-function".toCharArray(); //$NON-NLS-1$ public static final IType VOID_TYPE = new CPPBasicType(Kind.eVoid, 0); public static final IType INT_TYPE = new CPPBasicType(Kind.eInt, 0); + private static final char[] CALL_FUNCTION = "call-function".toCharArray(); //$NON-NLS-1$ + private static final ICPPEvaluation[] NO_INITCLAUSE_EVALUATION = {}; + // Set to true for debugging. public static boolean traceBindingResolution = false; public static int traceIndent= 0; // special return value for costForFunctionCall private static final FunctionCost CONTAINS_DEPENDENT_TYPES = new FunctionCost(null, 0); + static protected IBinding resolveBinding(IASTName name) { if (traceBindingResolution) { for (int i = 0; i < traceIndent; i++) @@ -276,7 +267,7 @@ public class CPPSemantics { // 3: resolve ambiguities IBinding binding; try { - binding = resolveAmbiguities(data, name); + binding = resolveAmbiguities(data); } catch (DOMException e) { binding = e.getProblem(); } @@ -301,17 +292,21 @@ public class CPPSemantics { if (binding instanceof IProblemBinding) return binding; + final IASTName lookupName = data.getLookupName(); + if (lookupName == null) + return binding; + if (binding == null && data.checkClassContainingFriend()) { // 3.4.1-10 if we don't find a name used in a friend declaration in the member declaration's class // we should look in the class granting friendship - IASTNode parent = data.astName.getParent(); + IASTNode parent = lookupName.getParent(); while (parent != null && !(parent instanceof ICPPASTCompositeTypeSpecifier)) parent = parent.getParent(); if (parent instanceof ICPPASTCompositeTypeSpecifier) { IScope scope = ((ICPPASTCompositeTypeSpecifier) parent).getScope(); try { lookup(data, scope); - binding = resolveAmbiguities(data, data.astName); + binding = resolveAmbiguities(data); } catch (DOMException e) { binding = e.getProblem(); } @@ -319,8 +314,8 @@ public class CPPSemantics { } // Explicit type conversion in functional notation - if (binding instanceof ICPPClassTemplate && data.astName instanceof ICPPASTTemplateId) { - final IASTNode parent = data.astName.getParent(); + if (binding instanceof ICPPClassTemplate && lookupName instanceof ICPPASTTemplateId) { + final IASTNode parent = lookupName.getParent(); if (parent instanceof IASTIdExpression && parent.getPropertyInParent() == IASTFunctionCallExpression.FUNCTION_NAME) { return binding; @@ -331,20 +326,22 @@ public class CPPSemantics { * Within the scope of a class template, when the name of the template is neither qualified nor * followed by <, it is equivalent to the name followed by the template parameters enclosed in <>. */ - if (binding instanceof ICPPClassTemplate && !(binding instanceof ICPPClassSpecialization) && - !(binding instanceof ICPPTemplateParameter) && !(data.astName instanceof ICPPASTTemplateId)) { - ASTNodeProperty prop = data.astName.getPropertyInParent(); - if (prop != ICPPASTTemplateId.TEMPLATE_NAME && !data.astName.isQualified()) { + if (binding instanceof ICPPClassTemplate + && !(binding instanceof ICPPClassSpecialization) + && !(binding instanceof ICPPTemplateParameter) + && !(lookupName instanceof ICPPASTTemplateId)) { + ASTNodeProperty prop = lookupName.getPropertyInParent(); + if (prop != ICPPASTTemplateId.TEMPLATE_NAME && !lookupName.isQualified()) { // You cannot use a class template name outside of the class template scope, // mark it as a problem. - IBinding user= CPPTemplates.isUsedInClassTemplateScope((ICPPClassTemplate) binding, data.astName); + IBinding user= CPPTemplates.isUsedInClassTemplateScope((ICPPClassTemplate) binding, lookupName); if (user instanceof ICPPClassTemplate) { binding= ((ICPPClassTemplate) user).asDeferredInstance(); } else if (user != null) { binding= user; } else { boolean ok= false; - IASTNode node= data.astName.getParent(); + IASTNode node= lookupName.getParent(); while (node != null && !ok) { if (node instanceof ICPPASTTemplateId || node instanceof ICPPASTTemplatedTypeTemplateParameter) { @@ -365,7 +362,7 @@ public class CPPSemantics { node= node.getParent(); } if (!ok) { - binding = new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_INVALID_TYPE, + binding = new ProblemBinding(lookupName, IProblemBinding.SEMANTIC_INVALID_TYPE, data.getFoundBindings()); } } @@ -373,7 +370,7 @@ public class CPPSemantics { } else if (binding instanceof ICPPDeferredClassInstance) { // try to replace binding by the one pointing to the enclosing template declaration. ICPPDeferredClassInstance dcl= (ICPPDeferredClassInstance) binding; - IBinding usedHere= CPPTemplates.isUsedInClassTemplateScope(dcl.getClassTemplate(), data.astName); + IBinding usedHere= CPPTemplates.isUsedInClassTemplateScope(dcl.getClassTemplate(), lookupName); if (usedHere instanceof ICPPClassTemplatePartialSpecialization) { if (CPPTemplates.areSameArguments(((ICPPClassTemplatePartialSpecialization) usedHere).getTemplateArguments(), dcl.getTemplateArguments())) binding= ((ICPPClassTemplatePartialSpecialization) usedHere).asDeferredInstance(); @@ -386,17 +383,17 @@ public class CPPSemantics { if (binding instanceof IType) { IType t = getNestedType((IType) binding, TDEF); - if (t instanceof ICPPClassType && convertClassToConstructor(data.astName)) { + if (t instanceof ICPPClassType && convertClassToConstructor(lookupName)) { ICPPClassType cls= (ICPPClassType) t; if (cls instanceof IIndexBinding) { - cls= data.tu.mapToAST(cls); + cls= data.getTranslationUnit().mapToAST(cls, lookupName); } try { - if (data.astName instanceof ICPPASTTemplateId && cls instanceof ICPPClassTemplate) { - if (data.tu != null) { - ICPPASTTemplateId id = (ICPPASTTemplateId) data.astName; + if (lookupName instanceof ICPPASTTemplateId && cls instanceof ICPPClassTemplate) { + if (data.getTranslationUnit() != null) { + ICPPASTTemplateId id = (ICPPASTTemplateId) lookupName; ICPPTemplateArgument[] args = CPPTemplates.createTemplateArgumentArray(id); - IBinding inst= CPPTemplates.instantiate((ICPPClassTemplate) cls, args); + IBinding inst= CPPTemplates.instantiate((ICPPClassTemplate) cls, args, data.getLookupPoint()); if (inst instanceof ICPPClassType) { cls= (ICPPClassType) inst; } @@ -413,7 +410,7 @@ public class CPPSemantics { } } - IASTName name= data.astName; + IASTName name= lookupName; IASTNode nameParent= name.getParent(); if (nameParent instanceof ICPPASTTemplateId) { if (binding instanceof ICPPTemplateInstance) { @@ -453,12 +450,12 @@ public class CPPSemantics { if (parent instanceof IASTTypeId && parent.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_ID_ARGUMENT) { if (!(binding instanceof IType)) { // a type id needs to hold a type - binding = new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_INVALID_TYPE, + binding = new ProblemBinding(lookupName, IProblemBinding.SEMANTIC_INVALID_TYPE, data.getFoundBindings()); } // don't create a problem here } else { - binding = new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_INVALID_TYPE, + binding = new ProblemBinding(lookupName, IProblemBinding.SEMANTIC_INVALID_TYPE, data.getFoundBindings()); } } @@ -474,7 +471,7 @@ public class CPPSemantics { && ((ICPPASTUnaryExpression) idExpr.getParent()).getOperator() == IASTUnaryExpression.op_sizeofParameterPack) { // Argument of sizeof... can be a type } else { - binding= new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_INVALID_TYPE, + binding= new ProblemBinding(lookupName, IProblemBinding.SEMANTIC_INVALID_TYPE, data.getFoundBindings()); } } @@ -487,17 +484,17 @@ public class CPPSemantics { if (declaration != null) { // Functions if (binding instanceof IFunction) { - binding= checkDeclSpecifier(binding, data.astName, declaration); + binding= checkDeclSpecifier(binding, lookupName, declaration); if (!(binding instanceof IProblemBinding)) { if (declaration instanceof ICPPASTFunctionDefinition) { - ASTInternal.addDefinition(binding, data.astName); + ASTInternal.addDefinition(binding, lookupName); } } } // Definitions of static fields. - if (binding instanceof ICPPField && data.astName.isDefinition()) { + if (binding instanceof ICPPField && lookupName.isDefinition()) { if (declaration.getPropertyInParent() != IASTCompositeTypeSpecifier.MEMBER_DECLARATION) { - ASTInternal.addDefinition(binding, data.astName); + ASTInternal.addDefinition(binding, lookupName); } } } @@ -505,10 +502,10 @@ public class CPPSemantics { // If we're still null... if (binding == null) { if (name instanceof ICPPASTQualifiedName && declaration != null) { - binding = new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_MEMBER_DECLARATION_NOT_FOUND, + binding = new ProblemBinding(lookupName, IProblemBinding.SEMANTIC_MEMBER_DECLARATION_NOT_FOUND, data.getFoundBindings()); } else { - binding = new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_NAME_NOT_FOUND, + binding = new ProblemBinding(lookupName, IProblemBinding.SEMANTIC_NAME_NOT_FOUND, data.getFoundBindings()); } } @@ -519,7 +516,7 @@ public class CPPSemantics { if (name == null) return false; final ASTNodeProperty propertyInParent = name.getPropertyInParent(); - if (propertyInParent == CPPSemantics.STRING_LOOKUP_PROPERTY || propertyInParent == null) + if (propertyInParent == null) return false; if (propertyInParent == ICPPASTTemplateId.TEMPLATE_NAME) @@ -547,7 +544,7 @@ public class CPPSemantics { private static void doKoenigLookup(LookupData data) throws DOMException { data.ignoreUsingDirectives = true; - data.forceQualified = true; + data.qualified = true; Set friendFns = new HashSet(2); Set associated = getAssociatedScopes(data, friendFns); for (ICPPNamespaceScope scope : associated) { @@ -599,7 +596,7 @@ public class CPPSemantics { if (parent instanceof IASTDeclarator && parent.getPropertyInParent() == IASTSimpleDeclaration.DECLARATOR) { IASTSimpleDeclaration simple = (IASTSimpleDeclaration) parent.getParent(); if (simple.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef) - data.forceQualified = true; + data.qualified = true; } if (parent instanceof IASTIdExpression) { @@ -631,7 +628,7 @@ public class CPPSemantics { ICPPASTNewExpression newExp = (ICPPASTNewExpression) typeId.getParent(); IASTInitializer init = newExp.getInitializer(); if (init == null) { - data.setFunctionArguments(false); + data.setFunctionArguments(false, NO_INITCLAUSE_EVALUATION); } else if (init instanceof ICPPASTConstructorInitializer) { data.setFunctionArguments(false, ((ICPPASTConstructorInitializer) init).getArguments()); } else if (init instanceof ICPPASTInitializerList) { @@ -660,15 +657,16 @@ public class CPPSemantics { ObjectSet handled = new ObjectSet(2); for (IType p : ps) { try { - getAssociatedScopes(p, namespaces, friendFns, handled, data.tu); + getAssociatedScopes(p, namespaces, friendFns, handled, data.getTranslationUnit()); } catch (DOMException e) { } } - if (data.astName != null) { - final char[] simpleID = data.astName.getSimpleID(); + IASTName lookupName= data.getLookupName(); + if (lookupName != null) { + final char[] simpleID = lookupName.getSimpleID(); if (CharArrayUtils.equals(CPPVisitor.BEGIN, simpleID) || CharArrayUtils.equals(CPPVisitor.END, simpleID)) { - IASTNode parent = data.astName.getParent(); // id-expression + IASTNode parent = lookupName.getParent(); // id-expression if (parent != null) parent= parent.getParent(); // function call if (parent != null) @@ -740,7 +738,7 @@ public class CPPSemantics { getAssociatedScopes(pmt.getType(), namespaces, friendFns, handled, tu); } else if (t instanceof FunctionSetType) { FunctionSetType fst= (FunctionSetType) t; - for (ICPPFunction fn : fst.getFunctionSet()) { + for (ICPPFunction fn : fst.getFunctionSet().getBindings()) { getAssociatedScopes(fn.getType(), namespaces, friendFns, handled, tu); } } @@ -772,7 +770,7 @@ public class CPPSemantics { } } - static ICPPScope getLookupScope(IASTName name, LookupData data) throws DOMException { + static ICPPScope getLookupScope(IASTName name) throws DOMException { IASTNode parent = name.getParent(); IScope scope = null; if (parent instanceof ICPPASTBaseSpecifier) { @@ -783,7 +781,7 @@ public class CPPSemantics { } scope = CPPVisitor.getContainingScope(n); } else { - scope = CPPVisitor.getContainingScope(name, data); + scope = CPPVisitor.getContainingScope(name); } if (scope instanceof ICPPScope) { return (ICPPScope) scope; @@ -873,25 +871,13 @@ public class CPPSemantics { return resultMap; } - private static IIndexFileSet getIndexFileSet(LookupData data) { - if (data.tu != null) { - final IIndexFileSet fs= data.tu.getIndexFileSet(); - if (fs != null) - return fs; - } - return IIndexFileSet.EMPTY; - } - /** * Perform a lookup with the given data starting in the given scope, considering bases and parent scopes. * @param data the lookup data created off a name * @param start either a scope or a name. */ static protected void lookup(LookupData data, IScope start) throws DOMException { - if (data.astName == null) - return; - - if (start == null && lookupDestructor(data, start)) { + if (start == null && lookupDestructor(data)) { return; } @@ -900,18 +886,22 @@ public class CPPSemantics { if (start instanceof ICPPScope) { nextScope= (ICPPScope) start; } else { - nextScope= getLookupScope(data.astName, data); + IASTName lookupName= data.getLookupName(); + if (lookupName == null) + return; + + nextScope= getLookupScope(lookupName); if (nextScope instanceof ICPPTemplateScope) { nextTmplScope= (ICPPTemplateScope) nextScope; - nextScope= getParentScope(nextScope, data.tu); + nextScope= getParentScope(nextScope, data.getTranslationUnit()); } else { - nextTmplScope= enclosingTemplateScope(data.astName); + nextTmplScope= enclosingTemplateScope(lookupName); } - if (!data.usesEnclosingScope && nextTmplScope != null) { + if (data.qualified && nextTmplScope != null) { nextTmplScope= null; - if (dependsOnTemplateFieldReference(data.astName)) { - data.checkPointOfDecl= false; + if (dependsOnTemplateFieldReference(lookupName)) { + data.setIgnorePointOfDeclaration(true); } } } @@ -927,7 +917,6 @@ public class CPPSemantics { } } - final IIndexFileSet fileSet= getIndexFileSet(data); while (nextScope != null || nextTmplScope != null) { // when the non-template scope is no longer contained within the first template scope, // we use the template scope for the next iteration. @@ -942,21 +931,22 @@ public class CPPSemantics { } } ICPPScope scope= useTemplScope ? nextTmplScope : nextScope; - if (scope instanceof IIndexScope && data.tu != null) { - scope= (ICPPScope) data.tu.mapToASTScope(((IIndexScope) scope)); + CPPASTTranslationUnit tu = data.getTranslationUnit(); + if (scope instanceof IIndexScope && tu != null) { + scope= (ICPPScope) tu.mapToASTScope(((IIndexScope) scope)); } if (!data.usingDirectivesOnly && !(data.ignoreMembers && scope instanceof ICPPClassScope)) { - mergeResults(data, getBindingsFromScope(scope, fileSet, data), true); + mergeResults(data, getBindingsFromScope(scope, data), true); // Nominate using-directives found in this block or namespace. if (scope instanceof ICPPNamespaceScope) { final ICPPNamespaceScope blockScope= (ICPPNamespaceScope) scope; - if (data.qualified() && blockScope.getKind() != EScopeKind.eLocal) { - lookupInlineNamespaces(data, fileSet, blockScope); + if (data.qualified && blockScope.getKind() != EScopeKind.eLocal) { + lookupInlineNamespaces(data, blockScope); } - if (data.contentAssist || !data.hasResults() || !data.qualified()) { + if (data.contentAssist || !data.hasResults() || !data.qualified) { // Nominate namespaces nominateNamespaces(data, blockScope); } @@ -965,8 +955,8 @@ public class CPPSemantics { // Lookup in nominated namespaces if (!data.ignoreUsingDirectives && scope instanceof ICPPNamespaceScope && !(scope instanceof ICPPBlockScope)) { - if (!data.hasResults() || !data.qualified() || data.contentAssist) { - lookupInNominated(data, fileSet, (ICPPNamespaceScope) scope); + if (!data.hasResults() || !data.qualified || data.contentAssist) { + lookupInNominated(data, (ICPPNamespaceScope) scope); } } @@ -977,12 +967,12 @@ public class CPPSemantics { // Lookup in base classes if (!data.usingDirectivesOnly && scope instanceof ICPPClassScope && !data.ignoreMembers) { - BaseClassLookup.lookupInBaseClasses(data, (ICPPClassScope) scope, fileSet); + BaseClassLookup.lookupInBaseClasses(data, (ICPPClassScope) scope); if (!data.contentAssist && data.hasResultOrProblem()) return; } - if (data.qualified() && !(scope instanceof ICPPTemplateScope)) { + if (data.qualified && !(scope instanceof ICPPTemplateScope)) { if (data.ignoreUsingDirectives || data.usingDirectives.isEmpty()) return; data.usingDirectivesOnly = true; @@ -992,7 +982,7 @@ public class CPPSemantics { if (useTemplScope && nextTmplScope != null) { nextTmplScope= enclosingTemplateScope(nextTmplScope.getTemplateDeclaration()); } else { - nextScope= getParentScope(scope, data.tu); + nextScope= getParentScope(scope, data.getTranslationUnit()); } } } @@ -1010,7 +1000,8 @@ public class CPPSemantics { for (Object item : (Object[]) data.foundItems) { if (item instanceof IBinding) { IBinding binding = (IBinding) item; - if (!isFromIndex(binding) || data.tu == null || isReachableFromAst(data.tu, binding)) { + CPPASTTranslationUnit tu = data.getTranslationUnit(); + if (!isFromIndex(binding) || tu == null || isReachableFromAst(tu, binding)) { return true; } } @@ -1019,12 +1010,12 @@ public class CPPSemantics { return false; } - private static void lookupInlineNamespaces(LookupData data, IIndexFileSet fileSet, ICPPNamespaceScope namespace) throws DOMException { + private static void lookupInlineNamespaces(LookupData data, ICPPNamespaceScope namespace) throws DOMException { if (namespace instanceof ICPPInternalNamespaceScope) { ICPPInternalNamespaceScope ns= (ICPPInternalNamespaceScope) namespace; for (ICPPInternalNamespaceScope inline : ns.getInlineNamespaces()) { - mergeResults(data, getBindingsFromScope(inline, fileSet, data), true); - lookupInlineNamespaces(data, fileSet, inline); + mergeResults(data, getBindingsFromScope(inline, data), true); + lookupInlineNamespaces(data, inline); nominateNamespaces(data, inline); } } @@ -1035,23 +1026,26 @@ public class CPPSemantics { final boolean isBlockScope = blockScope.getKind() == EScopeKind.eLocal; if (!isBlockScope) { data.visited.put(blockScope); // Mark as searched. - if (data.tu != null) { - data.tu.handleAdditionalDirectives(blockScope); + CPPASTTranslationUnit tu= data.getTranslationUnit(); + if (tu != null) { + tu.handleAdditionalDirectives(blockScope); } } ICPPUsingDirective[] uds= blockScope.getUsingDirectives(); if (uds != null && uds.length > 0) { HashSet handled= new HashSet(); for (final ICPPUsingDirective ud : uds) { - if (declaredBefore(ud, data.astName, false)) { + if (data.isIgnorePointOfDeclaration() || declaredBefore(ud, data.getLookupPoint(), false)) { storeUsingDirective(data, blockScope, ud, handled); } } } } - private static boolean lookupDestructor(LookupData data, IScope start) throws DOMException { - IASTName typeDtorName= data.astName; + private static boolean lookupDestructor(LookupData data) throws DOMException { + IASTName typeDtorName= data.getLookupName(); + if (typeDtorName == null) + return false; final char[] typeDtorChars= typeDtorName.getSimpleID(); if (typeDtorChars.length == 0 || typeDtorChars[0] != '~') return false; @@ -1059,46 +1053,27 @@ public class CPPSemantics { // Assume class C; typedef C T; // When looking up ~T the strategy is to lookup T::~C in two steps: // * First resolve 'T', then compute '~C' and resolve it. - CPPASTQualifiedName syntheticName= new CPPASTQualifiedName(); IASTNode parent= typeDtorName.getParent(); if (parent instanceof ICPPASTQualifiedName) { ICPPASTQualifiedName dqname= (ICPPASTQualifiedName) parent; - if (dqname.getLastName() != data) + if (dqname.getLastName() != typeDtorName) return false; - - syntheticName.setFullyQualified(dqname.isFullyQualified()); - IASTName[] children = dqname.getNames(); - for (IASTName child : children) { - if (child != data) { - final IASTName childCopy = child.copy(); - childCopy.setBinding(child.resolveBinding()); - syntheticName.addName(childCopy); - } - } - syntheticName.setOffsetAndLength((ASTNode) parent); - syntheticName.setParent(parent.getParent()); - syntheticName.setPropertyInParent(parent.getPropertyInParent()); - } else { - syntheticName.setOffsetAndLength((ASTNode) typeDtorName); - syntheticName.setParent(parent); - syntheticName.setPropertyInParent(typeDtorName.getPropertyInParent()); } char[] tchars= new char[typeDtorChars.length-1]; System.arraycopy(typeDtorChars, 1, tchars, 0, tchars.length); - final CPPASTName typeName = new CPPASTName(tchars); - typeName.setOffsetAndLength((ASTNode) typeDtorName); - syntheticName.addName(typeName); - - final CPPASTName classDtorName = new CPPASTName(typeDtorChars); - classDtorName.setOffsetAndLength((ASTNode) typeDtorName); - syntheticName.addName(classDtorName); - - IBinding type= resolveBinding(typeName); - if (!(type instanceof ITypedef)) + LookupData ld2= new LookupData(tchars, data.fTemplateArguments, data.getLookupPoint()); + ld2.setIgnorePointOfDeclaration(data.isIgnorePointOfDeclaration()); + ld2.contentAssist= data.contentAssist; + ld2.fNoNarrowing= data.fNoNarrowing; + ld2.qualified= parent instanceof ICPPASTQualifiedName; + ld2.typesOnly= true; + lookup(ld2, getLookupScope(typeDtorName)); + IBinding[] typedefs = ld2.getFoundBindings(); + if (typedefs.length < 1 || !(typedefs[0] instanceof ITypedef)) return false; - - IType t= SemanticUtil.getNestedType((ITypedef) type, TDEF); + + IType t= SemanticUtil.getNestedType((ITypedef) typedefs[0], TDEF); if (t instanceof ICPPUnknownBinding || t instanceof ISemanticProblem || !(t instanceof ICPPClassType)) { return false; @@ -1114,14 +1089,8 @@ public class CPPSemantics { char[] classDtorChars= new char[classChars.length+1]; classDtorChars[0]= '~'; System.arraycopy(classChars, 0, classDtorChars, 1, classChars.length); - classDtorName.setName(classDtorChars); - - data.astName = classDtorName; - try { - lookup(data, scope); - } finally { - data.astName= typeDtorName; - } + data.setLookupKey(classDtorChars); + lookup(data, scope); return true; } @@ -1171,9 +1140,10 @@ public class CPPSemantics { @Override public int visit(IASTExpression expression) { - if (expression instanceof IASTLiteralExpression) { - if (((IASTLiteralExpression) expression).getKind() == IASTLiteralExpression.lk_this) { - final IType thisType = SemanticUtil.getNestedType(typeOrFunctionSet(expression), TDEF | ALLCVQ | PTR | ARRAY | MPTR | REF); + if (expression instanceof ICPPASTLiteralExpression) { + final ICPPASTLiteralExpression litExpr = (ICPPASTLiteralExpression) expression; + if (litExpr.getKind() == IASTLiteralExpression.lk_this) { + final IType thisType = SemanticUtil.getNestedType(litExpr.getEvaluation().getTypeOrFunctionSet(litExpr), TDEF | ALLCVQ | PTR | ARRAY | MPTR | REF); if (thisType instanceof ICPPUnknownBinding || thisType instanceof ICPPTemplateDefinition) { result[0]= true; return PROCESS_ABORT; @@ -1218,35 +1188,28 @@ public class CPPSemantics { return result[0]; } - static IBinding[] getBindingsFromScope(ICPPScope scope, final IIndexFileSet fileSet, LookupData data) throws DOMException { - IBinding[] bindings; + static IBinding[] getBindingsFromScope(ICPPScope scope, LookupData data) throws DOMException { + IBinding[] bindings= scope.getBindings(data); - // For internal scopes we need to check the point of declaration - if (scope instanceof ICPPASTInternalScope) { - final IASTName astName = data.astName; - final ICPPASTInternalScope internalScope = (ICPPASTInternalScope) scope; - bindings= internalScope.getBindings(astName, true, data.prefixLookup, fileSet, data.checkPointOfDecl); - - // Bug 103857: Members declared after the point of completion cannot be - // found in the partial AST, we look them up in the index - if (data.checkWholeClassScope && scope instanceof ICPPClassScope) { - final IASTTranslationUnit tu = astName.getTranslationUnit(); - if (tu instanceof ASTTranslationUnit && ((ASTTranslationUnit) tu).isForContentAssist()) { + if (scope instanceof ICPPASTInternalScope && scope instanceof ICPPClassScope) { + final IASTName lookupName = data.getLookupName(); + if (LookupData.checkWholeClassScope(lookupName)) { + // Bug 103857: Members declared after the point of completion cannot be + // found in the partial AST, we look them up in the index + CPPASTTranslationUnit tu = data.getTranslationUnit(); + if (tu != null && tu.isForContentAssist()) { IIndex index = tu.getIndex(); - IASTNode node = internalScope.getPhysicalNode(); - if (index != null && node != null && node.contains(astName)) { + IASTNode node = ((IASTInternalScope) scope).getPhysicalNode(); + if (index != null && node != null && node.contains(lookupName)) { IBinding indexBinding= index.adaptBinding(((ICPPClassScope) scope).getClassType()); if (indexBinding instanceof ICPPClassType) { IScope scopeInIndex= ((ICPPClassType) indexBinding).getCompositeScope(); - bindings= ArrayUtil.addAll(bindings, scopeInIndex.getBindings(astName, true, data.prefixLookup, fileSet)); + bindings= ArrayUtil.addAll(bindings, scopeInIndex.getBindings(data)); } } } } - } else { - // For index scopes the point of declaration is ignored. - bindings= scope.getBindings(data.astName, true, data.prefixLookup, fileSet); - } + } return expandUsingDeclarationsAndRemoveObjects(bindings, data); } @@ -1313,15 +1276,15 @@ public class CPPSemantics { return ((ICPPASTTemplateDeclaration) parent).getScope(); } - static ICPPScope getParentScope(IScope scope, CPPASTTranslationUnit unit) throws DOMException { + static ICPPScope getParentScope(IScope scope, ICPPASTTranslationUnit unit) throws DOMException { IScope parentScope= scope.getParent(); // the index cannot return the translation unit as parent scope - if (unit != null) { + if (unit instanceof CPPASTTranslationUnit) { if (parentScope == null && (scope instanceof IIndexScope || scope instanceof ICPPClassSpecializationScope)) { parentScope = unit.getScope(); } else if (parentScope instanceof IIndexScope) { - parentScope = unit.mapToASTScope((IIndexScope) parentScope); + parentScope = ((CPPASTTranslationUnit) unit).mapToASTScope((IIndexScope) parentScope); } } return (ICPPScope) parentScope; @@ -1335,14 +1298,15 @@ public class CPPSemantics { private static void storeUsingDirective(LookupData data, ICPPNamespaceScope container, ICPPUsingDirective directive, Set handled) throws DOMException { ICPPNamespaceScope nominated= directive.getNominatedScope(); - if (nominated instanceof IIndexScope && data.tu != null) { - nominated= (ICPPNamespaceScope) data.tu.mapToASTScope((IIndexScope) nominated); + CPPASTTranslationUnit tu= data.getTranslationUnit(); + if (nominated instanceof IIndexScope && tu != null) { + nominated= (ICPPNamespaceScope) tu.mapToASTScope((IIndexScope) nominated); } if (nominated == null || data.visited.containsKey(nominated) || (handled != null && !handled.add(nominated))) { return; } // 7.3.4.1 names appear at end of common enclosing scope of container and nominated scope. - final IScope appearsIn= getCommonEnclosingScope(nominated, container, data.tu); + final IScope appearsIn= getCommonEnclosingScope(nominated, container, tu); if (appearsIn instanceof ICPPNamespaceScope) { // store the directive with the scope where it has to be considered List listOfNominated= data.usingDirectives.get(appearsIn); @@ -1358,10 +1322,10 @@ public class CPPSemantics { // in a non-qualified lookup the transitive directive have to be stored right away, they may overtake the // container. - if (!data.qualified() || data.contentAssist) { + if (!data.qualified || data.contentAssist) { assert handled != null; - if (data.tu != null) { - data.tu.handleAdditionalDirectives(nominated); + if (tu != null) { + tu.handleAdditionalDirectives(nominated); } ICPPUsingDirective[] transitive= nominated.getUsingDirectives(); for (ICPPUsingDirective element : transitive) { @@ -1373,7 +1337,7 @@ public class CPPSemantics { /** * Computes the common enclosing scope of s1 and s2. */ - private static ICPPScope getCommonEnclosingScope(IScope s1, IScope s2, CPPASTTranslationUnit tu) throws DOMException { + private static ICPPScope getCommonEnclosingScope(IScope s1, IScope s2, ICPPASTTranslationUnit tu) throws DOMException { ObjectSet set = new ObjectSet(2); IScope parent= s1; while (parent != null) { @@ -1723,8 +1687,7 @@ public class CPPSemantics { * directive returns empty. * @param fileSet */ - private static void lookupInNominated(LookupData data, IIndexFileSet fileSet, - ICPPNamespaceScope scope) throws DOMException { + private static void lookupInNominated(LookupData data, ICPPNamespaceScope scope) throws DOMException { List allNominated= data.usingDirectives.remove(scope); while (allNominated != null) { for (ICPPNamespaceScope nominated : allNominated) { @@ -1734,7 +1697,7 @@ public class CPPSemantics { data.visited.put(nominated); boolean found = false; - IBinding[] bindings= getBindingsFromScope(nominated, fileSet, data); + IBinding[] bindings= getBindingsFromScope(nominated, data); if (bindings != null && bindings.length > 0) { mergeResults(data, bindings, true); found = true; @@ -1743,9 +1706,10 @@ public class CPPSemantics { // In the qualified lookup we have to nominate the transitive directives only when // the lookup did not succeed. In the qualified case this is done earlier, when // the directive is encountered. - if (!found && data.qualified() && !data.contentAssist) { - if (data.tu != null) { - data.tu.handleAdditionalDirectives(nominated); + if (!found && data.qualified && !data.contentAssist) { + final CPPASTTranslationUnit tu = data.getTranslationUnit(); + if (tu != null) { + tu.handleAdditionalDirectives(nominated); } ICPPUsingDirective[] usings= nominated.getUsingDirectives(); for (ICPPUsingDirective using : usings) { @@ -1791,25 +1755,23 @@ public class CPPSemantics { } } - if (name.getPropertyInParent() != STRING_LOOKUP_PROPERTY) { - LookupData data = createLookupData(name); - data.foundItems = bindings; - try { - return resolveAmbiguities(data, name); - } catch (DOMException e) { - return e.getProblem(); - } + LookupData data = createLookupData(name); + data.foundItems = bindings; + try { + return resolveAmbiguities(data); + } catch (DOMException e) { + return e.getProblem(); } - - IBinding[] result = null; - for (Object binding : bindings) { - if (binding instanceof IASTName) { - result = ArrayUtil.append(IBinding.class, result, ((IASTName) binding).resolveBinding()); - } else if (binding instanceof IBinding) { - result = ArrayUtil.append(IBinding.class, result, (IBinding) binding); - } - } - return new CPPCompositeBinding(result); +// +// IBinding[] result = null; +// for (Object binding : bindings) { +// if (binding instanceof IASTName) { +// result = ArrayUtil.append(IBinding.class, result, ((IASTName) binding).resolveBinding()); +// } else if (binding instanceof IBinding) { +// result = ArrayUtil.append(IBinding.class, result, (IBinding) binding); +// } +// } +// return new CPPCompositeBinding(result); } public static boolean declaredBefore(Object obj, IASTNode node, boolean indexBased) { @@ -1817,10 +1779,6 @@ public class CPPSemantics { return true; final int pointOfRef= ((ASTNode) node).getOffset(); - if (node.getPropertyInParent() == STRING_LOOKUP_PROPERTY && pointOfRef <= 0) { - return true; - } - ASTNode nd = null; if (obj instanceof ICPPSpecialization) { obj = ((ICPPSpecialization) obj).getSpecializedBinding(); @@ -1919,24 +1877,27 @@ public class CPPSemantics { return false; } - private static IBinding resolveAmbiguities(LookupData data, IASTName name) throws DOMException { + private static IBinding resolveAmbiguities(LookupData data) throws DOMException { if (!data.hasResults() || data.contentAssist) return null; - final boolean indexBased= data.tu != null && data.tu.getIndex() != null; + final IASTName lookupName = data.getLookupName(); + final boolean indexBased= data.getIndex() != null; + final boolean checkWholeClass= lookupName == null || LookupData.checkWholeClassScope(lookupName); @SuppressWarnings("unchecked") ObjectSet fns= ObjectSet.EMPTY_SET; IBinding type = null; IBinding obj = null; IBinding temp = null; + final CPPASTTranslationUnit tu = data.getTranslationUnit(); Object[] items = (Object[]) data.foundItems; - for (int i = 0; i < items.length && items[i] != null; i++) { + for (int i = 0; i < items.length && items[i] != null; i++) { Object o = items[i]; - boolean declaredBefore = !data.checkPointOfDecl || declaredBefore(o, name, indexBased); + boolean declaredBefore = data.isIgnorePointOfDeclaration() || declaredBefore(o, data.getLookupPoint(), indexBased); boolean checkResolvedNamesOnly= false; - if (!data.checkWholeClassScope && !declaredBefore) { - if (name.getRoleOfName(false) != IASTNameOwner.r_reference) { + if (!checkWholeClass && !declaredBefore) { + if (lookupName != null && lookupName.getRoleOfName(false) != IASTNameOwner.r_reference) { checkResolvedNamesOnly= true; declaredBefore= true; } else { @@ -1998,7 +1959,7 @@ public class CPPSemantics { if (type == null) { type = temp; } else if (!type.equals(temp)) { - int c = compareByRelevance(data.tu, type, temp); + int c = compareByRelevance(tu, type, temp); if (c < 0) { type= temp; } else if (c == 0) { @@ -2008,7 +1969,7 @@ public class CPPSemantics { type= temp; } } else { - return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, + return new ProblemBinding(lookupName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.getFoundBindings()); } } @@ -2019,17 +1980,17 @@ public class CPPSemantics { } else if (obj.equals(temp)) { // Ok, delegates are synonyms. } else { - int c = compareByRelevance(data.tu, obj, temp); + int c = compareByRelevance(tu, obj, temp); if (c < 0) { obj= temp; } else if (c == 0) { - return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, + return new ProblemBinding(lookupName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.getFoundBindings()); } } } } - if (data.forUsingDeclaration()) { + if (data.forUsingDeclaration) { int cmp= -1; if (obj != null) { cmp= 1; @@ -2037,7 +1998,7 @@ public class CPPSemantics { IFunction[] fnArray= fns.keyArray(IFunction.class); cmp= compareByRelevance(data, obj, fnArray); if (cmp == 0) { - return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, + return new ProblemBinding(lookupName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.getFoundBindings()); } } @@ -2052,13 +2013,13 @@ public class CPPSemantics { bindings = ArrayUtil.addAll(bindings, fns.keyArray()); } bindings = ArrayUtil.trim(IBinding.class, bindings); - ICPPUsingDeclaration composite = new CPPUsingDeclaration(data.astName, bindings); + ICPPUsingDeclaration composite = new CPPUsingDeclaration(lookupName, bindings); return composite; } if (obj != null && type != null) { if (obj instanceof ICPPNamespace) { - if (compareByRelevance(data.tu, type, obj) >= 0) { + if (compareByRelevance(tu, type, obj) >= 0) { obj= null; } } else if (!data.typesOnly && overrulesByRelevance(data, type, obj)) { @@ -2082,7 +2043,7 @@ public class CPPSemantics { if (obj != null) { int cmp= compareByRelevance(data, obj, fnArray); if (cmp == 0) { - return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, + return new ProblemBinding(lookupName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.getFoundBindings()); } if (cmp > 0) { @@ -2134,8 +2095,11 @@ public class CPPSemantics { * latter is not. */ static boolean overrulesByRelevance(LookupData data, IBinding type, IBinding b2) { - if (data != null && data.tu != null) { - return !isReachableFromAst(data.tu, b2) && isReachableFromAst(data.tu, type); + if (data == null) + return false; + final CPPASTTranslationUnit tu = data.getTranslationUnit(); + if (tu != null) { + return !isReachableFromAst(tu, b2) && isReachableFromAst(tu, type); } return false; } @@ -2146,9 +2110,9 @@ public class CPPSemantics { * the former is reachable but none of the functions are. */ static boolean overrulesByRelevance(LookupData data, IBinding type, IFunction[] fns) { - if (data == null || data.tu == null) { + if (data == null) return false; - } + final CPPASTTranslationUnit tu = data.getTranslationUnit(); for (int i = 0; i < fns.length; i++) { if (!isFromIndex(fns[i])) { @@ -2156,12 +2120,12 @@ public class CPPSemantics { } } - if (!isReachableFromAst(data.tu, type)) { + if (!isReachableFromAst(tu, type)) { return false; } for (IFunction fn : fns) { - if (isReachableFromAst(data.tu, fn)) { + if (isReachableFromAst(tu, fn)) { return false; // function from ast } } @@ -2188,9 +2152,10 @@ public class CPPSemantics { return !b1FromIndex ? 1 : -1; } else if (b1FromIndex) { // Both are from index. - if (data.tu != null) { - boolean b1Reachable= isReachableFromAst(data.tu, b1); - boolean b2Reachable= isReachableFromAst(data.tu, b2); + final CPPASTTranslationUnit tu = data.getTranslationUnit(); + if (tu != null) { + boolean b1Reachable= isReachableFromAst(tu, b1); + boolean b2Reachable= isReachableFromAst(tu, b2); if (b1Reachable != b2Reachable) { return b1Reachable ? 1 : -1; } @@ -2216,12 +2181,13 @@ public class CPPSemantics { } } // Everything is from the index - if (!isReachableFromAst(data.tu, obj)) { + final CPPASTTranslationUnit tu = data.getTranslationUnit(); + if (!isReachableFromAst(tu, obj)) { return -1; // obj not reachable } for (IFunction fn : fns) { - if (isReachableFromAst(data.tu, fn)) { + if (isReachableFromAst(tu, fn)) { return 0; // obj reachable, 1 function reachable } } @@ -2352,16 +2318,17 @@ public class CPPSemantics { } public static IBinding resolveFunction(LookupData data, ICPPFunction[] fns, boolean allowUDC) throws DOMException { - if (fns == null || fns.length == 0 || fns[0] == null) + final IASTName lookupName = data.getLookupName(); + if (fns == null || fns.length == 0 || fns[0] == null) return null; fns= ArrayUtil.trim(fns); sortAstBeforeIndex(fns); - if (data.forUsingDeclaration()) - return new CPPUsingDeclaration(data.astName, fns); + if (data.forUsingDeclaration) + return new CPPUsingDeclaration(lookupName, fns); - if (data.astName instanceof ICPPASTConversionName) { + if (lookupName instanceof ICPPASTConversionName) { return resolveUserDefinedConversion(data, fns); } @@ -2370,18 +2337,20 @@ public class CPPSemantics { } // No arguments to resolve function + final IASTNode lookupPoint = data.getLookupPoint(); if (!data.hasFunctionArguments()) { - return createFunctionSet(data.astName, fns); + return createFunctionSet(fns, data.fTemplateArguments, lookupPoint, lookupName); } // Reduce our set of candidate functions to only those who have the right number of parameters final IType[] argTypes = data.getFunctionArgumentTypes(); ICPPFunction[] tmp= selectByArgumentCount(data, fns); - tmp= CPPTemplates.instantiateForFunctionCall(data.astName, tmp, + tmp= CPPTemplates.instantiateForFunctionCall(tmp, data.fTemplateArguments, Arrays.asList(argTypes), - Arrays.asList(data.getFunctionArgumentValueCategories()), data.argsContainImpliedObject); + Arrays.asList(data.getFunctionArgumentValueCategories()), + data.argsContainImpliedObject, lookupPoint); if (tmp.length == 0 || tmp[0] == null) - return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_NAME_NOT_FOUND, fns); + return new ProblemBinding(lookupName, IProblemBinding.SEMANTIC_NAME_NOT_FOUND, fns); int viableCount= 0; for (IFunction f : tmp) { @@ -2394,7 +2363,7 @@ public class CPPSemantics { ++viableCount; } if (viableCount == 0) - return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_NAME_NOT_FOUND, fns); + return new ProblemBinding(lookupName, IProblemBinding.SEMANTIC_NAME_NOT_FOUND, fns); // Check for dependent arguments fns= tmp; @@ -2411,6 +2380,7 @@ public class CPPSemantics { // Loop over all functions List potentialCosts= null; IFunction unknownFunction= null; + final CPPASTTranslationUnit tu = data.getTranslationUnit(); for (ICPPFunction fn : fns) { if (fn == null) continue; @@ -2433,7 +2403,7 @@ public class CPPSemantics { potentialCosts.add(fnCost); continue; } - int cmp= fnCost.compareTo(data.tu, bestFnCost); + int cmp= fnCost.compareTo(tu, bestFnCost, lookupPoint); if (cmp < 0) { bestFnCost= fnCost; ambiguousFunctions= null; @@ -2444,8 +2414,8 @@ public class CPPSemantics { if (potentialCosts != null) { for (FunctionCost fnCost : potentialCosts) { - if (!fnCost.mustBeWorse(bestFnCost) && fnCost.performUDC()) { - int cmp= fnCost.compareTo(data.tu, bestFnCost); + if (!fnCost.mustBeWorse(bestFnCost) && fnCost.performUDC(lookupPoint)) { + int cmp= fnCost.compareTo(tu, bestFnCost, lookupPoint); if (cmp < 0) { bestFnCost= fnCost; ambiguousFunctions= null; @@ -2466,11 +2436,11 @@ public class CPPSemantics { if (ambiguousFunctions != null) { ambiguousFunctions= ArrayUtil.append(IFunction.class, ambiguousFunctions, bestFnCost.getFunction()); - return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, + return new ProblemBinding(lookupName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, ambiguousFunctions); } if (bestFnCost.hasAmbiguousUserDefinedConversion()) { - return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, + return new ProblemBinding(lookupName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.getFoundBindings()); } @@ -2490,18 +2460,18 @@ public class CPPSemantics { return result; } - private static IBinding createFunctionSet(IASTName name, ICPPFunction[] fns) { + private static IBinding createFunctionSet(ICPPFunction[] fns, ICPPTemplateArgument[] args, IASTNode point, IASTName name) { // First try to find a unique function - ICPPFunction f= getUniqueFunctionForSet(name, fns); - return f == null ? new CPPFunctionSet(fns) : f; - } - - private static ICPPFunction getUniqueFunctionForSet(IASTName name, ICPPFunction[] fns) { - // First try to find a unique function - if (name.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME) { + if (name != null && name.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME) { name= (IASTName) name.getParent(); } - final boolean haveTemplateArgs= name instanceof ICPPASTTemplateId; + ICPPFunction f= getUniqueFunctionForSet(fns, args, point); + return f == null ? new CPPFunctionSet(fns, args, name) : f; + } + + private static ICPPFunction getUniqueFunctionForSet(ICPPFunction[] fns, + ICPPTemplateArgument[] args, IASTNode point) { + // First try to find a unique function ICPPFunction result= null; boolean haveASTResult= false; for (ICPPFunction f : fns) { @@ -2512,11 +2482,11 @@ public class CPPSemantics { if (f instanceof ICPPFunctionTemplate) { // Works only if there are template arguments - if (!haveTemplateArgs || result != null) + if (args == null || result != null) return null; result= f; haveASTResult= !fromIndex; - } else if (!haveTemplateArgs) { + } else if (args == null) { if (result != null) return null; result= f; @@ -2524,8 +2494,8 @@ public class CPPSemantics { } } - if (result instanceof ICPPFunctionTemplate) - return CPPTemplates.instantiateForAddressOfFunction((ICPPFunctionTemplate) result, null, name); + if (result instanceof ICPPFunctionTemplate) + return CPPTemplates.instantiateForAddressOfFunction((ICPPFunctionTemplate) result, null, args, point); return result; } @@ -2550,7 +2520,7 @@ public class CPPSemantics { final ICPPFunctionType ft= (ICPPFunctionType) t; - IASTName templateID= data.astName; + IASTName templateID= data.getLookupName(); if (templateID.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME) { templateID= (ICPPASTTemplateId) templateID.getParent(); } @@ -2575,7 +2545,7 @@ public class CPPSemantics { } // Try to instantiate a template - IASTTranslationUnit tu= data.tu; + IASTTranslationUnit tu= data.getTranslationUnit(); ICPPTemplateArgument[] tmplArgs= ICPPTemplateArgument.EMPTY_ARGUMENTS; if (templateID instanceof ICPPASTTemplateId) { tmplArgs = CPPTemplates.createTemplateArgumentArray((ICPPASTTemplateId) templateID); @@ -2588,9 +2558,9 @@ public class CPPSemantics { if (fn instanceof ICPPFunctionTemplate && !(fn instanceof IProblemBinding) && !(fn instanceof ICPPUnknownBinding)) { ICPPFunctionTemplate template= (ICPPFunctionTemplate) fn; - ICPPFunction inst= CPPTemplates.instantiateForFunctionDeclaration(template, tmplArgs, ft); + ICPPFunction inst= CPPTemplates.instantiateForFunctionDeclaration(template, tmplArgs, ft, data.getLookupPoint()); if (inst != null) { - int cmp= CPPTemplates.orderFunctionTemplates(bestTemplate, template, TypeSelection.PARAMETERS_AND_RETURN_TYPE); + int cmp= CPPTemplates.orderFunctionTemplates(bestTemplate, template, TypeSelection.PARAMETERS_AND_RETURN_TYPE, data.getLookupPoint()); if (cmp == 0) cmp= compareByRelevance(tu, bestTemplate, template); @@ -2606,7 +2576,7 @@ public class CPPSemantics { } } if (isAmbiguous) - return new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, fns); + return new ProblemBinding(data.getLookupName(), IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, fns); return bestInst; } @@ -2669,7 +2639,7 @@ public class CPPSemantics { cost = new Cost(impliedObjectType, implicitParameterType, Rank.IDENTITY); cost.setImpliedObject(); } else { - cost = Conversions.checkImplicitConversionSequence(implicitParameterType, impliedObjectType, sourceIsLValue, UDCMode.FORBIDDEN, Context.IMPLICIT_OBJECT); + cost = Conversions.checkImplicitConversionSequence(implicitParameterType, impliedObjectType, sourceIsLValue, UDCMode.FORBIDDEN, Context.IMPLICIT_OBJECT, data.getLookupPoint()); if (cost.converts()) { cost.setImpliedObject(); } else { @@ -2709,7 +2679,7 @@ public class CPPSemantics { } if (argType instanceof FunctionSetType) { - cost= ((FunctionSetType) argType).costForTarget(paramType); + cost= ((FunctionSetType) argType).costForTarget(paramType, data.getLookupPoint()); } else if (argType.isSameType(paramType)) { cost = new Cost(argType, paramType, Rank.IDENTITY); } else { @@ -2725,7 +2695,7 @@ public class CPPSemantics { } } } - cost = Conversions.checkImplicitConversionSequence(paramType, argType, sourceIsLValue, udc, ctx); + cost = Conversions.checkImplicitConversionSequence(paramType, argType, sourceIsLValue, udc, ctx, data.getLookupPoint()); if (data.fNoNarrowing && cost.isNarrowingConversion()) { cost= Cost.NO_CONVERSION; } @@ -2750,14 +2720,14 @@ public class CPPSemantics { } private static IBinding resolveUserDefinedConversion(LookupData data, ICPPFunction[] fns) { - ICPPASTConversionName astName= (ICPPASTConversionName) data.astName; + ICPPASTConversionName astName= (ICPPASTConversionName) data.getLookupName(); IType t= CPPVisitor.createType(astName.getTypeId()); if (t instanceof ISemanticProblem) { return new ProblemBinding(astName, IProblemBinding.SEMANTIC_INVALID_TYPE, data.getFoundBindings()); } if (data.forDeclaration() == null || data.forExplicitFunctionSpecialization() || data.forExplicitFunctionInstantiation()) { - fns= CPPTemplates.instantiateConversionTemplates(fns, t); + fns= CPPTemplates.instantiateConversionTemplates(fns, t, data.getLookupPoint()); } IFunction unknown= null; @@ -2779,7 +2749,7 @@ public class CPPSemantics { /** * 13.4-1 A use of an overloaded function without arguments is resolved in certain contexts to a function */ - static IBinding resolveTargetedFunction(IASTName name, ICPPFunction[] fns) { + static IBinding resolveTargetedFunction(IASTName name, CPPFunctionSet functionSet) { boolean addressOf= false; IASTNode node= name.getParent(); while (node instanceof IASTName) @@ -2924,19 +2894,20 @@ public class CPPSemantics { return newBinding; } - ICPPFunction function = resolveTargetedFunction(targetType, name, fns); + ICPPFunction function = resolveTargetedFunction(targetType, functionSet, name); if (function == null) return new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_OVERLOAD); return function; } - static ICPPFunction resolveTargetedFunction(IType targetType, IASTName name, ICPPFunction[] fns) { + static ICPPFunction resolveTargetedFunction(IType targetType, CPPFunctionSet set, IASTNode point) { targetType= getNestedType(targetType, TDEF | REF | CVTYPE | PTR | MPTR); if (!(targetType instanceof ICPPFunctionType)) return null; // First pass, consider functions + ICPPFunction[] fns= set.getBindings(); for (ICPPFunction fn : fns) { if (!(fn instanceof ICPPFunctionTemplate)) { if (targetType.isSameType(fn.getType())) @@ -2948,14 +2919,14 @@ public class CPPSemantics { ICPPFunction result= null; ICPPFunctionTemplate resultTemplate= null; boolean isAmbiguous= false; - final IASTTranslationUnit tu= name.getTranslationUnit(); + final IASTTranslationUnit tu= point.getTranslationUnit(); for (IFunction fn : fns) { try { if (fn instanceof ICPPFunctionTemplate) { final ICPPFunctionTemplate template = (ICPPFunctionTemplate) fn; - ICPPFunction inst= CPPTemplates.instantiateForAddressOfFunction(template, (ICPPFunctionType) targetType, name); + ICPPFunction inst= CPPTemplates.instantiateForAddressOfFunction(template, (ICPPFunctionType) targetType, set.getTemplateArguments(), point); if (inst != null) { - int cmp= CPPTemplates.orderFunctionTemplates(resultTemplate, template, TypeSelection.PARAMETERS_AND_RETURN_TYPE); + int cmp= CPPTemplates.orderFunctionTemplates(resultTemplate, template, TypeSelection.PARAMETERS_AND_RETURN_TYPE, point); if (cmp == 0) cmp= compareByRelevance(tu, resultTemplate, template); @@ -2978,47 +2949,53 @@ public class CPPSemantics { return result; } - public static ICPPFunction findOverloadedOperator(IASTArraySubscriptExpression exp) { - final IASTExpression arrayExpression = exp.getArrayExpression(); - IASTInitializerClause[] args = {arrayExpression, exp.getArgument()}; - IType type = typeOrFunctionSet(arrayExpression); - type = SemanticUtil.getNestedType(type, TDEF | REF | CVTYPE); - return findOverloadedOperator(exp, args, type, OverloadableOperator.BRACKET, LookupMode.NO_GLOBALS); - } + public static ICPPFunction findOverloadedBinaryOperator(IASTNode point, OverloadableOperator op, ICPPEvaluation arg1, ICPPEvaluation arg2) { + if (op == null || arg1 == null || arg2 == null) + return null; + + IType op1type = getNestedType(arg1.getTypeOrFunctionSet(point), TDEF | REF | CVTYPE); + if (!isUserDefined(op1type) && !isUserDefined( + getNestedType(arg2.getTypeOrFunctionSet(point), TDEF | REF | CVTYPE))) + return null; - public static ICPPFunction findOverloadedOperator(IASTFunctionCallExpression exp, ICPPClassType type) { - IASTInitializerClause[] args = exp.getArguments(); - ArrayList argsToPass = new ArrayList(args.length + 1); - argsToPass.add(exp.getFunctionNameExpression()); - for (IASTInitializerClause e : args) { - argsToPass.add(e); - } - args = argsToPass.toArray(new IASTInitializerClause[argsToPass.size()]); - - return findOverloadedOperator(exp, args, type, OverloadableOperator.PAREN, LookupMode.NO_GLOBALS); + final LookupMode lookupNonMember; + if (op == OverloadableOperator.ASSIGN || op == OverloadableOperator.BRACKET) { + lookupNonMember = LookupMode.NO_GLOBALS; + } else { + lookupNonMember= LookupMode.LIMITED_GLOBALS; + } + return findOverloadedOperator(point, new ICPPEvaluation[] {arg1, arg2}, + op1type, op, lookupNonMember); } public static ICPPFunction findOverloadedOperator(ICPPASTNewExpression expr) { OverloadableOperator op = OverloadableOperator.fromNewExpression(expr); - IType type = getTypeOfPointer(expr.getExpressionType()); - if (type == null) - return null; + final ICPPEvaluation evaluation = expr.getEvaluation(); + if (evaluation.isTypeDependent()) + return null; - IASTTypeId typeId = expr.getTypeId().copy(); - IASTExpression sizeExpression = new CPPASTTypeIdExpression(IASTTypeIdExpression.op_sizeof, typeId); - sizeExpression.setParent(expr); + final IASTInitializerClause[] placement = expr.getPlacementArguments(); + final ICPPEvaluation arg1= new EvalUnary(IASTUnaryExpression.op_star, evaluation); + final ICPPEvaluation arg2= new EvalUnary(IASTUnaryExpression.op_sizeof, evaluation); - IASTInitializerClause[] placement = expr.getPlacementArguments(); - List args = new ArrayList(); - args.add(createArgForType(expr, type)); - args.add(sizeExpression); - if (placement != null) { + ICPPEvaluation[] args; + if (placement == null) { + args= new ICPPEvaluation[] {arg1, arg2}; + } else { + args= new ICPPEvaluation[2+placement.length]; + args[0]= arg1; + args[1]= arg2; + int i=2; for (IASTInitializerClause p : placement) { - args.add(p); + final ICPPASTInitializerClause arg = (ICPPASTInitializerClause) p; + final ICPPEvaluation a = arg.getEvaluation(); + if (a.isTypeDependent()) + return null; + args[i++]= a; } } - IASTInitializerClause[] argArray = args.toArray(new IASTInitializerClause[args.size()]); - return findOverloadedOperator(expr, argArray, type, op, LookupMode.GLOBALS_IF_NO_MEMBERS); + IType type= getNestedType(arg1.getTypeOrFunctionSet(expr), TDEF | REF | CVTYPE); + return findOverloadedOperator(expr, args, type, op, LookupMode.GLOBALS_IF_NO_MEMBERS); } public static ICPPFunction findOverloadedOperator(ICPPASTDeleteExpression expr) { @@ -3027,7 +3004,8 @@ public class CPPSemantics { if (type == null) return null; - IASTExpression[] args = {createArgForType(expr, type), expr.getOperand()}; + ICPPEvaluation[] args = {new EvalFixed(type, LVALUE, Value.UNKNOWN), + ((ICPPASTExpression) expr.getOperand()).getEvaluation()}; return findOverloadedOperator(expr, args, type, op, LookupMode.GLOBALS_IF_NO_MEMBERS); } @@ -3092,22 +3070,16 @@ public class CPPSemantics { if (initializer instanceof IASTEqualsInitializer) { // Copy initialization IASTEqualsInitializer eqInit= (IASTEqualsInitializer) initializer; - IASTInitializerClause initClause = eqInit.getInitializerClause(); - IType sourceType= null; - ValueCategory isLValue= PRVALUE; - if (initClause instanceof IASTExpression) { - final IASTExpression expr = (IASTExpression) initClause; - isLValue= valueCat(expr); - sourceType= SemanticUtil.getSimplifiedType(typeOrFunctionSet(expr)); - } else if (initClause instanceof ICPPASTInitializerList) { - sourceType= new InitializerListType((ICPPASTInitializerList) initClause); - } + ICPPASTInitializerClause initClause = (ICPPASTInitializerClause) eqInit.getInitializerClause(); + final ICPPEvaluation evaluation = initClause.getEvaluation(); + IType sourceType= evaluation.getTypeOrFunctionSet(name); + ValueCategory isLValue= evaluation.getValueCategory(name); if (sourceType != null) { Cost c; if (calculateInheritanceDepth(sourceType, classType) >= 0) { - c = Conversions.copyInitializationOfClass(isLValue, sourceType, classType, false); + c = Conversions.copyInitializationOfClass(isLValue, sourceType, classType, false, name); } else { - c = Conversions.checkImplicitConversionSequence(type, sourceType, isLValue, UDCMode.ALLOWED, Context.ORDINARY); + c = Conversions.checkImplicitConversionSequence(type, sourceType, isLValue, UDCMode.ALLOWED, Context.ORDINARY, name); } if (c.converts()) { ICPPFunction f = c.getUserDefinedConversion(); @@ -3118,13 +3090,15 @@ public class CPPSemantics { } } else if (initializer instanceof ICPPASTInitializerList) { // List initialization - final InitializerListType listType = new InitializerListType((ICPPASTInitializerList) initializer); - Cost c= Conversions.listInitializationSequence(listType, type, UDCMode.ALLOWED, true); - if (c.converts()) { - ICPPFunction f = c.getUserDefinedConversion(); - if (f instanceof ICPPConstructor) - return (ICPPConstructor) f; - } + ICPPEvaluation eval= ((ICPPASTInitializerList) initializer).getEvaluation(); + if (eval instanceof EvalInitList) { + Cost c= Conversions.listInitializationSequence((EvalInitList) eval, type, UDCMode.ALLOWED, true, name); + if (c.converts()) { + ICPPFunction f = c.getUserDefinedConversion(); + if (f instanceof ICPPConstructor) + return (ICPPConstructor) f; + } + } } else if (initializer instanceof ICPPASTConstructorInitializer) { // Direct Initialization final IASTInitializerClause[] arguments = ((ICPPASTConstructorInitializer) initializer).getArguments(); @@ -3137,9 +3111,9 @@ public class CPPSemantics { LookupData data = new LookupData(astName); data.setFunctionArguments(false, arguments); - data.forceQualified = true; + data.qualified = true; data.foundItems = classType.getConstructors(); - binding = resolveAmbiguities(data, astName); + binding = resolveAmbiguities(data); if (binding instanceof ICPPConstructor) return (ICPPConstructor) binding; } else if (initializer == null) { @@ -3166,27 +3140,22 @@ public class CPPSemantics { if (scope == null) return null; - CPPASTName astName = new CPPASTName(); - astName.setParent(expr); - astName.setPropertyInParent(STRING_LOOKUP_PROPERTY); - astName.setName(CharArrayUtils.concat("~".toCharArray(), cls.getNameCharArray())); //$NON-NLS-1$ - - IASTExpression arg = createArgForType(expr, cls); - - LookupData data = new LookupData(astName); - data.forceQualified = true; - data.setFunctionArguments(true, arg); + final char[] name = CharArrayUtils.concat("~".toCharArray(), cls.getNameCharArray()); //$NON-NLS-1$ + LookupData data = new LookupData(name, null, expr); + data.qualified = true; + data.setFunctionArguments(true, new EvalFixed(cls, LVALUE, Value.UNKNOWN)); try { lookup(data, scope); - IBinding binding = resolveAmbiguities(data, astName); - if (binding instanceof ICPPFunction) - return (ICPPFunction) binding; + IBinding[] found= data.getFoundBindings(); + if (found.length > 0 && found[0] instanceof ICPPFunction) { + return (ICPPFunction) found[0]; + } } catch (DOMException e) { } return null; } - public static IASTExpression createArgForType(IASTNode node, final IType type) { + public static ICPPASTExpression createArgForType(IASTNode node, final IType type) { CPPASTName x= new CPPASTName(); x.setBinding(new CPPVariable(x) { @Override public IType getType() { @@ -3198,62 +3167,14 @@ public class CPPSemantics { return idExpression; } - public static ICPPFunction findOverloadedOperator(IASTUnaryExpression exp) { - final IASTExpression operand = exp.getOperand(); - if (operand == null) - return null; - - OverloadableOperator op = OverloadableOperator.fromUnaryExpression(exp); - if (op == null) - return null; - - IType type = typeOrFunctionSet(operand); - type = SemanticUtil.getNestedType(type, TDEF | REF | CVTYPE); - if (!isUserDefined(type)) - return null; - - IASTExpression[] args; - int operator = exp.getOperator(); - if (operator == IASTUnaryExpression.op_postFixDecr || operator == IASTUnaryExpression.op_postFixIncr) { - args = new IASTExpression[] { operand, CPPASTLiteralExpression.INT_ZERO }; - } else { - args = new IASTExpression[] { operand }; - } - return findOverloadedOperator(exp, args, type, op, LookupMode.LIMITED_GLOBALS); - } - - public static ICPPFunction findOverloadedOperator(IASTBinaryExpression exp) { - OverloadableOperator op = OverloadableOperator.fromBinaryExpression(exp); - if (op == null) - return null; - - final IASTExpression op1 = exp.getOperand1(); - final IASTExpression op2 = exp.getOperand2(); - if(op2==null){ - return null; - } - IType op1type = getNestedType(typeOrFunctionSet(op1), TDEF | REF | CVTYPE); - IType op2type = getNestedType(typeOrFunctionSet(op2), TDEF | REF | CVTYPE); - if (!isUserDefined(op1type) && !isUserDefined(op2type)) - return null; - - final IASTExpression[] args = new IASTExpression[] { op1, op2 }; - final LookupMode lookupNonMember; - if (exp.getOperator() == IASTBinaryExpression.op_assign) { - lookupNonMember = LookupMode.NO_GLOBALS; - } else { - lookupNonMember= LookupMode.LIMITED_GLOBALS; - } - return findOverloadedOperator(exp, args, op1type, op, lookupNonMember); - } + /** * For simplicity returns an operator of form RT (T, T) rather than RT (boolean, T, T) */ - public static ICPPFunction findOverloadedConditionalOperator(IASTExpression positive, IASTExpression negative) { - final IASTExpression parent = (IASTExpression) positive.getParent(); - final IASTExpression[] args = new IASTExpression[] {positive, negative}; - return findOverloadedOperator(parent, args, null, + public static ICPPFunction findOverloadedConditionalOperator(IASTNode point, ICPPEvaluation positive, ICPPEvaluation negative) { + final ICPPEvaluation[] args = new ICPPEvaluation[] {positive, negative}; + return findOverloadedOperator(point, args, null, OverloadableOperator.CONDITIONAL_OPERATOR, LookupMode.NO_GLOBALS); } @@ -3261,63 +3182,39 @@ public class CPPSemantics { * Returns the operator,() function that would apply to the two given arguments. * The lookup type of the class where the operator,() might be found must also be provided. */ - public static ICPPFunction findOverloadedOperatorComma(IASTExpression first, final IType lookupType, final ValueCategory valueCat, IASTExpression second) { - IType op1type = getNestedType(lookupType, TDEF | REF | CVTYPE); - IType op2type = getNestedType(typeOrFunctionSet(second), TDEF | REF | CVTYPE); + public static ICPPFunction findOverloadedOperatorComma(IASTNode point, ICPPEvaluation arg1, ICPPEvaluation arg2) { + IType op1type = getNestedType(arg1.getTypeOrFunctionSet(point), TDEF | REF | CVTYPE); + IType op2type = getNestedType(arg2.getTypeOrFunctionSet(point), TDEF | REF | CVTYPE); if (!isUserDefined(op1type) && !isUserDefined(op2type)) return null; - IASTUnaryExpression dummy = new CPPASTUnaryExpression() { - @Override public IType getExpressionType() { return lookupType; } - @Override public ValueCategory getValueCategory() { return valueCat; } - }; - dummy.setParent(first); - - IASTExpression[] args = new IASTExpression[] { dummy , second }; - return findOverloadedOperator(dummy, args, op1type, OverloadableOperator.COMMA, LookupMode.LIMITED_GLOBALS); + ICPPEvaluation[] args = { arg1 , arg2 }; + return findOverloadedOperator(point, args, op1type, OverloadableOperator.COMMA, LookupMode.LIMITED_GLOBALS); } - /** - * Returns the operator->() function - */ - public static ICPPFunction findOverloadedOperator(ICPPASTFieldReference fieldRef, IType cvQualifiedType, ICPPClassType classType) { - IASTExpression arg = CPPSemantics.createArgForType(fieldRef, cvQualifiedType); - return findOverloadedOperator(fieldRef, new IASTExpression[] {arg}, classType, OverloadableOperator.ARROW, LookupMode.NO_GLOBALS); - } - private static enum LookupMode {NO_GLOBALS, GLOBALS_IF_NO_MEMBERS, LIMITED_GLOBALS, ALL_GLOBALS} - private static ICPPFunction findOverloadedOperator(IASTExpression parent, IASTInitializerClause[] args, IType methodLookupType, + static enum LookupMode {NO_GLOBALS, GLOBALS_IF_NO_MEMBERS, LIMITED_GLOBALS, ALL_GLOBALS} + static ICPPFunction findOverloadedOperator(IASTNode point, ICPPEvaluation[] args, IType methodLookupType, OverloadableOperator operator, LookupMode mode) { + while (point instanceof IASTName) + point= point.getParent(); + ICPPClassType callToObjectOfClassType= null; IType type2= null; - if (args.length >= 2 && args[1] instanceof IASTExpression) { - type2 = typeOrFunctionSet((IASTExpression) args[1]); + if (args.length >= 2) { + type2 = args[1].getTypeOrFunctionSet(point); type2= getNestedType(type2, TDEF | REF | CVTYPE); } - if (methodLookupType instanceof ICPPUnknownType || type2 instanceof ICPPUnknownType) { - if (methodLookupType instanceof FunctionSetType) - ((FunctionSetType) methodLookupType).setToUnknown(); - if (type2 instanceof FunctionSetType) - ((FunctionSetType) type2).setToUnknown(); - - return new CPPUnknownFunction(null, operator.toCharArray()); - } - // Find a method LookupData methodData = null; - CPPASTName methodName = null; if (methodLookupType instanceof ISemanticProblem) return null; if (methodLookupType instanceof ICPPClassType) { ICPPClassType classType = (ICPPClassType) methodLookupType; - - methodName = new CPPASTName(operator.toCharArray()); - methodName.setParent(parent); - methodName.setPropertyInParent(STRING_LOOKUP_PROPERTY); - methodData = new LookupData(methodName); + methodData = new LookupData(operator.toCharArray(), null, point); methodData.setFunctionArguments(true, args); - methodData.forceQualified = true; // (13.3.1.2.3) + methodData.qualified = true; // (13.3.1.2.3) try { IScope scope = classType.getCompositeScope(); @@ -3325,7 +3222,7 @@ public class CPPSemantics { return null; lookup(methodData, scope); - if (parent instanceof IASTFunctionCallExpression) { + if (operator == OverloadableOperator.PAREN) { callToObjectOfClassType= classType; } } catch (DOMException e) { @@ -3334,10 +3231,7 @@ public class CPPSemantics { } // Find a function - CPPASTName funcName = new CPPASTName(operator.toCharArray()); - funcName.setParent(parent); - funcName.setPropertyInParent(STRING_LOOKUP_PROPERTY); - LookupData funcData = new LookupData(funcName); + LookupData funcData = new LookupData(operator.toCharArray(), null, point); // Global new and delete operators do not take an argument for the this pointer. switch (operator) { @@ -3354,7 +3248,7 @@ public class CPPSemantics { if (mode == LookupMode.ALL_GLOBALS || mode == LookupMode.LIMITED_GLOBALS || (mode == LookupMode.GLOBALS_IF_NO_MEMBERS && !haveMembers)) { try { - IScope scope = CPPVisitor.getContainingScope(parent); + IScope scope = CPPVisitor.getContainingScope(point); if (scope == null) return null; lookup(funcData, scope); @@ -3363,7 +3257,7 @@ public class CPPSemantics { } catch (DOMException e) { } // Filter with file-set - IASTTranslationUnit tu= parent.getTranslationUnit(); + IASTTranslationUnit tu= point.getTranslationUnit(); if (tu != null && funcData.foundItems instanceof Object[]) { final IIndexFileSet fileSet = tu.getIndexFileSet(); if (fileSet != null) { @@ -3449,7 +3343,7 @@ public class CPPSemantics { IType ptt= SemanticUtil.getNestedType(((IPointerType) rt).getType(), SemanticUtil.TDEF); if (ptt instanceof IFunctionType) { IFunctionType ft2= (IFunctionType) ptt; - IBinding sf= createSurrogateCallFunction(parent.getTranslationUnit().getScope(), ft2.getReturnType(), rt, ft2.getParameterTypes()); + IBinding sf= createSurrogateCallFunction(point.getTranslationUnit().getScope(), ft2.getReturnType(), rt, ft2.getParameterTypes()); mergeResults(funcData, sf, false); } } @@ -3461,7 +3355,7 @@ public class CPPSemantics { } if (methodLookupType instanceof ICPPClassType || type2 instanceof ICPPClassType) { - ICPPFunction[] builtins= BuiltinOperators.create(operator, args, parent.getTranslationUnit(), (Object[]) funcData.foundItems); + ICPPFunction[] builtins= BuiltinOperators.create(operator, args, point, (Object[]) funcData.foundItems); mergeResults(funcData, builtins, false); } @@ -3470,11 +3364,11 @@ public class CPPSemantics { if (methodData != null && funcData.hasResults()) { // if there was two lookups then merge the results mergeResults(funcData, methodData.foundItems, false); - binding = resolveAmbiguities(funcData, funcName); + binding = resolveAmbiguities(funcData); } else if (funcData.hasResults()) { - binding = resolveAmbiguities(funcData, funcName); + binding = resolveAmbiguities(funcData); } else if (methodData != null) { - binding = resolveAmbiguities(methodData, methodName); + binding = resolveAmbiguities(methodData); } if (binding instanceof ICPPFunction) @@ -3500,7 +3394,7 @@ public class CPPSemantics { return new CPPImplicitFunction(CALL_FUNCTION, scope, functionType, theParms, false); } - private static boolean isUserDefined(IType type) { + static boolean isUserDefined(IType type) { if (type instanceof ISemanticProblem) return false; @@ -3516,16 +3410,15 @@ public class CPPSemantics { } public static IBinding[] findBindings(IScope scope, char[] name, boolean qualified, IASTNode beforeNode) { - CPPASTName astName = new CPPASTName(); - astName.setName(name); - astName.setParent(ASTInternal.getPhysicalNodeOfScope(scope)); - astName.setPropertyInParent(STRING_LOOKUP_PROPERTY); - if (beforeNode instanceof ASTNode) { - astName.setOffsetAndLength((ASTNode) beforeNode); - } - - LookupData data = new LookupData(astName); - data.forceQualified = qualified; + LookupData data; + if (beforeNode == null) { + data= new LookupData(name, null, ASTInternal.getPhysicalNodeOfScope(scope)); + data.setIgnorePointOfDeclaration(true); + } else { + data= new LookupData(name, null, beforeNode); + data.setIgnorePointOfDeclaration(false); + } + data.qualified = qualified; return standardLookup(data, scope); } @@ -3533,13 +3426,13 @@ public class CPPSemantics { String[] additionalNamespaces) { LookupData data = createLookupData(name); data.contentAssist = true; - data.prefixLookup = prefixLookup; + data.setPrefixLookup(prefixLookup); data.foundItems = new CharArrayObjectMap(2); // Convert namespaces to scopes. List nsScopes= new ArrayList(); IASTTranslationUnit tu = name.getTranslationUnit(); - if (additionalNamespaces != null && tu != null) { + if (additionalNamespaces != null && tu instanceof CPPASTTranslationUnit) { for (String nsName : additionalNamespaces) { nsName= nsName.trim(); if (nsName.startsWith("::")) { //$NON-NLS-1$ @@ -3547,7 +3440,7 @@ public class CPPSemantics { } String[] namespaceParts = nsName.split("::"); //$NON-NLS-1$ try { - ICPPScope nsScope = getNamespaceScope(tu, namespaceParts); + ICPPScope nsScope = getNamespaceScope((CPPASTTranslationUnit) tu, namespaceParts, name); if (nsScope != null) { nsScopes.add(nsScope); } @@ -3559,16 +3452,13 @@ public class CPPSemantics { return contentAssistLookup(data, nsScopes); } - private static ICPPScope getNamespaceScope(IASTTranslationUnit tu, String[] namespaceParts) + private static ICPPScope getNamespaceScope(CPPASTTranslationUnit tu, String[] namespaceParts, IASTNode point) throws DOMException { - ICPPScope nsScope= (ICPPScope) tu.getScope(); + ICPPScope nsScope= tu.getScope(); outer: for (String nsPart : namespaceParts) { nsPart= nsPart.trim(); if (nsPart.length() != 0) { - CPPASTName searchName= new CPPASTName(nsPart.toCharArray()); - searchName.setParent(tu); - searchName.setPropertyInParent(STRING_LOOKUP_PROPERTY); - IBinding[] nsBindings = nsScope.getBindings(searchName, true, false); + IBinding[] nsBindings = nsScope.getBindings(new ScopeLookupData(nsPart.toCharArray(), point)); for (IBinding nsBinding : nsBindings) { if (nsBinding instanceof ICPPNamespace) { nsScope= ((ICPPNamespace) nsBinding).getNamespaceScope(); @@ -3593,7 +3483,7 @@ public class CPPSemantics { if (additionalNamespaces != null) { data.ignoreUsingDirectives = true; - data.forceQualified = true; + data.qualified = true; for (ICPPScope nsScope : additionalNamespaces) { if (!data.visited.containsKey(nsScope)) { lookup(data, nsScope); @@ -3755,7 +3645,7 @@ public class CPPSemantics { protected static IBinding resolveUnknownName(IScope scope, ICPPUnknownBinding unknown) { final IASTName unknownName = unknown.getUnknownName(); LookupData data = new LookupData(unknownName); - data.checkPointOfDecl= false; + data.setIgnorePointOfDeclaration(true); data.typesOnly= unknown instanceof IType; try { @@ -3771,7 +3661,7 @@ public class CPPSemantics { // 3: resolve ambiguities IBinding binding; try { - binding = resolveAmbiguities(data, unknownName); + binding = resolveAmbiguities(data); } catch (DOMException e) { binding = e.getProblem(); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index d932253975c..9929b37eaac 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -34,7 +34,6 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTIdExpression; -import org.eclipse.cdt.core.dom.ast.IASTInitializerClause; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; @@ -58,7 +57,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBas import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; @@ -164,19 +162,19 @@ public class CPPTemplates { /** * Instantiates a class template with the given arguments. May return null. */ - public static IBinding instantiate(ICPPClassTemplate template, ICPPTemplateArgument[] args) { - return instantiate(template, args, false, false); + public static IBinding instantiate(ICPPClassTemplate template, ICPPTemplateArgument[] args, IASTNode point) { + return instantiate(template, args, false, false, point); } /** * Instantiates a class template with the given arguments. May return null. */ private static IBinding instantiate(ICPPClassTemplate template, ICPPTemplateArgument[] args, - boolean isDefinition, boolean isExplicitSpecialization) { + boolean isDefinition, boolean isExplicitSpecialization, IASTNode point) { try { // Add default arguments, if necessary. ICPPTemplateArgument[] arguments= SemanticUtil.getSimplifiedArguments(args); - arguments= addDefaultArguments(template, arguments); + arguments= addDefaultArguments(template, arguments, point); if (arguments == null) return createProblem(template, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS); @@ -185,7 +183,7 @@ public class CPPTemplates { } if (template instanceof ICPPClassTemplatePartialSpecialization) { - return instantiatePartialSpecialization((ICPPClassTemplatePartialSpecialization) template, arguments, isDefinition, null); + return instantiatePartialSpecialization((ICPPClassTemplatePartialSpecialization) template, arguments, isDefinition, null, point); } final ICPPTemplateParameter[] parameters= template.getTemplateParameters(); @@ -208,7 +206,7 @@ public class CPPTemplates { } if (i < numArgs) { ICPPTemplateArgument arg= arguments[i]; - ICPPTemplateArgument newArg = CPPTemplates.matchTemplateParameterAndArgument(param, arg, map); + ICPPTemplateArgument newArg = CPPTemplates.matchTemplateParameterAndArgument(param, arg, map, point); if (newArg == null) return createProblem(template, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS); if (newArg != arg) { @@ -239,12 +237,12 @@ public class CPPTemplates { return prim; if (!isExplicitSpecialization) { - IBinding result= CPPTemplates.selectSpecialization(template, arguments, isDefinition); + IBinding result= CPPTemplates.selectSpecialization(template, arguments, isDefinition, point); if (result != null) return result; } - return instantiatePrimaryTemplate(template, arguments, map, isDefinition); + return instantiatePrimaryTemplate(template, arguments, map, isDefinition, point); } catch (DOMException e) { return e.getProblem(); } @@ -308,24 +306,25 @@ public class CPPTemplates { } private static IBinding instantiateFunctionTemplate(ICPPFunctionTemplate template, - ICPPTemplateArgument[] arguments, CPPTemplateParameterMap map) throws DOMException { + ICPPTemplateArgument[] arguments, CPPTemplateParameterMap map, IASTNode point) throws DOMException { ICPPTemplateInstance instance= getInstance(template, arguments, false); if (instance != null) { return instance; } IBinding owner= template.getOwner(); - instance = CPPTemplates.createInstance(owner, template, map, arguments); + instance = CPPTemplates.createInstance(owner, template, map, arguments, point); addInstance(template, arguments, instance); return instance; } /** * Instantiates a partial class template specialization. + * @param point */ private static IBinding instantiatePartialSpecialization( ICPPClassTemplatePartialSpecialization partialSpec, ICPPTemplateArgument[] args, boolean isDef, - CPPTemplateParameterMap tpMap) throws DOMException { + CPPTemplateParameterMap tpMap, IASTNode point) throws DOMException { ICPPTemplateInstance instance= getInstance(partialSpec, args, isDef); if (instance != null) return instance; @@ -333,11 +332,11 @@ public class CPPTemplates { if (tpMap == null) { tpMap = new CPPTemplateParameterMap(args.length); if (!TemplateArgumentDeduction.fromTemplateArguments(partialSpec.getTemplateParameters(), - partialSpec.getTemplateArguments(), args, tpMap)) + partialSpec.getTemplateArguments(), args, tpMap, point)) return null; } - instance= createInstance(partialSpec.getOwner(), partialSpec, tpMap, args); + instance= createInstance(partialSpec.getOwner(), partialSpec, tpMap, args, point); addInstance(partialSpec, args, instance); return instance; } @@ -347,7 +346,7 @@ public class CPPTemplates { * @param map */ private static IBinding instantiatePrimaryTemplate(ICPPClassTemplate template, ICPPTemplateArgument[] arguments, - CPPTemplateParameterMap map, boolean isDef) throws DOMException { + CPPTemplateParameterMap map, boolean isDef, IASTNode point) throws DOMException { assert !(template instanceof ICPPClassTemplatePartialSpecialization); ICPPTemplateInstance instance= getInstance(template, arguments, isDef); @@ -356,7 +355,7 @@ public class CPPTemplates { } IBinding owner= template.getOwner(); - instance = CPPTemplates.createInstance(owner, template, map, arguments); + instance = CPPTemplates.createInstance(owner, template, map, arguments, point); addInstance(template, arguments, instance); return instance; } @@ -395,7 +394,7 @@ public class CPPTemplates { } private static ICPPTemplateArgument[] addDefaultArguments(ICPPClassTemplate template, - ICPPTemplateArgument[] arguments) throws DOMException { + ICPPTemplateArgument[] arguments, IASTNode point) throws DOMException { if (template instanceof ICPPClassTemplatePartialSpecialization) return arguments; @@ -461,7 +460,7 @@ public class CPPTemplates { } if (defaultArg == null) return null; - arg= instantiateArgument(defaultArg, map, -1, null); + arg= instantiateArgument(defaultArg, map, -1, null, point); arg= SemanticUtil.getSimplifiedArgument(arg); if (!isValidArgument(arg)) { return null; @@ -672,7 +671,7 @@ public class CPPTemplates { if (argsAreTrivial(classTemplate.getTemplateParameters(), args)) { result= classTemplate; } else { - args= addDefaultArguments(classTemplate, args); + args= addDefaultArguments(classTemplate, args, id); if (args == null) { return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, templateName.toCharArray()); } @@ -692,7 +691,7 @@ public class CPPTemplates { } } if (result == null) { - result= instantiate(classTemplate, args, isDefinition, isExplicitSpecialization); + result= instantiate(classTemplate, args, isDefinition, isExplicitSpecialization, id); if (result instanceof ICPPInternalBinding) { if (isDeclaration) { ASTInternal.addDeclaration(result, id); @@ -731,7 +730,7 @@ public class CPPTemplates { public static ICPPTemplateInstance createInstance(IBinding owner, ICPPTemplateDefinition template, - CPPTemplateParameterMap tpMap, ICPPTemplateArgument[] args) { + CPPTemplateParameterMap tpMap, ICPPTemplateArgument[] args, IASTNode point) { if (owner instanceof ICPPSpecialization) { ICPPTemplateParameterMap map= ((ICPPSpecialization) owner).getTemplateParameterMap(); if (map != null) { @@ -742,26 +741,36 @@ public class CPPTemplates { ICPPTemplateInstance instance = null; if (template instanceof ICPPClassType) { instance = new CPPClassInstance((ICPPClassType) template, owner, tpMap, args); - } else if (owner instanceof ICPPClassType && template instanceof ICPPMethod) { - if (template instanceof ICPPConstructor) { - instance = new CPPConstructorInstance((ICPPConstructor) template, (ICPPClassType) owner, tpMap, args); - } else { - instance = new CPPMethodInstance((ICPPMethod) template, (ICPPClassType) owner, tpMap, args); - } } else if (template instanceof ICPPFunction) { - instance = new CPPFunctionInstance((ICPPFunction) template, owner, tpMap, args); + ICPPFunction func= (ICPPFunction) template; + ICPPClassSpecialization within = getSpecializationContext(owner); + ICPPFunctionType type= (ICPPFunctionType) CPPTemplates.instantiateType(func.getType(), tpMap, -1, within, point); + IType[] exceptionSpecs= instantiateTypes(func.getExceptionSpecification(), tpMap, -1, within, point); + if (owner instanceof ICPPClassType && template instanceof ICPPMethod) { + if (template instanceof ICPPConstructor) { + instance = new CPPConstructorInstance((ICPPConstructor) template, (ICPPClassType) owner, tpMap, args, type, exceptionSpecs); + } else { + instance = new CPPMethodInstance((ICPPMethod) template, (ICPPClassType) owner, tpMap, args, type, exceptionSpecs); + } + } else { + instance = new CPPFunctionInstance((ICPPFunction) template, owner, tpMap, args, type, exceptionSpecs); + } } return instance; } - public static IBinding createSpecialization(ICPPClassSpecialization owner, IBinding decl) { + public static IBinding createSpecialization(ICPPClassSpecialization owner, IBinding decl, IASTNode point) { IBinding spec = null; final ICPPTemplateParameterMap tpMap= owner.getTemplateParameterMap(); if (decl instanceof ICPPClassTemplatePartialSpecialization) { try { + final ICPPClassSpecialization within = getSpecializationContext(owner); ICPPClassTemplatePartialSpecialization pspec= (ICPPClassTemplatePartialSpecialization) decl; - ICPPClassTemplate template= (ICPPClassTemplate) owner.specializeMember(pspec.getPrimaryClassTemplate()); - spec= new CPPClassTemplatePartialSpecializationSpecialization(pspec, template, tpMap); + ICPPClassTemplate template= pspec.getPrimaryClassTemplate(); + ICPPTemplateArgument[] args = pspec.getTemplateArguments(); + template= (ICPPClassTemplate) owner.specializeMember(template, point); + args= CPPTemplates.instantiateArguments(args, tpMap, -1, within, point); + spec= new CPPClassTemplatePartialSpecializationSpecialization(pspec, tpMap, template, args); } catch (DOMException e) { } } else if (decl instanceof ICPPClassTemplate) { @@ -774,33 +783,82 @@ public class CPPTemplates { spec = new CPPClassSpecialization((ICPPClassType) decl, oldOwner, tpMap); } } else if (decl instanceof ICPPField) { - spec = new CPPFieldSpecialization(decl, owner, tpMap); - } else if (decl instanceof ICPPFunctionTemplate) { - if (decl instanceof ICPPConstructor) - spec = new CPPConstructorTemplateSpecialization((ICPPConstructor) decl, owner, tpMap); - else if (decl instanceof ICPPMethod) - spec = new CPPMethodTemplateSpecialization((ICPPMethod) decl, owner, tpMap); - else - spec = new CPPFunctionTemplateSpecialization((ICPPFunctionTemplate) decl, owner, tpMap); - } else if (decl instanceof ICPPConstructor) { - spec = new CPPConstructorSpecialization((ICPPConstructor) decl, owner, tpMap); - } else if (decl instanceof ICPPMethod) { - spec = new CPPMethodSpecialization((ICPPMethod) decl, owner, tpMap); + final ICPPClassSpecialization within = getSpecializationContext(owner); + ICPPField field= (ICPPField) decl; + IType type= CPPTemplates.instantiateType(field.getType(), tpMap, -1, within, point); + IValue value= CPPTemplates.instantiateValue(field.getInitialValue(), tpMap, -1, within, Value.MAX_RECURSION_DEPTH, point); + spec = new CPPFieldSpecialization(decl, owner, tpMap, type, value); } else if (decl instanceof ICPPFunction) { - IBinding oldOwner = decl.getOwner(); - spec = new CPPFunctionSpecialization((ICPPFunction) decl, oldOwner, tpMap, owner); + ICPPFunction func= (ICPPFunction) decl; + ICPPClassSpecialization within = getSpecializationContext(owner); + ICPPFunctionType type= (ICPPFunctionType) CPPTemplates.instantiateType(func.getType(), tpMap, -1, within, point); + IType[] exceptionSpecs= instantiateTypes(func.getExceptionSpecification(), tpMap, -1, within, point); + + if (decl instanceof ICPPFunctionTemplate) { + if (decl instanceof ICPPConstructor) + spec = new CPPConstructorTemplateSpecialization((ICPPConstructor) decl, owner, tpMap, type, exceptionSpecs); + else if (decl instanceof ICPPMethod) + spec = new CPPMethodTemplateSpecialization((ICPPMethod) decl, owner, tpMap, type, exceptionSpecs); + else + spec = new CPPFunctionTemplateSpecialization((ICPPFunctionTemplate) decl, owner, tpMap, type, exceptionSpecs); + } else if (decl instanceof ICPPConstructor) { + spec = new CPPConstructorSpecialization((ICPPConstructor) decl, owner, tpMap, type, exceptionSpecs); + } else if (decl instanceof ICPPMethod) { + spec = new CPPMethodSpecialization((ICPPMethod) decl, owner, tpMap, type, exceptionSpecs); + } else if (decl instanceof ICPPFunction) { + IBinding oldOwner = decl.getOwner(); + spec = new CPPFunctionSpecialization((ICPPFunction) decl, oldOwner, tpMap, type, exceptionSpecs); + } } else if (decl instanceof ITypedef) { - spec = new CPPTypedefSpecialization(decl, owner, tpMap); + IType type= CPPTemplates.instantiateType(((ITypedef) decl).getType(), tpMap, -1, getSpecializationContext(owner), point); + spec = new CPPTypedefSpecialization(decl, owner, tpMap, type); } else if (decl instanceof IEnumeration || decl instanceof IEnumerator) { // TODO(sprigogin): Deal with a case when an enumerator value depends on a template parameter. spec = decl; } else if (decl instanceof ICPPUsingDeclaration) { - spec= new CPPUsingDeclarationSpecialization((ICPPUsingDeclaration) decl, owner, tpMap); + IBinding[] delegates= ((ICPPUsingDeclaration) decl).getDelegates(); + List result= new ArrayList(); + ICPPClassSpecialization within = getSpecializationContext(owner); + for (IBinding delegate : delegates) { + try { + if (delegate instanceof ICPPUnknownBinding) { + delegate= CPPTemplates.resolveUnknown((ICPPUnknownBinding) delegate, tpMap, -1, within, point); + } + if (delegate instanceof CPPFunctionSet) { + for (IBinding b : ((CPPFunctionSet) delegate).getBindings()) { + result.add(b); + } + } else if (delegate != null) { + result.add(delegate); + } + } catch (DOMException e) { + } + } + delegates= result.toArray(new IBinding[result.size()]); + spec= new CPPUsingDeclarationSpecialization((ICPPUsingDeclaration) decl, owner, tpMap, delegates); } return spec; } - public static IValue instantiateValue(IValue value, ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, int maxdepth) { + private static ICPPClassSpecialization getSpecializationContext(IBinding owner) { + if (!(owner instanceof ICPPClassSpecialization)) + return null; + ICPPClassSpecialization within= (ICPPClassSpecialization) owner; + ICPPClassType orig = within.getSpecializedBinding(); + for(;;) { + IBinding o1 = within.getOwner(); + IBinding o2 = orig.getOwner(); + if (!(o1 instanceof ICPPClassSpecialization && o2 instanceof ICPPClassType)) + return within; + ICPPClassSpecialization nextWithin = (ICPPClassSpecialization) o1; + orig= (ICPPClassType) o2; + if (orig.isSameType(nextWithin)) + return within; + within= nextWithin; + } + } + +public static IValue instantiateValue(IValue value, ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, int maxdepth, IASTNode point) { if (value == null) return null; IBinding[] unknowns= value.getUnknownBindings(); @@ -811,7 +869,7 @@ public class CPPTemplates { IBinding resolved= unknown; if (unknown instanceof ICPPUnknownBinding) { try { - resolved= resolveUnknown((ICPPUnknownBinding) unknown, tpMap, packOffset, within); + resolved= resolveUnknown((ICPPUnknownBinding) unknown, tpMap, packOffset, within, point); } catch (DOMException e) { return Value.UNKNOWN; } @@ -945,9 +1003,13 @@ public class CPPTemplates { * Instantiates types contained in an array. * @param types an array of types * @param tpMap template argument map + * @param point * @return an array containing instantiated types. */ - public static IType[] instantiateTypes(IType[] types, ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within) { + public static IType[] instantiateTypes(IType[] types, ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, IASTNode point) { + if (types == null) + return null; + // Don't create a new array until it's really needed. IType[] result = types; int j= 0; @@ -966,12 +1028,12 @@ public class CPPTemplates { System.arraycopy(result, 0, newResult, 0, j); result= newResult; for(int k=0; k fnArgs, List argCats, boolean withImpliedObjectArg) { - if (name != null && name.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME) { - name= (IASTName) name.getParent(); - } - + static ICPPFunction[] instantiateForFunctionCall(ICPPFunction[] fns, ICPPTemplateArgument[] tmplArgs, + List fnArgs, List argCats, boolean withImpliedObjectArg, IASTNode point) { // Extract template arguments. - ICPPTemplateArgument[] tmplArgs= ICPPTemplateArgument.EMPTY_ARGUMENTS; - boolean requireTemplate= name instanceof ICPPASTTemplateId; + boolean requireTemplate= tmplArgs != null; boolean haveTemplate= false; for (final ICPPFunction func : fns) { @@ -1675,7 +1735,6 @@ public class CPPTemplates { return new ICPPFunction[] {CPPUnknownFunction.createForSample(template)}; if (requireTemplate) { - tmplArgs = createTemplateArgumentArray((ICPPASTTemplateId) name); if (hasDependentArgument(tmplArgs)) return new ICPPFunction[] {CPPUnknownFunction.createForSample(template)}; } @@ -1695,7 +1754,7 @@ public class CPPTemplates { if (fn != null) { if (fn instanceof ICPPFunctionTemplate) { ICPPFunctionTemplate fnTmpl= (ICPPFunctionTemplate) fn; - ICPPFunction inst = instantiateForFunctionCall(fnTmpl, tmplArgs, fnArgs, argCats, withImpliedObjectArg); + ICPPFunction inst = instantiateForFunctionCall(fnTmpl, tmplArgs, fnArgs, argCats, withImpliedObjectArg, point); if (inst != null) result.add(inst); } else if (!requireTemplate || fn instanceof ICPPUnknownBinding) { @@ -1708,7 +1767,7 @@ public class CPPTemplates { private static ICPPFunction instantiateForFunctionCall(ICPPFunctionTemplate template, ICPPTemplateArgument[] tmplArgs, List fnArgs, List argCats, - boolean withImpliedObjectArg) { + boolean withImpliedObjectArg, IASTNode point) { if (withImpliedObjectArg && template instanceof ICPPMethod) { fnArgs= fnArgs.subList(1, fnArgs.size()); argCats= argCats.subList(1, argCats.size()); @@ -1716,9 +1775,9 @@ public class CPPTemplates { CPPTemplateParameterMap map= new CPPTemplateParameterMap(fnArgs.size()); try { - ICPPTemplateArgument[] args= TemplateArgumentDeduction.deduceForFunctionCall(template, tmplArgs, fnArgs, argCats, map); + ICPPTemplateArgument[] args= TemplateArgumentDeduction.deduceForFunctionCall(template, tmplArgs, fnArgs, argCats, map, point); if (args != null) { - IBinding instance= instantiateFunctionTemplate(template, args, map); + IBinding instance= instantiateFunctionTemplate(template, args, map, point); if (instance instanceof ICPPFunction) { final ICPPFunction f = (ICPPFunction) instance; if (isValidType(f.getType())) @@ -1732,8 +1791,9 @@ public class CPPTemplates { /** * 14.8.2.3 Deducing conversion function template arguments + * @param point */ - static ICPPFunction[] instantiateConversionTemplates(ICPPFunction[] functions, IType conversionType) { + static ICPPFunction[] instantiateConversionTemplates(ICPPFunction[] functions, IType conversionType, IASTNode point) { boolean checkedForDependentType= false; ICPPFunction[] result= functions; int i=0; @@ -1758,9 +1818,9 @@ public class CPPTemplates { } CPPTemplateParameterMap map= new CPPTemplateParameterMap(1); try { - ICPPTemplateArgument[] args= TemplateArgumentDeduction.deduceForConversion(template, conversionType, map); + ICPPTemplateArgument[] args= TemplateArgumentDeduction.deduceForConversion(template, conversionType, map, point); if (args != null) { - IBinding instance= instantiateFunctionTemplate(template, args, map); + IBinding instance= instantiateFunctionTemplate(template, args, map, point); if (instance instanceof ICPPFunction) { inst= (ICPPFunction) instance; } @@ -1784,15 +1844,16 @@ public class CPPTemplates { /** * 14.8.2.6 Deducing template arguments from a function declaration + * @param point * @return */ static ICPPFunction instantiateForFunctionDeclaration(ICPPFunctionTemplate template, - ICPPTemplateArgument[] args, ICPPFunctionType functionType) { + ICPPTemplateArgument[] args, ICPPFunctionType functionType, IASTNode point) { CPPTemplateParameterMap map= new CPPTemplateParameterMap(1); try { - args= TemplateArgumentDeduction.deduceForDeclaration(template, args, functionType, map); + args= TemplateArgumentDeduction.deduceForDeclaration(template, args, functionType, map, point); if (args != null) { - IBinding instance= instantiateFunctionTemplate(template, args, map); + IBinding instance= instantiateFunctionTemplate(template, args, map, point); if (instance instanceof ICPPFunction) { return (ICPPFunction) instance; } @@ -1807,29 +1868,20 @@ public class CPPTemplates { /** * 14.8.2.2 Deducing template arguments taking the address of a function template [temp.deduct.funcaddr] */ - static ICPPFunction instantiateForAddressOfFunction(ICPPFunctionTemplate template, IFunctionType target, IASTName name) { - if (name.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME) { - name= (IASTName) name.getParent(); - } + static ICPPFunction instantiateForAddressOfFunction(ICPPFunctionTemplate template, IFunctionType target, + ICPPTemplateArgument[] args, IASTNode point) { try { if (target != null && isDependentType(target)) { return CPPUnknownFunction.createForSample(template); } - - ICPPTemplateArgument[] tmplArgs; - if (name instanceof ICPPASTTemplateId && !(template instanceof ICPPConstructor)) { - tmplArgs = createTemplateArgumentArray((ICPPASTTemplateId) name); - if (hasDependentArgument(tmplArgs)) { - return CPPUnknownFunction.createForSample(template); - } - } else { - tmplArgs= ICPPTemplateArgument.EMPTY_ARGUMENTS; - } + + if (template instanceof ICPPConstructor || args == null) + args= ICPPTemplateArgument.EMPTY_ARGUMENTS; CPPTemplateParameterMap map= new CPPTemplateParameterMap(4); - ICPPTemplateArgument[] args= TemplateArgumentDeduction.deduceForAddressOf(template, tmplArgs, target, map); + args= TemplateArgumentDeduction.deduceForAddressOf(template, args, target, map, point); if (args != null) { - IBinding instance= instantiateFunctionTemplate(template, args, map); + IBinding instance= instantiateFunctionTemplate(template, args, map, point); if (instance instanceof ICPPFunction) { return (ICPPFunction) instance; } @@ -1840,7 +1892,7 @@ public class CPPTemplates { } // 14.5.6.2 Partial ordering of function templates - static int orderFunctionTemplates(ICPPFunctionTemplate f1, ICPPFunctionTemplate f2, TypeSelection mode) + static int orderFunctionTemplates(ICPPFunctionTemplate f1, ICPPFunctionTemplate f2, TypeSelection mode, IASTNode point) throws DOMException { if (f1 == f2) return 0; @@ -1849,8 +1901,8 @@ public class CPPTemplates { if (f2 == null) return 1; - int s1 = compareSpecialization(f1, f2, mode); - int s2 = compareSpecialization(f2, f1, mode); + int s1 = compareSpecialization(f1, f2, mode, point); + int s2 = compareSpecialization(f2, f1, mode, point); if (s1 == s2) return 0; @@ -1860,7 +1912,7 @@ public class CPPTemplates { return 1; } - private static ICPPFunction transferFunctionTemplate(ICPPFunctionTemplate f) throws DOMException { + private static ICPPFunction transferFunctionTemplate(ICPPFunctionTemplate f, IASTNode point) throws DOMException { final ICPPTemplateParameter[] tpars = f.getTemplateParameters(); final int argLen = tpars.length; @@ -1878,7 +1930,7 @@ public class CPPTemplates { } } - IBinding result = instantiateFunctionTemplate(f, args, map); + IBinding result = instantiateFunctionTemplate(f, args, map, point); if (result instanceof ICPPFunction) return (ICPPFunction) result; @@ -1895,8 +1947,8 @@ public class CPPTemplates { return arg; } - private static int compareSpecialization(ICPPFunctionTemplate f1, ICPPFunctionTemplate f2, TypeSelection mode) throws DOMException { - ICPPFunction transF1 = transferFunctionTemplate(f1); + private static int compareSpecialization(ICPPFunctionTemplate f1, ICPPFunctionTemplate f2, TypeSelection mode, IASTNode point) throws DOMException { + ICPPFunction transF1 = transferFunctionTemplate(f1, point); if (transF1 == null) return -1; @@ -1928,7 +1980,7 @@ public class CPPTemplates { } break; } - return TemplateArgumentDeduction.deduceForPartialOrdering(f2.getTemplateParameters(), pars, args); + return TemplateArgumentDeduction.deduceForPartialOrdering(f2.getTemplateParameters(), pars, args, point); } private static boolean isNonStaticMember(ICPPFunctionTemplate f) { @@ -1965,7 +2017,7 @@ public class CPPTemplates { } private static IBinding selectSpecialization(ICPPClassTemplate template, ICPPTemplateArgument[] args, - boolean isDef) throws DOMException { + boolean isDef, IASTNode point) throws DOMException { if (template == null) { return null; } @@ -1980,8 +2032,8 @@ public class CPPTemplates { for (ICPPClassTemplatePartialSpecialization specialization : specializations) { spec = specialization; final CPPTemplateParameterMap map = new CPPTemplateParameterMap(args.length); - if (TemplateArgumentDeduction.fromTemplateArguments(spec.getTemplateParameters(), spec.getTemplateArguments(), args, map)) { - int compare = orderSpecializations(bestMatch, spec); + if (TemplateArgumentDeduction.fromTemplateArguments(spec.getTemplateParameters(), spec.getTemplateArguments(), args, map, point)) { + int compare = orderSpecializations(bestMatch, spec, point); if (compare == 0) { bestMatchIsBest = false; } else if (compare < 0) { @@ -2001,7 +2053,7 @@ public class CPPTemplates { if (bestMatch == null) return null; - return instantiatePartialSpecialization(bestMatch, args, isDef, bestMap); + return instantiatePartialSpecialization(bestMatch, args, isDef, bestMap, point); } /** @@ -2009,10 +2061,11 @@ public class CPPTemplates { * is more specialized, = 0 otherwise. * @param spec1 * @param spec2 + * @param point * @return * @throws DOMException */ - static private int orderSpecializations(ICPPClassTemplatePartialSpecialization spec1, ICPPClassTemplatePartialSpecialization spec2) throws DOMException { + static private int orderSpecializations(ICPPClassTemplatePartialSpecialization spec1, ICPPClassTemplatePartialSpecialization spec2, IASTNode point) throws DOMException { if (spec1 == null) { return -1; } @@ -2023,8 +2076,8 @@ public class CPPTemplates { // 14.5.5.2 // A template is more specialized than another if and only if it is at least as specialized as the // other template and that template is not at least as specialized as the first. - boolean f1IsAtLeastAsSpecializedAsF2 = isAtLeastAsSpecializedAs(spec1, spec2); - boolean f2IsAtLeastAsSpecializedAsF1 = isAtLeastAsSpecializedAs(spec2, spec1); + boolean f1IsAtLeastAsSpecializedAsF2 = isAtLeastAsSpecializedAs(spec1, spec2, point); + boolean f2IsAtLeastAsSpecializedAsF1 = isAtLeastAsSpecializedAs(spec2, spec1, point); if (f1IsAtLeastAsSpecializedAsF2 == f2IsAtLeastAsSpecializedAsF1) return 0; @@ -2035,7 +2088,7 @@ public class CPPTemplates { return -1; } - private static boolean isAtLeastAsSpecializedAs(ICPPClassTemplatePartialSpecialization f1, ICPPClassTemplatePartialSpecialization f2) throws DOMException { + private static boolean isAtLeastAsSpecializedAs(ICPPClassTemplatePartialSpecialization f1, ICPPClassTemplatePartialSpecialization f2, IASTNode point) throws DOMException { // 14.5.5.2 // Using the transformed parameter list, perform argument deduction against the other // function template @@ -2058,16 +2111,16 @@ public class CPPTemplates { args[i]= arg; transferMap.put(param, arg); } - final ICPPTemplateArgument[] transferredArgs1 = instantiateArguments(targs1, transferMap, -1, null); + final ICPPTemplateArgument[] transferredArgs1 = instantiateArguments(targs1, transferMap, -1, null, point); // Deduce arguments for specialization 2 final CPPTemplateParameterMap deductionMap= new CPPTemplateParameterMap(2); - if (!TemplateArgumentDeduction.fromTemplateArguments(tpars2, targs2, transferredArgs1, deductionMap)) + if (!TemplateArgumentDeduction.fromTemplateArguments(tpars2, targs2, transferredArgs1, deductionMap, point)) return false; // Compare for (int i = 0; i < targs2.length; i++) { - ICPPTemplateArgument transferredArg2= instantiateArgument(targs2[i], deductionMap, -1, null); + ICPPTemplateArgument transferredArg2= instantiateArgument(targs2[i], deductionMap, -1, null, point); if (!transferredArg2.isSameValue(transferredArgs1[i])) return false; } @@ -2103,7 +2156,7 @@ public class CPPTemplates { } static ICPPTemplateArgument matchTemplateParameterAndArgument(ICPPTemplateParameter param, - ICPPTemplateArgument arg, CPPTemplateParameterMap map) { + ICPPTemplateArgument arg, CPPTemplateParameterMap map, IASTNode point) { if (arg == null || !isValidType(arg.getTypeValue())) { return null; } @@ -2150,9 +2203,9 @@ public class CPPTemplates { pType= ((ICPPParameterPackType) pType).getType(); } if (map != null && pType != null) { - pType= instantiateType(pType, map, -1, null); + pType= instantiateType(pType, map, -1, null, point); } - if (argType instanceof ICPPUnknownType || argType instanceof ISemanticProblem || isNonTypeArgumentConvertible(pType, argType)) { + if (argType instanceof ICPPUnknownType || argType instanceof ISemanticProblem || isNonTypeArgumentConvertible(pType, argType, point)) { return new CPPTemplateArgument(arg.getNonTypeValue(), pType); } return null; @@ -2226,14 +2279,14 @@ public class CPPTemplates { * @return * @throws DOMException */ - private static boolean isNonTypeArgumentConvertible(IType paramType, IType arg) throws DOMException { + private static boolean isNonTypeArgumentConvertible(IType paramType, IType arg, IASTNode point) throws DOMException { //14.1s8 function to pointer and array to pointer conversions if (paramType instanceof IFunctionType) { paramType = new CPPPointerType(paramType); } else if (paramType instanceof IArrayType) { paramType = new CPPPointerType(((IArrayType) paramType).getType()); } - Cost cost = Conversions.checkImplicitConversionSequence(paramType, arg, LVALUE, UDCMode.FORBIDDEN, Context.ORDINARY); + Cost cost = Conversions.checkImplicitConversionSequence(paramType, arg, LVALUE, UDCMode.FORBIDDEN, Context.ORDINARY, point); return cost != null && cost.converts(); } @@ -2326,7 +2379,7 @@ public class CPPTemplates { } t= ((ITypeContainer) t).getType(); } else if (t instanceof InitializerListType) { - return isDependentInitializerList(((InitializerListType) t).getInitializerList()); + return ((InitializerListType) t).getEvaluation().isTypeDependent(); } else if (t instanceof IBinding) { IBinding owner = ((IBinding) t).getOwner(); if (owner instanceof ICPPClassTemplate) @@ -2338,21 +2391,6 @@ public class CPPTemplates { } } - private static boolean isDependentInitializerList(ICPPASTInitializerList initializerList) { - IASTInitializerClause[] clauses= initializerList.getClauses(); - for (IASTInitializerClause clause : clauses) { - if (clause instanceof IASTExpression) { - IType t= ((IASTExpression) clause).getExpressionType(); - if (isDependentType(t)) - return true; - } else if (clause instanceof ICPPASTInitializerList) { - if (isDependentInitializerList((ICPPASTInitializerList) clause)) - return true; - } - } - return false; - } - public static boolean containsDependentArg(ObjectMap tpMap) { for (Object arg : tpMap.valueArray()) { if (isDependentType((IType)arg)) @@ -2365,9 +2403,9 @@ public class CPPTemplates { * Attempts to (partially) resolve an unknown binding with the given arguments. */ public static IBinding resolveUnknown(ICPPUnknownBinding unknown, ICPPTemplateParameterMap tpMap, - int packOffset, ICPPClassSpecialization within) throws DOMException { + int packOffset, ICPPClassSpecialization within, IASTNode point) throws DOMException { if (unknown instanceof ICPPDeferredClassInstance) { - return resolveDeferredClassInstance((ICPPDeferredClassInstance) unknown, tpMap, packOffset, within); + return resolveDeferredClassInstance((ICPPDeferredClassInstance) unknown, tpMap, packOffset, within, point); } final IBinding owner= unknown.getOwner(); @@ -2375,14 +2413,14 @@ public class CPPTemplates { return unknown; IBinding result = unknown; - IType t = CPPTemplates.instantiateType((IType) owner, tpMap, packOffset, within); + IType t = CPPTemplates.instantiateType((IType) owner, tpMap, packOffset, within, point); if (t != null) { t = SemanticUtil.getUltimateType(t, false); if (t instanceof ICPPUnknownBinding) { if (unknown instanceof ICPPUnknownClassInstance) { ICPPUnknownClassInstance ucli= (ICPPUnknownClassInstance) unknown; final ICPPTemplateArgument[] arguments = ucli.getArguments(); - ICPPTemplateArgument[] newArgs = CPPTemplates.instantiateArguments(arguments, tpMap, packOffset, within); + ICPPTemplateArgument[] newArgs = CPPTemplates.instantiateArguments(arguments, tpMap, packOffset, within, point); if (!t.equals(owner) && newArgs != arguments) { newArgs= SemanticUtil.getSimplifiedArguments(newArgs); result= new CPPUnknownClassInstance((ICPPUnknownBinding) t, ucli.getNameCharArray(), newArgs); @@ -2402,9 +2440,9 @@ public class CPPTemplates { result= CPPSemantics.resolveUnknownName(s, unknown); if (unknown instanceof ICPPUnknownClassInstance && result instanceof ICPPTemplateDefinition) { ICPPTemplateArgument[] newArgs = CPPTemplates.instantiateArguments( - ((ICPPUnknownClassInstance) unknown).getArguments(), tpMap, packOffset, within); + ((ICPPUnknownClassInstance) unknown).getArguments(), tpMap, packOffset, within, point); if (result instanceof ICPPClassTemplate) { - result = instantiate((ICPPClassTemplate) result, newArgs); + result = instantiate((ICPPClassTemplate) result, newArgs, point); } } } @@ -2417,18 +2455,18 @@ public class CPPTemplates { } private static IBinding resolveDeferredClassInstance(ICPPDeferredClassInstance dci, - ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within) { + ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within, IASTNode point) { ICPPTemplateArgument[] arguments = dci.getTemplateArguments(); ICPPTemplateArgument[] newArgs; try { - newArgs = CPPTemplates.instantiateArguments(arguments, tpMap, packOffset, within); + newArgs = CPPTemplates.instantiateArguments(arguments, tpMap, packOffset, within, point); } catch (DOMException e) { return e.getProblem(); } boolean changed= arguments != newArgs; ICPPClassTemplate classTemplate = dci.getClassTemplate(); - IType classTemplateSpecialization= instantiateType(classTemplate, tpMap, packOffset, within); + IType classTemplateSpecialization= instantiateType(classTemplate, tpMap, packOffset, within, point); if (classTemplateSpecialization != classTemplate && classTemplateSpecialization instanceof ICPPClassTemplate) { classTemplate= (ICPPClassTemplate) classTemplateSpecialization; changed= true; @@ -2438,11 +2476,11 @@ public class CPPTemplates { IBinding inst= null; if (classTemplate instanceof ICPPClassTemplatePartialSpecialization) { try { - inst= instantiatePartialSpecialization((ICPPClassTemplatePartialSpecialization) classTemplate, newArgs, false, null); + inst= instantiatePartialSpecialization((ICPPClassTemplatePartialSpecialization) classTemplate, newArgs, false, null, point); } catch (DOMException e) { } } else { - inst= instantiate(classTemplate, newArgs); + inst= instantiate(classTemplate, newArgs, point); } if (inst != null) return inst; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java index 2d1347274a9..f6369015283 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java @@ -13,11 +13,7 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; -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.TDEF; -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.getUltimateTypeUptoPointers; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*; import java.util.ArrayList; import java.util.Arrays; @@ -108,6 +104,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTIfStatement; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification; @@ -197,9 +194,12 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateArgument; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTypedef; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownTypeScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVariable; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType; import org.eclipse.cdt.internal.core.index.IIndexScope; /** @@ -230,6 +230,7 @@ public class CPPVisitor extends ASTQueries { return new HashSet(); } }; + private static final ICPPScope UNKNOWN_TYPE_SCOPE = new CPPUnknownTypeScope(new CPPASTName("".toCharArray()), null); //$NON-NLS-1$ public static IBinding createBinding(IASTName name) { IASTNode parent = name.getParent(); @@ -307,6 +308,32 @@ public class CPPVisitor extends ASTQueries { if (names.length < 2) return false; + IASTNode parent= qname.getParent(); + IASTNode decl= null; + if (parent instanceof IASTCompositeTypeSpecifier) { + decl= parent.getParent(); + } else if (parent instanceof IASTDeclarator) { + decl= ASTQueries.findOutermostDeclarator((IASTDeclarator) parent).getParent(); + } + IScope inScope= null; + while (decl != null) { + ASTNodeProperty prop = decl.getPropertyInParent(); + if (prop == IASTCompositeTypeSpecifier.MEMBER_DECLARATION) { + inScope = ((ICPPASTCompositeTypeSpecifier) decl.getParent()).getScope(); + break; + } else if (prop == ICPPASTNamespaceDefinition.OWNED_DECLARATION) { + inScope = ((ICPPASTNamespaceDefinition) decl.getParent()).getScope(); + break; + } else if (prop == ICPPASTTemplateDeclaration.OWNED_DECLARATION) { + decl= decl.getParent(); + } else { + return false; + } + } + + if (inScope == null) + return false; + IBinding pb= names[names.length-2].resolvePreBinding(); if (pb instanceof IProblemBinding) return false; @@ -320,32 +347,8 @@ public class CPPVisitor extends ASTQueries { } else if (pb instanceof ICPPNamespace) { scope= ((ICPPNamespace)pb).getNamespaceScope(); } - if (scope == null) - return false; - - IASTNode parent= qname.getParent(); - IASTNode decl= null; - if (parent instanceof IASTCompositeTypeSpecifier) { - decl= parent.getParent(); - } else if (parent instanceof IASTDeclarator) { - decl= ASTQueries.findOutermostDeclarator((IASTDeclarator) parent).getParent(); - } - while (decl != null) { - ASTNodeProperty prop = decl.getPropertyInParent(); - if (prop == IASTCompositeTypeSpecifier.MEMBER_DECLARATION) { - return scope == ((ICPPASTCompositeTypeSpecifier) decl.getParent()).getScope(); - } - if (prop == ICPPASTNamespaceDefinition.OWNED_DECLARATION) { - return scope == ((ICPPASTNamespaceDefinition) decl.getParent()).getScope(); - } - - if (prop == ICPPASTTemplateDeclaration.OWNED_DECLARATION) { - decl= decl.getParent(); - } else { - return false; - } - } - return false; + + return scope == inScope; } private static IBinding createBinding(IASTGotoStatement gotoStatement) { @@ -452,7 +455,7 @@ public class CPPVisitor extends ASTQueries { binding = CPPSemantics.resolveBinding(elabType.getName()); } if (binding instanceof IIndexBinding && binding instanceof ICPPClassType) { - binding= ((CPPASTTranslationUnit) elabType.getTranslationUnit()).mapToAST((ICPPClassType) binding); + binding= ((CPPASTTranslationUnit) elabType.getTranslationUnit()).mapToAST((ICPPClassType) binding, elabType); ASTInternal.addDeclaration(binding, elabType); } @@ -874,7 +877,7 @@ public class CPPVisitor extends ASTQueries { if (name == null) return false; final ASTNodeProperty propertyInParent = name.getPropertyInParent(); - if (propertyInParent == CPPSemantics.STRING_LOOKUP_PROPERTY || propertyInParent == null) + if (propertyInParent == null) return false; IASTNode parent = name.getParent(); if (parent instanceof ICPPASTTemplateId) { @@ -1130,11 +1133,7 @@ public class CPPVisitor extends ASTQueries { } public static IScope getContainingScope(IASTName name) { - return getContainingScope(name, null); - } - - public static IScope getContainingScope(IASTName name, LookupData data) { - IScope scope= getContainingScopeOrNull(name, data); + IScope scope= getContainingScopeOrNull(name); if (scope == null) { return new CPPScope.CPPScopeProblem(name, IProblemBinding.SEMANTIC_BAD_SCOPE); } @@ -1142,7 +1141,7 @@ public class CPPVisitor extends ASTQueries { return scope; } - private static IScope getContainingScopeOrNull(IASTName name, LookupData data) { + private static IScope getContainingScopeOrNull(IASTName name) { if (name == null) { return null; } @@ -1172,9 +1171,6 @@ public class CPPVisitor extends ASTQueries { parent= name.getParent(); } } else if (i > 0) { - if (data != null) { - data.usesEnclosingScope= false; - } // For template functions we may need to resolve a template parameter // as a parent of an unknown type used as parameter type. IBinding binding = names[i - 1].resolvePreBinding(); @@ -1190,7 +1186,7 @@ public class CPPVisitor extends ASTQueries { IScope scope= null; if (binding instanceof ICPPClassType) { if (binding instanceof IIndexBinding && tu != null) { - binding= (((CPPASTTranslationUnit) tu)).mapToAST((ICPPClassType) binding); + binding= (((CPPASTTranslationUnit) tu)).mapToAST((ICPPClassType) binding, name); } scope= ((ICPPClassType) binding).getCompositeScope(); } else if (binding instanceof ICPPNamespace) { @@ -1215,9 +1211,6 @@ public class CPPVisitor extends ASTQueries { } if (parent instanceof ICPPASTFieldReference) { - if (data != null) { - data.usesEnclosingScope= false; - } final ICPPASTFieldReference fieldReference = (ICPPASTFieldReference) parent; IType type = fieldReference.getFieldOwnerType(); type= getUltimateTypeUptoPointers(type); @@ -1226,8 +1219,9 @@ public class CPPVisitor extends ASTQueries { return ((ICPPClassType) type).getCompositeScope(); } else if (type instanceof ICPPUnknownBinding) { return ((ICPPUnknownBinding) type).asScope(); + } else if (type instanceof ICPPUnknownType) { + return UNKNOWN_TYPE_SCOPE; } else { - // mstodo introduce problem category return new CPPScope.CPPScopeProblem(name, ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); } } else if (parent instanceof IASTGotoStatement || parent instanceof IASTLabelStatement) { @@ -1285,7 +1279,7 @@ public class CPPVisitor extends ASTQueries { public static IASTNode getContainingBlockItem(IASTNode node) { if (node == null) return null; - if (node.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return null; + if (node.getPropertyInParent() == null) return null; IASTNode parent = node.getParent(); if (parent == null) return null; @@ -1960,14 +1954,14 @@ public class CPPVisitor extends ASTQueries { if (declarator instanceof ICPPASTFunctionDeclarator) { return createAutoFunctionType(declSpec, (ICPPASTFunctionDeclarator) declarator); } - IASTInitializerClause autoInitClause= null; + ICPPASTInitializerClause autoInitClause= null; IASTNode parent = declarator.getParent().getParent(); if (parent instanceof ICPPASTNewExpression) { IASTInitializer initializer = ((ICPPASTNewExpression) parent).getInitializer(); if (initializer != null) { IASTInitializerClause[] arguments = ((ICPPASTConstructorInitializer) initializer).getArguments(); if (arguments.length == 1) { - autoInitClause = arguments[0]; + autoInitClause = (ICPPASTInitializerClause) arguments[0]; } } } else if (parent instanceof ICPPASTRangeBasedForStatement) { @@ -1988,9 +1982,9 @@ public class CPPVisitor extends ASTQueries { IBinding b= implicits[0].getBinding(); CPPASTName name= new CPPASTName(); name.setBinding(b); - if (b instanceof ICPPMethod) { + if (b instanceof ICPPMethod && forInit instanceof IASTExpression) { beginExpr= new CPPASTFunctionCallExpression( - new CPPASTFieldReference(name, null), NO_ARGS); + new CPPASTFieldReference(name, (IASTExpression) forInit.copy()), NO_ARGS); } else { beginExpr= new CPPASTFunctionCallExpression(new CPPASTIdExpression(name), NO_ARGS); } @@ -2008,15 +2002,15 @@ public class CPPVisitor extends ASTQueries { } else { IASTInitializer initClause= declarator.getInitializer(); if (initClause instanceof IASTEqualsInitializer) { - autoInitClause= ((IASTEqualsInitializer) initClause).getInitializerClause(); - } else if (initClause instanceof IASTInitializerClause) { - autoInitClause= (IASTInitializerClause) initClause; + autoInitClause= (ICPPASTInitializerClause) ((IASTEqualsInitializer) initClause).getInitializerClause(); + } else if (initClause instanceof ICPPASTInitializerClause) { + autoInitClause= (ICPPASTInitializerClause) initClause; } } return createAutoType(autoInitClause, declSpec, declarator); } - private static IType createAutoType(IASTInitializerClause initClause, IASTDeclSpecifier declSpec, + private static IType createAutoType(ICPPASTInitializerClause initClause, IASTDeclSpecifier declSpec, IASTDeclarator declarator) { // C++0x: 7.1.6.4 if (initClause == null || !autoTypeDeclSpecs.get().add(declSpec)) { @@ -2035,20 +2029,15 @@ public class CPPVisitor extends ASTQueries { return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE); } type = (IType) CPPTemplates.instantiate(initializer_list_template, - new ICPPTemplateArgument[] { new CPPTemplateArgument(type) }); + new ICPPTemplateArgument[] { new CPPTemplateArgument(type) }, initClause); if (type instanceof IProblemBinding) { return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE); } } type = decorateType(type, declSpec, declarator); - - if (initClause instanceof IASTExpression) { - final IASTExpression expression = (IASTExpression) initClause; - initType = expression.getExpressionType(); - valueCat= expression.getValueCategory(); - } else if (initClause instanceof ICPPASTInitializerList) { - initType = new InitializerListType((ICPPASTInitializerList) initClause); - } + final ICPPEvaluation evaluation = initClause.getEvaluation(); + initType= evaluation.getTypeOrFunctionSet(declarator); + valueCat= evaluation.getValueCategory(declarator); if (initType == null) { return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE); } @@ -2058,7 +2047,7 @@ public class CPPVisitor extends ASTQueries { ICPPFunctionTemplate template = new AutoTypeResolver(type); CPPTemplateParameterMap paramMap = new CPPTemplateParameterMap(1); TemplateArgumentDeduction.deduceFromFunctionArgs(template, Collections.singletonList(initType), - Collections.singletonList(valueCat), paramMap); + Collections.singletonList(valueCat), paramMap, initClause); ICPPTemplateArgument argument = paramMap.getArgument(0, 0); if (argument == null) { return new ProblemType(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE); @@ -2069,7 +2058,7 @@ public class CPPVisitor extends ASTQueries { type = t; if (initClause instanceof ICPPASTInitializerList) { type = (IType) CPPTemplates.instantiate(initializer_list_template, - new ICPPTemplateArgument[] { new CPPTemplateArgument(type) }); + new ICPPTemplateArgument[] { new CPPTemplateArgument(type) }, initClause); } return decorateType(type, declSpec, declarator); } @@ -2241,8 +2230,8 @@ public class CPPVisitor extends ASTQueries { return null; } - public static IType getPointerDiffType(final IASTBinaryExpression binary) { - IType t= getStdType(binary, PTRDIFF_T); + public static IType getPointerDiffType(final IASTNode point) { + IType t= getStdType(point, PTRDIFF_T); return t != null ? t : INT_TYPE; } @@ -2264,8 +2253,8 @@ public class CPPVisitor extends ASTQueries { return null; } - public static IType get_type_info(IASTExpression expression) { - IType t= getStdType(expression, TYPE_INFO); + public static IType get_type_info(IASTNode point) { + IType t= getStdType(point, TYPE_INFO); return t != null ? t : INT_TYPE; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java index c94bc69312f..1a63d462fee 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java @@ -32,9 +32,8 @@ import java.util.Collections; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; -import org.eclipse.cdt.core.dom.ast.IASTInitializerClause; import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression; -import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBasicType.Kind; @@ -46,7 +45,6 @@ import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IQualifierType; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IValue; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; @@ -63,12 +61,12 @@ import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.parser.ArithmeticConversion; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; import org.eclipse.cdt.internal.core.dom.parser.Value; -import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerToMemberType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPQualifierType; import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.DeferredUDC; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.Rank; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.ReferenceBinding; @@ -93,7 +91,7 @@ public class Conversions { * @throws DOMException */ public static Cost checkImplicitConversionSequence(IType target, IType exprType, - ValueCategory valueCat, UDCMode udc, Context ctx) throws DOMException { + ValueCategory valueCat, UDCMode udc, Context ctx, IASTNode point) throws DOMException { final boolean isImpliedObject= ctx == Context.IMPLICIT_OBJECT; if (isImpliedObject) udc= UDCMode.FORBIDDEN; @@ -124,7 +122,7 @@ public class Conversions { if (isLValueRef && getCVQualifier(cv1T1) != CVQualifier.CONST) return Cost.NO_CONVERSION; - Cost cost= listInitializationSequence(((InitializerListType) exprType), T1, udc, false); + Cost cost= listInitializationSequence(((InitializerListType) exprType).getEvaluation(), T1, udc, false, point); if (cost.converts()) { cost.setReferenceBinding(refBindingType); } @@ -148,7 +146,7 @@ public class Conversions { // 'cv3 T3' (this conversion is selected by enumerating the applicable conversion functions (13.3.1.6) // and choosing the best one through overload resolution (13.3)), if (T2 instanceof ICPPClassType && udc != UDCMode.FORBIDDEN && isReferenceRelated(T1, T2) < 0) { - Cost cost= initializationByConversionForDirectReference(cv1T1, cv2T2, (ICPPClassType) T2, true, ctx); + Cost cost= initializationByConversionForDirectReference(cv1T1, cv2T2, (ICPPClassType) T2, true, ctx, point); if (cost != null) { cost.setReferenceBinding(refBindingType); return cost; @@ -182,7 +180,7 @@ public class Conversions { // and choosing the best one through overload resolution (13.3)), the reference is bound to the // function lvalue that is the result of the conversion; if (T2 instanceof ICPPClassType) { - Cost cost= initializationByConversionForDirectReference(cv1T1, cv2T2, (ICPPClassType) T2, true, ctx); + Cost cost= initializationByConversionForDirectReference(cv1T1, cv2T2, (ICPPClassType) T2, true, ctx, point); if (cost != null) { cost.setReferenceBinding(refBindingType); return cost; @@ -215,7 +213,7 @@ public class Conversions { // first case and to the object that is the result of the conversion in the second case (or, // in either case, to the appropriate base class sub-object of the object). if (udc != UDCMode.FORBIDDEN && isReferenceRelated(T1, T2) < 0) { - Cost cost= initializationByConversionForDirectReference(cv1T1, cv2T2, (ICPPClassType) T2, false, ctx); + Cost cost= initializationByConversionForDirectReference(cv1T1, cv2T2, (ICPPClassType) T2, false, ctx, point); if (cost != null) { cost.setReferenceBinding(refBindingType); return cost; @@ -242,7 +240,7 @@ public class Conversions { // 13.3.3.1.7 no temporary object when converting the implicit object parameter if (!isImpliedObject && ctx != Context.REQUIRE_DIRECT_BINDING) { if (isReferenceRelated(T1, T2) < 0 || compareQualifications(cv1T1, cv2T2) >= 0) { - Cost cost= nonReferenceConversion(valueCat, cv2T2, T1, udc); + Cost cost= nonReferenceConversion(valueCat, cv2T2, T1, udc, point); if (cost.converts()) { cost.setReferenceBinding(refBindingType); } @@ -253,13 +251,14 @@ public class Conversions { } // Non-reference binding - return nonReferenceConversion(valueCat, exprType, T1, udc); + return nonReferenceConversion(valueCat, exprType, T1, udc, point); } /** * C++0x: 13.3.1.6 Initialization by conversion function for direct reference binding + * @param point */ - private static Cost initializationByConversionForDirectReference(final IType cv1T1, final IType cv2T2, final ICPPClassType T2, boolean needLValue, Context ctx) + private static Cost initializationByConversionForDirectReference(final IType cv1T1, final IType cv2T2, final ICPPClassType T2, boolean needLValue, Context ctx, IASTNode point) throws DOMException { ICPPMethod[] fcns= SemanticUtil.getConversionOperators(T2); Cost operatorCost= null; @@ -282,7 +281,7 @@ public class Conversions { // Make sure top-level cv-qualifiers are compared udcCost.setReferenceBinding(ReferenceBinding.LVALUE_REF); FunctionCost udcFuncCost= new FunctionCost(op, udcCost); - int cmp= udcFuncCost.compareTo(null, bestUdcCost); + int cmp= udcFuncCost.compareTo(null, bestUdcCost, point); if (cmp <= 0) { Cost cost= isReferenceCompatible(cv1T1, getNestedType(t, TDEF | REF), false); // converted to target if (cost != null) { @@ -306,9 +305,9 @@ public class Conversions { /** * 8.5-16 */ - private static Cost nonReferenceConversion(ValueCategory valueCat, IType source, IType target, UDCMode udc) throws DOMException { + private static Cost nonReferenceConversion(ValueCategory valueCat, IType source, IType target, UDCMode udc, IASTNode point) throws DOMException { if (source instanceof InitializerListType) { - return listInitializationSequence(((InitializerListType) source), target, udc, false); + return listInitializationSequence(((InitializerListType) source).getEvaluation(), target, udc, false, point); } IType uqTarget= SemanticUtil.getNestedType(target, TDEF | REF | CVTYPE); @@ -329,14 +328,14 @@ public class Conversions { if (udc == UDCMode.FORBIDDEN) return Cost.NO_CONVERSION; - return copyInitializationOfClass(valueCat, source, (ICPPClassType) uqTarget, udc == UDCMode.DEFER); + return copyInitializationOfClass(valueCat, source, (ICPPClassType) uqTarget, udc == UDCMode.DEFER, point); } if (uqSource instanceof ICPPClassType) { if (udc == UDCMode.FORBIDDEN) return Cost.NO_CONVERSION; - return initializationByConversion(valueCat, source, (ICPPClassType) uqSource, target, udc == UDCMode.DEFER); + return initializationByConversion(valueCat, source, (ICPPClassType) uqSource, target, udc == UDCMode.DEFER, point); } return checkStandardConversionSequence(uqSource, target); @@ -345,15 +344,14 @@ public class Conversions { /** * 13.3.3.1.5 List-initialization sequence [over.ics.list] */ - static Cost listInitializationSequence(InitializerListType arg, IType target, UDCMode udc, boolean isDirect) throws DOMException { + static Cost listInitializationSequence(EvalInitList arg, IType target, UDCMode udc, boolean isDirect, IASTNode point) throws DOMException { IType listType= getInitListType(target); if (listType != null) { - IType[] exprTypes= arg.getExpressionTypes(); - ValueCategory[] valueCats= arg.getValueCategories(); - Cost worstCost= new Cost(arg, target, Rank.IDENTITY); - for (int i = 0; i < exprTypes.length; i++) { - IType exprType = exprTypes[i]; - Cost cost= checkImplicitConversionSequence(listType, exprType, valueCats[i], UDCMode.ALLOWED, Context.ORDINARY); + ICPPEvaluation[] clauses = arg.getClauses(); + Cost worstCost= new Cost(arg.getTypeOrFunctionSet(point), target, Rank.IDENTITY); + for (ICPPEvaluation clause : clauses) { + Cost cost= checkImplicitConversionSequence(listType, clause.getTypeOrFunctionSet(point), + clause.getValueCategory(point), UDCMode.ALLOWED, Context.ORDINARY, point); if (!cost.converts()) return cost; if (cost.isNarrowingConversion()) { @@ -374,26 +372,25 @@ public class Conversions { ICPPClassType classTarget= (ICPPClassType) noCVTarget; if (ClassTypeHelper.isAggregateClass(classTarget)) { - Cost cost= new Cost(arg, target, Rank.IDENTITY); + Cost cost= new Cost(arg.getTypeOrFunctionSet(point), target, Rank.IDENTITY); cost.setUserDefinedConversion(null); return cost; } - return listInitializationOfClass(arg, classTarget, isDirect, udc == UDCMode.DEFER); + return listInitializationOfClass(arg, classTarget, isDirect, udc == UDCMode.DEFER, point); } - IASTInitializerClause[] args = arg.getInitializerList().getClauses(); + ICPPEvaluation[] args = arg.getClauses(); if (args.length == 1) { - final IASTInitializerClause firstArg = args[0]; - if (firstArg instanceof IASTExpression) { - IASTExpression expr= (IASTExpression) firstArg; - Cost cost= checkImplicitConversionSequence(target, expr.getExpressionType(), expr.getValueCategory(), udc, Context.ORDINARY); + final ICPPEvaluation firstArg = args[0]; + if (!firstArg.isInitializerList()) { + Cost cost= checkImplicitConversionSequence(target, firstArg.getTypeOrFunctionSet(point), firstArg.getValueCategory(point), udc, Context.ORDINARY, point); if (cost.isNarrowingConversion()) { return Cost.NO_CONVERSION; } return cost; } } else if (args.length == 0) { - return new Cost(arg, target, Rank.IDENTITY); + return new Cost(arg.getTypeOrFunctionSet(point), target, Rank.IDENTITY); } return Cost.NO_CONVERSION; @@ -538,9 +535,9 @@ public class Conversions { } // 13.3.1.7 Initialization by list-initialization - static Cost listInitializationOfClass(InitializerListType arg, ICPPClassType t, boolean isDirect, boolean deferUDC) throws DOMException { + static Cost listInitializationOfClass(EvalInitList arg, ICPPClassType t, boolean isDirect, boolean deferUDC, IASTNode point) throws DOMException { if (deferUDC) { - Cost c= new Cost(arg, t, Rank.USER_DEFINED_CONVERSION); + Cost c= new Cost(arg.getTypeOrFunctionSet(point), t, Rank.USER_DEFINED_CONVERSION); c.setDeferredUDC(isDirect ? DeferredUDC.DIRECT_LIST_INIT_OF_CLASS : DeferredUDC.LIST_INIT_OF_CLASS); return c; } @@ -554,8 +551,8 @@ public class Conversions { for (ICPPConstructor ctor : ctors) { final int minArgCount = ctor.getRequiredArgumentCount(); if (minArgCount == 0) { - if (arg.getExpressionTypes().length == 0) { - Cost c= new Cost(arg, t, Rank.IDENTITY); + if (arg.getClauses().length == 0) { + Cost c= new Cost(arg.getTypeOrFunctionSet(point), t, Rank.IDENTITY); c.setUserDefinedConversion(ctor); return c; } @@ -565,7 +562,7 @@ public class Conversions { final IType target = parTypes[0]; if (getInitListType(target) != null) { hasInitListConstructor= true; - Cost cost= listInitializationSequence(arg, target, UDCMode.FORBIDDEN, isDirect); + Cost cost= listInitializationSequence(arg, target, UDCMode.FORBIDDEN, isDirect, point); if (cost.converts()) { int cmp= cost.compareTo(bestCost); if (bestCost == null || cmp < 0) { @@ -593,13 +590,8 @@ public class Conversions { } // No initializer-list constructor - final ICPPASTInitializerList initializerList = arg.getInitializerList(); - - LookupData data= new LookupData(); - IASTName name = new CPPASTName(t.getNameCharArray()); - name.setParent(initializerList); - name.setPropertyInParent(CPPSemantics.STRING_LOOKUP_PROPERTY); - final IASTInitializerClause[] expandedArgs = initializerList.getClauses(); + LookupData data= new LookupData(t.getNameCharArray(), null, point); + final ICPPEvaluation[] expandedArgs = arg.getClauses(); data.setFunctionArguments(false, expandedArgs); data.fNoNarrowing= true; @@ -623,11 +615,11 @@ public class Conversions { final IBinding result= CPPSemantics.resolveFunction(data, filteredConstructors, true); final Cost c; if (result instanceof ICPPMethod) { - c= new Cost(arg, t, Rank.IDENTITY); + c= new Cost(arg.getTypeOrFunctionSet(point), t, Rank.IDENTITY); c.setUserDefinedConversion((ICPPMethod) result); } else if (result instanceof IProblemBinding && ((IProblemBinding) result).getID() == IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP) { - c = new Cost(arg, t, Rank.USER_DEFINED_CONVERSION); + c = new Cost(arg.getTypeOrFunctionSet(point), t, Rank.USER_DEFINED_CONVERSION); c.setAmbiguousUDC(true); } else { c= Cost.NO_CONVERSION; @@ -638,7 +630,7 @@ public class Conversions { /** * 13.3.1.4 Copy-initialization of class by user-defined conversion [over.match.copy] */ - static final Cost copyInitializationOfClass(ValueCategory valueCat, IType source, ICPPClassType t, boolean deferUDC) throws DOMException { + static final Cost copyInitializationOfClass(ValueCategory valueCat, IType source, ICPPClassType t, boolean deferUDC, IASTNode point) throws DOMException { if (deferUDC) { Cost c= new Cost(source, t, Rank.USER_DEFINED_CONVERSION); c.setDeferredUDC(DeferredUDC.COPY_INIT_OF_CLASS); @@ -648,8 +640,8 @@ public class Conversions { FunctionCost cost1= null; Cost cost2= null; ICPPFunction[] ctors= t.getConstructors(); - ctors = CPPTemplates.instantiateForFunctionCall(null, ctors, - Collections.singletonList(source), Collections.singletonList(valueCat), false); + ctors = CPPTemplates.instantiateForFunctionCall(ctors, null, + Collections.singletonList(source), Collections.singletonList(valueCat), false, point); for (ICPPFunction f : ctors) { if (!(f instanceof ICPPConstructor) || f instanceof IProblemBinding) @@ -677,9 +669,9 @@ public class Conversions { if (ctor.getRequiredArgumentCount() > 1) continue; - c1= new FunctionCost(ctor, checkImplicitConversionSequence(ptype, source, valueCat, UDCMode.FORBIDDEN, Context.ORDINARY)); + c1= new FunctionCost(ctor, checkImplicitConversionSequence(ptype, source, valueCat, UDCMode.FORBIDDEN, Context.ORDINARY, point)); } - int cmp= c1.compareTo(null, cost1); + int cmp= c1.compareTo(null, cost1, point); if (cmp <= 0) { cost1= c1; cost2= new Cost(t, t, Rank.IDENTITY); @@ -694,7 +686,7 @@ public class Conversions { final IType uqSource= getNestedType(source, TDEF | REF | CVTYPE); if (uqSource instanceof ICPPClassType) { ICPPFunction[] ops = SemanticUtil.getConversionOperators((ICPPClassType) uqSource); - ops= CPPTemplates.instantiateConversionTemplates(ops, t); + ops= CPPTemplates.instantiateConversionTemplates(ops, t, point); for (final ICPPFunction f : ops) { if (f instanceof ICPPMethod && !(f instanceof IProblemBinding)) { ICPPMethod op= (ICPPMethod) f; @@ -710,7 +702,7 @@ public class Conversions { // Make sure top-level cv-qualifiers are compared udcCost.setReferenceBinding(ReferenceBinding.LVALUE_REF); FunctionCost c1= new FunctionCost(op, udcCost); - int cmp= c1.compareTo(null, cost1); + int cmp= c1.compareTo(null, cost1, point); if (cmp <= 0) { cost1= c1; cost2= new Cost(t, t, Rank.IDENTITY); @@ -737,14 +729,14 @@ public class Conversions { /** * 13.3.1.5 Initialization by conversion function [over.match.conv] */ - static Cost initializationByConversion(ValueCategory valueCat, IType source, ICPPClassType uqSource, IType target, boolean deferUDC) throws DOMException { + static Cost initializationByConversion(ValueCategory valueCat, IType source, ICPPClassType uqSource, IType target, boolean deferUDC, IASTNode point) throws DOMException { if (deferUDC) { Cost c= new Cost(source, target, Rank.USER_DEFINED_CONVERSION); c.setDeferredUDC(DeferredUDC.INIT_BY_CONVERSION); return c; } ICPPFunction[] ops = SemanticUtil.getConversionOperators(uqSource); - ops= CPPTemplates.instantiateConversionTemplates(ops, target); + ops= CPPTemplates.instantiateConversionTemplates(ops, target, point); FunctionCost cost1= null; Cost cost2= null; for (final ICPPFunction f : ops) { @@ -756,7 +748,7 @@ public class Conversions { final IType returnType = op.getType().getReturnType(); IType uqReturnType= getNestedType(returnType, TDEF | ALLCVQ); - Cost c2= checkImplicitConversionSequence(target, uqReturnType, valueCategoryFromReturnType(uqReturnType), UDCMode.FORBIDDEN, Context.ORDINARY); + Cost c2= checkImplicitConversionSequence(target, uqReturnType, valueCategoryFromReturnType(uqReturnType), UDCMode.FORBIDDEN, Context.ORDINARY, point); if (c2.converts()) { if (isExplicitConversion && c2.getRank() != Rank.IDENTITY) continue; @@ -766,7 +758,7 @@ public class Conversions { // Make sure top-level cv-qualifiers are compared udcCost.setReferenceBinding(ReferenceBinding.LVALUE_REF); FunctionCost c1= new FunctionCost(op, udcCost); - int cmp= c1.compareTo(null, cost1); + int cmp= c1.compareTo(null, cost1, point); if (cmp <= 0) { cost1= c1; cost2= c2; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java new file mode 100644 index 00000000000..6f5c0d98f17 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java @@ -0,0 +1,276 @@ +/******************************************************************************* + * Copyright (c) 2012 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 + * + * 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; +import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromFunctionCall; +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 org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; +import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IPointerType; +import org.eclipse.cdt.core.dom.ast.ISemanticProblem; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.IValue; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; +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.CPPArithmeticConversion; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; +import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator; +import org.eclipse.core.runtime.CoreException; + +/** + * Performs evaluation of an expression. + */ +public class EvalBinary implements ICPPEvaluation { + 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; + + public EvalBinary(int operator, ICPPEvaluation arg1, ICPPEvaluation arg2) { + fOperator= operator; + fArg1= arg1; + fArg2= arg2; + } + + public int getOperator() { + return fOperator; + } + + public ICPPEvaluation getArg1() { + return fArg1; + } + + public ICPPEvaluation getArg2() { + return fArg2; + } + + @Override + public boolean isInitializerList() { + return false; + } + + @Override + public boolean isFunctionSet() { + return false; + } + + @Override + public IType getTypeOrFunctionSet(IASTNode point) { + if (fType == null) { + if (isTypeDependent()) { + fType= new TypeOfDependentExpression(this); + } else { + ICPPFunction overload = getOverload(point); + if (overload != null) { + fType= ExpressionTypes.typeFromFunctionCall(overload); + } else { + fType= computeType(point); + } + } + } + return fType; + } + + @Override + public IValue getValue(IASTNode point) { + return Value.create(this, point); + } + + @Override + public boolean isTypeDependent() { + if (fType != null) { + return fType instanceof TypeOfDependentExpression; + } + return fArg1.isTypeDependent() || fArg2.isTypeDependent(); + } + + @Override + public boolean isValueDependent() { + return fArg1.isValueDependent() || fArg2.isValueDependent(); + } + + @Override + public ValueCategory getValueCategory(IASTNode point) { + if (isTypeDependent()) + return ValueCategory.PRVALUE; + + ICPPFunction overload = getOverload(point); + if (overload != null) + return ExpressionTypes.valueCategoryFromFunctionCall(overload); + + switch (fOperator) { + case op_arrayAccess: + case IASTBinaryExpression.op_assign: + case IASTBinaryExpression.op_binaryAndAssign: + case IASTBinaryExpression.op_binaryOrAssign: + case IASTBinaryExpression.op_binaryXorAssign: + case IASTBinaryExpression.op_divideAssign: + case IASTBinaryExpression.op_minusAssign: + case IASTBinaryExpression.op_moduloAssign: + case IASTBinaryExpression.op_multiplyAssign: + case IASTBinaryExpression.op_plusAssign: + case IASTBinaryExpression.op_shiftLeftAssign: + case IASTBinaryExpression.op_shiftRightAssign: + return LVALUE; + + case IASTBinaryExpression.op_pmdot: + if (!(getTypeOrFunctionSet(point) instanceof ICPPFunctionType)) + return fArg1.getValueCategory(point); + break; + + case IASTBinaryExpression.op_pmarrow: + if (!(getTypeOrFunctionSet(point) instanceof ICPPFunctionType)) + return LVALUE; + break; + } + + return ValueCategory.PRVALUE; + } + + public ICPPFunction getOverload(IASTNode point) { + if (fOverload == CPPFunction.UNINITIALIZED_FUNCTION) { + fOverload= computeOverload(point); + } + return fOverload; + } + + private ICPPFunction computeOverload(IASTNode point) { + if (isTypeDependent()) + return null; + + if (fOperator == op_arrayAccess) { + IType type = fArg1.getTypeOrFunctionSet(point); + type= SemanticUtil.getNestedType(type, TDEF | REF | CVTYPE); + if (type instanceof ICPPClassType) { + return CPPSemantics.findOverloadedBinaryOperator(point, OverloadableOperator.BRACKET, fArg1, fArg2); + } + } else { + final OverloadableOperator op = OverloadableOperator.fromBinaryExpression(fOperator); + if (op != null) { + return CPPSemantics.findOverloadedBinaryOperator(point, op, fArg1, fArg2); + } + } + return null; + } + + public IType computeType(IASTNode point) { + // Check for overloaded operator. + ICPPFunction o= getOverload(point); + if (o != null) + return typeFromFunctionCall(o); + + IType type1 = prvalueType(fArg1.getTypeOrFunctionSet(point)); + if (type1 instanceof ISemanticProblem) { + return type1; + } + + IType type2 = prvalueType(fArg2.getTypeOrFunctionSet(point)); + if (type2 instanceof ISemanticProblem) { + return type2; + } + + IType type= CPPArithmeticConversion.convertCppOperandTypes(fOperator, type1, type2); + if (type != null) { + return type; + } + + + switch (fOperator) { + case op_arrayAccess: + if (type1 instanceof IPointerType) { + return glvalueType(((IPointerType) type1).getType()); + } + if (type2 instanceof IPointerType) { + return glvalueType(((IPointerType) type2).getType()); + } + return ProblemType.UNKNOWN_FOR_EXPRESSION; + + case IASTBinaryExpression.op_lessEqual: + case IASTBinaryExpression.op_lessThan: + case IASTBinaryExpression.op_greaterEqual: + case IASTBinaryExpression.op_greaterThan: + case IASTBinaryExpression.op_logicalAnd: + case IASTBinaryExpression.op_logicalOr: + case IASTBinaryExpression.op_equals: + case IASTBinaryExpression.op_notequals: + return CPPBasicType.BOOLEAN; + + case IASTBinaryExpression.op_plus: + if (type1 instanceof IPointerType) { + return type1; + } + if (type2 instanceof IPointerType) { + return type2; + } + break; + + case IASTBinaryExpression.op_minus: + if (type1 instanceof IPointerType) { + if (type2 instanceof IPointerType) { + return CPPVisitor.getPointerDiffType(point); + } + return type1; + } + break; + + case ICPPASTBinaryExpression.op_pmarrow: + case ICPPASTBinaryExpression.op_pmdot: + if (type2 instanceof ICPPPointerToMemberType) { + IType t= ((ICPPPointerToMemberType) type2).getType(); + if (t instanceof ICPPFunctionType) + return t; + if (fOperator == ICPPASTBinaryExpression.op_pmdot && fArg1.getValueCategory(point) == PRVALUE) { + return prvalueType(t); + } + return glvalueType(t); + } + return ProblemType.UNKNOWN_FOR_EXPRESSION; + } + return type1; + } + + @Override + public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException { + buffer.putByte(ITypeMarshalBuffer.EVAL_BINARY); + buffer.putByte((byte) fOperator); + 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(); + ICPPEvaluation arg2= (ICPPEvaluation) buffer.unmarshalEvaluation(); + return new EvalBinary(op, arg1, arg2); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinaryTypeId.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinaryTypeId.java new file mode 100644 index 00000000000..f710e0b834e --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinaryTypeId.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * Copyright (c) 2012 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 + * + * 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.PRVALUE; + +import org.eclipse.cdt.core.dom.ast.IASTBinaryTypeIdExpression.Operator; +import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.ISemanticProblem; +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.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 { + 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; + fType2= type2; + } + + public Operator getOperator() { + return fOperator; + } + + public IType getType1() { + return fType1; + } + + public IType getType2() { + return fType2; + } + + @Override + public boolean isInitializerList() { + return false; + } + + @Override + public boolean isFunctionSet() { + return false; + } + + @Override + public IType getTypeOrFunctionSet(IASTNode point) { + switch (fOperator) { + case __is_base_of: + return CPPBasicType.BOOLEAN; + } + return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); + } + + @Override + public IValue getValue(IASTNode point) { + return Value.create(this, point); + } + + @Override + public boolean isTypeDependent() { + return false; + } + + @Override + public boolean isValueDependent() { + if (!fCheckedValueDependent) { + fIsValueDependent= CPPTemplates.isDependentType(fType1) || CPPTemplates.isDependentType(fType2); + fCheckedValueDependent= true; + } + return fIsValueDependent; + } + + @Override + public ValueCategory getValueCategory(IASTNode point) { + return PRVALUE; + } + + @Override + public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException { + buffer.putByte(ITypeMarshalBuffer.EVAL_BINARY_TYPE_ID); + buffer.putByte((byte) fOperator.ordinal()); + buffer.marshalType(fType1); + buffer.marshalType(fType2); + } + + public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException { + int op= buffer.getByte(); + IType arg1= buffer.unmarshalType(); + IType arg2= buffer.unmarshalType(); + return new EvalBinaryTypeId(Operator.values()[op], arg1, arg2); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java new file mode 100644 index 00000000000..b353d5f4040 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinding.java @@ -0,0 +1,189 @@ +/******************************************************************************* + * Copyright (c) 2012 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 + * + * Contributors: + * 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; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType; + +import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IEnumerator; +import org.eclipse.cdt.core.dom.ast.IFunction; +import org.eclipse.cdt.core.dom.ast.IFunctionType; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.IValue; +import org.eclipse.cdt.core.dom.ast.IVariable; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter; +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 { + private final IBinding fBinding; + private final boolean fFixedType; + + private IType fType; + private boolean fCheckedIsValueDependent; + private boolean fIsValueDependent; + private boolean fIsTypeDependent; + private boolean fCheckedIsTypeDependent; + + + public EvalBinding(IBinding binding, IType type) { + fBinding= binding; + fType= type; + fFixedType= type != null; + } + + public IBinding getBinding() { + return fBinding; + } + + public IType getFixedType() { + return fFixedType ? fType : null; + } + + @Override + public boolean isInitializerList() { + return false; + } + + @Override + public boolean isFunctionSet() { + return false; + } + + @Override + public boolean isTypeDependent() { + if (!fCheckedIsTypeDependent) { + fCheckedIsTypeDependent= true; + fIsTypeDependent= computeIsTypeDependent(); + } + return fIsTypeDependent; + } + + private boolean computeIsTypeDependent() { + if (fBinding instanceof ICPPUnknownBinding) + return true; + + IType t= null; + if (fBinding instanceof IEnumerator) { + t= ((IEnumerator) fBinding).getType(); + } else if (fBinding instanceof ICPPTemplateNonTypeParameter) { + t= ((ICPPTemplateNonTypeParameter) fBinding).getType(); + } else if (fBinding instanceof IVariable) { + t = ((IVariable) fBinding).getType(); + } else if (fBinding instanceof IFunction) { + t= ((IFunction) fBinding).getType(); + } else if (fBinding instanceof ICPPUnknownBinding) { + return true; + } else { + return false; + } + return CPPTemplates.isDependentType(t); + } + + @Override + public boolean isValueDependent() { + if (!fCheckedIsValueDependent) { + fCheckedIsValueDependent= true; + fIsValueDependent= computeIsValueDependent(); + } + 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) { + fType= computeType(point); + } + 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; + } + return ValueCategory.PRVALUE; + } + + @Override + public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException { + buffer.putByte(ITypeMarshalBuffer.EVAL_BINDING); + 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(); + return new EvalBinding(binding, type); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalComma.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalComma.java new file mode 100644 index 00000000000..5925b119095 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalComma.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * Copyright (c) 2012 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 + * + * Contributors: + * 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; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCategoryFromFunctionCall; + +import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.ISemanticProblem; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.IValue; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; +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.core.runtime.CoreException; + +public class EvalComma implements ICPPEvaluation { + private static final ICPPFunction[] NO_FUNCTIONS = {}; + + private final ICPPEvaluation[] fArguments; + private ICPPFunction[] fOverloads; + + private IType fType; + + public EvalComma(ICPPEvaluation[] evals) { + fArguments= evals; + } + + public ICPPEvaluation[] getArguments() { + return fArguments; + } + + @Override + public boolean isInitializerList() { + return false; + } + + @Override + public boolean isFunctionSet() { + return false; + } + + @Override + public boolean isTypeDependent() { + if (fType != null) + return fType instanceof TypeOfDependentExpression; + + for (ICPPEvaluation arg : fArguments) { + if (arg.isTypeDependent()) + return true; + } + return false; + } + + @Override + public boolean isValueDependent() { + for (ICPPEvaluation arg : fArguments) { + if (arg.isValueDependent()) + return true; + } + return false; + } + + public ICPPFunction[] getOverloads(IASTNode point) { + if (fOverloads == null) { + fOverloads= computeOverloads(point); + } + return fOverloads; + } + + 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]; + for (int i = 1; i < fArguments.length; i++) { + ICPPEvaluation e2 = fArguments[i]; + ICPPFunction overload = CPPSemantics.findOverloadedOperatorComma(point, e1, e2); + if (overload == null) { + e1= e2; + } else { + overloads[i - 1] = overload; + e1= new EvalFixed(typeFromFunctionCall(overload), valueCategoryFromFunctionCall(overload), Value.UNKNOWN); + if (e1.getTypeOrFunctionSet(point) instanceof ISemanticProblem) { + e1= e2; + } + } + } + return overloads; + } + + @Override + public IType getTypeOrFunctionSet(IASTNode point) { + if (fType == null) { + fType= computeType(point); + } + 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]; + if (last != null) { + return typeFromFunctionCall(last); + } + } + return fArguments[fArguments.length-1].getTypeOrFunctionSet(point); + } + + @Override + public IValue getValue(IASTNode point) { + return Value.create(this, point); + } + + @Override + public ValueCategory getValueCategory(IASTNode point) { + ICPPFunction[] overloads = getOverloads(point); + if (overloads.length > 0) { + ICPPFunction last = overloads[overloads.length - 1]; + if (last != null) { + return valueCategoryFromFunctionCall(last); + } + } + return fArguments[fArguments.length-1].getValueCategory(point); + } + + @Override + public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException { + buffer.putByte(ITypeMarshalBuffer.EVAL_COMMA); + buffer.putShort((short) fArguments.length); + for (ICPPEvaluation arg : fArguments) { + buffer.marshalEvaluation(arg, includeValue); + } + } + + public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException { + int len= buffer.getShort(); + ICPPEvaluation[] args = new ICPPEvaluation[len]; + for (int i = 0; i < args.length; i++) { + args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation(); + } + return new EvalComma(args); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalCompound.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalCompound.java new file mode 100644 index 00000000000..c602e10c936 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalCompound.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2012 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 + * + * 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.PRVALUE; + +import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; +import org.eclipse.cdt.core.dom.ast.IASTNode; +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.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; + +/** + * Performs evaluation of an expression. + */ +public class EvalCompound implements ICPPEvaluation { + private final ICPPEvaluation fDelegate; + + public EvalCompound(ICPPEvaluation delegate) { + fDelegate= delegate; + } + + public ICPPEvaluation getLastEvaluation() { + return fDelegate; + } + + @Override + public boolean isInitializerList() { + return false; + } + + @Override + public boolean isFunctionSet() { + return false; + } + + @Override + public boolean isTypeDependent() { + return fDelegate.isTypeDependent(); + } + + @Override + public boolean isValueDependent() { + return fDelegate.isValueDependent(); + } + + @Override + public IType getTypeOrFunctionSet(IASTNode point) { + return fDelegate.getTypeOrFunctionSet(point); + } + + @Override + public IValue getValue(IASTNode point) { + return Value.create(this, point); + } + + @Override + public ValueCategory getValueCategory(IASTNode point) { + return PRVALUE; + } + + @Override + public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException { + 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); + } +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConditional.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConditional.java new file mode 100644 index 00000000000..023e432448f --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConditional.java @@ -0,0 +1,311 @@ +/******************************************************************************* + * Copyright (c) 2012 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 + * + * 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.PRVALUE; +import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.XVALUE; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*; + +import org.eclipse.cdt.core.dom.ast.DOMException; +import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; +import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.ISemanticProblem; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.IValue; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; +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.CPPArithmeticConversion; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.Context; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.UDCMode; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.Rank; +import org.eclipse.core.runtime.CoreException; + +/** + * Performs evaluation of an expression. + */ +public class EvalConditional implements ICPPEvaluation { + 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. + fCondition= arg1; + fPositive= arg2; + fNegative= arg3; + fPositiveThrows= positiveThrows; + fNegativeThrows= negativeThrows; + } + + public ICPPEvaluation getCondition() { + return fCondition; + } + + public ICPPEvaluation getPositive() { + return fPositive; + } + + public ICPPEvaluation getNegative() { + return fNegative; + } + + public boolean isPositiveThrows() { + return fPositiveThrows; + } + + public boolean isNegativeThrows() { + return fNegativeThrows; + } + + @Override + public boolean isInitializerList() { + return false; + } + + @Override + public boolean isFunctionSet() { + return false; + } + + public ICPPFunction getOverload(IASTNode point) { + evaluate(point); + return fOverload; + } + + @Override + public IType getTypeOrFunctionSet(IASTNode point) { + evaluate(point); + return fType; + } + + @Override + 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) { + fType= uqt2; + return; + } + if (uqt3 instanceof ISemanticProblem || uqt3 instanceof ICPPUnknownType) { + fType= uqt3; + return; + } + + final boolean void2= isVoidType(uqt2); + final boolean void3= isVoidType(uqt3); + + // Void types: Either both are void or one is a throw expression. + if (void2 || void3) { + if (fPositiveThrows) { + fType= Conversions.lvalue_to_rvalue(t3, false); + } else if (fNegativeThrows) { + fType= Conversions.lvalue_to_rvalue(t2, false); + } else if (void2 && void3) { + fType= uqt2; + } else { + fType= new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); + } + return; + } + + final ValueCategory vcat2= positive.getValueCategory(point); + final ValueCategory vcat3= fNegative.getValueCategory(point); + + // Same type + if (t2.isSameType(t3)) { + if (vcat2 == vcat3) { + fType= t2; + fValueCategory= vcat2; + } else { + fType= prvalueType(t2); + fValueCategory= PRVALUE; + } + return; + } + + final boolean isClassType2 = uqt2 instanceof ICPPClassType; + final boolean isClassType3 = uqt3 instanceof ICPPClassType; + + // Different types with at least one class type + if (isClassType2 || isClassType3) { + final Cost cost2= convertToMatch(t2, vcat2, uqt2, t3, vcat3, uqt3, point); // sets fType and fValueCategory + final Cost cost3= convertToMatch(t3, vcat3, uqt3, t2, vcat2, uqt2, point); // sets fType and fValueCategory + if (cost2.converts() || cost3.converts()) { + if (cost2.converts()) { + if (cost3.converts() || cost2.isAmbiguousUDC()) { + fType= new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); + } + } else if (cost3.isAmbiguousUDC()) { + fType= new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); + } + return; + } + } else if (vcat2 == vcat3 && vcat2.isGLValue() && uqt2.isSameType(uqt3)) { + // Two lvalues or two xvalues with same type up to qualification. + final CVQualifier cv2 = SemanticUtil.getCVQualifier(t2); + final CVQualifier cv3 = SemanticUtil.getCVQualifier(t3); + if (cv2.isAtLeastAsQualifiedAs(cv3)) { + fType= t2; + fValueCategory= vcat2; + } else if (cv3.isAtLeastAsQualifiedAs(cv2)) { + fType= t3; + fValueCategory= vcat3; + } else { + fType= new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); + } + return; + } + + // 5.16-5: At least one class type but no conversion + if (isClassType2 || isClassType3) { + fOverload = CPPSemantics.findOverloadedConditionalOperator(point, positive, fNegative); + if (fOverload != null) { + fType= ExpressionTypes.typeFromFunctionCall(fOverload); + } else { + fType= new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); + } + return; + } + + // 5.16-6 + t2= Conversions.lvalue_to_rvalue(t2, false); + t3= Conversions.lvalue_to_rvalue(t3, false); + if (t2.isSameType(t3)) { + fType= t2; + } else { + fType= CPPArithmeticConversion.convertCppOperandTypes(IASTBinaryExpression.op_plus, t2, t3); + if (fType == null) { + fType= Conversions.compositePointerType(t2, t3); + if (fType == null) { + fType= new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); + } + } + } + } + + private Cost convertToMatch(IType t1, ValueCategory vcat1, IType uqt1, IType t2, ValueCategory vcat2, IType uqt2, IASTNode point) { + // E2 is an lvalue or E2 is an xvalue + try { + if (vcat2.isGLValue()) { + IType target= new CPPReferenceType(t2, vcat2 == XVALUE); + Cost c= Conversions.checkImplicitConversionSequence(target, t1, vcat1, UDCMode.ALLOWED, Context.REQUIRE_DIRECT_BINDING, point); + if (c.converts()) { + fType= t2; + fValueCategory= vcat2; + return c; + } + } + // Both are class types and one derives from the other + if (uqt1 instanceof ICPPClassType && uqt2 instanceof ICPPClassType) { + int dist= SemanticUtil.calculateInheritanceDepth(uqt1, uqt2); + if (dist >= 0) { + CVQualifier cv1 = SemanticUtil.getCVQualifier(t1); + CVQualifier cv2 = SemanticUtil.getCVQualifier(t2); + if (cv2.isAtLeastAsQualifiedAs(cv1)) { + fType= t2; + fValueCategory= PRVALUE; + return new Cost(t1, t2, Rank.IDENTITY); + } + return Cost.NO_CONVERSION; + } + if (SemanticUtil.calculateInheritanceDepth(uqt2, uqt1) >= 0) + return Cost.NO_CONVERSION; + } + // Unrelated class types or just one class: + if (vcat2 != PRVALUE) { + t2= Conversions.lvalue_to_rvalue(t2, false); + } + Cost c= Conversions.checkImplicitConversionSequence(t2, t1, vcat1, UDCMode.ALLOWED, Context.ORDINARY, point); + if (c.converts()) { + fType= t2; + fValueCategory= PRVALUE; + return c; + } + } catch (DOMException e) { + } + return Cost.NO_CONVERSION; + } + + private boolean isVoidType(IType t) { + return t instanceof ICPPBasicType && ((ICPPBasicType) t).getKind() == ICPPBasicType.Kind.eVoid; + } + + @Override + public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException { + int firstByte = ITypeMarshalBuffer.EVAL_CONDITIONAL; + if (fPositiveThrows) + 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; + ICPPEvaluation cond= (ICPPEvaluation) buffer.unmarshalEvaluation(); + ICPPEvaluation pos= (ICPPEvaluation) buffer.unmarshalEvaluation(); + ICPPEvaluation neg= (ICPPEvaluation) buffer.unmarshalEvaluation(); + return new EvalConditional(cond, pos, neg, pth, nth); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFixed.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFixed.java new file mode 100644 index 00000000000..28d1ba27c61 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFixed.java @@ -0,0 +1,149 @@ +/******************************************************************************* + * Copyright (c) 2012 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 + * + * 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; +import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; +import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.XVALUE; + +import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; +import org.eclipse.cdt.core.dom.ast.IASTNode; +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.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.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); + + private final IType fType; + private final IValue fValue; + private final ValueCategory fValueCategory; + private boolean fIsTypeDependent; + private boolean fCheckedIsTypeDependent; + private boolean fIsValueDependent; + private boolean fCheckedIsValueDependent; + + public EvalFixed(IType type, ValueCategory cat, IValue value) { + fType= type; + fValueCategory= cat; + fValue= value; + } + + public IType getType() { + return fType; + } + + public IValue getValue() { + return fValue; + } + + public ValueCategory getValueCategory() { + return fValueCategory; + } + + @Override + public boolean isInitializerList() { + return false; + } + + @Override + public boolean isFunctionSet() { + return false; + } + + @Override + public boolean isTypeDependent() { + if (!fCheckedIsTypeDependent) { + fCheckedIsTypeDependent= true; + fIsTypeDependent= CPPTemplates.isDependentType(fType); + } + return fIsTypeDependent; + } + + @Override + public boolean isValueDependent() { + if (!fCheckedIsValueDependent) { + fCheckedIsValueDependent= true; + fIsValueDependent= Value.isDependentValue(fValue); + } + return fIsValueDependent; + } + + @Override + public IType getTypeOrFunctionSet(IASTNode point) { + return fType; + } + + @Override + public IValue getValue(IASTNode point) { + return fValue; + } + + @Override + public ValueCategory getValueCategory(IASTNode point) { + return fValueCategory; + } + + @Override + public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException { + includeValue= includeValue && fValue != Value.UNKNOWN; + int firstByte = ITypeMarshalBuffer.EVAL_FIXED; + if (includeValue) + firstByte |= ITypeMarshalBuffer.FLAG1; + switch(fValueCategory) { + case LVALUE: + firstByte |= ITypeMarshalBuffer.FLAG2; + break; + case PRVALUE: + firstByte |= ITypeMarshalBuffer.FLAG3; + break; + 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; + } + + IType type= buffer.unmarshalType(); + value= readValue ? buffer.unmarshalValue() : Value.UNKNOWN; + return new EvalFixed(type, cat, value); + } +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java new file mode 100644 index 00000000000..d0925faec8a --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java @@ -0,0 +1,168 @@ +/******************************************************************************* + * Copyright (c) 2012 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 + * + * Contributors: + * 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; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCategoryFromFunctionCall; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCategoryFromReturnType; +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 org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IFunctionType; +import org.eclipse.cdt.core.dom.ast.IPointerType; +import org.eclipse.cdt.core.dom.ast.ISemanticProblem; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.IValue; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; +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.CPPFunction; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; +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 { + private final ICPPEvaluation[] fArguments; + private ICPPFunction fOverload= CPPFunction.UNINITIALIZED_FUNCTION; + private IType fType; + + public EvalFunctionCall(ICPPEvaluation[] args) { + fArguments= args; + } + + public ICPPEvaluation[] getArguments() { + return fArguments; + } + + @Override + public boolean isInitializerList() { + return false; + } + + @Override + public boolean isFunctionSet() { + return false; + } + + @Override + public boolean isTypeDependent() { + for (ICPPEvaluation arg : fArguments) { + if (arg.isTypeDependent()) + return true; + } + return false; + } + + @Override + public boolean isValueDependent() { + for (ICPPEvaluation arg : fArguments) { + if (arg.isValueDependent()) + return true; + } + return false; + } + + public ICPPFunction getOverload(IASTNode point) { + if (fOverload == CPPFunction.UNINITIALIZED_FUNCTION) { + fOverload= computeOverload(point); + } + return fOverload; + } + + 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) + fType= computeType(point); + return fType; + } + + private IType computeType(IASTNode point) { + if (isTypeDependent()) + return new TypeOfDependentExpression(this); + + ICPPFunction overload = getOverload(point); + if (overload != null) + return ExpressionTypes.typeFromFunctionCall(overload); + + + IType t= SemanticUtil.getNestedType(fArguments[0].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); + } + if (t instanceof IFunctionType) { + return typeFromReturnType(((IFunctionType) t).getReturnType()); + } + return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); + } + + @Override + public IValue getValue(IASTNode point) { + return Value.create(this, point); + } + + @Override + public ValueCategory getValueCategory(IASTNode point) { + ICPPFunction overload = getOverload(point); + 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); + } + if (t instanceof IFunctionType) { + return valueCategoryFromReturnType(((IFunctionType) t).getReturnType()); + } + return ValueCategory.PRVALUE; + } + + @Override + public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException { + buffer.putByte(ITypeMarshalBuffer.EVAL_FUNCTION_CALL); + buffer.putShort((short) fArguments.length); + for (ICPPEvaluation arg : fArguments) { + buffer.marshalEvaluation(arg, includeValue); + } + } + + public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException { + int len= buffer.getShort(); + ICPPEvaluation[] args = new ICPPEvaluation[len]; + for (int i = 0; i < args.length; i++) { + args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation(); + } + return new EvalComma(args); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java new file mode 100644 index 00000000000..4be4f8ac06c --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionSet.java @@ -0,0 +1,128 @@ +/******************************************************************************* + * Copyright (c) 2012 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 + * + * 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.PRVALUE; + +import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.IValue; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; +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 { + private final CPPFunctionSet fFunctionSet; + private final boolean fAddressOf; + + public EvalFunctionSet(CPPFunctionSet set, boolean addressOf) { + fFunctionSet= set; + fAddressOf= addressOf; + } + + public CPPFunctionSet getFunctionSet() { + return fFunctionSet; + } + + public boolean isAddressOf() { + return fAddressOf; + } + + @Override + public boolean isInitializerList() { + return false; + } + + @Override + public boolean isFunctionSet() { + return true; + } + + @Override + public boolean isTypeDependent() { + final ICPPTemplateArgument[] args = fFunctionSet.getTemplateArguments(); + if (args != null) { + for (ICPPTemplateArgument arg : args) { + if (CPPTemplates.isDependentArgument(arg)) + return true; + } + } + for (ICPPFunction f : fFunctionSet.getBindings()) { + if (f instanceof ICPPUnknownBinding) + return true; + } + return false; + } + + @Override + public boolean isValueDependent() { + return false; + } + + @Override + public IType getTypeOrFunctionSet(IASTNode point) { + return new FunctionSetType(fFunctionSet, fAddressOf); + } + + @Override + public IValue getValue(IASTNode point) { + return Value.UNKNOWN; + } + + @Override + public ValueCategory getValueCategory(IASTNode point) { + return PRVALUE; + } + + @Override + public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException { + final ICPPFunction[] bindings = fFunctionSet.getBindings(); + final ICPPTemplateArgument[] args = fFunctionSet.getTemplateArguments(); + int firstByte = ITypeMarshalBuffer.EVAL_FUNCTION_SET; + if (fAddressOf) + firstByte |= ITypeMarshalBuffer.FLAG1; + if (args != null) + firstByte |= ITypeMarshalBuffer.FLAG2; + + buffer.putByte((byte) firstByte); + buffer.putShort((short) bindings.length); + for (ICPPFunction binding : bindings) { + buffer.marshalBinding(binding); + } + if (args != null) { + // mstodo marshall arguments + } + } + + public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException { + final boolean addressOf= (firstByte & ITypeMarshalBuffer.FLAG1) != 0; + int bindingCount= buffer.getShort(); + ICPPFunction[] bindings= new ICPPFunction[bindingCount]; + for (int i = 0; i < bindings.length; i++) { + bindings[i]= (ICPPFunction) buffer.unmarshalBinding(); + } + ICPPTemplateArgument[] args= null; + if ((firstByte & ITypeMarshalBuffer.FLAG2) != 0) { + // mstodo marshall arguments + } + return new EvalFunctionSet(new CPPFunctionSet(bindings, args, null), addressOf); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java new file mode 100644 index 00000000000..3bf54753c7b --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalID.java @@ -0,0 +1,246 @@ +/******************************************************************************* + * Copyright (c) 2012 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 + * + * 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; +import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; + +import org.eclipse.cdt.core.dom.ast.IASTExpression; +import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; +import org.eclipse.cdt.core.dom.ast.IASTIdExpression; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IEnumerator; +import org.eclipse.cdt.core.dom.ast.IFunction; +import org.eclipse.cdt.core.dom.ast.IProblemBinding; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.IValue; +import org.eclipse.cdt.core.dom.ast.IVariable; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter; +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; + +public class EvalID implements ICPPEvaluation { + private final ICPPEvaluation fFieldOwner; + private final char[] fName; + private final IBinding fNameOwner; + private final boolean fAddressOf; + private final boolean fQualified; + private final ICPPTemplateArgument[] fTemplateArgs; + + public EvalID(ICPPEvaluation fieldOwner, IBinding nameOwner, char[] simpleID, boolean addressOf, boolean qualified, ICPPTemplateArgument[] templateArgs) { + fFieldOwner= fieldOwner; + fName= simpleID; + fNameOwner= nameOwner; + fAddressOf= addressOf; + fQualified= qualified; + fTemplateArgs= templateArgs; + } + + public ICPPEvaluation getFieldOwner() { + return fFieldOwner; + } + + public IBinding getNameOwner() { + return fNameOwner; + } + + public char[] getName() { + return fName; + } + + public boolean isAddressOf() { + return fAddressOf; + } + + public boolean isQualified() { + return fQualified; + } + + public ICPPTemplateArgument[] getTemplateArgs() { + return fTemplateArgs; + } + + @Override + public boolean isInitializerList() { + return false; + } + + @Override + public boolean isFunctionSet() { + return false; + } + + @Override + 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; + } + + @Override + public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException { + int firstByte = ITypeMarshalBuffer.EVAL_ID; + if (fAddressOf) + firstByte |= ITypeMarshalBuffer.FLAG1; + if (fQualified) + firstByte |= ITypeMarshalBuffer.FLAG2; + if (fTemplateArgs != null) + firstByte |= ITypeMarshalBuffer.FLAG3; + + buffer.putByte((byte) firstByte); + buffer.marshalEvaluation(fFieldOwner, false); + buffer.putCharArray(fName); + buffer.marshalBinding(fNameOwner); + if (fTemplateArgs != null) { + // 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; + ICPPEvaluation fieldOwner= (ICPPEvaluation) buffer.unmarshalEvaluation(); + char[] name= buffer.getCharArray(); + IBinding nameOwner= buffer.unmarshalBinding(); + ICPPTemplateArgument[] args= null; + if ((firstByte & ITypeMarshalBuffer.FLAG3) != 0) { + // mstodo marshall arguments + } + return new EvalID(fieldOwner, nameOwner, name, addressOf, qualified, args); + } + + 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) + return EvalFixed.INCOMPLETE; + if (binding instanceof CPPFunctionSet) { + return new EvalFunctionSet((CPPFunctionSet) binding, isAddressOf(expr)); + } + if (binding instanceof ICPPUnknownBinding) { + IBinding owner = binding.getOwner(); + if (owner instanceof IProblemBinding) + return EvalFixed.INCOMPLETE; + + ICPPEvaluation fieldOwner= null; + IType fieldOwnerType= withinNonStaticMethod(expr); + if (fieldOwnerType != null) { + fieldOwner= new EvalFixed(fieldOwnerType, ValueCategory.LVALUE, Value.UNKNOWN); + } + ICPPTemplateArgument[] templateArgs = null; + final IASTName lastName = name.getLastName(); + if (lastName instanceof ICPPASTTemplateId) { + templateArgs= CPPTemplates.createTemplateArgumentArray((ICPPASTTemplateId) lastName); + } + 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. + */ + 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) { + ICPPEnumeration enumType= (ICPPEnumeration) type; + if (enumType.asScope() == CPPVisitor.getContainingScope(expr)) { + // C++0x: 7.2-5 + type= enumType.getFixedType(); + if (type == null) { + // This is a simplification, the actual type is determined + // - in an implementation dependent manner - by the value + // of the enumerator. + type= CPPSemantics.INT_TYPE; + } + return new EvalBinding(binding, type); + } + } + return new EvalBinding(binding, null); + } + if (binding instanceof ICPPTemplateNonTypeParameter || binding instanceof IVariable + || binding instanceof IFunction) { + return new EvalBinding(binding, null); + } + return EvalFixed.INCOMPLETE; + } + + private static IType withinNonStaticMethod(IASTExpression expr) { + IASTNode parent= expr.getParent(); + while (parent != null && !(parent instanceof ICPPASTFunctionDefinition)) { + parent= parent.getParent(); + } + if (parent instanceof ICPPASTFunctionDefinition) { + ICPPASTFunctionDefinition fdef= (ICPPASTFunctionDefinition) parent; + final IBinding methodBinding = fdef.getDeclarator().getName().resolvePreBinding(); + if (methodBinding instanceof ICPPMethod && !((ICPPMethod) methodBinding).isStatic()) { + IScope scope = CPPVisitor.getContainingScope(expr); + return CPPVisitor.getImpliedObjectType(scope); + } + } + return null; + } + + private static boolean isAddressOf(IASTIdExpression expr) { + IASTNode e = expr.getParent(); + while (e instanceof IASTUnaryExpression) { + final IASTUnaryExpression unary = (IASTUnaryExpression) e; + final int op= unary.getOperator(); + if (op == IASTUnaryExpression.op_bracketedPrimary) { + e= unary.getOperand(); + } else { + return op == IASTUnaryExpression.op_amper; + } + } + return false; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalInitList.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalInitList.java new file mode 100644 index 00000000000..408f9cfac5f --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalInitList.java @@ -0,0 +1,100 @@ +/******************************************************************************* + * Copyright (c) 2012 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 + * + * 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.PRVALUE; + +import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; +import org.eclipse.cdt.core.dom.ast.IASTNode; +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.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; + +/** + * Performs evaluation of an expression. + */ +public class EvalInitList implements ICPPEvaluation { + private final ICPPEvaluation[] fClauses; + + public EvalInitList(ICPPEvaluation[] clauses) { + fClauses= clauses; + } + + public ICPPEvaluation[] getClauses() { + return fClauses; + } + + @Override + public boolean isInitializerList() { + return true; + } + + @Override + public boolean isFunctionSet() { + return false; + } + + @Override + public boolean isTypeDependent() { + for (ICPPEvaluation clause : fClauses) { + if (clause.isTypeDependent()) + return true; + } + return false; + } + + @Override + public boolean isValueDependent() { + for (ICPPEvaluation clause : fClauses) { + if (clause.isValueDependent()) + return true; + } + return false; + } + + @Override + public IType getTypeOrFunctionSet(IASTNode point) { + return new InitializerListType(this); + } + + @Override + public IValue getValue(IASTNode point) { + return Value.create(this, point); + } + + @Override + public ValueCategory getValueCategory(IASTNode point) { + return PRVALUE; + } + + @Override + public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException { + buffer.putByte(ITypeMarshalBuffer.EVAL_INIT_LIST); + buffer.putShort((short) fClauses.length); + for (ICPPEvaluation arg : fClauses) { + buffer.marshalEvaluation(arg, includeValue); + } + } + + public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException { + int len= buffer.getShort(); + ICPPEvaluation[] args = new ICPPEvaluation[len]; + for (int i = 0; i < args.length; i++) { + args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation(); + } + return new EvalComma(args); + } +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalMemberAccess.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalMemberAccess.java new file mode 100644 index 00000000000..d3ea8f9a23c --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalMemberAccess.java @@ -0,0 +1,307 @@ +/******************************************************************************* + * Copyright (c) 2012 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 + * + * 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; +import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; +import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.XVALUE; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromFunctionCall; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*; + +import java.util.Collection; + +import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.IEnumerator; +import org.eclipse.cdt.core.dom.ast.IFunction; +import org.eclipse.cdt.core.dom.ast.IPointerType; +import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.ISemanticProblem; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.IValue; +import org.eclipse.cdt.core.dom.ast.IVariable; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; +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.CPPUnknownClass; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalUnknownScope; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType; +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 { + private final IType fOwnerType; + private final IBinding fMember; + private final ValueCategory fOwnerValueCategory; + private final boolean fIsPointerDeref; + + private IType fType; + private boolean fIsTypeDependent; + private boolean fCheckedIsTypeDependent; + private boolean fIsValueDependent; + private boolean fCheckedIsValueDependent; + + public EvalMemberAccess(IType ownerType, ValueCategory ownerValueCat, IBinding member, + boolean isPointerDeref) { + fOwnerType= ownerType; + fOwnerValueCategory= ownerValueCat; + fMember= member; + fIsPointerDeref= isPointerDeref; + } + + public IType getOwnerType() { + return fOwnerType; + } + + public ValueCategory getOwnerValueCategory() { + return fOwnerValueCategory; + } + + public IBinding getMember() { + return fMember; + } + + public boolean isPointerDeref() { + return fIsPointerDeref; + } + + @Override + public boolean isInitializerList() { + return false; + } + + @Override + public boolean isFunctionSet() { + return false; + } + + @Override + public boolean isTypeDependent() { + if (!fCheckedIsTypeDependent) { + fCheckedIsTypeDependent= true; + fIsTypeDependent= computeIsTypeDependent(); + } + return fIsTypeDependent; + } + + private boolean computeIsTypeDependent() { + IType t; + if (fMember instanceof ICPPUnknownBinding) { + return true; + } else if (fMember instanceof IEnumerator) { + t= ((IEnumerator) fMember).getType(); + } else if (fMember instanceof IVariable) { + t = ((IVariable) fMember).getType(); + } else if (fMember instanceof IFunction) { + t= ((IFunction) fMember).getType(); + } else { + return false; + } + return CPPTemplates.isDependentType(t); + } + + @Override + public boolean isValueDependent() { + if (!fCheckedIsValueDependent) { + fCheckedIsValueDependent= true; + fIsValueDependent= computeIsValueDependent(); + } + 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 functionBindings, + boolean returnUnnamed) { + IType type= fieldOwnerExpressionType; + if (!isDeref) + return type; + + // 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)) + 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) + break; + + if (functionBindings != null) + functionBindings.add(op); + + type= typeFromFunctionCall(op); + type= SemanticUtil.mapToAST(type, point); + } + + IType prValue= prvalueType(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) { + fType= computeType(point); + } + 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); + if (e2 instanceof ICPPUnknownType) + return new TypeOfDependentExpression(this); + if (e2 instanceof ICPPReferenceType) { + e2= glvalueType(e2); + } else if (fMember instanceof ICPPField && !((ICPPField) fMember).isStatic()) { + e2 = addQualifiersForAccess((ICPPField) fMember, e2, fOwnerType); + if (!fIsPointerDeref && fOwnerValueCategory == PRVALUE) { + e2= prvalueType(e2); + } 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); + if (field.isMutable()) { + // Remove const, add union of volatile. + if (cvq2.isConst()) { + fieldType= SemanticUtil.getNestedType(fieldType, ALLCVQ | TDEF | REF); + } + fieldType= SemanticUtil.addQualifiers(fieldType, false, cvq1.isVolatile() || cvq2.isVolatile(), cvq2.isRestrict()); + } else { + fieldType= SemanticUtil.addQualifiers(fieldType, cvq1.isConst(), cvq1.isVolatile(), cvq2.isRestrict()); + } + return fieldType; + } + + @Override + public IValue getValue(IASTNode point) { + return Value.create(this, point); + } + + @Override + public ValueCategory getValueCategory(IASTNode point) { + if (fMember instanceof IVariable) { + IType e2= ((IVariable) fMember).getType(); + e2= SemanticUtil.getNestedType(e2, TDEF); + if (e2 instanceof ICPPReferenceType) { + return LVALUE; + } + if (fMember instanceof ICPPField && !((ICPPField) fMember).isStatic()) { + if (fIsPointerDeref) + return LVALUE; + + return fOwnerValueCategory; + } + return LVALUE; + } + if (fMember instanceof IFunction) { + return LVALUE; + } + return PRVALUE; + } + + @Override + public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException { + int firstByte = ITypeMarshalBuffer.EVAL_MEMBER_ACCESS; + if (fIsPointerDeref) + firstByte |= ITypeMarshalBuffer.FLAG1; + if (fOwnerValueCategory == LVALUE) { + firstByte |= ITypeMarshalBuffer.FLAG2; + } 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; + if ((firstByte & ITypeMarshalBuffer.FLAG2) != 0) { + ownerValueCat= LVALUE; + } else if ((firstByte & ITypeMarshalBuffer.FLAG3) != 0) { + ownerValueCat= XVALUE; + } else { + ownerValueCat= PRVALUE; + } + + IType ownerType= buffer.unmarshalType(); + IBinding member= buffer.unmarshalBinding(); + return new EvalMemberAccess(ownerType, ownerValueCat, member, isDeref); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java new file mode 100644 index 00000000000..d788d3204a3 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalTypeId.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright (c) 2012 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 + * + * Contributors: + * 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; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCategoryFromReturnType; + +import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; +import org.eclipse.cdt.core.dom.ast.IASTNode; +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.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; + +/** + * Performs evaluation of an expression. + */ +public class EvalTypeId implements ICPPEvaluation { + private final IType fInputType; + private final ICPPEvaluation[] fArguments; + private IType fOutputType; + + public EvalTypeId(IType type, ICPPEvaluation... argument) { + fInputType= type; + fArguments= argument; + } + + public IType getInputType() { + return fInputType; + } + + public ICPPEvaluation[] getArguments() { + return fArguments; + } + + @Override + public boolean isInitializerList() { + return false; + } + + @Override + public boolean isFunctionSet() { + return false; + } + + @Override + public IType getTypeOrFunctionSet(IASTNode point) { + if (fOutputType == null) { + fOutputType= computeType(); + } + return fOutputType; + } + + private IType computeType() { + if (CPPTemplates.isDependentType(fInputType)) + return new TypeOfDependentExpression(this); + return typeFromReturnType(fInputType); + } + + @Override + public IValue getValue(IASTNode point) { + return Value.create(this, point); + } + + @Override + public boolean isTypeDependent() { + if (fOutputType == null) { + fOutputType= computeType(); + } + return fOutputType instanceof TypeOfDependentExpression; + } + + @Override + public boolean isValueDependent() { + if (fArguments == null) + return false; + for (ICPPEvaluation arg : fArguments) { + if (arg.isValueDependent()) + return true; + } + return false; + } + + @Override + public ValueCategory getValueCategory(IASTNode point) { + return valueCategoryFromReturnType(fInputType); + } + + @Override + public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException { + int firstByte = ITypeMarshalBuffer.EVAL_TYPE_ID; + if (includeValue) + firstByte |= ITypeMarshalBuffer.FLAG1; + + buffer.putByte((byte) firstByte); + buffer.marshalType(fInputType); + if (includeValue) { + buffer.putShort((short) fArguments.length); + for (ICPPEvaluation arg : fArguments) { + buffer.marshalEvaluation(arg, includeValue); + } + } + } + + public static ISerializableEvaluation unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException { + IType type= buffer.unmarshalType(); + ICPPEvaluation[] args= null; + if ((firstByte & ITypeMarshalBuffer.FLAG1) != 0) { + int len= buffer.getShort(); + args = new ICPPEvaluation[len]; + for (int i = 0; i < args.length; i++) { + args[i]= (ICPPEvaluation) buffer.unmarshalEvaluation(); + } + } + return new EvalTypeId(type, args); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java new file mode 100644 index 00000000000..578dcbfe230 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java @@ -0,0 +1,222 @@ +/******************************************************************************* + * Copyright (c) 2012 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 + * + * 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; +import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; +import static org.eclipse.cdt.core.dom.ast.IASTUnaryExpression.*; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType; +import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCategoryFromFunctionCall; +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 org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; +import org.eclipse.cdt.core.dom.ast.IPointerType; +import org.eclipse.cdt.core.dom.ast.ISemanticProblem; +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.IValue; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; +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.CPPArithmeticConversion; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; +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 { + 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; + } + + public int getOperator() { + return fOperator; + } + + public ICPPEvaluation getArgument() { + return fArgument; + } + + @Override + public boolean isInitializerList() { + return false; + } + + @Override + public boolean isFunctionSet() { + return false; + } + + @Override + public boolean isTypeDependent() { + if (fType != null) + return fType instanceof TypeOfDependentExpression; + + switch(fOperator) { + case op_alignOf: + case op_not: + case op_sizeof: + case op_sizeofParameterPack: + case op_throw: + case op_typeid: + return false; + default: + return fArgument.isTypeDependent(); + } + } + + @Override + public boolean isValueDependent() { + switch(fOperator) { + case op_alignOf: + case op_sizeof: + case op_sizeofParameterPack: + case op_typeid: + return fArgument.isTypeDependent(); + case op_throw: + return false; + default: + return fArgument.isValueDependent(); + } + } + + public ICPPFunction getOverload(IASTNode point) { + if (fOverload == CPPFunction.UNINITIALIZED_FUNCTION) { + fOverload= computeOverload(point); + } + return fOverload; + } + + private ICPPFunction computeOverload(IASTNode point) { + 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)) + return null; + + ICPPEvaluation[] args; + if (fOperator == IASTUnaryExpression.op_postFixDecr || fOperator == IASTUnaryExpression.op_postFixIncr) { + args = new ICPPEvaluation[] { fArgument, ZERO_EVAL }; + } else { + args = new ICPPEvaluation[] { fArgument }; + } + return CPPSemantics.findOverloadedOperator(point, args, type, op, LookupMode.LIMITED_GLOBALS); + } + + @Override + public IType getTypeOrFunctionSet(IASTNode point) { + if (fType == null) + fType= computeType(point); + return fType; + } + + private IType computeType(IASTNode point) { + if (isTypeDependent()) + return new TypeOfDependentExpression(this); + + ICPPFunction overload = getOverload(point); + if (overload != null) + return ExpressionTypes.typeFromFunctionCall(overload); + + switch (fOperator) { + case op_sizeof: + case op_sizeofParameterPack: + return CPPVisitor.get_SIZE_T(point); + case op_typeid: + return CPPVisitor.get_type_info(point); + case op_throw: + return CPPSemantics.VOID_TYPE; + case op_amper: + return new CPPPointerType(fArgument.getTypeOrFunctionSet(point)); + case op_star: + IType type= fArgument.getTypeOrFunctionSet(point); + type = prvalueType(type); + if (type instanceof IPointerType) { + return glvalueType(((IPointerType) type).getType()); + } + if (type instanceof ISemanticProblem) { + return type; + } + return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION); + case op_not: + return CPPBasicType.BOOLEAN; + case op_postFixDecr: + case op_postFixIncr: + return prvalueType(fArgument.getTypeOrFunctionSet(point)); + case op_minus: + case op_plus: + case op_tilde: + final IType t1 = prvalueType(fArgument.getTypeOrFunctionSet(point)); + final IType t2= CPPArithmeticConversion.promoteCppType(t1); + return t2 != null ? t2 : t1; + } + return fArgument.getTypeOrFunctionSet(point); + } + + @Override + public IValue getValue(IASTNode point) { + return Value.create(this, point); + } + + @Override + public ValueCategory getValueCategory(IASTNode point) { + ICPPFunction overload = getOverload(point); + if (overload != null) + return valueCategoryFromFunctionCall(overload); + + switch (fOperator) { + case op_typeid: + case op_star: + case op_prefixDecr: + case op_prefixIncr: + return LVALUE; + default: + return PRVALUE; + } + } + + @Override + public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException { + buffer.putByte(ITypeMarshalBuffer.EVAL_UNARY); + 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(); + return new EvalUnary(op, arg); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java new file mode 100644 index 00000000000..7c2ad77d1ad --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnaryTypeID.java @@ -0,0 +1,152 @@ +/******************************************************************************* + * Copyright (c) 2012 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 + * + * 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; +import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; +import static org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression.*; + +import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; +import org.eclipse.cdt.core.dom.ast.IASTNode; +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.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 { + private final int fOperator; + private final IType fOrigType; + private IType fType; + + public EvalUnaryTypeID(int operator, IType type) { + fOperator= operator; + fOrigType= type; + } + + public int getOperator() { + return fOperator; + } + + public IType getArgument() { + return fOrigType; + } + + @Override + public boolean isInitializerList() { + return false; + } + + @Override + public boolean isFunctionSet() { + return false; + } + + @Override + public boolean isTypeDependent() { + if (fOperator == op_typeof) + return CPPTemplates.isDependentType(fOrigType); + return false; + } + + @Override + public boolean isValueDependent() { + switch (fOperator) { + case op_sizeof: + case op_alignof: + case op_has_nothrow_copy: + case op_has_nothrow_constructor: + case op_has_trivial_assign: + case op_has_trivial_constructor: + case op_has_trivial_copy: + case op_has_trivial_destructor: + case op_has_virtual_destructor: + case op_is_abstract: + case op_is_class: + case op_is_empty: + case op_is_enum: + case op_is_pod: + case op_is_polymorphic: + case op_is_union: + return CPPTemplates.isDependentType(fOrigType); + + case op_typeid: + case op_typeof: + return false; + } + return false; + } + + @Override + public IType getTypeOrFunctionSet(IASTNode point) { + if (fType == null) + fType= computeType(point); + return fType; + } + + private IType computeType(IASTNode point) { + switch (fOperator) { + case op_sizeof: + case op_alignof: + return CPPVisitor.get_SIZE_T(point); + case op_typeid: + return CPPVisitor.get_type_info(point); + case op_has_nothrow_copy: + case op_has_nothrow_constructor: + case op_has_trivial_assign: + case op_has_trivial_constructor: + case op_has_trivial_copy: + case op_has_trivial_destructor: + case op_has_virtual_destructor: + case op_is_abstract: + case op_is_class: + case op_is_empty: + case op_is_enum: + case op_is_pod: + case op_is_polymorphic: + case op_is_union: + return CPPBasicType.BOOLEAN; + case op_typeof: + if (isTypeDependent()) + return new TypeOfDependentExpression(this); + return fOrigType; + } + return ProblemType.UNKNOWN_FOR_EXPRESSION; + } + + @Override + public IValue getValue(IASTNode point) { + return Value.create(this, point); + } + + @Override + public ValueCategory getValueCategory(IASTNode point) { + return fOperator == op_typeid ? LVALUE : PRVALUE; + } + + @Override + public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException { + buffer.putByte(ITypeMarshalBuffer.EVAL_UNARY_TYPE_ID); + 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(); + return new EvalUnaryTypeID(op, arg); + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/ExpressionTypes.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/ExpressionTypes.java index 56480dbc3aa..a4e0443e607 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/ExpressionTypes.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/ExpressionTypes.java @@ -11,17 +11,9 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; -import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.COND_TDEF; -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.*; -import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; -import org.eclipse.cdt.core.dom.ast.IASTIdExpression; -import org.eclipse.cdt.core.dom.ast.IASTName; -import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; -import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; @@ -78,48 +70,7 @@ public class ExpressionTypes { } return prvalueType(type); } - - public static IType typeOrFunctionSet(IASTExpression exp) { - FunctionSetType fs= getFunctionSetType(exp); - if (fs != null) { - return fs; - } - return exp.getExpressionType(); - } - public static ValueCategory valueCat(IASTExpression exp) { - FunctionSetType fs= getFunctionSetType(exp); - if (fs != null) - return fs.getValueCategory(); - return exp.getValueCategory(); - } - - private static FunctionSetType getFunctionSetType(IASTExpression exp) { - boolean addressOf= false; - while (exp instanceof IASTUnaryExpression) { - final IASTUnaryExpression unary = (IASTUnaryExpression) exp; - final int op= unary.getOperator(); - if (op == IASTUnaryExpression.op_bracketedPrimary) { - exp= unary.getOperand(); - } else if (!addressOf && op == IASTUnaryExpression.op_amper) { - addressOf= true; - exp= unary.getOperand(); - } else { - break; - } - } - - if (exp instanceof IASTIdExpression) { - IASTIdExpression idexpr= (IASTIdExpression) exp; - final IASTName name = idexpr.getName(); - IBinding b= name.resolvePreBinding(); - if (b instanceof CPPFunctionSet) { - return new FunctionSetType(((CPPFunctionSet) b).getBindings(), name, addressOf); - } - } - return null; - } - public static IType restoreTypedefs(IType type, IType originalType) { IType t = SemanticUtil.substituteTypedef(type, originalType); if (t != null) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/FunctionCost.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/FunctionCost.java index b7e933cf1a3..4c95cf732cd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/FunctionCost.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/FunctionCost.java @@ -16,6 +16,7 @@ import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUti import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; +import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IFunction; @@ -85,7 +86,7 @@ class FunctionCost { return false; } - public boolean performUDC() throws DOMException { + public boolean performUDC(IASTNode point) throws DOMException { for (int i = 0; i < fCosts.length; i++) { Cost cost = fCosts[i]; Cost udcCost= null; @@ -94,20 +95,20 @@ class FunctionCost { continue; case COPY_INIT_OF_CLASS: udcCost = Conversions.copyInitializationOfClass(fValueCategories[i], cost.source, - (ICPPClassType) cost.target, false); + (ICPPClassType) cost.target, false, point); break; case INIT_BY_CONVERSION: IType uqSource= getNestedType(cost.source, TDEF | REF | CVTYPE); udcCost = Conversions.initializationByConversion(fValueCategories[i], cost.source, - (ICPPClassType) uqSource, cost.target, false); + (ICPPClassType) uqSource, cost.target, false, point); break; case LIST_INIT_OF_CLASS: - udcCost = Conversions.listInitializationOfClass((InitializerListType) cost.source, - (ICPPClassType) cost.target, false, false); + udcCost = Conversions.listInitializationOfClass(((InitializerListType) cost.source).getEvaluation(), + (ICPPClassType) cost.target, false, false, point); break; case DIRECT_LIST_INIT_OF_CLASS: - udcCost = Conversions.listInitializationOfClass((InitializerListType) cost.source, - (ICPPClassType) cost.target, true, false); + udcCost = Conversions.listInitializationOfClass(((InitializerListType) cost.source).getEvaluation(), + (ICPPClassType) cost.target, true, false, point); break; default: return false; @@ -123,8 +124,9 @@ class FunctionCost { /** * Compares this function call cost to another one. + * @param point */ - public int compareTo(IASTTranslationUnit tu, FunctionCost other) throws DOMException { + public int compareTo(IASTTranslationUnit tu, FunctionCost other, IASTNode point) throws DOMException { if (other == null) return -1; @@ -164,7 +166,7 @@ class FunctionCost { haveBetter = true; } else if (isTemplate && otherIsTemplate) { TypeSelection ts= SemanticUtil.isConversionOperator(f1) ? RETURN_TYPE : PARAMETERS; - int order = CPPTemplates.orderFunctionTemplates(otherAsTemplate, asTemplate, ts); + int order = CPPTemplates.orderFunctionTemplates(otherAsTemplate, asTemplate, ts, point); if (order < 0) { haveBetter= true; } else if (order > 0) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/FunctionSetType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/FunctionSetType.java index 29f411715c5..91a406cd7b7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/FunctionSetType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/FunctionSetType.java @@ -11,12 +11,11 @@ import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; -import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; -import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownFunction; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.Rank; /** @@ -24,19 +23,17 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.Rank; */ public class FunctionSetType implements IType { - private ICPPFunction[] fFunctionSet; - private boolean fPointerType; - private IASTName fName; + private final CPPFunctionSet fFunctionSet; + private final boolean fPointerType; - public FunctionSetType(ICPPFunction[] functions, IASTName name, boolean addressOf) { - fName= name; - fFunctionSet= functions; + public FunctionSetType(CPPFunctionSet set, boolean addressOf) { + fFunctionSet= set; fPointerType= addressOf; } @Override public boolean isSameType(IType type) { - return type == this; + return type instanceof FunctionSetType && fFunctionSet == ((FunctionSetType) type).fFunctionSet; } @Override @@ -48,8 +45,8 @@ public class FunctionSetType implements IType { return fPointerType ? PRVALUE : LVALUE; } - public Cost costForTarget(IType paramType) { - IBinding result = CPPSemantics.resolveTargetedFunction(paramType, fName, fFunctionSet); + public Cost costForTarget(IType paramType, IASTNode point) { + IBinding result = CPPSemantics.resolveTargetedFunction(paramType, fFunctionSet, point); if (result instanceof ICPPFunction && !(result instanceof IProblemBinding)) { Cost c= new Cost(paramType, paramType, Rank.IDENTITY); c.setSelectedFunction((ICPPFunction) result); @@ -59,16 +56,14 @@ public class FunctionSetType implements IType { } public void applySelectedFunction(ICPPFunction selectedFunction) { - if (selectedFunction != null) { - fName.setBinding(selectedFunction); - } + fFunctionSet.applySelectedFunction(selectedFunction); } - public ICPPFunction[] getFunctionSet() { + public CPPFunctionSet getFunctionSet() { return fFunctionSet; } public void setToUnknown() { - fName.setBinding(new CPPUnknownFunction(null, fName.toCharArray())); + fFunctionSet.setToUnknown(); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/InitializerListType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/InitializerListType.java index 8cb763dc3ff..74850ce7280 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/InitializerListType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/InitializerListType.java @@ -10,25 +10,22 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; -import org.eclipse.cdt.core.dom.ast.IASTExpression; -import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; -import org.eclipse.cdt.core.dom.ast.IASTInitializerClause; import org.eclipse.cdt.core.dom.ast.IType; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList; /** * Wrapper for initializer lists to allow for participation in the overload resolution. */ class InitializerListType implements IType { + private final EvalInitList fInitializerList; - private final ICPPASTInitializerList fInitializerList; - private IType[] fExpressionTypes; - private ValueCategory[] fLValues; - - public InitializerListType(ICPPASTInitializerList list) { - fInitializerList= list; + public InitializerListType(EvalInitList exprEvalInitList) { + fInitializerList= exprEvalInitList; } + public EvalInitList getEvaluation() { + return fInitializerList; + } + @Override public boolean isSameType(IType type) { return false; @@ -43,40 +40,4 @@ class InitializerListType implements IType { return null; } } - - public ICPPASTInitializerList getInitializerList() { - return fInitializerList; - } - - public IType[] getExpressionTypes() { - if (fExpressionTypes == null) { - final IASTInitializerClause[] clauses = fInitializerList.getClauses(); - fExpressionTypes= new IType[clauses.length]; - for (int i = 0; i < clauses.length; i++) { - IASTInitializerClause clause = clauses[i]; - if (clause instanceof IASTExpression) { - fExpressionTypes[i]= ((IASTExpression) clause).getExpressionType(); - } else if (clause instanceof ICPPASTInitializerList) { - fExpressionTypes[i]= new InitializerListType((ICPPASTInitializerList) clause); - } else { - assert false; - } - } - } - return fExpressionTypes; - } - - public ValueCategory[] getValueCategories() { - if (fLValues == null) { - final IASTInitializerClause[] clauses = fInitializerList.getClauses(); - fLValues= new ValueCategory[clauses.length]; - for (int i = 0; i < clauses.length; i++) { - IASTInitializerClause clause = clauses[i]; - if (clause instanceof IASTExpression) { - fLValues[i]= ((IASTExpression) clause).getValueCategory(); - } - } - } - return fLValues; - } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java index 90bbd338099..88ce838a268 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java @@ -26,7 +26,6 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTEqualsInitializer; -import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; import org.eclipse.cdt.core.dom.ast.IASTFieldReference; import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; @@ -41,6 +40,7 @@ import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IScope; +import org.eclipse.cdt.core.dom.ast.IScope.ScopeLookupData; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.c.ICASTFieldDesignator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; @@ -50,9 +50,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPackExpansionExpression; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerClause; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; @@ -63,117 +61,129 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.CharArrayObjectMap; -import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.ObjectSet; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTranslationUnit; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPCompositeBinding; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; /** * Context data for IASTName lookup */ -public class LookupData { - protected IASTName astName; - protected CPPASTTranslationUnit tu; +public class LookupData extends ScopeLookupData { + final public ICPPTemplateArgument[] fTemplateArguments; public Map> usingDirectives= Collections.emptyMap(); /** Used to ensure we don't visit things more than once. */ public ObjectSet visited= new ObjectSet(1); - public boolean checkWholeClassScope = false; - public boolean ignoreUsingDirectives = false; - public boolean usingDirectivesOnly = false; - public boolean forceQualified = false; - public boolean forAssociatedScopes = false; public boolean contentAssist = false; - public boolean prefixLookup = false; + public boolean typesOnly = false; - /** For lookup of unknown bindings the point of declaration can be reversed. */ - public boolean checkPointOfDecl= true; - /** For field references or qualified names, enclosing template declarations are ignored. */ - public boolean usesEnclosingScope= true; + public boolean usingDirectivesOnly = false; + public boolean ignoreUsingDirectives = false; + public boolean ignoreMembers = false; + + public boolean qualified = false; + public boolean checkAssociatedScopes= false; + + public boolean forAssociatedScopes = false; + public boolean forUsingDeclaration = false; + /** When computing the cost of a method call, treat the first argument as the implied object. */ public boolean argsContainImpliedObject = false; - public boolean ignoreMembers = false; /** In list-initialization **/ public boolean fNoNarrowing= false; - private IASTInitializerClause[] functionArgs; + private IASTDeclarator fDeclarator; + private boolean fFunctionCall; + private IType fImpliedObjectType; + private ICPPEvaluation[] functionArgs; private IType[] functionArgTypes; private ValueCategory[] functionArgValueCategories; public ICPPClassType skippedScope; public Object foundItems = null; public ProblemBinding problem; - - public LookupData(IASTName n) { - astName = n; - tu= (CPPASTTranslationUnit) astName.getTranslationUnit(); - typesOnly = typesOnly(astName); - checkWholeClassScope = checkWholeClassScope(n); - } - - public LookupData() { - astName = null; - } - - public final char[] getNameCharArray() { - if (astName != null) - return astName.toCharArray(); - return CharArrayUtils.EMPTY; - } - - public boolean includeBlockItem(IASTNode item) { - if (astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return true; - if ((astName != null && astName.getParent() instanceof IASTIdExpression) || - item instanceof ICPPASTNamespaceDefinition || - (item instanceof IASTSimpleDeclaration && ((IASTSimpleDeclaration) item).getDeclSpecifier() instanceof IASTCompositeTypeSpecifier) || - item instanceof ICPPASTTemplateDeclaration) { - return true; - } - return false; - } - - static boolean typesOnly(IASTName name) { - if (name == null) return false; - if (name.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return false; - IASTNode parent = name.getParent(); - if (parent instanceof ICPPASTBaseSpecifier || parent instanceof ICPPASTElaboratedTypeSpecifier || - parent instanceof ICPPASTCompositeTypeSpecifier) - return true; - if (parent instanceof ICPPASTQualifiedName) { - IASTName[] ns = ((ICPPASTQualifiedName) parent).getNames(); - return (name != ns[ns.length -1]); - } - return false; - } - - public boolean forUsingDeclaration() { - if (astName == null) return false; - if (astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return false; - IASTNode p1 = astName.getParent(); - if (p1 instanceof ICPPASTUsingDeclaration) - return true; - if (p1 instanceof ICPPASTQualifiedName) { - IASTNode p2 = p1.getParent(); - if (p2 instanceof ICPPASTUsingDeclaration) { - IASTName[] ns = ((ICPPASTQualifiedName) p1).getNames(); - return (ns[ns.length - 1] == astName); - } + public LookupData(IASTName n) { + super(n, true, false); + if (n == null) + throw new IllegalArgumentException(); + + if (n instanceof ICPPASTTemplateId) { + fTemplateArguments= CPPTemplates.createTemplateArgumentArray((ICPPASTTemplateId) n); + } else { + fTemplateArguments= null; + } + configureWith(n); + } + + public LookupData(char[] name, ICPPTemplateArgument[] templateArgs, IASTNode lookupPoint) { + super(name, lookupPoint); + fTemplateArguments= templateArgs; + } + + @Override + public CPPASTTranslationUnit getTranslationUnit() { + return (CPPASTTranslationUnit) super.getTranslationUnit(); + } + + private void configureWith(final IASTName name) { + IASTName tn= name; + if (tn.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME) { + tn= (IASTName) tn.getParent(); + } + + IASTNode parent = tn.getParent(); + IASTNode nameParent= parent; + if (parent instanceof ICPPASTBaseSpecifier + || parent instanceof ICPPASTElaboratedTypeSpecifier + || parent instanceof ICPPASTCompositeTypeSpecifier) { + typesOnly= true; + } else if (parent instanceof ICPPASTQualifiedName) { + final ICPPASTQualifiedName qn = (ICPPASTQualifiedName) parent; + if (qn.getLastName() != tn) { + // For resolving template id ambiguities we need to consider non-types. + if (!(tn instanceof ICPPASTTemplateId)) { + typesOnly= true; + } + } else { + nameParent= parent.getParent(); + } + final IASTName[] names = qn.getNames(); + if (qn.isFullyQualified()) { + qualified= true; + } else if (names.length > 0) { + if (names[0] != tn) { + qualified= true; + } + } + } + + if (nameParent instanceof ICPPASTUsingDeclaration) { + forUsingDeclaration= true; + } else if (nameParent instanceof IASTDeclarator) { + fDeclarator= (IASTDeclarator) nameParent; + } else if (nameParent instanceof IASTFieldReference) { + qualified= true; + } else if (nameParent instanceof IASTIdExpression) { + if (nameParent.getPropertyInParent() == IASTFunctionCallExpression.FUNCTION_NAME) { + fFunctionCall= true; + } } - return false; } /** * Returns whether the name belongs to a simple declaration or function definition. */ public IASTDeclaration forDeclaration() { - IASTNode node = getDeclarator(); - + IASTNode node = fDeclarator; while (node instanceof IASTDeclarator) node= node.getParent(); @@ -184,30 +194,16 @@ public class LookupData { } public IASTDeclarator getDeclarator() { - IASTName name= astName; - if (name == null || name.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) - return null; - - if (name.getParent() instanceof ICPPASTTemplateId) - name= (IASTName) name.getParent(); - - IASTNode node= name.getParent(); - if (node instanceof ICPPASTQualifiedName) { - if (((ICPPASTQualifiedName) node).getLastName() != name) - return null; - node = node.getParent(); - } - - if (node instanceof IASTDeclarator) - return (IASTDeclarator) node; - - return null; + return fDeclarator; } public boolean forExplicitFunctionSpecialization() { + IASTName n = getLookupName(); + if (n == null) + return false; + IASTDeclaration decl= forDeclaration(); if (decl != null) { - IASTName n = astName; if (n.getParent() instanceof ICPPASTTemplateId) n = (IASTName) n.getParent(); @@ -222,43 +218,12 @@ public class LookupData { return decl != null && decl.getParent() instanceof ICPPASTExplicitTemplateInstantiation; } - public boolean qualified() { - if (forceQualified) - return true; - - IASTName n= astName; - if (n == null || n.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) - return false; - - IASTNode p = n.getParent(); - if (p instanceof ICPPASTTemplateId) { - n= (IASTName) p; - p= p.getParent(); - } - if (p instanceof ICPPASTQualifiedName) { - final ICPPASTQualifiedName qname = (ICPPASTQualifiedName) p; - if (qname.isFullyQualified()) - return true; - final IASTName[] qnames = qname.getNames(); - if (qnames.length > 0 && qnames[0] != n) - return true; - } - return p instanceof ICPPASTFieldReference; - } - public boolean isFunctionCall() { - if (astName == null) return false; - if (astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return false; - IASTNode p1 = astName.getParent(); - if (p1 instanceof ICPPASTQualifiedName) - p1 = p1.getParent(); - return (p1 instanceof IASTIdExpression && p1.getPropertyInParent() == IASTFunctionCallExpression.FUNCTION_NAME); + return fFunctionCall; } public static boolean checkWholeClassScope(IASTName name) { if (name == null) - return false; - if (name.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return true; IASTNode node = name.getParent(); @@ -331,6 +296,25 @@ public class LookupData { } return false; } + + public static boolean typesOnly(IASTName tn) { + if (tn.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME) { + tn= (IASTName) tn.getParent(); + } + + IASTNode parent = tn.getParent(); + if (parent instanceof ICPPASTBaseSpecifier + || parent instanceof ICPPASTElaboratedTypeSpecifier + || parent instanceof ICPPASTCompositeTypeSpecifier) { + return true; + } else if (parent instanceof ICPPASTQualifiedName) { + final ICPPASTQualifiedName qn = (ICPPASTQualifiedName) parent; + if (qn.getLastName() != tn) { + return true; + } + } + return false; + } public boolean hasResultOrProblem() { return problem != null || hasResults(); @@ -363,38 +347,51 @@ public class LookupData { * Returns the implied object type, or null. */ public IType getImpliedObjectType() { - if (astName == null) - return null; - - IASTName name= astName; - IASTNode nameParent= name.getParent(); - while (nameParent instanceof IASTName) { - name= (IASTName) nameParent; - nameParent= name.getParent(); - } - - final ASTNodeProperty prop = name.getPropertyInParent(); - if (prop == CPPSemantics.STRING_LOOKUP_PROPERTY) { - return null; - } - if (prop == IASTFieldReference.FIELD_NAME) { - ICPPASTFieldReference fieldRef = (ICPPASTFieldReference) nameParent; - return fieldRef.getFieldOwnerType(); - } - if (prop == IASTIdExpression.ID_NAME) { - IScope scope = CPPVisitor.getContainingScope(name); - if (scope instanceof ICPPClassScope) { - return ((ICPPClassScope) scope).getClassType(); - } - return CPPVisitor.getImpliedObjectType(scope); - } - return null; + if (fImpliedObjectType == null) { + fImpliedObjectType= determineImpliedObjectType(); + } + return fImpliedObjectType; } + private IType determineImpliedObjectType() { + IASTName tn = getLookupName(); + if (tn == null) + return null; + + if (tn.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME) { + tn= (IASTName) tn.getParent(); + } + + IASTNode parent = tn.getParent(); + IASTNode nameParent= parent; + if (parent instanceof ICPPASTQualifiedName) { + final ICPPASTQualifiedName qn = (ICPPASTQualifiedName) parent; + if (qn.getLastName() == tn) { + nameParent= parent.getParent(); + } + } + + if (nameParent instanceof IASTFieldReference) { + return ((ICPPASTFieldReference) nameParent).getFieldOwnerType(); + } else if (nameParent instanceof IASTIdExpression) { + if (nameParent.getPropertyInParent() == IASTFunctionCallExpression.FUNCTION_NAME) { + IScope scope = CPPVisitor.getContainingScope(nameParent); + if (scope instanceof ICPPClassScope) { + return ((ICPPClassScope) scope).getClassType(); + } else { + return CPPVisitor.getImpliedObjectType(scope); + } + } + } + return null; + } + public boolean forFriendship() { - if (astName == null) + IASTName lookupName= getLookupName(); + if (lookupName == null) return false; - IASTNode node = astName.getParent(); + + IASTNode node = lookupName.getParent(); while (node instanceof IASTName) node = node.getParent(); @@ -429,25 +426,15 @@ public class LookupData { } public boolean checkAssociatedScopes() { - IASTName name= astName; - if (name == null || name instanceof ICPPASTQualifiedName) - return false; - - IASTNode parent = name.getParent(); - if (name.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME) - parent= parent.getParent(); - - if (parent instanceof ICPPASTQualifiedName) { - return false; - } - return isFunctionCall(); + return !qualified && fFunctionCall; } public boolean checkClassContainingFriend() { - if (astName == null || astName instanceof ICPPASTQualifiedName) + IASTName lookupName= getLookupName(); + if (lookupName == null || lookupName instanceof ICPPASTQualifiedName) return false; - - IASTNode p = astName.getParent(); + + IASTNode p = lookupName.getParent(); ASTNodeProperty prop = null; while (p != null) { prop = p.getPropertyInParent(); @@ -467,45 +454,33 @@ public class LookupData { return false; } - public void setFunctionArguments(boolean containsImpliedObject, IASTInitializerClause... exprs) { + public void setFunctionArguments(boolean containsImpliedObject, ICPPEvaluation... exprs) { argsContainImpliedObject= containsImpliedObject; functionArgs= exprs; - if (exprs.length != 0) { - IASTNode node= exprs[0]; - boolean checkForDependentName= false; - while (node != null) { - if (node instanceof ICPPASTTemplateDeclaration) { - checkForDependentName= true; - break; - } - node= node.getParent(); - } - if (checkForDependentName) { - IType[] types= getFunctionArgumentTypes(); - for (IType type : types) { - if (CPPTemplates.isDependentType(type)) { - checkPointOfDecl= false; - break; - } - } + for (ICPPEvaluation e : exprs) { + if (e.isTypeDependent()) { + setIgnorePointOfDeclaration(true); + break; } } } + public void setFunctionArguments(boolean containsImpliedObject, IASTInitializerClause... exprs) { + ICPPEvaluation[] evals= new ICPPEvaluation[exprs.length]; + for (int i = 0; i < evals.length; i++) { + evals[i]= ((ICPPASTInitializerClause) exprs[i]).getEvaluation(); + } + setFunctionArguments(containsImpliedObject, evals); + } + public IType[] getFunctionArgumentTypes() { if (functionArgTypes == null) { if (functionArgs != null) { - IASTInitializerClause[] exprs= functionArgs; + ICPPEvaluation[] exprs= functionArgs; functionArgTypes= new IType[exprs.length]; for (int i = 0; i < exprs.length; i++) { - IASTInitializerClause e = exprs[i]; - if (e instanceof IASTExpression) { - // Find function set when taking an address of a function - final IType t = ExpressionTypes.typeOrFunctionSet((IASTExpression) e); - functionArgTypes[i]= getSimplifiedType(t); - } else if (e instanceof ICPPASTInitializerList) { - functionArgTypes[i]= new InitializerListType((ICPPASTInitializerList) e); - } + ICPPEvaluation e = exprs[i]; + functionArgTypes[i]= getSimplifiedType(e.getTypeOrFunctionSet(getLookupPoint())); } } } @@ -514,14 +489,12 @@ public class LookupData { public ValueCategory[] getFunctionArgumentValueCategories() { if (functionArgValueCategories == null) { - IASTInitializerClause[] args= functionArgs; + ICPPEvaluation[] args= functionArgs; if (args != null) { functionArgValueCategories= new ValueCategory[args.length]; for (int i = 0; i < args.length; i++) { - final IASTInitializerClause arg = args[i]; - if (arg instanceof IASTExpression) { - functionArgValueCategories[i] = ExpressionTypes.valueCat((IASTExpression) arg); - } + final ICPPEvaluation arg = args[i]; + functionArgValueCategories[i] = arg.getValueCategory(getLookupPoint()); } } } @@ -534,11 +507,11 @@ public class LookupData { return 0; } - public int getFunctionArgumentPackExpansionCount() { + public int getFunctionArgumentPackExpansionCount() { int count= 0; if (functionArgs != null) { - for (IASTInitializerClause arg : functionArgs) { - if (arg instanceof ICPPASTPackExpansionExpression) + for (ICPPEvaluation arg : functionArgs) { + if (arg instanceof EvalFixed && arg.getTypeOrFunctionSet(null) instanceof ICPPParameterPackType) count++; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java index 16b4c891625..cd03ac12cc5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java @@ -459,7 +459,7 @@ public class SemanticUtil { } else if (type instanceof ICPPClassType && type instanceof IIndexBinding) { IASTTranslationUnit tu = node.getTranslationUnit(); if (tu instanceof CPPASTTranslationUnit) { - return ((CPPASTTranslationUnit) tu).mapToAST((ICPPClassType) type); + return ((CPPASTTranslationUnit) tu).mapToAST((ICPPClassType) type, node); } } return type; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java index 81d7ddfdac5..11fa5ddacea 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TemplateArgumentDeduction.java @@ -22,6 +22,7 @@ import java.util.Set; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory; +import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBinding; @@ -55,6 +56,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateArgument; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; /** @@ -64,17 +66,18 @@ public class TemplateArgumentDeduction { /** * Deduce arguments for a template function from the template id + the template function parameters. * 14.8.2.1 + * @param point */ static ICPPTemplateArgument[] deduceForFunctionCall(ICPPFunctionTemplate template, - ICPPTemplateArgument[] tmplArgs, List fnArgs, List argIsLValue, CPPTemplateParameterMap map) + ICPPTemplateArgument[] tmplArgs, List fnArgs, List argIsLValue, CPPTemplateParameterMap map, IASTNode point) throws DOMException { final ICPPTemplateParameter[] tmplParams = template.getTemplateParameters(); - if (!addExplicitArguments(tmplParams, tmplArgs, map)) + if (tmplArgs != null && !addExplicitArguments(tmplParams, tmplArgs, map, point)) return null; - if (!deduceFromFunctionArgs(template, fnArgs, argIsLValue, map)) + if (!deduceFromFunctionArgs(template, fnArgs, argIsLValue, map, point)) return null; return createArguments(map, tmplParams); @@ -85,7 +88,7 @@ public class TemplateArgumentDeduction { * returns false if there is no mapping. */ static boolean deduceFromFunctionArgs(ICPPFunctionTemplate template, List fnArgs, List argCats, - CPPTemplateParameterMap map) { + CPPTemplateParameterMap map, IASTNode point) { try { IType[] fnPars = template.getType().getParameterTypes(); final int fnParCount = fnPars.length; @@ -110,7 +113,7 @@ public class TemplateArgumentDeduction { break; } - par= CPPTemplates.instantiateType(par, map, -1, null); + par= CPPTemplates.instantiateType(par, map, -1, null, point); if (!CPPTemplates.isValidType(par)) return false; @@ -125,17 +128,16 @@ public class TemplateArgumentDeduction { // Check if this is a deduced context IType inner= Conversions.getInitListType(par); if (inner != null) { - final InitializerListType initListType = (InitializerListType) arg; - IType[] types = initListType.getExpressionTypes(); - ValueCategory[] valueCats = initListType.getValueCategories(); - for (int i = 0; i < types.length; i++) { - if (!deduceFromFunctionArg(inner, types[i], valueCats[i], deduct)) + final EvalInitList eval = ((InitializerListType) arg).getEvaluation(); + for (ICPPEvaluation clause : eval.getClauses()) { + if (!deduceFromFunctionArg(inner, clause.getTypeOrFunctionSet(point), + clause.getValueCategory(point), deduct, point)) return false; } } } else if (arg instanceof FunctionSetType) { // 14.8.2.1-6 Handling of overloaded function sets - ICPPFunction[] fs= ((FunctionSetType) arg).getFunctionSet(); + ICPPFunction[] fs= ((FunctionSetType) arg).getFunctionSet().getBindings(); for (ICPPFunction f : fs) { if (f instanceof ICPPFunctionTemplate) continue argLoop; // Non-deduced context @@ -151,7 +153,7 @@ public class TemplateArgumentDeduction { } if (handled.add(ASTTypeUtil.getType(arg, true))) { final CPPTemplateParameterMap state = deduct.saveState(); - if (deduceFromFunctionArg(par, arg, argCats.get(j), deduct)) { + if (deduceFromFunctionArg(par, arg, argCats.get(j), deduct, point)) { if (success != null) { deduct.restoreState(state); continue argLoop; // Non-deduced context @@ -165,7 +167,7 @@ public class TemplateArgumentDeduction { return false; deduct.restoreState(success); } else { - if (!deduceFromFunctionArg(par, arg, argCats.get(j), deduct)) + if (!deduceFromFunctionArg(par, arg, argCats.get(j), deduct, point)) return false; } } @@ -174,13 +176,13 @@ public class TemplateArgumentDeduction { if (!map.addDeducedArgs(deduct.fDeducedArgs)) return false; - return verifyDeduction(tmplPars, map, true); + return verifyDeduction(tmplPars, map, true, point); } catch (DOMException e) { } return false; } - private static boolean deduceFromFunctionArg(IType par, IType arg, ValueCategory valueCat, TemplateArgumentDeduction deduct) throws DOMException { + private static boolean deduceFromFunctionArg(IType par, IType arg, ValueCategory valueCat, TemplateArgumentDeduction deduct, IASTNode point) throws DOMException { boolean isReferenceTypeParameter= false; if (par instanceof ICPPReferenceType) { // If P is an rvalue reference to a cv-unqualified template parameter and the argument is an @@ -237,22 +239,23 @@ public class TemplateArgumentDeduction { } } - return deduct.fromType(par, arg, true); + return deduct.fromType(par, arg, true, point); } /** * 14.8.2.2 [temp.deduct.funcaddr] * Deducing template arguments taking the address of a function template + * @param point * @throws DOMException */ static ICPPTemplateArgument[] deduceForAddressOf(ICPPFunctionTemplate template, - ICPPTemplateArgument[] tmplArgs, IFunctionType arg, CPPTemplateParameterMap map) throws DOMException { + ICPPTemplateArgument[] tmplArgs, IFunctionType arg, CPPTemplateParameterMap map, IASTNode point) throws DOMException { final ICPPTemplateParameter[] tmplParams = template.getTemplateParameters(); - if (!addExplicitArguments(tmplParams, tmplArgs, map)) + if (!addExplicitArguments(tmplParams, tmplArgs, map, point)) return null; IType par= template.getType(); - par= CPPTemplates.instantiateType(par, map, -1, null); + par= CPPTemplates.instantiateType(par, map, -1, null, point); if (!CPPTemplates.isValidType(par)) return null; @@ -260,17 +263,17 @@ public class TemplateArgumentDeduction { if (isDependentPar) { TemplateArgumentDeduction deduct= new TemplateArgumentDeduction(tmplParams, map, new CPPTemplateParameterMap(tmplParams.length), 0); par= SemanticUtil.getNestedType(par, SemanticUtil.TDEF); - if (arg != null && !deduct.fromType(par, arg, false)) + if (arg != null && !deduct.fromType(par, arg, false, point)) return null; if (!map.addDeducedArgs(deduct.fDeducedArgs)) return null; } - if (!verifyDeduction(tmplParams, map, true)) + if (!verifyDeduction(tmplParams, map, true, point)) return null; if (isDependentPar) - par= CPPTemplates.instantiateType(par, map, -1, null); + par= CPPTemplates.instantiateType(par, map, -1, null, point); if (arg == null || arg.isSameType(par)) { return createArguments(map, tmplParams); @@ -281,9 +284,10 @@ public class TemplateArgumentDeduction { /** * Deduce arguments for a user defined conversion template * 14.8.2.3 + * @param point */ static ICPPTemplateArgument[] deduceForConversion(ICPPFunctionTemplate template, - IType conversionType, CPPTemplateParameterMap map) throws DOMException { + IType conversionType, CPPTemplateParameterMap map, IASTNode point) throws DOMException { final ICPPTemplateParameter[] tmplParams = template.getTemplateParameters(); final int length = tmplParams.length; @@ -293,7 +297,7 @@ public class TemplateArgumentDeduction { p= getArgumentTypeForDeduction(p, a instanceof ICPPReferenceType); a= SemanticUtil.getNestedType(a, SemanticUtil.REF | SemanticUtil.TDEF); TemplateArgumentDeduction deduct= new TemplateArgumentDeduction(tmplParams, null, map, 0); - if (!deduct.fromType(p, a, true)) { + if (!deduct.fromType(p, a, true, point)) { return null; } @@ -315,31 +319,32 @@ public class TemplateArgumentDeduction { /** * Deduce arguments for a function declaration * 14.8.2.6 + * @param point */ static ICPPTemplateArgument[] deduceForDeclaration(ICPPFunctionTemplate template, - ICPPTemplateArgument[] args, ICPPFunctionType ftype, CPPTemplateParameterMap map) throws DOMException { + ICPPTemplateArgument[] args, ICPPFunctionType ftype, CPPTemplateParameterMap map, IASTNode point) throws DOMException { final ICPPTemplateParameter[] tmplParams = template.getTemplateParameters(); - if (!addExplicitArguments(tmplParams, args, map)) + if (!addExplicitArguments(tmplParams, args, map, point)) return null; IType a= SemanticUtil.getSimplifiedType(ftype); - IType p= CPPTemplates.instantiateType(template.getType(), map, -1, null); + IType p= CPPTemplates.instantiateType(template.getType(), map, -1, null, point); if (!CPPTemplates.isValidType(p)) return null; TemplateArgumentDeduction deduct= new TemplateArgumentDeduction(tmplParams, map, new CPPTemplateParameterMap(tmplParams.length), 0); - if (!deduct.fromType(p, a, false)) { + if (!deduct.fromType(p, a, false, point)) { return null; } if (!map.addDeducedArgs(deduct.fDeducedArgs)) return null; - if (!verifyDeduction(tmplParams, map, true)) + if (!verifyDeduction(tmplParams, map, true, point)) return null; - IType type= CPPTemplates.instantiateType(p, map, -1, null); + IType type= CPPTemplates.instantiateType(p, map, -1, null, point); if (!ftype.isSameType(type)) return null; @@ -349,8 +354,9 @@ public class TemplateArgumentDeduction { /** * Deduces the mapping for the template parameters from the function parameters, * returns false if there is no mapping. + * @param point */ - static int deduceForPartialOrdering(ICPPTemplateParameter[] tmplPars, IType[] fnPars, IType[] fnArgs) { + static int deduceForPartialOrdering(ICPPTemplateParameter[] tmplPars, IType[] fnPars, IType[] fnArgs, IASTNode point) { try { final int fnParCount = fnPars.length; final int fnArgCount = fnArgs.length; @@ -377,7 +383,7 @@ public class TemplateArgumentDeduction { } IType arg = fnArgs[j]; - int cmpSpecialized= deduceForPartialOrdering(par, arg, deduct); + int cmpSpecialized= deduceForPartialOrdering(par, arg, deduct, point); if (cmpSpecialized < 0) return cmpSpecialized; if (cmpSpecialized > 0) @@ -389,7 +395,7 @@ public class TemplateArgumentDeduction { return -1; } - private static int deduceForPartialOrdering(IType par, IType arg, TemplateArgumentDeduction deduct) throws DOMException { + private static int deduceForPartialOrdering(IType par, IType arg, TemplateArgumentDeduction deduct, IASTNode point) throws DOMException { par= getNestedType(par, TDEF); arg= getNestedType(arg, TDEF); boolean isMoreCVQualified= false; @@ -403,7 +409,7 @@ public class TemplateArgumentDeduction { par= getNestedType(par, TDEF | REF | ALLCVQ); arg= getNestedType(arg, TDEF | REF | ALLCVQ); - if (!deduct.fromType(par, arg, false)) + if (!deduct.fromType(par, arg, false, point)) return -1; return isMoreCVQualified ? 1 : 0; @@ -411,9 +417,10 @@ public class TemplateArgumentDeduction { /** * Adds the explicit arguments to the map. + * @param point */ private static boolean addExplicitArguments(final ICPPTemplateParameter[] tmplParams, - ICPPTemplateArgument[] tmplArgs, CPPTemplateParameterMap map) { + ICPPTemplateArgument[] tmplArgs, CPPTemplateParameterMap map, IASTNode point) { tmplArgs= SemanticUtil.getSimplifiedArguments(tmplArgs); ICPPTemplateParameter tmplParam= null; int packOffset= -1; @@ -428,7 +435,7 @@ public class TemplateArgumentDeduction { } } ICPPTemplateArgument tmplArg= tmplArgs[i]; - tmplArg= CPPTemplates.matchTemplateParameterAndArgument(tmplParam, tmplArg, map); + tmplArg= CPPTemplates.matchTemplateParameterAndArgument(tmplParam, tmplArg, map, point); if (tmplArg == null) return false; @@ -534,22 +541,23 @@ 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) 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) { return false; } for (int j= 0; j < len; j++) { - if (!deduct.fromTemplateArgument(p[j], a[j])) { + if (!deduct.fromTemplateArgument(p[j], a[j], point)) { return false; } } - return verifyDeduction(pars, map, false); + return verifyDeduction(pars, map, false, point); } - private static boolean verifyDeduction(ICPPTemplateParameter[] pars, CPPTemplateParameterMap tpMap, boolean useDefaults) { + private static boolean verifyDeduction(ICPPTemplateParameter[] pars, CPPTemplateParameterMap tpMap, boolean useDefaults, IASTNode point) { for (ICPPTemplateParameter tpar : pars) { if (tpar.isParameterPack()) { ICPPTemplateArgument[] deducedArgs= tpMap.getPackExpansion(tpar); @@ -566,7 +574,7 @@ public class TemplateArgumentDeduction { if (deducedArg == null && useDefaults) { deducedArg= tpar.getDefaultValue(); if (deducedArg != null) { - deducedArg= CPPTemplates.instantiateArgument(deducedArg, tpMap, -1, null); + deducedArg= CPPTemplates.instantiateArgument(deducedArg, tpMap, -1, null, point); if (deducedArg != null) { tpMap.put(tpar, deducedArg); } @@ -580,7 +588,7 @@ public class TemplateArgumentDeduction { } - private CPPTemplateParameterMap fExplicitArgs; + private final CPPTemplateParameterMap fExplicitArgs; private CPPTemplateParameterMap fDeducedArgs; private Set fTemplateParameterPacks; private int fPackOffset; @@ -624,8 +632,9 @@ public class TemplateArgumentDeduction { /** * Deduces the template parameter mapping from one pair of template arguments. + * @param point */ - private boolean fromTemplateArgument(ICPPTemplateArgument p, ICPPTemplateArgument a) throws DOMException { + private boolean fromTemplateArgument(ICPPTemplateArgument p, ICPPTemplateArgument a, IASTNode point) throws DOMException { if (p.isNonTypeValue() != a.isNonTypeValue()) return false; @@ -651,11 +660,11 @@ public class TemplateArgumentDeduction { return tval.equals(sval); } - return fromType(p.getTypeValue(), a.getTypeValue(), false); + return fromType(p.getTypeValue(), a.getTypeValue(), false, point); } - private boolean fromType(IType p, IType a, boolean allowCVQConversion) throws DOMException { + private boolean fromType(IType p, IType a, boolean allowCVQConversion, IASTNode point) throws DOMException { while (p != null) { while (a instanceof ITypedef) a = ((ITypedef) a).getType(); @@ -668,7 +677,7 @@ public class TemplateArgumentDeduction { final ICPPPointerToMemberType ptrA = (ICPPPointerToMemberType) a; if (!allowCVQConversion && (ptrP.isConst() != ptrA.isConst() || ptrP.isVolatile() != ptrA.isVolatile())) return false; - if (!fromType(ptrP.getMemberOfClass(), ptrA.getMemberOfClass(), false)) { + if (!fromType(ptrP.getMemberOfClass(), ptrA.getMemberOfClass(), false, point)) { return false; } p = ptrP.getType(); @@ -739,7 +748,7 @@ public class TemplateArgumentDeduction { } else if (p instanceof ICPPFunctionType) { if (!(a instanceof ICPPFunctionType)) return false; - return fromFunctionType((ICPPFunctionType) p, (ICPPFunctionType) a); + return fromFunctionType((ICPPFunctionType) p, (ICPPFunctionType) a, point); } else if (p instanceof ICPPTemplateParameter) { ICPPTemplateArgument current= fDeducedArgs.getArgument(((ICPPTemplateParameter) p).getParameterID(), fPackOffset); if (current != null) { @@ -753,7 +762,7 @@ public class TemplateArgumentDeduction { } else if (p instanceof ICPPTemplateInstance) { if (!(a instanceof ICPPTemplateInstance)) return false; - return fromTemplateInstance((ICPPTemplateInstance) p, (ICPPTemplateInstance) a); + return fromTemplateInstance((ICPPTemplateInstance) p, (ICPPTemplateInstance) a, point); } else if (p instanceof ICPPUnknownBinding) { return true; // An unknown type may match anything. } else { @@ -764,7 +773,7 @@ public class TemplateArgumentDeduction { return false; } - private boolean fromTemplateInstance(ICPPTemplateInstance pInst, ICPPTemplateInstance aInst) + private boolean fromTemplateInstance(ICPPTemplateInstance pInst, ICPPTemplateInstance aInst, IASTNode point) throws DOMException { ICPPClassTemplate pTemplate= getPrimaryTemplate(pInst); ICPPClassTemplate aTemplate= getPrimaryTemplate(aInst); @@ -807,7 +816,7 @@ public class TemplateArgumentDeduction { if (expansionPattern != null) { p= expansionPattern; deduct.incPackOffset(); - p= CPPTemplates.instantiateArgument(p, fExplicitArgs, deduct.fPackOffset, null); + p= CPPTemplates.instantiateArgument(p, fExplicitArgs, deduct.fPackOffset, null, point); if (!CPPTemplates.isValidArgument(p)) return false; } else { @@ -815,22 +824,22 @@ public class TemplateArgumentDeduction { if (p.isPackExpansion()) { p= expansionPattern= p.getExpansionPattern(); deduct= new TemplateArgumentDeduction(this, aArgs.length-i); - p= CPPTemplates.instantiateArgument(p, fExplicitArgs, deduct.fPackOffset, null); + p= CPPTemplates.instantiateArgument(p, fExplicitArgs, deduct.fPackOffset, null, point); if (!CPPTemplates.isValidArgument(p)) return false; } } - if (!deduct.fromTemplateArgument(p, aArgs[i])) + if (!deduct.fromTemplateArgument(p, aArgs[i], point)) return false; } return true; } - private boolean fromFunctionType(ICPPFunctionType ftp, ICPPFunctionType fta) throws DOMException { + private boolean fromFunctionType(ICPPFunctionType ftp, ICPPFunctionType fta, IASTNode point) throws DOMException { if (ftp.isConst() != fta.isConst() || ftp.isVolatile() != fta.isVolatile()) return false; - if (!fromType(ftp.getReturnType(), fta.getReturnType(), false)) + if (!fromType(ftp.getReturnType(), fta.getReturnType(), false, point)) return false; IType[] pParams = ftp.getParameterTypes(); @@ -851,7 +860,7 @@ public class TemplateArgumentDeduction { if (parameterPack != null) { p= parameterPack; deduct.incPackOffset(); - p= CPPTemplates.instantiateType(p, fExplicitArgs, deduct.fPackOffset, null); + p= CPPTemplates.instantiateType(p, fExplicitArgs, deduct.fPackOffset, null, point); if (!CPPTemplates.isValidType(p)) return false; } else { @@ -859,12 +868,12 @@ public class TemplateArgumentDeduction { if (p instanceof ICPPParameterPackType) { p= parameterPack= ((ICPPParameterPackType) p).getType(); deduct= new TemplateArgumentDeduction(this, aParams.length - i); - p= CPPTemplates.instantiateType(p, fExplicitArgs, deduct.fPackOffset, null); + p= CPPTemplates.instantiateType(p, fExplicitArgs, deduct.fPackOffset, null, point); if (!CPPTemplates.isValidType(p)) return false; } } - if (!deduct.fromType(p, aParams[i], false)) + if (!deduct.fromType(p, aParams[i], false, point)) return false; } return true; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeOfDependentExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeOfDependentExpression.java new file mode 100644 index 00000000000..c9014ba8a0d --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/TypeOfDependentExpression.java @@ -0,0 +1,64 @@ +/******************************************************************************* + * Copyright (c) 2012 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 + * + * 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; +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.ProblemType; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType; +import org.eclipse.core.runtime.CoreException; + +/** + * Represents the type of a dependent expression. + */ +public class TypeOfDependentExpression implements ICPPUnknownType, ISerializableType { + private final ICPPEvaluation fEvaluation; + + public TypeOfDependentExpression(ICPPEvaluation evaluation) { + fEvaluation= evaluation; + } + + public ICPPEvaluation getEvaluation() { + return fEvaluation; + } + + @Override + public boolean isSameType(IType type) { + return type instanceof TypeOfDependentExpression + && fEvaluation == ((TypeOfDependentExpression) type).fEvaluation; + } + + @Override + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + return null; + } + } + + @Override + public void marshal(ITypeMarshalBuffer buffer) throws CoreException { + buffer.putByte(ITypeMarshalBuffer.DEPENDENT_EXPRESSION_TYPE); + buffer.marshalEvaluation(fEvaluation, false); + } + + public static IType unmarshal(int firstByte, ITypeMarshalBuffer buffer) throws CoreException { + ISerializableEvaluation eval= buffer.unmarshalEvaluation(); + if (eval instanceof ICPPEvaluation) + return new TypeOfDependentExpression((ICPPEvaluation) eval); + return ProblemType.UNKNOWN_FOR_EXPRESSION; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/CompositeScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/CompositeScope.java index 9537c4dad99..c03863f0ddd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/CompositeScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/CompositeScope.java @@ -121,7 +121,7 @@ public abstract class CompositeScope implements IIndexScope { @Override public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefix) { - return getBindings(name, resolve, prefix, IIndexFileSet.EMPTY); + return getBindings(new ScopeLookupData(name, resolve, prefix)); } /** diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/c/CompositeCCompositeScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/c/CompositeCCompositeScope.java index 03d5ceeb136..2b3c012d28e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/c/CompositeCCompositeScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/c/CompositeCCompositeScope.java @@ -43,9 +43,14 @@ class CompositeCCompositeScope extends CompositeScope implements ICCompositeType return processUncertainBinding(binding); } - @Override + @Override @Deprecated public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) { - IBinding[] bindings = ((ICompositeType)rbinding).getCompositeScope().getBindings(name, resolve, prefixLookup, fileSet); + return getBindings(new ScopeLookupData(name, resolve, prefixLookup)); + } + + @Override + public IBinding[] getBindings(ScopeLookupData lookup) { + IBinding[] bindings = ((ICompositeType)rbinding).getCompositeScope().getBindings(lookup); return processUncertainBindings(bindings); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/c/CompositeCEnumerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/c/CompositeCEnumerator.java index ee8389259f9..f0844214e92 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/c/CompositeCEnumerator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/c/CompositeCEnumerator.java @@ -10,7 +10,6 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.index.composite.c; -import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IValue; @@ -23,7 +22,7 @@ class CompositeCEnumerator extends CompositeCBinding implements IEnumerator { } @Override - public IType getType() throws DOMException { + public IType getType() { return cf.getCompositeType(((IEnumerator) rbinding).getType()); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java index 71ea180a863..482571a9c84 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CPPCompositesFactory.java @@ -44,6 +44,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter; @@ -65,10 +66,28 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPQualifierType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPClassSpecializationScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; +import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalUnknownScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownClassType; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPFunctionSet; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinary; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinaryTypeId; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinding; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalComma; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalCompound; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalConditional; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFunctionCall; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFunctionSet; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalID; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalInitList; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalMemberAccess; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUnary; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUnaryTypeID; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.TypeOfDependentExpression; import org.eclipse.cdt.internal.core.index.CIndex; import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding; import org.eclipse.cdt.internal.core.index.IIndexScope; @@ -198,7 +217,15 @@ public class CPPCompositesFactory extends AbstractCompositeFactory { return new CPPArrayType(r2, v2); } return at; - } + } + if (rtype instanceof TypeOfDependentExpression) { + TypeOfDependentExpression tde= (TypeOfDependentExpression) rtype; + ICPPEvaluation e= tde.getEvaluation(); + ICPPEvaluation e2= getCompositeEvaluation(e); + if (e != e2) + return new TypeOfDependentExpression(e2); + return tde; + } if (rtype instanceof IBasicType || rtype == null || rtype instanceof ISemanticProblem) { return rtype; } @@ -206,6 +233,194 @@ public class CPPCompositesFactory extends AbstractCompositeFactory { throw new CompositingNotImplementedError(); } + private ICPPEvaluation getCompositeEvaluation(ICPPEvaluation eval) { + if (eval == null) + return null; + if (eval instanceof EvalBinary) { + EvalBinary e= (EvalBinary) eval; + ICPPEvaluation a = e.getArg1(); + ICPPEvaluation b = e.getArg2(); + + ICPPEvaluation a2 = getCompositeEvaluation(a); + ICPPEvaluation b2 = getCompositeEvaluation(b); + if (a != a2 || b != b2) + e= new EvalBinary(e.getOperator(), a2, b2); + return e; + } + if (eval instanceof EvalBinaryTypeId) { + EvalBinaryTypeId e= (EvalBinaryTypeId) eval; + IType a = e.getType1(); + IType b = e.getType2(); + + IType a2 = getCompositeType(a); + IType b2 = getCompositeType(b); + if (a != a2 || b != b2) + e= new EvalBinaryTypeId(e.getOperator(), a2, b2); + return e; + } + if (eval instanceof EvalBinding) { + EvalBinding e= (EvalBinding) eval; + IBinding a = e.getBinding(); + IType b = e.getFixedType(); + + IBinding a2 = getCompositeBinding((IIndexFragmentBinding) a); + IType b2 = getCompositeType(b); + if (a != a2 || b != b2) + e= new EvalBinding(a2, b2); + return e; + } + if (eval instanceof EvalComma) { + EvalComma e= (EvalComma) eval; + ICPPEvaluation[] a = e.getArguments(); + ICPPEvaluation[] a2 = getCompositeEvaluationArray(a); + if (a != a2) + e= new EvalComma(a2); + return e; + } + if (eval instanceof EvalCompound) { + EvalCompound e= (EvalCompound) eval; + ICPPEvaluation a = e.getLastEvaluation(); + ICPPEvaluation a2 = getCompositeEvaluation(a); + if (a != a2) + e= new EvalCompound(a2); + return e; + } + if (eval instanceof EvalConditional) { + EvalConditional e= (EvalConditional) eval; + ICPPEvaluation a = e.getCondition(); + ICPPEvaluation b = e.getPositive(); + ICPPEvaluation c = e.getNegative(); + ICPPEvaluation a2 = getCompositeEvaluation(a); + ICPPEvaluation b2 = getCompositeEvaluation(b); + ICPPEvaluation c2 = getCompositeEvaluation(c); + if (a != a2 || b != b2 || c != c2) + e= new EvalConditional(a2, b2, c2, e.isPositiveThrows(), e.isNegativeThrows()); + return e; + } + if (eval instanceof EvalFixed) { + EvalFixed e= (EvalFixed) eval; + IType a = e.getType(); + IValue b = e.getValue(); + IType a2 = getCompositeType(a); + IValue b2= getCompositeValue(b); + if (a != a2 || b != b2) + e= new EvalFixed(a2, e.getValueCategory(), b2); + return e; + } + if (eval instanceof EvalFunctionCall) { + EvalFunctionCall e= (EvalFunctionCall) eval; + ICPPEvaluation[] a = e.getArguments(); + ICPPEvaluation[] a2 = getCompositeEvaluationArray(a); + if (a != a2) + e= new EvalFunctionCall(a2); + return e; + } + if (eval instanceof EvalFunctionSet) { + EvalFunctionSet e= (EvalFunctionSet) eval; + final CPPFunctionSet fset = e.getFunctionSet(); + ICPPFunction[] a = fset.getBindings(); + ICPPTemplateArgument[] b = fset.getTemplateArguments(); + + ICPPFunction[] a2 = getCompositeFunctionArray(a); + ICPPTemplateArgument[] b2 = TemplateInstanceUtil.convert(this, b); + if (a != a2 || b != b2) + e= new EvalFunctionSet(new CPPFunctionSet(a2, b2, null), e.isAddressOf()); + return e; + } + if (eval instanceof EvalID) { + EvalID e= (EvalID) eval; + ICPPEvaluation a = e.getFieldOwner(); + IBinding b = e.getNameOwner(); + ICPPTemplateArgument[] c = e.getTemplateArgs(); + + ICPPEvaluation a2 = getCompositeEvaluation(a); + IIndexBinding b2 = getCompositeBinding((IIndexFragmentBinding) b); + ICPPTemplateArgument[] c2 = TemplateInstanceUtil.convert(this, c); + + if (a != a2 || b != b2 || c != c2) + e= new EvalID(a2, b2, e.getName(), e.isAddressOf(), e.isQualified(), c2); + return e; + } + if (eval instanceof EvalInitList) { + EvalInitList e= (EvalInitList) eval; + ICPPEvaluation[] a = e.getClauses(); + ICPPEvaluation[] a2 = getCompositeEvaluationArray(a); + if (a != a2) + e= new EvalInitList(a2); + return e; + } + if (eval instanceof EvalMemberAccess) { + EvalMemberAccess e= (EvalMemberAccess) eval; + IType a = e.getOwnerType(); + IBinding b = e.getMember(); + IType a2= getCompositeType(a); + IBinding b2= getCompositeBinding((IIndexFragmentBinding) b); + if (a != a2 || b != b2) + e= new EvalMemberAccess(a2, e.getOwnerValueCategory(), b2, e.isPointerDeref()); + return e; + } + if (eval instanceof EvalTypeId) { + EvalTypeId e= (EvalTypeId) eval; + IType a = e.getInputType(); + ICPPEvaluation[] b = e.getArguments(); + IType a2= getCompositeType(a); + ICPPEvaluation[] b2 = getCompositeEvaluationArray(b); + if (a != a2 || b != b2) + e= new EvalTypeId(a2, b2); + return e; + } + if (eval instanceof EvalUnary) { + EvalUnary e= (EvalUnary) eval; + ICPPEvaluation a = e.getArgument(); + ICPPEvaluation a2 = getCompositeEvaluation(a); + if (a != a2) + e= new EvalUnary(e.getOperator(), a2); + return e; + } + if (eval instanceof EvalUnaryTypeID) { + EvalUnaryTypeID e= (EvalUnaryTypeID) eval; + IType a = e.getArgument(); + IType a2 = getCompositeType(a); + if (a != a2) + e= new EvalUnaryTypeID(e.getOperator(), a2); + return e; + } + + throw new CompositingNotImplementedError(); + } + + private ICPPEvaluation[] getCompositeEvaluationArray(ICPPEvaluation[] array) { + ICPPEvaluation[] array2= array; + for (int i = 0; i < array.length; i++) { + ICPPEvaluation a = array[i]; + ICPPEvaluation a2= getCompositeEvaluation(a); + if (array != array2) { + array2[i]= a2; + } else if (a != a2) { + array2= new ICPPEvaluation[array.length]; + System.arraycopy(array, 0, array2, 0, i); + array2[i]= a2; + } + } + return array2; + } + + private ICPPFunction[] getCompositeFunctionArray(ICPPFunction[] array) { + ICPPFunction[] array2= array; + for (int i = 0; i < array.length; i++) { + ICPPFunction a = array[i]; + ICPPFunction a2= (ICPPFunction) getCompositeBinding((IIndexFragmentBinding) a); + if (array != array2) { + array2[i]= a2; + } else if (a != a2) { + array2= new ICPPFunction[array.length]; + System.arraycopy(array, 0, array2, 0, i); + array2[i]= a2; + } + } + return array2; + } + @Override public IValue getCompositeValue(IValue v) { if (v == null) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassScope.java index 824653a38e6..ab9e34545f0 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassScope.java @@ -65,9 +65,14 @@ class CompositeCPPClassScope extends CompositeScope implements ICPPClassScope { return processUncertainBinding(binding); } - @Override + @Override @Deprecated public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) { - IBinding[] bindings = ((ICPPClassType)rbinding).getCompositeScope().getBindings(name, resolve, prefixLookup, fileSet); + return getBindings(new ScopeLookupData(name, resolve, prefixLookup)); + } + + @Override + public IBinding[] getBindings(ScopeLookupData lookup) { + IBinding[] bindings = ((ICPPClassType)rbinding).getCompositeScope().getBindings(lookup); return processUncertainBindings(bindings); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecialization.java index 7b8589160c1..aaf32627865 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecialization.java @@ -11,6 +11,10 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.index.composite.cpp; +import java.util.HashSet; +import java.util.Set; + +import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; @@ -23,6 +27,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.parser.util.ObjectMap; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassSpecialization.RecursionResolvingBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPClassSpecializationScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; @@ -34,6 +39,8 @@ import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory; public class CompositeCPPClassSpecialization extends CompositeCPPClassType implements ICPPClassSpecialization { private ObjectMap specializationMap= null; + private final ThreadLocal> fInProgress= new ThreadLocal>(); + public CompositeCPPClassSpecialization(ICompositesFactory cf, ICPPClassType rbinding) { super(cf, rbinding); @@ -60,6 +67,11 @@ public class CompositeCPPClassSpecialization extends CompositeCPPClassType imple @Override public IBinding specializeMember(IBinding original) { + return specializeMember(original, null); + } + + @Override + public IBinding specializeMember(IBinding original, IASTNode point) { if (specializationMap == null) { final Object key= CPPCompositesFactory.createSpecializationKey(cf, rbinding); final IIndexFragment frag= rbinding.getFragment(); @@ -89,12 +101,23 @@ public class CompositeCPPClassSpecialization extends CompositeCPPClassType imple specializationMap= (ObjectMap) frag.putCachedResult(key, newMap, false); } } + Set set; synchronized (specializationMap) { IBinding result= (IBinding) specializationMap.get(original); if (result != null) return result; + set= fInProgress.get(); + if (set == null) { + set= new HashSet(); + fInProgress.set(set); + } + if (!set.add(original)) + return new RecursionResolvingBinding(null, null); + } - IBinding newSpec= CPPTemplates.createSpecialization(this, original); + IBinding newSpec= CPPTemplates.createSpecialization(this, original, point); + set.remove(original); + synchronized (specializationMap) { IBinding oldSpec= (IBinding) specializationMap.put(original, newSpec); if (oldSpec != null) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecializationScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecializationScope.java index 5de773b597b..4776ac8bdf6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecializationScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPClassSpecializationScope.java @@ -83,11 +83,16 @@ public class CompositeCPPClassSpecializationScope extends CompositeScope impleme return fDelegate.getBinding(name, resolve, acceptLocalBindings); } - @Override + @Deprecated @Override public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet acceptLocalBindings) { + return getBindings(new ScopeLookupData(name, resolve, prefixLookup)); + } + + @Override + public IBinding[] getBindings(ScopeLookupData lookup) { createDelegate(); - return fDelegate.getBindings(name, resolve, prefixLookup, acceptLocalBindings); + return fDelegate.getBindings(lookup); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumScope.java index a19f6f06303..8933319fb05 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumScope.java @@ -37,9 +37,14 @@ class CompositeCPPEnumScope extends CompositeScope implements ICPPScope { return processUncertainBinding(binding); } - @Override + @Deprecated @Override public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) { - IBinding[] bindings = ((ICPPEnumeration)rbinding).asScope().getBindings(name, resolve, prefixLookup, fileSet); + return getBindings(new ScopeLookupData(name, resolve, prefixLookup)); + } + + @Override + public IBinding[] getBindings(ScopeLookupData lookup) { + IBinding[] bindings = ((ICPPEnumeration)rbinding).asScope().getBindings(lookup); return processUncertainBindings(bindings); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumerator.java index 990fc35ae32..27ebbe83184 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumerator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPEnumerator.java @@ -10,7 +10,6 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.index.composite.cpp; -import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IValue; @@ -22,7 +21,7 @@ class CompositeCPPEnumerator extends CompositeCPPBinding implements IEnumerator } @Override - public IType getType() throws DOMException { + public IType getType() { IType type = ((IEnumerator) rbinding).getType(); return cf.getCompositeType(type); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPNamespaceScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPNamespaceScope.java index 0b6f1b5c84f..2e67f4da97a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPNamespaceScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/CompositeCPPNamespaceScope.java @@ -57,11 +57,16 @@ class CompositeCPPNamespaceScope extends CompositeScope implements ICPPNamespace return processUncertainBinding(preresult); } - @Override + @Deprecated @Override public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) { + return getBindings(new ScopeLookupData(name, resolve, prefixLookup)); + } + + @Override + public IBinding[] getBindings(ScopeLookupData lookup) { IIndexFragmentBinding[][] preresult = new IIndexFragmentBinding[namespaces.length][]; for(int i=0; i= fBuffer.length) + throw unmarshallingError(); + + byte firstByte= fBuffer[fPos]; + if (firstByte == NULL_TYPE) { + fPos++; + return null; + } + return fLinkage.unmarshalEvaluation(this); + } + @Override public void marshalValue(IValue value) throws CoreException { if (value instanceof Value) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMBinding.java index d04f19fe4ee..cdaa9d00180 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMBinding.java @@ -22,6 +22,7 @@ import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IFunctionType; +import org.eclipse.cdt.core.dom.ast.IScope.ScopeLookupData; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration; @@ -426,10 +427,15 @@ public abstract class PDOMBinding extends PDOMNamedNode implements IPDOMBinding } public final IBinding[] getBindings(IASTName name, boolean resolve, boolean prefix) { - return getBindings(name, resolve, prefix, null); + return getBindings(new ScopeLookupData(name, resolve, prefix)); } + @Deprecated public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefix, IIndexFileSet fileSet) { - return null; + return IBinding.EMPTY_BINDING_ARRAY; + } + + public IBinding[] getBindings(ScopeLookupData lookup) { + return IBinding.EMPTY_BINDING_ARRAY; } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java index 812fbadd984..40a3ac04027 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMLinkage.java @@ -36,6 +36,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective; import org.eclipse.cdt.core.index.IIndexLinkage; import org.eclipse.cdt.core.parser.util.CharArrayMap; import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; +import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.index.IIndexBindingConstants; import org.eclipse.cdt.internal.core.index.IIndexScope; @@ -430,6 +431,7 @@ public abstract class PDOMLinkage extends PDOMNamedNode implements IIndexLinkage public abstract PDOMBinding addTypeBinding(IBinding type) throws CoreException; public abstract IType unmarshalType(ITypeMarshalBuffer buffer) throws CoreException; + public abstract ISerializableEvaluation unmarshalEvaluation(ITypeMarshalBuffer typeMarshalBuffer) throws CoreException; public void storeType(long offset, IType type) throws CoreException { final Database db= getDB(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCEnumerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCEnumerator.java index 3e6758c720a..fcf9141a181 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCEnumerator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCEnumerator.java @@ -11,7 +11,6 @@ package org.eclipse.cdt.internal.core.pdom.dom.c; import org.eclipse.cdt.core.CCorePlugin; -import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IType; @@ -71,7 +70,7 @@ class PDOMCEnumerator extends PDOMBinding implements IEnumerator { } @Override - public IType getType() throws DOMException { + public IType getType() { IIndexFragmentBinding owner = getOwner(); if (owner instanceof IType) return (IType) owner; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java index 5bc96bd2275..9640f88b0c7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCLinkage.java @@ -25,6 +25,7 @@ import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.index.IIndexBinding; +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.c.CArrayType; @@ -329,15 +330,15 @@ class PDOMCLinkage extends PDOMLinkage implements IIndexCBindingConstants { public IType unmarshalType(ITypeMarshalBuffer buffer) throws CoreException { int firstByte= buffer.getByte(); switch((firstByte & ITypeMarshalBuffer.KIND_MASK)) { - case ITypeMarshalBuffer.ARRAY: + case ITypeMarshalBuffer.ARRAY_TYPE: return CArrayType.unmarshal(firstByte, buffer); case ITypeMarshalBuffer.BASIC_TYPE: return CBasicType.unmarshal(firstByte, buffer); - case ITypeMarshalBuffer.CVQUALIFIER: + case ITypeMarshalBuffer.CVQUALIFIER_TYPE: return CQualifierType.unmarshal(firstByte, buffer); case ITypeMarshalBuffer.FUNCTION_TYPE: return CFunctionType.unmarshal(firstByte, buffer); - case ITypeMarshalBuffer.POINTER: + case ITypeMarshalBuffer.POINTER_TYPE: return CPointerType.unmarshal(firstByte, buffer); case ITypeMarshalBuffer.PROBLEM_TYPE: return ProblemType.unmarshal(firstByte, buffer); @@ -345,4 +346,10 @@ class PDOMCLinkage extends PDOMLinkage implements IIndexCBindingConstants { throw new CoreException(CCorePlugin.createStatus("Cannot unmarshal a type, first byte=" + firstByte)); //$NON-NLS-1$ } + + @Override + public ISerializableEvaluation unmarshalEvaluation(ITypeMarshalBuffer buffer) + throws CoreException { + throw new CoreException(CCorePlugin.createStatus("Cannot unmarshal an evaluation, first byte=" + buffer.getByte())); //$NON-NLS-1$ + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCStructure.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCStructure.java index 5be9b10a41a..246d78c6391 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCStructure.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/c/PDOMCStructure.java @@ -126,7 +126,7 @@ public class PDOMCStructure extends PDOMBinding implements ICompositeType, ICCom } private static class GetFields implements IPDOMVisitor { - private List fields = new ArrayList(); + private final List fields = new ArrayList(); @Override public boolean visit(IPDOMNode node) throws CoreException { if (node instanceof IField) { @@ -277,9 +277,14 @@ public class PDOMCStructure extends PDOMBinding implements ICompositeType, ICCom return getBinding(name.toCharArray()); } - @Override + @Deprecated @Override public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) { - return getBindings(name.toCharArray()); + return getBindings(new ScopeLookupData(name, resolve, prefixLookup)); + } + + @Override + public IBinding[] getBindings(ScopeLookupData lookup) { + return getBindings(lookup.getLookupKey()); } @Override diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassScope.java index 652b940d467..0be176e51d3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassScope.java @@ -117,7 +117,7 @@ class PDOMCPPClassScope implements ICPPClassScope, IIndexScope { @Override public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup) { - return getBindings(name, resolve, prefixLookup, null); + return getBindings(new ScopeLookupData(name, resolve, prefixLookup)); } @Override @@ -141,19 +141,24 @@ class PDOMCPPClassScope implements ICPPClassScope, IIndexScope { return fBinding; } - @Override + @Deprecated @Override public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) { + return getBindings(new ScopeLookupData(name, resolve, prefixLookup)); + } + + @Override + public IBinding[] getBindings(ScopeLookupData lookup) { try { - if (name instanceof ICPPASTConversionName) { + if (lookup.getLookupName() instanceof ICPPASTConversionName) { BindingCollector visitor = new BindingCollector(fBinding.getLinkage(), Keywords.cOPERATOR, CONVERSION_FILTER, true, false, true); acceptViaCache(fBinding, visitor, true); return visitor.getBindings(); } - final char[] nameChars = name.getSimpleID(); - if (!prefixLookup) { + final char[] nameChars = lookup.getLookupKey(); + if (!lookup.isPrefixLookup()) { if (CharArrayUtils.equals(fBinding.getNameCharArray(), nameChars)) { - if (CPPClassScope.shallReturnConstructors(name, prefixLookup)){ + if (CPPClassScope.shallReturnConstructors(lookup.getLookupName(), false)){ return fBinding.getConstructors(); } return new IBinding[] {getClassNameBinding()}; @@ -162,7 +167,7 @@ class PDOMCPPClassScope implements ICPPClassScope, IIndexScope { } // prefix lookup - BindingCollector visitor = new BindingCollector(fBinding.getLinkage(), nameChars, IndexFilter.CPP_DECLARED_OR_IMPLICIT_NO_INSTANCE, prefixLookup, prefixLookup, !prefixLookup); + BindingCollector visitor = new BindingCollector(fBinding.getLinkage(), nameChars, IndexFilter.CPP_DECLARED_OR_IMPLICIT_NO_INSTANCE, true, true, !true); if (ContentAssistMatcherFactory.getInstance().match(nameChars, fBinding.getNameCharArray())) { // add the class itself, constructors will be found during the visit visitor.visit((IPDOMNode) getClassNameBinding()); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassSpecialization.java index eb31fe7c9dc..8a801a9b415 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassSpecialization.java @@ -14,10 +14,13 @@ package org.eclipse.cdt.internal.core.pdom.dom.cpp; import java.util.ArrayList; import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Set; import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.IPDOMVisitor; +import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IField; import org.eclipse.cdt.core.dom.ast.IScope; @@ -33,6 +36,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.parser.util.ObjectMap; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassSpecialization; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassSpecialization.RecursionResolvingBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPClassSpecializationScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; @@ -62,7 +66,8 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements private volatile ICPPClassScope fScope; private ObjectMap specializationMap= null; // Obtained from the synchronized PDOM cache - + private final ThreadLocal> fInProgress= new ThreadLocal>(); + public PDOMCPPClassSpecialization(PDOMLinkage linkage, PDOMNode parent, ICPPClassType classType, PDOMBinding specialized) throws CoreException { super(linkage, parent, (ICPPSpecialization) classType, specialized); @@ -88,7 +93,12 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements } @Override - public IBinding specializeMember(IBinding original) { + public IBinding specializeMember(IBinding original) { + return specializeMember(original, null); + } + + @Override + public IBinding specializeMember(IBinding original, IASTNode point) { if (specializationMap == null) { final Long key= record+PDOMCPPLinkage.CACHE_INSTANCE_SCOPE; Object cached= getPDOM().getCachedResult(key); @@ -111,12 +121,22 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements specializationMap= (ObjectMap) getPDOM().putCachedResult(key, newMap, false); } } + Set set; synchronized (specializationMap) { IBinding result= (IBinding) specializationMap.get(original); if (result != null) return result; + set= fInProgress.get(); + if (set == null) { + set= new HashSet(); + fInProgress.set(set); + } + if (!set.add(original)) + return new RecursionResolvingBinding(null, null); } - IBinding newSpec= CPPTemplates.createSpecialization(this, original); + IBinding newSpec= CPPTemplates.createSpecialization(this, original, point); + set.remove(original); + synchronized (specializationMap) { IBinding oldSpec= (IBinding) specializationMap.put(original, newSpec); if (oldSpec != null) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplateSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplateSpecialization.java index f53318c54a2..ccbdb499f7b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplateSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplateSpecialization.java @@ -11,6 +11,7 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.pdom.dom.cpp; +import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IType; @@ -157,11 +158,12 @@ class PDOMCPPClassTemplateSpecialization extends PDOMCPPClassSpecialization @Override public ICPPClassTemplatePartialSpecialization[] getPartialSpecializations() { + IASTNode point= null; // Instantiation of dependent expression may not work. ICPPClassTemplate origTemplate= (ICPPClassTemplate) getSpecializedBinding(); ICPPClassTemplatePartialSpecialization[] orig = origTemplate.getPartialSpecializations(); ICPPClassTemplatePartialSpecialization[] spec = new ICPPClassTemplatePartialSpecialization[orig.length]; for (int i = 0; i < orig.length; i++) { - spec[i]= (ICPPClassTemplatePartialSpecialization) specializeMember(orig[i]); + spec[i]= (ICPPClassTemplatePartialSpecialization) specializeMember(orig[i], point); } return spec; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumScope.java index 0514ae7a11e..25f34538a52 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumScope.java @@ -59,7 +59,7 @@ class PDOMCPPEnumScope implements ICPPScope, IIndexScope { @Override public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup) { - return getBindings(name, resolve, prefixLookup, null); + return getBindings(new ScopeLookupData(name, resolve, prefixLookup)); } @Override @@ -73,13 +73,18 @@ class PDOMCPPEnumScope implements ICPPScope, IIndexScope { } } - @Override + @Deprecated @Override public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) { + return getBindings(new ScopeLookupData(name, resolve, prefixLookup)); + } + + @Override + public IBinding[] getBindings(ScopeLookupData lookup) { try { CharArrayMap map= getBindingMap(fBinding); - if (prefixLookup) { + if (lookup.isPrefixLookup()) { final List result= new ArrayList(); - final char[] nc= name.toCharArray(); + final char[] nc= lookup.getLookupKey(); IContentAssistMatcher matcher = ContentAssistMatcherFactory.getInstance().createMatcher(nc); for (char[] key : map.keys()) { if (matcher.match(key)) { @@ -88,7 +93,7 @@ class PDOMCPPEnumScope implements ICPPScope, IIndexScope { } return result.toArray(new IBinding[result.size()]); } - IBinding b= map.get(name.toCharArray()); + IBinding b= map.get(lookup.getLookupKey()); if (b != null) { return new IBinding[] {b}; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerator.java index 80e2efa3428..b449b88b6ab 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPEnumerator.java @@ -12,7 +12,6 @@ package org.eclipse.cdt.internal.core.pdom.dom.cpp; import org.eclipse.cdt.core.CCorePlugin; -import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IType; @@ -68,7 +67,7 @@ class PDOMCPPEnumerator extends PDOMCPPBinding implements IEnumerator { } @Override - public IType getType() throws DOMException { + public IType getType() { IIndexFragmentBinding owner = getOwner(); if (owner instanceof IType) return (IType) owner; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java index 03e07663c86..d2e86cd34c4 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPLinkage.java @@ -70,6 +70,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.internal.core.Util; import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; +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.cpp.CPPArrayType; @@ -86,6 +87,22 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownClassType; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinary; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinaryTypeId; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinding; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalComma; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalCompound; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalConditional; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFunctionCall; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFunctionSet; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalID; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalInitList; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalMemberAccess; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUnary; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalUnaryTypeID; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.TypeOfDependentExpression; import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; import org.eclipse.cdt.internal.core.index.composite.CompositeIndexBinding; import org.eclipse.cdt.internal.core.pdom.PDOM; @@ -117,7 +134,7 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { private final static int RECORD_SIZE= FIRST_NAMESPACE_CHILD_OFFSET + Database.PTR_SIZE; // Only used when writing to database, which is single-threaded - private LinkedList postProcesses = new LinkedList(); + private final LinkedList postProcesses = new LinkedList(); public PDOMCPPLinkage(PDOM pdom, long record) { super(pdom, record); @@ -1030,26 +1047,67 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants { public IType unmarshalType(ITypeMarshalBuffer buffer) throws CoreException { int firstByte= buffer.getByte(); switch((firstByte & ITypeMarshalBuffer.KIND_MASK)) { - case ITypeMarshalBuffer.ARRAY: + case ITypeMarshalBuffer.ARRAY_TYPE: return CPPArrayType.unmarshal(firstByte, buffer); case ITypeMarshalBuffer.BASIC_TYPE: return CPPBasicType.unmarshal(firstByte, buffer); - case ITypeMarshalBuffer.CVQUALIFIER: + case ITypeMarshalBuffer.CVQUALIFIER_TYPE: return CPPQualifierType.unmarshal(firstByte, buffer); case ITypeMarshalBuffer.FUNCTION_TYPE: return CPPFunctionType.unmarshal(firstByte, buffer); - case ITypeMarshalBuffer.POINTER: + case ITypeMarshalBuffer.POINTER_TYPE: return CPPPointerType.unmarshal(firstByte, buffer); case ITypeMarshalBuffer.PROBLEM_TYPE: return ProblemType.unmarshal(firstByte, buffer); - case ITypeMarshalBuffer.REFERENCE: + case ITypeMarshalBuffer.REFERENCE_TYPE: return CPPReferenceType.unmarshal(firstByte, buffer); - case ITypeMarshalBuffer.PACK_EXPANSION: + case ITypeMarshalBuffer.PACK_EXPANSION_TYPE: return CPPParameterPackType.unmarshal(firstByte, buffer); - case ITypeMarshalBuffer.POINTER_TO_MEMBER: + case ITypeMarshalBuffer.POINTER_TO_MEMBER_TYPE: return CPPPointerToMemberType.unmarshal(firstByte, buffer); + 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)) { + case ITypeMarshalBuffer.EVAL_BINARY: + return EvalBinary.unmarshal(firstByte, buffer); + case ITypeMarshalBuffer.EVAL_BINARY_TYPE_ID: + return EvalBinaryTypeId.unmarshal(firstByte, buffer); + case ITypeMarshalBuffer.EVAL_BINDING: + return EvalBinding.unmarshal(firstByte, buffer); + case ITypeMarshalBuffer.EVAL_COMMA: + return EvalComma.unmarshal(firstByte, buffer); + case ITypeMarshalBuffer.EVAL_COMPOUND: + return EvalCompound.unmarshal(firstByte, buffer); + case ITypeMarshalBuffer.EVAL_CONDITIONAL: + return EvalConditional.unmarshal(firstByte, buffer); + case ITypeMarshalBuffer.EVAL_FIXED: + return EvalFixed.unmarshal(firstByte, buffer); + case ITypeMarshalBuffer.EVAL_FUNCTION_CALL: + return EvalFunctionCall.unmarshal(firstByte, buffer); + case ITypeMarshalBuffer.EVAL_FUNCTION_SET: + return EvalFunctionSet.unmarshal(firstByte, buffer); + case ITypeMarshalBuffer.EVAL_ID: + return EvalID.unmarshal(firstByte, buffer); + case ITypeMarshalBuffer.EVAL_INIT_LIST: + return EvalInitList.unmarshal(firstByte, buffer); + case ITypeMarshalBuffer.EVAL_MEMBER_ACCESS: + return EvalMemberAccess.unmarshal(firstByte, buffer); + case ITypeMarshalBuffer.EVAL_TYPE_ID: + return EvalTypeId.unmarshal(firstByte, buffer); + case ITypeMarshalBuffer.EVAL_UNARY: + return EvalUnary.unmarshal(firstByte, buffer); + case ITypeMarshalBuffer.EVAL_UNARY_TYPE_ID: + return EvalUnaryTypeID.unmarshal(firstByte, buffer); + } + throw new CoreException(CCorePlugin.createStatus("Cannot unmarshal an evaluation, first byte=" + firstByte)); //$NON-NLS-1$ + } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPNamespace.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPNamespace.java index 33f84b2ad59..ddaee5b9e94 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPNamespace.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPNamespace.java @@ -182,20 +182,26 @@ class PDOMCPPNamespace extends PDOMCPPBinding return null; } - @Override + @Deprecated @Override public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) { + return getBindings(new ScopeLookupData(name, resolve, prefixLookup)); + } + + @Override + public IBinding[] getBindings(ScopeLookupData lookup) { IBinding[] result = null; try { - if (!prefixLookup) { - result= getBindingsViaCache(name.getLookupKey()); + if (!lookup.isPrefixLookup()) { + result= getBindingsViaCache(lookup.getLookupKey()); } else { - BindingCollector visitor= new BindingCollector(getLinkage(), name.getLookupKey(), - IndexFilter.CPP_DECLARED_OR_IMPLICIT_NO_INSTANCE, prefixLookup, prefixLookup, !prefixLookup); + BindingCollector visitor= new BindingCollector(getLinkage(), lookup.getLookupKey(), + IndexFilter.CPP_DECLARED_OR_IMPLICIT_NO_INSTANCE, true, true, false); getIndex().accept(visitor); result = visitor.getBindings(); } - if (fileSet != null) { - result= fileSet.filterFileLocalBindings(result); + IIndexFileSet filter = lookup.getIncludedFiles(); + if (filter != null) { + result= filter.filterFileLocalBindings(result); } } catch (CoreException e) { CCorePlugin.log(e); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTypedefSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTypedefSpecialization.java index 32a54c1fcf4..dd3ee67bcea 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTypedefSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPTypedefSpecialization.java @@ -16,7 +16,6 @@ import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer; -import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTypedefSpecialization; import org.eclipse.cdt.internal.core.index.CPPTypedefClone; import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; import org.eclipse.cdt.internal.core.index.IIndexType; @@ -38,24 +37,9 @@ class PDOMCPPTypedefSpecialization extends PDOMCPPSpecialization implements ITyp throws CoreException { super(linkage, parent, (ICPPSpecialization) typedef, specialized); - // The following may try to add the same typedef specialization to the index again. - // We protect against infinite recursion using a counter inside typedef. - try { - if (typedef instanceof CPPTypedefSpecialization) { - if (((CPPTypedefSpecialization) typedef).incResolutionDepth(1) > - CPPTypedefSpecialization.MAX_RESOLUTION_DEPTH) { - return; - } - } - linkage.storeType(record + TYPE_OFFSET, typedef.getType()); - if (PDOMCPPTypedef.introducesRecursion(getType(), getParentNodeRec(), getNameCharArray())) { - linkage.storeType(record + TYPE_OFFSET, null); - } - - } finally { - if (typedef instanceof CPPTypedefSpecialization) { - ((CPPTypedefSpecialization) typedef).incResolutionDepth(-1); - } + linkage.storeType(record + TYPE_OFFSET, typedef.getType()); + if (PDOMCPPTypedef.introducesRecursion(getType(), getParentNodeRec(), getNameCharArray())) { + linkage.storeType(record + TYPE_OFFSET, null); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPUnknownClassType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPUnknownClassType.java index 8e219260eae..32f96933696 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPUnknownClassType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPUnknownClassType.java @@ -140,10 +140,15 @@ class PDOMCPPUnknownClassType extends PDOMCPPUnknownBinding implements ICPPClass return null; } - @Override + @Deprecated @Override public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) { return IBinding.EMPTY_BINDING_ARRAY; } + + @Override + public IBinding[] getBindings(ScopeLookupData lookup) { + return IBinding.EMPTY_BINDING_ARRAY; + } @Override public IBinding[] find(String name) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPUnknownScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPUnknownScope.java index 7f672db8004..84c07283f7e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPUnknownScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPUnknownScope.java @@ -41,7 +41,7 @@ public class PDOMCPPUnknownScope extends CPPUnknownScope implements IIndexScope @Override // Needs to be thread-safe. - protected synchronized IBinding getOrCreateBinding(IASTName name, int idx) { + protected synchronized IBinding getOrCreateBinding(char[] name, int idx) { return super.getOrCreateBinding(name, idx); } } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/RefactoringTestBase.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/RefactoringTestBase.java index b163c61ca5e..160d01cd05c 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/RefactoringTestBase.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/refactoring/RefactoringTestBase.java @@ -94,8 +94,7 @@ public abstract class RefactoringTestBase extends BaseTestCase { Bundle bundle = CTestPlugin.getDefault().getBundle(); CharSequence[] testData = TestSourceReader.getContentsForTest(bundle, "ui", getClass(), getName(), 0); - for (int i = 0; i < testData.length; i++) { - CharSequence contents = testData[i]; + for (CharSequence contents : testData) { TestSourceFile testFile = null; boolean expectedResult = false; BufferedReader reader = new BufferedReader(new StringReader(contents.toString())); @@ -356,6 +355,8 @@ public abstract class RefactoringTestBase extends BaseTestCase { String expectedSource = testFile.getExpectedSource(); IFile file = cproject.getProject().getFile(new Path(testFile.getName())); String actualSource = getFileContents(file); + expectedSource= expectedSource.replace("\r\n", "\n"); + actualSource= actualSource.replace("\r\n", "\n"); assertEquals(expectedSource, actualSource); } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/TypeHierarchyUI.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/TypeHierarchyUI.java index 50b3bd3a15b..fae01a0f429 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/TypeHierarchyUI.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/TypeHierarchyUI.java @@ -26,7 +26,6 @@ import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.texteditor.ITextEditor; import org.eclipse.cdt.core.CCorePlugin; -import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.ICompositeType; @@ -212,21 +211,15 @@ public class TypeHierarchyUI { } private static IBinding findTypeBinding(IBinding memberBinding) { - try { - if (memberBinding instanceof IEnumerator) { - IType type= ((IEnumerator) memberBinding).getType(); - if (type instanceof IBinding) { - return (IBinding) type; - } + if (memberBinding instanceof IEnumerator) { + IType type= ((IEnumerator) memberBinding).getType(); + if (type instanceof IBinding) { + return (IBinding) type; } - else if (memberBinding instanceof ICPPMember) { - return ((ICPPMember) memberBinding).getClassOwner(); - } - else if (memberBinding instanceof IField) { - return ((IField) memberBinding).getCompositeTypeOwner(); - } - } catch (DOMException e) { - // don't log problem bindings + } else if (memberBinding instanceof ICPPMember) { + return ((ICPPMember) memberBinding).getClassOwner(); + } else if (memberBinding instanceof IField) { + return ((IField) memberBinding).getCompositeTypeOwner(); } return null; } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IndexUI.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IndexUI.java index 1b055ed0631..528fd655cde 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IndexUI.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/viewsupport/IndexUI.java @@ -511,10 +511,11 @@ public class IndexUI { // Check for specializations of the owner IBinding owner = binding.getOwner(); if (owner != null) { + IASTNode point= null; // Instantiation of dependent expression may not work. for (IBinding specOwner : findSpecializations(index, owner)) { if (specOwner instanceof ICPPClassSpecialization) { // Add the specialized member - IBinding specializedMember = ((ICPPClassSpecialization) specOwner).specializeMember(binding); + IBinding specializedMember = ((ICPPClassSpecialization) specOwner).specializeMember(binding, point); specializedMember= index.adaptBinding(specializedMember); if (specializedMember != null) { if (result == null) diff --git a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Scope.java b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Scope.java index 9e7b7933f7f..7061c36eac0 100644 --- a/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Scope.java +++ b/lrparser/org.eclipse.cdt.core.lrparser/old/org/eclipse/cdt/internal/core/dom/lrparser/c99/bindings/C99Scope.java @@ -101,8 +101,16 @@ public class C99Scope implements IC99Scope, IASTInternalScope { return null; } + /** + * @deprecated Use {@link #getBindings(ScopeLookupData)} instead + */ + @Deprecated public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet acceptLocalBindings) { + return getBindings(new ScopeLookupData(name, resolve, prefixLookup)); + } + + public IBinding[] getBindings(ScopeLookupData lookup) { // TODO Auto-generated method stub return null; }