NestedNameSpecifier.cpp revision 1734317845d60307d474b5da8a8d33adbaf5e723
1e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor//===--- NestedNameSpecifier.cpp - C++ nested name specifiers -----*- C++ -*-=//
2e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor//
3e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor//                     The LLVM Compiler Infrastructure
4e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor//
5e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor// This file is distributed under the University of Illinois Open Source
6e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor// License. See LICENSE.TXT for details.
7e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor//
8e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor//===----------------------------------------------------------------------===//
9e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor//
10e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor//  This file defines the NestedNameSpecifier class, which represents
11e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor//  a C++ nested-name-specifier.
12e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor//
13e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor//===----------------------------------------------------------------------===//
14e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor#include "clang/AST/NestedNameSpecifier.h"
15e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor#include "clang/AST/ASTContext.h"
16e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor#include "clang/AST/Decl.h"
17e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor#include "clang/AST/Type.h"
18bad351822117eaf280081494e3dbe4a06c0dbfcfDouglas Gregor#include "llvm/Support/raw_ostream.h"
19ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor#include <cassert>
20bad351822117eaf280081494e3dbe4a06c0dbfcfDouglas Gregor
21e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregorusing namespace clang;
22e4e5b054b4917f0ee493bb2fda5b1ec749bfb9a1Douglas Gregor
23ab452ba8323d1985e08bade2bced588cddf2cc28Douglas GregorNestedNameSpecifier *
24ab452ba8323d1985e08bade2bced588cddf2cc28Douglas GregorNestedNameSpecifier::FindOrInsert(ASTContext &Context,
25ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor                                  const NestedNameSpecifier &Mockup) {
26ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  llvm::FoldingSetNodeID ID;
27ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  Mockup.Profile(ID);
28ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
29ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  void *InsertPos = 0;
30ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  NestedNameSpecifier *NNS
31ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    = Context.NestedNameSpecifiers.FindNodeOrInsertPos(ID, InsertPos);
32ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  if (!NNS) {
331734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    NNS = new (Context, 4) NestedNameSpecifier(Mockup);
34ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    Context.NestedNameSpecifiers.InsertNode(NNS, InsertPos);
35ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  }
36ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
37ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  return NNS;
38ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor}
39ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
40ab452ba8323d1985e08bade2bced588cddf2cc28Douglas GregorNestedNameSpecifier *
41ab452ba8323d1985e08bade2bced588cddf2cc28Douglas GregorNestedNameSpecifier::Create(ASTContext &Context, NestedNameSpecifier *Prefix,
42ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor                            IdentifierInfo *II) {
43ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  assert(II && "Identifier cannot be NULL");
44ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  assert(Prefix && Prefix->isDependent() && "Prefix must be dependent");
45ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
46ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  NestedNameSpecifier Mockup;
471734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  Mockup.Prefix.setPointer(Prefix);
481734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  Mockup.Prefix.setInt(Identifier);
491734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  Mockup.Specifier = II;
50ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  return FindOrInsert(Context, Mockup);
51ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor}
52ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
53ab452ba8323d1985e08bade2bced588cddf2cc28Douglas GregorNestedNameSpecifier *
54ab452ba8323d1985e08bade2bced588cddf2cc28Douglas GregorNestedNameSpecifier::Create(ASTContext &Context, NestedNameSpecifier *Prefix,
55ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor                            NamespaceDecl *NS) {
56ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  assert(NS && "Namespace cannot be NULL");
57ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  assert((!Prefix ||
58ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor          (Prefix->getAsType() == 0 && Prefix->getAsIdentifier() == 0)) &&
59ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor         "Broken nested name specifier");
60ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  NestedNameSpecifier Mockup;
611734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  Mockup.Prefix.setPointer(Prefix);
621734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  Mockup.Prefix.setInt(Namespace);
631734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  Mockup.Specifier = NS;
64ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  return FindOrInsert(Context, Mockup);
65ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor}
66ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
67ab452ba8323d1985e08bade2bced588cddf2cc28Douglas GregorNestedNameSpecifier *
68ab452ba8323d1985e08bade2bced588cddf2cc28Douglas GregorNestedNameSpecifier::Create(ASTContext &Context, NestedNameSpecifier *Prefix,
69ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor                            bool Template, Type *T) {
70ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  assert(T && "Type cannot be NULL");
71ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  NestedNameSpecifier Mockup;
721734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  Mockup.Prefix.setPointer(Prefix);
731734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  Mockup.Prefix.setInt(Template? TypeSpecWithTemplate : TypeSpec);
741734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  Mockup.Specifier = T;
75ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  return FindOrInsert(Context, Mockup);
76ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor}
77bad351822117eaf280081494e3dbe4a06c0dbfcfDouglas Gregor
78ab452ba8323d1985e08bade2bced588cddf2cc28Douglas GregorNestedNameSpecifier *NestedNameSpecifier::GlobalSpecifier(ASTContext &Context) {
79ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  if (!Context.GlobalNestedNameSpecifier)
801734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    Context.GlobalNestedNameSpecifier = new (Context, 4) NestedNameSpecifier();
81ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  return Context.GlobalNestedNameSpecifier;
82ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor}
83ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
84ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor/// \brief Whether this nested name specifier refers to a dependent
85ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor/// type or not.
86ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregorbool NestedNameSpecifier::isDependent() const {
87ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  switch (getKind()) {
88ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  case Identifier:
89ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    // Identifier specifiers always represent dependent types
90ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    return true;
91ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
92ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  case Namespace:
93ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  case Global:
94ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    return false;
95ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
96ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  case TypeSpec:
97ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  case TypeSpecWithTemplate:
98ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    return getAsType()->isDependentType();
99bad351822117eaf280081494e3dbe4a06c0dbfcfDouglas Gregor  }
100ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
101ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  // Necessary to suppress a GCC warning.
102ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  return false;
103ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor}
104ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
105ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor/// \brief Print this nested name specifier to the given output
106ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor/// stream.
1079bde77309fd2f9f7a53446e374472c48c81f5182Douglas Gregorvoid NestedNameSpecifier::print(llvm::raw_ostream &OS) const {
1081734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor  if (getPrefix())
1091734317845d60307d474b5da8a8d33adbaf5e723Douglas Gregor    getPrefix()->print(OS);
110ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
111ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  switch (getKind()) {
112ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  case Identifier:
113ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    OS << getAsIdentifier()->getName();
114ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    break;
115ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
116ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  case Namespace:
117ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    OS << getAsNamespace()->getIdentifier()->getName();
118ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    break;
119ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
120ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  case Global:
121ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    break;
122ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
123ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  case TypeSpecWithTemplate:
124ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    OS << "template ";
125ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    // Fall through to print the type.
126ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
127ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  case TypeSpec: {
128ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    std::string TypeStr;
129ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    Type *T = getAsType();
130ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
131ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    // If this is a qualified name type, suppress the qualification:
132ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    // it's part of our nested-name-specifier sequence anyway.  FIXME:
133ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    // We should be able to assert that this doesn't happen.
134ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    if (const QualifiedNameType *QualT = dyn_cast<QualifiedNameType>(T))
135ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor      T = QualT->getNamedType().getTypePtr();
136ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
137ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    if (const TagType *TagT = dyn_cast<TagType>(T))
138ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor      TagT->getAsStringInternal(TypeStr, true);
139ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    else
140ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor      T->getAsStringInternal(TypeStr);
141ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    OS << TypeStr;
142ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor    break;
143ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  }
144ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  }
145ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
146ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  OS << "::";
147ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor}
148ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor
149ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregorvoid NestedNameSpecifier::Destroy(ASTContext &Context) {
150ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  this->~NestedNameSpecifier();
151ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  Context.Deallocate((void *)this);
152bad351822117eaf280081494e3dbe4a06c0dbfcfDouglas Gregor}
153d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
1549bde77309fd2f9f7a53446e374472c48c81f5182Douglas Gregorvoid NestedNameSpecifier::dump() {
1559bde77309fd2f9f7a53446e374472c48c81f5182Douglas Gregor  print(llvm::errs());
156d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor}
157