[AMDGPU][AsmParser][NFC] Translate parsed MIMG instructions to MCInsts automatically.
[llvm-project.git] / clang-tools-extra / clangd / unittests / CollectMacrosTests.cpp
blob91b2d3ef870647bc03b2583f2ebe1472ca65f0b5
1 //===-- CollectMacrosTests.cpp ----------------------------------*- C++ -*-===//
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 #include "AST.h"
9 #include "Annotations.h"
10 #include "CollectMacros.h"
11 #include "Matchers.h"
12 #include "SourceCode.h"
13 #include "TestTU.h"
14 #include "clang/Basic/SourceLocation.h"
15 #include "llvm/Support/ScopedPrinter.h"
16 #include "gmock/gmock.h"
17 #include "gtest/gtest.h"
18 #include <vector>
20 namespace clang {
21 namespace clangd {
22 namespace {
24 using testing::UnorderedElementsAreArray;
26 MATCHER_P(rangeIs, R, "") {
27 return arg.StartOffset == R.Begin && arg.EndOffset == R.End;
29 MATCHER(isDef, "") { return arg.IsDefinition; }
30 MATCHER(inConditionalDirective, "") { return arg.InConditionalDirective; }
32 TEST(CollectMainFileMacros, SelectedMacros) {
33 // References of the same symbol must have the ranges with the same
34 // name(integer). If there are N different symbols then they must be named
35 // from 1 to N. Macros for which SymbolID cannot be computed must be named
36 // "Unknown". The payload of the annotation describes the extra bit
37 // information of the MacroOccurrence (e.g. $1(def) => IsDefinition).
38 const char *Tests[] = {
39 R"cpp(// Macros: Cursor on definition.
40 #define $1(def)[[FOO]](x,y) (x + y)
41 int main() { int x = $1[[FOO]]($1[[FOO]](3, 4), $1[[FOO]](5, 6)); }
42 )cpp",
43 R"cpp(
44 #define $1(def)[[M]](X) X;
45 #define $2(def)[[abc]] 123
46 int s = $1[[M]]($2[[abc]]);
47 )cpp",
48 // FIXME: Locating macro in duplicate definitions doesn't work. Enable
49 // this once LocateMacro is fixed.
50 // R"cpp(// Multiple definitions.
51 // #define $1[[abc]] 1
52 // int func1() { int a = $1[[abc]];}
53 // #undef $1[[abc]]
55 // #define $2[[abc]] 2
56 // int func2() { int a = $2[[abc]];}
57 // #undef $2[[abc]]
58 // )cpp",
59 R"cpp(
60 #ifdef $Unknown(condit)[[UNDEFINED]]
61 #elifdef $Unknown(condit)[[UNDEFINED]]
62 #endif
64 #ifdef $Unknown(condit)[[UNDEFINED]]
65 #elifndef $Unknown(condit)[[UNDEFINED]]
66 #endif
68 #ifndef $Unknown(condit)[[UNDEFINED]]
69 #endif
71 #if defined($Unknown(condit)[[UNDEFINED]])
72 #endif
73 )cpp",
74 R"cpp(
75 #ifndef $Unknown(condit)[[abc]]
76 #define $1(def)[[abc]]
77 #ifdef $1(condit)[[abc]]
78 #endif
79 #endif
80 )cpp",
81 R"cpp(
82 // Macros from token concatenations not included.
83 #define $1(def)[[CONCAT]](X) X##A()
84 #define $2(def)[[PREPEND]](X) MACRO##X()
85 #define $3(def)[[MACROA]]() 123
86 int B = $1[[CONCAT]](MACRO);
87 int D = $2[[PREPEND]](A);
88 )cpp",
89 R"cpp(
90 #define $1(def)[[MACRO_ARGS2]](X, Y) X Y
91 #define $3(def)[[BAR]] 1
92 #define $2(def)[[FOO]] $3[[BAR]]
93 int A = $2[[FOO]];
94 )cpp"};
95 auto ExpectedResults = [](const llvm::Annotations &T, StringRef Name) {
96 std::vector<Matcher<MacroOccurrence>> ExpectedLocations;
97 for (const auto &[R, Bits] : T.rangesWithPayload(Name)) {
98 if (Bits == "def")
99 ExpectedLocations.push_back(testing::AllOf(rangeIs(R), isDef()));
100 else if (Bits == "condit")
101 ExpectedLocations.push_back(
102 testing::AllOf(rangeIs(R), inConditionalDirective()));
103 else
104 ExpectedLocations.push_back(testing::AllOf(rangeIs(R)));
106 return ExpectedLocations;
109 for (const char *Test : Tests) {
110 llvm::Annotations T(Test);
111 auto Inputs = TestTU::withCode(T.code());
112 Inputs.ExtraArgs.push_back("-std=c++2b");
113 auto AST = Inputs.build();
114 auto ActualMacroRefs = AST.getMacros();
115 auto &SM = AST.getSourceManager();
116 auto &PP = AST.getPreprocessor();
117 for (const auto &[Name, Ranges] : T.all_ranges()) {
118 if (Name == "Unknown") {
119 EXPECT_THAT(ActualMacroRefs.UnknownMacros,
120 UnorderedElementsAreArray(ExpectedResults(T, "Unknown")))
121 << "Unknown macros doesn't match in " << Test;
122 continue;
125 auto Loc = sourceLocationInMainFile(
126 SM, offsetToPosition(T.code(), Ranges.front().Begin));
127 ASSERT_TRUE(bool(Loc));
128 const auto *Id = syntax::spelledIdentifierTouching(*Loc, AST.getTokens());
129 ASSERT_TRUE(Id);
130 auto Macro = locateMacroAt(*Id, PP);
131 assert(Macro);
132 auto SID = getSymbolID(Macro->Name, Macro->Info, SM);
134 EXPECT_THAT(ActualMacroRefs.MacroRefs[SID],
135 UnorderedElementsAreArray(ExpectedResults(T, Name)))
136 << "Annotation=" << Name << ", MacroName=" << Macro->Name
137 << ", Test = " << Test;
141 } // namespace
142 } // namespace clangd
143 } // namespace clang