ffrankies created this revision.
ffrankies added a reviewer: alexfh.
ffrankies created this object with visibility "All Users".
ffrankies added a project: clang-tools-extra.
Herald added subscribers: arphaman, xazax.hun, Anastasia, mgorny, srhines.
Herald added a reviewer: jdoerfert.
Herald added a project: clang.

This lint check is a part of the FLOCL (**F**PGA **L**inters for 
**O**pen**CL**) project out of the Synergy Lab at Virginia Tech.

FLOCL is a set of lint checks aimed at FPGA developers who write code in OpenCL.

The FPGA struct pack align lint check finds structs that are inefficiently 
packed or aligned and recommends packing/aligning of the structs using the 
packed and aligned attributes as needed in a warning.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D66564

Files:
  clang-tidy/fpga/CMakeLists.txt
  clang-tidy/fpga/FPGATidyModule.cpp
  clang-tidy/fpga/StructPackAlignCheck.cpp
  clang-tidy/fpga/StructPackAlignCheck.h
  docs/clang-tidy/checks/fpga-struct-pack-align.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/index.rst
  test/clang-tidy/fpga-struct-pack-align.cpp

Index: test/clang-tidy/fpga-struct-pack-align.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/fpga-struct-pack-align.cpp
@@ -0,0 +1,74 @@
+// RUN: %check_clang_tidy %s fpga-struct-pack-align %t -- -header-filter=.* "--" --include opencl-c.h -cl-std=CL1.2 -c 
+
+// Struct needs both alignment and packing
+struct error {
+char a;
+double b;
+char c;
+};
+// CHECK-MESSAGES: :[[@LINE-5]]:8: warning: struct 'error' has inefficient access due to padding, only needs 10 bytes but is using 24 bytes, use "__attribute((packed))" [fpga-struct-pack-align]
+// CHECK-MESSAGES: :[[@LINE-6]]:8: warning: struct 'error' has inefficient access due to poor alignment. Currently aligned to 8 bytes, but size 10 bytes is large enough to benefit from "__attribute((aligned(16)))" [fpga-struct-pack-align]
+
+// Struct is explicitly packed, but needs alignment
+struct error_packed {
+char a;
+double b;
+char c;
+} __attribute((packed));
+// CHECK-MESSAGES: :[[@LINE-5]]:8: warning: struct 'error_packed' has inefficient access due to poor alignment. Currently aligned to 1 bytes, but size 10 bytes is large enough to benefit from "__attribute((aligned(16)))" [fpga-struct-pack-align]
+
+// Struct is properly packed, but needs alignment
+struct align_only {
+char a;
+char b;
+char c;
+char d;
+int e;
+double f;
+};
+// CHECK-MESSAGES: :[[@LINE-8]]:8: warning: struct 'align_only' has inefficient access due to poor alignment. Currently aligned to 8 bytes, but size 16 bytes is large enough to benefit from "__attribute((aligned(16)))" [fpga-struct-pack-align]
+
+// Struct is perfectly packed but wrongly aligned
+struct bad_align {
+char a;
+double b;
+char c;
+} __attribute((packed)) __attribute((aligned(8)));
+// CHECK-MESSAGES: :[[@LINE-5]]:8: warning: struct 'bad_align' has inefficient access due to poor alignment. Currently aligned to 8 bytes, but size 10 bytes is large enough to benefit from "__attribute((aligned(16)))" [fpga-struct-pack-align]
+
+struct bad_align2 {
+char a;
+double b;
+char c;
+} __attribute((packed)) __attribute((aligned(32)));
+// CHECK-MESSAGES: :[[@LINE-5]]:8: warning: struct 'bad_align2' has inefficient access due to poor alignment. Currently aligned to 32 bytes, but size 10 bytes is large enough to benefit from "__attribute((aligned(16)))" [fpga-struct-pack-align]
+
+struct bad_align3 {
+char a;
+double b;
+char c;
+} __attribute((packed)) __attribute((aligned(4)));
+// CHECK-MESSAGES: :[[@LINE-5]]:8: warning: struct 'bad_align3' has inefficient access due to poor alignment. Currently aligned to 4 bytes, but size 10 bytes is large enough to benefit from "__attribute((aligned(16)))" [fpga-struct-pack-align]
+
+// Struct is both perfectly packed and aligned
+struct success {
+char a;
+double b;
+char c;
+} __attribute((packed)) __attribute((aligned(16)));
+//Should take 10 bytes and be aligned to 16 bytes
+
+// Struct is properly packed, and explicitly aligned
+struct success2 {
+int a;
+int b;
+int c;
+} __attribute((aligned(16)));
+
+// If struct is properly aligned, packing not needed
+struct error_aligned {
+char a;
+double b;
+char c;
+} __attribute((aligned(16)));
+
Index: docs/clang-tidy/index.rst
===================================================================
--- docs/clang-tidy/index.rst
+++ docs/clang-tidy/index.rst
@@ -64,6 +64,7 @@
 ``cert-``              Checks related to CERT Secure Coding Guidelines.
 ``cppcoreguidelines-`` Checks related to C++ Core Guidelines.
 ``clang-analyzer-``    Clang Static Analyzer checks.
