1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #ifndef CustomTypeAnnotation_h__ 6 #define CustomTypeAnnotation_h__ 7 8 #include "CustomAttributes.h" 9 #include "plugin.h" 10 #include "llvm/ADT/BitmaskEnum.h" 11 12 class CustomTypeAnnotation { 13 enum ReasonKind { 14 RK_None, 15 RK_Direct, 16 RK_ArrayElement, 17 RK_BaseClass, 18 RK_Field, 19 RK_TemplateInherited, 20 RK_Implicit, 21 }; 22 struct AnnotationReason { 23 QualType Type; 24 ReasonKind Kind; 25 const FieldDecl *Field; 26 std::string ImplicitReason; 27 validAnnotationReason28 bool valid() const { return Kind != RK_None; } 29 }; 30 typedef DenseMap<void *, AnnotationReason> ReasonCache; 31 32 CustomAttributes Attribute; 33 const char *Pretty; 34 ReasonCache Cache; 35 36 public: CustomTypeAnnotation(CustomAttributes Attribute,const char * Pretty)37 CustomTypeAnnotation(CustomAttributes Attribute, const char *Pretty) 38 : Attribute(Attribute), Pretty(Pretty){}; 39 ~CustomTypeAnnotation()40 virtual ~CustomTypeAnnotation() {} 41 42 // Checks if this custom annotation "effectively affects" the given type. hasEffectiveAnnotation(QualType T)43 bool hasEffectiveAnnotation(QualType T) { 44 return directAnnotationReason(T).valid(); 45 } 46 void dumpAnnotationReason(BaseCheck &Check, QualType T, SourceLocation Loc); 47 reportErrorIfPresent(BaseCheck & Check,QualType T,SourceLocation Loc,const char * Error,const char * Note)48 void reportErrorIfPresent(BaseCheck &Check, QualType T, SourceLocation Loc, 49 const char *Error, const char *Note) { 50 if (hasEffectiveAnnotation(T)) { 51 Check.diag(Loc, Error, DiagnosticIDs::Error) << T; 52 Check.diag(Loc, Note, DiagnosticIDs::Note); 53 dumpAnnotationReason(Check, T, Loc); 54 } 55 } 56 57 private: 58 AnnotationReason directAnnotationReason(QualType T); 59 AnnotationReason tmplArgAnnotationReason(ArrayRef<TemplateArgument> Args); 60 61 protected: 62 // Flags specifying which properties of the underlying type we want to visit. 63 enum VisitFlags { 64 VISIT_NONE = 0, 65 VISIT_FIELDS = 1, 66 VISIT_TMPL_ARGS = 2, 67 VISIT_BASES = 4, 68 LLVM_MARK_AS_BITMASK_ENUM(VISIT_BASES) 69 }; 70 71 // Allow subclasses to apply annotations for reasons other than a direct 72 // annotation. A non-empty string return value means that the object D is 73 // annotated, and should contain the reason why. 74 // 75 // The subclass may also modify `VisitFlags` to change what properties of the 76 // type will be inspected to skip inspecting fields, force template arguments 77 // to be inspected, etc. getImplicitReason(const TagDecl * D,VisitFlags & Flags)78 virtual std::string getImplicitReason(const TagDecl *D, 79 VisitFlags &Flags) const { 80 return ""; 81 } 82 }; 83 84 extern CustomTypeAnnotation StackClass; 85 extern CustomTypeAnnotation GlobalClass; 86 extern CustomTypeAnnotation NonHeapClass; 87 extern CustomTypeAnnotation HeapClass; 88 extern CustomTypeAnnotation NonTemporaryClass; 89 extern CustomTypeAnnotation TemporaryClass; 90 extern CustomTypeAnnotation StaticLocalClass; 91 92 #endif 93