// RUN: %check_clang_tidy %s performance-unnecessary-copy-initialization %t

struct ExpensiveToCopyType {
  ExpensiveToCopyType();
  virtual ~ExpensiveToCopyType();
  const ExpensiveToCopyType &reference() const;
  void nonConstMethod();
  bool constMethod() const;
};

struct TrivialToCopyType {
  const TrivialToCopyType &reference() const;
};

struct WeirdCopyCtorType {
  WeirdCopyCtorType();
  WeirdCopyCtorType(const WeirdCopyCtorType &w, bool oh_yes = true);

  void nonConstMethod();
  bool constMethod() const;
};

ExpensiveToCopyType global_expensive_to_copy_type;

const ExpensiveToCopyType &ExpensiveTypeReference();
const TrivialToCopyType &TrivialTypeReference();

void mutate(ExpensiveToCopyType &);
void mutate(ExpensiveToCopyType *);
void useAsConstPointer(const ExpensiveToCopyType *);
void useAsConstReference(const ExpensiveToCopyType &);
void useByValue(ExpensiveToCopyType);

void PositiveFunctionCall() {
  const auto AutoAssigned = ExpensiveTypeReference();
  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoAssigned' is copy-constructed from a const reference; consider making it a const reference [performance-unnecessary-copy-initialization]
  // CHECK-FIXES: const auto& AutoAssigned = ExpensiveTypeReference();
  const auto AutoCopyConstructed(ExpensiveTypeReference());
  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoCopyConstructed'
  // CHECK-FIXES: const auto& AutoCopyConstructed(ExpensiveTypeReference());
  const ExpensiveToCopyType VarAssigned = ExpensiveTypeReference();
  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable 'VarAssigned'
  // CHECK-FIXES:   const ExpensiveToCopyType& VarAssigned = ExpensiveTypeReference();
  const ExpensiveToCopyType VarCopyConstructed(ExpensiveTypeReference());
  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable 'VarCopyConstructed'
  // CHECK-FIXES: const ExpensiveToCopyType& VarCopyConstructed(ExpensiveTypeReference());
}

void PositiveMethodCallConstReferenceParam(const ExpensiveToCopyType &Obj) {
  const auto AutoAssigned = Obj.reference();
  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoAssigned'
  // CHECK-FIXES: const auto& AutoAssigned = Obj.reference();
  const auto AutoCopyConstructed(Obj.reference());
  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoCopyConstructed'
  // CHECK-FIXES: const auto& AutoCopyConstructed(Obj.reference());
  const ExpensiveToCopyType VarAssigned = Obj.reference();
  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable 'VarAssigned'
  // CHECK-FIXES: const ExpensiveToCopyType& VarAssigned = Obj.reference();
  const ExpensiveToCopyType VarCopyConstructed(Obj.reference());
  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable 'VarCopyConstructed'
  // CHECK-FIXES: const ExpensiveToCopyType& VarCopyConstructed(Obj.reference());
}

void PositiveMethodCallConstParam(const ExpensiveToCopyType Obj) {
  const auto AutoAssigned = Obj.reference();
  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoAssigned'
  // CHECK-FIXES: const auto& AutoAssigned = Obj.reference();
  const auto AutoCopyConstructed(Obj.reference());
  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoCopyConstructed'
  // CHECK-FIXES: const auto& AutoCopyConstructed(Obj.reference());
  const ExpensiveToCopyType VarAssigned = Obj.reference();
  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable 'VarAssigned'
  // CHECK-FIXES: const ExpensiveToCopyType& VarAssigned = Obj.reference();
  const ExpensiveToCopyType VarCopyConstructed(Obj.reference());
  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable 'VarCopyConstructed'
  // CHECK-FIXES: const ExpensiveToCopyType& VarCopyConstructed(Obj.reference());
}

void PositiveMethodCallConstPointerParam(const ExpensiveToCopyType *const Obj) {
  const auto AutoAssigned = Obj->reference();
  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoAssigned'
  // CHECK-FIXES: const auto& AutoAssigned = Obj->reference();
  const auto AutoCopyConstructed(Obj->reference());
  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoCopyConstructed'
  // CHECK-FIXES: const auto& AutoCopyConstructed(Obj->reference());
  const ExpensiveToCopyType VarAssigned = Obj->reference();
  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable 'VarAssigned'
  // CHECK-FIXES: const ExpensiveToCopyType& VarAssigned = Obj->reference();
  const ExpensiveToCopyType VarCopyConstructed(Obj->reference());
  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: the const qualified variable 'VarCopyConstructed'
  // CHECK-FIXES: const ExpensiveToCopyType& VarCopyConstructed(Obj->reference());
}

