1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Bug 299911. Few fixes and a test that is currently failing due to a NPE.

This commit is contained in:
Sergey Prigogin 2012-07-31 18:43:37 -07:00
parent 52466b82d7
commit 304d72c17d
3 changed files with 70 additions and 11 deletions

View file

@ -5591,6 +5591,50 @@ public class AST2TemplateTests extends AST2BaseTest {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// class A;
// class B;
//
// template <bool bool_value>
// struct bool_constant {
// static const bool value = bool_value;
// };
//
// template <typename From, typename To>
// struct ImplicitlyConvertible {
// static From MakeFrom();
//
// static char Helper(To);
// static char (&Helper(...))[2];
//
// static const bool value = sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1;
// };
//
// template <typename T>
// struct IsAorB
// : public bool_constant<
// ImplicitlyConvertible<const T*, const A*>::value ||
// ImplicitlyConvertible<const T*, const B*>::value> {
// };
//
// namespace ns {
//
// template <bool U>
// class C {
// };
//
// template <typename V>
// void f(V a);
//
// } // namespace ns
//
// void test() {
// ns::C<IsAorB<int>::value> a;
// f(a);
// };
public void _testDependentExpressions() throws Exception {
parseAndCheckBindings();
}
// template <int> void* foo(int); // template <int> void* foo(int);
// template <typename T> void f(T t) { // template <typename T> void f(T t) {
// if (T* i = foo<0>(0)) // if (T* i = foo<0>(0))

View file

@ -32,6 +32,7 @@ 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.SizeofCalculator.SizeAndAlignment;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; 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.dom.parser.cpp.ICPPUnknownBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalBinding;
import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator; import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator;
import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator.EvalException; import org.eclipse.cdt.internal.core.parser.scanner.ExpressionEvaluator.EvalException;
@ -350,9 +351,10 @@ public class Value implements IValue {
IASTTypeIdExpression typeIdEx = (IASTTypeIdExpression) exp; IASTTypeIdExpression typeIdEx = (IASTTypeIdExpression) exp;
switch (typeIdEx.getOperator()) { switch (typeIdEx.getOperator()) {
case IASTTypeIdExpression.op_sizeof: case IASTTypeIdExpression.op_sizeof:
final IType type;
ASTTranslationUnit ast = (ASTTranslationUnit) typeIdEx.getTranslationUnit(); ASTTranslationUnit ast = (ASTTranslationUnit) typeIdEx.getTranslationUnit();
type = ast.createType(typeIdEx.getTypeId()); final IType type = ast.createType(typeIdEx.getTypeId());
if (type instanceof ICPPUnknownType)
return null;
SizeofCalculator calculator = ast.getSizeofCalculator(); SizeofCalculator calculator = ast.getSizeofCalculator();
SizeAndAlignment info = calculator.sizeAndAlignment(type); SizeAndAlignment info = calculator.sizeAndAlignment(type);
if (info == null) if (info == null)
@ -401,6 +403,8 @@ public class Value implements IValue {
final IASTExpression operand = exp.getOperand(); final IASTExpression operand = exp.getOperand();
if (operand != null) { if (operand != null) {
IType type = operand.getExpressionType(); IType type = operand.getExpressionType();
if (type instanceof ICPPUnknownType)
return null;
ASTTranslationUnit ast = (ASTTranslationUnit) exp.getTranslationUnit(); ASTTranslationUnit ast = (ASTTranslationUnit) exp.getTranslationUnit();
SizeofCalculator calculator = ast.getSizeofCalculator(); SizeofCalculator calculator = ast.getSizeofCalculator();
SizeAndAlignment info = calculator.sizeAndAlignment(type); SizeAndAlignment info = calculator.sizeAndAlignment(type);

View file

@ -36,6 +36,7 @@ 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.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; 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.ICPPClassType; 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.ICPPConstructor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPEnumeration;
@ -291,21 +292,20 @@ public class EvalID extends CPPEvaluation {
if (fieldOwner != null) { if (fieldOwner != null) {
fieldOwner = fieldOwner.instantiate(tpMap, packOffset, within, maxdepth, point); fieldOwner = fieldOwner.instantiate(tpMap, packOffset, within, maxdepth, point);
} }
IBinding nameOwner = fNameOwner; IBinding nameOwner = fNameOwner;
if (fNameOwner instanceof ICPPTemplateParameter) { if (nameOwner instanceof ICPPTemplateParameter) {
ICPPTemplateArgument argument = tpMap.getArgument((ICPPTemplateParameter) fNameOwner); ICPPTemplateArgument argument = tpMap.getArgument((ICPPTemplateParameter) nameOwner);
if (argument != null) { if (argument != null) {
IType type = argument.getTypeValue(); IType type = argument.getTypeValue();
if (type instanceof IBinding) if (type instanceof IBinding)
nameOwner = (IBinding) type; nameOwner = (IBinding) type;
} }
} else if (fNameOwner instanceof ICPPUnknownBinding) { } else if (nameOwner instanceof ICPPUnknownBinding) {
try { nameOwner = resolveUnknown(nameOwner, tpMap, packOffset, within, point);
nameOwner = CPPTemplates.resolveUnknown((ICPPUnknownBinding) fNameOwner, tpMap, } else if (nameOwner instanceof ICPPClassTemplate) {
packOffset, within, point); nameOwner = resolveUnknown(CPPTemplates.createDeferredInstance((ICPPClassTemplate) nameOwner),
} catch (DOMException e) { tpMap, packOffset, within, point);
CCorePlugin.log(e);
}
} }
if (Arrays.equals(templateArgs, fTemplateArgs) && fieldOwner == fFieldOwner && nameOwner == fNameOwner) if (Arrays.equals(templateArgs, fTemplateArgs) && fieldOwner == fFieldOwner && nameOwner == fNameOwner)
return this; return this;
@ -316,6 +316,17 @@ public class EvalID extends CPPEvaluation {
return new EvalID(fieldOwner, nameOwner, fName, fAddressOf, fQualified, templateArgs); return new EvalID(fieldOwner, nameOwner, fName, fAddressOf, fQualified, templateArgs);
} }
IBinding resolveUnknown(IBinding binding, ICPPTemplateParameterMap tpMap, int packOffset,
ICPPClassSpecialization within, IASTNode point) {
try {
binding = CPPTemplates.resolveUnknown((ICPPUnknownBinding) binding, tpMap,
packOffset, within, point);
} catch (DOMException e) {
CCorePlugin.log(e);
}
return binding;
}
private ICPPEvaluation resolveName(ICPPClassType nameOwner, ICPPTemplateArgument[] templateArgs, private ICPPEvaluation resolveName(ICPPClassType nameOwner, ICPPTemplateArgument[] templateArgs,
IASTNode point) { IASTNode point) {
LookupData data = new LookupData(fName, templateArgs, point); LookupData data = new LookupData(fName, templateArgs, point);