2
0

RecyclerChecker.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #pragma once
  6. #include <unordered_set>
  7. #include <queue>
  8. #include "clang/Frontend/FrontendPluginRegistry.h"
  9. #include "clang/AST/AST.h"
  10. #include "clang/AST/ASTConsumer.h"
  11. #include "clang/AST/RecursiveASTVisitor.h"
  12. #include "clang/Frontend/CompilerInstance.h"
  13. #include "clang/Rewrite/Core/Rewriter.h"
  14. #include "clang/Sema/Sema.h"
  15. #include "Helpers.h"
  16. using namespace std;
  17. using namespace clang;
  18. // To record seen allocators with a Type
  19. //
  20. enum AllocationTypes
  21. {
  22. Unknown = 0x0, // e.g. template dependent
  23. NonRecycler = 0x1, // Heap, Arena, JitArena, ...
  24. Recycler = 0x2, // Recycler
  25. WriteBarrier = 0x4, // Recycler write barrier
  26. RecyclerWriteBarrier = Recycler | WriteBarrier,
  27. };
  28. class MainVisitor:
  29. public RecursiveASTVisitor<MainVisitor>
  30. {
  31. private:
  32. CompilerInstance& _compilerInstance;
  33. ASTContext& _context;
  34. Rewriter _rewriter;
  35. bool _fix; // whether user requested to fix missing annotations
  36. bool _fixed; // whether this plugin committed any annotation fixes
  37. bool _barrierTypeDefined;
  38. map<string, set<string>> _allocatorTypeMap;
  39. set<string> _pointerClasses;
  40. set<string> _barrieredClasses;
  41. map<const Type*, int> _allocationTypes; // {type -> AllocationTypes}
  42. public:
  43. MainVisitor(CompilerInstance& compilerInstance, ASTContext& context, bool fix);
  44. const ASTContext& getContext() const { return _context; }
  45. bool VisitCXXRecordDecl(CXXRecordDecl* recordDecl);
  46. bool VisitFunctionDecl(FunctionDecl* functionDecl);
  47. void RecordAllocation(QualType qtype, AllocationTypes allocationType);
  48. void RecordRecyclerAllocation(
  49. const string& allocationFunction, const string& type);
  50. void Inspect();
  51. bool ApplyFix();
  52. private:
  53. template <class Set, class DumpItemFunc>
  54. void dump(const char* name, const Set& set, const DumpItemFunc& func);
  55. template <class Item>
  56. void dump(const char* name, const set<Item>& set);
  57. void dump(const char* name, const unordered_set<const Type*> set);
  58. template <class PushFieldType>
  59. void ProcessUnbarrieredFields(CXXRecordDecl* recordDecl, const PushFieldType& pushFieldType);
  60. bool MatchType(const string& type, const char* source, const char** pSourceEnd);
  61. const char* GetFieldTypeAnnotation(QualType qtype);
  62. };
  63. class CheckAllocationsInFunctionVisitor:
  64. public RecursiveASTVisitor<CheckAllocationsInFunctionVisitor>
  65. {
  66. public:
  67. CheckAllocationsInFunctionVisitor(
  68. MainVisitor* mainVisitor, FunctionDecl* functionDecl)
  69. : _mainVisitor(mainVisitor), _functionDecl(functionDecl)
  70. {}
  71. bool VisitCXXNewExpr(CXXNewExpr* newExpression);
  72. bool VisitCallExpr(CallExpr* callExpr);
  73. private:
  74. MainVisitor* _mainVisitor;
  75. FunctionDecl* _functionDecl;
  76. template <class A0, class A1, class T>
  77. void VisitAllocate(const A0& getArg0, const A1& getArg1, const T& getAllocType);
  78. };
  79. class RecyclerCheckerConsumer: public ASTConsumer
  80. {
  81. private:
  82. CompilerInstance& _compilerInstance;
  83. bool _fix; // whether user requested to fix missing annotations
  84. public:
  85. RecyclerCheckerConsumer(CompilerInstance& compilerInstance, bool fix)
  86. : _compilerInstance(compilerInstance), _fix(fix)
  87. {}
  88. void HandleTranslationUnit(ASTContext& context);
  89. };
  90. class RecyclerCheckerAction: public PluginASTAction
  91. {
  92. private:
  93. bool _fix; // whether user requested to fix missing annotations
  94. public:
  95. RecyclerCheckerAction() : _fix(false) {}
  96. protected:
  97. std::unique_ptr<ASTConsumer> CreateASTConsumer(
  98. CompilerInstance& compilerInstance, llvm::StringRef) override;
  99. bool ParseArgs(
  100. const CompilerInstance& compilerInstance,
  101. const std::vector<std::string>& args) override;
  102. };