+``fpga-``              Checks related to OpenCL programming for FPGAs..
 ``fuchsia-``           Checks related to Fuchsia coding conventions.
 ``google-``            Checks related to Google coding conventions.
 ``hicpp-``             Checks related to High Integrity C++ Coding Standard.
Index: docs/clang-tidy/checks/list.rst
===================================================================
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -4,7 +4,6 @@
 =================
 
 .. toctree::
-
    abseil-duration-addition
    abseil-duration-comparison
    abseil-duration-conversion-cast
@@ -19,8 +18,6 @@
    abseil-redundant-strcat-calls
    abseil-str-cat-append
    abseil-string-find-startswith
-   abseil-time-comparison
-   abseil-time-subtraction
    abseil-upgrade-duration-conversions
    android-cloexec-accept
    android-cloexec-accept4
@@ -33,15 +30,12 @@
    android-cloexec-inotify-init1
    android-cloexec-memfd-create
    android-cloexec-open
-   android-cloexec-pipe
-   android-cloexec-pipe2
    android-cloexec-socket
    android-comparison-in-temp-failure-retry
    boost-use-to-string
    bugprone-argument-comment
    bugprone-assert-side-effect
    bugprone-bool-pointer-implicit-conversion
-   bugprone-branch-clone
    bugprone-copy-constructor-init
    bugprone-dangling-handle
    bugprone-exception-escape
@@ -59,7 +53,6 @@
    bugprone-move-forwarding-reference
    bugprone-multiple-statement-macro
    bugprone-parent-virtual-call
-   bugprone-posix-return
    bugprone-sizeof-container
    bugprone-sizeof-expression
    bugprone-string-constructor
@@ -76,7 +69,6 @@
    bugprone-too-small-loop-variable
    bugprone-undefined-memory-manipulation
    bugprone-undelegated-constructor
-   bugprone-unhandled-self-assignment
    bugprone-unused-raii
    bugprone-unused-return-value
    bugprone-use-after-move
@@ -102,96 +94,10 @@
    cert-msc50-cpp
    cert-msc51-cpp
    cert-oop11-cpp (redirects to performance-move-constructor-init) <cert-oop11-cpp>
