Manuel Klimek | a732899 | 2013-06-03 13:51:33 +0000 | [diff] [blame] | 1 | //===- unittests/AST/DeclTest.cpp --- Declaration tests -------------------===// |
| 2 | // |
Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 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-exception |
Manuel Klimek | a732899 | 2013-06-03 13:51:33 +0000 | [diff] [blame] | 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | // |
| 9 | // Unit tests for Decl nodes in the AST. |
| 10 | // |
| 11 | //===----------------------------------------------------------------------===// |
| 12 | |
Vedant Kumar | f6bc251 | 2019-09-25 18:00:31 +0000 | [diff] [blame] | 13 | #include "clang/AST/ASTContext.h" |
| 14 | #include "clang/AST/Mangle.h" |
Manuel Klimek | a732899 | 2013-06-03 13:51:33 +0000 | [diff] [blame] | 15 | #include "clang/ASTMatchers/ASTMatchFinder.h" |
Vedant Kumar | f6bc251 | 2019-09-25 18:00:31 +0000 | [diff] [blame] | 16 | #include "clang/Basic/LLVM.h" |
Manuel Klimek | a732899 | 2013-06-03 13:51:33 +0000 | [diff] [blame] | 17 | #include "clang/Tooling/Tooling.h" |
| 18 | #include "gtest/gtest.h" |
| 19 | |
| 20 | using namespace clang::ast_matchers; |
| 21 | using namespace clang::tooling; |
Vedant Kumar | f6bc251 | 2019-09-25 18:00:31 +0000 | [diff] [blame] | 22 | using namespace clang; |
Manuel Klimek | a732899 | 2013-06-03 13:51:33 +0000 | [diff] [blame] | 23 | |
| 24 | TEST(Decl, CleansUpAPValues) { |
| 25 | MatchFinder Finder; |
Ahmed Charles | b898432 | 2014-03-07 20:03:18 +0000 | [diff] [blame] | 26 | std::unique_ptr<FrontendActionFactory> Factory( |
Manuel Klimek | a732899 | 2013-06-03 13:51:33 +0000 | [diff] [blame] | 27 | 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 Northover | d1fafc8 | 2017-08-08 23:17:51 +0000 | [diff] [blame] | 32 | std::vector<std::string> Args(1, "-std=c++11"); |
NAKAMURA Takumi | 05f4370 | 2013-06-05 06:54:06 +0000 | [diff] [blame] | 33 | Args.push_back("-fno-ms-extensions"); |
Manuel Klimek | a732899 | 2013-06-03 13:51:33 +0000 | [diff] [blame] | 34 | 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 Kramer | 8a8557e | 2013-06-03 19:37:18 +0000 | [diff] [blame] | 40 | "\n#ifdef __SIZEOF_INT128__\n" |
Manuel Klimek | a732899 | 2013-06-03 13:51:33 +0000 | [diff] [blame] | 41 | "constexpr __uint128_t large_int = 0xffffffffffffffff;" |
| 42 | "constexpr __uint128_t small_int = 1;" |
Benjamin Kramer | 8a8557e | 2013-06-03 19:37:18 +0000 | [diff] [blame] | 43 | "\n#endif\n" |
Manuel Klimek | a732899 | 2013-06-03 13:51:33 +0000 | [diff] [blame] | 44 | "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 Kumar | f6bc251 | 2019-09-25 18:00:31 +0000 | [diff] [blame] | 63 | |
| 64 | TEST(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 Stepanov | 8b57831 | 2019-09-25 22:38:20 +0000 | [diff] [blame] | 97 | std::unique_ptr<ItaniumMangleContext> MC( |
| 98 | ItaniumMangleContext::create(Ctx, Diags)); |
Vedant Kumar | f6bc251 | 2019-09-25 18:00:31 +0000 | [diff] [blame] | 99 | { |
| 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 | } |