|
16 | 16 | #include "ParseJavadoc.hpp"
|
17 | 17 | #include "Support/Path.hpp"
|
18 | 18 | #include "Support/Debug.hpp"
|
| 19 | +#include "Tool/Diagnostics.hpp" |
19 | 20 | #include <mrdox/Metadata.hpp>
|
20 | 21 | #include <clang/AST/Attr.h>
|
21 | 22 | #include <clang/AST/Decl.h>
|
|
24 | 25 | #include <clang/Frontend/CompilerInstance.h>
|
25 | 26 | #include <clang/Index/USRGeneration.h>
|
26 | 27 | #include <clang/Lex/Lexer.h>
|
| 28 | +#include <clang/Sema/SemaConsumer.h> |
27 | 29 | #include <llvm/ADT/Hashing.h>
|
28 | 30 | #include <llvm/ADT/StringExtras.h>
|
29 | 31 | #include <llvm/Support/Error.h>
|
@@ -1712,25 +1714,8 @@ class ASTVisitor
|
1712 | 1714 | bool traverseContext(DeclContext* D);
|
1713 | 1715 | };
|
1714 | 1716 |
|
1715 |
| - |
1716 |
| - |
1717 |
| - |
1718 |
| - |
1719 |
| - |
1720 |
| - |
1721 |
| - |
1722 |
| - |
1723 |
| - |
1724 | 1717 | //------------------------------------------------
|
1725 | 1718 |
|
1726 |
| - |
1727 |
| - |
1728 |
| - |
1729 |
| - |
1730 |
| - |
1731 |
| - |
1732 |
| - |
1733 |
| - |
1734 | 1719 | bool
|
1735 | 1720 | ASTVisitor::
|
1736 | 1721 | traverse(NamespaceDecl* D)
|
@@ -2328,147 +2313,224 @@ traverseContext(
|
2328 | 2313 | return true;
|
2329 | 2314 | }
|
2330 | 2315 |
|
2331 |
| -} // (anon) |
2332 |
| - |
2333 | 2316 | //------------------------------------------------
|
2334 | 2317 | //
|
2335 | 2318 | // ASTVisitorConsumer
|
2336 | 2319 | //
|
2337 | 2320 | //------------------------------------------------
|
2338 | 2321 |
|
2339 |
| -ASTVisitorConsumer:: |
2340 |
| -ASTVisitorConsumer( |
2341 |
| - const ConfigImpl& config, |
2342 |
| - tooling::ExecutionContext& ex, |
2343 |
| - CompilerInstance& compiler) noexcept |
2344 |
| - : ex_(static_cast<ExecutionContext&>(ex)) |
2345 |
| - , config_(config) |
2346 |
| - , compiler_(compiler) |
| 2322 | +class ASTVisitorConsumer |
| 2323 | + : public SemaConsumer |
2347 | 2324 | {
|
2348 |
| -} |
| 2325 | + const ConfigImpl& config_; |
| 2326 | + ExecutionContext& ex_; |
| 2327 | + CompilerInstance& compiler_; |
2349 | 2328 |
|
2350 |
| -void |
2351 |
| -ASTVisitorConsumer:: |
2352 |
| -InitializeSema(Sema& S) |
2353 |
| -{ |
2354 |
| - // Sema should not have been initialized yet |
2355 |
| - MRDOX_ASSERT(! sema_); |
2356 |
| - sema_ = &S; |
2357 |
| -} |
| 2329 | + Sema* sema_ = nullptr; |
2358 | 2330 |
|
2359 |
| -void |
2360 |
| -ASTVisitorConsumer:: |
2361 |
| -ForgetSema() |
2362 |
| -{ |
2363 |
| - sema_ = nullptr; |
2364 |
| -} |
| 2331 | + void |
| 2332 | + InitializeSema(Sema& S) override |
| 2333 | + { |
| 2334 | + // Sema should not have been initialized yet |
| 2335 | + MRDOX_ASSERT(! sema_); |
| 2336 | + sema_ = &S; |
| 2337 | + } |
2365 | 2338 |
|
2366 |
| -void |
2367 |
| -ASTVisitorConsumer:: |
2368 |
| -HandleTranslationUnit( |
2369 |
| - ASTContext& Context) |
2370 |
| -{ |
2371 |
| - // the Sema better be valid |
2372 |
| - MRDOX_ASSERT(sema_); |
2373 |
| - |
2374 |
| - // initialize the diagnostics reporter first |
2375 |
| - // so errors prior to traversal are reported |
2376 |
| - Diagnostics diags; |
2377 |
| - |
2378 |
| - SourceManager& source = Context.getSourceManager(); |
2379 |
| - // get the name of the translation unit. |
2380 |
| - // will be std::nullopt_t if it isn't a file |
2381 |
| - std::optional<llvm::SmallString<128>> file_name = |
2382 |
| - source.getNonBuiltinFilenameForID(source.getMainFileID()); |
2383 |
| - // KRYSTIAN NOTE: should we report anything here? |
2384 |
| - if(! file_name) |
2385 |
| - return; |
| 2339 | + void |
| 2340 | + ForgetSema() override |
| 2341 | + { |
| 2342 | + sema_ = nullptr; |
| 2343 | + } |
2386 | 2344 |
|
2387 |
| - // skip the translation unit if configured to do so |
2388 |
| - if(! config_.shouldVisitTU( |
2389 |
| - convert_to_slash(*file_name))) |
2390 |
| - return; |
| 2345 | + void |
| 2346 | + HandleTranslationUnit(ASTContext& Context) override |
| 2347 | + { |
| 2348 | + // the Sema better be valid |
| 2349 | + MRDOX_ASSERT(sema_); |
| 2350 | + |
| 2351 | + // initialize the diagnostics reporter first |
| 2352 | + // so errors prior to traversal are reported |
| 2353 | + Diagnostics diags; |
| 2354 | + |
| 2355 | + SourceManager& source = Context.getSourceManager(); |
| 2356 | + // get the name of the translation unit. |
| 2357 | + // will be std::nullopt_t if it isn't a file |
| 2358 | + std::optional<llvm::SmallString<128>> file_name = |
| 2359 | + source.getNonBuiltinFilenameForID(source.getMainFileID()); |
| 2360 | + // KRYSTIAN NOTE: should we report anything here? |
| 2361 | + if(! file_name) |
| 2362 | + return; |
| 2363 | + |
| 2364 | + // skip the translation unit if configured to do so |
| 2365 | + if(! config_.shouldVisitTU( |
| 2366 | + convert_to_slash(*file_name))) |
| 2367 | + return; |
2391 | 2368 |
|
2392 |
| - ASTVisitor visitor( |
2393 |
| - config_, |
2394 |
| - diags, |
2395 |
| - compiler_, |
2396 |
| - Context, |
2397 |
| - *sema_); |
| 2369 | + ASTVisitor visitor( |
| 2370 | + config_, |
| 2371 | + diags, |
| 2372 | + compiler_, |
| 2373 | + Context, |
| 2374 | + *sema_); |
2398 | 2375 |
|
2399 |
| - // traverse the translation unit |
2400 |
| - visitor.traverseContext( |
2401 |
| - Context.getTranslationUnitDecl()); |
| 2376 | + // traverse the translation unit |
| 2377 | + visitor.traverseContext( |
| 2378 | + Context.getTranslationUnitDecl()); |
2402 | 2379 |
|
2403 |
| - // convert results to bitcode |
2404 |
| - for(auto& info : visitor.results()) |
2405 |
| - insertBitcode(ex_, writeBitcode(*info)); |
2406 |
| - |
2407 |
| - // VFALCO If we returned from the function early |
2408 |
| - // then this line won't execute, which means we |
2409 |
| - // will miss error and warnings emitted before |
2410 |
| - // the return. |
2411 |
| - ex_.report(std::move(diags)); |
2412 |
| -} |
| 2380 | + // convert results to bitcode |
| 2381 | + for(auto& info : visitor.results()) |
| 2382 | + insertBitcode(ex_, writeBitcode(*info)); |
| 2383 | + |
| 2384 | + // VFALCO If we returned from the function early |
| 2385 | + // then this line won't execute, which means we |
| 2386 | + // will miss error and warnings emitted before |
| 2387 | + // the return. |
| 2388 | + ex_.report(std::move(diags)); |
| 2389 | + } |
2413 | 2390 |
|
2414 |
| -/** Skip function bodies |
| 2391 | + /** Skip function bodies |
2415 | 2392 |
|
2416 |
| - This is called by Sema when parsing a function that has a body and: |
2417 |
| - - is constexpr, or |
2418 |
| - - uses a placeholder for a deduced return type |
| 2393 | + This is called by Sema when parsing a function that has a body and: |
| 2394 | + - is constexpr, or |
| 2395 | + - uses a placeholder for a deduced return type |
2419 | 2396 |
|
2420 |
| - We always return `true` because whenever this function *is* called, |
2421 |
| - it will be for a function that cannot be used in a constant expression, |
2422 |
| - nor one that introduces a new type via returning a local class. |
2423 |
| -*/ |
2424 |
| -bool |
2425 |
| -ASTVisitorConsumer:: |
2426 |
| -shouldSkipFunctionBody(Decl* D) |
| 2397 | + We always return `true` because whenever this function *is* called, |
| 2398 | + it will be for a function that cannot be used in a constant expression, |
| 2399 | + nor one that introduces a new type via returning a local class. |
| 2400 | + */ |
| 2401 | + bool |
| 2402 | + shouldSkipFunctionBody(Decl* D) override |
| 2403 | + { |
| 2404 | + return true; |
| 2405 | + } |
| 2406 | + |
| 2407 | + bool |
| 2408 | + HandleTopLevelDecl(DeclGroupRef DG) override |
| 2409 | + { |
| 2410 | + return true; |
| 2411 | + } |
| 2412 | + |
| 2413 | + ASTMutationListener* |
| 2414 | + GetASTMutationListener() override |
| 2415 | + { |
| 2416 | + return nullptr; |
| 2417 | + } |
| 2418 | + |
| 2419 | + void |
| 2420 | + HandleCXXStaticMemberVarInstantiation(VarDecl* D) override |
| 2421 | + { |
| 2422 | + // implicitly instantiated definitions of non-inline |
| 2423 | + // static data members of class templates are added to |
| 2424 | + // the end of the TU DeclContext. Decl::isImplicit returns |
| 2425 | + // false for these VarDecls, so we manually set it here. |
| 2426 | + D->setImplicit(); |
| 2427 | + } |
| 2428 | + |
| 2429 | + void |
| 2430 | + HandleCXXImplicitFunctionInstantiation(FunctionDecl* D) override |
| 2431 | + { |
| 2432 | + D->setImplicit(); |
| 2433 | + } |
| 2434 | + |
| 2435 | + void HandleInlineFunctionDefinition(FunctionDecl* D) override { } |
| 2436 | + void HandleTagDeclDefinition(TagDecl* D) { } |
| 2437 | + void HandleTagDeclRequiredDefinition(const TagDecl* D) override { } |
| 2438 | + void HandleInterestingDecl(DeclGroupRef DG) override { } |
| 2439 | + void CompleteTentativeDefinition(VarDecl* D) override { } |
| 2440 | + void CompleteExternalDeclaration(VarDecl* D) override { } |
| 2441 | + void AssignInheritanceModel(CXXRecordDecl* D) override { } |
| 2442 | + void HandleVTable(CXXRecordDecl* D) override { } |
| 2443 | + void HandleImplicitImportDecl(ImportDecl* D) override { } |
| 2444 | + void HandleTopLevelDeclInObjCContainer(DeclGroupRef DG) override { } |
| 2445 | + |
| 2446 | +public: |
| 2447 | + ASTVisitorConsumer( |
| 2448 | + const ConfigImpl& config, |
| 2449 | + tooling::ExecutionContext& ex, |
| 2450 | + CompilerInstance& compiler) noexcept |
| 2451 | + : ex_(static_cast<ExecutionContext&>(ex)) |
| 2452 | + , config_(config) |
| 2453 | + , compiler_(compiler) |
| 2454 | + { |
| 2455 | + } |
| 2456 | +}; |
| 2457 | + |
| 2458 | +//------------------------------------------------ |
| 2459 | +// |
| 2460 | +// ASTAction |
| 2461 | +// |
| 2462 | +//------------------------------------------------ |
| 2463 | + |
| 2464 | +struct ASTAction |
| 2465 | + : public clang::ASTFrontendAction |
2427 | 2466 | {
|
2428 |
| - return true; |
2429 |
| -} |
| 2467 | + ASTAction( |
| 2468 | + tooling::ExecutionContext& ex, |
| 2469 | + ConfigImpl const& config) noexcept |
| 2470 | + : ex_(ex) |
| 2471 | + , config_(config) |
| 2472 | + { |
| 2473 | + } |
2430 | 2474 |
|
2431 |
| -bool |
2432 |
| -ASTVisitorConsumer:: |
2433 |
| -HandleTopLevelDecl(DeclGroupRef D) |
2434 |
| -{ |
2435 |
| - return true; |
2436 |
| -} |
| 2475 | + bool |
| 2476 | + PrepareToExecuteAction( |
| 2477 | + CompilerInstance& Compiler) override |
| 2478 | + { |
| 2479 | + FrontendOptions& FEOpts = |
| 2480 | + Compiler.getFrontendOpts(); |
| 2481 | + FEOpts.SkipFunctionBodies = true; |
| 2482 | + return true; |
| 2483 | + } |
2437 | 2484 |
|
2438 |
| -ASTMutationListener* |
2439 |
| -ASTVisitorConsumer::GetASTMutationListener() |
2440 |
| -{ |
2441 |
| - return nullptr; |
2442 |
| -} |
| 2485 | + std::unique_ptr<clang::ASTConsumer> |
| 2486 | + CreateASTConsumer( |
| 2487 | + clang::CompilerInstance& Compiler, |
| 2488 | + llvm::StringRef InFile) override |
| 2489 | + { |
| 2490 | + return std::make_unique<ASTVisitorConsumer>( |
| 2491 | + config_, ex_, Compiler); |
| 2492 | + } |
| 2493 | + |
| 2494 | +private: |
| 2495 | + tooling::ExecutionContext& ex_; |
| 2496 | + ConfigImpl const& config_; |
| 2497 | +}; |
2443 | 2498 |
|
2444 |
| -void |
2445 |
| -ASTVisitorConsumer:: |
2446 |
| -HandleCXXStaticMemberVarInstantiation(VarDecl* D) |
| 2499 | +//------------------------------------------------ |
| 2500 | + |
| 2501 | +struct ASTActionFactory : |
| 2502 | + tooling::FrontendActionFactory |
2447 | 2503 | {
|
2448 |
| - // implicitly instantiated definitions of non-inline |
2449 |
| - // static data members of class templates are added to |
2450 |
| - // the end of the TU DeclContext. Decl::isImplicit returns |
2451 |
| - // false for these VarDecls, so we manually set it here. |
2452 |
| - D->setImplicit(); |
2453 |
| -} |
| 2504 | + ASTActionFactory( |
| 2505 | + tooling::ExecutionContext& ex, |
| 2506 | + ConfigImpl const& config) noexcept |
| 2507 | + : ex_(ex) |
| 2508 | + , config_(config) |
| 2509 | + { |
| 2510 | + } |
| 2511 | + |
| 2512 | + std::unique_ptr<FrontendAction> |
| 2513 | + create() override |
| 2514 | + { |
| 2515 | + return std::make_unique<ASTAction>(ex_, config_); |
| 2516 | + } |
| 2517 | + |
| 2518 | +private: |
| 2519 | + tooling::ExecutionContext& ex_; |
| 2520 | + ConfigImpl const& config_; |
| 2521 | +}; |
2454 | 2522 |
|
2455 |
| -void |
2456 |
| -ASTVisitorConsumer:: |
2457 |
| -HandleCXXImplicitFunctionInstantiation(FunctionDecl* D) |
| 2523 | +} // (anon) |
| 2524 | + |
| 2525 | +//------------------------------------------------ |
| 2526 | + |
| 2527 | +std::unique_ptr<tooling::FrontendActionFactory> |
| 2528 | +makeFrontendActionFactory( |
| 2529 | + tooling::ExecutionContext& ex, |
| 2530 | + ConfigImpl const& config) |
2458 | 2531 | {
|
2459 |
| - D->setImplicit(); |
| 2532 | + return std::make_unique<ASTActionFactory>(ex, config); |
2460 | 2533 | }
|
2461 | 2534 |
|
2462 |
| -void ASTVisitorConsumer::HandleInlineFunctionDefinition(FunctionDecl* D) { } |
2463 |
| -void ASTVisitorConsumer::HandleTagDeclDefinition(TagDecl* D) { } |
2464 |
| -void ASTVisitorConsumer::HandleTagDeclRequiredDefinition(const TagDecl* D) { } |
2465 |
| -void ASTVisitorConsumer::HandleInterestingDecl(DeclGroupRef D) { } |
2466 |
| -void ASTVisitorConsumer::CompleteTentativeDefinition(VarDecl* D) { } |
2467 |
| -void ASTVisitorConsumer::CompleteExternalDeclaration(VarDecl* D) { } |
2468 |
| -void ASTVisitorConsumer::AssignInheritanceModel(CXXRecordDecl* D) { } |
2469 |
| -void ASTVisitorConsumer::HandleVTable(CXXRecordDecl* D) { } |
2470 |
| -void ASTVisitorConsumer::HandleImplicitImportDecl(ImportDecl* D) { } |
2471 |
| -void ASTVisitorConsumer::HandleTopLevelDeclInObjCContainer(DeclGroupRef D) { } |
2472 |
| - |
2473 | 2535 | } // mrdox
|
2474 | 2536 | } // clang
|
0 commit comments