Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions clang/lib/AST/QualTypeNames.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ static bool getFullyQualifiedTemplateName(const ASTContext &Ctx,
NestedNameSpecifier NNS = std::nullopt;

TemplateDecl *ArgTDecl = TName.getAsTemplateDecl();
// ArgTDecl won't be NULL because we asserted that this isn't a
// dependent context very early in the call chain.
assert(ArgTDecl != nullptr);
if (!ArgTDecl) // ArgTDecl can be null in dependent contexts.
return false;

QualifiedTemplateName *QTName = TName.getAsQualifiedTemplateName();

if (QTName &&
Expand Down Expand Up @@ -252,6 +252,9 @@ createNestedNameSpecifierForScopeOf(const ASTContext &Ctx, const Decl *Decl,
bool WithGlobalNsPrefix) {
assert(Decl);

// Some declaration cannot be qualified.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks clearer to me:

Suggested change
// Some declaration cannot be qualified.
// Template parameters can't be qualified.

if (Decl->isTemplateParameter())
return std::nullopt;
const DeclContext *DC = Decl->getDeclContext()->getRedeclContext();
const auto *Outer = dyn_cast<NamedDecl>(DC);
const auto *OuterNS = dyn_cast<NamespaceDecl>(DC);
Expand Down
1 change: 1 addition & 0 deletions clang/unittests/AST/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ add_clang_unittest(ASTTests
ExternalASTSourceTest.cpp
NamedDeclPrinterTest.cpp
ProfilingTest.cpp
QualTypeNamesTest.cpp
RandstructTest.cpp
RawCommentForDeclTest.cpp
RecursiveASTVisitorTest.cpp
Expand Down
56 changes: 56 additions & 0 deletions clang/unittests/AST/QualTypeNamesTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//===- unittests/AST/QualTypeNamesTest.cpp --------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains tests for helpers from QualTypeNames.h.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/QualTypeNames.h"
#include "ASTPrint.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/TypeBase.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
#include "gtest/gtest.h"

namespace clang {
namespace {

TEST(QualTypeNamesTest, TemplateParameters) {
constexpr llvm::StringLiteral Code = R"cpp(
template <template<class> class T> struct Foo {
using type_of_interest = T<int>;
};
)cpp";
auto AST = tooling::buildASTFromCode(Code);
ASSERT_NE(AST, nullptr);

auto &Ctx = AST->getASTContext();
auto FooLR = Ctx.getTranslationUnitDecl()->lookup(
DeclarationName(AST->getPreprocessor().getIdentifierInfo("Foo")));
ASSERT_TRUE(FooLR.isSingleResult());

auto TypeLR =
llvm::cast<ClassTemplateDecl>(FooLR.front())
->getTemplatedDecl()
->lookup(DeclarationName(
AST->getPreprocessor().getIdentifierInfo("type_of_interest")));
ASSERT_TRUE(TypeLR.isSingleResult());

auto Type = cast<TypeAliasDecl>(TypeLR.front())->getUnderlyingType();
ASSERT_TRUE(isa<TemplateSpecializationType>(Type));

EXPECT_EQ(TypeName::getFullyQualifiedName(Type, Ctx, Ctx.getPrintingPolicy()),
"T<int>");
}

} // namespace
} // namespace clang