Is there any way to get clang::SourceLocation
for every #include
in file by its clang::FileID
or clang::FileEntry
or something?
Asked
Active
Viewed 1,194 times
2

Mike Kinghan
- 55,740
- 12
- 153
- 182

Yuriy
- 701
- 4
- 18
2 Answers
2
What about using source manager's GetIncludedLoc function which takes fileid as parameter.
SourceManager.GetIncludedLoc(fileid)

Hemant
- 767
- 6
- 20
-
Once I have the include location, how do I navigate between the includes include? I'm using this to inject an include statement but it goes before the comments of the copyright which is not what I want. – emitrax Mar 09 '21 at 15:05
-
This is a good tip, but the method name is `getIncludeLoc` (and has been since its [introduction](https://github.com/llvm/llvm-project/commit/61ef3db22246)). – Scott McPeak Jul 20 '23 at 04:47
1
Thank's @Hemant for your answer, you're right
I Already found that by myself (in clang 3.8 it is called getIncludeLoc
)
but forgot to write here.
I used this to find the location after all #includes where i can put my own.
Here's the function (For sure not the best way) I wrote for this, hope it helps someone
SourceLocation getIncludeLocation(FileID fileID, SourceManager &sm, unsigned carriages) {
return SourceLocation();
set<unsigned> lines;
if (fileID.isInvalid())
for (auto it = sm.fileinfo_begin(); it != sm.fileinfo_end(); it++) {
SourceLocation includeLoc = sm.getIncludeLoc(sm.translateFile(it->first));
if (includeLoc.isValid() && sm.isInFileID(includeLoc, fileID)) {
lines.insert(sm.getSpellingLineNumber(includeLoc));
}
}
unsigned pos(0);
if (!lines.empty()) {
bool first = true;
for (unsigned line :lines) {
if (first)
first = false;
else if ((line - pos) > carriages)
break;
pos = line;
//cout << "Include line:" << pos << endl;
}
//cout << console_hline('-') << endl;
}
cout << sm.getFileEntryForID(fileID)->getName() << endl;
return sm.translateFileLineCol(sm.getFileEntryForID(fileID), ++pos, 1);
}
Also some information about includes can be get by
Preprocessor::GetIncludeFilenameSpelling(SourceLocation Loc, StringRef &Buffer)
and
Lexer::ComputePreamble(StringRef Buffer, const LangOptions &LangOpts, unsigned MaxLines = 0)

Yuriy
- 701
- 4
- 18