xref: /netbsd-src/external/apache2/llvm/dist/clang/lib/AST/DataCollection.cpp (revision e038c9c4676b0f19b1b7dd08a940c6ed64a6d5ae)
17330f729Sjoerg //===-- DataCollection.cpp --------------------------------------*- C++ -*-===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg 
97330f729Sjoerg #include "clang/AST/DataCollection.h"
10*e038c9c4Sjoerg #include "clang/Basic/SourceManager.h"
117330f729Sjoerg #include "clang/Lex/Lexer.h"
127330f729Sjoerg 
137330f729Sjoerg namespace clang {
147330f729Sjoerg namespace data_collection {
157330f729Sjoerg 
167330f729Sjoerg /// Prints the macro name that contains the given SourceLocation into the given
177330f729Sjoerg /// raw_string_ostream.
printMacroName(llvm::raw_string_ostream & MacroStack,ASTContext & Context,SourceLocation Loc)187330f729Sjoerg static void printMacroName(llvm::raw_string_ostream &MacroStack,
197330f729Sjoerg                            ASTContext &Context, SourceLocation Loc) {
207330f729Sjoerg   MacroStack << Lexer::getImmediateMacroName(Loc, Context.getSourceManager(),
217330f729Sjoerg                                              Context.getLangOpts());
227330f729Sjoerg 
237330f729Sjoerg   // Add an empty space at the end as a padding to prevent
247330f729Sjoerg   // that macro names concatenate to the names of other macros.
257330f729Sjoerg   MacroStack << " ";
267330f729Sjoerg }
277330f729Sjoerg 
287330f729Sjoerg /// Returns a string that represents all macro expansions that expanded into the
297330f729Sjoerg /// given SourceLocation.
307330f729Sjoerg ///
317330f729Sjoerg /// If 'getMacroStack(A) == getMacroStack(B)' is true, then the SourceLocations
327330f729Sjoerg /// A and B are expanded from the same macros in the same order.
getMacroStack(SourceLocation Loc,ASTContext & Context)337330f729Sjoerg std::string getMacroStack(SourceLocation Loc, ASTContext &Context) {
347330f729Sjoerg   std::string MacroStack;
357330f729Sjoerg   llvm::raw_string_ostream MacroStackStream(MacroStack);
367330f729Sjoerg   SourceManager &SM = Context.getSourceManager();
377330f729Sjoerg 
387330f729Sjoerg   // Iterate over all macros that expanded into the given SourceLocation.
397330f729Sjoerg   while (Loc.isMacroID()) {
407330f729Sjoerg     // Add the macro name to the stream.
417330f729Sjoerg     printMacroName(MacroStackStream, Context, Loc);
427330f729Sjoerg     Loc = SM.getImmediateMacroCallerLoc(Loc);
437330f729Sjoerg   }
447330f729Sjoerg   MacroStackStream.flush();
457330f729Sjoerg   return MacroStack;
467330f729Sjoerg }
477330f729Sjoerg 
487330f729Sjoerg } // end namespace data_collection
497330f729Sjoerg } // end namespace clang
50