struct ui_file *stream = mem_fileopen ();
struct cleanup *back_to = make_cleanup_ui_file_delete (stream);
- /* Format: class|struct|union NAME<parameters> */
+ /* Format: class|struct|union namespaces::NAME<parameters> */
if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
{
if (TYPE_DECLARED_CLASS (type))
fputs_unfiltered ("union ", stream);
}
+ /* Print all namespaces. Note that we do not push the last
+ scope_component -- that's the actual type we are defining. */
+
+ compile::compile_scope scope = type_name_to_scope (TYPE_NAME (type), NULL);
+ std::for_each (scope.begin (), scope.end () - 1, [&] (const auto &comp)
+ {
+ gdb_assert (TYPE_CODE (SYMBOL_TYPE (comp.bsymbol.symbol))
+ == TYPE_CODE_NAMESPACE);
+
+ if (comp.name != CP_ANONYMOUS_NAMESPACE_STR)
+ {
+ fputs_unfiltered (comp.name.c_str (), stream);
+ fputs_unfiltered ("::", stream);
+ }
+ });
+
fputs_unfiltered (name.c_str (), stream);
fputc_unfiltered ('<', stream);
print_template_parameter_list (stream, TYPE_TEMPLATE_ARGUMENT_INFO (type));
if (pos == m_class_template_defns->end ())
{
/* Insert the new template definition into the cache. */
- defn
- = new class_template_defn (decl_name, generic, type);
+ defn = new class_template_defn (decl_name, generic, type);
m_class_template_defns->insert (std::make_pair (generic, defn));
}
else
/* Create/push new scope. */
compile_scope scope
- = m_instance->new_scope (defn->decl_name (), defn->type ());
+ = m_instance->new_scope (TYPE_NAME (defn->type ()), defn->type ());
if (scope.nested_type () != GCC_TYPE_NONE)
{
return s[code + 1];
}
-/* Convert TYPENAME into a vector of namespace and top-most/super
- composite scopes.
-
- For example, for the input "Namespace::classB::classInner", the
- resultant vector will contain the tokens "Namespace" and
- "classB". */
+/* See description in compile-cplus.h. */
-static compile_scope
-ccp_type_name_to_scope (const char *type_name, const struct block *block)
+compile_scope
+compile::type_name_to_scope (const char *type_name, const struct block *block)
{
compile_scope scope;
/* Break the type name into components. If TYPE was defined in some
superclass, we do not process TYPE but process the enclosing type
instead. */
- compile_scope scope = ccp_type_name_to_scope (type_name, block ());
+ compile_scope scope = type_name_to_scope (type_name, block ());
if (!scope.empty ())
{
bool operator== (const compile_scope &lhs, const compile_scope &rhs);
bool operator!= (const compile_scope &lhs, const compile_scope &rhs);
+ /* Convert TYPENAME into a vector of namespace and top-most/super
+ composite scopes.
+
+ For example, for the input "Namespace::classB::classInner", the
+ resultant vector will contain the tokens "Namespace" and
+ "classB". */
+
+ compile_scope type_name_to_scope (const char *type_name,
+ const struct block *block);
+
/* A subclass of compile_instance that is specific to the C++ front
end. */
--- /dev/null
+/* Copyright 2016-2017 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+namespace N1
+{
+ namespace N2
+ {
+ template <typename T, int V>
+ T mytemplate (int a)
+ {
+ return static_cast<T> (a) + V;
+ }
+
+ template <typename T, int V>
+ T mytemplate (void)
+ {
+ return -V;
+ }
+
+ template <int V = 100>
+ int mytemplate (void)
+ {
+ return V;
+ }
+
+ struct A
+ {
+ A (int val) : value (val) { }
+ operator int () const { return value; }
+
+ template <typename T = A>
+ T tempmethod (void)
+ {
+ return value;
+ }
+
+ template <typename T = A, int V = -1>
+ static T stempmethod (void)
+ {
+ return V;
+ }
+
+ template <typename T = A, int V = -2>
+ static T stempmethod (T arg)
+ {
+ return arg + V;
+ }
+
+ int value;
+ };
+
+ template<>
+ int
+ A::tempmethod (void)
+ {
+ return -value;
+ }
+
+ // A handful of operator templates
+ struct O
+ {
+ O (int v) : v_ (v) { }
+
+ template <typename T>
+ operator T (void) { return -v_; }
+
+ template <typename T>
+ O operator+ (T val)
+ {
+ return v_ + val;
+ }
+
+ int v_;
+ };
+
+ // A simple class template
+ template <typename T1 = O, typename T2 = int, int V = 3>
+ class classt
+ {
+ public:
+ classt (T1 v) : val1_ (v), val2_ (107) { }
+ T1 get1 (void) const { return val1_; }
+ T2 get2 (void) const { return val2_; }
+ int get3 (void) const { return V; }
+
+ private:
+ T1 val1_;
+ T2 val2_;
+ };
+ };
+};
+
+int
+main (void)
+{
+ using namespace N1::N2;
+
+ A a (20);
+ O o (30);
+ int var = 0xdeadbeef;
+ int i = 1;
+ const int j = 1;
+ int* pi = &i;
+ int const* const cpci = &j;
+ int *const cpi = &i;
+
+ int o_val = o + 30;
+
+ classt<> cddd (o);
+ classt<int> cdd (100);
+ classt<int, char> cd (101);
+ classt<int, char, 12> c (102);
+ int cvals = cddd.get1 () + cddd.get2 () + cddd.get3 ();
+ cvals += cdd.get1 () + cdd.get2 () + cdd.get3 ();
+ cvals += cd.get1 () + cd.get2 () + cd.get3 ();
+ cvals += c.get1 () + c.get2 () + c.get3 ();
+
+ return mytemplate<int, 1> (0)
+ + mytemplate<int, 1> ()
+ + mytemplate<0> ()
+ + mytemplate ()
+ + a.tempmethod ()
+ + a.tempmethod<int> ()
+ + A::stempmethod ()
+ + A::stempmethod (0); // break here
+}
+
--- /dev/null
+# Copyright 2016-2017 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# Namespace-qualified template tests.
+
+load_lib compiler-support.exp
+
+standard_testfile .cc
+
+if {[skip_cplus_tests]} {
+ untested "skipping C++ tests"
+ return
+}
+
+if {[prepare_for_testing $testfile $testfile $srcfile \
+ {debug nowarnings c++}]} {
+ return -1
+}
+
+if {![runto_main]} {
+ return -1
+}
+
+if {[skip_compile_feature_tests]} {
+ untested \
+ "compile command not supported (could not find libcc1 shared library?)"
+ return -1
+}
+
+gdb_breakpoint [gdb_get_line_number "break here" $srcfile]
+gdb_continue_to_breakpoint "testing location"
+
+CompileExpression::new "var"
+CompileExpression::test "N1::N2::mytemplate<int, 1> ()" -1
+CompileExpression::test "N1::N2::mytemplate<int, 1> (1)" 2
+CompileExpression::test "N1::N2::mytemplate<0> ()" 0
+CompileExpression::test "N1::N2::mytemplate ()" 100
+CompileExpression::test "a.tempmethod ()" {(20|{value = 20})} \
+ -print {xfail *-*-* gcc/debug/49348} \
+ -value {xfail *-*-* gcc/debug/49348}
+CompileExpression::test "a.tempmethod<N1::N2::A> ()" {(20|{value = 20})}
+CompileExpression::test "a.tempmethod<int> ()" -20
+CompileExpression::test "o + 3" {(-33|{v_ = 33})}
+CompileExpression::test "cddd.get1 ()" {(-30|{v_ = 30})}
+CompileExpression::test "cddd.get2 ()" 107
+CompileExpression::test "cddd.get3 ()" 3
+CompileExpression::test "cdd.get1 ()" 100
+CompileExpression::test "cdd.get2 ()" 107
+CompileExpression::test "cdd.get3 ()" 3
+CompileExpression::test "cd.get1 ()" 101
+CompileExpression::test "cd.get2 ()" {107( 'k')?}
+CompileExpression::test "cd.get3 ()" 3
+CompileExpression::test "c.get1 ()" 102
+CompileExpression::test "c.get2 ()" {107( 'k')?}
+CompileExpression::test "c.get3 ()" 12