xref: /openbsd-src/gnu/llvm/clang/lib/AST/DataCollection.cpp (revision ec727ea710c91afd8ce4f788c5aaa8482b7b69b2)
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