mirror of
https://github.com/llvm/llvm-project.git
synced 2025-05-01 17:26:04 +00:00

This seems to negatively affect compile time onsome ObjC tests (which use a lot of partial diagnostics I assume). I have to come up with a way to keep them inline without including Diagnostic.h everywhere. Now adding a new diagnostic requires a full rebuild of e.g. the static analyzer which doesn't even use those diagnostics. This reverts commit 6496bd10dc3a6d5e3266348f08b6e35f8184bc99. This reverts commit 7af19b817ba964ac560b50c1ed6183235f699789. This reverts commit fdd15602a42bbe26185978ef1e17019f6d969aa7. This reverts commit 00bd44d5677783527d7517c1ffe45e4d75a0f56f. This reverts commit ef9b60ffed980864a8db26ad30344be429e58ff5. llvm-svn: 150006
623 lines
19 KiB
C++
623 lines
19 KiB
C++
//===-- 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/Decl.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;
|
|
};
|
|
|
|
/// CXXLiberalOperatorName - 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;
|
|
|
|
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!");
|
|
}
|
|
|
|
} // end namespace clang
|
|
|
|
DeclarationName::DeclarationName(Selector Sel) {
|
|
if (!Sel.getAsOpaquePtr()) {
|
|
Ptr = 0;
|
|
return;
|
|
}
|
|
|
|
switch (Sel.getNumArgs()) {
|
|
case 0:
|
|
Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
|
|
assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
|
|
Ptr |= StoredObjCZeroArgSelector;
|
|
break;
|
|
|
|
case 1:
|
|
Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
|
|
assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
|
|
Ptr |= StoredObjCOneArgSelector;
|
|
break;
|
|
|
|
default:
|
|
Ptr = Sel.InfoPtr & ~Selector::ArgFlags;
|
|
assert((Ptr & PtrMask) == 0 && "Improperly aligned MultiKeywordSelector");
|
|
Ptr |= StoredDeclarationNameExtra;
|
|
break;
|
|
}
|
|
}
|
|
|
|
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);
|
|
printName(OS);
|
|
return OS.str();
|
|
}
|
|
|
|
void DeclarationName::printName(raw_ostream &OS) const {
|
|
switch (getNameKind()) {
|
|
case Identifier:
|
|
if (const IdentifierInfo *II = getAsIdentifierInfo())
|
|
OS << II->getName();
|
|
return;
|
|
|
|
case ObjCZeroArgSelector:
|
|
case ObjCOneArgSelector:
|
|
case ObjCMultiArgSelector:
|
|
OS << getObjCSelector().getAsString();
|
|
return;
|
|
|
|
case CXXConstructorName: {
|
|
QualType ClassType = getCXXNameType();
|
|
if (const RecordType *ClassRec = ClassType->getAs<RecordType>())
|
|
OS << *ClassRec->getDecl();
|
|
else
|
|
OS << ClassType.getAsString();
|
|
return;
|
|
}
|
|
|
|
case CXXDestructorName: {
|
|
OS << '~';
|
|
QualType Type = getCXXNameType();
|
|
if (const RecordType *Rec = Type->getAs<RecordType>())
|
|
OS << *Rec->getDecl();
|
|
else
|
|
OS << Type.getAsString();
|
|
return;
|
|
}
|
|
|
|
case CXXOperatorName: {
|
|
static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
|
|
0,
|
|
#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
|
|
Spelling,
|
|
#include "clang/Basic/OperatorKinds.def"
|
|
};
|
|
const char *OpName = OperatorNames[getCXXOverloadedOperator()];
|
|
assert(OpName && "not an overloaded operator");
|
|
|
|
OS << "operator";
|
|
if (OpName[0] >= 'a' && OpName[0] <= 'z')
|
|
OS << ' ';
|
|
OS << OpName;
|
|
return;
|
|
}
|
|
|
|
case CXXLiteralOperatorName:
|
|
OS << "operator \"\" " << getCXXLiteralIdentifier()->getName();
|
|
return;
|
|
|
|
case CXXConversionFunctionName: {
|
|
OS << "operator ";
|
|
QualType Type = getCXXNameType();
|
|
if (const RecordType *Rec = Type->getAs<RecordType>())
|
|
OS << *Rec->getDecl();
|
|
else
|
|
OS << Type.getAsString();
|
|
return;
|
|
}
|
|
case CXXUsingDirective:
|
|
OS << "<using-directive>";
|
|
return;
|
|
}
|
|
|
|
llvm_unreachable("Unexpected declaration name kind");
|
|
}
|
|
|
|
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 0;
|
|
}
|
|
|
|
Selector DeclarationName::getObjCSelector() const {
|
|
switch (getNameKind()) {
|
|
case ObjCZeroArgSelector:
|
|
return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 0);
|
|
|
|
case ObjCOneArgSelector:
|
|
return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 1);
|
|
|
|
case ObjCMultiArgSelector:
|
|
return Selector(reinterpret_cast<MultiKeywordSelector *>(Ptr & ~PtrMask));
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return Selector();
|
|
}
|
|
|
|
void *DeclarationName::getFETokenInfoAsVoid() const {
|
|
switch (getNameKind()) {
|
|
case Identifier:
|
|
return getAsIdentifierInfo()->getFETokenInfo<void>();
|
|
|
|
case CXXConstructorName:
|
|
case CXXDestructorName:
|
|
case CXXConversionFunctionName:
|
|
return getAsCXXSpecialName()->FETokenInfo;
|
|
|
|
case CXXOperatorName:
|
|
return getAsCXXOperatorIdName()->FETokenInfo;
|
|
|
|
case CXXLiteralOperatorName:
|
|
return getCXXLiteralIdentifier()->getFETokenInfo<void>();
|
|
|
|
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:
|
|
getCXXLiteralIdentifier()->setFETokenInfo(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);
|
|
}
|
|
|
|
void DeclarationName::dump() const {
|
|
printName(llvm::errs());
|
|
llvm::errs() << '\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 = 0;
|
|
}
|
|
}
|
|
|
|
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::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 = 0;
|
|
if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
|
|
return DeclarationName(Name);
|
|
|
|
CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
|
|
SpecialName->ExtraKindOrNumArgs = EKind;
|
|
SpecialName->Type = Ty;
|
|
SpecialName->FETokenInfo = 0;
|
|
|
|
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 = 0;
|
|
if (CXXLiteralOperatorIdName *Name =
|
|
LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
|
|
return DeclarationName (Name);
|
|
|
|
CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
|
|
LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
|
|
LiteralName->ID = II;
|
|
|
|
LiteralNames->InsertNode(LiteralName, InsertPos);
|
|
return DeclarationName(LiteralName);
|
|
}
|
|
|
|
unsigned
|
|
llvm::DenseMapInfo<clang::DeclarationName>::
|
|
getHashValue(clang::DeclarationName N) {
|
|
return DenseMapInfo<void*>::getHashValue(N.getAsOpaquePtr());
|
|
}
|
|
|
|
DeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
|
|
switch (Name.getNameKind()) {
|
|
case DeclarationName::Identifier:
|
|
break;
|
|
case DeclarationName::CXXConstructorName:
|
|
case DeclarationName::CXXDestructorName:
|
|
case DeclarationName::CXXConversionFunctionName:
|
|
NamedType.TInfo = 0;
|
|
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:
|
|
Name.printName(OS);
|
|
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 ";
|
|
OS << TInfo->getType().getAsString();
|
|
}
|
|
else
|
|
Name.printName(OS);
|
|
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");
|
|
}
|