Files
TheRock/compiler/amd-llvm/clang-tools-extra/clangd/unittests/DumpASTTests.cpp
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

262 lines
8.0 KiB
C++

//===-- DumpASTTests.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
//
//===----------------------------------------------------------------------===//
#include "Annotations.h"
#include "DumpAST.h"
#include "TestTU.h"
#include "clang/AST/ASTTypeTraits.h"
#include "llvm/Support/ScopedPrinter.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
namespace clang {
namespace clangd {
namespace {
using testing::Contains;
using testing::Not;
using testing::SizeIs;
MATCHER_P(withDetail, str, "") { return arg.detail == str; }
TEST(DumpASTTests, BasicInfo) {
std::pair</*Code=*/std::string, /*Expected=*/std::string> Cases[] = {
{R"cpp(
float root(int *x) {
return *x + 1;
}
)cpp",
R"(
declaration: Function - root
type: FunctionProto
type: Builtin - float
declaration: ParmVar - x
type: Pointer
type: Builtin - int
statement: Compound
statement: Return
expression: ImplicitCast - IntegralToFloating
expression: BinaryOperator - +
expression: ImplicitCast - LValueToRValue
expression: UnaryOperator - *
expression: ImplicitCast - LValueToRValue
expression: DeclRef - x
expression: IntegerLiteral - 1
)"},
{R"cpp(
namespace root {
struct S { static const int x = 0; ~S(); };
int y = S::x + root::S().x;
}
)cpp",
R"(
declaration: Namespace - root
declaration: CXXRecord - S
declaration: Var - x
type: Qualified - const
type: Builtin - int
expression: IntegerLiteral - 0
declaration: CXXDestructor
type: Record - S
type: FunctionProto
type: Builtin - void
declaration: CXXConstructor
declaration: CXXConstructor
declaration: Var - y
type: Builtin - int
expression: ExprWithCleanups
expression: BinaryOperator - +
expression: ImplicitCast - LValueToRValue
expression: DeclRef - x
specifier: Type
type: Record - S
expression: ImplicitCast - LValueToRValue
expression: Member - x
expression: CXXBindTemporary
expression: CXXTemporaryObject - S
type: Record - S
specifier: Namespace - root::
)"},
{R"cpp(
namespace root {
struct S { static const int x = 0; };
int y = S::x + root::S().x;
}
)cpp",
R"(
declaration: Namespace - root
declaration: CXXRecord - S
declaration: Var - x
type: Qualified - const
type: Builtin - int
expression: IntegerLiteral - 0
declaration: CXXConstructor
declaration: CXXConstructor
declaration: CXXConstructor
declaration: CXXDestructor
declaration: Var - y
type: Builtin - int
expression: BinaryOperator - +
expression: ImplicitCast - LValueToRValue
expression: DeclRef - x
specifier: Type
type: Record - S
expression: ImplicitCast - LValueToRValue
expression: Member - x
expression: CXXTemporaryObject - S
type: Record - S
specifier: Namespace - root::
)"},
{R"cpp(
namespace root {
template <typename T> int tmpl() {
(void)tmpl<unsigned>();
return T::value;
}
}
)cpp",
R"(
declaration: Namespace - root
declaration: FunctionTemplate - tmpl
declaration: TemplateTypeParm - T
declaration: Function - tmpl
type: FunctionProto
type: Builtin - int
statement: Compound
expression: CStyleCast - ToVoid
type: Builtin - void
expression: Call
expression: ImplicitCast - FunctionToPointerDecay
expression: DeclRef - tmpl
template argument: Type
type: Builtin - unsigned int
statement: Return
expression: DependentScopeDeclRef - value
specifier: Type
type: TemplateTypeParm - T
)"},
{R"cpp(
struct Foo { char operator+(int); };
char root = Foo() + 42;
)cpp",
R"(
declaration: Var - root
type: Builtin - char
expression: ExprWithCleanups
expression: CXXOperatorCall
expression: ImplicitCast - FunctionToPointerDecay
expression: DeclRef - operator+
expression: MaterializeTemporary - lvalue
expression: CXXTemporaryObject - Foo
type: Record - Foo
expression: IntegerLiteral - 42
)"},
{R"cpp(
struct Bar {
int x;
int root() const {
return x;
}
};
)cpp",
R"(
declaration: CXXMethod - root
type: FunctionProto
type: Builtin - int
statement: Compound
statement: Return
expression: ImplicitCast - LValueToRValue
expression: Member - x
expression: CXXThis - const, implicit
)"},
};
for (const auto &Case : Cases) {
ParsedAST AST = TestTU::withCode(Case.first).build();
auto Node = dumpAST(DynTypedNode::create(findUnqualifiedDecl(AST, "root")),
AST.getTokens(), AST.getASTContext());
EXPECT_EQ(llvm::StringRef(Case.second).trim(),
llvm::StringRef(llvm::to_string(Node)).trim());
}
}
TEST(DumpASTTests, Range) {
Annotations Case("$var[[$type[[int]] x]];");
ParsedAST AST = TestTU::withCode(Case.code()).build();
auto Node = dumpAST(DynTypedNode::create(findDecl(AST, "x")), AST.getTokens(),
AST.getASTContext());
EXPECT_EQ(Node.range, Case.range("var"));
ASSERT_THAT(Node.children, SizeIs(1)) << "Expected one child typeloc";
EXPECT_EQ(Node.children.front().range, Case.range("type"));
}
TEST(DumpASTTests, NoRange) {
auto TU = TestTU::withHeaderCode("void funcFromHeader();");
TU.Code = "int varFromSource;";
ParsedAST AST = TU.build();
auto Node = dumpAST(
DynTypedNode::create(*AST.getASTContext().getTranslationUnitDecl()),
AST.getTokens(), AST.getASTContext());
ASSERT_THAT(Node.children, Contains(withDetail("varFromSource")));
ASSERT_THAT(Node.children, Not(Contains(withDetail("funcFromHeader"))));
EXPECT_THAT(Node.arcana, testing::StartsWith("TranslationUnitDecl "));
ASSERT_FALSE(Node.range) << "Expected no range for translation unit";
}
TEST(DumpASTTests, Arcana) {
ParsedAST AST = TestTU::withCode("int x;").build();
auto Node = dumpAST(DynTypedNode::create(findDecl(AST, "x")), AST.getTokens(),
AST.getASTContext());
EXPECT_THAT(Node.arcana, testing::StartsWith("VarDecl "));
EXPECT_THAT(Node.arcana, testing::EndsWith(" 'int' external-linkage"));
ASSERT_THAT(Node.children, SizeIs(1)) << "Expected one child typeloc";
EXPECT_THAT(Node.children.front().arcana, testing::StartsWith("QualType "));
}
TEST(DumpASTTests, UnbalancedBraces) {
// Test that we don't crash while trying to compute a source range for the
// node whose ending brace is missing, and also that the source range is
// not empty.
Annotations Case("/*error-ok*/ $func[[int main() {]]");
ParsedAST AST = TestTU::withCode(Case.code()).build();
auto Node = dumpAST(DynTypedNode::create(findDecl(AST, "main")),
AST.getTokens(), AST.getASTContext());
ASSERT_EQ(Node.range, Case.range("func"));
}
TEST(DumpASTTests, NestedTemplates) {
// Test that we don't crash while trying to dump AST of a template function
// with nested template names such as Foo<V>::template Bar<W>::Value.
const char *Code = R"cpp(
template <typename T>
struct TypeA {
template <typename U>
struct TypeB {
static U Value;
};
};
template <typename V, typename W>
auto func() {
return TypeA<V>::template TypeB<W>::Value;
}
)cpp";
ParsedAST AST = TestTU::withCode(Code).build();
const NamedDecl &Func = findDecl(AST, [](const NamedDecl &D) {
return isa<FunctionDecl>(D) && D.getNameAsString() == "func";
});
const ASTNode Node =
dumpAST(DynTypedNode::create(Func), AST.getTokens(), AST.getASTContext());
EXPECT_EQ(Node.kind, "Function");
}
} // namespace
} // namespace clangd
} // namespace clang