enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG };
-/* These are uses as bits in flags passed to build_new_method_call
- to control its error reporting behavior.
-
- LOOKUP_PROTECT means flag access violations.
- LOOKUP_COMPLAIN mean complain if no suitable member function
- matching the arguments is found.
- LOOKUP_NORMAL is just a combination of these two.
- LOOKUP_NONVIRTUAL means make a direct call to the member function found
- LOOKUP_ONLYCONVERTING means that non-conversion constructors are not tried.
- DIRECT_BIND means that if a temporary is created, it should be created so
- that it lives as long as the current variable bindings; otherwise it
- only lives until the end of the complete-expression. It also forces
- direct-initialization in cases where other parts of the compiler have
- already generated a temporary, such as reference initialization and the
- catch parameter.
- LOOKUP_NO_CONVERSION means that user-defined conversions are not
- permitted. Built-in conversions are permitted.
- LOOKUP_DESTRUCTOR means explicit call to destructor.
- LOOKUP_NO_TEMP_BIND means temporaries will not be bound to references.
-
- These are used in global lookup to support elaborated types and
- qualifiers.
-
- LOOKUP_PREFER_TYPES means not to accept objects, and possibly namespaces.
- LOOKUP_PREFER_NAMESPACES means not to accept objects, and possibly types.
- LOOKUP_PREFER_BOTH means class-or-namespace-name. */
-
+/* These are uses as bits in flags passed to various functions to
+ control their behavior. Despite the LOOKUP_ prefix, many of these
+ do not control name lookup. ??? Functions using these flags should
+ probably be modified to accept explicit boolean flags for the
+ behaviors relevant to them. */
+/* Check for access violations. */
#define LOOKUP_PROTECT (1 << 0)
+/* Complain if no suitable member function matching the arguments is
+ found. */
#define LOOKUP_COMPLAIN (1 << 1)
#define LOOKUP_NORMAL (LOOKUP_PROTECT | LOOKUP_COMPLAIN)
+/* Even if the function found by lookup is a virtual function, it
+ should be called directly. */
#define LOOKUP_NONVIRTUAL (1 << 2)
+/* Non-converting (i.e., "explicit") constructors are not tried. */
#define LOOKUP_ONLYCONVERTING (1 << 3)
+/* If a temporary is created, it should be created so that it lives
+ as long as the current variable bindings; otherwise it only lives
+ until the end of the complete-expression. It also forces
+ direct-initialization in cases where other parts of the compiler
+ have already generated a temporary, such as reference
+ initialization and the catch parameter. */
#define DIRECT_BIND (1 << 4)
+/* User-defined conversions are not permitted. (Built-in conversions
+ are permitted.) */
#define LOOKUP_NO_CONVERSION (1 << 5)
+/* The user has explicitly called a destructor. (Therefore, we do
+ not need to check that the object is non-NULL before calling the
+ destructor.) */
#define LOOKUP_DESTRUCTOR (1 << 6)
+/* Do not permit references to bind to temporaries. */
#define LOOKUP_NO_TEMP_BIND (1 << 7)
+/* Do not accept objects, and possibly namespaces. */
#define LOOKUP_PREFER_TYPES (1 << 8)
+/* Do not accept objects, and possibly types. */
#define LOOKUP_PREFER_NAMESPACES (1 << 9)
+/* Accept types or namespaces. */
#define LOOKUP_PREFER_BOTH (LOOKUP_PREFER_TYPES | LOOKUP_PREFER_NAMESPACES)
+/* We are checking that a constructor can be called -- but we do not
+ actually plan to call it. */
#define LOOKUP_CONSTRUCTOR_CALLABLE (1 << 10)
+/* Return friend decarations and un-declared builtin functions.
+ (Normally, these entities are registered in the symbol table, but
+ not found by lookup.) */
+#define LOOKUP_HIDDEN (LOOKUP_CONSTRUCTOR_CALLABLE << 1)
#define LOOKUP_NAMESPACES_ONLY(F) \
(((F) & LOOKUP_PREFER_NAMESPACES) && !((F) & LOOKUP_PREFER_TYPES))
if (b)
{
- if (b->value && hidden_name_p (b->value))
- /* Ignore anticipated built-in functions and friends. */
- ;
- else
+ if (b->value
+ && ((flags & LOOKUP_HIDDEN) || !hidden_name_p (b->value)))
binding.value = b->value;
binding.type = b->type;
}
continue;
/* If this is the kind of thing we're looking for, we're done. */
- if (qualify_lookup (iter->value, flags)
- && !hidden_name_p (iter->value))
+ if (qualify_lookup (iter->value, flags))
binding = iter->value;
else if ((flags & LOOKUP_PREFER_TYPES)
- && qualify_lookup (iter->type, flags)
- && !hidden_name_p (iter->type))
+ && qualify_lookup (iter->type, flags))
binding = iter->type;
else
binding = NULL_TREE;
if (binding)
{
+ /* Only namespace-scope bindings can be hidden. */
+ gcc_assert (!hidden_name_p (binding));
val = binding;
break;
}
push_nested_class (tsubst (context, args, tf_none, NULL_TREE));
}
- /* First, we look for a class template. */
- tmpl = lookup_name (DECL_NAME (friend_tmpl));
+ /* Look for a class template declaration. We look for hidden names
+ because two friend declarations of the same template are the
+ same. For example, in:
+
+ struct A {
+ template <typename> friend class F;
+ };
+ template <typename> struct B {
+ template <typename> friend class F;
+ };
+
+ both F templates are the same. */
+ tmpl = lookup_name_real (DECL_NAME (friend_tmpl), 0, 0,
+ /*block_p=*/true, 0,
+ LOOKUP_COMPLAIN | LOOKUP_HIDDEN);
/* But, if we don't find one, it might be because we're in a
situation like this: