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