void PositiveLocalConstValue() {
  const ExpensiveToCopyType Obj;
  const auto UnnecessaryCopy = Obj.reference();
  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'UnnecessaryCopy'
  // CHECK-FIXES: const auto& UnnecessaryCopy = Obj.reference();
}

void PositiveLocalConstRef() {
  const ExpensiveToCopyType Obj;
  const ExpensiveToCopyType &ConstReference = Obj.reference();
  const auto UnnecessaryCopy = ConstReference.reference();
  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'UnnecessaryCopy'
  // CHECK-FIXES: const auto& UnnecessaryCopy = ConstReference.reference();
}

void PositiveLocalConstPointer() {
  const ExpensiveToCopyType Obj;
  const ExpensiveToCopyType *const ConstPointer = &Obj;
  const auto UnnecessaryCopy = ConstPointer->reference();
  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'UnnecessaryCopy'
  // CHECK-FIXES: const auto& UnnecessaryCopy = ConstPointer->reference();
}

void NegativeFunctionCallTrivialType() {
  const auto AutoAssigned = TrivialTypeReference();
  const auto AutoCopyConstructed(TrivialTypeReference());
  const TrivialToCopyType VarAssigned = TrivialTypeReference();
  const TrivialToCopyType VarCopyConstructed(TrivialTypeReference());
}

void NegativeStaticLocalVar(const ExpensiveToCopyType &Obj) {
  static const auto StaticVar = Obj.reference();
}

void PositiveFunctionCallExpensiveTypeNonConstVariable() {
  auto AutoAssigned = ExpensiveTypeReference();
  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: the variable 'AutoAssigned' is copy-constructed from a const reference but is only used as const reference; consider making it a const reference [performance-unnecessary-copy-initialization]
  // CHECK-FIXES: const auto& AutoAssigned = ExpensiveTypeReference();
  auto AutoCopyConstructed(ExpensiveTypeReference());
  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: the variable 'AutoCopyConstructed'
  // CHECK-FIXES: const auto& AutoCopyConstructed(ExpensiveTypeReference());
  ExpensiveToCopyType VarAssigned = ExpensiveTypeReference();
  // CHECK-MESSAGES: [[@LINE-1]]:23: warning: the variable 'VarAssigned'
  // CHECK-FIXES: const ExpensiveToCopyType& VarAssigned = ExpensiveTypeReference();
  ExpensiveToCopyType VarCopyConstructed(ExpensiveTypeReference());
  // CHECK-MESSAGES: [[@LINE-1]]:23: warning: the variable 'VarCopyConstructed'
  // CHECK-FIXES: const ExpensiveToCopyType& VarCopyConstructed(ExpensiveTypeReference());
}

void positiveNonConstVarInCodeBlock(const ExpensiveToCopyType &Obj) {
  {
    auto Assigned = Obj.reference();
    // CHECK-MESSAGES: [[@LINE-1]]:10: warning: the variable 'Assigned'
    // CHECK-FIXES: const auto& Assigned = Obj.reference();
    Assigned.reference();
    useAsConstReference(Assigned);
    useByValue(Assigned);
  }
}

void negativeNonConstVarWithNonConstUse(const ExpensiveToCopyType &Obj) {
  {
    auto NonConstInvoked = Obj.reference();
    // CHECK-FIXES: auto NonConstInvoked = Obj.reference();
    NonConstInvoked.nonConstMethod();
  }
  {
    auto Reassigned = Obj.reference();
    // CHECK-FIXES: auto Reassigned = Obj.reference();
    Reassigned = ExpensiveToCopyType();
  }
  {
    auto MutatedByReference = Obj.reference();
    // CHECK-FIXES: auto MutatedByReference = Obj.reference();
    mutate(MutatedByReference);
  }
  {
    auto MutatedByPointer = Obj.reference();
    // CHECK-FIXES: auto MutatedByPointer = Obj.reference();
    mutate(&MutatedByPointer);
  }
}

void PositiveMethodCallNonConstRefNotModified(ExpensiveToCopyType &Obj) {
  const auto AutoAssigned = Obj.reference();
  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoAssigned'
  // CHECK-FIXES: const auto& AutoAssigned = Obj.reference();
}

