Add an error for pointers in structs (#379)

Fixes #376

* Add a frontend diagnostic if a structure contains a pointer
  * tests
diff --git a/lib/FrontendPlugin.cpp b/lib/FrontendPlugin.cpp
index 39b4bd0..4c72a1f 100644
--- a/lib/FrontendPlugin.cpp
+++ b/lib/FrontendPlugin.cpp
@@ -54,10 +54,27 @@
     CustomDiagnosticSSBOUnalignedArray = 14,
     CustomDiagnosticSSBOUnalignedStruct = 15,
     CustomDiagnosticOverloadedKernel = 16,
+    CustomDiagnosticStructContainsPointer = 17,
     CustomDiagnosticTotal
   };
   std::vector<unsigned> CustomDiagnosticsIDMap;
 
+  bool ContainsPointerType(QualType QT) {
+    auto canonical = QT.getCanonicalType();
+    if (canonical->isPointerType()) {
+      return true;
+    } else if (auto *AT = dyn_cast<ArrayType>(canonical)) {
+      return ContainsPointerType(AT->getElementType());
+    } else if (auto *RT = dyn_cast<RecordType>(canonical)) {
+      for (auto field_decl : RT->getDecl()->fields()) {
+        if (ContainsPointerType(field_decl->getType()))
+          return true;
+      }
+    }
+
+    return false;
+  }
+
   bool IsSupportedType(QualType QT, SourceRange SR) {
     auto *Ty = QT.getTypePtr();
 
@@ -83,6 +100,14 @@
             CustomDiagnosticsIDMap[CustomDiagnosticVectorsMoreThan4Elements]);
         return false;
       }
+    } else if (canonicalType->isRecordType()) {
+      // Structures should not contain pointers.
+      if (ContainsPointerType(canonicalType)) {
+        Instance.getDiagnostics().Report(
+            SR.getBegin(),
+            CustomDiagnosticsIDMap[CustomDiagnosticStructContainsPointer]);
+        return false;
+      }
     }
 
     return true;
@@ -409,6 +434,9 @@
     CustomDiagnosticsIDMap[CustomDiagnosticOverloadedKernel] =
         DE.getCustomDiagID(DiagnosticsEngine::Error,
                            "kernel functions can't be overloaded");
+    CustomDiagnosticsIDMap[CustomDiagnosticStructContainsPointer] =
+        DE.getCustomDiagID(DiagnosticsEngine::Error,
+                           "structures may not contain pointers");
   }
 
   virtual bool HandleTopLevelDecl(DeclGroupRef DG) override {