brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.1 KiB · cd83372 Raw
268 lines · cpp
1//===- unittests/AST/NamedDeclPrinterTest.cpp --- NamedDecl printer tests -===//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// This file contains tests for NamedDecl::printQualifiedName().10//11// These tests have a coding convention:12// * declaration to be printed is named 'A' unless it should have some special13// name (e.g., 'operator+');14// * additional helper declarations are 'Z', 'Y', 'X' and so on.15//16//===----------------------------------------------------------------------===//17 18#include "ASTPrint.h"19#include "clang/AST/ASTContext.h"20#include "clang/AST/Decl.h"21#include "clang/AST/PrettyPrinter.h"22#include "clang/ASTMatchers/ASTMatchFinder.h"23#include "clang/Tooling/Tooling.h"24#include "llvm/ADT/SmallString.h"25#include "llvm/Support/raw_ostream.h"26#include "gtest/gtest.h"27 28using namespace clang;29using namespace ast_matchers;30using namespace tooling;31 32namespace {33 34class PrintMatch : public MatchFinder::MatchCallback {35  SmallString<1024> Printed;36  unsigned NumFoundDecls;37  std::function<void(llvm::raw_ostream &OS, const NamedDecl *)> Printer;38 39public:40  explicit PrintMatch(41      std::function<void(llvm::raw_ostream &OS, const NamedDecl *)> Printer)42      : NumFoundDecls(0), Printer(std::move(Printer)) {}43 44  void run(const MatchFinder::MatchResult &Result) override {45    const NamedDecl *ND = Result.Nodes.getNodeAs<NamedDecl>("id");46    if (!ND)47      return;48    NumFoundDecls++;49    if (NumFoundDecls > 1)50      return;51 52    llvm::raw_svector_ostream Out(Printed);53    Printer(Out, ND);54  }55 56  StringRef getPrinted() const {57    return Printed;58  }59 60  unsigned getNumFoundDecls() const {61    return NumFoundDecls;62  }63};64 65::testing::AssertionResult PrintedDeclMatches(66    StringRef Code, const std::vector<std::string> &Args,67    const DeclarationMatcher &NodeMatch, StringRef ExpectedPrinted,68    StringRef FileName,69    std::function<void(llvm::raw_ostream &, const NamedDecl *)> Print) {70  return PrintedNodeMatches<NamedDecl>(71      Code, Args, NodeMatch, ExpectedPrinted, FileName,72      [Print](llvm::raw_ostream &Out, const ASTContext *Context,73              const NamedDecl *ND,74              PrintingPolicyAdjuster PolicyAdjuster) { Print(Out, ND); });75}76 77::testing::AssertionResult78PrintedNamedDeclMatches(StringRef Code, const std::vector<std::string> &Args,79                        bool SuppressUnwrittenScope,80                        const DeclarationMatcher &NodeMatch,81                        StringRef ExpectedPrinted, StringRef FileName) {82  return PrintedDeclMatches(Code, Args, NodeMatch, ExpectedPrinted, FileName,83                            [=](llvm::raw_ostream &Out, const NamedDecl *ND) {84                              auto Policy =85                                  ND->getASTContext().getPrintingPolicy();86                              Policy.SuppressUnwrittenScope =87                                  SuppressUnwrittenScope;88                              ND->printQualifiedName(Out, Policy);89                            });90}91 92::testing::AssertionResult93PrintedNamedDeclCXX98Matches(StringRef Code, StringRef DeclName,94                             StringRef ExpectedPrinted) {95  std::vector<std::string> Args(1, "-std=c++98");96  return PrintedNamedDeclMatches(Code, Args,97                                 /*SuppressUnwrittenScope*/ false,98                                 namedDecl(hasName(DeclName)).bind("id"),99                                 ExpectedPrinted, "input.cc");100}101 102::testing::AssertionResult103PrintedWrittenNamedDeclCXX11Matches(StringRef Code, StringRef DeclName,104                                    StringRef ExpectedPrinted) {105  std::vector<std::string> Args(1, "-std=c++11");106  return PrintedNamedDeclMatches(Code, Args,107                                 /*SuppressUnwrittenScope*/ true,108                                 namedDecl(hasName(DeclName)).bind("id"),109                                 ExpectedPrinted, "input.cc");110}111 112::testing::AssertionResult113PrintedWrittenPropertyDeclObjCMatches(StringRef Code, StringRef DeclName,114                                   StringRef ExpectedPrinted) {115  std::vector<std::string> Args{"-std=c++11", "-xobjective-c++"};116  return PrintedNamedDeclMatches(Code, Args,117                                 /*SuppressUnwrittenScope*/ true,118                                 objcPropertyDecl(hasName(DeclName)).bind("id"),119                                 ExpectedPrinted, "input.m");120}121 122::testing::AssertionResult123PrintedNestedNameSpecifierMatches(StringRef Code, StringRef DeclName,124                                  StringRef ExpectedPrinted) {125  std::vector<std::string> Args{"-std=c++11"};126  return PrintedDeclMatches(Code, Args, namedDecl(hasName(DeclName)).bind("id"),127                            ExpectedPrinted, "input.cc",128                            [](llvm::raw_ostream &Out, const NamedDecl *D) {129                              D->printNestedNameSpecifier(Out);130                            });131}132 133} // unnamed namespace134 135TEST(NamedDeclPrinter, TestNamespace1) {136  ASSERT_TRUE(PrintedNamedDeclCXX98Matches(137    "namespace { int A; }",138    "A",139    "(anonymous namespace)::A"));140}141 142TEST(NamedDeclPrinter, TestNamespace2) {143  ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(144    "inline namespace Z { namespace { int A; } }",145    "A",146    "A"));147}148 149TEST(NamedDeclPrinter, TestUnscopedUnnamedEnum) {150  ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(151    "enum { A };",152    "A",153    "A"));154}155 156TEST(NamedDeclPrinter, TestNamedEnum) {157  ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(158    "enum X { A };",159    "A",160    "A"));161}162 163TEST(NamedDeclPrinter, TestScopedNamedEnum) {164  ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(165    "enum class X { A };",166    "A",167    "X::A"));168}169 170TEST(NamedDeclPrinter, TestClassWithUnscopedUnnamedEnum) {171  ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(172    "class X { enum { A }; };",173    "A",174    "X::A"));175}176 177TEST(NamedDeclPrinter, TestClassWithUnscopedNamedEnum) {178  ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(179    "class X { enum Y { A }; };",180    "A",181    "X::A"));182}183 184TEST(NamedDeclPrinter, TestClassWithScopedNamedEnum) {185  ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(186    "class X { enum class Y { A }; };",187    "A",188    "X::Y::A"));189}190 191TEST(NamedDeclPrinter, TestLinkageInNamespace) {192  ASSERT_TRUE(PrintedWrittenNamedDeclCXX11Matches(193    "namespace X { extern \"C\" { int A; } }",194    "A",195    "X::A"));196}197 198TEST(NamedDeclPrinter, TestObjCClassExtension) {199  const char *Code =200R"(201  @interface Obj202  @end203 204  @interface Obj ()205  @property(nonatomic) int property;206  @end207)";208  ASSERT_TRUE(PrintedWrittenPropertyDeclObjCMatches(209    Code,210    "property",211    "Obj::property"));212}213 214TEST(NamedDeclPrinter, TestInstanceObjCClassExtension) {215  const char *Code =216R"(217@interface ObjC218@end219@interface ObjC () {220  char data; // legal with non-fragile ABI.221}222@end223)";224 225  std::vector<std::string> Args{226      "-std=c++11", "-xobjective-c++",227      "-fobjc-runtime=macosx" /*force to use non-fragile ABI*/};228  ASSERT_TRUE(PrintedNamedDeclMatches(Code, Args,229                                      /*SuppressUnwrittenScope*/ true,230                                      namedDecl(hasName("data")).bind("id"),231                                      // not "::data"232                                      "ObjC::data", "input.mm"));233}234 235TEST(NamedDeclPrinter, TestObjCClassExtensionWithGetter) {236  const char *Code =237R"(238  @interface Obj239  @end240 241  @interface Obj ()242  @property(nonatomic, getter=myPropertyGetter) int property;243  @end244)";245  ASSERT_TRUE(PrintedWrittenPropertyDeclObjCMatches(246    Code,247    "property",248    "Obj::property"));249}250 251TEST(NamedDeclPrinter, NestedNameSpecifierSimple) {252  const char *Code =253      R"(254  namespace foo { namespace bar { void func(); }  }255)";256  ASSERT_TRUE(PrintedNestedNameSpecifierMatches(Code, "func", "foo::bar::"));257}258 259TEST(NamedDeclPrinter, NestedNameSpecifierTemplateArgs) {260  const char *Code =261      R"(262        template <class T> struct vector;263        template <> struct vector<int> { int method(); };264)";265  ASSERT_TRUE(266      PrintedNestedNameSpecifierMatches(Code, "method", "vector<int>::"));267}268