//===----------------------------------------------------------------------===//
//
// 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 "StdNamespaceModificationCheck.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchersInternal.h"

using namespace clang;
using namespace clang::ast_matchers;

namespace {

AST_POLYMORPHIC_MATCHER_P(
    hasAnyTemplateArgumentIncludingPack,
    AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
                                    TemplateSpecializationType, FunctionDecl),
    ast_matchers::internal::Matcher<TemplateArgument>, InnerMatcher) {
  const ArrayRef<TemplateArgument> Args =
      ast_matchers::internal::getTemplateSpecializationArgs(Node);
  for (const auto &Arg : Args) {
    if (Arg.getKind() != TemplateArgument::Pack)
      continue;
    const ArrayRef<TemplateArgument> PackArgs = Arg.getPackAsArray();
    if (matchesFirstInRange(InnerMatcher, PackArgs.begin(), PackArgs.end(),
                            Finder, Builder) != PackArgs.end())
      return true;
  }
  return matchesFirstInRange(InnerMatcher, Args.begin(), Args.end(), Finder,
                             Builder) != Args.end();
}

} // namespace

namespace clang::tidy::bugprone {

void StdNamespaceModificationCheck::registerMatchers(MatchFinder *Finder) {
  auto HasStdParent =
      hasDeclContext(namespaceDecl(hasAnyName("std", "posix"),
                                   unless(hasParent(namespaceDecl())))
                         .bind("nmspc"));
  auto UserDefinedDecl =
      namedDecl(anyOf(classTemplateDecl(), tagDecl()),
                hasAncestor(namespaceDecl(hasAnyName("std", "posix"),
                                          unless(hasParent(namespaceDecl())))));
  auto UserDefinedType = qualType(hasUnqualifiedDesugaredType(anyOf(
      tagType(unless(hasDeclaration(UserDefinedDecl))),
      templateSpecializationType(unless(hasDeclaration(UserDefinedDecl))))));
  auto HasNoProgramDefinedTemplateArgument = unless(
      hasAnyTemplateArgumentIncludingPack(refersToType(UserDefinedType)));
  auto InsideStdClassOrClassTemplateSpecialization = hasDeclContext(
      anyOf(cxxRecordDecl(HasStdParent),
            classTemplateSpecializationDecl(
                HasStdParent, HasNoProgramDefinedTemplateArgument)));

  // Try to follow exactly CERT rule DCL58-CPP (this text is taken from C++
  // standard into the CERT rule):
  // "
  // 1 The behavior of a C++ program is undefined if it adds declarations or
  // definitions to namespace std or to a namespace within namespace std unless
  // otherwise specified. A program may add a template specialization for any
  // standard library template to namespace std only if the declaration depends
  // on a user-defined type and the specialization meets the standard library
  // requirements for the original template and is not explicitly prohibited. 2
  // The behavior of a C++ program is undefined if it declares — an explicit
  // specialization of any member function of a standard library class template,
  // or — an explicit specialization of any member function template of a
  // standard library class or class template, or — an explicit or partial
  // specialization of any member class template of a standard library class or
  // class template.
  // "
  // The "standard library requirements" and explicit prohibition are not
  // checked.

  auto BadNonTemplateSpecializationDecl =
      decl(unless(anyOf(functionDecl(isExplicitTemplateSpecialization()),
                        varDecl(isExplicitTemplateSpecialization()),
                        cxxRecordDecl(isExplicitTemplateSpecialization()))),
           HasStdParent);
  auto BadClassTemplateSpec = classTemplateSpecializationDecl(
      HasNoProgramDefinedTemplateArgument, HasStdParent);
  auto BadInnerClassTemplateSpec = classTemplateSpecializationDecl(
      InsideStdClassOrClassTemplateSpecialization);
  auto BadFunctionTemplateSpec =
      functionDecl(unless(cxxMethodDecl()), isExplicitTemplateSpecialization(),
                   HasNoProgramDefinedTemplateArgument, HasStdParent);
  auto BadMemberFunctionSpec =
      cxxMethodDecl(isExplicitTemplateSpecialization(),
                    InsideStdClassOrClassTemplateSpecialization);

  Finder->addMatcher(decl(anyOf(BadNonTemplateSpecializationDecl,
                                BadClassTemplateSpec, BadInnerClassTemplateSpec,
                                BadFunctionTemplateSpec, BadMemberFunctionSpec))
                         .bind("decl"),
                     this);
}
} // namespace clang::tidy::bugprone

static const NamespaceDecl *getTopLevelLexicalNamespaceDecl(const Decl *D) {
  const NamespaceDecl *LastNS = nullptr;
  while (D) {
    if (const auto *NS = dyn_cast<NamespaceDecl>(D))
      LastNS = NS;
    D = dyn_cast_or_null<Decl>(D->getLexicalDeclContext());
  }
  return LastNS;
}

void clang::tidy::bugprone::StdNamespaceModificationCheck::check(
    const MatchFinder::MatchResult &Result) {
  const auto *D = Result.Nodes.getNodeAs<Decl>("decl");
  const auto *NS = Result.Nodes.getNodeAs<NamespaceDecl>("nmspc");
  if (!D || !NS)
    return;

  // Skip compiler-generated implicit declarations (e.g. std::align_val_t).
  if (D->isImplicit())
    return;

  diag(D->getLocation(),
       "modification of %0 namespace can result in undefined behavior")
      << NS;
  // 'NS' is not always the namespace declaration that lexically contains 'D',
  // try to find such a namespace.
  if (const NamespaceDecl *LexNS = getTopLevelLexicalNamespaceDecl(D)) {
    assert(NS->getCanonicalDecl() == LexNS->getCanonicalDecl() &&
           "Mismatch in found namespace");
    diag(LexNS->getLocation(), "%0 namespace opened here", DiagnosticIDs::Note)
        << LexNS;
  }
}
