2016-12-18 00:35:53 +03:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
#ifndef CustomTypeAnnotation_h__
|
|
|
|
#define CustomTypeAnnotation_h__
|
|
|
|
|
2018-09-18 16:03:33 +03:00
|
|
|
#include "CustomAttributes.h"
|
2016-12-18 00:35:53 +03:00
|
|
|
#include "plugin.h"
|
|
|
|
|
|
|
|
class CustomTypeAnnotation {
|
|
|
|
enum ReasonKind {
|
|
|
|
RK_None,
|
|
|
|
RK_Direct,
|
|
|
|
RK_ArrayElement,
|
|
|
|
RK_BaseClass,
|
|
|
|
RK_Field,
|
|
|
|
RK_TemplateInherited,
|
2017-04-27 19:44:55 +03:00
|
|
|
RK_Implicit,
|
2016-12-18 00:35:53 +03:00
|
|
|
};
|
|
|
|
struct AnnotationReason {
|
|
|
|
QualType Type;
|
|
|
|
ReasonKind Kind;
|
|
|
|
const FieldDecl *Field;
|
2017-04-27 19:44:55 +03:00
|
|
|
std::string ImplicitReason;
|
2016-12-18 00:35:53 +03:00
|
|
|
|
|
|
|
bool valid() const { return Kind != RK_None; }
|
|
|
|
};
|
|
|
|
typedef DenseMap<void *, AnnotationReason> ReasonCache;
|
|
|
|
|
2018-09-18 16:03:33 +03:00
|
|
|
CustomAttributes Attribute;
|
2016-12-18 00:35:53 +03:00
|
|
|
const char *Pretty;
|
|
|
|
ReasonCache Cache;
|
|
|
|
|
|
|
|
public:
|
2018-09-18 16:03:33 +03:00
|
|
|
CustomTypeAnnotation(CustomAttributes Attribute, const char *Pretty)
|
|
|
|
: Attribute(Attribute), Pretty(Pretty){};
|
2016-12-18 00:35:53 +03:00
|
|
|
|
|
|
|
virtual ~CustomTypeAnnotation() {}
|
|
|
|
|
|
|
|
// Checks if this custom annotation "effectively affects" the given type.
|
|
|
|
bool hasEffectiveAnnotation(QualType T) {
|
|
|
|
return directAnnotationReason(T).valid();
|
|
|
|
}
|
2017-10-20 20:11:50 +03:00
|
|
|
void dumpAnnotationReason(BaseCheck &Check, QualType T, SourceLocation Loc);
|
2016-12-18 00:35:53 +03:00
|
|
|
|
2017-10-20 20:11:50 +03:00
|
|
|
void reportErrorIfPresent(BaseCheck &Check, QualType T, SourceLocation Loc,
|
|
|
|
const char *Error, const char *Note) {
|
2016-12-18 00:35:53 +03:00
|
|
|
if (hasEffectiveAnnotation(T)) {
|
2016-12-18 05:14:37 +03:00
|
|
|
Check.diag(Loc, Error, DiagnosticIDs::Error) << T;
|
|
|
|
Check.diag(Loc, Note, DiagnosticIDs::Note);
|
|
|
|
dumpAnnotationReason(Check, T, Loc);
|
2016-12-18 00:35:53 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
AnnotationReason directAnnotationReason(QualType T);
|
|
|
|
AnnotationReason tmplArgAnnotationReason(ArrayRef<TemplateArgument> Args);
|
|
|
|
|
|
|
|
protected:
|
2017-04-27 19:44:55 +03:00
|
|
|
// Allow subclasses to apply annotations for reasons other than a direct
|
|
|
|
// annotation. A non-empty string return value means that the object D is
|
|
|
|
// annotated, and should contain the reason why.
|
|
|
|
virtual std::string getImplicitReason(const TagDecl *D) const { return ""; }
|
2016-12-18 00:35:53 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
extern CustomTypeAnnotation StackClass;
|
|
|
|
extern CustomTypeAnnotation GlobalClass;
|
|
|
|
extern CustomTypeAnnotation NonHeapClass;
|
|
|
|
extern CustomTypeAnnotation HeapClass;
|
|
|
|
extern CustomTypeAnnotation NonTemporaryClass;
|
2018-02-01 02:03:26 +03:00
|
|
|
extern CustomTypeAnnotation TemporaryClass;
|
2019-07-30 21:50:52 +03:00
|
|
|
extern CustomTypeAnnotation StaticLocalClass;
|
2016-12-18 00:35:53 +03:00
|
|
|
|
|
|
|
#endif
|