-   cert-oop54-cpp (redirects to bugprone-unhandled-self-assignment) <cert-oop54-cpp>
-   clang-analyzer-core.CallAndMessage
-   clang-analyzer-core.DivideZero
-   clang-analyzer-core.DynamicTypePropagation
-   clang-analyzer-core.NonNullParamChecker
-   clang-analyzer-core.NullDereference
-   clang-analyzer-core.StackAddressEscape
-   clang-analyzer-core.UndefinedBinaryOperatorResult
-   clang-analyzer-core.VLASize
-   clang-analyzer-core.uninitialized.ArraySubscript
-   clang-analyzer-core.uninitialized.Assign
-   clang-analyzer-core.uninitialized.Branch
-   clang-analyzer-core.uninitialized.CapturedBlockVariable
-   clang-analyzer-core.uninitialized.UndefReturn
-   clang-analyzer-cplusplus.InnerPointer
-   clang-analyzer-cplusplus.Move
-   clang-analyzer-cplusplus.NewDelete
-   clang-analyzer-cplusplus.NewDeleteLeaks
-   clang-analyzer-deadcode.DeadStores
-   clang-analyzer-nullability.NullPassedToNonnull
-   clang-analyzer-nullability.NullReturnedFromNonnull
-   clang-analyzer-nullability.NullableDereferenced
-   clang-analyzer-nullability.NullablePassedToNonnull
-   clang-analyzer-nullability.NullableReturnedFromNonnull
-   clang-analyzer-optin.cplusplus.UninitializedObject
-   clang-analyzer-optin.cplusplus.VirtualCall
-   clang-analyzer-optin.mpi.MPI-Checker
-   clang-analyzer-optin.osx.OSObjectCStyleCast
-   clang-analyzer-optin.osx.cocoa.localizability.EmptyLocalizationContextChecker
-   clang-analyzer-optin.osx.cocoa.localizability.NonLocalizedStringChecker
-   clang-analyzer-optin.performance.GCDAntipattern
-   clang-analyzer-optin.performance.Padding
-   clang-analyzer-optin.portability.UnixAPI
-   clang-analyzer-osx.API
-   clang-analyzer-osx.MIG
-   clang-analyzer-osx.NumberObjectConversion
-   clang-analyzer-osx.OSObjectRetainCount
-   clang-analyzer-osx.ObjCProperty
-   clang-analyzer-osx.SecKeychainAPI
-   clang-analyzer-osx.cocoa.AtSync
-   clang-analyzer-osx.cocoa.AutoreleaseWrite
-   clang-analyzer-osx.cocoa.ClassRelease
-   clang-analyzer-osx.cocoa.Dealloc
-   clang-analyzer-osx.cocoa.IncompatibleMethodTypes
-   clang-analyzer-osx.cocoa.Loops
-   clang-analyzer-osx.cocoa.MissingSuperCall
-   clang-analyzer-osx.cocoa.NSAutoreleasePool
-   clang-analyzer-osx.cocoa.NSError
-   clang-analyzer-osx.cocoa.NilArg
-   clang-analyzer-osx.cocoa.NonNilReturnValue
-   clang-analyzer-osx.cocoa.ObjCGenerics
-   clang-analyzer-osx.cocoa.RetainCount
-   clang-analyzer-osx.cocoa.RunLoopAutoreleaseLeak
-   clang-analyzer-osx.cocoa.SelfInit
-   clang-analyzer-osx.cocoa.SuperDealloc
-   clang-analyzer-osx.cocoa.UnusedIvars
-   clang-analyzer-osx.cocoa.VariadicMethodTypes
-   clang-analyzer-osx.coreFoundation.CFError
-   clang-analyzer-osx.coreFoundation.CFNumber
-   clang-analyzer-osx.coreFoundation.CFRetainRelease
-   clang-analyzer-osx.coreFoundation.containers.OutOfBounds
-   clang-analyzer-osx.coreFoundation.containers.PointerSizedValues
-   clang-analyzer-security.FloatLoopCounter
-   clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling
-   clang-analyzer-security.insecureAPI.UncheckedReturn
-   clang-analyzer-security.insecureAPI.bcmp
-   clang-analyzer-security.insecureAPI.bcopy
-   clang-analyzer-security.insecureAPI.bzero
-   clang-analyzer-security.insecureAPI.getpw
-   clang-analyzer-security.insecureAPI.gets
-   clang-analyzer-security.insecureAPI.mkstemp
-   clang-analyzer-security.insecureAPI.mktemp
-   clang-analyzer-security.insecureAPI.rand
-   clang-analyzer-security.insecureAPI.strcpy
-   clang-analyzer-security.insecureAPI.vfork
-   clang-analyzer-unix.API
-   clang-analyzer-unix.Malloc
-   clang-analyzer-unix.MallocSizeof
-   clang-analyzer-unix.MismatchedDeallocator
-   clang-analyzer-unix.Vfork
-   clang-analyzer-unix.cstring.BadSizeArg
-   clang-analyzer-unix.cstring.NullArg
-   clang-analyzer-valist.CopyToSelf
-   clang-analyzer-valist.Uninitialized
-   clang-analyzer-valist.Unterminated
    cppcoreguidelines-avoid-c-arrays (redirects to modernize-avoid-c-arrays) <cppcoreguidelines-avoid-c-arrays>
    cppcoreguidelines-avoid-goto
    cppcoreguidelines-avoid-magic-numbers (redirects to readability-magic-numbers) <cppcoreguidelines-avoid-magic-numbers>
    cppcoreguidelines-c-copy-assignment-signature (redirects to misc-unconventional-assign-operator) <cppcoreguidelines-c-copy-assignment-signature>
