1193326Sed//===-- DeclarationName.cpp - Declaration names implementation --*- C++ -*-===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9193326Sed//
10193326Sed// This file implements the DeclarationName and DeclarationNameTable
11193326Sed// classes.
12193326Sed//
13193326Sed//===----------------------------------------------------------------------===//
14208600Srdivacky#include "clang/AST/ASTContext.h"
15208600Srdivacky#include "clang/AST/Decl.h"
16193326Sed#include "clang/AST/DeclarationName.h"
17193326Sed#include "clang/AST/Type.h"
18212904Sdim#include "clang/AST/TypeLoc.h"
19198954Srdivacky#include "clang/AST/TypeOrdering.h"
20193326Sed#include "clang/Basic/IdentifierTable.h"
21193326Sed#include "llvm/ADT/DenseMap.h"
22193326Sed#include "llvm/ADT/FoldingSet.h"
23218893Sdim#include "llvm/Support/ErrorHandling.h"
24207619Srdivacky#include "llvm/Support/raw_ostream.h"
25193326Sedusing namespace clang;
26193326Sed
27193326Sednamespace clang {
28193326Sed/// CXXSpecialName - Records the type associated with one of the
29193326Sed/// "special" kinds of declaration names in C++, e.g., constructors,
30193326Sed/// destructors, and conversion functions.
31198092Srdivackyclass CXXSpecialName
32193326Sed  : public DeclarationNameExtra, public llvm::FoldingSetNode {
33193326Sedpublic:
34193326Sed  /// Type - The type associated with this declaration name.
35193326Sed  QualType Type;
36193326Sed
37193326Sed  /// FETokenInfo - Extra information associated with this declaration
38193326Sed  /// name that can be used by the front end.
39193326Sed  void *FETokenInfo;
40193326Sed
41193326Sed  void Profile(llvm::FoldingSetNodeID &ID) {
42193326Sed    ID.AddInteger(ExtraKindOrNumArgs);
43193326Sed    ID.AddPointer(Type.getAsOpaquePtr());
44193326Sed  }
45193326Sed};
46193326Sed
47193326Sed/// CXXOperatorIdName - Contains extra information for the name of an
48198092Srdivacky/// overloaded operator in C++, such as "operator+.
49193326Sedclass CXXOperatorIdName : public DeclarationNameExtra {
50193326Sedpublic:
51193326Sed  /// FETokenInfo - Extra information associated with this operator
52193326Sed  /// name that can be used by the front end.
53193326Sed  void *FETokenInfo;
54193326Sed};
55193326Sed
56234353Sdim/// CXXLiteralOperatorName - Contains the actual identifier that makes up the
57199990Srdivacky/// name.
58199990Srdivacky///
59199990Srdivacky/// This identifier is stored here rather than directly in DeclarationName so as
60199990Srdivacky/// to allow Objective-C selectors, which are about a million times more common,
61199990Srdivacky/// to consume minimal memory.
62202379Srdivackyclass CXXLiteralOperatorIdName
63202379Srdivacky  : public DeclarationNameExtra, public llvm::FoldingSetNode {
64199990Srdivackypublic:
65199990Srdivacky  IdentifierInfo *ID;
66202379Srdivacky
67234353Sdim  /// FETokenInfo - Extra information associated with this operator
68234353Sdim  /// name that can be used by the front end.
69234353Sdim  void *FETokenInfo;
70234353Sdim
71202379Srdivacky  void Profile(llvm::FoldingSetNodeID &FSID) {
72202379Srdivacky    FSID.AddPointer(ID);
73202379Srdivacky  }
74199990Srdivacky};
75199990Srdivacky
76203955Srdivackystatic int compareInt(unsigned A, unsigned B) {
77203955Srdivacky  return (A < B ? -1 : (A > B ? 1 : 0));
78203955Srdivacky}
79203955Srdivacky
80203955Srdivackyint DeclarationName::compare(DeclarationName LHS, DeclarationName RHS) {
81198954Srdivacky  if (LHS.getNameKind() != RHS.getNameKind())
82203955Srdivacky    return (LHS.getNameKind() < RHS.getNameKind() ? -1 : 1);
83198954Srdivacky
84198954Srdivacky  switch (LHS.getNameKind()) {
85203955Srdivacky  case DeclarationName::Identifier: {
86203955Srdivacky    IdentifierInfo *LII = LHS.getAsIdentifierInfo();
87203955Srdivacky    IdentifierInfo *RII = RHS.getAsIdentifierInfo();
88203955Srdivacky    if (!LII) return RII ? -1 : 0;
89203955Srdivacky    if (!RII) return 1;
90203955Srdivacky
91203955Srdivacky    return LII->getName().compare(RII->getName());
92203955Srdivacky  }
93193326Sed
94198954Srdivacky  case DeclarationName::ObjCZeroArgSelector:
95198954Srdivacky  case DeclarationName::ObjCOneArgSelector:
96198954Srdivacky  case DeclarationName::ObjCMultiArgSelector: {
97198954Srdivacky    Selector LHSSelector = LHS.getObjCSelector();
98198954Srdivacky    Selector RHSSelector = RHS.getObjCSelector();
99203955Srdivacky    unsigned LN = LHSSelector.getNumArgs(), RN = RHSSelector.getNumArgs();
100203955Srdivacky    for (unsigned I = 0, N = std::min(LN, RN); I != N; ++I) {
101218893Sdim      switch (LHSSelector.getNameForSlot(I).compare(
102218893Sdim                                               RHSSelector.getNameForSlot(I))) {
103198954Srdivacky      case -1: return true;
104198954Srdivacky      case 1: return false;
105198954Srdivacky      default: break;
106198954Srdivacky      }
107198954Srdivacky    }
108203955Srdivacky
109203955Srdivacky    return compareInt(LN, RN);
110198954Srdivacky  }
111198954Srdivacky
112198954Srdivacky  case DeclarationName::CXXConstructorName:
113198954Srdivacky  case DeclarationName::CXXDestructorName:
114198954Srdivacky  case DeclarationName::CXXConversionFunctionName:
115203955Srdivacky    if (QualTypeOrdering()(LHS.getCXXNameType(), RHS.getCXXNameType()))
116203955Srdivacky      return -1;
117203955Srdivacky    if (QualTypeOrdering()(RHS.getCXXNameType(), LHS.getCXXNameType()))
118203955Srdivacky      return 1;
119203955Srdivacky    return 0;
120198954Srdivacky
121198954Srdivacky  case DeclarationName::CXXOperatorName:
122203955Srdivacky    return compareInt(LHS.getCXXOverloadedOperator(),
123203955Srdivacky                      RHS.getCXXOverloadedOperator());
124199990Srdivacky
125199990Srdivacky  case DeclarationName::CXXLiteralOperatorName:
126203955Srdivacky    return LHS.getCXXLiteralIdentifier()->getName().compare(
127203955Srdivacky                                   RHS.getCXXLiteralIdentifier()->getName());
128198954Srdivacky
129198954Srdivacky  case DeclarationName::CXXUsingDirective:
130203955Srdivacky    return 0;
131198954Srdivacky  }
132234353Sdim
133234353Sdim  llvm_unreachable("Invalid DeclarationName Kind!");
134193326Sed}
135193326Sed
136263508Sdimraw_ostream &operator<<(raw_ostream &OS, DeclarationName N) {
137263508Sdim  switch (N.getNameKind()) {
138263508Sdim  case DeclarationName::Identifier:
139263508Sdim    if (const IdentifierInfo *II = N.getAsIdentifierInfo())
140263508Sdim      OS << II->getName();
141263508Sdim    return OS;
142263508Sdim
143263508Sdim  case DeclarationName::ObjCZeroArgSelector:
144263508Sdim  case DeclarationName::ObjCOneArgSelector:
145263508Sdim  case DeclarationName::ObjCMultiArgSelector:
146263508Sdim    return OS << N.getObjCSelector().getAsString();
147263508Sdim
148263508Sdim  case DeclarationName::CXXConstructorName: {
149263508Sdim    QualType ClassType = N.getCXXNameType();
150263508Sdim    if (const RecordType *ClassRec = ClassType->getAs<RecordType>())
151263508Sdim      return OS << *ClassRec->getDecl();
152263508Sdim    return OS << ClassType.getAsString();
153263508Sdim  }
154263508Sdim
155263508Sdim  case DeclarationName::CXXDestructorName: {
156263508Sdim    OS << '~';
157263508Sdim    QualType Type = N.getCXXNameType();
158263508Sdim    if (const RecordType *Rec = Type->getAs<RecordType>())
159263508Sdim      return OS << *Rec->getDecl();
160263508Sdim    return OS << Type.getAsString();
161263508Sdim  }
162263508Sdim
163263508Sdim  case DeclarationName::CXXOperatorName: {
164263508Sdim    static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
165263508Sdim      0,
166263508Sdim#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
167263508Sdim      Spelling,
168263508Sdim#include "clang/Basic/OperatorKinds.def"
169263508Sdim    };
170263508Sdim    const char *OpName = OperatorNames[N.getCXXOverloadedOperator()];
171263508Sdim    assert(OpName && "not an overloaded operator");
172263508Sdim
173263508Sdim    OS << "operator";
174263508Sdim    if (OpName[0] >= 'a' && OpName[0] <= 'z')
175263508Sdim      OS << ' ';
176263508Sdim    return OS << OpName;
177263508Sdim  }
178263508Sdim
179263508Sdim  case DeclarationName::CXXLiteralOperatorName:
180263508Sdim    return OS << "operator \"\" " << N.getCXXLiteralIdentifier()->getName();
181263508Sdim
182263508Sdim  case DeclarationName::CXXConversionFunctionName: {
183263508Sdim    OS << "operator ";
184263508Sdim    QualType Type = N.getCXXNameType();
185263508Sdim    if (const RecordType *Rec = Type->getAs<RecordType>())
186263508Sdim      return OS << *Rec->getDecl();
187263508Sdim    return OS << Type.getAsString();
188263508Sdim  }
189263508Sdim  case DeclarationName::CXXUsingDirective:
190263508Sdim    return OS << "<using-directive>";
191263508Sdim  }
192263508Sdim
193263508Sdim  llvm_unreachable("Unexpected declaration name kind");
194263508Sdim}
195263508Sdim
196193326Sed} // end namespace clang
197193326Sed
198193326SedDeclarationName::NameKind DeclarationName::getNameKind() const {
199193326Sed  switch (getStoredNameKind()) {
200193326Sed  case StoredIdentifier:          return Identifier;
201193326Sed  case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
202193326Sed  case StoredObjCOneArgSelector:  return ObjCOneArgSelector;
203193326Sed
204193326Sed  case StoredDeclarationNameExtra:
205193326Sed    switch (getExtra()->ExtraKindOrNumArgs) {
206198092Srdivacky    case DeclarationNameExtra::CXXConstructor:
207193326Sed      return CXXConstructorName;
208193326Sed
209198092Srdivacky    case DeclarationNameExtra::CXXDestructor:
210193326Sed      return CXXDestructorName;
211193326Sed
212198092Srdivacky    case DeclarationNameExtra::CXXConversionFunction:
213193326Sed      return CXXConversionFunctionName;
214193326Sed
215199990Srdivacky    case DeclarationNameExtra::CXXLiteralOperator:
216199990Srdivacky      return CXXLiteralOperatorName;
217199990Srdivacky
218193326Sed    case DeclarationNameExtra::CXXUsingDirective:
219193326Sed      return CXXUsingDirective;
220193326Sed
221193326Sed    default:
222193326Sed      // Check if we have one of the CXXOperator* enumeration values.
223198092Srdivacky      if (getExtra()->ExtraKindOrNumArgs <
224193326Sed            DeclarationNameExtra::CXXUsingDirective)
225193326Sed        return CXXOperatorName;
226193326Sed
227193326Sed      return ObjCMultiArgSelector;
228193326Sed    }
229193326Sed  }
230193326Sed
231193326Sed  // Can't actually get here.
232226633Sdim  llvm_unreachable("This should be unreachable!");
233193326Sed}
234193326Sed
235202379Srdivackybool DeclarationName::isDependentName() const {
236202379Srdivacky  QualType T = getCXXNameType();
237202379Srdivacky  return !T.isNull() && T->isDependentType();
238202379Srdivacky}
239202379Srdivacky
240193326Sedstd::string DeclarationName::getAsString() const {
241207619Srdivacky  std::string Result;
242207619Srdivacky  llvm::raw_string_ostream OS(Result);
243263508Sdim  OS << *this;
244207619Srdivacky  return OS.str();
245207619Srdivacky}
246207619Srdivacky
247193326SedQualType DeclarationName::getCXXNameType() const {
248193326Sed  if (CXXSpecialName *CXXName = getAsCXXSpecialName())
249193326Sed    return CXXName->Type;
250193326Sed  else
251193326Sed    return QualType();
252193326Sed}
253193326Sed
254193326SedOverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
255193326Sed  if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
256198092Srdivacky    unsigned value
257193326Sed      = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
258193326Sed    return static_cast<OverloadedOperatorKind>(value);
259193326Sed  } else {
260193326Sed    return OO_None;
261193326Sed  }
262193326Sed}
263193326Sed
264199990SrdivackyIdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
265199990Srdivacky  if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
266199990Srdivacky    return CXXLit->ID;
267199990Srdivacky  else
268199990Srdivacky    return 0;
269199990Srdivacky}
270199990Srdivacky
271239462Sdimvoid *DeclarationName::getFETokenInfoAsVoidSlow() const {
272193326Sed  switch (getNameKind()) {
273193326Sed  case Identifier:
274239462Sdim    llvm_unreachable("Handled by getFETokenInfo()");
275193326Sed
276193326Sed  case CXXConstructorName:
277193326Sed  case CXXDestructorName:
278193326Sed  case CXXConversionFunctionName:
279193326Sed    return getAsCXXSpecialName()->FETokenInfo;
280193326Sed
281193326Sed  case CXXOperatorName:
282193326Sed    return getAsCXXOperatorIdName()->FETokenInfo;
283193326Sed
284199990Srdivacky  case CXXLiteralOperatorName:
285234353Sdim    return getAsCXXLiteralOperatorIdName()->FETokenInfo;
286199990Srdivacky
287193326Sed  default:
288226633Sdim    llvm_unreachable("Declaration name has no FETokenInfo");
289193326Sed  }
290193326Sed}
291193326Sed
292193326Sedvoid DeclarationName::setFETokenInfo(void *T) {
293193326Sed  switch (getNameKind()) {
294193326Sed  case Identifier:
295193326Sed    getAsIdentifierInfo()->setFETokenInfo(T);
296193326Sed    break;
297193326Sed
298193326Sed  case CXXConstructorName:
299193326Sed  case CXXDestructorName:
300193326Sed  case CXXConversionFunctionName:
301193326Sed    getAsCXXSpecialName()->FETokenInfo = T;
302193326Sed    break;
303193326Sed
304193326Sed  case CXXOperatorName:
305193326Sed    getAsCXXOperatorIdName()->FETokenInfo = T;
306193326Sed    break;
307193326Sed
308199990Srdivacky  case CXXLiteralOperatorName:
309234353Sdim    getAsCXXLiteralOperatorIdName()->FETokenInfo = T;
310199990Srdivacky    break;
311199990Srdivacky
312193326Sed  default:
313226633Sdim    llvm_unreachable("Declaration name has no FETokenInfo");
314193326Sed  }
315193326Sed}
316193326Sed
317193326SedDeclarationName DeclarationName::getUsingDirectiveName() {
318193326Sed  // Single instance of DeclarationNameExtra for using-directive
319200583Srdivacky  static const DeclarationNameExtra UDirExtra =
320193326Sed    { DeclarationNameExtra::CXXUsingDirective };
321193326Sed
322193326Sed  uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
323193326Sed  Ptr |= StoredDeclarationNameExtra;
324193326Sed
325193326Sed  return DeclarationName(Ptr);
326193326Sed}
327193326Sed
328199482Srdivackyvoid DeclarationName::dump() const {
329263508Sdim  llvm::errs() << *this << '\n';
330199482Srdivacky}
331199482Srdivacky
332218893SdimDeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
333193326Sed  CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
334202379Srdivacky  CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
335193326Sed
336193326Sed  // Initialize the overloaded operator names.
337208600Srdivacky  CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
338193326Sed  for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
339198092Srdivacky    CXXOperatorNames[Op].ExtraKindOrNumArgs
340193326Sed      = Op + DeclarationNameExtra::CXXConversionFunction;
341193326Sed    CXXOperatorNames[Op].FETokenInfo = 0;
342193326Sed  }
343193326Sed}
344193326Sed
345193326SedDeclarationNameTable::~DeclarationNameTable() {
346202379Srdivacky  llvm::FoldingSet<CXXSpecialName> *SpecialNames =
347193326Sed    static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
348208600Srdivacky  llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
349208600Srdivacky    = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
350208600Srdivacky        (CXXLiteralOperatorNames);
351193326Sed
352202379Srdivacky  delete SpecialNames;
353202379Srdivacky  delete LiteralNames;
354193326Sed}
355193326Sed
356249423SdimDeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
357249423Sdim  return getCXXSpecialName(DeclarationName::CXXConstructorName,
358249423Sdim                           Ty.getUnqualifiedType());
359249423Sdim}
360249423Sdim
361249423SdimDeclarationName DeclarationNameTable::getCXXDestructorName(CanQualType Ty) {
362249423Sdim  return getCXXSpecialName(DeclarationName::CXXDestructorName,
363249423Sdim                           Ty.getUnqualifiedType());
364249423Sdim}
365249423Sdim
366198092SrdivackyDeclarationName
367249423SdimDeclarationNameTable::getCXXConversionFunctionName(CanQualType Ty) {
368249423Sdim  return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty);
369249423Sdim}
370249423Sdim
371249423SdimDeclarationName
372198092SrdivackyDeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
373198092Srdivacky                                        CanQualType Ty) {
374193326Sed  assert(Kind >= DeclarationName::CXXConstructorName &&
375193326Sed         Kind <= DeclarationName::CXXConversionFunctionName &&
376193326Sed         "Kind must be a C++ special name kind");
377198092Srdivacky  llvm::FoldingSet<CXXSpecialName> *SpecialNames
378193326Sed    = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
379193326Sed
380193326Sed  DeclarationNameExtra::ExtraKind EKind;
381193326Sed  switch (Kind) {
382198092Srdivacky  case DeclarationName::CXXConstructorName:
383193326Sed    EKind = DeclarationNameExtra::CXXConstructor;
384198092Srdivacky    assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
385193326Sed    break;
386193326Sed  case DeclarationName::CXXDestructorName:
387193326Sed    EKind = DeclarationNameExtra::CXXDestructor;
388198092Srdivacky    assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
389193326Sed    break;
390193326Sed  case DeclarationName::CXXConversionFunctionName:
391193326Sed    EKind = DeclarationNameExtra::CXXConversionFunction;
392193326Sed    break;
393193326Sed  default:
394193326Sed    return DeclarationName();
395193326Sed  }
396193326Sed
397193326Sed  // Unique selector, to guarantee there is one per name.
398193326Sed  llvm::FoldingSetNodeID ID;
399193326Sed  ID.AddInteger(EKind);
400193326Sed  ID.AddPointer(Ty.getAsOpaquePtr());
401193326Sed
402193326Sed  void *InsertPos = 0;
403193326Sed  if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
404193326Sed    return DeclarationName(Name);
405193326Sed
406208600Srdivacky  CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
407193326Sed  SpecialName->ExtraKindOrNumArgs = EKind;
408193326Sed  SpecialName->Type = Ty;
409193326Sed  SpecialName->FETokenInfo = 0;
410193326Sed
411193326Sed  SpecialNames->InsertNode(SpecialName, InsertPos);
412193326Sed  return DeclarationName(SpecialName);
413193326Sed}
414193326Sed
415198092SrdivackyDeclarationName
416193326SedDeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
417193326Sed  return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
418193326Sed}
419193326Sed
420199990SrdivackyDeclarationName
421199990SrdivackyDeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
422202379Srdivacky  llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
423202379Srdivacky    = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
424202379Srdivacky                                                      (CXXLiteralOperatorNames);
425202379Srdivacky
426202379Srdivacky  llvm::FoldingSetNodeID ID;
427202379Srdivacky  ID.AddPointer(II);
428202379Srdivacky
429202379Srdivacky  void *InsertPos = 0;
430202379Srdivacky  if (CXXLiteralOperatorIdName *Name =
431202379Srdivacky                               LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
432202379Srdivacky    return DeclarationName (Name);
433202379Srdivacky
434208600Srdivacky  CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
435199990Srdivacky  LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
436199990Srdivacky  LiteralName->ID = II;
437234353Sdim  LiteralName->FETokenInfo = 0;
438202379Srdivacky
439202379Srdivacky  LiteralNames->InsertNode(LiteralName, InsertPos);
440199990Srdivacky  return DeclarationName(LiteralName);
441199990Srdivacky}
442199990Srdivacky
443212904SdimDeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
444212904Sdim  switch (Name.getNameKind()) {
445212904Sdim  case DeclarationName::Identifier:
446212904Sdim    break;
447212904Sdim  case DeclarationName::CXXConstructorName:
448212904Sdim  case DeclarationName::CXXDestructorName:
449212904Sdim  case DeclarationName::CXXConversionFunctionName:
450212904Sdim    NamedType.TInfo = 0;
451212904Sdim    break;
452212904Sdim  case DeclarationName::CXXOperatorName:
453212904Sdim    CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
454212904Sdim    CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
455212904Sdim    break;
456212904Sdim  case DeclarationName::CXXLiteralOperatorName:
457212904Sdim    CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
458212904Sdim    break;
459212904Sdim  case DeclarationName::ObjCZeroArgSelector:
460212904Sdim  case DeclarationName::ObjCOneArgSelector:
461212904Sdim  case DeclarationName::ObjCMultiArgSelector:
462212904Sdim    // FIXME: ?
463212904Sdim    break;
464212904Sdim  case DeclarationName::CXXUsingDirective:
465212904Sdim    break;
466212904Sdim  }
467212904Sdim}
468212904Sdim
469218893Sdimbool DeclarationNameInfo::containsUnexpandedParameterPack() const {
470218893Sdim  switch (Name.getNameKind()) {
471218893Sdim  case DeclarationName::Identifier:
472218893Sdim  case DeclarationName::ObjCZeroArgSelector:
473218893Sdim  case DeclarationName::ObjCOneArgSelector:
474218893Sdim  case DeclarationName::ObjCMultiArgSelector:
475218893Sdim  case DeclarationName::CXXOperatorName:
476218893Sdim  case DeclarationName::CXXLiteralOperatorName:
477218893Sdim  case DeclarationName::CXXUsingDirective:
478218893Sdim    return false;
479218893Sdim
480218893Sdim  case DeclarationName::CXXConstructorName:
481218893Sdim  case DeclarationName::CXXDestructorName:
482218893Sdim  case DeclarationName::CXXConversionFunctionName:
483218893Sdim    if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
484218893Sdim      return TInfo->getType()->containsUnexpandedParameterPack();
485218893Sdim
486218893Sdim    return Name.getCXXNameType()->containsUnexpandedParameterPack();
487218893Sdim  }
488218893Sdim  llvm_unreachable("All name kinds handled.");
489218893Sdim}
490218893Sdim
491224145Sdimbool DeclarationNameInfo::isInstantiationDependent() const {
492224145Sdim  switch (Name.getNameKind()) {
493224145Sdim  case DeclarationName::Identifier:
494224145Sdim  case DeclarationName::ObjCZeroArgSelector:
495224145Sdim  case DeclarationName::ObjCOneArgSelector:
496224145Sdim  case DeclarationName::ObjCMultiArgSelector:
497224145Sdim  case DeclarationName::CXXOperatorName:
498224145Sdim  case DeclarationName::CXXLiteralOperatorName:
499224145Sdim  case DeclarationName::CXXUsingDirective:
500224145Sdim    return false;
501224145Sdim
502224145Sdim  case DeclarationName::CXXConstructorName:
503224145Sdim  case DeclarationName::CXXDestructorName:
504224145Sdim  case DeclarationName::CXXConversionFunctionName:
505224145Sdim    if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
506224145Sdim      return TInfo->getType()->isInstantiationDependentType();
507224145Sdim
508224145Sdim    return Name.getCXXNameType()->isInstantiationDependentType();
509224145Sdim  }
510224145Sdim  llvm_unreachable("All name kinds handled.");
511224145Sdim}
512224145Sdim
513212904Sdimstd::string DeclarationNameInfo::getAsString() const {
514212904Sdim  std::string Result;
515212904Sdim  llvm::raw_string_ostream OS(Result);
516212904Sdim  printName(OS);
517212904Sdim  return OS.str();
518212904Sdim}
519212904Sdim
520226633Sdimvoid DeclarationNameInfo::printName(raw_ostream &OS) const {
521212904Sdim  switch (Name.getNameKind()) {
522212904Sdim  case DeclarationName::Identifier:
523212904Sdim  case DeclarationName::ObjCZeroArgSelector:
524212904Sdim  case DeclarationName::ObjCOneArgSelector:
525212904Sdim  case DeclarationName::ObjCMultiArgSelector:
526212904Sdim  case DeclarationName::CXXOperatorName:
527212904Sdim  case DeclarationName::CXXLiteralOperatorName:
528212904Sdim  case DeclarationName::CXXUsingDirective:
529263508Sdim    OS << Name;
530212904Sdim    return;
531212904Sdim
532212904Sdim  case DeclarationName::CXXConstructorName:
533212904Sdim  case DeclarationName::CXXDestructorName:
534212904Sdim  case DeclarationName::CXXConversionFunctionName:
535212904Sdim    if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
536212904Sdim      if (Name.getNameKind() == DeclarationName::CXXDestructorName)
537212904Sdim        OS << '~';
538212904Sdim      else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
539212904Sdim        OS << "operator ";
540212904Sdim      OS << TInfo->getType().getAsString();
541263508Sdim    } else
542263508Sdim      OS << Name;
543212904Sdim    return;
544212904Sdim  }
545226633Sdim  llvm_unreachable("Unexpected declaration name kind");
546212904Sdim}
547212904Sdim
548212904SdimSourceLocation DeclarationNameInfo::getEndLoc() const {
549212904Sdim  switch (Name.getNameKind()) {
550212904Sdim  case DeclarationName::Identifier:
551212904Sdim    return NameLoc;
552212904Sdim
553212904Sdim  case DeclarationName::CXXOperatorName: {
554212904Sdim    unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
555212904Sdim    return SourceLocation::getFromRawEncoding(raw);
556212904Sdim  }
557212904Sdim
558212904Sdim  case DeclarationName::CXXLiteralOperatorName: {
559212904Sdim    unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
560212904Sdim    return SourceLocation::getFromRawEncoding(raw);
561212904Sdim  }
562212904Sdim
563212904Sdim  case DeclarationName::CXXConstructorName:
564212904Sdim  case DeclarationName::CXXDestructorName:
565212904Sdim  case DeclarationName::CXXConversionFunctionName:
566212904Sdim    if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
567212904Sdim      return TInfo->getTypeLoc().getEndLoc();
568212904Sdim    else
569212904Sdim      return NameLoc;
570212904Sdim
571212904Sdim    // DNInfo work in progress: FIXME.
572212904Sdim  case DeclarationName::ObjCZeroArgSelector:
573212904Sdim  case DeclarationName::ObjCOneArgSelector:
574212904Sdim  case DeclarationName::ObjCMultiArgSelector:
575212904Sdim  case DeclarationName::CXXUsingDirective:
576212904Sdim    return NameLoc;
577212904Sdim  }
578226633Sdim  llvm_unreachable("Unexpected declaration name kind");
579212904Sdim}
580