clang-tools 10.0.0

CollectMacrosTests.cpp
Go to the documentation of this file.
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 "Annotations.h"
9 #include "CollectMacros.h"
10 #include "Matchers.h"
11 #include "SourceCode.h"
12 #include "TestTU.h"
13 #include "index/SymbolID.h"
14 #include "clang/Basic/SourceLocation.h"
15 #include "llvm/Support/ScopedPrinter.h"
16 #include "gmock/gmock.h"
17 #include "gtest/gtest.h"
18
19 namespace clang {
20 namespace clangd {
21 namespace {
22
23 using testing::UnorderedElementsAreArray;
24
25 TEST(CollectMainFileMacros, SelectedMacros) {
26 // References of the same symbol must have the ranges with the same
27 // name(integer). If there are N different symbols then they must be named
28 // from 1 to N. Macros for which SymbolID cannot be computed must be named
29 // "Unknown".
30 const char *Tests[] = {
31 R"cpp(// Macros: Cursor on definition.
32 #define $1[[FOO]](x,y) (x + y)
33 int main() { int x = $1[[FOO]]($1[[FOO]](3, 4), $1[[FOO]](5, 6)); }
34 )cpp",
35 R"cpp(
36 #define $1[[M]](X) X;
37 #define $2[[abc]] 123
38 int s = $1[[M]]($2[[abc]]);
39 )cpp",
40 // FIXME: Locating macro in duplicate definitions doesn't work. Enable
41 // this once LocateMacro is fixed.
42 // R"cpp(// Multiple definitions.
43 // #define $1[[abc]] 1
44 // int func1() { int a = $1[[abc]];}
45 // #undef $1[[abc]]
46
47 // #define $2[[abc]] 2
48 // int func2() { int a = $2[[abc]];}
49 // #undef $2[[abc]]
50 // )cpp",
51 R"cpp(
52 #ifdef $Unknown[[UNDEFINED]]
53 #endif
54 )cpp",
55 R"cpp(
56 #ifndef $Unknown[[abc]]
57 #define $1[[abc]]
58 #ifdef $1[[abc]]
59 #endif
60 #endif
61 )cpp",
62 R"cpp(
63 // Macros from token concatenations not included.
64 #define $1[[CONCAT]](X) X##A()
65 #define $2[[PREPEND]](X) MACRO##X()
66 #define $3[[MACROA]]() 123
67 int B = $1[[CONCAT]](MACRO);
68 int D = $2[[PREPEND]](A)
69 )cpp",
70 R"cpp(
71 // FIXME: Macro names in a definition are not detected.
72 #define $1[[MACRO_ARGS2]](X, Y) X Y
73 #define $2[[FOO]] BAR
74 #define $3[[BAR]] 1
75 int A = $2[[FOO]];
76 )cpp"};
77 for (const char *Test : Tests) {
78 Annotations T(Test);
79 auto AST = TestTU::withCode(T.code()).build();
80 auto ActualMacroRefs = AST.getMacros();
81 auto &SM = AST.getSourceManager();
82 auto &PP = AST.getPreprocessor();
83
84 // Known macros.
85 for (int I = 1;; I++) {
86 const auto ExpectedRefs = T.ranges(llvm::to_string(I));
87 if (ExpectedRefs.empty())
88 break;
89
90 auto Loc = getBeginningOfIdentifier(ExpectedRefs.begin()->start, SM,
91 AST.getLangOpts());
92 auto Macro = locateMacroAt(Loc, PP);
93 assert(Macro);
94 auto SID = getSymbolID(Macro->Name, Macro->Info, SM);
95
96 EXPECT_THAT(ExpectedRefs,
97 UnorderedElementsAreArray(ActualMacroRefs.MacroRefs[*SID]))
98 << "Annotation=" << I << ", MacroName=" << Macro->Name
99 << ", Test = " << Test;
100 }
101 // Unkown macros.
102 EXPECT_THAT(AST.getMacros().UnknownMacros,
103 UnorderedElementsAreArray(T.ranges("Unknown")))
104 << "Unknown macros doesn't match in " << Test;
105 }
106 }
107 } // namespace
108 } // namespace clangd
109 } // namespace clang
Loc
SourceLocation Loc
&#39;#&#39; location in the include directive
Definition: IncludeOrderCheck.cpp:37
clang::clangd::HighlightingKind::Macro
clang::clangd::ParsedAST::getLangOpts
const LangOptions & getLangOpts() const
Definition: ParsedAST.h:80
clang::clangd::getSymbolID
llvm::Optional< SymbolID > getSymbolID(const Decl *D)
Gets the symbol ID for a declaration, if possible.
Definition: AST.cpp:286
clang::clangd::ParsedAST::getPreprocessor
Preprocessor & getPreprocessor()
Definition: ParsedAST.cpp:430
SourceCode.h
Matchers.h
clang::clangd::getBeginningOfIdentifier
SourceLocation getBeginningOfIdentifier(const Position &Pos, const SourceManager &SM, const LangOptions &LangOpts)
Get the beginning SourceLocation at a specified Pos in the main file.
Definition: SourceCode.cpp:277
TestTU.h
clang::clangd::MainFileMacros::UnknownMacros
std::vector< Range > UnknownMacros
Definition: CollectMacros.h:32
Annotations.h
clang::clangd::TEST
TEST(BackgroundQueueTest, Priority)
Definition: BackgroundIndexTests.cpp:647
clang::clangd::TestTU::withCode
static TestTU withCode(llvm::StringRef Code)
Definition: TestTU.h:33
clang::clangd::ParsedAST::getSourceManager
SourceManager & getSourceManager()
Definition: ParsedAST.h:73
clang::clangd::ParsedAST::getMacros
const MainFileMacros & getMacros() const
Gets all macro references (definition, expansions) present in the main file, including those in the p...
Definition: ParsedAST.cpp:444
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
clang::tidy::bugprone::PP
static Preprocessor * PP
Definition: BadSignalToKillThreadCheck.cpp:28
CollectMacros.h
clang::clangd::locateMacroAt
llvm::Optional< DefinedMacro > locateMacroAt(SourceLocation Loc, Preprocessor &PP)
Gets the macro at a specified Loc.
Definition: SourceCode.cpp:987
SymbolID.h