diff options
Diffstat (limited to 'core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java')
-rw-r--r-- | core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java | 62 |
1 files changed, 52 insertions, 10 deletions
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index bcb87fc8d92..45f8fb677b5 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -231,6 +231,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPReferenceType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateNonTypeArgument; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateTypeArgument; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownField; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownMemberClass; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownMethod; @@ -298,14 +299,14 @@ public class CPPSemantics { // that are not reachable via includes from the file containing the name. // Generally this is not allowed, but certain consumers, such as IncludeOrganizer, // need it (since the whole point of IncludeOrganizer is to find missing headers). - private static final ThreadLocal<Boolean> fAllowPromiscuousBindingResolution = new ThreadLocal<Boolean>() { + private static final ThreadLocal<Boolean> fAllowPromiscuousBindingResolution = new ThreadLocal<>() { @Override protected Boolean initialValue() { return false; } }; - private static final ThreadLocal<Deque<IASTNode>> fLookupPoints = new ThreadLocal<Deque<IASTNode>>() { + private static final ThreadLocal<Deque<IASTNode>> fLookupPoints = new ThreadLocal<>() { @Override protected Deque<IASTNode> initialValue() { return new ArrayDeque<>(); @@ -1142,7 +1143,7 @@ public class CPPSemantics { return; } - if (data.qualified && !(scope instanceof ICPPTemplateScope)) { + if (!data.isDestructor && data.qualified && !(scope instanceof ICPPTemplateScope)) { if (data.ignoreUsingDirectives || data.usingDirectives.isEmpty()) return; data.usingDirectivesOnly = true; @@ -1249,6 +1250,7 @@ public class CPPSemantics { ld2.fHeuristicBaseLookup = data.fHeuristicBaseLookup; ld2.qualified = parent instanceof ICPPASTQualifiedName; ld2.typesOnly = true; + ld2.isDestructor = true; lookup(ld2, getLookupScope(typeDtorName)); IBinding[] typedefs = ld2.getFoundBindings(); ITypedef typedef = null; @@ -2653,7 +2655,7 @@ public class CPPSemantics { } } } - return result; + return ArrayUtil.trim(result); } /** @@ -3453,11 +3455,10 @@ public class CPPSemantics { data.setFunctionArguments(false, createArgForType(exp, charArray)); ret = resolveFunction(data, funcs, true, false); - // char[] stringLiteral = exp.getValue(); // The string literal that was passed to the operator // The string literal is passed to the operator as chars: - // "literal"_op -> operator "" _op<'l', 'i', 't', 'e', 'r', 'a', 'l'>(); + // 12345_op -> operator "" _op<'1', '2', '3', '4', '5'>(); ICPPTemplateArgument args[] = new ICPPTemplateArgument[stringLiteral.length]; for (int k = 0; k < stringLiteral.length; k++) { args[k] = new CPPTemplateNonTypeArgument( @@ -3492,13 +3493,48 @@ public class CPPSemantics { * str (i.e., its length excluding the terminating null character). * L is treated as operator "" X(str, len) */ - CPPPointerType strType = new CPPPointerType( - new CPPBasicType(((CPPASTLiteralExpression) exp).getBasicCharKind(), 0, null), true, false, - false); + IType charType = new CPPBasicType(((CPPASTLiteralExpression) exp).getBasicCharKind(), 0, null); + CPPPointerType strType = new CPPPointerType(charType, true, false, false); IASTInitializerClause[] initializer = new IASTInitializerClause[] { createArgForType(exp, strType), createArgForType(null, CPPBasicType.UNSIGNED_INT) }; data.setFunctionArguments(false, initializer); ret = resolveFunction(data, funcs, true, false); + + // GNU extension: allow literal operator templates for string literals. + // The implementation follows the proposed spec in + // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3599.html. + char[] stringLiteral = exp.getValue(); // The string literal that was passed to the operator + + // The operator template is expected to take the character type as its first argument, + // followed by the characters as non-type arguments. + // "literal"_op -> operator "" _op<char, 'l', 'i', 't', 'e', 'r', 'a', 'l'>(); + ICPPTemplateArgument args[] = new ICPPTemplateArgument[stringLiteral.length + 1]; + args[0] = new CPPTemplateTypeArgument(charType); + for (int k = 0; k < stringLiteral.length; k++) { + args[k + 1] = new CPPTemplateNonTypeArgument( + new EvalFixed(CPPBasicType.CHAR, PRVALUE, IntegralValue.create(stringLiteral[k]))); + } + + data = new LookupData(((CPPASTLiteralExpression) exp).getOperatorName(), args, exp); + IBinding litTpl = resolveFunction(data, tplFunctions, true, false); + + // Do we have valid template and non-template bindings? + if (ret != null && !(ret instanceof IProblemBinding)) { + // Do we have valid template and non-template bindings? + if (litTpl instanceof ICPPFunctionInstance) { + // Ambiguity? It has two valid options, and the spec says it shouldn't + return new ProblemBinding(data.getLookupName(), exp, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, + tplFunctions); + } + } else { + if (litTpl instanceof ICPPFunctionInstance) { + // Only the template binding is valid + ret = litTpl; + } else { + // Couldn't find a valid operator + return ret; + } + } } else if (kind == IASTLiteralExpression.lk_char_constant) { /* * 2.14.8.6 @@ -3743,7 +3779,13 @@ public class CPPSemantics { if (CPPTemplates.isDependentType(sourceType)) { IType[] tmp = { sourceType }; setTargetedFunctionsToUnknown(tmp); - return CPPDeferredFunction.createForCandidates(type.getConstructors()); + ICPPConstructor[] ctors = type.getConstructors(); + if (ctors != null && ctors.length > 0) { + return CPPDeferredFunction.createForCandidates(ctors); + } else { + return new ProblemBinding(typeId, ISemanticProblem.BINDING_NOT_FOUND, + type.getNameCharArray()); + } } Cost c; if (calculateInheritanceDepth(sourceType, type) >= 0) { |