summaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/AST/DeclarationName.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/AST/DeclarationName.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/AST/DeclarationName.cpp520
1 files changed, 520 insertions, 0 deletions
diff --git a/contrib/llvm-project/clang/lib/AST/DeclarationName.cpp b/contrib/llvm-project/clang/lib/AST/DeclarationName.cpp
new file mode 100644
index 000000000000..fe69c71aa3dd
--- /dev/null
+++ b/contrib/llvm-project/clang/lib/AST/DeclarationName.cpp
@@ -0,0 +1,520 @@
+//===- DeclarationName.cpp - Declaration names implementation -------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the DeclarationName and DeclarationNameTable
+// classes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/PrettyPrinter.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeLoc.h"
+#include "clang/AST/TypeOrdering.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/OperatorKinds.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <string>
+
+using namespace clang;
+
+static int compareInt(unsigned A, unsigned B) {
+ return (A < B ? -1 : (A > B ? 1 : 0));
+}
+
+int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) {
+ if (LHS.getNameKind() != RHS.getNameKind())
+ return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
+
+ switch (LHS.getNameKind()) {
+ case DeclarationName::Identifier: {
+ IdentifierInfo *LII = LHS.castAsIdentifierInfo();
+ IdentifierInfo *RII = RHS.castAsIdentifierInfo();
+ if (!LII)
+ return RII ? -1 : 0;
+ if (!RII)
+ return 1;
+
+ return LII->getName().compare(RII->getName());
+ }
+
+ case DeclarationName::ObjCZeroArgSelector:
+ case DeclarationName::ObjCOneArgSelector:
+ case DeclarationName::ObjCMultiArgSelector: {
+ Selector LHSSelector = LHS.getObjCSelector();
+ Selector RHSSelector = RHS.getObjCSelector();
+ // getNumArgs for ZeroArgSelector returns 0, but we still need to compare.
+ if (LHS.getNameKind() == DeclarationName::ObjCZeroArgSelector &&
+ RHS.getNameKind() == DeclarationName::ObjCZeroArgSelector) {
+ return LHSSelector.getAsIdentifierInfo()->getName().compare(
+ RHSSelector.getAsIdentifierInfo()->getName());
+ }
+ unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
+ for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
+ switch (LHSSelector.getNameForSlot(I).compare(
+ RHSSelector.getNameForSlot(I))) {
+ case -1:
+ return -1;
+ case 1:
+ return 1;
+ default:
+ break;
+ }
+ }
+
+ return compareInt(LN, RN);
+ }
+
+ case DeclarationName::CXXConstructorName:
+ case DeclarationName::CXXDestructorName:
+ case DeclarationName::CXXConversionFunctionName:
+ if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
+ return -1;
+ if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
+ return 1;
+ return 0;
+
+ case DeclarationName::CXXDeductionGuideName:
+ // We never want to compare deduction guide names for templates from
+ // different scopes, so just compare the template-name.
+ return compare(LHS.getCXXDeductionGuideTemplate()->getDeclName(),
+ RHS.getCXXDeductionGuideTemplate()->getDeclName());
+
+ case DeclarationName::CXXOperatorName:
+ return compareInt(LHS.getCXXOverloadedOperator(),
+ RHS.getCXXOverloadedOperator());
+
+ case DeclarationName::CXXLiteralOperatorName:
+ return LHS.getCXXLiteralIdentifier()->getName().compare(
+ RHS.getCXXLiteralIdentifier()->getName());
+
+ case DeclarationName::CXXUsingDirective:
+ return 0;
+ }
+
+ llvm_unreachable("Invalid DeclarationName Kind!");
+}
+
+static void printCXXConstructorDestructorName(QualType ClassType,
+ raw_ostream &OS,
+ PrintingPolicy Policy) {
+ // We know we're printing C++ here. Ensure we print types properly.
+ Policy.adjustForCPlusPlus();
+
+ if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) {
+ OS << *ClassRec->getDecl();
+ return;
+ }
+ if (Policy.SuppressTemplateArgsInCXXConstructors) {
+ if (auto *InjTy = ClassType->getAs<InjectedClassNameType>()) {
+ OS << *InjTy->getDecl();
+ return;
+ }
+ }
+ ClassType.print(OS, Policy);
+}
+
+void DeclarationName::print(raw_ostream &OS, const PrintingPolicy &Policy) {
+ switch (getNameKind()) {
+ case DeclarationName::Identifier:
+ if (const IdentifierInfo *II = getAsIdentifierInfo())
+ OS << II->getName();
+ return;
+
+ case DeclarationName::ObjCZeroArgSelector:
+ case DeclarationName::ObjCOneArgSelector:
+ case DeclarationName::ObjCMultiArgSelector:
+ getObjCSelector().print(OS);
+ return;
+
+ case DeclarationName::CXXConstructorName:
+ return printCXXConstructorDestructorName(getCXXNameType(), OS, Policy);
+
+ case DeclarationName::CXXDestructorName:
+ OS << '~';
+ return printCXXConstructorDestructorName(getCXXNameType(), OS, Policy);
+
+ case DeclarationName::CXXDeductionGuideName:
+ OS << "<deduction guide for ";
+ getCXXDeductionGuideTemplate()->getDeclName().print(OS, Policy);
+ OS << '>';
+ return;
+
+ case DeclarationName::CXXOperatorName: {
+ const char *OpName = getOperatorSpelling(getCXXOverloadedOperator());
+ assert(OpName && "not an overloaded operator");
+
+ OS << "operator";
+ if (OpName[0] >= 'a' && OpName[0] <= 'z')
+ OS << ' ';
+ OS << OpName;
+ return;
+ }
+
+ case DeclarationName::CXXLiteralOperatorName:
+ OS << "operator\"\"" << getCXXLiteralIdentifier()->getName();
+ return;
+
+ case DeclarationName::CXXConversionFunctionName: {
+ OS << "operator ";
+ QualType Type = getCXXNameType();
+ if (const RecordType *Rec = Type->getAs<RecordType>()) {
+ OS << *Rec->getDecl();
+ return;
+ }
+ // We know we're printing C++ here, ensure we print 'bool' properly.
+ PrintingPolicy CXXPolicy = Policy;
+ CXXPolicy.adjustForCPlusPlus();
+ Type.print(OS, CXXPolicy);
+ return;
+ }
+ case DeclarationName::CXXUsingDirective:
+ OS << "<using-directive>";
+ return;
+ }
+
+ llvm_unreachable("Unexpected declaration name kind");
+}
+
+namespace clang {
+
+raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
+ LangOptions LO;
+ N.print(OS, PrintingPolicy(LO));
+ return OS;
+}
+
+} // namespace clang
+
+bool DeclarationName::isDependentName() const {
+ QualType T = getCXXNameType();
+ if (!T.isNull() && T->isDependentType())
+ return true;
+
+ // A class-scope deduction guide in a dependent context has a dependent name.
+ auto *TD = getCXXDeductionGuideTemplate();
+ if (TD && TD->getDeclContext()->isDependentContext())
+ return true;
+
+ return false;
+}
+
+std::string DeclarationName::getAsString() const {
+ std::string Result;
+ llvm::raw_string_ostream OS(Result);
+ OS << *this;
+ return OS.str();
+}
+
+void *DeclarationName::getFETokenInfoSlow() const {
+ switch (getNameKind()) {
+ case Identifier:
+ llvm_unreachable("case Identifier already handled by getFETokenInfo!");
+ case CXXConstructorName:
+ case CXXDestructorName:
+ case CXXConversionFunctionName:
+ return castAsCXXSpecialNameExtra()->FETokenInfo;
+ case CXXOperatorName:
+ return castAsCXXOperatorIdName()->FETokenInfo;
+ case CXXDeductionGuideName:
+ return castAsCXXDeductionGuideNameExtra()->FETokenInfo;
+ case CXXLiteralOperatorName:
+ return castAsCXXLiteralOperatorIdName()->FETokenInfo;
+ default:
+ llvm_unreachable("DeclarationName has no FETokenInfo!");
+ }
+}
+
+void DeclarationName::setFETokenInfoSlow(void *T) {
+ switch (getNameKind()) {
+ case Identifier:
+ llvm_unreachable("case Identifier already handled by setFETokenInfo!");
+ case CXXConstructorName:
+ case CXXDestructorName:
+ case CXXConversionFunctionName:
+ castAsCXXSpecialNameExtra()->FETokenInfo = T;
+ break;
+ case CXXOperatorName:
+ castAsCXXOperatorIdName()->FETokenInfo = T;
+ break;
+ case CXXDeductionGuideName:
+ castAsCXXDeductionGuideNameExtra()->FETokenInfo = T;
+ break;
+ case CXXLiteralOperatorName:
+ castAsCXXLiteralOperatorIdName()->FETokenInfo = T;
+ break;
+ default:
+ llvm_unreachable("DeclarationName has no FETokenInfo!");
+ }
+}
+
+LLVM_DUMP_METHOD void DeclarationName::dump() const {
+ llvm::errs() << *this << '\n';
+}
+
+DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
+ // Initialize the overloaded operator names.
+ for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op)
+ CXXOperatorNames[Op].Kind = static_cast<OverloadedOperatorKind>(Op);
+}
+
+DeclarationName
+DeclarationNameTable::getCXXDeductionGuideName(TemplateDecl *Template) {
+ Template = cast<TemplateDecl>(Template->getCanonicalDecl());
+
+ llvm::FoldingSetNodeID ID;
+ ID.AddPointer(Template);
+
+ void *InsertPos = nullptr;
+ if (auto *Name = CXXDeductionGuideNames.FindNodeOrInsertPos(ID, InsertPos))
+ return DeclarationName(Name);
+
+ auto *Name = new (Ctx) detail::CXXDeductionGuideNameExtra(Template);
+ CXXDeductionGuideNames.InsertNode(Name, InsertPos);
+ return DeclarationName(Name);
+}
+
+DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
+ // The type of constructors is unqualified.
+ Ty = Ty.getUnqualifiedType();
+ // Do we already have this C++ constructor name ?
+ llvm::FoldingSetNodeID ID;
+ ID.AddPointer(Ty.getAsOpaquePtr());
+ void *InsertPos = nullptr;
+ if (auto *Name = CXXConstructorNames.FindNodeOrInsertPos(ID, InsertPos))
+ return {Name, DeclarationName::StoredCXXConstructorName};
+
+ // We have to create it.
+ auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
+ CXXConstructorNames.InsertNode(SpecialName, InsertPos);
+ return {SpecialName, DeclarationName::StoredCXXConstructorName};
+}
+
+DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) {
+ // The type of destructors is unqualified.
+ Ty = Ty.getUnqualifiedType();
+ // Do we already have this C++ destructor name ?
+ llvm::FoldingSetNodeID ID;
+ ID.AddPointer(Ty.getAsOpaquePtr());
+ void *InsertPos = nullptr;
+ if (auto *Name = CXXDestructorNames.FindNodeOrInsertPos(ID, InsertPos))
+ return {Name, DeclarationName::StoredCXXDestructorName};
+
+ // We have to create it.
+ auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
+ CXXDestructorNames.InsertNode(SpecialName, InsertPos);
+ return {SpecialName, DeclarationName::StoredCXXDestructorName};
+}
+
+DeclarationName
+DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
+ // Do we already have this C++ conversion function name ?
+ llvm::FoldingSetNodeID ID;
+ ID.AddPointer(Ty.getAsOpaquePtr());
+ void *InsertPos = nullptr;
+ if (auto *Name =
+ CXXConversionFunctionNames.FindNodeOrInsertPos(ID, InsertPos))
+ return {Name, DeclarationName::StoredCXXConversionFunctionName};
+
+ // We have to create it.
+ auto *SpecialName = new (Ctx) detail::CXXSpecialNameExtra(Ty);
+ CXXConversionFunctionNames.InsertNode(SpecialName, InsertPos);
+ return {SpecialName, DeclarationName::StoredCXXConversionFunctionName};
+}
+
+DeclarationName
+DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
+ CanQualType Ty) {
+ switch (Kind) {
+ case DeclarationName::CXXConstructorName:
+ return getCXXConstructorName(Ty);
+ case DeclarationName::CXXDestructorName:
+ return getCXXDestructorName(Ty);
+ case DeclarationName::CXXConversionFunctionName:
+ return getCXXConversionFunctionName(Ty);
+ default:
+ llvm_unreachable("Invalid kind in getCXXSpecialName!");
+ }
+}
+
+DeclarationName
+DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
+ llvm::FoldingSetNodeID ID;
+ ID.AddPointer(II);
+
+ void *InsertPos = nullptr;
+ if (auto *Name = CXXLiteralOperatorNames.FindNodeOrInsertPos(ID, InsertPos))
+ return DeclarationName(Name);
+
+ auto *LiteralName = new (Ctx) detail::CXXLiteralOperatorIdName(II);
+ CXXLiteralOperatorNames.InsertNode(LiteralName, InsertPos);
+ return DeclarationName(LiteralName);
+}
+
+DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
+ switch (Name.getNameKind()) {
+ case DeclarationName::Identifier:
+ case DeclarationName::CXXDeductionGuideName:
+ break;
+ case DeclarationName::CXXConstructorName:
+ case DeclarationName::CXXDestructorName:
+ case DeclarationName::CXXConversionFunctionName:
+ NamedType.TInfo = nullptr;
+ break;
+ case DeclarationName::CXXOperatorName:
+ CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
+ CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
+ break;
+ case DeclarationName::CXXLiteralOperatorName:
+ CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
+ break;
+ case DeclarationName::ObjCZeroArgSelector:
+ case DeclarationName::ObjCOneArgSelector:
+ case DeclarationName::ObjCMultiArgSelector:
+ // FIXME: ?
+ break;
+ case DeclarationName::CXXUsingDirective:
+ break;
+ }
+}
+
+bool DeclarationNameInfo::containsUnexpandedParameterPack() const {
+ switch (Name.getNameKind()) {
+ case DeclarationName::Identifier:
+ case DeclarationName::ObjCZeroArgSelector:
+ case DeclarationName::ObjCOneArgSelector:
+ case DeclarationName::ObjCMultiArgSelector:
+ case DeclarationName::CXXOperatorName:
+ case DeclarationName::CXXLiteralOperatorName:
+ case DeclarationName::CXXUsingDirective:
+ case DeclarationName::CXXDeductionGuideName:
+ return false;
+
+ case DeclarationName::CXXConstructorName:
+ case DeclarationName::CXXDestructorName:
+ case DeclarationName::CXXConversionFunctionName:
+ if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
+ return TInfo->getType()->containsUnexpandedParameterPack();
+
+ return Name.getCXXNameType()->containsUnexpandedParameterPack();
+ }
+ llvm_unreachable("All name kinds handled.");
+}
+
+bool DeclarationNameInfo::isInstantiationDependent() const {
+ switch (Name.getNameKind()) {
+ case DeclarationName::Identifier:
+ case DeclarationName::ObjCZeroArgSelector:
+ case DeclarationName::ObjCOneArgSelector:
+ case DeclarationName::ObjCMultiArgSelector:
+ case DeclarationName::CXXOperatorName:
+ case DeclarationName::CXXLiteralOperatorName:
+ case DeclarationName::CXXUsingDirective:
+ case DeclarationName::CXXDeductionGuideName:
+ return false;
+
+ case DeclarationName::CXXConstructorName:
+ case DeclarationName::CXXDestructorName:
+ case DeclarationName::CXXConversionFunctionName:
+ if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
+ return TInfo->getType()->isInstantiationDependentType();
+
+ return Name.getCXXNameType()->isInstantiationDependentType();
+ }
+ llvm_unreachable("All name kinds handled.");
+}
+
+std::string DeclarationNameInfo::getAsString() const {
+ std::string Result;
+ llvm::raw_string_ostream OS(Result);
+ printName(OS);
+ return OS.str();
+}
+
+void DeclarationNameInfo::printName(raw_ostream &OS) const {
+ switch (Name.getNameKind()) {
+ case DeclarationName::Identifier:
+ case DeclarationName::ObjCZeroArgSelector:
+ case DeclarationName::ObjCOneArgSelector:
+ case DeclarationName::ObjCMultiArgSelector:
+ case DeclarationName::CXXOperatorName:
+ case DeclarationName::CXXLiteralOperatorName:
+ case DeclarationName::CXXUsingDirective:
+ case DeclarationName::CXXDeductionGuideName:
+ OS << Name;
+ return;
+
+ case DeclarationName::CXXConstructorName:
+ case DeclarationName::CXXDestructorName:
+ case DeclarationName::CXXConversionFunctionName:
+ if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
+ if (Name.getNameKind() == DeclarationName::CXXDestructorName)
+ OS << '~';
+ else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
+ OS << "operator ";
+ LangOptions LO;
+ LO.CPlusPlus = true;
+ LO.Bool = true;
+ PrintingPolicy PP(LO);
+ PP.SuppressScope = true;
+ OS << TInfo->getType().getAsString(PP);
+ } else
+ OS << Name;
+ return;
+ }
+ llvm_unreachable("Unexpected declaration name kind");
+}
+
+SourceLocation DeclarationNameInfo::getEndLocPrivate() const {
+ switch (Name.getNameKind()) {
+ case DeclarationName::Identifier:
+ case DeclarationName::CXXDeductionGuideName:
+ return NameLoc;
+
+ case DeclarationName::CXXOperatorName: {
+ unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
+ return SourceLocation::getFromRawEncoding(raw);
+ }
+
+ case DeclarationName::CXXLiteralOperatorName: {
+ unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
+ return SourceLocation::getFromRawEncoding(raw);
+ }
+
+ case DeclarationName::CXXConstructorName:
+ case DeclarationName::CXXDestructorName:
+ case DeclarationName::CXXConversionFunctionName:
+ if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
+ return TInfo->getTypeLoc().getEndLoc();
+ else
+ return NameLoc;
+
+ // DNInfo work in progress: FIXME.
+ case DeclarationName::ObjCZeroArgSelector:
+ case DeclarationName::ObjCOneArgSelector:
+ case DeclarationName::ObjCMultiArgSelector:
+ case DeclarationName::CXXUsingDirective:
+ return NameLoc;
+ }
+ llvm_unreachable("Unexpected declaration name kind");
+}