| 129 | } |
| 130 | |
| 131 | QString includeDirectiveArgumentFromPath(const Path& file, |
| 132 | const DeclarationPointer& declaration) |
| 133 | { |
| 134 | const auto includeManager = IDefinesAndIncludesManager::manager(); |
| 135 | const auto filePath = file.toLocalFile(); |
| 136 | const auto projectModel = ICore::self()->projectController()->projectModel(); |
| 137 | auto item = projectModel->itemForPath(IndexedStringView{filePath}); |
| 138 | |
| 139 | if (!item) { |
| 140 | // try the folder where the file is placed and guess includes from there |
| 141 | // prefer target over file |
| 142 | const IndexedStringView folderPath{file.parent().toLocalFile()}; |
| 143 | clangDebug() << "File not known, guessing includes from items in folder:" << folderPath; |
| 144 | |
| 145 | // default to the folder, if no targets or files |
| 146 | item = projectModel->itemForPath(folderPath); |
| 147 | if (item) { |
| 148 | const auto targetItems = item->targetList(); |
| 149 | bool itemChosen = false; |
| 150 | // Prefer items defined inside a target with non-empty includes. |
| 151 | for (const auto& targetItem : targetItems) { |
| 152 | item = targetItem; |
| 153 | if (!includeManager->includes(targetItem, IDefinesAndIncludesManager::ProjectSpecific).isEmpty()) { |
| 154 | clangDebug() << "Guessing includes from target" << targetItem->baseName(); |
| 155 | itemChosen = true; |
| 156 | break; |
| 157 | } |
| 158 | } |
| 159 | if (!itemChosen) { |
| 160 | const auto fileItems = item->fileList(); |
| 161 | // Prefer items defined inside a target with non-empty includes. |
| 162 | for (const auto& fileItem : fileItems) { |
| 163 | item = fileItem; |
| 164 | if (!includeManager->includes(fileItem, IDefinesAndIncludesManager::ProjectSpecific).isEmpty()) { |
| 165 | clangDebug() << "Guessing includes from file" << fileItem->baseName(); |
| 166 | break; |
| 167 | } |
| 168 | } |
| 169 | } |
| 170 | } |
| 171 | } |
| 172 | |
| 173 | const auto includePaths = includeManager->includes(item); |
| 174 | |
| 175 | if (includePaths.isEmpty()) { |
| 176 | clangDebug() << "Include path is empty"; |
| 177 | return {}; |
| 178 | } |
| 179 | |
| 180 | clangDebug() << "found include paths for" << file << ":" << includePaths; |
| 181 | |
| 182 | const auto includeFiles = UnknownDeclarationProblem::findMatchingIncludeFiles(QVector<Declaration*> {declaration.data()}); |
| 183 | if (includeFiles.isEmpty()) { |
| 184 | // return early as the computation of the include paths is quite expensive |
| 185 | return {}; |
| 186 | } |
| 187 | |
| 188 | // create include arguments for all candidates |
no test coverage detected