@@ -859,17 +859,56 @@ std::vector<DocumentLink> getDocumentLinks(ParsedAST &AST) {
859859 for (auto &Inc : AST.getIncludeStructure ().MainFileIncludes ) {
860860 if (Inc.Resolved .empty ())
861861 continue ;
862+
863+ // Get the location of the # symbole of the "#include ..." statement
862864 auto HashLoc = SM.getComposedLoc (SM.getMainFileID (), Inc.HashOffset );
865+
866+ // get the # Token itself, std::next to get the "include" token and the
867+ // first token after (aka "File Token")
863868 const auto *HashTok = AST.getTokens ().spelledTokenContaining (HashLoc);
864869 assert (HashTok && " got inclusion at wrong offset" );
865870 const auto *IncludeTok = std::next (HashTok);
866871 const auto *FileTok = std::next (IncludeTok);
867- // FileTok->range is not sufficient here, as raw lexing wouldn't yield
868- // correct tokens for angled filenames. Hence we explicitly use
869- // Inc.Written's length.
870- auto FileRange =
871- syntax::FileRange (SM, FileTok->location (), Inc.Written .length ())
872- .toCharRange (SM);
872+
873+ // The File Token can either be of kind :
874+ // "less" if using the "#include <h-char-sequence> new-line" syntax
875+ // "string_literal" if using the "#include "q-char-sequence" new-line"
876+ // syntax something else (most likely "identifier") if using the "#include
877+ // pp-tokens new-line" syntax (#include with macro argument)
878+
879+ CharSourceRange FileRange;
880+
881+ if (FileTok->kind () == tok::TokenKind::less) {
882+ // FileTok->range would only include the '<' char. Hence we explicitly use
883+ // Inc.Written's length.
884+ FileRange =
885+ syntax::FileRange (SM, FileTok->location (), Inc.Written .length ())
886+ .toCharRange (SM);
887+ } else if (FileTok->kind () == tok::TokenKind::string_literal) {
888+ // FileTok->range includes the quotes for string literals so just return
889+ // it.
890+ FileRange = FileTok->range (SM).toCharRange (SM);
891+ } else {
892+ // FileTok is the first Token of a macro spelling
893+ // We can use the AST to get the macro expansion from the spelling
894+ // starting at FileTok and use the expansion to get all the spelled Tokens
895+ // that expanded to it
896+
897+ auto OptExpansion = AST.getTokens ().expansionStartingAt (FileTok);
898+ if (OptExpansion && !OptExpansion->Spelled .empty ()) {
899+ // If an expansion was found and has an non-empty spelling, return the
900+ // range from the start of the first Token to the end of the last Token
901+ const auto &LastTok = OptExpansion->Spelled .back ();
902+
903+ FileRange = FileTok->range (SM).toCharRange (SM);
904+ const auto EndRange = LastTok.range (SM).toCharRange (SM);
905+ FileRange.setEnd (EndRange.getEnd ());
906+ } else {
907+ // We failed to find a macro expansion from the spelling
908+ // fallback to FileTok->range
909+ FileRange = FileTok->range (SM).toCharRange (SM);
910+ }
911+ }
873912
874913 Result.push_back (
875914 DocumentLink ({halfOpenToRange (SM, FileRange),
0 commit comments