Commit 5ca28c1d by David Malcolm Committed by David Malcolm

C++: hints for missing std:: headers

gcc/cp/ChangeLog:
	* name-lookup.c (get_std_name_hint): New function.
	(maybe_suggest_missing_header): New function.
	(suggest_alternative_in_explicit_scope): Call
	maybe_suggest_missing_header.

gcc/testsuite/ChangeLog:
	* g++.dg/lookup/missing-std-include.C: New test file.

From-SVN: r247240
parent 2ec07fa6
2017-04-25 David Malcolm <dmalcolm@redhat.com>
* name-lookup.c (get_std_name_hint): New function.
(maybe_suggest_missing_header): New function.
(suggest_alternative_in_explicit_scope): Call
maybe_suggest_missing_header.
2017-04-25 David Malcolm <dmalcolm@redhat.com>
PR c++/80177
* name-lookup.c (suggest_alternative_in_explicit_scope): Convert
candidate type of bm from tree to const char *.
......
......@@ -4537,6 +4537,113 @@ suggest_alternatives_for (location_t location, tree name,
candidates.release ();
}
/* Subroutine of maybe_suggest_missing_header for handling unrecognized names
for some of the most common names within "std::".
Given non-NULL NAME, a name for lookup within "std::", return the header
name defining it within the C++ Standard Library (without '<' and '>'),
or NULL. */
static const char *
get_std_name_hint (const char *name)
{
struct std_name_hint
{
const char *name;
const char *header;
};
static const std_name_hint hints[] = {
/* <array>. */
{"array", "array"}, // C++11
/* <deque>. */
{"deque", "deque"},
/* <forward_list>. */
{"forward_list", "forward_list"}, // C++11
/* <fstream>. */
{"basic_filebuf", "fstream"},
{"basic_ifstream", "fstream"},
{"basic_ofstream", "fstream"},
{"basic_fstream", "fstream"},
/* <iostream>. */
{"cin", "iostream"},
{"cout", "iostream"},
{"cerr", "iostream"},
{"clog", "iostream"},
{"wcin", "iostream"},
{"wcout", "iostream"},
{"wclog", "iostream"},
/* <list>. */
{"list", "list"},
/* <map>. */
{"map", "map"},
{"multimap", "map"},
/* <queue>. */
{"queue", "queue"},
{"priority_queue", "queue"},
/* <ostream>. */
{"ostream", "ostream"},
{"wostream", "ostream"},
{"ends", "ostream"},
{"flush", "ostream"},
{"endl", "ostream"},
/* <set>. */
{"set", "set"},
{"multiset", "set"},
/* <sstream>. */
{"basic_stringbuf", "sstream"},
{"basic_istringstream", "sstream"},
{"basic_ostringstream", "sstream"},
{"basic_stringstream", "sstream"},
/* <stack>. */
{"stack", "stack"},
/* <string>. */
{"string", "string"},
{"wstring", "string"},
{"u16string", "string"},
{"u32string", "string"},
/* <unordered_map>. */
{"unordered_map", "unordered_map"}, // C++11
{"unordered_multimap", "unordered_map"}, // C++11
/* <unordered_set>. */
{"unordered_set", "unordered_set"}, // C++11
{"unordered_multiset", "unordered_set"}, // C++11
/* <vector>. */
{"vector", "vector"},
};
const size_t num_hints = sizeof (hints) / sizeof (hints[0]);
for (size_t i = 0; i < num_hints; i++)
{
if (0 == strcmp (name, hints[i].name))
return hints[i].header;
}
return NULL;
}
/* Subroutine of suggest_alternative_in_explicit_scope, for use when we have no
suggestions to offer.
If SCOPE is the "std" namespace, then suggest pertinent header
files for NAME. */
static void
maybe_suggest_missing_header (location_t location, tree name, tree scope)
{
if (scope == NULL_TREE)
return;
if (TREE_CODE (scope) != NAMESPACE_DECL)
return;
/* We only offer suggestions for the "std" namespace. */
if (scope != std_node)
return;
gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
const char *name_str = IDENTIFIER_POINTER (name);
const char *header_hint = get_std_name_hint (name_str);
if (header_hint)
inform (location,
"%<std::%s%> is defined in header %<<%s>%>;"
" did you forget to %<#include <%s>%>?",
name_str, header_hint, header_hint);
}
/* Look for alternatives for NAME, an IDENTIFIER_NODE for which name
lookup failed within the explicitly provided SCOPE. Suggest the
the best meaningful candidates (if any) as a fix-it hint.
......@@ -4564,6 +4671,8 @@ suggest_alternative_in_explicit_scope (location_t location, tree name,
fuzzy_name);
return true;
}
else
maybe_suggest_missing_header (location, name, scope);
return false;
}
......
2017-04-25 David Malcolm <dmalcolm@redhat.com>
* g++.dg/lookup/missing-std-include.C: New test file.
2017-04-25 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
Jakub Jelinek <jakub@redhat.com>
......
void test (void)
{
std::string s ("hello world"); // { dg-error ".string. is not a member of .std." }
// { dg-message ".std::string. is defined in header .<string>.; did you forget to .#include <string>.?" "" { target *-*-* } .-1 }
std::wstring ws ("hello world"); // { dg-error ".wstring. is not a member of .std." }
// { dg-message ".std::wstring. is defined in header .<string>.; did you forget to .#include <string>.?" "" { target *-*-* } .-1 }
std::cout << 10; // { dg-error ".cout. is not a member of .std." }
// { dg-message ".std::cout. is defined in header .<iostream>.; did you forget to .#include <iostream>.?" "" { target *-*-* } .-1 }
int i;
std::cin >> i; // { dg-error ".cin. is not a member of .std." }
// { dg-message ".std::cin. is defined in header .<iostream>.; did you forget to .#include <iostream>.?" "" { target *-*-* } .-1 }
std::array a; // { dg-error ".array. is not a member of .std." }
// { dg-message ".std::array. is defined in header .<array>.; did you forget to .#include <array>.?" "" { target *-*-* } .-1 }
std::deque a; // { dg-error ".deque. is not a member of .std." }
// { dg-message ".std::deque. is defined in header .<deque>.; did you forget to .#include <deque>.?" "" { target *-*-* } .-1 }
std::vector<int> v; // { dg-error ".vector. is not a member of .std." }
// { dg-message ".std::vector. is defined in header .<vector>.; did you forget to .#include <vector>.?" "" { target *-*-* } .-1 }
// { dg-error "expected primary-expression before .int." "" { target *-*-* } .-2 }
std::list<int> lst; // { dg-error ".list. is not a member of .std." }
// { dg-message ".std::list. is defined in header .<list>.; did you forget to .#include <list>.?" "" { target *-*-* } .-1 }
// { dg-error "expected primary-expression before .int." "" { target *-*-* } .-2 }
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment