brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.2 KiB · 5c857d0 Raw
233 lines · cpp
1//===-- DumpASTTests.cpp --------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "Annotations.h"10#include "DumpAST.h"11#include "TestTU.h"12#include "clang/AST/ASTTypeTraits.h"13#include "llvm/Support/ScopedPrinter.h"14#include "gmock/gmock.h"15#include "gtest/gtest.h"16 17namespace clang {18namespace clangd {19namespace {20using testing::Contains;21using testing::Not;22using testing::SizeIs;23 24MATCHER_P(withDetail, str, "") { return arg.detail == str; }25 26TEST(DumpASTTests, BasicInfo) {27  std::pair</*Code=*/std::string, /*Expected=*/std::string> Cases[] = {28      {R"cpp(29float root(int *x) {30  return *x + 1;31}32      )cpp",33       R"(34declaration: Function - root35  type: FunctionProto36    type: Builtin - float37    declaration: ParmVar - x38      type: Pointer39        type: Builtin - int40  statement: Compound41    statement: Return42      expression: ImplicitCast - IntegralToFloating43        expression: BinaryOperator - +44          expression: ImplicitCast - LValueToRValue45            expression: UnaryOperator - *46              expression: ImplicitCast - LValueToRValue47                expression: DeclRef - x48          expression: IntegerLiteral - 149      )"},50      {R"cpp(51namespace root {52struct S { static const int x = 0; ~S(); };53int y = S::x + root::S().x;54}55      )cpp",56       R"(57declaration: Namespace - root58  declaration: CXXRecord - S59    declaration: Var - x60      type: Qualified - const61        type: Builtin - int62      expression: IntegerLiteral - 063    declaration: CXXDestructor64      type: Record - S65      type: FunctionProto66        type: Builtin - void67    declaration: CXXConstructor68    declaration: CXXConstructor69  declaration: Var - y70    type: Builtin - int71    expression: ExprWithCleanups72      expression: BinaryOperator - +73        expression: ImplicitCast - LValueToRValue74          expression: DeclRef - x75            specifier: Type76              type: Record - S77        expression: ImplicitCast - LValueToRValue78          expression: Member - x79            expression: CXXBindTemporary80              expression: CXXTemporaryObject - S81                type: Record - S82                  specifier: Namespace - root::83      )"},84      {R"cpp(85namespace root {86struct S { static const int x = 0; };87int y = S::x + root::S().x;88}89      )cpp",90       R"(91declaration: Namespace - root92  declaration: CXXRecord - S93    declaration: Var - x94      type: Qualified - const95        type: Builtin - int96      expression: IntegerLiteral - 097    declaration: CXXConstructor98    declaration: CXXConstructor99    declaration: CXXConstructor100    declaration: CXXDestructor101  declaration: Var - y102    type: Builtin - int103    expression: BinaryOperator - +104      expression: ImplicitCast - LValueToRValue105        expression: DeclRef - x106          specifier: Type107            type: Record - S108      expression: ImplicitCast - LValueToRValue109        expression: Member - x110          expression: CXXTemporaryObject - S111            type: Record - S112              specifier: Namespace - root::113      )"},114      {R"cpp(115namespace root {116template <typename T> int tmpl() {117  (void)tmpl<unsigned>();118  return T::value;119}120}121      )cpp",122       R"(123declaration: Namespace - root124  declaration: FunctionTemplate - tmpl125    declaration: TemplateTypeParm - T126    declaration: Function - tmpl127      type: FunctionProto128        type: Builtin - int129      statement: Compound130        expression: CStyleCast - ToVoid131          type: Builtin - void132          expression: Call133            expression: ImplicitCast - FunctionToPointerDecay134              expression: DeclRef - tmpl135                template argument: Type136                  type: Builtin - unsigned int137        statement: Return138          expression: DependentScopeDeclRef - value139            specifier: Type140              type: TemplateTypeParm - T141      )"},142      {R"cpp(143struct Foo { char operator+(int); };144char root = Foo() + 42;145      )cpp",146       R"(147declaration: Var - root148  type: Builtin - char149  expression: ExprWithCleanups150    expression: CXXOperatorCall151      expression: ImplicitCast - FunctionToPointerDecay152        expression: DeclRef - operator+153      expression: MaterializeTemporary - lvalue154        expression: CXXTemporaryObject - Foo155          type: Record - Foo156      expression: IntegerLiteral - 42157      )"},158      {R"cpp(159struct Bar {160  int x;161  int root() const {162    return x;163  }164};165      )cpp",166       R"(167declaration: CXXMethod - root168  type: FunctionProto169    type: Builtin - int170  statement: Compound171    statement: Return172      expression: ImplicitCast - LValueToRValue173        expression: Member - x174          expression: CXXThis - const, implicit175      )"},176  };177  for (const auto &Case : Cases) {178    ParsedAST AST = TestTU::withCode(Case.first).build();179    auto Node = dumpAST(DynTypedNode::create(findUnqualifiedDecl(AST, "root")),180                        AST.getTokens(), AST.getASTContext());181    EXPECT_EQ(llvm::StringRef(Case.second).trim(),182              llvm::StringRef(llvm::to_string(Node)).trim());183  }184}185 186TEST(DumpASTTests, Range) {187  Annotations Case("$var[[$type[[int]] x]];");188  ParsedAST AST = TestTU::withCode(Case.code()).build();189  auto Node = dumpAST(DynTypedNode::create(findDecl(AST, "x")), AST.getTokens(),190                      AST.getASTContext());191  EXPECT_EQ(Node.range, Case.range("var"));192  ASSERT_THAT(Node.children, SizeIs(1)) << "Expected one child typeloc";193  EXPECT_EQ(Node.children.front().range, Case.range("type"));194}195 196TEST(DumpASTTests, NoRange) {197  auto TU = TestTU::withHeaderCode("void funcFromHeader();");198  TU.Code = "int varFromSource;";199  ParsedAST AST = TU.build();200  auto Node = dumpAST(201      DynTypedNode::create(*AST.getASTContext().getTranslationUnitDecl()),202      AST.getTokens(), AST.getASTContext());203  ASSERT_THAT(Node.children, Contains(withDetail("varFromSource")));204  ASSERT_THAT(Node.children, Not(Contains(withDetail("funcFromHeader"))));205  EXPECT_THAT(Node.arcana, testing::StartsWith("TranslationUnitDecl "));206  ASSERT_FALSE(Node.range) << "Expected no range for translation unit";207}208 209TEST(DumpASTTests, Arcana) {210  ParsedAST AST = TestTU::withCode("int x;").build();211  auto Node = dumpAST(DynTypedNode::create(findDecl(AST, "x")), AST.getTokens(),212                      AST.getASTContext());213  EXPECT_THAT(Node.arcana, testing::StartsWith("VarDecl "));214  EXPECT_THAT(Node.arcana, testing::EndsWith(" 'int'"));215  ASSERT_THAT(Node.children, SizeIs(1)) << "Expected one child typeloc";216  EXPECT_THAT(Node.children.front().arcana, testing::StartsWith("QualType "));217}218 219TEST(DumpASTTests, UnbalancedBraces) {220  // Test that we don't crash while trying to compute a source range for the221  // node whose ending brace is missing, and also that the source range is222  // not empty.223  Annotations Case("/*error-ok*/ $func[[int main() {]]");224  ParsedAST AST = TestTU::withCode(Case.code()).build();225  auto Node = dumpAST(DynTypedNode::create(findDecl(AST, "main")),226                      AST.getTokens(), AST.getASTContext());227  ASSERT_EQ(Node.range, Case.range("func"));228}229 230} // namespace231} // namespace clangd232} // namespace clang233