10 #include "llvm/Support/Debug.h"
12 #define DEBUG_TYPE "macro-expansion-context"
22 MacroExpansionContext::ExpansionRangeMap &ExpansionRanges;
27 MacroExpansionContext::ExpansionRangeMap &ExpansionRanges)
28 : PP(PP),
SM(
SM), ExpansionRanges(ExpansionRanges) {}
37 assert(MacroNameBegin ==
SM.getExpansionLoc(Range.getBegin()));
41 if (Range.getBegin() == Range.getEnd())
42 return SM.getExpansionLoc(
46 return SM.getExpansionLoc(Range.getEnd()).getLocWithOffset(1);
50 LLVM_DEBUG(llvm::dbgs() <<
"MacroExpands event: '";
53 <<
"' with length " << MacroName.
getLength() <<
" at ";
54 MacroNameBegin.
print(llvm::dbgs(),
SM);
55 llvm::dbgs() <<
", expansion end at ";
56 ExpansionEnd.
print(llvm::dbgs(),
SM); llvm::dbgs() <<
'\n';);
60 MacroExpansionContext::ExpansionRangeMap::iterator It;
62 std::tie(It, Inserted) =
63 ExpansionRanges.try_emplace(MacroNameBegin, ExpansionEnd);
65 LLVM_DEBUG(llvm::dbgs() <<
"maps ";
66 It->getFirst().
print(llvm::dbgs(),
SM); llvm::dbgs() <<
" to ";
67 It->getSecond().print(llvm::dbgs(),
SM);
68 llvm::dbgs() <<
'\n';);
70 if (
SM.isBeforeInTranslationUnit(It->getSecond(), ExpansionEnd)) {
71 It->getSecond() = ExpansionEnd;
73 llvm::dbgs() <<
"remaps "; It->getFirst().
print(llvm::dbgs(),
SM);
74 llvm::dbgs() <<
" to "; It->getSecond().print(llvm::dbgs(),
SM);
75 llvm::dbgs() <<
'\n';);
83 using namespace clang;
86 : LangOpts(LangOpts) {}
93 PP->
addPPCallbacks(std::make_unique<detail::MacroExpansionRangeRecorder>(
94 *PP, *SM, ExpansionRanges));
105 if (ExpansionRanges.find_as(MacroExpansionLoc) == ExpansionRanges.end())
109 const auto It = ExpandedTokens.find_as(MacroExpansionLoc);
110 if (It == ExpandedTokens.end())
111 return StringRef{
""};
114 return It->getSecond().str();
122 const auto It = ExpansionRanges.find_as(MacroExpansionLoc);
123 if (It == ExpansionRanges.end())
126 assert(It->getFirst() != It->getSecond() &&
127 "Every macro expansion must cover a non-empty range.");
142 std::vector<std::pair<SourceLocation, SourceLocation>> LocalExpansionRanges;
143 LocalExpansionRanges.reserve(ExpansionRanges.size());
144 for (
const auto &Record : ExpansionRanges)
145 LocalExpansionRanges.emplace_back(
146 std::make_pair(Record.getFirst(), Record.getSecond()));
147 llvm::sort(LocalExpansionRanges);
149 OS <<
"\n=============== ExpansionRanges ===============\n";
150 for (
const auto &Record : LocalExpansionRanges) {
152 Record.first.print(OS, *SM);
154 Record.second.print(OS, *SM);
160 std::vector<std::pair<SourceLocation, MacroExpansionText>>
162 LocalExpandedTokens.reserve(ExpandedTokens.size());
163 for (
const auto &Record : ExpandedTokens)
164 LocalExpandedTokens.emplace_back(
165 std::make_pair(Record.getFirst(), Record.getSecond()));
166 llvm::sort(LocalExpandedTokens);
168 OS <<
"\n=============== ExpandedTokens ===============\n";
169 for (
const auto &Record : LocalExpandedTokens) {
171 Record.first.print(OS, *SM);
172 OS <<
" -> '" << Record.second <<
"'\n";
177 assert(Tok.
isNot(tok::raw_identifier));
188 OS << II->getName() <<
' ';
194 const char *TokPtr = Tmp;
197 OS.write(TokPtr, Len);
199 OS <<
"<too long token>";
204 void MacroExpansionContext::onTokenLexed(
const Token &Tok) {
209 LLVM_DEBUG(llvm::dbgs() <<
"lexed macro expansion token '";
210 dumpTokenInto(*PP, llvm::dbgs(), Tok); llvm::dbgs() <<
"' at ";
211 SLoc.
print(llvm::dbgs(), *SM); llvm::dbgs() <<
'\n';);
216 MacroExpansionText TokenAsString;
217 llvm::raw_svector_ostream
OS(TokenAsString);
224 ExpansionMap::iterator It;
226 std::tie(It, Inserted) =
227 ExpandedTokens.try_emplace(CurrExpansionLoc, std::move(TokenAsString));
229 It->getSecond().append(TokenAsString);