-   cppcoreguidelines-explicit-virtual-functions (redirects to modernize-use-override) <cppcoreguidelines-explicit-virtual-functions>
    cppcoreguidelines-interfaces-global-init
    cppcoreguidelines-macro-usage
    cppcoreguidelines-narrowing-conversions
@@ -210,8 +116,8 @@
    cppcoreguidelines-pro-type-vararg
    cppcoreguidelines-slicing
    cppcoreguidelines-special-member-functions
-   fuchsia-default-arguments-calls
-   fuchsia-default-arguments-declarations
+   fpga-struct-pack-align
+   fuchsia-default-arguments
    fuchsia-header-anon-namespaces (redirects to google-build-namespaces) <fuchsia-header-anon-namespaces>
    fuchsia-multiple-inheritance
    fuchsia-overloaded-operator
@@ -225,7 +131,6 @@
    google-default-arguments
    google-explicit-constructor
    google-global-names-in-headers
-   google-objc-avoid-nsobject-new
    google-objc-avoid-throwing-exception
    google-objc-function-naming
    google-objc-global-variable-declaration
@@ -238,7 +143,6 @@
    google-runtime-int
    google-runtime-operator
    google-runtime-references
-   google-upgrade-googletest-case
    hicpp-avoid-c-arrays (redirects to modernize-avoid-c-arrays) <hicpp-avoid-c-arrays>
    hicpp-avoid-goto
    hicpp-braces-around-statements (redirects to readability-braces-around-statements) <hicpp-braces-around-statements>
@@ -269,11 +173,9 @@
    hicpp-use-nullptr (redirects to modernize-use-nullptr) <hicpp-use-nullptr>
    hicpp-use-override (redirects to modernize-use-override) <hicpp-use-override>
    hicpp-vararg (redirects to cppcoreguidelines-pro-type-vararg) <hicpp-vararg>
-   linuxkernel-must-use-errs
    llvm-header-guard
    llvm-include-order
    llvm-namespace-comment
-   llvm-prefer-isa-or-dyn-cast-in-conditionals
    llvm-twine-local
    misc-definitions-in-headers
    misc-misplaced-const
@@ -314,7 +216,6 @@
    modernize-use-noexcept
    modernize-use-nullptr
    modernize-use-override
-   modernize-use-trailing-return-type
    modernize-use-transparent-functors
    modernize-use-uncaught-exceptions
    modernize-use-using
@@ -324,9 +225,6 @@
    objc-avoid-spinlock
    objc-forbidden-subclassing
    objc-property-declaration
-   objc-super-self
-   openmp-exception-escape
-   openmp-use-default-none
    performance-faster-string-find
    performance-for-range-copy
    performance-implicit-conversion-in-loop
@@ -344,7 +242,6 @@
    readability-braces-around-statements
    readability-const-return-type
    readability-container-size-empty
-   readability-convert-member-functions-to-static
    readability-delete-null-pointer
    readability-deleted-default
    readability-else-after-return
