DeclarationName.cpp revision 234353
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
136193326Sed} // end namespace clang
137193326Sed
138193326SedDeclarationName::DeclarationName(Selector Sel) {
139193326Sed  if (!Sel.getAsOpaquePtr()) {
140198398Srdivacky    Ptr = 0;
141193326Sed    return;
142193326Sed  }
143193326Sed
144193326Sed  switch (Sel.getNumArgs()) {
145193326Sed  case 0:
146193326Sed    Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
147193326Sed    assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
148193326Sed    Ptr |= StoredObjCZeroArgSelector;
149193326Sed    break;
150193326Sed
151193326Sed  case 1:
152193326Sed    Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
153193326Sed    assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
154193326Sed    Ptr |= StoredObjCOneArgSelector;
155193326Sed    break;
156193326Sed
157193326Sed  default:
158193326Sed    Ptr = Sel.InfoPtr & ~Selector::ArgFlags;
159193326Sed    assert((Ptr & PtrMask) == 0 && "Improperly aligned MultiKeywordSelector");
160193326Sed    Ptr |= StoredDeclarationNameExtra;
161193326Sed    break;
162193326Sed  }
163193326Sed}
164193326Sed
165193326SedDeclarationName::NameKind DeclarationName::getNameKind() const {
166193326Sed  switch (getStoredNameKind()) {
167193326Sed  case StoredIdentifier:          return Identifier;
168193326Sed  case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
169193326Sed  case StoredObjCOneArgSelector:  return ObjCOneArgSelector;
170193326Sed
171193326Sed  case StoredDeclarationNameExtra:
172193326Sed    switch (getExtra()->ExtraKindOrNumArgs) {
173198092Srdivacky    case DeclarationNameExtra::CXXConstructor:
174193326Sed      return CXXConstructorName;
175193326Sed
176198092Srdivacky    case DeclarationNameExtra::CXXDestructor:
177193326Sed      return CXXDestructorName;
178193326Sed
179198092Srdivacky    case DeclarationNameExtra::CXXConversionFunction:
180193326Sed      return CXXConversionFunctionName;
181193326Sed
182199990Srdivacky    case DeclarationNameExtra::CXXLiteralOperator:
183199990Srdivacky      return CXXLiteralOperatorName;
184199990Srdivacky
185193326Sed    case DeclarationNameExtra::CXXUsingDirective:
186193326Sed      return CXXUsingDirective;
187193326Sed
188193326Sed    default:
189193326Sed      // Check if we have one of the CXXOperator* enumeration values.
190198092Srdivacky      if (getExtra()->ExtraKindOrNumArgs <
191193326Sed            DeclarationNameExtra::CXXUsingDirective)
192193326Sed        return CXXOperatorName;
193193326Sed
194193326Sed      return ObjCMultiArgSelector;
195193326Sed    }
196193326Sed  }
197193326Sed
198193326Sed  // Can't actually get here.
199226633Sdim  llvm_unreachable("This should be unreachable!");
200193326Sed}
201193326Sed
202202379Srdivackybool DeclarationName::isDependentName() const {
203202379Srdivacky  QualType T = getCXXNameType();
204202379Srdivacky  return !T.isNull() && T->isDependentType();
205202379Srdivacky}
206202379Srdivacky
207193326Sedstd::string DeclarationName::getAsString() const {
208207619Srdivacky  std::string Result;
209207619Srdivacky  llvm::raw_string_ostream OS(Result);
210207619Srdivacky  printName(OS);
211207619Srdivacky  return OS.str();
212207619Srdivacky}
213207619Srdivacky
214226633Sdimvoid DeclarationName::printName(raw_ostream &OS) const {
215193326Sed  switch (getNameKind()) {
216193326Sed  case Identifier:
217193326Sed    if (const IdentifierInfo *II = getAsIdentifierInfo())
218207619Srdivacky      OS << II->getName();
219207619Srdivacky    return;
220193326Sed
221193326Sed  case ObjCZeroArgSelector:
222193326Sed  case ObjCOneArgSelector:
223193326Sed  case ObjCMultiArgSelector:
224207619Srdivacky    OS << getObjCSelector().getAsString();
225207619Srdivacky    return;
226193326Sed
227193326Sed  case CXXConstructorName: {
228193326Sed    QualType ClassType = getCXXNameType();
229198092Srdivacky    if (const RecordType *ClassRec = ClassType->getAs<RecordType>())
230226633Sdim      OS << *ClassRec->getDecl();
231207619Srdivacky    else
232207619Srdivacky      OS << ClassType.getAsString();
233207619Srdivacky    return;
234193326Sed  }
235193326Sed
236193326Sed  case CXXDestructorName: {
237207619Srdivacky    OS << '~';
238193326Sed    QualType Type = getCXXNameType();
239198092Srdivacky    if (const RecordType *Rec = Type->getAs<RecordType>())
240226633Sdim      OS << *Rec->getDecl();
241193326Sed    else
242207619Srdivacky      OS << Type.getAsString();
243207619Srdivacky    return;
244193326Sed  }
245193326Sed
246193326Sed  case CXXOperatorName: {
247201361Srdivacky    static const char* const OperatorNames[NUM_OVERLOADED_OPERATORS] = {
248193326Sed      0,
249193326Sed#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
250193326Sed      Spelling,
251193326Sed#include "clang/Basic/OperatorKinds.def"
252193326Sed    };
253193326Sed    const char *OpName = OperatorNames[getCXXOverloadedOperator()];
254193326Sed    assert(OpName && "not an overloaded operator");
255198092Srdivacky
256207619Srdivacky    OS << "operator";
257193326Sed    if (OpName[0] >= 'a' && OpName[0] <= 'z')
258207619Srdivacky      OS << ' ';
259207619Srdivacky    OS << OpName;
260207619Srdivacky    return;
261193326Sed  }
262193326Sed
263207619Srdivacky  case CXXLiteralOperatorName:
264207619Srdivacky    OS << "operator \"\" " << getCXXLiteralIdentifier()->getName();
265207619Srdivacky    return;
266199990Srdivacky
267193326Sed  case CXXConversionFunctionName: {
268207619Srdivacky    OS << "operator ";
269193326Sed    QualType Type = getCXXNameType();
270198092Srdivacky    if (const RecordType *Rec = Type->getAs<RecordType>())
271226633Sdim      OS << *Rec->getDecl();
272193326Sed    else
273207619Srdivacky      OS << Type.getAsString();
274207619Srdivacky    return;
275193326Sed  }
276193326Sed  case CXXUsingDirective:
277207619Srdivacky    OS << "<using-directive>";
278207619Srdivacky    return;
279193326Sed  }
280193326Sed
281226633Sdim  llvm_unreachable("Unexpected declaration name kind");
282193326Sed}
283193326Sed
284193326SedQualType DeclarationName::getCXXNameType() const {
285193326Sed  if (CXXSpecialName *CXXName = getAsCXXSpecialName())
286193326Sed    return CXXName->Type;
287193326Sed  else
288193326Sed    return QualType();
289193326Sed}
290193326Sed
291193326SedOverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const {
292193326Sed  if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) {
293198092Srdivacky    unsigned value
294193326Sed      = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction;
295193326Sed    return static_cast<OverloadedOperatorKind>(value);
296193326Sed  } else {
297193326Sed    return OO_None;
298193326Sed  }
299193326Sed}
300193326Sed
301199990SrdivackyIdentifierInfo *DeclarationName::getCXXLiteralIdentifier() const {
302199990Srdivacky  if (CXXLiteralOperatorIdName *CXXLit = getAsCXXLiteralOperatorIdName())
303199990Srdivacky    return CXXLit->ID;
304199990Srdivacky  else
305199990Srdivacky    return 0;
306199990Srdivacky}
307199990Srdivacky
308193326SedSelector DeclarationName::getObjCSelector() const {
309193326Sed  switch (getNameKind()) {
310193326Sed  case ObjCZeroArgSelector:
311193326Sed    return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 0);
312193326Sed
313193326Sed  case ObjCOneArgSelector:
314193326Sed    return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 1);
315193326Sed
316193326Sed  case ObjCMultiArgSelector:
317193326Sed    return Selector(reinterpret_cast<MultiKeywordSelector *>(Ptr & ~PtrMask));
318193326Sed
319193326Sed  default:
320193326Sed    break;
321193326Sed  }
322193326Sed
323193326Sed  return Selector();
324193326Sed}
325193326Sed
326193326Sedvoid *DeclarationName::getFETokenInfoAsVoid() const {
327193326Sed  switch (getNameKind()) {
328193326Sed  case Identifier:
329193326Sed    return getAsIdentifierInfo()->getFETokenInfo<void>();
330193326Sed
331193326Sed  case CXXConstructorName:
332193326Sed  case CXXDestructorName:
333193326Sed  case CXXConversionFunctionName:
334193326Sed    return getAsCXXSpecialName()->FETokenInfo;
335193326Sed
336193326Sed  case CXXOperatorName:
337193326Sed    return getAsCXXOperatorIdName()->FETokenInfo;
338193326Sed
339199990Srdivacky  case CXXLiteralOperatorName:
340234353Sdim    return getAsCXXLiteralOperatorIdName()->FETokenInfo;
341199990Srdivacky
342193326Sed  default:
343226633Sdim    llvm_unreachable("Declaration name has no FETokenInfo");
344193326Sed  }
345193326Sed}
346193326Sed
347193326Sedvoid DeclarationName::setFETokenInfo(void *T) {
348193326Sed  switch (getNameKind()) {
349193326Sed  case Identifier:
350193326Sed    getAsIdentifierInfo()->setFETokenInfo(T);
351193326Sed    break;
352193326Sed
353193326Sed  case CXXConstructorName:
354193326Sed  case CXXDestructorName:
355193326Sed  case CXXConversionFunctionName:
356193326Sed    getAsCXXSpecialName()->FETokenInfo = T;
357193326Sed    break;
358193326Sed
359193326Sed  case CXXOperatorName:
360193326Sed    getAsCXXOperatorIdName()->FETokenInfo = T;
361193326Sed    break;
362193326Sed
363199990Srdivacky  case CXXLiteralOperatorName:
364234353Sdim    getAsCXXLiteralOperatorIdName()->FETokenInfo = T;
365199990Srdivacky    break;
366199990Srdivacky
367193326Sed  default:
368226633Sdim    llvm_unreachable("Declaration name has no FETokenInfo");
369193326Sed  }
370193326Sed}
371193326Sed
372193326SedDeclarationName DeclarationName::getUsingDirectiveName() {
373193326Sed  // Single instance of DeclarationNameExtra for using-directive
374200583Srdivacky  static const DeclarationNameExtra UDirExtra =
375193326Sed    { DeclarationNameExtra::CXXUsingDirective };
376193326Sed
377193326Sed  uintptr_t Ptr = reinterpret_cast<uintptr_t>(&UDirExtra);
378193326Sed  Ptr |= StoredDeclarationNameExtra;
379193326Sed
380193326Sed  return DeclarationName(Ptr);
381193326Sed}
382193326Sed
383199482Srdivackyvoid DeclarationName::dump() const {
384207619Srdivacky  printName(llvm::errs());
385207619Srdivacky  llvm::errs() << '\n';
386199482Srdivacky}
387199482Srdivacky
388218893SdimDeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
389193326Sed  CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
390202379Srdivacky  CXXLiteralOperatorNames = new llvm::FoldingSet<CXXLiteralOperatorIdName>;
391193326Sed
392193326Sed  // Initialize the overloaded operator names.
393208600Srdivacky  CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
394193326Sed  for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
395198092Srdivacky    CXXOperatorNames[Op].ExtraKindOrNumArgs
396193326Sed      = Op + DeclarationNameExtra::CXXConversionFunction;
397193326Sed    CXXOperatorNames[Op].FETokenInfo = 0;
398193326Sed  }
399193326Sed}
400193326Sed
401193326SedDeclarationNameTable::~DeclarationNameTable() {
402202379Srdivacky  llvm::FoldingSet<CXXSpecialName> *SpecialNames =
403193326Sed    static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
404208600Srdivacky  llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
405208600Srdivacky    = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
406208600Srdivacky        (CXXLiteralOperatorNames);
407193326Sed
408202379Srdivacky  delete SpecialNames;
409202379Srdivacky  delete LiteralNames;
410193326Sed}
411193326Sed
412198092SrdivackyDeclarationName
413198092SrdivackyDeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
414198092Srdivacky                                        CanQualType Ty) {
415193326Sed  assert(Kind >= DeclarationName::CXXConstructorName &&
416193326Sed         Kind <= DeclarationName::CXXConversionFunctionName &&
417193326Sed         "Kind must be a C++ special name kind");
418198092Srdivacky  llvm::FoldingSet<CXXSpecialName> *SpecialNames
419193326Sed    = static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
420193326Sed
421193326Sed  DeclarationNameExtra::ExtraKind EKind;
422193326Sed  switch (Kind) {
423198092Srdivacky  case DeclarationName::CXXConstructorName:
424193326Sed    EKind = DeclarationNameExtra::CXXConstructor;
425198092Srdivacky    assert(!Ty.hasQualifiers() &&"Constructor type must be unqualified");
426193326Sed    break;
427193326Sed  case DeclarationName::CXXDestructorName:
428193326Sed    EKind = DeclarationNameExtra::CXXDestructor;
429198092Srdivacky    assert(!Ty.hasQualifiers() && "Destructor type must be unqualified");
430193326Sed    break;
431193326Sed  case DeclarationName::CXXConversionFunctionName:
432193326Sed    EKind = DeclarationNameExtra::CXXConversionFunction;
433193326Sed    break;
434193326Sed  default:
435193326Sed    return DeclarationName();
436193326Sed  }
437193326Sed
438193326Sed  // Unique selector, to guarantee there is one per name.
439193326Sed  llvm::FoldingSetNodeID ID;
440193326Sed  ID.AddInteger(EKind);
441193326Sed  ID.AddPointer(Ty.getAsOpaquePtr());
442193326Sed
443193326Sed  void *InsertPos = 0;
444193326Sed  if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
445193326Sed    return DeclarationName(Name);
446193326Sed
447208600Srdivacky  CXXSpecialName *SpecialName = new (Ctx) CXXSpecialName;
448193326Sed  SpecialName->ExtraKindOrNumArgs = EKind;
449193326Sed  SpecialName->Type = Ty;
450193326Sed  SpecialName->FETokenInfo = 0;
451193326Sed
452193326Sed  SpecialNames->InsertNode(SpecialName, InsertPos);
453193326Sed  return DeclarationName(SpecialName);
454193326Sed}
455193326Sed
456198092SrdivackyDeclarationName
457193326SedDeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) {
458193326Sed  return DeclarationName(&CXXOperatorNames[(unsigned)Op]);
459193326Sed}
460193326Sed
461199990SrdivackyDeclarationName
462199990SrdivackyDeclarationNameTable::getCXXLiteralOperatorName(IdentifierInfo *II) {
463202379Srdivacky  llvm::FoldingSet<CXXLiteralOperatorIdName> *LiteralNames
464202379Srdivacky    = static_cast<llvm::FoldingSet<CXXLiteralOperatorIdName>*>
465202379Srdivacky                                                      (CXXLiteralOperatorNames);
466202379Srdivacky
467202379Srdivacky  llvm::FoldingSetNodeID ID;
468202379Srdivacky  ID.AddPointer(II);
469202379Srdivacky
470202379Srdivacky  void *InsertPos = 0;
471202379Srdivacky  if (CXXLiteralOperatorIdName *Name =
472202379Srdivacky                               LiteralNames->FindNodeOrInsertPos(ID, InsertPos))
473202379Srdivacky    return DeclarationName (Name);
474202379Srdivacky
475208600Srdivacky  CXXLiteralOperatorIdName *LiteralName = new (Ctx) CXXLiteralOperatorIdName;
476199990Srdivacky  LiteralName->ExtraKindOrNumArgs = DeclarationNameExtra::CXXLiteralOperator;
477199990Srdivacky  LiteralName->ID = II;
478234353Sdim  LiteralName->FETokenInfo = 0;
479202379Srdivacky
480202379Srdivacky  LiteralNames->InsertNode(LiteralName, InsertPos);
481199990Srdivacky  return DeclarationName(LiteralName);
482199990Srdivacky}
483199990Srdivacky
484198092Srdivackyunsigned
485193326Sedllvm::DenseMapInfo<clang::DeclarationName>::
486193326SedgetHashValue(clang::DeclarationName N) {
487193326Sed  return DenseMapInfo<void*>::getHashValue(N.getAsOpaquePtr());
488193326Sed}
489193326Sed
490212904SdimDeclarationNameLoc::DeclarationNameLoc(DeclarationName Name) {
491212904Sdim  switch (Name.getNameKind()) {
492212904Sdim  case DeclarationName::Identifier:
493212904Sdim    break;
494212904Sdim  case DeclarationName::CXXConstructorName:
495212904Sdim  case DeclarationName::CXXDestructorName:
496212904Sdim  case DeclarationName::CXXConversionFunctionName:
497212904Sdim    NamedType.TInfo = 0;
498212904Sdim    break;
499212904Sdim  case DeclarationName::CXXOperatorName:
500212904Sdim    CXXOperatorName.BeginOpNameLoc = SourceLocation().getRawEncoding();
501212904Sdim    CXXOperatorName.EndOpNameLoc = SourceLocation().getRawEncoding();
502212904Sdim    break;
503212904Sdim  case DeclarationName::CXXLiteralOperatorName:
504212904Sdim    CXXLiteralOperatorName.OpNameLoc = SourceLocation().getRawEncoding();
505212904Sdim    break;
506212904Sdim  case DeclarationName::ObjCZeroArgSelector:
507212904Sdim  case DeclarationName::ObjCOneArgSelector:
508212904Sdim  case DeclarationName::ObjCMultiArgSelector:
509212904Sdim    // FIXME: ?
510212904Sdim    break;
511212904Sdim  case DeclarationName::CXXUsingDirective:
512212904Sdim    break;
513212904Sdim  }
514212904Sdim}
515212904Sdim
516218893Sdimbool DeclarationNameInfo::containsUnexpandedParameterPack() const {
517218893Sdim  switch (Name.getNameKind()) {
518218893Sdim  case DeclarationName::Identifier:
519218893Sdim  case DeclarationName::ObjCZeroArgSelector:
520218893Sdim  case DeclarationName::ObjCOneArgSelector:
521218893Sdim  case DeclarationName::ObjCMultiArgSelector:
522218893Sdim  case DeclarationName::CXXOperatorName:
523218893Sdim  case DeclarationName::CXXLiteralOperatorName:
524218893Sdim  case DeclarationName::CXXUsingDirective:
525218893Sdim    return false;
526218893Sdim
527218893Sdim  case DeclarationName::CXXConstructorName:
528218893Sdim  case DeclarationName::CXXDestructorName:
529218893Sdim  case DeclarationName::CXXConversionFunctionName:
530218893Sdim    if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
531218893Sdim      return TInfo->getType()->containsUnexpandedParameterPack();
532218893Sdim
533218893Sdim    return Name.getCXXNameType()->containsUnexpandedParameterPack();
534218893Sdim  }
535218893Sdim  llvm_unreachable("All name kinds handled.");
536218893Sdim}
537218893Sdim
538224145Sdimbool DeclarationNameInfo::isInstantiationDependent() const {
539224145Sdim  switch (Name.getNameKind()) {
540224145Sdim  case DeclarationName::Identifier:
541224145Sdim  case DeclarationName::ObjCZeroArgSelector:
542224145Sdim  case DeclarationName::ObjCOneArgSelector:
543224145Sdim  case DeclarationName::ObjCMultiArgSelector:
544224145Sdim  case DeclarationName::CXXOperatorName:
545224145Sdim  case DeclarationName::CXXLiteralOperatorName:
546224145Sdim  case DeclarationName::CXXUsingDirective:
547224145Sdim    return false;
548224145Sdim
549224145Sdim  case DeclarationName::CXXConstructorName:
550224145Sdim  case DeclarationName::CXXDestructorName:
551224145Sdim  case DeclarationName::CXXConversionFunctionName:
552224145Sdim    if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
553224145Sdim      return TInfo->getType()->isInstantiationDependentType();
554224145Sdim
555224145Sdim    return Name.getCXXNameType()->isInstantiationDependentType();
556224145Sdim  }
557224145Sdim  llvm_unreachable("All name kinds handled.");
558224145Sdim}
559224145Sdim
560212904Sdimstd::string DeclarationNameInfo::getAsString() const {
561212904Sdim  std::string Result;
562212904Sdim  llvm::raw_string_ostream OS(Result);
563212904Sdim  printName(OS);
564212904Sdim  return OS.str();
565212904Sdim}
566212904Sdim
567226633Sdimvoid DeclarationNameInfo::printName(raw_ostream &OS) const {
568212904Sdim  switch (Name.getNameKind()) {
569212904Sdim  case DeclarationName::Identifier:
570212904Sdim  case DeclarationName::ObjCZeroArgSelector:
571212904Sdim  case DeclarationName::ObjCOneArgSelector:
572212904Sdim  case DeclarationName::ObjCMultiArgSelector:
573212904Sdim  case DeclarationName::CXXOperatorName:
574212904Sdim  case DeclarationName::CXXLiteralOperatorName:
575212904Sdim  case DeclarationName::CXXUsingDirective:
576212904Sdim    Name.printName(OS);
577212904Sdim    return;
578212904Sdim
579212904Sdim  case DeclarationName::CXXConstructorName:
580212904Sdim  case DeclarationName::CXXDestructorName:
581212904Sdim  case DeclarationName::CXXConversionFunctionName:
582212904Sdim    if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) {
583212904Sdim      if (Name.getNameKind() == DeclarationName::CXXDestructorName)
584212904Sdim        OS << '~';
585212904Sdim      else if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName)
586212904Sdim        OS << "operator ";
587212904Sdim      OS << TInfo->getType().getAsString();
588212904Sdim    }
589212904Sdim    else
590212904Sdim      Name.printName(OS);
591212904Sdim    return;
592212904Sdim  }
593226633Sdim  llvm_unreachable("Unexpected declaration name kind");
594212904Sdim}
595212904Sdim
596212904SdimSourceLocation DeclarationNameInfo::getEndLoc() const {
597212904Sdim  switch (Name.getNameKind()) {
598212904Sdim  case DeclarationName::Identifier:
599212904Sdim    return NameLoc;
600212904Sdim
601212904Sdim  case DeclarationName::CXXOperatorName: {
602212904Sdim    unsigned raw = LocInfo.CXXOperatorName.EndOpNameLoc;
603212904Sdim    return SourceLocation::getFromRawEncoding(raw);
604212904Sdim  }
605212904Sdim
606212904Sdim  case DeclarationName::CXXLiteralOperatorName: {
607212904Sdim    unsigned raw = LocInfo.CXXLiteralOperatorName.OpNameLoc;
608212904Sdim    return SourceLocation::getFromRawEncoding(raw);
609212904Sdim  }
610212904Sdim
611212904Sdim  case DeclarationName::CXXConstructorName:
612212904Sdim  case DeclarationName::CXXDestructorName:
613212904Sdim  case DeclarationName::CXXConversionFunctionName:
614212904Sdim    if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo)
615212904Sdim      return TInfo->getTypeLoc().getEndLoc();
616212904Sdim    else
617212904Sdim      return NameLoc;
618212904Sdim
619212904Sdim    // DNInfo work in progress: FIXME.
620212904Sdim  case DeclarationName::ObjCZeroArgSelector:
621212904Sdim  case DeclarationName::ObjCOneArgSelector:
622212904Sdim  case DeclarationName::ObjCMultiArgSelector:
623212904Sdim  case DeclarationName::CXXUsingDirective:
624212904Sdim    return NameLoc;
625212904Sdim  }
626226633Sdim  llvm_unreachable("Unexpected declaration name kind");
627212904Sdim}
628