You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
611 lines
19 KiB
611 lines
19 KiB
//===-- DeclarationName.cpp - Declaration names implementation --*- C++ -*-===// |
|
// |
|
// The LLVM Compiler Infrastructure |
|
// |
|
// This file is distributed under the University of Illinois Open Source |
|
// License. See LICENSE.TXT for details. |
|
// |
|
//===----------------------------------------------------------------------===// |
|
// |
|
// This file implements the DeclarationName and DeclarationNameTable |
|
// classes. |
|
// |
|
//===----------------------------------------------------------------------===// |
|
#include "clang/AST/ASTContext.h" |
|
#include "clang/AST/DeclCXX.h" |
|
#include "clang/AST/DeclarationName.h" |
|
#include "clang/AST/Type.h" |
|
#include "clang/AST/TypeLoc.h" |
|
#include "clang/AST/TypeOrdering.h" |
|
#include "clang/Basic/IdentifierTable.h" |
|
#include "llvm/ADT/DenseMap.h" |
|
#include "llvm/ADT/FoldingSet.h" |
|
#include "llvm/Support/ErrorHandling.h" |
|
#include "llvm/Support/raw_ostream.h" |
|
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()); |
|
} |
|
}; |
|
|
|
/// 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); |
|
} |
|
}; |
|
|
|
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.getAsIdentifierInfo(); |
|
IdentifierInfo *RII = RHS.getAsIdentifierInfo(); |
|
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(); |
|
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 true; |
|
case 1: return false; |
|
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::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) { |
|
DeclarationName &N = *this; |
|
switch (N.getNameKind()) { |
|
case DeclarationName::Identifier: |
|
if (const IdentifierInfo *II = N.getAsIdentifierInfo()) |
|
OS << II->getName(); |
|
return; |
|
|
|
case DeclarationName::ObjCZeroArgSelector: |
|
case DeclarationName::ObjCOneArgSelector: |
|
case DeclarationName::ObjCMultiArgSelector: |
|
N.getObjCSelector().print(OS); |
|
return; |
|
|
|
case DeclarationName::CXXConstructorName: |
|
return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy); |
|
|
|
case DeclarationName::CXXDestructorName: { |
|
OS << '~'; |
|
return printCXXConstructorDestructorName(N.getCXXNameType(), OS, Policy); |
|
} |
|
|
|
case DeclarationName::CXXOperatorName: { |
|
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()]; |
|
assert(OpName && "not an overloaded operator"); |
|
|
|
OS << "operator"; |
|
if (OpName[0] >= 'a' && OpName[0] <= 'z') |
|
OS << ' '; |
|
OS << OpName; |
|
return; |
|
} |
|
|
|
case DeclarationName::CXXLiteralOperatorName: |
|
OS << "operator\"\"" << N.getCXXLiteralIdentifier()->getName(); |
|
return; |
|
|
|
case DeclarationName::CXXConversionFunctionName: { |
|
OS << "operator "; |
|
QualType Type = N.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"); |
|
} |
|
|
|
raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) { |
|
LangOptions LO; |
|
N.print(OS, PrintingPolicy(LO)); |
|
return OS; |
|
} |
|
|
|
} // end 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::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(); |
|
return !T.isNull() && T->isDependentType(); |
|
} |
|
|
|
std::string DeclarationName::getAsString() const { |
|
std::string Result; |
|
llvm::raw_string_ostream OS(Result); |
|
OS << *this; |
|
return OS.str(); |
|
} |
|
|
|
QualType DeclarationName::getCXXNameType() const { |
|
if (CXXSpecialName *CXXName = getAsCXXSpecialName()) |
|
return CXXName->Type; |
|
else |
|
return QualType(); |
|
} |
|
|
|
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 { |
|
switch (getNameKind()) { |
|
case Identifier: |
|
llvm_unreachable("Handled by getFETokenInfo()"); |
|
|
|
case CXXConstructorName: |
|
case CXXDestructorName: |
|
case CXXConversionFunctionName: |
|
return getAsCXXSpecialName()->FETokenInfo; |
|
|
|
case CXXOperatorName: |
|
return getAsCXXOperatorIdName()->FETokenInfo; |
|
|
|
case CXXLiteralOperatorName: |
|
return getAsCXXLiteralOperatorIdName()->FETokenInfo; |
|
|
|
default: |
|
llvm_unreachable("Declaration name has no FETokenInfo"); |
|
} |
|
} |
|
|
|
void DeclarationName::setFETokenInfo(void *T) { |
|
switch (getNameKind()) { |
|
case Identifier: |
|
getAsIdentifierInfo()->setFETokenInfo(T); |
|
break; |
|
|
|
case CXXConstructorName: |
|
case CXXDestructorName: |
|
case CXXConversionFunctionName: |
|
getAsCXXSpecialName()->FETokenInfo = T; |
|
break; |
|
|
|
case CXXOperatorName: |
|
getAsCXXOperatorIdName()->FETokenInfo = T; |
|
break; |
|
|
|
case CXXLiteralOperatorName: |
|
getAsCXXLiteralOperatorIdName()->FETokenInfo = T; |
|
break; |
|
|
|
default: |
|
llvm_unreachable("Declaration name 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>; |
|
|
|
// 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() { |
|
llvm::FoldingSet<CXXSpecialName> *SpecialNames = |
|
static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl); |
|
llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames |
|
= static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*> |
|
(CXXLiteralOperatorNames); |
|
|
|
delete SpecialNames; |
|
delete LiteralNames; |
|
} |
|
|
|
DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) { |
|
return getCXXSpecialName(DeclarationName::CXXConstructorName, |
|
Ty.getUnqualifiedType()); |
|
} |
|
|
|
DeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) { |
|
return getCXXSpecialName(DeclarationName::CXXDestructorName, |
|
Ty.getUnqualifiedType()); |
|
} |
|
|
|
DeclarationName |
|
DeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) { |
|
return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty); |
|
} |
|
|
|
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; |
|
case DeclarationName::CXXDestructorName: |
|
EKind = DeclarationNameExtra::CXXDestructor; |
|
assert(!Ty.hasQualifiers() && "Destructor type must be unqualified"); |
|
break; |
|
case DeclarationName::CXXConversionFunctionName: |
|
EKind = DeclarationNameExtra::CXXConversionFunction; |
|
break; |
|
default: |
|
return DeclarationName(); |
|
} |
|
|
|
// 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; |
|
|
|
LiteralNames->InsertNode(LiteralName, InsertPos); |
|
return DeclarationName(LiteralName); |
|
} |
|
|
|
DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) { |
|
switch (Name.getNameKind()) { |
|
case DeclarationName::Identifier: |
|
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: |
|
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: |
|
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: |
|
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; |
|
OS << TInfo->getType().getAsString(PrintingPolicy(LO)); |
|
} else |
|
OS << Name; |
|
return; |
|
} |
|
llvm_unreachable("Unexpected declaration name kind"); |
|
} |
|
|
|
SourceLocation DeclarationNameInfo::getEndLoc() const { |
|
switch (Name.getNameKind()) { |
|
case DeclarationName::Identifier: |
|
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"); |
|
}
|
|
|