Как получить исходное местоположение #includes, используя clang libtooling?
Есть ли способ получить clang::SourceLocation
для каждого #include
в файле его clang::FileID
или же clang::FileEntry
или что-то?
2 ответа
Решение
Как насчет использования функции GetIncludedLoc менеджера исходного кода, которая принимает fileid в качестве параметра.
SourceManager.GetIncludedLoc (FILEID)
Спасибо @Hemant за ваш ответ, вы правы
Я уже нашел, что сам (в Clang 3.8 это называется getIncludeLoc
) но забыл написать здесь. Я использовал это, чтобы найти местоположение после всех #includes, где я могу поместить свое собственное. Вот функция (наверняка, не лучшим образом), которую я написал для этого, надеюсь, она кому-нибудь поможет
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);
}
Также некоторую информацию о включениях можно получить по
Preprocessor::GetIncludeFilenameSpelling(SourceLocation Loc, StringRef &Buffer)
а также
Lexer::ComputePreamble(StringRef Buffer, const LangOptions &LangOpts, unsigned MaxLines = 0)