mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-22 14:12: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 {
|
||||
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.IType;
|
||||
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.ICPPFunctionType;
|
||||
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() {
|
||||
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.IScope;
|
||||
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.ICPPNamespace;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
|
||||
|
@ -278,6 +279,9 @@ public class CPPScopeMapper {
|
|||
private final Map<String, List<UsingDirectiveWrapper>> fPerName= new HashMap<>();
|
||||
private final CPPASTTranslationUnit fTu;
|
||||
protected CharArrayMap<IASTName[]> fClasses;
|
||||
|
||||
private final Map<ICPPClassTemplatePartialSpecialization, ICPPClassTemplatePartialSpecialization>
|
||||
fPartialSpecs = new HashMap<>();
|
||||
|
||||
public CPPScopeMapper(CPPASTTranslationUnit tu) {
|
||||
fTu= tu;
|
||||
|
@ -429,4 +433,17 @@ public class CPPScopeMapper {
|
|||
}
|
||||
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());
|
||||
}
|
||||
ICPPPartialSpecialization partialSpec= findPartialSpecialization(classTemplate, args);
|
||||
ICPPClassTemplatePartialSpecialization indexSpec = null;
|
||||
if ((isDeclaration || isDefinition) &&
|
||||
(partialSpec instanceof ICPPClassTemplatePartialSpecialization)) {
|
||||
indexSpec = (ICPPClassTemplatePartialSpecialization) partialSpec;
|
||||
partialSpec = null;
|
||||
}
|
||||
if (partialSpec == null) {
|
||||
if (isDeclaration || isDefinition) {
|
||||
if (template instanceof ICPPClassTemplate) {
|
||||
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(
|
||||
(ICPPClassTemplatePartialSpecialization) partialSpec);
|
||||
}
|
||||
|
@ -2500,9 +2509,9 @@ public class CPPTemplates {
|
|||
return (f instanceof ICPPMethod) && !((ICPPMethod) f).isStatic();
|
||||
}
|
||||
|
||||
private static ICPPPartialSpecialization findPartialSpecialization(ICPPPartiallySpecializable ct,
|
||||
private static ICPPPartialSpecialization findPartialSpecialization(ICPPPartiallySpecializable template,
|
||||
ICPPTemplateArgument[] args) throws DOMException {
|
||||
ICPPPartialSpecialization[] pspecs = ct.getPartialSpecializations();
|
||||
ICPPPartialSpecialization[] pspecs = template.getPartialSpecializations();
|
||||
if (pspecs != null && pspecs.length > 0) {
|
||||
final String argStr= ASTTypeUtil.getArgumentListString(args, true);
|
||||
for (ICPPPartialSpecialization pspec : pspecs) {
|
||||
|
@ -2554,6 +2563,10 @@ public class CPPTemplates {
|
|||
if (bestMatch == null)
|
||||
return null;
|
||||
|
||||
if (bestMatch instanceof ICPPClassTemplatePartialSpecialization) {
|
||||
bestMatch = SemanticUtil.mapToAST((ICPPClassTemplatePartialSpecialization) bestMatch, 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.ICPPASTInitializerList;
|
||||
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.ICPPFunction;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
|
||||
|
@ -559,6 +560,27 @@ public class SemanticUtil {
|
|||
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) {
|
||||
// Don't create a new array until it's really needed.
|
||||
IType[] result = types;
|
||||
|
|
Loading…
Add table
Reference in a new issue