mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-21 21:52:10 +02:00
Add basic support for c++17 deduction guides
This commit is contained in:
parent
aafb1d951a
commit
f17675be16
25 changed files with 1017 additions and 59 deletions
|
@ -57,6 +57,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTAliasDeclaration;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeductionGuide;
|
||||
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.ICPPASTFunctionDeclarator;
|
||||
|
@ -544,7 +545,10 @@ public class CModelBuilder2 implements IContributedModelBuilder {
|
|||
return createTypeDef(parent, declSpecifier, declarator);
|
||||
}
|
||||
IASTDeclarator typeRelevant = ASTQueries.findTypeRelevantDeclarator(declarator);
|
||||
if (typeRelevant instanceof IASTFunctionDeclarator) {
|
||||
if (typeRelevant instanceof ICPPASTDeductionGuide) {
|
||||
// TODO [cmodel] deduction guide
|
||||
return null;
|
||||
} else if (typeRelevant instanceof IASTFunctionDeclarator) {
|
||||
return createFunctionDeclaration(parent, declSpecifier, (IASTFunctionDeclarator) typeRelevant, isTemplate);
|
||||
}
|
||||
return createVariable(parent, declSpecifier, declarator, isTemplate);
|
||||
|
|
|
@ -118,6 +118,7 @@ public interface IScope {
|
|||
private boolean fPrefixLookup;
|
||||
private boolean fIgnorePointOfDeclaration;
|
||||
private boolean fArgumentDependent;
|
||||
private boolean fDeductionGuidesOnly = false;
|
||||
|
||||
public ScopeLookupData(IASTName name, boolean resolve, boolean prefixLookup) {
|
||||
if (name == null)
|
||||
|
@ -172,6 +173,11 @@ public interface IScope {
|
|||
fArgumentDependent = argumentDependent;
|
||||
}
|
||||
|
||||
/** @since 8.1 */
|
||||
public final void setDeductionGuidesOnly(boolean deductionGuidesOnly) {
|
||||
fDeductionGuidesOnly = deductionGuidesOnly;
|
||||
}
|
||||
|
||||
public final void setLookupKey(char[] key) {
|
||||
fLookupKey = key;
|
||||
}
|
||||
|
@ -201,6 +207,11 @@ public interface IScope {
|
|||
return fArgumentDependent;
|
||||
}
|
||||
|
||||
/** @since 8.1 */
|
||||
public final boolean isDeductionGuidesOnly() {
|
||||
return fDeductionGuidesOnly;
|
||||
}
|
||||
|
||||
public final IIndexFileSet getIncludedFiles() {
|
||||
return fTu == null ? IIndexFileSet.EMPTY : fTu.getIndexFileSet();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2023 Igor V. Kovalenko.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Igor V. Kovalenko - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.dom.ast.cpp;
|
||||
|
||||
/**
|
||||
* Deduction guide, introduced in C++17.
|
||||
*
|
||||
* @since 8.1
|
||||
* @noextend This interface is not intended to be extended by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
*/
|
||||
|
||||
public interface ICPPASTDeductionGuide extends ICPPASTFunctionDeclarator {
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2023 Igor V. Kovalenko.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Igor V. Kovalenko - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.dom.ast.cpp;
|
||||
|
||||
/**
|
||||
* Marker for deduction guide synthesized from class constructor
|
||||
*
|
||||
* @since 8.1
|
||||
* @noextend This interface is not intended to be extended by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
*/
|
||||
public interface ICPPClassConstructorDeductionGuide {
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2023 Igor V. Kovalenko.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Igor V. Kovalenko - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.dom.ast.cpp;
|
||||
|
||||
/**
|
||||
* Marker for deduction guide synthesized from class constructor template
|
||||
*
|
||||
* @since 8.1
|
||||
* @noextend This interface is not intended to be extended by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
*/
|
||||
public interface ICPPClassConstructorTemplateDeductionGuide {
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2023 Igor V. Kovalenko.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Igor V. Kovalenko - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.dom.ast.cpp;
|
||||
|
||||
/**
|
||||
* Marker for copy deduction candidate used with Class Template Argument Deduction, introduced in C++17.
|
||||
*
|
||||
* @since 8.1
|
||||
* @noextend This interface is not intended to be extended by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
*/
|
||||
public interface ICPPCopyDeductionCandidate {
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2023 Igor V. Kovalenko.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Igor V. Kovalenko - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.dom.ast.cpp;
|
||||
|
||||
/**
|
||||
* Deduction guide, introduced in C++17.
|
||||
*
|
||||
* @since 8.1
|
||||
* @noextend This interface is not intended to be extended by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
*/
|
||||
public interface ICPPDeductionGuide extends ICPPBinding {
|
||||
public static final ICPPDeductionGuide[] EMPTY_BINDING_ARRAY = {};
|
||||
|
||||
public ICPPFunction getFunctionBinding();
|
||||
}
|
|
@ -253,6 +253,11 @@ public interface ICPPNodeFactory extends INodeFactory {
|
|||
public ICPPASTFoldExpression newFoldExpression(int opToken, boolean isComma, IASTExpression lhs,
|
||||
IASTExpression rhs);
|
||||
|
||||
/**
|
||||
* @since 8.1
|
||||
*/
|
||||
public ICPPASTDeductionGuide newDeductionGuide();
|
||||
|
||||
public ICPPASTLinkageSpecification newLinkageSpecification(String literal);
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2023 Igor V. Kovalenko.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Igor V. Kovalenko - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.dom.ast.cpp;
|
||||
|
||||
/**
|
||||
* Marker for user-defined deduction guide for Class Template Argument Deduction, introduced in C++17.
|
||||
*
|
||||
* @since 8.1
|
||||
* @noextend This interface is not intended to be extended by clients.
|
||||
* @noimplement This interface is not intended to be implemented by clients.
|
||||
*/
|
||||
public interface ICPPUserDefinedDeductionGuide {
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2023 Igor V. Kovalenko.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Igor V. Kovalenko - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeductionGuide;
|
||||
|
||||
/**
|
||||
* Implementation for deduction guide.
|
||||
*/
|
||||
public class CPPASTDeductionGuide extends CPPASTFunctionDeclarator implements ICPPASTDeductionGuide {
|
||||
public CPPASTDeductionGuide() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CPPASTDeductionGuide copy() {
|
||||
return copy(CopyStyle.withoutLocations);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CPPASTDeductionGuide copy(CopyStyle style) {
|
||||
CPPASTDeductionGuide copy = new CPPASTDeductionGuide();
|
||||
return super.copy(copy, style);
|
||||
}
|
||||
}
|
|
@ -73,13 +73,17 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS
|
|||
@Override
|
||||
public CPPASTFunctionDeclarator copy(CopyStyle style) {
|
||||
CPPASTFunctionDeclarator copy = new CPPASTFunctionDeclarator();
|
||||
copy.varArgs = varArgs;
|
||||
copy.pureVirtual = pureVirtual;
|
||||
copy.isVolatile = isVolatile;
|
||||
copy.isConst = isConst;
|
||||
copy.isMutable = isMutable;
|
||||
copy.refQualifier = refQualifier;
|
||||
copy.isConstexpr = isConstexpr;
|
||||
return copy(copy, style);
|
||||
}
|
||||
|
||||
protected <T extends CPPASTFunctionDeclarator> T copy(T copy, CopyStyle style) {
|
||||
copy.setVarArgs(varArgs);
|
||||
copy.setPureVirtual(pureVirtual);
|
||||
copy.setVolatile(isVolatile);
|
||||
copy.setConst(isConst);
|
||||
copy.setMutable(isMutable);
|
||||
copy.setRefQualifier(refQualifier);
|
||||
copy.setConstexpr(isConstexpr);
|
||||
|
||||
for (IASTParameterDeclaration param : getParameters()) {
|
||||
copy.addParameterDeclaration(param == null ? null : param.copy(style));
|
||||
|
@ -97,7 +101,7 @@ public class CPPASTFunctionDeclarator extends CPPASTDeclarator implements ICPPAS
|
|||
for (ICPPASTVirtSpecifier virtSpecifier : getVirtSpecifiers()) {
|
||||
copy.addVirtSpecifier(virtSpecifier.copy(style));
|
||||
}
|
||||
return copy(copy, style);
|
||||
return super.copy(copy, style);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2023 Igor V. Kovalenko.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Igor V. Kovalenko - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ILinkage;
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||
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.ICPPDeductionGuide;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
||||
import org.eclipse.core.runtime.PlatformObject;
|
||||
|
||||
/**
|
||||
* Represents c++17 deduction guide.
|
||||
*/
|
||||
public class CPPDeductionGuide extends PlatformObject implements ICPPDeductionGuide {
|
||||
protected IASTDeclarator definition;
|
||||
protected ICPPFunction functionBinding;
|
||||
|
||||
public CPPDeductionGuide(IASTDeclarator fnDecl, ICPPFunction functionBinding) {
|
||||
this.definition = fnDecl;
|
||||
this.functionBinding = functionBinding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICPPFunction getFunctionBinding() {
|
||||
return functionBinding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getQualifiedName() throws DOMException {
|
||||
return functionBinding.getQualifiedName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[][] getQualifiedNameCharArray() throws DOMException {
|
||||
return functionBinding.getQualifiedNameCharArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGloballyQualified() throws DOMException {
|
||||
return functionBinding.isGloballyQualified();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return functionBinding.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] getNameCharArray() {
|
||||
return functionBinding.getNameCharArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ILinkage getLinkage() {
|
||||
return functionBinding.getLinkage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinding getOwner() {
|
||||
return functionBinding.getOwner();
|
||||
}
|
||||
|
||||
protected IASTName getASTName() {
|
||||
return definition.getName().getLastName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IScope getScope() throws DOMException {
|
||||
return CPPVisitor.getContainingScope(getASTName());
|
||||
}
|
||||
}
|
|
@ -77,6 +77,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
|
|||
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.ICPPASTDecltypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeductionGuide;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDesignatedInitializer;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
|
||||
|
@ -577,6 +578,11 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
|
|||
return new CPPASTFoldExpression(operator, fIsComma, lhs, rhs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICPPASTDeductionGuide newDeductionGuide() {
|
||||
return new CPPASTDeductionGuide();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICPPASTLinkageSpecification newLinkageSpecification(String literal) {
|
||||
return new CPPASTLinkageSpecification(literal);
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
|
|||
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.ICPPClassScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPDeductionGuide;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
|
||||
|
@ -226,6 +227,12 @@ abstract public class CPPScope implements ICPPASTInternalScope {
|
|||
CCorePlugin.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
// Deduction guides are not visible to ordinary name lookup
|
||||
if (result.length > 0) {
|
||||
result = ArrayUtil.filter(result, lookup.isDeductionGuidesOnly() ? CPPSemantics.opIsDeductionGuide
|
||||
: CPPSemantics.opIsNotDeductionGuide);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -313,6 +320,11 @@ abstract public class CPPScope implements ICPPASTInternalScope {
|
|||
binding = (IBinding) candidate;
|
||||
}
|
||||
|
||||
// Deduction guides are not visible to ordinary name lookup
|
||||
if (lookup.isDeductionGuidesOnly() ^ binding instanceof ICPPDeductionGuide) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (binding != null)
|
||||
result = ArrayUtil.append(result, binding);
|
||||
return result;
|
||||
|
|
|
@ -94,6 +94,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
|
|||
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.ICPPASTDecltypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeductionGuide;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDesignatedInitializer;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDesignator;
|
||||
|
@ -2443,7 +2444,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
}
|
||||
|
||||
if (LT(1) == IToken.tLPAREN) {
|
||||
ICPPASTFunctionDeclarator dtor = functionDeclarator(true);
|
||||
ICPPASTFunctionDeclarator dtor = functionDeclarator((IASTName) null, (IASTDeclSpecifier) null, true);
|
||||
lambdaExpr.setDeclarator(dtor);
|
||||
if (LT(1) == IToken.tEOC)
|
||||
return setRange(lambdaExpr, offset, calculateEndOffset(dtor));
|
||||
|
@ -4292,7 +4293,10 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
private void verifyDtor(IASTDeclSpecifier declspec, IASTDeclarator dtor, DeclarationOptions opt)
|
||||
throws BacktrackException {
|
||||
if (CPPVisitor.doesNotSpecifyType(declspec)) {
|
||||
if (ASTQueries.findTypeRelevantDeclarator(dtor) instanceof IASTFunctionDeclarator) {
|
||||
if (ASTQueries.findTypeRelevantDeclarator(dtor) instanceof IASTFunctionDeclarator typeRelevantDtor) {
|
||||
if (typeRelevantDtor instanceof ICPPASTDeductionGuide) {
|
||||
return;
|
||||
}
|
||||
boolean isQualified = false;
|
||||
IASTName name = ASTQueries.findInnermostDeclarator(dtor).getName();
|
||||
if (name instanceof ICPPASTQualifiedName) {
|
||||
|
@ -4373,7 +4377,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
*/
|
||||
private IASTDeclarator initDeclarator(DtorStrategy strategy, IASTDeclSpecifier declspec, DeclarationOptions option)
|
||||
throws EndOfFileException, BacktrackException, FoundAggregateInitializer {
|
||||
final IASTDeclarator dtor = declarator(strategy, option);
|
||||
final IASTDeclarator dtor = declarator(strategy, declspec, option);
|
||||
if (option.fAllowInitializer) {
|
||||
final IASTDeclarator typeRelevantDtor = ASTQueries.findTypeRelevantDeclarator(dtor);
|
||||
if (option != DeclarationOptions.PARAMETER && typeRelevantDtor instanceof IASTFunctionDeclarator) {
|
||||
|
@ -4767,7 +4771,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
* @throws BacktrackException
|
||||
* request a backtrack
|
||||
*/
|
||||
protected IASTDeclarator declarator(DtorStrategy strategy, DeclarationOptions option)
|
||||
protected IASTDeclarator declarator(DtorStrategy strategy, IASTDeclSpecifier declspec, DeclarationOptions option)
|
||||
throws EndOfFileException, BacktrackException {
|
||||
final int startingOffset = LA(1).getOffset();
|
||||
int endOffset = startingOffset;
|
||||
|
@ -4810,7 +4814,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
final IASTName declaratorName = !option.fRequireSimpleName ? qualifiedName() : identifier();
|
||||
endOffset = calculateEndOffset(declaratorName);
|
||||
return declarator(pointerOps, hasEllipsis, declaratorName, null, startingOffset, endOffset, strategy,
|
||||
option, attributes);
|
||||
declspec, option, attributes);
|
||||
}
|
||||
|
||||
if (lt1 == IToken.tLPAREN) {
|
||||
|
@ -4821,7 +4825,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
final IToken mark = mark();
|
||||
try {
|
||||
cand1 = declarator(pointerOps, hasEllipsis, getNodeFactory().newName(), null, startingOffset,
|
||||
endOffset, strategy, option, attributes);
|
||||
endOffset, strategy, declspec, option, attributes);
|
||||
if (option.fRequireAbstract || !option.fAllowNested || hasEllipsis)
|
||||
return cand1;
|
||||
|
||||
|
@ -4835,7 +4839,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
if (!option.fAllowNested || hasEllipsis) {
|
||||
if (option.fAllowAbstract) {
|
||||
return declarator(pointerOps, hasEllipsis, getNodeFactory().newName(), null, startingOffset,
|
||||
endOffset, strategy, option, attributes);
|
||||
endOffset, strategy, declspec, option, attributes);
|
||||
}
|
||||
throwBacktrack(LA(1));
|
||||
}
|
||||
|
@ -4846,10 +4850,10 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
if (LT(1) == IToken.tRPAREN)
|
||||
throwBacktrack(LA(1));
|
||||
|
||||
final IASTDeclarator nested = declarator(DtorStrategy.PREFER_FUNCTION, option);
|
||||
final IASTDeclarator nested = declarator(DtorStrategy.PREFER_FUNCTION, declspec, option);
|
||||
endOffset = consume(IToken.tRPAREN).getEndOffset();
|
||||
final IASTDeclarator cand2 = declarator(pointerOps, hasEllipsis, getNodeFactory().newName(), nested,
|
||||
startingOffset, endOffset, strategy, option, attributes);
|
||||
startingOffset, endOffset, strategy, declspec, option, attributes);
|
||||
if (cand1 == null || cand1End == null)
|
||||
return cand2;
|
||||
final IToken cand2End = LA(1);
|
||||
|
@ -4877,7 +4881,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
throwBacktrack(LA(1));
|
||||
}
|
||||
return declarator(pointerOps, hasEllipsis, getNodeFactory().newName(), null, startingOffset, endOffset,
|
||||
strategy, option, attributes);
|
||||
strategy, declspec, option, attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -5000,15 +5004,15 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
|
||||
private IASTDeclarator declarator(List<? extends IASTPointerOperator> pointerOps, boolean hasEllipsis,
|
||||
IASTName declaratorName, IASTDeclarator nestedDeclarator, int startingOffset, int endOffset,
|
||||
DtorStrategy strategy, DeclarationOptions option, List<IASTAttributeSpecifier> attributes)
|
||||
throws EndOfFileException, BacktrackException {
|
||||
DtorStrategy strategy, IASTDeclSpecifier declspec, DeclarationOptions option,
|
||||
List<IASTAttributeSpecifier> attributes) throws EndOfFileException, BacktrackException {
|
||||
ICPPASTDeclarator result = null;
|
||||
loop: while (true) {
|
||||
final int lt1 = LTcatchEOF(1);
|
||||
switch (lt1) {
|
||||
case IToken.tLPAREN:
|
||||
if (option.fAllowFunctions && strategy == DtorStrategy.PREFER_FUNCTION) {
|
||||
result = functionDeclarator(false);
|
||||
result = functionDeclarator(declaratorName, declspec, false);
|
||||
setDeclaratorID(result, hasEllipsis, declaratorName, nestedDeclarator);
|
||||
}
|
||||
break loop;
|
||||
|
@ -5086,16 +5090,47 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
declarator.setDeclaresParameterPack(hasEllipsis);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a function declarator or a deduction guide, starting with the left parenthesis.
|
||||
*/
|
||||
private ICPPASTFunctionDeclarator functionDeclarator(IASTName declaratorName, IASTDeclSpecifier declspec,
|
||||
boolean isLambdaDeclarator) throws EndOfFileException, BacktrackException {
|
||||
final IToken mark = mark();
|
||||
|
||||
ICPPASTFunctionDeclarator fc = getNodeFactory().newFunctionDeclarator(null);
|
||||
functionDeclarator(fc, isLambdaDeclarator);
|
||||
|
||||
// Test if this is a deduction guide and retry with correct object type
|
||||
final IASTTypeId typeId = fc.getTrailingReturnType();
|
||||
if (!isLambdaDeclarator && typeId != null && CPPVisitor.doesNotSpecifyType(declspec) && declaratorName != null
|
||||
&& typeId.getDeclSpecifier() instanceof IASTNamedTypeSpecifier namedTypeSpec
|
||||
&& namedTypeSpec.getName() instanceof ICPPASTTemplateId templateId) {
|
||||
|
||||
if (CharArrayUtils.equals(templateId.getTemplateName().getLookupKey(), declaratorName.getLookupKey())) {
|
||||
if (declspec instanceof ICPPASTSimpleDeclSpecifier simpleDeclSpecifier) {
|
||||
// TODO: This enables auto type resolution from return type, validate implementation in CreateType()
|
||||
simpleDeclSpecifier.setType(IASTSimpleDeclSpecifier.t_auto);
|
||||
}
|
||||
|
||||
backup(mark);
|
||||
|
||||
fc = getNodeFactory().newDeductionGuide();
|
||||
functionDeclarator(fc, isLambdaDeclarator);
|
||||
}
|
||||
}
|
||||
|
||||
return fc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a function declarator starting with the left parenthesis.
|
||||
*/
|
||||
private ICPPASTFunctionDeclarator functionDeclarator(boolean isLambdaDeclarator)
|
||||
private void functionDeclarator(final ICPPASTFunctionDeclarator fc, boolean isLambdaDeclarator)
|
||||
throws EndOfFileException, BacktrackException {
|
||||
IToken last = consume(IToken.tLPAREN);
|
||||
final int startOffset = last.getOffset();
|
||||
int endOffset = last.getEndOffset();
|
||||
|
||||
final ICPPASTFunctionDeclarator fc = getNodeFactory().newFunctionDeclarator(null);
|
||||
ICPPASTParameterDeclaration pd = null;
|
||||
paramLoop: while (true) {
|
||||
switch (LT(1)) {
|
||||
|
@ -5245,7 +5280,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
|
|||
endOffset = calculateEndOffset(typeId);
|
||||
}
|
||||
|
||||
return setRange(fc, startOffset, endOffset);
|
||||
setRange(fc, startOffset, endOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -157,12 +157,16 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTWhileStatement;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPAliasTemplate;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBlockScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassConstructorDeductionGuide;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassConstructorTemplateDeductionGuide;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
|
||||
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.ICPPClassType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPCopyDeductionCandidate;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPDeductionGuide;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPDeferredFunction;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||
|
@ -188,6 +192,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUserDefinedDeductionGuide;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
|
||||
|
@ -224,10 +229,14 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBuiltinParameter;
|
|||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPCompositeBinding;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredConstructor;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredFunction;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionTemplate;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitConstructor;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitFunction;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPNamespace;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPNamespaceScope;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPParameter;
|
||||
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.CPPScope;
|
||||
|
@ -274,6 +283,13 @@ public class CPPSemantics {
|
|||
private static final char[] CALL_FUNCTION = "call-function".toCharArray(); //$NON-NLS-1$
|
||||
private static final ICPPEvaluation[] NO_INITCLAUSE_EVALUATION = {};
|
||||
|
||||
public static final IUnaryPredicate<IBinding> opIsDeductionGuide = (argument) -> {
|
||||
return argument instanceof ICPPDeductionGuide;
|
||||
};
|
||||
public static final IUnaryPredicate<IBinding> opIsNotDeductionGuide = (argument) -> {
|
||||
return !(argument instanceof ICPPDeductionGuide);
|
||||
};
|
||||
|
||||
// Set to true for debugging.
|
||||
public static boolean traceBindingResolution = false;
|
||||
public static int traceIndent = 0;
|
||||
|
@ -399,6 +415,289 @@ public class CPPSemantics {
|
|||
return postResolution(binding, data);
|
||||
}
|
||||
|
||||
private static IBinding doClassTemplateArgumentDeduction(ICPPClassTemplate classTemplate, LookupData data) {
|
||||
// Implementation common to all candidate function non-templates
|
||||
class CTADDeductionCandidateProbeFunction extends CPPFunction {
|
||||
ICPPFunction method;
|
||||
ICPPFunctionType functionType;
|
||||
|
||||
public CTADDeductionCandidateProbeFunction(ICPPFunction method) {
|
||||
super(null);
|
||||
this.method = method;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] getNameCharArray() {
|
||||
return method.getNameCharArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICPPFunctionType getType() {
|
||||
if (functionType == null) {
|
||||
ICPPFunctionType ft = method.getType();
|
||||
functionType = new CPPFunctionType(ft.getReturnType(), ft.getParameterTypes(),
|
||||
ft.getNoexceptSpecifier(), ft.isConst(), ft.isVolatile(), ft.hasRefQualifier(),
|
||||
ft.isRValueReference(), ft.takesVarArgs());
|
||||
}
|
||||
|
||||
return functionType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IType[] getExceptionSpecification() {
|
||||
return method.getExceptionSpecification();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICPPParameter[] getParameters() {
|
||||
return method.getParameters();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean takesVarArgs() {
|
||||
return method.takesVarArgs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasParameterPack() {
|
||||
return method.hasParameterPack();
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation common to all candidate function templates
|
||||
class CTADDeductionCandidateProbeFunctionTemplate extends CPPFunctionTemplate {
|
||||
ICPPClassTemplate classTemplate;
|
||||
ICPPFunction method;
|
||||
boolean isClassConstructor;
|
||||
private ICPPTemplateParameter[] deductionTemplateParameters;
|
||||
ICPPFunctionType functionType;
|
||||
|
||||
private final void resetCachedValues() {
|
||||
deductionTemplateParameters = null;
|
||||
functionType = null;
|
||||
}
|
||||
|
||||
public CTADDeductionCandidateProbeFunctionTemplate(ICPPClassTemplate classTemplate) {
|
||||
super(null);
|
||||
this.classTemplate = classTemplate;
|
||||
}
|
||||
|
||||
public CTADDeductionCandidateProbeFunctionTemplate(ICPPClassTemplate classTemplate, ICPPFunction method,
|
||||
boolean isClassConstructor) {
|
||||
this(classTemplate);
|
||||
setMethod(method);
|
||||
setIsClassConstructor(isClassConstructor);
|
||||
}
|
||||
|
||||
protected void setMethod(ICPPFunction method) {
|
||||
this.method = method;
|
||||
resetCachedValues(); // Force recalculation of type and template args
|
||||
}
|
||||
|
||||
protected void setIsClassConstructor(boolean isClassConstructor) {
|
||||
this.isClassConstructor = isClassConstructor;
|
||||
resetCachedValues(); // Force recalculation of type and template args
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] getNameCharArray() {
|
||||
return method.getNameCharArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICPPFunctionType getType() {
|
||||
if (functionType == null) {
|
||||
ICPPFunctionType ft = method.getType();
|
||||
IType returnType;
|
||||
if (isClassConstructor) {
|
||||
returnType = (ICPPClassType) classTemplate.asDeferredInstance();
|
||||
} else {
|
||||
returnType = ft.getReturnType();
|
||||
}
|
||||
functionType = new CPPFunctionType(returnType, ft.getParameterTypes(), ft.getNoexceptSpecifier(),
|
||||
ft.isConst(), ft.isVolatile(), ft.hasRefQualifier(), ft.isRValueReference(),
|
||||
ft.takesVarArgs());
|
||||
}
|
||||
|
||||
return functionType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IType[] getExceptionSpecification() {
|
||||
//return method.getExceptionSpecification();
|
||||
// TODO: this requires class owner; see if exception specification is required to implement CTAD
|
||||
return IType.EMPTY_TYPE_ARRAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICPPParameter[] getParameters() {
|
||||
return method.getParameters();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean takesVarArgs() {
|
||||
return method.takesVarArgs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasParameterPack() {
|
||||
return method.hasParameterPack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICPPTemplateParameter[] getTemplateParameters() {
|
||||
// TODO: make sure template parameter identifiers are consistent with where parameters are coming from
|
||||
// Maybe need to re-instantiate all of them?
|
||||
if (deductionTemplateParameters == null) {
|
||||
ICPPTemplateParameter[] candParams = ICPPTemplateParameter.EMPTY_TEMPLATE_PARAMETER_ARRAY;
|
||||
if (isClassConstructor) {
|
||||
candParams = ArrayUtil.addAll(candParams, classTemplate.getTemplateParameters());
|
||||
}
|
||||
if (method instanceof ICPPTemplateDefinition ctorTemplate) {
|
||||
candParams = ArrayUtil.addAll(candParams, ctorTemplate.getTemplateParameters());
|
||||
}
|
||||
deductionTemplateParameters = ArrayUtil.trim(candParams);
|
||||
}
|
||||
return deductionTemplateParameters;
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation for candidate function synthesized from constructor non-template
|
||||
class CTADGuideFromConstructor extends CTADDeductionCandidateProbeFunctionTemplate
|
||||
implements ICPPClassConstructorDeductionGuide {
|
||||
|
||||
public CTADGuideFromConstructor(ICPPClassTemplate classTemplate, ICPPFunction method) {
|
||||
super(classTemplate, method, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation for candidate function synthesized from constructor template
|
||||
class CTADGuideFromConstructorTemplate extends CTADDeductionCandidateProbeFunctionTemplate
|
||||
implements ICPPClassConstructorTemplateDeductionGuide {
|
||||
|
||||
public CTADGuideFromConstructorTemplate(ICPPClassTemplate classTemplate, ICPPFunction method) {
|
||||
super(classTemplate, method, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation for candidate function from user-defined template deduction guide
|
||||
class CTADUserDefinedGuideTemplate extends CTADDeductionCandidateProbeFunctionTemplate
|
||||
implements ICPPUserDefinedDeductionGuide {
|
||||
|
||||
public CTADUserDefinedGuideTemplate(ICPPClassTemplate classTemplate, ICPPTemplateDefinition method) {
|
||||
super(classTemplate, (ICPPFunction) method, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation for candidate function from user-defined non-template deduction guide
|
||||
class CTADUserDefinedGuide extends CTADDeductionCandidateProbeFunction
|
||||
implements ICPPUserDefinedDeductionGuide {
|
||||
|
||||
public CTADUserDefinedGuide(ICPPFunction method) {
|
||||
super(method);
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation for "copy deduction candidate" synthesized from hypothetical constructor C(C)
|
||||
class CTADCopyDeductionCandidate extends CTADDeductionCandidateProbeFunctionTemplate
|
||||
implements ICPPCopyDeductionCandidate {
|
||||
|
||||
public CTADCopyDeductionCandidate(ICPPClassTemplate classTemplate) {
|
||||
super(classTemplate);
|
||||
|
||||
char[] className = classTemplate.getNameCharArray();
|
||||
|
||||
ICPPParameter[] copyDeductionCandidateParams = new ICPPParameter[] {
|
||||
new CPPParameter((ICPPClassType) classTemplate.asDeferredInstance(), 0) };
|
||||
ICPPMethod copyDeductionCandidate = new CPPImplicitConstructor(
|
||||
(ICPPClassScope) classTemplate.getCompositeScope(), className, copyDeductionCandidateParams,
|
||||
null);
|
||||
|
||||
setMethod(copyDeductionCandidate);
|
||||
setIsClassConstructor(true);
|
||||
}
|
||||
}
|
||||
|
||||
final IASTName lookupName = data.getLookupName();
|
||||
if (lookupName == null)
|
||||
return classTemplate;
|
||||
|
||||
char[] className = lookupName.getLookupKey();
|
||||
|
||||
ICPPConstructor[] ctors = classTemplate.getConstructors();
|
||||
|
||||
ICPPFunction[] deductionGuideCandidateFunctions = new ICPPFunction[ctors.length + 1];
|
||||
|
||||
if (ctors.length > 0) {
|
||||
// Add template probe functions synthesized from class constructors
|
||||
for (ICPPConstructor ctor : ctors) {
|
||||
if (ctor instanceof ICPPTemplateDefinition ctorTemplate) {
|
||||
deductionGuideCandidateFunctions = ArrayUtil.append(deductionGuideCandidateFunctions,
|
||||
new CTADGuideFromConstructorTemplate(classTemplate, ctor));
|
||||
} else {
|
||||
deductionGuideCandidateFunctions = ArrayUtil.append(deductionGuideCandidateFunctions,
|
||||
new CTADGuideFromConstructor(classTemplate, ctor));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If class is not defined or does not declare any constructors, add hypothetical constructor C()
|
||||
ICPPMethod defaultConstructor = new CPPImplicitConstructor(
|
||||
(ICPPClassScope) classTemplate.getCompositeScope(), className,
|
||||
ICPPParameter.EMPTY_CPPPARAMETER_ARRAY, null);
|
||||
|
||||
deductionGuideCandidateFunctions = ArrayUtil.append(deductionGuideCandidateFunctions,
|
||||
new CTADDeductionCandidateProbeFunctionTemplate(classTemplate, defaultConstructor, true));
|
||||
}
|
||||
|
||||
deductionGuideCandidateFunctions = ArrayUtil.append(deductionGuideCandidateFunctions,
|
||||
new CTADCopyDeductionCandidate(classTemplate));
|
||||
|
||||
// Add user-defined deduction guides
|
||||
try {
|
||||
// TODO: add support for lookup in containing class scope of classTemplate
|
||||
IScope lookupScope = getContainingNamespaceScope(classTemplate, data.getTranslationUnit());
|
||||
|
||||
if (lookupScope instanceof ICPPASTInternalScope internalScope) {
|
||||
|
||||
LookupData guideLookupData = new LookupData(className, null, lookupName);
|
||||
guideLookupData.setDeductionGuidesOnly(true);
|
||||
|
||||
IBinding[] bindings = getBindingsFromScope(internalScope, guideLookupData);
|
||||
|
||||
for (IBinding binding : bindings) {
|
||||
if (binding instanceof ICPPDeductionGuide guide) {
|
||||
IBinding guideBinding = guide.getFunctionBinding();
|
||||
|
||||
if (guideBinding instanceof ICPPTemplateDefinition guideFunctionTemplate) {
|
||||
deductionGuideCandidateFunctions = ArrayUtil.append(deductionGuideCandidateFunctions,
|
||||
new CTADUserDefinedGuideTemplate(classTemplate, guideFunctionTemplate));
|
||||
} else if (guideBinding instanceof ICPPFunction guideFunction) {
|
||||
deductionGuideCandidateFunctions = ArrayUtil.append(deductionGuideCandidateFunctions,
|
||||
new CTADUserDefinedGuide(guideFunction));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (DOMException e) {
|
||||
}
|
||||
|
||||
// Perform overload resolution for initializer clause.
|
||||
// Deduced class type is the return type of the function selected by overload resolution.
|
||||
try {
|
||||
IBinding resolved = resolveFunction(data, deductionGuideCandidateFunctions, true, false);
|
||||
|
||||
if (resolved instanceof ICPPFunction selected) {
|
||||
if (selected.getType().getReturnType() instanceof IBinding binding) {
|
||||
return binding;
|
||||
}
|
||||
}
|
||||
} catch (DOMException e) {
|
||||
}
|
||||
|
||||
// Not deduced
|
||||
return null;
|
||||
}
|
||||
|
||||
private static IBinding postResolution(IBinding binding, LookupData data) {
|
||||
final IASTName lookupName = data.getLookupName();
|
||||
if (lookupName == null)
|
||||
|
@ -468,17 +767,61 @@ public class CPPSemantics {
|
|||
*/
|
||||
if (binding instanceof ICPPClassTemplate && !(binding instanceof ICPPClassSpecialization)
|
||||
&& !(binding instanceof ICPPTemplateParameter) && !(lookupName instanceof ICPPASTTemplateId)) {
|
||||
|
||||
ASTNodeProperty prop = lookupName.getPropertyInParent();
|
||||
if (prop != ICPPASTTemplateId.TEMPLATE_NAME && !lookupName.isQualified()) {
|
||||
if (prop != ICPPASTTemplateId.TEMPLATE_NAME) {
|
||||
if (!lookupName.isQualified()) {
|
||||
// You cannot use a class template name outside of the class template scope,
|
||||
// mark it as a problem.
|
||||
// mark it as a problem - unless Class Template Argument Deduction needs to be done
|
||||
IBinding user = CPPTemplates.isUsedInClassTemplateScope((ICPPClassTemplate) binding, lookupName);
|
||||
if (user instanceof ICPPClassTemplate) {
|
||||
binding = ((ICPPClassTemplate) user).asDeferredInstance();
|
||||
} else if (user != null) {
|
||||
binding = user;
|
||||
} else {
|
||||
// Attempt class template argument deduction if appropriate
|
||||
if (data.getTranslationUnit().getEnableClassTemplateArgumentDeduction()) {
|
||||
if (lookupName.getParent() instanceof IASTIdExpression idExpression
|
||||
&& idExpression.getPropertyInParent() == IASTFunctionCallExpression.FUNCTION_NAME) {
|
||||
|
||||
// Class name for class type argument deduction is a type
|
||||
return doClassTemplateArgumentDeduction((ICPPClassTemplate) binding, data);
|
||||
}
|
||||
}
|
||||
boolean ok = false;
|
||||
// Attempt class template argument deduction if appropriate
|
||||
if (data.getTranslationUnit().getEnableClassTemplateArgumentDeduction()
|
||||
&& lookupName.getParent() instanceof IASTNamedTypeSpecifier namedTypeSpecifier
|
||||
&& namedTypeSpecifier.getPropertyInParent() == IASTSimpleDeclaration.DECL_SPECIFIER
|
||||
&& namedTypeSpecifier.getParent() instanceof IASTSimpleDeclaration declaration) {
|
||||
|
||||
IASTDeclarator[] declarators = declaration.getDeclarators();
|
||||
if (declarators != null && declarators.length > 0) {
|
||||
IASTDeclarator declarator = declarators[0];
|
||||
|
||||
// Cannot deduce pointer or reference class template argument
|
||||
if (declarator.getPointerOperators().length == 0) {
|
||||
// Class name for class type argument deduction is a type
|
||||
ICPPASTInitializerClause initializerClause = CPPVisitor
|
||||
.getAutoInitClauseForDeclarator(declarator);
|
||||
if (initializerClause != null) {
|
||||
data.setFunctionArguments(false,
|
||||
new ICPPASTInitializerClause[] { initializerClause });
|
||||
} else {
|
||||
data.setFunctionArguments(false, NO_INITCLAUSE_EVALUATION);
|
||||
}
|
||||
IBinding b = doClassTemplateArgumentDeduction((ICPPClassTemplate) binding, data);
|
||||
|
||||
if (b != null) {
|
||||
// Deduced class template arguments
|
||||
binding = b;
|
||||
// No need to check other cases
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IASTNode node = lookupName.getParent();
|
||||
while (node != null && !ok) {
|
||||
if (node instanceof ICPPASTTemplateId
|
||||
|
@ -504,6 +847,41 @@ public class CPPSemantics {
|
|||
data.getFoundBindings());
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
// Name is qualified-name
|
||||
// Attempt class template argument deduction if appropriate
|
||||
if (data.getTranslationUnit().getEnableClassTemplateArgumentDeduction()
|
||||
&& lookupName.getParent() instanceof ICPPASTQualifiedName qualifiedName
|
||||
&& qualifiedName.getParent() instanceof IASTNamedTypeSpecifier namedTypeSpecifier
|
||||
&& namedTypeSpecifier.getPropertyInParent() == IASTSimpleDeclaration.DECL_SPECIFIER
|
||||
&& namedTypeSpecifier.getParent() instanceof IASTSimpleDeclaration declaration) {
|
||||
|
||||
IASTDeclarator[] declarators = declaration.getDeclarators();
|
||||
if (declarators != null && declarators.length > 0) {
|
||||
IASTDeclarator declarator = declarators[0];
|
||||
|
||||
// Cannot deduce pointer or reference class template argument
|
||||
if (declarator.getPointerOperators().length == 0) {
|
||||
// Class name for class type argument deduction is a type
|
||||
ICPPASTInitializerClause initializerClause = CPPVisitor
|
||||
.getAutoInitClauseForDeclarator(declarator);
|
||||
if (initializerClause != null) {
|
||||
data.setFunctionArguments(false,
|
||||
new ICPPASTInitializerClause[] { initializerClause });
|
||||
} else {
|
||||
data.setFunctionArguments(false, NO_INITCLAUSE_EVALUATION);
|
||||
}
|
||||
IBinding b = doClassTemplateArgumentDeduction((ICPPClassTemplate) binding, data);
|
||||
|
||||
if (b != null) {
|
||||
// Deduced class template arguments
|
||||
binding = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (binding instanceof ICPPDeferredClassInstance) {
|
||||
// Try to replace binding by the one pointing to the enclosing template declaration.
|
||||
|
@ -1442,6 +1820,12 @@ public class CPPSemantics {
|
|||
});
|
||||
}
|
||||
|
||||
// Deduction guides are not visible to ordinary name lookup
|
||||
if (bindings.length > 0) {
|
||||
bindings = ArrayUtil.filter(bindings,
|
||||
data.isDeductionGuidesOnly() ? opIsDeductionGuide : opIsNotDeductionGuide);
|
||||
}
|
||||
|
||||
return expandUsingDeclarationsAndRemoveObjects(bindings, data);
|
||||
}
|
||||
|
||||
|
@ -1863,8 +2247,9 @@ public class CPPSemantics {
|
|||
declarator = declarator.getNestedDeclarator();
|
||||
}
|
||||
if (innermost != null) {
|
||||
IASTName declaratorName = innermost.getName();
|
||||
ASTInternal.addName(scope, declaratorName);
|
||||
// NOTE This now may include deduction guides which are filtered later during lookup
|
||||
IASTName declaratorOrDeductionGuideName = innermost.getName();
|
||||
ASTInternal.addName(scope, declaratorOrDeductionGuideName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,6 +117,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
|
||||
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.ICPPASTDeductionGuide;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTEnumerationSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
|
||||
|
@ -212,6 +213,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassType;
|
|||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClosureType;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPConstructor;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPConstructorTemplate;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeductionGuide;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPEnumeration;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPEnumerator;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPField;
|
||||
|
@ -883,6 +885,7 @@ public class CPPVisitor extends ASTQueries {
|
|||
binding = scope.getBinding(name, forceResolve);
|
||||
}
|
||||
|
||||
boolean isDeductionGuide = false;
|
||||
boolean isFunction = false;
|
||||
if (parent instanceof ICPPASTFunctionDefinition) {
|
||||
isFunction = true;
|
||||
|
@ -908,6 +911,9 @@ public class CPPVisitor extends ASTQueries {
|
|||
binding = td;
|
||||
} else if (typeRelevantDtor instanceof IASTFunctionDeclarator) {
|
||||
// Function declaration via function declarator.
|
||||
if (typeRelevantDtor instanceof ICPPASTDeductionGuide) {
|
||||
isDeductionGuide = true;
|
||||
}
|
||||
isFunction = true;
|
||||
} else {
|
||||
// Looks like a variable declaration.
|
||||
|
@ -991,11 +997,17 @@ public class CPPVisitor extends ASTQueries {
|
|||
} else {
|
||||
binding = template ? (ICPPFunction) new CPPFunctionTemplate(name) : new CPPFunction(typeRelevantDtor);
|
||||
}
|
||||
|
||||
if (isDeductionGuide) {
|
||||
binding = new CPPDeductionGuide(typeRelevantDtor, (ICPPFunction) binding);
|
||||
} else {
|
||||
binding = CPPSemantics.checkDeclSpecifier(binding, name, parent);
|
||||
|
||||
if (isFriendDecl && scope instanceof IASTInternalScope) {
|
||||
((IASTInternalScope) scope).addBinding(binding);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return binding;
|
||||
}
|
||||
|
@ -2473,7 +2485,7 @@ public class CPPVisitor extends ASTQueries {
|
|||
return autoInitClause;
|
||||
}
|
||||
|
||||
private static ICPPASTInitializerClause getAutoInitClauseForDeclarator(IASTDeclarator declarator) {
|
||||
protected static ICPPASTInitializerClause getAutoInitClauseForDeclarator(IASTDeclarator declarator) {
|
||||
IASTInitializer initClause = declarator.getInitializer();
|
||||
return getInitClauseForInitializer(initClause);
|
||||
}
|
||||
|
|
|
@ -28,12 +28,16 @@ import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
|||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IFunction;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassConstructorDeductionGuide;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassConstructorTemplateDeductionGuide;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPCopyDeductionCandidate;
|
||||
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.ICPPMethod;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUserDefinedDeductionGuide;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates.TypeSelection;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.DeferredUDC;
|
||||
|
@ -195,6 +199,10 @@ class FunctionCost {
|
|||
if (cmp != 0)
|
||||
return cmp;
|
||||
|
||||
cmp = compareAsDeductionGuides(f1, f2);
|
||||
if (cmp != 0)
|
||||
return cmp;
|
||||
|
||||
// At this point prefer non-index bindings
|
||||
return -CPPSemantics.compareByRelevance(tu, f1, f2);
|
||||
}
|
||||
|
@ -205,6 +213,43 @@ class FunctionCost {
|
|||
return 1;
|
||||
}
|
||||
|
||||
private int compareAsDeductionGuides(ICPPFunction f1, ICPPFunction f2) {
|
||||
ICPPFunction deductionCandidate = asTemplate(f1);
|
||||
if (deductionCandidate == null) {
|
||||
deductionCandidate = f1;
|
||||
}
|
||||
ICPPFunction otherDeductionCandidate = asTemplate(f2);
|
||||
if (otherDeductionCandidate == null) {
|
||||
otherDeductionCandidate = f2;
|
||||
}
|
||||
|
||||
// 16.3.3-1.12 F1 is generated from a deduction-guide and F2 is not
|
||||
final boolean isUserDefinedDeductionGuide = deductionCandidate instanceof ICPPUserDefinedDeductionGuide;
|
||||
final boolean otherUserDefinedDeductionGuide = otherDeductionCandidate instanceof ICPPUserDefinedDeductionGuide;
|
||||
|
||||
if (isUserDefinedDeductionGuide != otherUserDefinedDeductionGuide) {
|
||||
return isUserDefinedDeductionGuide ? -1 : 1;
|
||||
}
|
||||
|
||||
// 16.3.3-1.13 F1 is the copy deduction candidate and F2 is not
|
||||
final boolean isCopyDeductionCandidate = deductionCandidate instanceof ICPPCopyDeductionCandidate;
|
||||
final boolean otherCopyDeductionCandidate = otherDeductionCandidate instanceof ICPPCopyDeductionCandidate;
|
||||
|
||||
if (isCopyDeductionCandidate != otherCopyDeductionCandidate) {
|
||||
return isCopyDeductionCandidate ? -1 : 1;
|
||||
}
|
||||
|
||||
// 16.3.3-1.14 F1 is generated from a non-template constructor and F2 is generated from a constructor template
|
||||
final boolean isFromNonTemplateConstructor = deductionCandidate instanceof ICPPClassConstructorDeductionGuide;
|
||||
final boolean otherFromTemplateConstructor = otherDeductionCandidate instanceof ICPPClassConstructorTemplateDeductionGuide;
|
||||
|
||||
if (isFromNonTemplateConstructor && otherFromTemplateConstructor) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int overridesUsingDeclaration(ICPPFunction f1, ICPPFunction f2) {
|
||||
if (f1.takesVarArgs() != f2.takesVarArgs())
|
||||
return 0;
|
||||
|
|
|
@ -77,4 +77,6 @@ public interface IIndexCPPBindingConstants {
|
|||
int CPP_FIELD_TEMPLATE_PARTIAL_SPECIALIZATION = IIndexBindingConstants.LAST_CONSTANT + 60;
|
||||
int CPP_DEFERRED_VARIABLE_INSTANCE = IIndexBindingConstants.LAST_CONSTANT + 61;
|
||||
int CPP_ALIAS_TEMPLATE_SPECIALIZATION = IIndexBindingConstants.LAST_CONSTANT + 62;
|
||||
int CPP_DEDUCTION_GUIDE = IIndexBindingConstants.LAST_CONSTANT + 63;
|
||||
int CPP_DEDUCTION_GUIDE_TEMPLATE = IIndexBindingConstants.LAST_CONSTANT + 64;
|
||||
}
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecializationSpecialization;
|
||||
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.ICPPDeductionGuide;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumScope;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
|
||||
|
@ -753,6 +754,8 @@ public class CPPCompositesFactory extends AbstractCompositeFactory {
|
|||
return new CompositeCPPConstructorTemplate(this, (ICPPConstructor) binding);
|
||||
} else if (binding instanceof ICPPMethod) {
|
||||
return new CompositeCPPMethodTemplate(this, (ICPPMethod) binding);
|
||||
} else if (binding instanceof ICPPDeductionGuide guide) {
|
||||
return new CompositeCPPDeductionGuideTemplate(this, guide);
|
||||
} else if (binding instanceof ICPPFunctionTemplate) {
|
||||
return new CompositeCPPFunctionTemplate(this, (ICPPFunction) binding);
|
||||
} else if (binding instanceof ICPPAliasTemplate) {
|
||||
|
@ -810,6 +813,8 @@ public class CPPCompositesFactory extends AbstractCompositeFactory {
|
|||
} else if (binding instanceof ICPPEnumeration) {
|
||||
ICPPEnumeration def = (ICPPEnumeration) findOneBinding(binding);
|
||||
result = def == null ? null : new CompositeCPPEnumeration(this, def);
|
||||
} else if (binding instanceof ICPPDeductionGuide guide) {
|
||||
result = new CompositeCPPDeductionGuide(this, guide);
|
||||
} else if (binding instanceof ICPPFunction) {
|
||||
result = new CompositeCPPFunction(this, (ICPPFunction) binding);
|
||||
} else if (binding instanceof ICPPInternalEnumerator) {
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2023 Igor V. Kovalenko.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Igor V. Kovalenko - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.index.composite.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPDeductionGuide;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||
import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory;
|
||||
|
||||
public class CompositeCPPDeductionGuide extends CompositeCPPFunction implements ICPPDeductionGuide {
|
||||
public CompositeCPPDeductionGuide(ICompositesFactory cf, ICPPDeductionGuide rbinding) {
|
||||
super(cf, rbinding.getFunctionBinding());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICPPFunction getFunctionBinding() {
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2023 Igor V. Kovalenko.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Igor V. Kovalenko - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.index.composite.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPDeductionGuide;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||
import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory;
|
||||
|
||||
public class CompositeCPPDeductionGuideTemplate extends CompositeCPPFunctionTemplate implements ICPPDeductionGuide {
|
||||
public CompositeCPPDeductionGuideTemplate(ICompositesFactory cf, ICPPDeductionGuide rbinding) {
|
||||
super(cf, rbinding.getFunctionBinding());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICPPFunction getFunctionBinding() {
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2023 Igor V. Kovalenko.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Igor V. Kovalenko - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.pdom.dom.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPDeductionGuide;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
|
||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
|
||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
public class PDOMCPPDeductionGuide extends PDOMCPPFunction implements ICPPDeductionGuide {
|
||||
public PDOMCPPDeductionGuide(PDOMLinkage linkage, long bindingRecord) {
|
||||
super(linkage, bindingRecord);
|
||||
}
|
||||
|
||||
public PDOMCPPDeductionGuide(PDOMCPPLinkage linkage, PDOMNode parent, ICPPDeductionGuide guide)
|
||||
throws CoreException, DOMException {
|
||||
super(linkage, parent, guide.getFunctionBinding(), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNodeType() {
|
||||
return IIndexCPPBindingConstants.CPP_DEDUCTION_GUIDE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICPPFunction getFunctionBinding() {
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2023 Igor V. Kovalenko.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* https://www.eclipse.org/legal/epl-2.0/
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*
|
||||
* Contributors:
|
||||
* Igor V. Kovalenko - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.pdom.dom.cpp;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPDeductionGuide;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
|
||||
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
|
||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMLinkage;
|
||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMNode;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
|
||||
public class PDOMCPPDeductionGuideTemplate extends PDOMCPPFunctionTemplate implements ICPPDeductionGuide {
|
||||
public PDOMCPPDeductionGuideTemplate(PDOMLinkage linkage, long bindingRecord) {
|
||||
super(linkage, bindingRecord);
|
||||
}
|
||||
|
||||
public PDOMCPPDeductionGuideTemplate(PDOMCPPLinkage linkage, PDOMNode parent, ICPPDeductionGuide guide)
|
||||
throws CoreException, DOMException {
|
||||
super(linkage, parent, (ICPPFunctionTemplate) guide.getFunctionBinding());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getNodeType() {
|
||||
return IIndexCPPBindingConstants.CPP_DEDUCTION_GUIDE_TEMPLATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICPPFunction getFunctionBinding() {
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -60,6 +60,7 @@ 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.ICPPClassType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPDeductionGuide;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFieldTemplate;
|
||||
|
@ -851,6 +852,12 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
|
|||
if (parent instanceof PDOMCPPClassType || parent instanceof PDOMCPPClassSpecialization) {
|
||||
pdomBinding = new PDOMCPPMethod(this, parent, (ICPPMethod) binding);
|
||||
}
|
||||
} else if (binding instanceof ICPPDeductionGuide guide) {
|
||||
if (guide.getFunctionBinding() instanceof ICPPFunctionTemplate) {
|
||||
pdomBinding = new PDOMCPPDeductionGuideTemplate(this, parent, guide);
|
||||
} else {
|
||||
pdomBinding = new PDOMCPPDeductionGuide(this, parent, guide);
|
||||
}
|
||||
} else if (binding instanceof ICPPFunction) {
|
||||
pdomBinding = new PDOMCPPFunction(this, parent, (ICPPFunction) binding, true);
|
||||
} else if (binding instanceof ICPPNamespaceAlias) {
|
||||
|
@ -1137,6 +1144,12 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
|
|||
} else if (binding instanceof ICPPMethod) {
|
||||
// this must be before functions
|
||||
return CPPMETHOD;
|
||||
} else if (binding instanceof ICPPDeductionGuide guide) {
|
||||
if (guide.getFunctionBinding() instanceof ICPPFunctionTemplate) {
|
||||
return CPP_DEDUCTION_GUIDE_TEMPLATE;
|
||||
} else {
|
||||
return CPP_DEDUCTION_GUIDE;
|
||||
}
|
||||
} else if (binding instanceof ICPPFunction) {
|
||||
return CPPFUNCTION;
|
||||
} else if (binding instanceof ICPPUnknownBinding) {
|
||||
|
@ -1403,6 +1416,10 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
|
|||
return new PDOMCPPFieldTemplatePartialSpecialization(this, record);
|
||||
case CPP_ALIAS_TEMPLATE_SPECIALIZATION:
|
||||
return new PDOMCPPAliasTemplateSpecialization(this, record);
|
||||
case CPP_DEDUCTION_GUIDE:
|
||||
return new PDOMCPPDeductionGuide(this, record);
|
||||
case CPP_DEDUCTION_GUIDE_TEMPLATE:
|
||||
return new PDOMCPPDeductionGuideTemplate(this, record);
|
||||
}
|
||||
assert false : "nodeid= " + nodeType; //$NON-NLS-1$
|
||||
return null;
|
||||
|
|
Loading…
Add table
Reference in a new issue