@@ -343,8 +343,8 @@ llvm::Optional<std::string> qualifiedByUnresolved(const SourceManager &SM,
343
343
SourceLocation Loc,
344
344
const LangOptions &LangOpts) {
345
345
std::string Result;
346
-
347
- SourceLocation NextLoc = Loc;
346
+ // Accept qualifier written within macro arguments, but not macro bodies.
347
+ SourceLocation NextLoc = SM. getTopMacroCallerLoc ( Loc) ;
348
348
while (auto CCTok = Lexer::findNextToken (NextLoc, SM, LangOpts)) {
349
349
if (!CCTok->is (tok::coloncolon))
350
350
break ;
@@ -373,40 +373,46 @@ struct CheapUnresolvedName {
373
373
llvm::Optional<std::string> UnresolvedScope;
374
374
};
375
375
376
+ llvm::Optional<std::string> getSpelledSpecifier (const CXXScopeSpec &SS,
377
+ const SourceManager &SM) {
378
+ // Support specifiers written within a single macro argument.
379
+ if (!SM.isWrittenInSameFile (SS.getBeginLoc (), SS.getEndLoc ()))
380
+ return llvm::None;
381
+ SourceRange Range (SM.getTopMacroCallerLoc (SS.getBeginLoc ()), SM.getTopMacroCallerLoc (SS.getEndLoc ()));
382
+ if (Range.getBegin ().isMacroID () || Range.getEnd ().isMacroID ())
383
+ return llvm::None;
384
+
385
+ return (toSourceCode (SM, Range) + " ::" ).str ();
386
+ }
387
+
376
388
// Extracts unresolved name and scope information around \p Unresolved.
377
389
// FIXME: try to merge this with the scope-wrangling code in CodeComplete.
378
390
llvm::Optional<CheapUnresolvedName> extractUnresolvedNameCheaply (
379
391
const SourceManager &SM, const DeclarationNameInfo &Unresolved,
380
392
CXXScopeSpec *SS, const LangOptions &LangOpts, bool UnresolvedIsSpecifier) {
381
- bool Invalid = false ;
382
- llvm::StringRef Code = SM.getBufferData (
383
- SM.getDecomposedLoc (Unresolved.getBeginLoc ()).first , &Invalid);
384
- if (Invalid)
385
- return llvm::None;
386
393
CheapUnresolvedName Result;
387
394
Result.Name = Unresolved.getAsString ();
388
395
if (SS && SS->isNotEmpty ()) { // "::" or "ns::"
389
396
if (auto *Nested = SS->getScopeRep ()) {
390
- if (Nested->getKind () == NestedNameSpecifier::Global)
397
+ if (Nested->getKind () == NestedNameSpecifier::Global) {
391
398
Result.ResolvedScope = " " ;
392
- else if (const auto *NS = Nested->getAsNamespace ()) {
393
- auto SpecifiedNS = printNamespaceScope (*NS);
399
+ } else if (const auto *NS = Nested->getAsNamespace ()) {
400
+ std::string SpecifiedNS = printNamespaceScope (*NS);
401
+ llvm::Optional<std::string> Spelling = getSpelledSpecifier (*SS, SM);
394
402
395
403
// Check the specifier spelled in the source.
396
- // If the resolved scope doesn't end with the spelled scope. The
397
- // resolved scope can come from a sema typo correction. For example,
404
+ // If the resolved scope doesn't end with the spelled scope, the
405
+ // resolved scope may come from a sema typo correction. For example,
398
406
// sema assumes that "clangd::" is a typo of "clang::" and uses
399
407
// "clang::" as the specified scope in:
400
408
// namespace clang { clangd::X; }
401
409
// In this case, we use the "typo" specifier as extra scope instead
402
410
// of using the scope assumed by sema.
403
- auto B = SM.getFileOffset (SS->getBeginLoc ());
404
- auto E = SM.getFileOffset (SS->getEndLoc ());
405
- std::string Spelling = (Code.substr (B, E - B) + " ::" ).str ();
406
- if (llvm::StringRef (SpecifiedNS).endswith (Spelling))
407
- Result.ResolvedScope = SpecifiedNS;
408
- else
409
- Result.UnresolvedScope = Spelling;
411
+ if (!Spelling || llvm::StringRef (SpecifiedNS).endswith (*Spelling)) {
412
+ Result.ResolvedScope = std::move (SpecifiedNS);
413
+ } else {
414
+ Result.UnresolvedScope = std::move (*Spelling);
415
+ }
410
416
} else if (const auto *ANS = Nested->getAsNamespaceAlias ()) {
411
417
Result.ResolvedScope = printNamespaceScope (*ANS->getNamespace ());
412
418
} else {
0 commit comments