void NegativeMethodCallNonConstRefIsModified(ExpensiveToCopyType &Obj) {
  const auto AutoAssigned = Obj.reference();
  const auto AutoCopyConstructed(Obj.reference());
  const ExpensiveToCopyType VarAssigned = Obj.reference();
  const ExpensiveToCopyType VarCopyConstructed(Obj.reference());
  mutate(&Obj);
}

void PositiveMethodCallNonConstNotModified(ExpensiveToCopyType Obj) {
  const auto AutoAssigned = Obj.reference();
  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoAssigned'
  // CHECK-FIXES: const auto& AutoAssigned = Obj.reference();
}

void NegativeMethodCallNonConstValueArgumentIsModified(ExpensiveToCopyType Obj) {
  Obj.nonConstMethod();
  const auto AutoAssigned = Obj.reference();
}

void PositiveMethodCallNonConstPointerNotModified(ExpensiveToCopyType *const Obj) {
  const auto AutoAssigned = Obj->reference();
  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoAssigned'
  // CHECK-FIXES: const auto& AutoAssigned = Obj->reference();
  Obj->constMethod();
}

void NegativeMethodCallNonConstPointerIsModified(ExpensiveToCopyType *const Obj) {
  const auto AutoAssigned = Obj->reference();
  const auto AutoCopyConstructed(Obj->reference());
  const ExpensiveToCopyType VarAssigned = Obj->reference();
  const ExpensiveToCopyType VarCopyConstructed(Obj->reference());
  mutate(Obj);
}

void PositiveLocalVarIsNotModified() {
  ExpensiveToCopyType LocalVar;
  const auto AutoAssigned = LocalVar.reference();
  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: the const qualified variable 'AutoAssigned'
  // CHECK-FIXES: const auto& AutoAssigned = LocalVar.reference();
}

void NegativeLocalVarIsModified() {
  ExpensiveToCopyType Obj;
  const auto AutoAssigned = Obj.reference();
  Obj = AutoAssigned;
}

struct NegativeConstructor {
  NegativeConstructor(const ExpensiveToCopyType &Obj) : Obj(Obj) {}
  ExpensiveToCopyType Obj;
};

#define UNNECESSARY_COPY_INIT_IN_MACRO_BODY(TYPE)                              \
  void functionWith##TYPE(const TYPE &T) {                                     \
    auto AssignedInMacro = T.reference();                                      \
  }                                                                            \
// Ensure fix is not applied.
// CHECK-FIXES: auto AssignedInMacro = T.reference();

UNNECESSARY_COPY_INIT_IN_MACRO_BODY(ExpensiveToCopyType)
// CHECK-MESSAGES: [[@LINE-1]]:1: warning: the variable 'AssignedInMacro' is copy-constructed

#define UNNECESSARY_COPY_INIT_IN_MACRO_ARGUMENT(ARGUMENT) ARGUMENT

void PositiveMacroArgument(const ExpensiveToCopyType &Obj) {
  UNNECESSARY_COPY_INIT_IN_MACRO_ARGUMENT(auto CopyInMacroArg = Obj.reference());
  // CHECK-MESSAGES: [[@LINE-1]]:48: warning: the variable 'CopyInMacroArg' is copy-constructed
  // Ensure fix is not applied.
  // CHECK-FIXES: auto CopyInMacroArg = Obj.reference()
}

void PositiveLocalCopyConstMethodInvoked() {
  ExpensiveToCopyType orig;
  ExpensiveToCopyType copy_1 = orig;
  // CHECK-MESSAGES: [[@LINE-1]]:23: warning: local copy 'copy_1' of the variable 'orig' is never modified; consider avoiding the copy [performance-unnecessary-copy-initialization]
  // CHECK-FIXES: const ExpensiveToCopyType& copy_1 = orig;
  copy_1.constMethod();
  orig.constMethod();
}

void PositiveLocalCopyUsingExplicitCopyCtor() {
  ExpensiveToCopyType orig;
  ExpensiveToCopyType copy_2(orig);
  // CHECK-MESSAGES: [[@LINE-1]]:23: warning: local copy 'copy_2'
  // CHECK-FIXES: const ExpensiveToCopyType& copy_2(orig);
  copy_2.constMethod();
  orig.constMethod();
}

