1326941Sdim//===-- DataCollection.cpp --------------------------------------*- C++ -*-===//
2326941Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6326941Sdim//
7326941Sdim//===----------------------------------------------------------------------===//
8326941Sdim
9326941Sdim#include "clang/AST/DataCollection.h"
10326941Sdim
11326941Sdim#include "clang/Lex/Lexer.h"
12326941Sdim
13326941Sdimnamespace clang {
14326941Sdimnamespace data_collection {
15326941Sdim
16326941Sdim/// Prints the macro name that contains the given SourceLocation into the given
17326941Sdim/// raw_string_ostream.
18326941Sdimstatic void printMacroName(llvm::raw_string_ostream &MacroStack,
19326941Sdim                           ASTContext &Context, SourceLocation Loc) {
20326941Sdim  MacroStack << Lexer::getImmediateMacroName(Loc, Context.getSourceManager(),
21326941Sdim                                             Context.getLangOpts());
22326941Sdim
23326941Sdim  // Add an empty space at the end as a padding to prevent
24326941Sdim  // that macro names concatenate to the names of other macros.
25326941Sdim  MacroStack << " ";
26326941Sdim}
27326941Sdim
28326941Sdim/// Returns a string that represents all macro expansions that expanded into the
29326941Sdim/// given SourceLocation.
30326941Sdim///
31326941Sdim/// If 'getMacroStack(A) == getMacroStack(B)' is true, then the SourceLocations
32326941Sdim/// A and B are expanded from the same macros in the same order.
33326941Sdimstd::string getMacroStack(SourceLocation Loc, ASTContext &Context) {
34326941Sdim  std::string MacroStack;
35326941Sdim  llvm::raw_string_ostream MacroStackStream(MacroStack);
36326941Sdim  SourceManager &SM = Context.getSourceManager();
37326941Sdim
38326941Sdim  // Iterate over all macros that expanded into the given SourceLocation.
39326941Sdim  while (Loc.isMacroID()) {
40326941Sdim    // Add the macro name to the stream.
41326941Sdim    printMacroName(MacroStackStream, Context, Loc);
42326941Sdim    Loc = SM.getImmediateMacroCallerLoc(Loc);
43326941Sdim  }
44326941Sdim  MacroStackStream.flush();
45326941Sdim  return MacroStack;
46326941Sdim}
47326941Sdim
48326941Sdim} // end namespace data_collection
49326941Sdim} // end namespace clang
50