| 186 | } |
| 187 | |
| 188 | void HandleTranslationUnit(ASTContext& context) override |
| 189 | { |
| 190 | gAST = &context; |
| 191 | auto& sm = context.getSourceManager(); |
| 192 | |
| 193 | auto isExpansionInSystemHeader = [&sm](const Decl* d) { |
| 194 | auto expansionLoc = sm.getExpansionLoc(d->getLocation()); |
| 195 | |
| 196 | return expansionLoc.isInvalid() or sm.isInSystemHeader(expansionLoc); |
| 197 | }; |
| 198 | |
| 199 | const auto& mainFileId = sm.getMainFileID(); |
| 200 | |
| 201 | mRewriter.ReplaceText({sm.getLocForStartOfFile(mainFileId), sm.getLocForEndOfFile(mainFileId)}, ""); |
| 202 | |
| 203 | OutputFormatHelper outputFormatHelper{}; |
| 204 | CodeGeneratorVariant codeGenerator{outputFormatHelper}; |
| 205 | |
| 206 | auto include = mIncludes.begin(); |
| 207 | |
| 208 | auto insertBlankLineIfRequired = [&](std::optional<SourceLocation>& lastLoc, SourceLocation nextLoc) { |
| 209 | if(lastLoc.has_value() and |
| 210 | (2 <= (sm.getSpellingLineNumber(nextLoc) - sm.getSpellingLineNumber(lastLoc.value())))) { |
| 211 | outputFormatHelper.AppendNewLine(); |
| 212 | } |
| 213 | |
| 214 | lastLoc = nextLoc; |
| 215 | }; |
| 216 | |
| 217 | for(std::optional<SourceLocation> lastLoc{}; const auto* d : context.getTranslationUnitDecl()->decls()) { |
| 218 | if(isExpansionInSystemHeader(d)) { |
| 219 | continue; |
| 220 | } |
| 221 | |
| 222 | // includes before this decl |
| 223 | for(; (mIncludes.end() != include) and (include->first < d->getLocation()); include = std::next(include)) { |
| 224 | insertBlankLineIfRequired(lastLoc, include->first); |
| 225 | outputFormatHelper.Append(include->second); |
| 226 | } |
| 227 | |
| 228 | // ignore includes inside this decl |
| 229 | include = std::find_if_not(include, mIncludes.end(), [&](auto& inc) { |
| 230 | return ((inc.first >= d->getLocation()) and (inc.first <= d->getEndLoc())); |
| 231 | }); |
| 232 | |
| 233 | if(isa<LinkageSpecDecl>(d) and d->isImplicit()) { |
| 234 | continue; |
| 235 | |
| 236 | // Only handle explicit specializations here. Implicit ones are handled by the `VarTemplateDecl` |
| 237 | // itself. |
| 238 | } else if(const auto* vdspec = dyn_cast_or_null<VarTemplateSpecializationDecl>(d); |
| 239 | vdspec and (TSK_ExplicitSpecialization != vdspec->getSpecializationKind())) { |
| 240 | continue; |
| 241 | } |
| 242 | |
| 243 | insertBlankLineIfRequired(lastLoc, d->getLocation()); |
| 244 | |
| 245 | codeGenerator->InsertArg(d); |
nothing calls this directly
no test coverage detected