1 //===-- CollectMacrosTests.cpp ----------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "Annotations.h"
10 #include "CollectMacros.h"
11 #include "SourceCode.h"
13 #include "clang/Basic/SourceLocation.h"
14 #include "llvm/Support/ScopedPrinter.h"
15 #include "gmock/gmock.h"
16 #include "gtest/gtest.h"
22 using testing::UnorderedElementsAreArray
;
24 TEST(CollectMainFileMacros
, SelectedMacros
) {
25 // References of the same symbol must have the ranges with the same
26 // name(integer). If there are N different symbols then they must be named
27 // from 1 to N. Macros for which SymbolID cannot be computed must be named
29 const char *Tests
[] = {
30 R
"cpp(// Macros: Cursor on definition.
31 #define $1[[FOO]](x,y) (x + y)
32 int main() { int x = $1[[FOO]]($1[[FOO]](3, 4), $1[[FOO]](5, 6)); }
37 int s = $1[[M]]($2[[abc]]);
39 // FIXME: Locating macro in duplicate definitions doesn't work. Enable
40 // this once LocateMacro is fixed.
41 // R"cpp(// Multiple definitions.
42 // #define $1[[abc]] 1
43 // int func1() { int a = $1[[abc]];}
46 // #define $2[[abc]] 2
47 // int func2() { int a = $2[[abc]];}
51 #ifdef $Unknown[[UNDEFINED]]
55 #ifndef $Unknown[[abc]]
62 // Macros from token concatenations not included.
63 #define $1[[CONCAT]](X) X##A()
64 #define $2[[PREPEND]](X) MACRO##X()
65 #define $3[[MACROA]]() 123
66 int B = $1[[CONCAT]](MACRO);
67 int D = $2[[PREPEND]](A);
70 // FIXME: Macro names in a definition are not detected.
71 #define $1[[MACRO_ARGS2]](X, Y) X Y
76 for (const char *Test
: Tests
) {
78 auto AST
= TestTU::withCode(T
.code()).build();
79 auto ActualMacroRefs
= AST
.getMacros();
80 auto &SM
= AST
.getSourceManager();
81 auto &PP
= AST
.getPreprocessor();
84 for (int I
= 1;; I
++) {
85 const auto ExpectedRefs
= T
.ranges(llvm::to_string(I
));
86 if (ExpectedRefs
.empty())
89 auto Loc
= sourceLocationInMainFile(SM
, ExpectedRefs
.begin()->start
);
90 ASSERT_TRUE(bool(Loc
));
91 const auto *Id
= syntax::spelledIdentifierTouching(*Loc
, AST
.getTokens());
93 auto Macro
= locateMacroAt(*Id
, PP
);
95 auto SID
= getSymbolID(Macro
->Name
, Macro
->Info
, SM
);
97 std::vector
<Range
> Ranges
;
98 for (const auto &Ref
: ActualMacroRefs
.MacroRefs
[SID
])
99 Ranges
.push_back(Ref
.Rng
);
100 EXPECT_THAT(ExpectedRefs
, UnorderedElementsAreArray(Ranges
))
101 << "Annotation=" << I
<< ", MacroName=" << Macro
->Name
102 << ", Test = " << Test
;
105 std::vector
<Range
> Ranges
;
106 for (const auto &Ref
: AST
.getMacros().UnknownMacros
)
107 Ranges
.push_back(Ref
.Rng
);
108 EXPECT_THAT(Ranges
, UnorderedElementsAreArray(T
.ranges("Unknown")))
109 << "Unknown macros doesn't match in " << Test
;
113 } // namespace clangd