| 95 | } |
| 96 | |
| 97 | SourceLocation includeHashLoc(FileID IncludedFile, const SourceManager& SM) { |
| 98 | assert(SM.getLocForEndOfFile(IncludedFile).isFileID()); |
| 99 | FileID IncludingFile; |
| 100 | unsigned Offset; |
| 101 | std::tie(IncludingFile, Offset) = SM.getDecomposedExpansionLoc(SM.getIncludeLoc(IncludedFile)); |
| 102 | bool Invalid = false; |
| 103 | llvm::StringRef Buf = SM.getBufferData(IncludingFile, &Invalid); |
| 104 | if(Invalid) |
| 105 | return SourceLocation(); |
| 106 | // Now buf is "...\n#include <foo>\n..." |
| 107 | // and Offset points here: ^ |
| 108 | // Rewind to the preceding # on the line. |
| 109 | assert(Offset < Buf.size()); |
| 110 | for(;; --Offset) { |
| 111 | if(Buf[Offset] == '#') |
| 112 | return SM.getComposedLoc(IncludingFile, Offset); |
| 113 | if(Buf[Offset] == '\n' || Offset == 0) // no hash, what's going on? |
| 114 | return SourceLocation(); |
| 115 | } |
| 116 | } |
| 117 | |
| 118 | // Given a range whose endpoints may be in different expansions or files, |
| 119 | // tries to find a range within a common file by following up the expansion and |