580 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			580 lines
		
	
	
		
			18 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;
 | |
| };
 | |
| 
 | |
| /// 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!");
 | |
| }
 | |
| 
 | |
| raw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
 | |
|   switch (N.getNameKind()) {
 | |
|   case DeclarationName::Identifier:
 | |
|     if (const IdentifierInfo *II = N.getAsIdentifierInfo())
 | |
|       OS << II->getName();
 | |
|     return OS;
 | |
| 
 | |
|   case DeclarationName::ObjCZeroArgSelector:
 | |
|   case DeclarationName::ObjCOneArgSelector:
 | |
|   case DeclarationName::ObjCMultiArgSelector:
 | |
|     return OS << N.getObjCSelector().getAsString();
 | |
| 
 | |
|   case DeclarationName::CXXConstructorName: {
 | |
|     QualType ClassType = N.getCXXNameType();
 | |
|     if (const RecordType *ClassRec = ClassType->getAs<RecordType>())
 | |
|       return OS << *ClassRec->getDecl();
 | |
|     return OS << ClassType.getAsString();
 | |
|   }
 | |
| 
 | |
|   case DeclarationName::CXXDestructorName: {
 | |
|     OS << '~';
 | |
|     QualType Type = N.getCXXNameType();
 | |
|     if (const RecordType *Rec = Type->getAs<RecordType>())
 | |
|       return OS << *Rec->getDecl();
 | |
|     return OS << Type.getAsString();
 | |
|   }
 | |
| 
 | |
|   case DeclarationName::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[N.getCXXOverloadedOperator()];
 | |
|     assert(OpName && "not an overloaded operator");
 | |
| 
 | |
|     OS << "operator";
 | |
|     if (OpName[0] >= 'a' && OpName[0] <= 'z')
 | |
|       OS << ' ';
 | |
|     return OS << OpName;
 | |
|   }
 | |
| 
 | |
|   case DeclarationName::CXXLiteralOperatorName:
 | |
|     return OS << "operator \"\" " << N.getCXXLiteralIdentifier()->getName();
 | |
| 
 | |
|   case DeclarationName::CXXConversionFunctionName: {
 | |
|     OS << "operator ";
 | |
|     QualType Type = N.getCXXNameType();
 | |
|     if (const RecordType *Rec = Type->getAs<RecordType>())
 | |
|       return OS << *Rec->getDecl();
 | |
|     return OS << Type.getAsString();
 | |
|   }
 | |
|   case DeclarationName::CXXUsingDirective:
 | |
|     return OS << "<using-directive>";
 | |
|   }
 | |
| 
 | |
|   llvm_unreachable("Unexpected declaration name kind");
 | |
| }
 | |
| 
 | |
| } // 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 0;
 | |
| }
 | |
| 
 | |
| 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);
 | |
| }
 | |
| 
 | |
| 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 = 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::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 = 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;
 | |
|   LiteralName->FETokenInfo = 0;
 | |
| 
 | |
|   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 = 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:
 | |
|     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 ";
 | |
|       OS << TInfo->getType().getAsString();
 | |
|     } 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");
 | |
| }
 | 