Index: docs/clang-tidy/checks/fpga-struct-pack-align.rst
===================================================================
--- /dev/null
+++ docs/clang-tidy/checks/fpga-struct-pack-align.rst
@@ -0,0 +1,49 @@
+.. title:: clang-tidy - fpga-struct-pack-align
+
+fpga-struct-pack-align
+======================
+
+Finds structs that are inefficiently packed or aligned, and recommends
+packing and/or aligning of said structs as needed. 
+
+Structs that are not packed take up more space than they should, and accessing 
+structs that are not well aligned is inefficient.
+
+Based on the "Altera SDK for OpenCL: Best Practices Guide".
+
+.. code-block:: c++
+
+  // The following struct is originally aligned to 4 bytes, and thus takes up
+  // 12 bytes of memory instead of 10. Packing the struct will make it use
+  // only 10 bytes of memory, and aligning it to 16 bytes will make it 
+  // efficient to access. 
+  struct example {
+    char a;    // 1 byte
+    double b;  // 8 bytes
+    char c;    // 1 byte
+  };
+
+  // The following struct is arranged in such a way that packing is not needed.
+  // However, it is aligned to 4 bytes instead of 8, and thus needs to be 
+  // explicitly aligned.
+  struct implicitly_packed_example {
+    char a;  // 1 byte
+    char b;  // 1 byte
+    char c;  // 1 byte
+    char d;  // 1 byte
+    int e;   // 4 bytes
+  };
+
+  // The following struct is explicitly aligned and packed. 
+  struct good_example {
+    char a;    // 1 byte
+    double b;  // 8 bytes
+    char c;    // 1 byte
+  } __attribute((packed)) __attribute((aligned(16));
+
+  // Explicitly aligning a struct to a bad value will result in a warning
+  struct badly_aligned_example {
+    char a;    // 1 byte
+    double b;  // 8 bytes
+    char c;    // 1 byte
+  } __attribute((packed)) __attribute((aligned(32)));
Index: clang-tidy/fpga/StructPackAlignCheck.h
===================================================================
--- /dev/null
+++ clang-tidy/fpga/StructPackAlignCheck.h
@@ -0,0 +1,36 @@
+//===--- StructPackAlignCheck.h - clang-tidy---------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FPGA_STRUCT_PACK_ALIGN_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FPGA_STRUCT_PACK_ALIGN_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace FPGA {
+
+/// Finds structs that are inefficiently packed or aligned, and recommends
+/// packing and/or aligning of said structs as needed.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/FPGA-struct-pack-align.html
+class StructPackAlignCheck : public ClangTidyCheck {
+public:
+  StructPackAlignCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace FPGA
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FPGA_STRUCT_PACK_ALIGN_H
Index: clang-tidy/fpga/StructPackAlignCheck.cpp
===================================================================
--- /dev/null
+++ clang-tidy/fpga/StructPackAlignCheck.cpp
@@ -0,0 +1,113 @@
+//===--- StructPackAlignCheck.cpp - clang-tidy-----------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef MAX_ALIGN_POWER_OF_TWO
+#define MAX_ALIGN_POWER_OF_TWO 7
+#endif
+
+#include "StructPackAlignCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecordLayout.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace FPGA {
+
+void StructPackAlignCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(recordDecl(isStruct()).bind("struct"), this);
+}
+
+void StructPackAlignCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *Struct = Result.Nodes.getNodeAs<RecordDecl>("struct");
+  const auto *StructDef = Struct->getDefinition();
+  
+  // If not a definition, do nothing
+  if (Struct != StructDef) return;
+  
+  // Get sizing info for the struct
+  std::vector<std::pair<unsigned int, unsigned int>> FieldSizes;
+  unsigned int TotalBitSize = 0;
+  for (auto StructField : Struct->fields()) {  
+    // For each StructField, record how big it is (in bits)
+    // Would be good to use a pair of <offset, size> to advise a better 
+    // packing order
+    unsigned int StructFieldWidth = (unsigned int)Result.Context->getTypeInfo(
+        StructField->getType().getTypePtr()).Width;
+    FieldSizes.push_back(std::pair<unsigned int, unsigned int>(
+                         StructFieldWidth, StructField->getFieldIndex()));
+    // TODO: Recommend a reorganization of the struct (sort by StructField size, 
+    // largest to smallest)
+    TotalBitSize += StructFieldWidth;
+  }
+  // TODO: Express this as CharUnit rather than a hardcoded 8-bits (Rshift3)i
+  // After computing the minimum size in bits, check for an existing alignment
+  // flag
+  CharUnits CurrSize = Result.Context->getASTRecordLayout(Struct).getSize();
+  CharUnits MinByteSize = CharUnits::fromQuantity((TotalBitSize +7) >> 3);
+  CharUnits CurrAlign = Result.Context->getASTRecordLayout(
+      Struct).getAlignment();
+  CharUnits NewAlign = CharUnits::fromQuantity(1);
+  if (!MinByteSize.isPowerOfTwo()) {
+    int MSB = (int)MinByteSize.getQuantity();
+    for (; MSB > 0; MSB >>= 1) {
+      NewAlign = NewAlign.alignTo(CharUnits::fromQuantity(
+                                  ((int)NewAlign.getQuantity()) << 1));
+      //Abort if the computed alignment meets the maximum configured alignment
+      if (NewAlign.getQuantity() >= (1 << MAX_ALIGN_POWER_OF_TWO)) break; 
+    }
+  } else {
+    NewAlign = MinByteSize;
+  }
+  
+  // Check if struct has a "packed" attribute
+  bool IsPacked = false;
+  if (Struct->hasAttrs()) {
+    for (auto StructAttribute : Struct->getAttrs()) {
+      if (std::string(StructAttribute->getSpelling()).compare("packed") == 0) {
+        IsPacked = true;
+        break;
+      }
+    }
+  }
+
+  // If it's using much more space than it needs, suggest packing.
+  // (Do not suggest packing if it is currently explicitly aligned to what the
+  // minimum byte size would suggest as the new alignment)
+  if (MinByteSize < CurrSize && 
+      ((Struct->getMaxAlignment()>>3) != NewAlign.getQuantity()) && 
+      (CurrSize != NewAlign) && 
+      !IsPacked) {
+    diag(Struct->getLocation(), 
+         "struct %0 has inefficient access due to padding, only needs %1 bytes "
+         "but is using %2 bytes, use \"__attribute((packed))\"")
+	    << Struct
+	    << (int)MinByteSize.getQuantity()
+	    << (int)CurrSize.getQuantity();
+  }
+
+  // And suggest the minimum power-of-two alignment for the struct as a whole
+  // (with and without packing)
+  if (CurrAlign.getQuantity() != NewAlign.getQuantity()) {
+    diag(Struct->getLocation(), 
+         "struct %0 has inefficient access due to poor alignment. Currently "
+         "aligned to %1 bytes, but size %3 bytes is large enough to benefit "
+         "from \"__attribute((aligned(%2)))\"")
+	    << Struct
+	    << (int)CurrAlign.getQuantity()
+	    << (int)NewAlign.getQuantity()
+	    << (int)MinByteSize.getQuantity(); 
+  }
+}
+
+} // namespace FPGA
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/fpga/FPGATidyModule.cpp
===================================================================
--- /dev/null
+++ clang-tidy/fpga/FPGATidyModule.cpp
@@ -0,0 +1,39 @@
+//===--- OpenCLTidyModule.cpp - clang-tidy --------------------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../ClangTidy.h"
+#include "../ClangTidyModule.h"
+#include "../ClangTidyModuleRegistry.h"
+#include "StructPackAlignCheck.h"
+
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace FPGA {
+
+class FPGAModule : public ClangTidyModule {
+public:
+  void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
+    CheckFactories.registerCheck<StructPackAlignCheck>(
+        "fpga-struct-pack-align");
+  }
+};
+
+static ClangTidyModuleRegistry::Add<FPGAModule> X("fpga-module", "Adds Altera FPGA OpenCL lint checks.");
+
+} // namespace flocl
+
+// This anchor is used to force the linker to link in the generated object file
+// and thus register the MyModule.
+volatile int FPGAModuleAnchorSource = 0;
+
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/fpga/CMakeLists.txt
===================================================================
--- /dev/null
+++ clang-tidy/fpga/CMakeLists.txt
@@ -0,0 +1,14 @@
+set(LLVM_LINK_COMPONENTS support)
+
+add_clang_library(clangTidyFPGAModule
+  FPGATidyModule.cpp
+  StructPackAlignCheck.cpp
+  
+  LINK_LIBS
+  clangAST
+  clangASTMatchers
+  clangBasic
+  clangLex
+  clangTidy
+  clangTidyUtils
+  )
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to