blob: 7a662fb4fbae43eba09ca82eb7d18c0d4945213e [file] [log] [blame]
Manuel Klimeka7328992013-06-03 13:51:33 +00001//===- unittests/AST/DeclTest.cpp --- Declaration tests -------------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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-exception
Manuel Klimeka7328992013-06-03 13:51:33 +00006//
7//===----------------------------------------------------------------------===//
8//
9// Unit tests for Decl nodes in the AST.
10//
11//===----------------------------------------------------------------------===//
12
Vedant Kumarf6bc2512019-09-25 18:00:31 +000013#include "clang/AST/ASTContext.h"
14#include "clang/AST/Mangle.h"
Manuel Klimeka7328992013-06-03 13:51:33 +000015#include "clang/ASTMatchers/ASTMatchFinder.h"
Vedant Kumarf6bc2512019-09-25 18:00:31 +000016#include "clang/Basic/LLVM.h"
Manuel Klimeka7328992013-06-03 13:51:33 +000017#include "clang/Tooling/Tooling.h"
18#include "gtest/gtest.h"
19
20using namespace clang::ast_matchers;
21using namespace clang::tooling;
Vedant Kumarf6bc2512019-09-25 18:00:31 +000022using namespace clang;
Manuel Klimeka7328992013-06-03 13:51:33 +000023
24TEST(Decl, CleansUpAPValues) {
25 MatchFinder Finder;
Ahmed Charlesb8984322014-03-07 20:03:18 +000026 std::unique_ptr<FrontendActionFactory> Factory(
Manuel Klimeka7328992013-06-03 13:51:33 +000027 newFrontendActionFactory(&Finder));
28
29 // This is a regression test for a memory leak in APValues for structs that
30 // allocate memory. This test only fails if run under valgrind with full leak
31 // checking enabled.
Tim Northoverd1fafc82017-08-08 23:17:51 +000032 std::vector<std::string> Args(1, "-std=c++11");
NAKAMURA Takumi05f43702013-06-05 06:54:06 +000033 Args.push_back("-fno-ms-extensions");
Manuel Klimeka7328992013-06-03 13:51:33 +000034 ASSERT_TRUE(runToolOnCodeWithArgs(
35 Factory->create(),
36 "struct X { int a; }; constexpr X x = { 42 };"
37 "union Y { constexpr Y(int a) : a(a) {} int a; }; constexpr Y y = { 42 };"
38 "constexpr int z[2] = { 42, 43 };"
39 "constexpr int __attribute__((vector_size(16))) v1 = {};"
Benjamin Kramer8a8557e2013-06-03 19:37:18 +000040 "\n#ifdef __SIZEOF_INT128__\n"
Manuel Klimeka7328992013-06-03 13:51:33 +000041 "constexpr __uint128_t large_int = 0xffffffffffffffff;"
42 "constexpr __uint128_t small_int = 1;"
Benjamin Kramer8a8557e2013-06-03 19:37:18 +000043 "\n#endif\n"
Manuel Klimeka7328992013-06-03 13:51:33 +000044 "constexpr double d1 = 42.42;"
45 "constexpr long double d2 = 42.42;"
46 "constexpr _Complex long double c1 = 42.0i;"
47 "constexpr _Complex long double c2 = 42.0;"
48 "template<int N> struct A : A<N-1> {};"
49 "template<> struct A<0> { int n; }; A<50> a;"
50 "constexpr int &r = a.n;"
51 "constexpr int A<50>::*p = &A<50>::n;"
52 "void f() { foo: bar: constexpr int k = __builtin_constant_p(0) ?"
53 " (char*)&&foo - (char*)&&bar : 0; }",
54 Args));
55
56 // FIXME: Once this test starts breaking we can test APValue::needsCleanup
57 // for ComplexInt.
58 ASSERT_FALSE(runToolOnCodeWithArgs(
59 Factory->create(),
60 "constexpr _Complex __uint128_t c = 0xffffffffffffffff;",
61 Args));
62}
Vedant Kumarf6bc2512019-09-25 18:00:31 +000063
64TEST(Decl, AsmLabelAttr) {
65 // Create two method decls: `f` and `g`.
66 StringRef Code = R"(
67 struct S {
68 void f() {}
69 void g() {}
70 };
71 )";
72 auto AST =
73 tooling::buildASTFromCodeWithArgs(Code, {"-target", "i386-apple-darwin"});
74 ASTContext &Ctx = AST->getASTContext();
75 assert(Ctx.getTargetInfo().getDataLayout().getGlobalPrefix() &&
76 "Expected target to have a global prefix");
77 DiagnosticsEngine &Diags = AST->getDiagnostics();
78 SourceManager &SM = AST->getSourceManager();
79 FileID MainFileID = SM.getMainFileID();
80
81 // Find the method decls within the AST.
82 SmallVector<Decl *, 1> Decls;
83 AST->findFileRegionDecls(MainFileID, Code.find('{'), 0, Decls);
84 ASSERT_TRUE(Decls.size() == 1);
85 CXXRecordDecl *DeclS = cast<CXXRecordDecl>(Decls[0]);
86 NamedDecl *DeclF = *DeclS->method_begin();
87 NamedDecl *DeclG = *(++DeclS->method_begin());
88
89 // Attach asm labels to the decls: one literal, and one not.
90 DeclF->addAttr(::new (Ctx) AsmLabelAttr(Ctx, SourceLocation(), "foo",
91 /*LiteralLabel=*/true));
92 DeclG->addAttr(::new (Ctx) AsmLabelAttr(Ctx, SourceLocation(), "goo",
93 /*LiteralLabel=*/false));
94
95 // Mangle the decl names.
96 std::string MangleF, MangleG;
Evgeniy Stepanov8b578312019-09-25 22:38:20 +000097 std::unique_ptr<ItaniumMangleContext> MC(
98 ItaniumMangleContext::create(Ctx, Diags));
Vedant Kumarf6bc2512019-09-25 18:00:31 +000099 {
100 llvm::raw_string_ostream OS_F(MangleF);
101 llvm::raw_string_ostream OS_G(MangleG);
102 MC->mangleName(DeclF, OS_F);
103 MC->mangleName(DeclG, OS_G);
104 }
105
106 ASSERT_TRUE(0 == MangleF.compare("\x01" "foo"));
107 ASSERT_TRUE(0 == MangleG.compare("goo"));
108}