summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Kramer <benny.kra@googlemail.com>2016-05-10 08:25:31 +0000
committerBenjamin Kramer <benny.kra@googlemail.com>2016-05-10 08:25:31 +0000
commitad93500c52b6407dc854b7a19ad00da86b98d575 (patch)
tree2a6aa3019a42e0d0afc4699c6ba692ea73bbb7a6
parentc3459a50022a64e695560fbb43b3248c55ad29ac (diff)
downloadbcm5719-llvm-ad93500c52b6407dc854b7a19ad00da86b98d575.tar.gz
bcm5719-llvm-ad93500c52b6407dc854b7a19ad00da86b98d575.zip
[include-fixer] Work around partial names in both directions.
We already handled the case where we had a nested name specifier where parts from the beginning don't get a callback, also handle the case where the end doesn't get a callback. This happens with function calls in unknown namespaces. The way we do this for now based on character data is a bit of a hack, we may need to refine this later or fix clang to produce different callbacks. llvm-svn: 269029
-rw-r--r--clang-tools-extra/include-fixer/IncludeFixer.cpp31
-rw-r--r--clang-tools-extra/unittests/include-fixer/IncludeFixerTest.cpp6
2 files changed, 29 insertions, 8 deletions
diff --git a/clang-tools-extra/include-fixer/IncludeFixer.cpp b/clang-tools-extra/include-fixer/IncludeFixer.cpp
index 44fb7c096cf..f86a071eec9 100644
--- a/clang-tools-extra/include-fixer/IncludeFixer.cpp
+++ b/clang-tools-extra/include-fixer/IncludeFixer.cpp
@@ -109,21 +109,36 @@ public:
DeclContext *MemberContext,
bool EnteringContext,
const ObjCObjectPointerType *OPT) override {
- // We don't want to look up inner parts of nested name specifies. Looking up
- // the header where a namespace is defined in is rarely useful.
- if (LookupKind == clang::Sema::LookupNestedNameSpecifierName) {
- DEBUG(llvm::dbgs() << "ignoring " << Typo.getAsString() << "\n");
- return clang::TypoCorrection();
- }
-
/// If we have a scope specification, use that to get more precise results.
std::string QueryString;
if (SS && SS->getRange().isValid()) {
auto Range = CharSourceRange::getTokenRange(SS->getRange().getBegin(),
Typo.getLoc());
- QueryString =
+ StringRef Source =
Lexer::getSourceText(Range, getCompilerInstance().getSourceManager(),
getCompilerInstance().getLangOpts());
+
+ // Skip forward until we find a character that's neither identifier nor
+ // colon. This is a bit of a hack around the fact that we will only get a
+ // single callback for a long nested name if a part of the beginning is
+ // unknown. For example:
+ //
+ // llvm::sys::path::parent_path(...)
+ // ^~~~ ^~~
+ // known
+ // ^~~~
+ // unknown, last callback
+ // ^~~~~~~~~~~
+ // no callback
+ //
+ // With the extension we get the full nested name specifier including
+ // parent_path.
+ // FIXME: Don't rely on source text.
+ const char *End = Source.end();
+ while (isIdentifierBody(*End) || *End == ':')
+ ++End;
+
+ QueryString = std::string(Source.begin(), End);
} else {
QueryString = Typo.getAsString();
}
diff --git a/clang-tools-extra/unittests/include-fixer/IncludeFixerTest.cpp b/clang-tools-extra/unittests/include-fixer/IncludeFixerTest.cpp
index 09ee01211da..44be4c6fdd9 100644
--- a/clang-tools-extra/unittests/include-fixer/IncludeFixerTest.cpp
+++ b/clang-tools-extra/unittests/include-fixer/IncludeFixerTest.cpp
@@ -115,6 +115,12 @@ TEST(IncludeFixer, MinimizeInclude) {
runIncludeFixer("a::b::foo bar;\n", IncludePath));
}
+TEST(IncludeFixer, NestedName) {
+ EXPECT_EQ("#include \"dir/otherdir/qux.h\"\n"
+ "namespace a {}\nint a = a::b::foo(0);\n",
+ runIncludeFixer("namespace a {}\nint a = a::b::foo(0);\n"));
+}
+
TEST(IncludeFixer, MultipleMissingSymbols) {
EXPECT_EQ("#include <string>\nstd::string bar;\nstd::sting foo;\n",
runIncludeFixer("std::string bar;\nstd::sting foo;\n"));
OpenPOWER on IntegriCloud