diff --git a/clang-tools-extra/clangd/Selection.cpp b/clang-tools-extra/clangd/Selection.cpp --- a/clang-tools-extra/clangd/Selection.cpp +++ b/clang-tools-extra/clangd/Selection.cpp @@ -224,6 +224,11 @@ for (const syntax::Token *T = SelFirst; T < SelLimit; ++T) { if (shouldIgnore(*T)) continue; + // Ignore tokens in disabled preprocessor sections. + if (Buf.expandedTokens(SM.getMacroArgExpandedLocation(T->location())) + .empty() && + !Buf.expansionStartingAt(T)) + continue; SpelledTokens.emplace_back(); Tok &S = SpelledTokens.back(); S.Offset = SM.getFileOffset(T->location()); diff --git a/clang-tools-extra/clangd/unittests/SelectionTests.cpp b/clang-tools-extra/clangd/unittests/SelectionTests.cpp --- a/clang-tools-extra/clangd/unittests/SelectionTests.cpp +++ b/clang-tools-extra/clangd/unittests/SelectionTests.cpp @@ -521,6 +521,7 @@ EXPECT_THAT(AST.getDiagnostics(), ::testing::IsEmpty()); auto T = makeSelectionTree(Case, AST); + ASSERT_NE(T.commonAncestor(), nullptr); EXPECT_EQ("BreakStmt", T.commonAncestor()->kind()); EXPECT_EQ("WhileStmt", T.commonAncestor()->Parent->kind()); } @@ -538,7 +539,7 @@ auto AST = TU.build(); auto T = makeSelectionTree(Case, AST); - EXPECT_EQ("WhileStmt", T.commonAncestor()->kind()); + EXPECT_EQ(T.commonAncestor(), nullptr); } TEST(SelectionTest, MacroArgExpansion) { @@ -552,6 +553,7 @@ Annotations Test(Case); auto AST = TestTU::withCode(Test.code()).build(); auto T = makeSelectionTree(Case, AST); + ASSERT_NE(T.commonAncestor(), nullptr); EXPECT_EQ("IntegerLiteral", T.commonAncestor()->kind()); EXPECT_TRUE(T.commonAncestor()->Selected); @@ -566,6 +568,7 @@ AST = TestTU::withCode(Test.code()).build(); T = makeSelectionTree(Case, AST); + ASSERT_NE(T.commonAncestor(), nullptr); EXPECT_EQ("IntegerLiteral", T.commonAncestor()->kind()); } @@ -580,6 +583,7 @@ const SelectionTree::Node *Str = T.commonAncestor(); EXPECT_EQ("StringLiteral", nodeKind(Str)) << "Implicit selected?"; + ASSERT_NE(Str, nullptr); EXPECT_EQ("ImplicitCastExpr", nodeKind(Str->Parent)); EXPECT_EQ("CXXConstructExpr", nodeKind(Str->Parent->Parent)); EXPECT_EQ(Str, &Str->Parent->Parent->ignoreImplicit()) @@ -643,6 +647,32 @@ EXPECT_EQ(1u, Seen) << "one tree for nontrivial selection"; } +TEST(SelectionTest, DisabledPreprocessor) { + const char *Case = R"cpp( + namespace ns { + #define FOO B^AR + } + )cpp"; + Annotations Test(Case); + auto TU = TestTU::withCode(Test.code()); + auto AST = TU.build(); + auto T = makeSelectionTree(Case, AST); + EXPECT_EQ(T.commonAncestor(), nullptr); + + Case = R"cpp( + namespace ns { + #if 0 + void fu^nc(); + #endif + } + )cpp"; + Test = Annotations(Case); + TU = TestTU::withCode(Test.code()); + AST = TU.build(); + T = makeSelectionTree(Case, AST); + EXPECT_EQ(T.commonAncestor(), nullptr); +} + } // namespace } // namespace clangd } // namespace clang