void PositiveLocalCopyCopyIsArgument(const ExpensiveToCopyType &orig) {
  ExpensiveToCopyType copy_3 = orig;
  // CHECK-MESSAGES: [[@LINE-1]]:23: warning: local copy 'copy_3'
  // CHECK-FIXES: const ExpensiveToCopyType& copy_3 = orig;
  copy_3.constMethod();
}

void PositiveLocalCopyUsedAsConstRef() {
  ExpensiveToCopyType orig;
  ExpensiveToCopyType copy_4 = orig;
  // CHECK-MESSAGES: [[@LINE-1]]:23: warning: local copy 'copy_4'
  // CHECK-FIXES: const ExpensiveToCopyType& copy_4 = orig;
  useAsConstReference(orig);
}

void PositiveLocalCopyTwice() {
  ExpensiveToCopyType orig;
  ExpensiveToCopyType copy_5 = orig;
  // CHECK-MESSAGES: [[@LINE-1]]:23: warning: local copy 'copy_5'
  // CHECK-FIXES: const ExpensiveToCopyType& copy_5 = orig;
  ExpensiveToCopyType copy_6 = copy_5;
  // CHECK-MESSAGES: [[@LINE-1]]:23: warning: local copy 'copy_6'
  // CHECK-FIXES: const ExpensiveToCopyType& copy_6 = copy_5;
  copy_5.constMethod();
  copy_6.constMethod();
  orig.constMethod();
}


void PositiveLocalCopyWeirdCopy() {
  WeirdCopyCtorType orig;
  WeirdCopyCtorType weird_1(orig);
  // CHECK-MESSAGES: [[@LINE-1]]:21: warning: local copy 'weird_1'
  // CHECK-FIXES: const WeirdCopyCtorType& weird_1(orig);
  weird_1.constMethod();

  WeirdCopyCtorType weird_2 = orig;
  // CHECK-MESSAGES: [[@LINE-1]]:21: warning: local copy 'weird_2'
  // CHECK-FIXES: const WeirdCopyCtorType& weird_2 = orig;
  weird_2.constMethod();
}

void NegativeLocalCopySimpleTypes() {
  int i1 = 0;
  int i2 = i1;
}

void NegativeLocalCopyCopyIsModified() {
  ExpensiveToCopyType orig;
  ExpensiveToCopyType neg_copy_1 = orig;
  neg_copy_1.nonConstMethod();
}

void NegativeLocalCopyOriginalIsModified() {
  ExpensiveToCopyType orig;
  ExpensiveToCopyType neg_copy_2 = orig;
  orig.nonConstMethod();
}

void NegativeLocalCopyUsedAsRefArg() {
  ExpensiveToCopyType orig;
  ExpensiveToCopyType neg_copy_3 = orig;
  mutate(neg_copy_3);
}

void NegativeLocalCopyUsedAsPointerArg() {
  ExpensiveToCopyType orig;
  ExpensiveToCopyType neg_copy_4 = orig;
  mutate(&neg_copy_4);
}

void NegativeLocalCopyCopyFromGlobal() {
  ExpensiveToCopyType neg_copy_5 = global_expensive_to_copy_type;
}

void NegativeLocalCopyCopyToStatic() {
  ExpensiveToCopyType orig;
  static ExpensiveToCopyType neg_copy_6 = orig;
}

void NegativeLocalCopyNonConstInForLoop() {
  ExpensiveToCopyType orig;
  for (ExpensiveToCopyType neg_copy_7 = orig; orig.constMethod();
       orig.nonConstMethod()) {
    orig.constMethod();
  }
}

void NegativeLocalCopyWeirdNonCopy() {
  WeirdCopyCtorType orig;
  WeirdCopyCtorType neg_weird_1(orig, false);
  WeirdCopyCtorType neg_weird_2(orig, true);
}
void WarningOnlyMultiDeclStmt() {
  ExpensiveToCopyType orig;
  ExpensiveToCopyType copy = orig, copy2;
  // CHECK-MESSAGES: [[@LINE-1]]:23: warning: local copy 'copy' of the variable 'orig' is never modified; consider avoiding the copy [performance-unnecessary-copy-initialization]
  // CHECK-FIXES: ExpensiveToCopyType copy = orig, copy2;
}

class Element {};
class Container {
public:
  class Iterator {
  public:
    void operator++();
    Element operator*();
    bool operator!=(const Iterator &);
    WeirdCopyCtorType c;
  };
  const Iterator &begin() const;
  const Iterator &end() const;
};

void implicitVarFalsePositive() {
  for (const Element &E : Container()) {
  }
}
