mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-23 06:32:10 +02:00
Bug 470726 - Avoid name resolution resulting in PDOM bindings for class template partial specializations defined in the AST
Change-Id: I1e08c7430dd0478357867266648e02cc45eaa888
This commit is contained in:
parent
688b358746
commit
f47edd44e3
5 changed files with 89 additions and 3 deletions
|
@ -199,4 +199,28 @@ public class IndexMultiFileTest extends IndexBindingResolutionTestBase {
|
||||||
public void testFriendClassDeclaration_508338() throws Exception {
|
public void testFriendClassDeclaration_508338() throws Exception {
|
||||||
checkBindings();
|
checkBindings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test.h
|
||||||
|
// template <typename T>
|
||||||
|
// struct atomic;
|
||||||
|
//
|
||||||
|
// template <typename T>
|
||||||
|
// struct atomic<T*>;
|
||||||
|
|
||||||
|
// test1.cpp
|
||||||
|
// #include "test.h"
|
||||||
|
|
||||||
|
// test2.cpp *
|
||||||
|
// #include "test.h"
|
||||||
|
//
|
||||||
|
// template <typename T>
|
||||||
|
// struct atomic {};
|
||||||
|
//
|
||||||
|
// template <typename T>
|
||||||
|
// struct atomic<T*> {
|
||||||
|
// void fetch_sub();
|
||||||
|
// };
|
||||||
|
public void testClassTemplatePartialSpecialization_470726() throws Exception {
|
||||||
|
checkBindings();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.eclipse.cdt.core.dom.ast.IMacroBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit;
|
||||||
|
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.ICPPClassType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
|
||||||
|
@ -224,4 +225,13 @@ public class CPPASTTranslationUnit extends ASTTranslationUnit implements ICPPAST
|
||||||
public Map<ICPPClassType, FinalOverriderMap> getFinalOverriderMapCache() {
|
public Map<ICPPClassType, FinalOverriderMap> getFinalOverriderMapCache() {
|
||||||
return fFinalOverriderMapCache;
|
return fFinalOverriderMapCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void recordPartialSpecialization(ICPPClassTemplatePartialSpecialization indexSpec,
|
||||||
|
ICPPClassTemplatePartialSpecialization astSpec) {
|
||||||
|
fScopeMapper.recordPartialSpecialization(indexSpec, astSpec);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICPPClassTemplatePartialSpecialization mapToAST(ICPPClassTemplatePartialSpecialization indexSpec) {
|
||||||
|
return fScopeMapper.mapToAST(indexSpec);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@ import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
import org.eclipse.cdt.core.dom.ast.IScope;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
|
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.ICPPClassType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
|
||||||
|
@ -279,6 +280,9 @@ public class CPPScopeMapper {
|
||||||
private final CPPASTTranslationUnit fTu;
|
private final CPPASTTranslationUnit fTu;
|
||||||
protected CharArrayMap<IASTName[]> fClasses;
|
protected CharArrayMap<IASTName[]> fClasses;
|
||||||
|
|
||||||
|
private final Map<ICPPClassTemplatePartialSpecialization, ICPPClassTemplatePartialSpecialization>
|
||||||
|
fPartialSpecs = new HashMap<>();
|
||||||
|
|
||||||
public CPPScopeMapper(CPPASTTranslationUnit tu) {
|
public CPPScopeMapper(CPPASTTranslationUnit tu) {
|
||||||
fTu= tu;
|
fTu= tu;
|
||||||
}
|
}
|
||||||
|
@ -429,4 +433,17 @@ public class CPPScopeMapper {
|
||||||
}
|
}
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void recordPartialSpecialization(ICPPClassTemplatePartialSpecialization indexSpec,
|
||||||
|
ICPPClassTemplatePartialSpecialization astSpec) {
|
||||||
|
fPartialSpecs.put(indexSpec, astSpec);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICPPClassTemplatePartialSpecialization mapToAST(ICPPClassTemplatePartialSpecialization indexSpec) {
|
||||||
|
ICPPClassTemplatePartialSpecialization astSpec = fPartialSpecs.get(indexSpec);
|
||||||
|
if (astSpec != null) {
|
||||||
|
return astSpec;
|
||||||
|
}
|
||||||
|
return indexSpec;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -837,11 +837,20 @@ public class CPPTemplates {
|
||||||
return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, templateName.toCharArray());
|
return new ProblemBinding(id, IProblemBinding.SEMANTIC_INVALID_TEMPLATE_ARGUMENTS, templateName.toCharArray());
|
||||||
}
|
}
|
||||||
ICPPPartialSpecialization partialSpec= findPartialSpecialization(classTemplate, args);
|
ICPPPartialSpecialization partialSpec= findPartialSpecialization(classTemplate, args);
|
||||||
|
ICPPClassTemplatePartialSpecialization indexSpec = null;
|
||||||
|
if ((isDeclaration || isDefinition) &&
|
||||||
|
(partialSpec instanceof ICPPClassTemplatePartialSpecialization)) {
|
||||||
|
indexSpec = (ICPPClassTemplatePartialSpecialization) partialSpec;
|
||||||
|
partialSpec = null;
|
||||||
|
}
|
||||||
if (partialSpec == null) {
|
if (partialSpec == null) {
|
||||||
if (isDeclaration || isDefinition) {
|
if (isDeclaration || isDefinition) {
|
||||||
if (template instanceof ICPPClassTemplate) {
|
if (template instanceof ICPPClassTemplate) {
|
||||||
partialSpec = new CPPClassTemplatePartialSpecialization(id, args);
|
partialSpec = new CPPClassTemplatePartialSpecialization(id, args);
|
||||||
if (template instanceof ICPPInternalClassTemplate) {
|
if (indexSpec != null) {
|
||||||
|
SemanticUtil.recordPartialSpecialization(indexSpec,
|
||||||
|
(ICPPClassTemplatePartialSpecialization) partialSpec, id);
|
||||||
|
} else if (template instanceof ICPPInternalClassTemplate) {
|
||||||
((ICPPInternalClassTemplate) template).addPartialSpecialization(
|
((ICPPInternalClassTemplate) template).addPartialSpecialization(
|
||||||
(ICPPClassTemplatePartialSpecialization) partialSpec);
|
(ICPPClassTemplatePartialSpecialization) partialSpec);
|
||||||
}
|
}
|
||||||
|
@ -2500,9 +2509,9 @@ public class CPPTemplates {
|
||||||
return (f instanceof ICPPMethod) && !((ICPPMethod) f).isStatic();
|
return (f instanceof ICPPMethod) && !((ICPPMethod) f).isStatic();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ICPPPartialSpecialization findPartialSpecialization(ICPPPartiallySpecializable ct,
|
private static ICPPPartialSpecialization findPartialSpecialization(ICPPPartiallySpecializable template,
|
||||||
ICPPTemplateArgument[] args) throws DOMException {
|
ICPPTemplateArgument[] args) throws DOMException {
|
||||||
ICPPPartialSpecialization[] pspecs = ct.getPartialSpecializations();
|
ICPPPartialSpecialization[] pspecs = template.getPartialSpecializations();
|
||||||
if (pspecs != null && pspecs.length > 0) {
|
if (pspecs != null && pspecs.length > 0) {
|
||||||
final String argStr= ASTTypeUtil.getArgumentListString(args, true);
|
final String argStr= ASTTypeUtil.getArgumentListString(args, true);
|
||||||
for (ICPPPartialSpecialization pspec : pspecs) {
|
for (ICPPPartialSpecialization pspec : pspecs) {
|
||||||
|
@ -2554,6 +2563,10 @@ public class CPPTemplates {
|
||||||
if (bestMatch == null)
|
if (bestMatch == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
if (bestMatch instanceof ICPPClassTemplatePartialSpecialization) {
|
||||||
|
bestMatch = SemanticUtil.mapToAST((ICPPClassTemplatePartialSpecialization) bestMatch, point);
|
||||||
|
}
|
||||||
|
|
||||||
return instantiatePartialSpecialization(bestMatch, args, isDef, bestMap, point);
|
return instantiatePartialSpecialization(bestMatch, args, isDef, bestMap, point);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ import org.eclipse.cdt.core.dom.ast.IValue;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorInitializer;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTInitializerList;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
|
||||||
|
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.ICPPClassType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
|
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.ICPPFunctionType;
|
||||||
|
@ -559,6 +560,27 @@ public class SemanticUtil {
|
||||||
return scope;
|
return scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void recordPartialSpecialization(ICPPClassTemplatePartialSpecialization indexSpec,
|
||||||
|
ICPPClassTemplatePartialSpecialization astSpec, IASTNode point) {
|
||||||
|
if (point != null) {
|
||||||
|
IASTTranslationUnit ast = point.getTranslationUnit();
|
||||||
|
if (ast instanceof CPPASTTranslationUnit) {
|
||||||
|
((CPPASTTranslationUnit) ast).recordPartialSpecialization(indexSpec, astSpec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ICPPClassTemplatePartialSpecialization mapToAST(
|
||||||
|
ICPPClassTemplatePartialSpecialization indexSpec, IASTNode point) {
|
||||||
|
if (point != null) {
|
||||||
|
IASTTranslationUnit ast = point.getTranslationUnit();
|
||||||
|
if (ast instanceof CPPASTTranslationUnit) {
|
||||||
|
return ((CPPASTTranslationUnit) ast).mapToAST(indexSpec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return indexSpec;
|
||||||
|
}
|
||||||
|
|
||||||
public static IType[] getSimplifiedTypes(IType[] types) {
|
public static IType[] getSimplifiedTypes(IType[] types) {
|
||||||
// Don't create a new array until it's really needed.
|
// Don't create a new array until it's really needed.
|
||||||
IType[] result = types;
|
IType[] result = types;
|
||||||
|
|
Loading…
Add table
Reference in a new issue