kadircet updated this revision to Diff 194470. kadircet marked 3 inline comments as done. kadircet added a comment.
- Address comments Repository: rCTE Clang Tools Extra CHANGES SINCE LAST ACTION https://reviews.llvm.org/D59599/new/ https://reviews.llvm.org/D59599 Files: clangd/AST.cpp unittests/clangd/SymbolCollectorTests.cpp Index: unittests/clangd/SymbolCollectorTests.cpp =================================================================== --- unittests/clangd/SymbolCollectorTests.cpp +++ unittests/clangd/SymbolCollectorTests.cpp @@ -1222,6 +1222,22 @@ EXPECT_THAT(Symbols, Contains(QName("std::foo"))); } +TEST_F(SymbolCollectorTest, TemplateSpecForwardDecl) { + // FIXME: getTypeAsWritten returns null for friend decls, this should be fixed + // in AST. Testing just to make sure we don't crash. + Annotations Header(R"( + template <typename T> struct [[Foo]]; + struct Bar { + friend class Foo<int>; + }; + template <> struct Foo<int> {}; + )"); + runSymbolCollector(Header.code(), /*Main=*/""); + EXPECT_THAT(Symbols, + Contains(AllOf(QName("Foo<int>"), DeclRange(Header.range()), + ForCodeCompletion(true)))); +} + } // namespace } // namespace clangd } // namespace clang Index: clangd/AST.cpp =================================================================== --- clangd/AST.cpp +++ clangd/AST.cpp @@ -12,6 +12,7 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/TemplateBase.h" +#include "clang/AST/Type.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" @@ -82,14 +83,17 @@ if (auto Args = getTemplateSpecializationArgLocs(ND)) printTemplateArgumentList(OS, *Args, Policy); else if (auto *Cls = llvm::dyn_cast<ClassTemplateSpecializationDecl>(&ND)) { - if (auto STL = Cls->getTypeAsWritten() - ->getTypeLoc() - .getAs<TemplateSpecializationTypeLoc>()) { - llvm::SmallVector<TemplateArgumentLoc, 8> ArgLocs; - ArgLocs.reserve(STL.getNumArgs()); - for (unsigned I = 0; I < STL.getNumArgs(); ++I) - ArgLocs.push_back(STL.getArgLoc(I)); - printTemplateArgumentList(OS, ArgLocs, Policy); + if (const TypeSourceInfo *TSI = Cls->getTypeAsWritten()) { + if (auto STL = TSI->getTypeLoc().getAs<TemplateSpecializationTypeLoc>()) { + llvm::SmallVector<TemplateArgumentLoc, 8> ArgLocs; + ArgLocs.reserve(STL.getNumArgs()); + for (unsigned I = 0; I < STL.getNumArgs(); ++I) + ArgLocs.push_back(STL.getArgLoc(I)); + printTemplateArgumentList(OS, ArgLocs, Policy); + } + } else { + // FIXME: Fix cases when getTypeAsWritten returns null, e.g. friend decls. + printTemplateArgumentList(OS, Cls->getTemplateArgs().asArray(), Policy); } } OS.flush();
Index: unittests/clangd/SymbolCollectorTests.cpp =================================================================== --- unittests/clangd/SymbolCollectorTests.cpp +++ unittests/clangd/SymbolCollectorTests.cpp @@ -1222,6 +1222,22 @@ EXPECT_THAT(Symbols, Contains(QName("std::foo"))); } +TEST_F(SymbolCollectorTest, TemplateSpecForwardDecl) { + // FIXME: getTypeAsWritten returns null for friend decls, this should be fixed + // in AST. Testing just to make sure we don't crash. + Annotations Header(R"( + template <typename T> struct [[Foo]]; + struct Bar { + friend class Foo<int>; + }; + template <> struct Foo<int> {}; + )"); + runSymbolCollector(Header.code(), /*Main=*/""); + EXPECT_THAT(Symbols, + Contains(AllOf(QName("Foo<int>"), DeclRange(Header.range()), + ForCodeCompletion(true)))); +} + } // namespace } // namespace clangd } // namespace clang Index: clangd/AST.cpp =================================================================== --- clangd/AST.cpp +++ clangd/AST.cpp @@ -12,6 +12,7 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/TemplateBase.h" +#include "clang/AST/Type.h" #include "clang/AST/TypeLoc.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" @@ -82,14 +83,17 @@ if (auto Args = getTemplateSpecializationArgLocs(ND)) printTemplateArgumentList(OS, *Args, Policy); else if (auto *Cls = llvm::dyn_cast<ClassTemplateSpecializationDecl>(&ND)) { - if (auto STL = Cls->getTypeAsWritten() - ->getTypeLoc() - .getAs<TemplateSpecializationTypeLoc>()) { - llvm::SmallVector<TemplateArgumentLoc, 8> ArgLocs; - ArgLocs.reserve(STL.getNumArgs()); - for (unsigned I = 0; I < STL.getNumArgs(); ++I) - ArgLocs.push_back(STL.getArgLoc(I)); - printTemplateArgumentList(OS, ArgLocs, Policy); + if (const TypeSourceInfo *TSI = Cls->getTypeAsWritten()) { + if (auto STL = TSI->getTypeLoc().getAs<TemplateSpecializationTypeLoc>()) { + llvm::SmallVector<TemplateArgumentLoc, 8> ArgLocs; + ArgLocs.reserve(STL.getNumArgs()); + for (unsigned I = 0; I < STL.getNumArgs(); ++I) + ArgLocs.push_back(STL.getArgLoc(I)); + printTemplateArgumentList(OS, ArgLocs, Policy); + } + } else { + // FIXME: Fix cases when getTypeAsWritten returns null, e.g. friend decls. + printTemplateArgumentList(OS, Cls->getTemplateArgs().asArray(), Policy); } } OS.flush();
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits