@@ -175,9 +175,8 @@ llvm::Expected<std::vector<FoldingRange>> getFoldingRanges(ParsedAST &AST) {
175175 return collectFoldingRanges (SyntaxTree, TM);
176176}
177177
178- // FIXME( usaxena95): Collect PP conditional regions, includes and other code
179- // regions (e.g. public/private/protected sections of classes, control flow
180- // statement bodies).
178+ // FIXME( usaxena95): Collect includes and other code regions (e.g.
179+ // public/private/protected sections of classes, control flow statement bodies).
181180// Related issue: https://github.com/clangd/clangd/issues/310
182181llvm::Expected<std::vector<FoldingRange>>
183182getFoldingRanges (const std::string &Code, bool LineFoldingOnly) {
@@ -186,12 +185,6 @@ getFoldingRanges(const std::string &Code, bool LineFoldingOnly) {
186185 auto DirectiveStructure = DirectiveTree::parse (OrigStream);
187186 chooseConditionalBranches (DirectiveStructure, OrigStream);
188187
189- // FIXME: Provide ranges in the disabled-PP regions as well.
190- auto Preprocessed = DirectiveStructure.stripDirectives (OrigStream);
191-
192- auto ParseableStream = cook (Preprocessed, genericLangOpts ());
193- pairBrackets (ParseableStream);
194-
195188 std::vector<FoldingRange> Result;
196189 auto AddFoldingRange = [&](Position Start, Position End,
197190 llvm::StringLiteral Kind) {
@@ -220,7 +213,32 @@ getFoldingRanges(const std::string &Code, bool LineFoldingOnly) {
220213 auto EndPosition = [&](const Token &T) {
221214 return offsetToPosition (Code, EndOffset (T));
222215 };
216+
217+ // Preprocessor directives
218+ auto PPRanges = pairDirectiveRanges (DirectiveStructure, OrigStream);
219+ for (const auto &R : PPRanges) {
220+ auto BTok = OrigStream.tokens ()[R.Begin ];
221+ auto ETok = OrigStream.tokens ()[R.End ];
222+ if (ETok.Kind == tok::eof)
223+ continue ;
224+ if (BTok.Line >= ETok.Line )
225+ continue ;
226+
227+ Position Start = EndPosition (BTok);
228+ Position End = StartPosition (ETok);
229+ if (LineFoldingOnly)
230+ End.line --;
231+ AddFoldingRange (Start, End, FoldingRange::REGION_KIND);
232+ }
233+
234+ // FIXME: Provide ranges in the disabled-PP regions as well.
235+ auto Preprocessed = DirectiveStructure.stripDirectives (OrigStream);
236+
237+ auto ParseableStream = cook (Preprocessed, genericLangOpts ());
238+ pairBrackets (ParseableStream);
239+
223240 auto Tokens = ParseableStream.tokens ();
241+
224242 // Brackets.
225243 for (const auto &Tok : Tokens) {
226244 if (auto *Paired = Tok.pair ()) {
@@ -240,6 +258,7 @@ getFoldingRanges(const std::string &Code, bool LineFoldingOnly) {
240258 return OriginalToken (T).Length >= 2 &&
241259 Code.substr (StartOffset (T), 2 ) == " /*" ;
242260 };
261+
243262 // Multi-line comments.
244263 for (auto *T = Tokens.begin (); T != Tokens.end ();) {
245264 if (T->Kind != tok::comment) {
0 commit comments