14#include "clang/Basic/SourceLocation.h"
15#include "llvm/Support/ScopedPrinter.h"
16#include "gmock/gmock.h"
17#include "gtest/gtest.h"
24using testing::UnorderedElementsAreArray;
27 return arg.StartOffset == R.Begin && arg.EndOffset == R.End;
29MATCHER(isDef,
"") {
return arg.IsDefinition; }
30MATCHER(inConditionalDirective,
"") {
return arg.InConditionalDirective; }
32TEST(CollectMainFileMacros, SelectedMacros) {
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)); }
44 #define $1(def)[[M]](X) X;
45 #define $2(def)[[abc]] 123
46 int s = $1[[M]]($2[[abc]]);
60 #ifdef $Unknown(condit)[[UNDEFINED]]
61 #elifdef $Unknown(condit)[[UNDEFINED]]
64 #ifdef $Unknown(condit)[[UNDEFINED]]
65 #elifndef $Unknown(condit)[[UNDEFINED]]
68 #ifndef $Unknown(condit)[[UNDEFINED]]
71 #if defined($Unknown(condit)[[UNDEFINED]])
75 #ifndef $Unknown(condit)[[abc]]
76 #define $1(def)[[abc]]
77 #ifdef $1(condit)[[abc]]
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);
90 #define $1(def)[[MACRO_ARGS2]](X, Y) X Y
91 #define $3(def)[[BAR]] 1
92 #define $2(def)[[FOO]] $3[[BAR]]
95 auto ExpectedResults = [](
const llvm::Annotations &
T, StringRef
Name) {
96 std::vector<Matcher<MacroOccurrence>> ExpectedLocations;
97 for (
const auto &[R, Bits] :
T.rangesWithPayload(
Name)) {
99 ExpectedLocations.push_back(testing::AllOf(rangeIs(R), isDef()));
100 else if (Bits ==
"condit")
101 ExpectedLocations.push_back(
102 testing::AllOf(rangeIs(R), inConditionalDirective()));
104 ExpectedLocations.push_back(testing::AllOf(rangeIs(R)));
106 return ExpectedLocations;
109 for (
const char *Test : Tests) {
110 llvm::Annotations
T(Test);
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;
127 ASSERT_TRUE(
bool(
Loc));
128 const auto *
Id = syntax::spelledIdentifierTouching(*
Loc,
AST.getTokens());
134 EXPECT_THAT(ActualMacroRefs.MacroRefs[SID],
135 UnorderedElementsAreArray(ExpectedResults(T,
Name)))
136 <<
"Annotation=" <<
Name <<
", MacroName=" <<
Macro->Name
137 <<
", Test = " << Test;
llvm::SmallString< 256U > Name
SymbolID getSymbolID(const Decl *D)
Gets the symbol ID for a declaration. Returned SymbolID might be null.
Position offsetToPosition(llvm::StringRef Code, size_t Offset)
Turn an offset in Code into a [line, column] pair.
std::optional< DefinedMacro > locateMacroAt(const syntax::Token &SpelledTok, Preprocessor &PP)
Gets the macro referenced by SpelledTok.
TEST(BackgroundQueueTest, Priority)
llvm::Expected< SourceLocation > sourceLocationInMainFile(const SourceManager &SM, Position P)
Return the file location, corresponding to P.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
static TestTU withCode(llvm::StringRef Code)