Bug 1187073 - Add the MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS annotation to clang-plugin. r=ehsan
authorMichael Layzell <michael@thelayzells.com>
Fri, 24 Jul 2015 12:52:00 -0400
changeset 287632 c6b30a85cc23d50197e799b31fee20ba1585554e
parent 287631 79d3b8d912500dfc4705573c8036a0b9c91575f7
child 287633 635fb4ea6b503321347b17a69f980b83430559b0
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs1187073
milestone42.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1187073 - Add the MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS annotation to clang-plugin. r=ehsan
build/clang-plugin/clang-plugin.cpp
build/clang-plugin/tests/TestInheritTypeAnnotationsFromTemplateArgs.cpp
build/clang-plugin/tests/moz.build
--- a/build/clang-plugin/clang-plugin.cpp
+++ b/build/clang-plugin/clang-plugin.cpp
@@ -236,16 +236,17 @@ bool isInterestingDeclForImplicitConvers
 
 class CustomTypeAnnotation {
   enum ReasonKind {
     RK_None,
     RK_Direct,
     RK_ArrayElement,
     RK_BaseClass,
     RK_Field,
+    RK_TemplateInherited,
   };
   struct AnnotationReason {
     QualType Type;
     ReasonKind Kind;
     const FieldDecl *Field;
 
     bool valid() const { return Kind != RK_None; }
   };
@@ -837,16 +838,25 @@ void CustomTypeAnnotation::dumpAnnotatio
         Diag.Report(Decl->getLocation(), InheritsID)
           << Pretty << T << Reason.Type;
         break;
       }
     case RK_Field:
       Diag.Report(Reason.Field->getLocation(), MemberID)
         << Pretty << T << Reason.Field << Reason.Type;
       break;
+    case RK_TemplateInherited:
+      {
+        const CXXRecordDecl *Decl = T->getAsCXXRecordDecl();
+        assert(Decl && "This type should be a C++ class");
+
+        Diag.Report(Decl->getLocation(), TemplID)
+          << Pretty << T << Reason.Type;
+        break;
+      }
     default:
       return;
     }
 
     T = Reason.Type;
     Reason = directAnnotationReason(T);
   }
 }
@@ -900,16 +910,39 @@ CustomTypeAnnotation::AnnotationReason C
       // Recurse into members
       for (const FieldDecl *Field : Decl->fields()) {
         if (hasEffectiveAnnotation(Field->getType())) {
           AnnotationReason Reason = { Field->getType(), RK_Field, Field };
           Cache[Key] = Reason;
           return Reason;
         }
       }
+
+      // Recurse into template arguments if the annotation
+      // MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS is present
+      if (MozChecker::hasCustomAnnotation(
+            Decl, "moz_inherit_type_annotations_from_template_args")) {
+        const ClassTemplateSpecializationDecl *Spec =
+          dyn_cast<ClassTemplateSpecializationDecl>(Decl);
+        if (Spec) {
+          const TemplateArgumentList &Args = Spec->getTemplateArgs();
+
+          for (const TemplateArgument &Arg : Args.asArray()) {
+            if (Arg.getKind() == TemplateArgument::Type) {
+              QualType Type = Arg.getAsType();
+
+              if (hasEffectiveAnnotation(Type)) {
+                AnnotationReason Reason = { Type, RK_TemplateInherited, nullptr };
+                Cache[Key] = Reason;
+                return Reason;
+              }
+            }
+          }
+        }
+      }
     }
   }
 
   AnnotationReason Reason = { QualType(), RK_None, nullptr };
   Cache[Key] = Reason;
   return Reason;
 }
 
new file mode 100644
--- /dev/null
+++ b/build/clang-plugin/tests/TestInheritTypeAnnotationsFromTemplateArgs.cpp
@@ -0,0 +1,17 @@
+#define MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS                 \
+  __attribute__((annotate("moz_inherit_type_annotations_from_template_args")))
+#define MOZ_STACK_CLASS __attribute__((annotate("moz_stack_class")))
+
+class Normal {};
+class MOZ_STACK_CLASS Stack {};
+class IndirectStack : Stack {}; // expected-note {{'IndirectStack' is a stack type because it inherits from a stack type 'Stack'}}
+
+template<class T>
+class MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS Template {}; // expected-note 2 {{'Template<Stack>' is a stack type because it has a template argument stack type 'Stack'}} expected-note {{'Template<IndirectStack>' is a stack type because it has a template argument stack type 'IndirectStack'}}
+class IndirectTemplate : Template<Stack> {}; // expected-note {{'IndirectTemplate' is a stack type because it inherits from a stack type 'Template<Stack>'}}
+
+static Template<Stack> a; // expected-error {{variable of type 'Template<Stack>' only valid on the stack}}
+static Template<IndirectStack> b; // expected-error {{variable of type 'Template<IndirectStack>' only valid on the stack}}
+static Template<Normal> c;
+static IndirectTemplate d; // expected-error {{variable of type 'IndirectTemplate' only valid on the stack}}
+
--- a/build/clang-plugin/tests/moz.build
+++ b/build/clang-plugin/tests/moz.build
@@ -4,16 +4,17 @@
 # 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/.
 
 SOURCES += [
     'TestBadImplicitConversionCtor.cpp',
     'TestCustomHeap.cpp',
     'TestExplicitOperatorBool.cpp',
     'TestGlobalClass.cpp',
+    'TestInheritTypeAnnotationsFromTemplateArgs.cpp',
     'TestMultipleAnnotations.cpp',
     'TestMustOverride.cpp',
     'TestMustUse.cpp',
     'TestNANTestingExpr.cpp',
     'TestNANTestingExprC.c',
     'TestNeedsNoVTableType.cpp',
     'TestNoAddRefReleaseOnReturn.cpp',
     'TestNoArithmeticExprInArgument.cpp',