diff --git a/clang/lib/Tooling/Refactor/FillInEnumSwitchCases.cpp b/clang/lib/Tooling/Refactor/FillInEnumSwitchCases.cpp index 113a9ba280aaf..12e251180f36e 100644 --- a/clang/lib/Tooling/Refactor/FillInEnumSwitchCases.cpp +++ b/clang/lib/Tooling/Refactor/FillInEnumSwitchCases.cpp @@ -80,8 +80,12 @@ clang::tooling::initiateFillInEnumSwitchCasesOperation( if (!ED) return RefactoringOperationResult("The switch doesn't operate on an enum"); - if (!ED->isCompleteDefinition()) - return RefactoringOperationResult("The enum type is incomplete"); + + if (!ED->isCompleteDefinition()) { + ED = ED->getDefinition(); + if (!ED) + return RefactoringOperationResult("The enum type is incomplete"); + } if (Switch->isAllEnumCasesCovered()) return RefactoringOperationResult("All enum cases are already covered"); diff --git a/clang/lib/Tooling/Refactor/ImplementDeclaredMethods.cpp b/clang/lib/Tooling/Refactor/ImplementDeclaredMethods.cpp index 4c6c9667797d0..75de431196ed5 100644 --- a/clang/lib/Tooling/Refactor/ImplementDeclaredMethods.cpp +++ b/clang/lib/Tooling/Refactor/ImplementDeclaredMethods.cpp @@ -262,35 +262,42 @@ ImplementDeclaredCXXMethodsOperation::runInImplementationAST( std::string MethodString; llvm::raw_string_ostream OS(MethodString); + PrintingPolicy PP = Context.getPrintingPolicy(); + PP.PolishForDeclaration = true; + PP.SupressStorageClassSpecifiers = true; + PP.SuppressStrongLifetime = true; + PP.SuppressLifetimeQualifiers = true; + PP.SuppressUnwrittenScope = true; + + // Callback class for skipping namespaces. + class Callbacks final : public PrintingCallbacks { + public: + bool isScopeVisible(const DeclContext *DC) const override { + return DC->getDeclKind() == Decl::Namespace; + } + } CB; + // Pick a good insertion location. SourceLocation InsertionLoc; const CXXMethodDecl *InsertAfterMethod = nullptr; - std::optional NamePrefix = std::nullopt; if (DefinedOutOfLineMethods.empty()) { + PP.Callbacks = &CB; const RecordDecl *OutermostRecord = findOutermostRecord(Class); InsertionLoc = SM.getExpansionRange(OutermostRecord->getEndLoc()).getEnd(); if (SM.getFileID(InsertionLoc) == File) { - // We can insert right after the class. Compute the appropriate - // qualification. - NamePrefix = NestedNameSpecifier::getRequiredQualification( - Context, OutermostRecord->getLexicalDeclContext(), - Class->getLexicalDeclContext()); + // We can insert right after the class. } else { // We can't insert after the end of the class, since the indexer told us // that some file should have the implementation of it, even when there // are no methods here. We should try to insert at the end of the file. InsertionLoc = SM.getLocForEndOfFile(File); - NamePrefix = NestedNameSpecifier::getRequiredQualification( - Context, Context.getTranslationUnitDecl(), - Class->getLexicalDeclContext()); llvm::SmallVector Namespaces; - std::optional Qualifier = NamePrefix; - while (Qualifier) { - auto [ND, Prefix] = Qualifier->getAsNamespaceAndPrefix(); - if (ND) - Namespaces.push_back(ND->getNamespace()); - Qualifier = Prefix; - } + + for (const DeclContext *DC = OutermostRecord->getLexicalDeclContext(); DC; + DC = DC->getLookupParent()) + if (auto *ND = dyn_cast(DC)) + Namespaces.push_back(ND); + // When the class is in a namespace, add a 'using' declaration if it's // needed and adjust the out-of-line qualification. if (!Namespaces.empty()) { @@ -305,9 +312,6 @@ ImplementDeclaredCXXMethodsOperation::runInImplementationAST( } OS << "\nusing namespace " << NamespaceOS.str() << ";"; } - // Re-compute the name qualifier without the namespace. - NamePrefix = NestedNameSpecifier::getRequiredQualification( - Context, InnermostNamespace, Class->getLexicalDeclContext()); } } } else { @@ -324,12 +328,6 @@ ImplementDeclaredCXXMethodsOperation::runInImplementationAST( InsertionLoc = getLastLineLocationUnlessItHasOtherTokens( InsertionLoc, SM, Context.getLangOpts()); - PrintingPolicy PP = Context.getPrintingPolicy(); - PP.PolishForDeclaration = true; - PP.SupressStorageClassSpecifiers = true; - PP.SuppressStrongLifetime = true; - PP.SuppressLifetimeQualifiers = true; - PP.SuppressUnwrittenScope = true; OS << "\n"; for (const auto &I : SelectedMethods) { const CXXMethodDecl *MD = I.Decl; diff --git a/clang/lib/Tooling/Refactor/SymbolOccurrenceFinder.cpp b/clang/lib/Tooling/Refactor/SymbolOccurrenceFinder.cpp index d48462faac047..ada71a5fecbf7 100644 --- a/clang/lib/Tooling/Refactor/SymbolOccurrenceFinder.cpp +++ b/clang/lib/Tooling/Refactor/SymbolOccurrenceFinder.cpp @@ -278,9 +278,9 @@ class SymbolOccurrenceFinderASTVisitor checkDecl(TND, TTL.getNameLoc()); return true; } - TypeSpecTypeLoc TSTL = Loc.getAs(); - if (TSTL) { - checkDecl(Loc.getType()->getAsTagDecl(), TSTL.getNameLoc()); + TagTypeLoc TagTL = Loc.getAs(); + if (TagTL) { + checkDecl(Loc.getType()->getAsTagDecl(), TagTL.getNameLoc()); } if (const auto *TemplateTypeParm = dyn_cast(Loc.getType())) { diff --git a/clang/lib/Tooling/Refactor/USRFinder.cpp b/clang/lib/Tooling/Refactor/USRFinder.cpp index 90e72991c610b..ff28d731abb33 100644 --- a/clang/lib/Tooling/Refactor/USRFinder.cpp +++ b/clang/lib/Tooling/Refactor/USRFinder.cpp @@ -317,9 +317,9 @@ class NamedDeclFindingASTVisitor } return checkOccurrence(TND, TTL.getNameLoc()); } - TypeSpecTypeLoc TSTL = Loc.getAs(); - if (TSTL) { - return checkOccurrence(Loc.getType()->getAsTagDecl(), TSTL.getNameLoc()); + TagTypeLoc TagTL = Loc.getAs(); + if (TagTL) { + return checkOccurrence(Loc.getType()->getAsTagDecl(), TagTL.getNameLoc()); } return true; }