1e5dd7070Spatrick //===-- DataCollection.cpp --------------------------------------*- C++ -*-===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick
9e5dd7070Spatrick #include "clang/AST/DataCollection.h"
10*ec727ea7Spatrick #include "clang/Basic/SourceManager.h"
11e5dd7070Spatrick #include "clang/Lex/Lexer.h"
12e5dd7070Spatrick
13e5dd7070Spatrick namespace clang {
14e5dd7070Spatrick namespace data_collection {
15e5dd7070Spatrick
16e5dd7070Spatrick /// Prints the macro name that contains the given SourceLocation into the given
17e5dd7070Spatrick /// raw_string_ostream.
printMacroName(llvm::raw_string_ostream & MacroStack,ASTContext & Context,SourceLocation Loc)18e5dd7070Spatrick static void printMacroName(llvm::raw_string_ostream &MacroStack,
19e5dd7070Spatrick ASTContext &Context, SourceLocation Loc) {
20e5dd7070Spatrick MacroStack << Lexer::getImmediateMacroName(Loc, Context.getSourceManager(),
21e5dd7070Spatrick Context.getLangOpts());
22e5dd7070Spatrick
23e5dd7070Spatrick // Add an empty space at the end as a padding to prevent
24e5dd7070Spatrick // that macro names concatenate to the names of other macros.
25e5dd7070Spatrick MacroStack << " ";
26e5dd7070Spatrick }
27e5dd7070Spatrick
28e5dd7070Spatrick /// Returns a string that represents all macro expansions that expanded into the
29e5dd7070Spatrick /// given SourceLocation.
30e5dd7070Spatrick ///
31e5dd7070Spatrick /// If 'getMacroStack(A) == getMacroStack(B)' is true, then the SourceLocations
32e5dd7070Spatrick /// A and B are expanded from the same macros in the same order.
getMacroStack(SourceLocation Loc,ASTContext & Context)33e5dd7070Spatrick std::string getMacroStack(SourceLocation Loc, ASTContext &Context) {
34e5dd7070Spatrick std::string MacroStack;
35e5dd7070Spatrick llvm::raw_string_ostream MacroStackStream(MacroStack);
36e5dd7070Spatrick SourceManager &SM = Context.getSourceManager();
37e5dd7070Spatrick
38e5dd7070Spatrick // Iterate over all macros that expanded into the given SourceLocation.
39e5dd7070Spatrick while (Loc.isMacroID()) {
40e5dd7070Spatrick // Add the macro name to the stream.
41e5dd7070Spatrick printMacroName(MacroStackStream, Context, Loc);
42e5dd7070Spatrick Loc = SM.getImmediateMacroCallerLoc(Loc);
43e5dd7070Spatrick }
44e5dd7070Spatrick MacroStackStream.flush();
45e5dd7070Spatrick return MacroStack;
46e5dd7070Spatrick }
47e5dd7070Spatrick
48e5dd7070Spatrick } // end namespace data_collection
49e5dd7070Spatrick } // end namespace clang
50