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
262 lines
8.0 KiB
C++
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
|