[clang-tools-extra] r269029 - [include-fixer] Work around partial names in both directions.
Benjamin Kramer via cfe-commits
cfe-commits at lists.llvm.org
Tue May 10 01:25:31 PDT 2016
Author: d0k
Date: Tue May 10 03:25:31 2016
New Revision: 269029
URL: http://llvm.org/viewvc/llvm-project?rev=269029&view=rev
Log:
[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.
Modified:
clang-tools-extra/trunk/include-fixer/IncludeFixer.cpp
clang-tools-extra/trunk/unittests/include-fixer/IncludeFixerTest.cpp
Modified: clang-tools-extra/trunk/include-fixer/IncludeFixer.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/include-fixer/IncludeFixer.cpp?rev=269029&r1=269028&r2=269029&view=diff
==============================================================================
--- clang-tools-extra/trunk/include-fixer/IncludeFixer.cpp (original)
+++ clang-tools-extra/trunk/include-fixer/IncludeFixer.cpp Tue May 10 03:25:31 2016
@@ -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();
}
Modified: clang-tools-extra/trunk/unittests/include-fixer/IncludeFixerTest.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/unittests/include-fixer/IncludeFixerTest.cpp?rev=269029&r1=269028&r2=269029&view=diff
==============================================================================
--- clang-tools-extra/trunk/unittests/include-fixer/IncludeFixerTest.cpp (original)
+++ clang-tools-extra/trunk/unittests/include-fixer/IncludeFixerTest.cpp Tue May 10 03:25:31 2016
@@ -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"));
More information about the cfe-commits
mailing list