diff options
Diffstat (limited to 'lib/AST/DeclarationName.cpp')
-rw-r--r-- | lib/AST/DeclarationName.cpp | 399 |
1 files changed, 101 insertions, 298 deletions
diff --git a/lib/AST/DeclarationName.cpp b/lib/AST/DeclarationName.cpp index 9866d92f61eb4..f2c152f918ebf 100644 --- a/lib/AST/DeclarationName.cpp +++ b/lib/AST/DeclarationName.cpp @@ -39,74 +39,6 @@ using namespace clang; -namespace clang { - -/// CXXSpecialName - Records the type associated with one of the -/// "special" kinds of declaration names in C++, e.g., constructors, -/// destructors, and conversion functions. -class CXXSpecialName - : public DeclarationNameExtra, public llvm::FoldingSetNode { -public: - /// Type - The type associated with this declaration name. - QualType Type; - - /// FETokenInfo - Extra information associated with this declaration - /// name that can be used by the front end. - void *FETokenInfo; - - void Profile(llvm::FoldingSetNodeID &ID) { - ID.AddInteger(ExtraKindOrNumArgs); - ID.AddPointer(Type.getAsOpaquePtr()); - } -}; - -/// Contains extra information for the name of a C++ deduction guide. -class CXXDeductionGuideNameExtra : public DeclarationNameExtra, - public llvm::FoldingSetNode { -public: - /// The template named by the deduction guide. - TemplateDecl *Template; - - /// FETokenInfo - Extra information associated with this operator - /// name that can be used by the front end. - void *FETokenInfo; - - void Profile(llvm::FoldingSetNodeID &ID) { - ID.AddPointer(Template); - } -}; - -/// CXXOperatorIdName - Contains extra information for the name of an -/// overloaded operator in C++, such as "operator+. -class CXXOperatorIdName : public DeclarationNameExtra { -public: - /// FETokenInfo - Extra information associated with this operator - /// name that can be used by the front end. - void *FETokenInfo; -}; - -/// CXXLiteralOperatorName - Contains the actual identifier that makes up the -/// name. -/// -/// This identifier is stored here rather than directly in DeclarationName so as -/// to allow Objective-C selectors, which are about a million times more common, -/// to consume minimal memory. -class CXXLiteralOperatorIdName - : public DeclarationNameExtra, public llvm::FoldingSetNode { -public: - IdentifierInfo *ID; - - /// FETokenInfo - Extra information associated with this operator - /// name that can be used by the front end. - void *FETokenInfo; - - void Profile(llvm::FoldingSetNodeID &FSID) { - FSID.AddPointer(ID); - } -}; - -} // namespace clang - static int compareInt(unsigned A, unsigned B) { return (A < B ? -1 : (A > B ? 1 : 0)); } @@ -117,10 +49,12 @@ int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) { switch (LHS.getNameKind()) { case DeclarationName::Identifier: { - IdentifierInfo *LII = LHS.getAsIdentifierInfo(); - IdentifierInfo *RII = RHS.getAsIdentifierInfo(); - if (!LII) return RII ? -1 : 0; - if (!RII) return 1; + IdentifierInfo *LII = LHS.castAsIdentifierInfo(); + IdentifierInfo *RII = RHS.castAsIdentifierInfo(); + if (!LII) + return RII ? -1 : 0; + if (!RII) + return 1; return LII->getName().compare(RII->getName()); } @@ -134,15 +68,18 @@ int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) { if (LHS.getNameKind() == DeclarationName::ObjCZeroArgSelector && RHS.getNameKind() == DeclarationName::ObjCZeroArgSelector) { return LHSSelector.getAsIdentifierInfo()->getName().compare( - RHSSelector.getAsIdentifierInfo()->getName()); + 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; + RHSSelector.getNameForSlot(I))) { + case -1: + return -1; + case 1: + return 1; + default: + break; } } @@ -170,7 +107,7 @@ int DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) { case DeclarationName::CXXLiteralOperatorName: return LHS.getCXXLiteralIdentifier()->getName().compare( - RHS.getCXXLiteralIdentifier()->getName()); + RHS.getCXXLiteralIdentifier()->getName()); case DeclarationName::CXXUsingDirective: return 0; @@ -199,25 +136,24 @@ static void printCXXConstructorDestructorName(QualType ClassType, } void DeclarationName::print(raw_ostream &OS, const PrintingPolicy &Policy) { - DeclarationName &N = *this; - switch (N.getNameKind()) { + switch (getNameKind()) { case DeclarationName::Identifier: - if (const IdentifierInfo *II = N.getAsIdentifierInfo()) + if (const IdentifierInfo *II = getAsIdentifierInfo()) OS << II->getName(); return; case DeclarationName::ObjCZeroArgSelector: case DeclarationName::ObjCOneArgSelector: case DeclarationName::ObjCMultiArgSelector: - N.getObjCSelector().print(OS); + getObjCSelector().print(OS); return; case DeclarationName::CXXConstructorName: - return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy); + return printCXXConstructorDestructorName(getCXXNameType(), OS, Policy); case DeclarationName::CXXDestructorName: OS << '~'; - return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy); + return printCXXConstructorDestructorName(getCXXNameType(), OS, Policy); case DeclarationName::CXXDeductionGuideName: OS << "<deduction guide for "; @@ -226,13 +162,13 @@ void DeclarationName::print(raw_ostream &OS, const PrintingPolicy &Policy) { return; case DeclarationName::CXXOperatorName: { - static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = { - nullptr, -#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ - Spelling, + static const char *const OperatorNames[NUM_OVERLOADED_OPERATORS] = { + nullptr, +#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \ + Spelling, #include "clang/Basic/OperatorKinds.def" }; - const char *OpName = OperatorNames[N.getCXXOverloadedOperator()]; + const char *OpName = OperatorNames[getCXXOverloadedOperator()]; assert(OpName && "not an overloaded operator"); OS << "operator"; @@ -243,12 +179,12 @@ void DeclarationName::print(raw_ostream &OS, const PrintingPolicy &Policy) { } case DeclarationName::CXXLiteralOperatorName: - OS << "operator\"\"" << N.getCXXLiteralIdentifier()->getName(); + OS << "operator\"\"" << getCXXLiteralIdentifier()->getName(); return; case DeclarationName::CXXConversionFunctionName: { OS << "operator "; - QualType Type = N.getCXXNameType(); + QualType Type = getCXXNameType(); if (const RecordType *Rec = Type->getAs<RecordType>()) { OS << *Rec->getDecl(); return; @@ -277,46 +213,6 @@ raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) { } // namespace clang -DeclarationName::NameKind DeclarationName::getNameKind() const { - switch (getStoredNameKind()) { - case StoredIdentifier: return Identifier; - case StoredObjCZeroArgSelector: return ObjCZeroArgSelector; - case StoredObjCOneArgSelector: return ObjCOneArgSelector; - - case StoredDeclarationNameExtra: - switch (getExtra()->ExtraKindOrNumArgs) { - case DeclarationNameExtra::CXXConstructor: - return CXXConstructorName; - - case DeclarationNameExtra::CXXDestructor: - return CXXDestructorName; - - case DeclarationNameExtra::CXXDeductionGuide: - return CXXDeductionGuideName; - - case DeclarationNameExtra::CXXConversionFunction: - return CXXConversionFunctionName; - - case DeclarationNameExtra::CXXLiteralOperator: - return CXXLiteralOperatorName; - - case DeclarationNameExtra::CXXUsingDirective: - return CXXUsingDirective; - - default: - // Check if we have one of the CXXOperator* enumeration values. - if (getExtra()->ExtraKindOrNumArgs < - DeclarationNameExtra::CXXUsingDirective) - return CXXOperatorName; - - return ObjCMultiArgSelector; - } - } - - // Can't actually get here. - llvm_unreachable("This should be unreachable!"); -} - bool DeclarationName::isDependentName() const { QualType T = getCXXNameType(); if (!T.isNull() && T->isDependentType()) @@ -337,241 +233,148 @@ std::string DeclarationName::getAsString() const { return OS.str(); } -QualType DeclarationName::getCXXNameType() const { - if (CXXSpecialName *CXXName = getAsCXXSpecialName()) - return CXXName->Type; - else - return QualType(); -} - -TemplateDecl *DeclarationName::getCXXDeductionGuideTemplate() const { - if (auto *Guide = getAsCXXDeductionGuideNameExtra()) - return Guide->Template; - return nullptr; -} - -OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const { - if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) { - unsigned value - = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction; - return static_cast<OverloadedOperatorKind>(value); - } else { - return OO_None; - } -} - -IdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const { - if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName()) - return CXXLit->ID; - else - return nullptr; -} - -void *DeclarationName::getFETokenInfoAsVoidSlow() const { +void *DeclarationName::getFETokenInfoSlow() const { switch (getNameKind()) { case Identifier: - llvm_unreachable("Handled by getFETokenInfo()"); - + llvm_unreachable("case Identifier already handled by getFETokenInfo!"); case CXXConstructorName: case CXXDestructorName: case CXXConversionFunctionName: - return getAsCXXSpecialName()->FETokenInfo; - - case CXXDeductionGuideName: - return getAsCXXDeductionGuideNameExtra()->FETokenInfo; - + return castAsCXXSpecialNameExtra()->FETokenInfo; case CXXOperatorName: - return getAsCXXOperatorIdName()->FETokenInfo; - + return castAsCXXOperatorIdName()->FETokenInfo; + case CXXDeductionGuideName: + return castAsCXXDeductionGuideNameExtra()->FETokenInfo; case CXXLiteralOperatorName: - return getAsCXXLiteralOperatorIdName()->FETokenInfo; - + return castAsCXXLiteralOperatorIdName()->FETokenInfo; default: - llvm_unreachable("Declaration name has no FETokenInfo"); + llvm_unreachable("DeclarationName has no FETokenInfo!"); } } -void DeclarationName::setFETokenInfo(void *T) { +void DeclarationName::setFETokenInfoSlow(void *T) { switch (getNameKind()) { case Identifier: - getAsIdentifierInfo()->setFETokenInfo(T); - break; - + llvm_unreachable("case Identifier already handled by setFETokenInfo!"); case CXXConstructorName: case CXXDestructorName: case CXXConversionFunctionName: - getAsCXXSpecialName()->FETokenInfo = T; + castAsCXXSpecialNameExtra()->FETokenInfo = T; break; - - case CXXDeductionGuideName: - getAsCXXDeductionGuideNameExtra()->FETokenInfo = T; - break; - case CXXOperatorName: - getAsCXXOperatorIdName()->FETokenInfo = T; + castAsCXXOperatorIdName()->FETokenInfo = T; + break; + case CXXDeductionGuideName: + castAsCXXDeductionGuideNameExtra()->FETokenInfo = T; break; - case CXXLiteralOperatorName: - getAsCXXLiteralOperatorIdName()->FETokenInfo = T; + castAsCXXLiteralOperatorIdName()->FETokenInfo = T; break; - default: - llvm_unreachable("Declaration name has no FETokenInfo"); + llvm_unreachable("DeclarationName has no FETokenInfo!"); } } -DeclarationName DeclarationName::getUsingDirectiveName() { - // Single instance of DeclarationNameExtra for using-directive - static const DeclarationNameExtra UDirExtra = - { DeclarationNameExtra::CXXUsingDirective }; - - uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra); - Ptr |= StoredDeclarationNameExtra; - - return DeclarationName(Ptr); -} - LLVM_DUMP_METHOD void DeclarationName::dump() const { llvm::errs() << *this << '\n'; } DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) { - CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>; - CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>; - CXXDeductionGuideNames = new llvm::FoldingSet<CXXDeductionGuideNameExtra>; - // Initialize the overloaded operator names. - CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS]; - for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) { - CXXOperatorNames[Op].ExtraKindOrNumArgs - = Op + DeclarationNameExtra::CXXConversionFunction; - CXXOperatorNames[Op].FETokenInfo = nullptr; - } -} - -DeclarationNameTable::~DeclarationNameTable() { - auto *SpecialNames = - static_cast<llvm::FoldingSet<CXXSpecialName> *>(CXXSpecialNamesImpl); - auto *LiteralNames = - static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName> *>( - CXXLiteralOperatorNames); - auto *DeductionGuideNames = - static_cast<llvm::FoldingSet<CXXDeductionGuideNameExtra> *>( - CXXDeductionGuideNames); - - delete SpecialNames; - delete LiteralNames; - delete DeductionGuideNames; -} - -DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) { - return getCXXSpecialName(DeclarationName::CXXConstructorName, - Ty.getUnqualifiedType()); -} - -DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) { - return getCXXSpecialName(DeclarationName::CXXDestructorName, - Ty.getUnqualifiedType()); + 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()); - auto *DeductionGuideNames = - static_cast<llvm::FoldingSet<CXXDeductionGuideNameExtra> *>( - CXXDeductionGuideNames); - llvm::FoldingSetNodeID ID; ID.AddPointer(Template); void *InsertPos = nullptr; - if (auto *Name = DeductionGuideNames->FindNodeOrInsertPos(ID, InsertPos)) + if (auto *Name = CXXDeductionGuideNames.FindNodeOrInsertPos(ID, InsertPos)) return DeclarationName(Name); - auto *Name = new (Ctx) CXXDeductionGuideNameExtra; - Name->ExtraKindOrNumArgs = DeclarationNameExtra::CXXDeductionGuide; - Name->Template = Template; - Name->FETokenInfo = nullptr; - - DeductionGuideNames->InsertNode(Name, InsertPos); + 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) { - return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, 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) { - assert(Kind >= DeclarationName::CXXConstructorName && - Kind <= DeclarationName::CXXConversionFunctionName && - "Kind must be a C++ special name kind"); - llvm::FoldingSet<CXXSpecialName> *SpecialNames - = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl); - - DeclarationNameExtra::ExtraKind EKind; switch (Kind) { case DeclarationName::CXXConstructorName: - EKind = DeclarationNameExtra::CXXConstructor; - assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified"); - break; + return getCXXConstructorName(Ty); case DeclarationName::CXXDestructorName: - EKind = DeclarationNameExtra::CXXDestructor; - assert(!Ty.hasQualifiers() && "Destructor type must be unqualified"); - break; + return getCXXDestructorName(Ty); case DeclarationName::CXXConversionFunctionName: - EKind = DeclarationNameExtra::CXXConversionFunction; - break; + return getCXXConversionFunctionName(Ty); default: - return DeclarationName(); + llvm_unreachable("Invalid kind in getCXXSpecialName!"); } - - // Unique selector, to guarantee there is one per name. - llvm::FoldingSetNodeID ID; - ID.AddInteger(EKind); - ID.AddPointer(Ty.getAsOpaquePtr()); - - void *InsertPos = nullptr; - if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos)) - return DeclarationName(Name); - - CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName; - SpecialName->ExtraKindOrNumArgs = EKind; - SpecialName->Type = Ty; - SpecialName->FETokenInfo = nullptr; - - SpecialNames->InsertNode(SpecialName, InsertPos); - return DeclarationName(SpecialName); -} - -DeclarationName -DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) { - return DeclarationName(&CXXOperatorNames[(unsigned)Op]); } DeclarationName DeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) { - llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames - = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*> - (CXXLiteralOperatorNames); - llvm::FoldingSetNodeID ID; ID.AddPointer(II); void *InsertPos = nullptr; - if (CXXLiteralOperatorIdName *Name = - LiteralNames->FindNodeOrInsertPos(ID, InsertPos)) - return DeclarationName (Name); - - CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName; - LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator; - LiteralName->ID = II; - LiteralName->FETokenInfo = nullptr; + if (auto *Name = CXXLiteralOperatorNames.FindNodeOrInsertPos(ID, InsertPos)) + return DeclarationName(Name); - LiteralNames->InsertNode(LiteralName, InsertPos); + auto *LiteralName = new (Ctx) detail::CXXLiteralOperatorIdName(II); + CXXLiteralOperatorNames.InsertNode(LiteralName, InsertPos); return DeclarationName(LiteralName); } |