//===--- StructPackAlignCheck.cpp - clang-tidy ----------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "StructPackAlignCheck.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/RecordLayout.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include <math.h>

using namespace clang::ast_matchers;

namespace clang {
namespace tidy {
namespace altera {

void StructPackAlignCheck::registerMatchers(MatchFinder *Finder) {
  Finder->addMatcher(recordDecl(isStruct(), isDefinition(),
                                unless(isExpansionInSystemHeader()))
                         .bind("struct"),
                     this);
}

CharUnits
StructPackAlignCheck::computeRecommendedAlignment(CharUnits MinByteSize) {
  CharUnits NewAlign = CharUnits::fromQuantity(1);
  if (!MinByteSize.isPowerOfTwo()) {
    int MSB = (int)MinByteSize.getQuantity();
    for (; MSB > 0; MSB /= 2) {
      NewAlign = NewAlign.alignTo(
          CharUnits::fromQuantity(((int)NewAlign.getQuantity()) * 2));
      // Abort if the computed alignment meets the maximum configured alignment.
      if (NewAlign.getQuantity() >= MaxConfiguredAlignment)
        break;
    }
  } else {
    NewAlign = MinByteSize;
  }
  return NewAlign;
}

void StructPackAlignCheck::check(const MatchFinder::MatchResult &Result) {
  const auto *Struct = Result.Nodes.getNodeAs<RecordDecl>("struct");

  // Do not trigger on templated struct declarations because the packing and
  // alignment requirements are unknown.
  if (Struct->isTemplated())
     return;

  // Get sizing info for the struct.
  llvm::SmallVector<std::pair<unsigned int, unsigned int>, 10> FieldSizes;
  unsigned int TotalBitSize = 0;
  for (const FieldDecl *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.
    QualType StructFieldTy = StructField->getType();
    if (StructFieldTy->isIncompleteType())
      return;
    unsigned int StructFieldWidth =
        (unsigned int)Result.Context->getTypeInfo(StructFieldTy.getTypePtr())
            .Width;
    FieldSizes.emplace_back(StructFieldWidth, StructField->getFieldIndex());
    // FIXME: Recommend a reorganization of the struct (sort by StructField
    // size, largest to smallest).
    TotalBitSize += StructFieldWidth;
  }

  uint64_t CharSize = Result.Context->getCharWidth();
  CharUnits CurrSize = Result.Context->getASTRecordLayout(Struct).getSize();
  CharUnits MinByteSize =
      CharUnits::fromQuantity(ceil((float)TotalBitSize / CharSize));
  CharUnits MaxAlign = CharUnits::fromQuantity(
      ceil((float)Struct->getMaxAlignment() / CharSize));
  CharUnits CurrAlign =
      Result.Context->getASTRecordLayout(Struct).getAlignment();
  CharUnits NewAlign = computeRecommendedAlignment(MinByteSize);

  bool IsPacked = Struct->hasAttr<PackedAttr>();
  bool NeedsPacking = (MinByteSize < CurrSize) && (MaxAlign != NewAlign) &&
                      (CurrSize != NewAlign);
  bool NeedsAlignment = CurrAlign.getQuantity() != NewAlign.getQuantity();

  if (!NeedsAlignment && !NeedsPacking)
    return;

  // 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 (NeedsPacking && !IsPacked) {
    diag(Struct->getLocation(),
         "accessing fields in struct %0 is inefficient due to padding; only "
         "needs %1 bytes but is using %2 bytes")
        << Struct << (int)MinByteSize.getQuantity()
        << (int)CurrSize.getQuantity()
        << FixItHint::CreateInsertion(Struct->getEndLoc().getLocWithOffset(1),
                                      " __attribute__((packed))");
    diag(Struct->getLocation(),
         "use \"__attribute__((packed))\" to reduce the amount of padding "
         "applied to struct %0",
         DiagnosticIDs::Note)
        << Struct;
  }

  FixItHint FixIt;
  AlignedAttr *Attribute = Struct->getAttr<AlignedAttr>();
  std::string NewAlignQuantity = std::to_string((int)NewAlign.getQuantity());
  if (Attribute) {
    FixIt = FixItHint::CreateReplacement(
        Attribute->getRange(),
        (Twine("aligned(") + NewAlignQuantity + ")").str());
  } else {
    FixIt = FixItHint::CreateInsertion(
        Struct->getEndLoc().getLocWithOffset(1),
        (Twine(" __attribute__((aligned(") + NewAlignQuantity + ")))").str());
  }

  // And suggest the minimum power-of-two alignment for the struct as a whole
  // (with and without packing).
  if (NeedsAlignment) {
    diag(Struct->getLocation(),
         "accessing fields in struct %0 is inefficient due to poor alignment; "
         "currently aligned to %1 bytes, but recommended alignment is %2 bytes")
        << Struct << (int)CurrAlign.getQuantity() << NewAlignQuantity << FixIt;

    diag(Struct->getLocation(),
         "use \"__attribute__((aligned(%0)))\" to align struct %1 to %0 bytes",
         DiagnosticIDs::Note)
        << NewAlignQuantity << Struct;
  }
}

void StructPackAlignCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
  Options.store(Opts, "MaxConfiguredAlignment", MaxConfiguredAlignment);
}

} // namespace altera
} // namespace tidy
} // namespace clang
