aboutsummaryrefslogtreecommitdiff
path: root/include/clang
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2008-11-17 14:58:09 +0000
committerDouglas Gregor <dgregor@apple.com>2008-11-17 14:58:09 +0000
commit2e1cd4264d363ca869bf37ef160902f211d21b8c (patch)
treeb4e6314529ad811be3463a668f8b4e515f66fbcc /include/clang
parentb8abbdc90f902a2c09c566193b900c2c45a46672 (diff)
Introduction the DeclarationName class, as a single, general method of
representing the names of declarations in the C family of languages. DeclarationName is used in NamedDecl to store the name of the declaration (naturally), and ObjCMethodDecl is now a NamedDecl. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59441 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang')
-rw-r--r--include/clang/AST/ASTContext.h5
-rw-r--r--include/clang/AST/Decl.h63
-rw-r--r--include/clang/AST/DeclBase.h2
-rw-r--r--include/clang/AST/DeclCXX.h63
-rw-r--r--include/clang/AST/DeclObjC.h11
-rw-r--r--include/clang/AST/DeclarationName.h294
-rw-r--r--include/clang/Basic/IdentifierTable.h39
-rw-r--r--include/clang/Lex/Preprocessor.h4
8 files changed, 406 insertions, 75 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index b5adffdcb0..46a4e6f532 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -14,8 +14,10 @@
#ifndef LLVM_CLANG_AST_ASTCONTEXT_H
#define LLVM_CLANG_AST_ASTCONTEXT_H
+#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LangOptions.h"
#include "clang/AST/Builtins.h"
+#include "clang/AST/DeclarationName.h"
#include "clang/AST/DeclBase.h"
#include "clang/AST/Type.h"
#include "clang/Basic/SourceLocation.h"
@@ -110,7 +112,8 @@ public:
TargetInfo &Target;
IdentifierTable &Idents;
SelectorTable &Selectors;
-
+ DeclarationNameTable DeclarationNames;
+
SourceManager& getSourceManager() { return SourceMgr; }
llvm::MallocAllocator &getAllocator() { return Allocator; }
const LangOptions& getLangOptions() const { return LangOpts; }
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 3a766bfd5e..2ac94a9bdf 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -14,7 +14,9 @@
#ifndef LLVM_CLANG_AST_DECL_H
#define LLVM_CLANG_AST_DECL_H
+#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/OperatorKinds.h"
+#include "clang/AST/DeclarationName.h"
#include "clang/AST/DeclBase.h"
#include "clang/Parse/AccessSpecifier.h"
#include "llvm/ADT/SmallVector.h"
@@ -24,7 +26,6 @@ class Expr;
class Stmt;
class CompoundStmt;
class StringLiteral;
-class IdentifierInfo;
/// TranslationUnitDecl - The top declaration context.
/// FIXME: The TranslationUnit class should probably be modified to serve as
@@ -56,19 +57,51 @@ protected:
friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C);
};
-/// NamedDecl - This represents a decl with an identifier for a name. Many
+/// NamedDecl - This represents a decl with a name. Many
/// decls have names, but not ObjCMethodDecl, @class, etc.
class NamedDecl : public Decl {
- /// Identifier - The identifier for this declaration (e.g. the name for the
- /// variable, the tag for a struct).
- IdentifierInfo *Identifier;
+ /// Name - The name of this declaration, which is typically a normal
+ /// identifier but may also be a special kind of name (C++
+ /// constructor, Objective-C selector, etc.)
+ DeclarationName Name;
+
+protected:
+ NamedDecl(Kind DK, SourceLocation L, DeclarationName N)
+ : Decl(DK, L), Name(N) {}
+
public:
NamedDecl(Kind DK, SourceLocation L, IdentifierInfo *Id)
- : Decl(DK, L), Identifier(Id) {}
+ : Decl(DK, L), Name(Id) {}
+
+ /// getIdentifier - Get the identifier that names this declaration,
+ /// if there is one. This will return NULL if this declaration has
+ /// no name (e.g., for an unnamed class) or if the name is a special
+ /// name (C++ constructor, Objective-C selector, etc.).
+ IdentifierInfo *getIdentifier() const { return Name.getAsIdentifierInfo(); }
+
+ /// getIdentifierName - Get the name of identifier for this
+ /// declaration as a string. If the declaration has no name, or if
+ /// the name is a special name (C++ constructor, Objective-C
+ /// selector, etc.), returns NULL.
+ const char *getIdentifierName() const {
+ if (IdentifierInfo *II = getIdentifier())
+ return II->getName();
+ else
+ return 0;
+ }
+
+ /// getDeclName - Get the actual, stored name of the declaration,
+ /// which may be a special name.
+ DeclarationName getDeclName() const { return Name; }
+
+ /// getName - Get a human-readable name for the declaration, even if
+ /// it is one of the special kinds of names (C++ constructor,
+ /// Objective-C selector, etc.). Creating this name requires some
+ /// expensive string manipulation, so it should be called only when
+ /// absolutely critical. For simple declarations, @c
+ /// getIdentifierName() should suffice.
+ std::string getName() const;
- IdentifierInfo *getIdentifier() const { return Identifier; }
- virtual const char *getName() const;
-
static bool classof(const Decl *D) {
return D->getKind() >= NamedFirst && D->getKind() <= NamedLast;
}
@@ -120,8 +153,8 @@ class ScopedDecl : public NamedDecl {
protected:
ScopedDecl(Kind DK, DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, ScopedDecl *PrevDecl)
- : NamedDecl(DK, L, Id), NextDeclarator(PrevDecl), Next(0),
+ DeclarationName N, ScopedDecl *PrevDecl)
+ : NamedDecl(DK, L, N), NextDeclarator(PrevDecl), Next(0),
DeclCtx(reinterpret_cast<uintptr_t>(DC)) {}
virtual ~ScopedDecl();
@@ -272,8 +305,8 @@ class ValueDecl : public ScopedDecl {
protected:
ValueDecl(Kind DK, DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, QualType T, ScopedDecl *PrevDecl)
- : ScopedDecl(DK, DC, L, Id, PrevDecl), DeclType(T) {}
+ DeclarationName N, QualType T, ScopedDecl *PrevDecl)
+ : ScopedDecl(DK, DC, L, N, PrevDecl), DeclType(T) {}
public:
QualType getType() const { return DeclType; }
void setType(QualType newType) { DeclType = newType; }
@@ -512,10 +545,10 @@ private:
SourceLocation TypeSpecStartLoc;
protected:
FunctionDecl(Kind DK, DeclContext *DC, SourceLocation L,
- IdentifierInfo *Id, QualType T,
+ DeclarationName N, QualType T,
StorageClass S, bool isInline, ScopedDecl *PrevDecl,
SourceLocation TSSL = SourceLocation())
- : ValueDecl(DK, DC, L, Id, T, PrevDecl),
+ : ValueDecl(DK, DC, L, N, T, PrevDecl),
DeclContext(DK),
ParamInfo(0), Body(0), PreviousDeclaration(0),
SClass(S), IsInline(isInline), IsImplicit(0), TypeSpecStartLoc(TSSL) {}
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index f0ac1a5335..753d572fb3 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -52,6 +52,7 @@ public:
ObjCCategory,
ObjCCategoryImpl,
ObjCImplementation,
+ ObjCMethod, // [DeclContext]
ObjCProtocol,
ObjCProperty,
// ScopedDecl
@@ -75,7 +76,6 @@ public:
ParmVar,
ObjCInterface, // [DeclContext]
ObjCCompatibleAlias,
- ObjCMethod, // [DeclContext]
ObjCClass,
ObjCForwardProtocol,
ObjCPropertyImpl,
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 39c22aaf70..8edfc650a4 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -34,8 +34,8 @@ class CXXConversionDecl;
/// overloaded functions for name lookup.
class OverloadedFunctionDecl : public NamedDecl {
protected:
- OverloadedFunctionDecl(DeclContext *DC, IdentifierInfo *Id)
- : NamedDecl(OverloadedFunction, SourceLocation(), Id) { }
+ OverloadedFunctionDecl(DeclContext *DC, DeclarationName N)
+ : NamedDecl(OverloadedFunction, SourceLocation(), N) { }
/// Functions - the set of overloaded functions contained in this
/// overload set.
@@ -47,16 +47,16 @@ public:
function_const_iterator;
static OverloadedFunctionDecl *Create(ASTContext &C, DeclContext *DC,
- IdentifierInfo *Id);
+ DeclarationName N);
/// addOverload - Add an overloaded function FD to this set of
/// overloaded functions.
void addOverload(FunctionDecl *FD) {
assert((!getNumFunctions() || (FD->getDeclContext() == getDeclContext())) &&
"Overloaded functions must all be in the same context");
- assert((FD->getIdentifier() == getIdentifier() ||
- isa<CXXConversionDecl>(FD)) &&
- "Overloaded functions must have the same name or be conversions.");
+ assert((FD->getDeclName() == getDeclName() ||
+ isa<CXXConversionDecl>(FD) || isa<CXXConstructorDecl>(FD)) &&
+ "Overloaded functions must have the same name");
Functions.push_back(FD);
}
@@ -246,7 +246,7 @@ class CXXRecordDecl : public RecordDecl, public DeclContext {
/// CXXConversionDecl.
OverloadedFunctionDecl Conversions;
- CXXRecordDecl(ASTContext &C, TagKind TK, DeclContext *DC,
+ CXXRecordDecl(TagKind TK, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id);
~CXXRecordDecl();
@@ -389,9 +389,9 @@ protected:
class CXXMethodDecl : public FunctionDecl {
protected:
CXXMethodDecl(Kind DK, CXXRecordDecl *RD, SourceLocation L,
- IdentifierInfo *Id, QualType T,
+ DeclarationName N, QualType T,
bool isStatic, bool isInline, ScopedDecl *PrevDecl)
- : FunctionDecl(DK, RD, L, Id, T, (isStatic ? Static : None),
+ : FunctionDecl(DK, RD, L, N, T, (isStatic ? Static : None),
isInline, PrevDecl) {}
public:
@@ -576,21 +576,19 @@ class CXXConstructorDecl : public CXXMethodDecl {
/// FIXME: Add support for base and member initializers.
CXXConstructorDecl(CXXRecordDecl *RD, SourceLocation L,
- IdentifierInfo *Id, QualType T,
+ DeclarationName N, QualType T,
bool isExplicit, bool isInline, bool isImplicitlyDeclared)
- : CXXMethodDecl(CXXConstructor, RD, L, Id, T, false, isInline, /*PrevDecl=*/0),
+ : CXXMethodDecl(CXXConstructor, RD, L, N, T, false, isInline,
+ /*PrevDecl=*/0),
Explicit(isExplicit), ImplicitlyDeclared(isImplicitlyDeclared),
ImplicitlyDefined(false) { }
public:
static CXXConstructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
- SourceLocation L, IdentifierInfo *Id,
+ SourceLocation L, DeclarationName N,
QualType T, bool isExplicit,
bool isInline, bool isImplicitlyDeclared);
- /// getName - Returns a human-readable name for this constructor.
- virtual const char *getName() const;
-
/// isExplicit - Whether this constructor was marked "explicit" or not.
bool isExplicit() const { return Explicit; }
@@ -686,29 +684,20 @@ class CXXDestructorDecl : public CXXMethodDecl {
/// @c !ImplicitlyDeclared && ImplicitlyDefined.
bool ImplicitlyDefined : 1;
- /// Name - The formatted name of this destructor. This will be
- /// generated when getName() is called.
- mutable char *Name;
-
CXXDestructorDecl(CXXRecordDecl *RD, SourceLocation L,
- IdentifierInfo *Id, QualType T,
+ DeclarationName N, QualType T,
bool isInline, bool isImplicitlyDeclared)
- : CXXMethodDecl(CXXDestructor, RD, L, Id, T, false, isInline,
+ : CXXMethodDecl(CXXDestructor, RD, L, N, T, false, isInline,
/*PrevDecl=*/0),
ImplicitlyDeclared(isImplicitlyDeclared),
- ImplicitlyDefined(false), Name(0) { }
+ ImplicitlyDefined(false) { }
public:
static CXXDestructorDecl *Create(ASTContext &C, CXXRecordDecl *RD,
- SourceLocation L, IdentifierInfo *Id,
+ SourceLocation L, DeclarationName N,
QualType T, bool isInline,
bool isImplicitlyDeclared);
- virtual ~CXXDestructorDecl();
-
- /// getName - Returns a human-readable name for this destructor.
- virtual const char *getName() const;
-
/// isImplicitlyDeclared - Whether this destructor was implicitly
/// declared. If false, then this destructor was explicitly
/// declared by the user.
@@ -762,29 +751,19 @@ class CXXConversionDecl : public CXXMethodDecl {
/// explicitly wrote a cast. This is a C++0x feature.
bool Explicit : 1;
- /// Name - The formatted name of this conversion function. This will
- /// be generated when getName() is called.
- mutable char *Name;
-
CXXConversionDecl(CXXRecordDecl *RD, SourceLocation L,
- IdentifierInfo *Id, QualType T,
+ DeclarationName N, QualType T,
bool isInline, bool isExplicit)
- : CXXMethodDecl(CXXConversion, RD, L, Id, T, false, isInline,
+ : CXXMethodDecl(CXXConversion, RD, L, N, T, false, isInline,
/*PrevDecl=*/0),
- Explicit(isExplicit), Name(0) { }
+ Explicit(isExplicit) { }
public:
static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD,
- SourceLocation L, IdentifierInfo *Id,
+ SourceLocation L, DeclarationName N,
QualType T, bool isInline,
bool isExplicit);
- virtual ~CXXConversionDecl();
-
- /// getName - Returns a human-readable name for this conversion
- /// function.
- virtual const char *getName() const;
-
/// isExplicit - Whether this is an explicit conversion operator
/// (C++0x only). Explicit conversion operators are only considered
/// when the user has explicitly written a cast.
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index e8c383d73e..ffbb1e56fb 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -91,7 +91,7 @@ public:
/// A selector represents a unique name for a method. The selector names for
/// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu.
///
-class ObjCMethodDecl : public Decl, public DeclContext {
+class ObjCMethodDecl : public NamedDecl, public DeclContext {
public:
enum ImplementationControl { None, Required, Optional };
private:
@@ -115,9 +115,6 @@ private:
// Context this method is declared in.
NamedDecl *MethodContext;
- // A unigue name for this method.
- Selector SelName;
-
// Type of this method.
QualType MethodDeclType;
/// ParamInfo - new[]'d array of pointers to VarDecls for the formal
@@ -146,13 +143,13 @@ private:
bool isVariadic = false,
bool isSynthesized = false,
ImplementationControl impControl = None)
- : Decl(ObjCMethod, beginLoc),
+ : NamedDecl(ObjCMethod, beginLoc, SelInfo),
DeclContext(ObjCMethod),
IsInstance(isInstance), IsVariadic(isVariadic),
IsSynthesized(isSynthesized),
DeclImplementation(impControl), objcDeclQualifier(OBJC_TQ_None),
MethodContext(static_cast<NamedDecl*>(contextDecl)),
- SelName(SelInfo), MethodDeclType(T),
+ MethodDeclType(T),
ParamInfo(0), NumMethodParams(0),
EndLoc(endLoc), Body(0), SelfDecl(0), CmdDecl(0) {}
@@ -191,7 +188,7 @@ public:
return const_cast<ObjCMethodDecl*>(this)->getClassInterface();
}
- Selector getSelector() const { return SelName; }
+ Selector getSelector() const { return getDeclName().getObjCSelector(); }
unsigned getSynthesizedMethodSize() const;
QualType getResultType() const { return MethodDeclType; }
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
new file mode 100644
index 0000000000..385e2f34a3
--- /dev/null
+++ b/include/clang/AST/DeclarationName.h
@@ -0,0 +1,294 @@
+//===-- DeclarationName.h - Representation of declaration names -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the DeclarationName and DeclarationNameTable classes.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_CLANG_AST_DECLARATIONNAME_H
+#define LLVM_CLANG_AST_DECLARATIONNAME_H
+
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/AST/Type.h"
+#include "llvm/Bitcode/SerializationFwd.h"
+
+namespace llvm {
+ template <typename T> struct DenseMapInfo;
+}
+
+namespace clang {
+ class CXXSpecialName; // a private class used by DeclarationName
+ class DeclarationNameExtra; // a private class used by DeclarationName
+ class IdentifierInfo;
+ class MultiKeywordSelector; // a private class used by Selector and DeclarationName
+
+/// DeclarationName - The name of a declaration. In the common case,
+/// this just stores an IdentifierInfo pointer to a normal
+/// name. However, it also provides encodings for Objective-C
+/// selectors (optimizing zero- and one-argument selectors, which make
+/// up 78% percent of all selectors in Cocoa.h) and special C++ names
+/// for constructors, destructors, and conversion functions.
+class DeclarationName {
+public:
+ /// NameKind - The kind of name this object contains.
+ enum NameKind {
+ Identifier,
+ ObjCZeroArgSelector,
+ ObjCOneArgSelector,
+ ObjCMultiArgSelector,
+ CXXConstructorName,
+ CXXDestructorName,
+ CXXConversionFunctionName
+ };
+
+private:
+ /// StoredNameKind - The kind of name that is actually stored in the
+ /// upper bits of the Ptr field. This is only used internally.
+ enum StoredNameKind {
+ StoredIdentifier = 0,
+ StoredObjCZeroArgSelector,
+ StoredObjCOneArgSelector,
+ StoredObjCMultiArgSelectorOrCXXName,
+ PtrMask = 0x03
+ };
+
+ /// Ptr - The lowest two bits are used to express what kind of name
+ /// we're actually storing, using the values of NameKind. Depending
+ /// on the kind of name this is, the upper bits of Ptr may have one
+ /// of several different meanings:
+ ///
+ /// Identifier - The name is a normal identifier, and Ptr is a
+ /// normal IdentifierInfo pointer.
+ ///
+ /// ObjCZeroArgSelector - The name is an Objective-C selector with
+ /// zero arguments, and Ptr is an IdentifierInfo pointer pointing
+ /// to the selector name.
+ ///
+ /// ObjCOneArgSelector - The name is an Objective-C selector with
+ /// one argument, and Ptr is an IdentifierInfo pointer pointing to
+ /// the selector name.
+ ///
+ /// ObjCMultiArgSelectorOrCXXName - This is either an Objective-C
+ /// selector with two or more arguments or it is a C++ name. Ptr
+ /// is actually a DeclarationNameExtra structure, whose first
+ /// value will tell us whether this is an Objective-C selector or
+ /// special C++ name.
+ uintptr_t Ptr;
+
+ /// getStoredNameKind - Return the kind of object that is stored in
+ /// Ptr.
+ StoredNameKind getStoredNameKind() const {
+ return static_cast<StoredNameKind>(Ptr & PtrMask);
+ }
+
+ /// getExtra - Get the "extra" information associated with this
+ /// multi-argument selector or C++ special name.
+ DeclarationNameExtra *getExtra() const {
+ assert(getStoredNameKind() == StoredObjCMultiArgSelectorOrCXXName &&
+ "Declaration name does not store an Extra structure");
+ return reinterpret_cast<DeclarationNameExtra *>(Ptr & ~PtrMask);
+ }
+
+ /// getAsCXXSpecialName - If the stored pointer is actually a
+ /// CXXSpecialName, returns a pointer to it. Otherwise, returns
+ /// a NULL pointer.
+ CXXSpecialName *getAsCXXSpecialName() const {
+ if (getNameKind() >= CXXConstructorName &&
+ getNameKind() <= CXXConversionFunctionName)
+ return reinterpret_cast<CXXSpecialName *>(Ptr & ~PtrMask);
+ else
+ return 0;
+ }
+
+ // Construct a declaration name from the name of a C++ constructor,
+ // destructor, or conversion function.
+ DeclarationName(CXXSpecialName *Name)
+ : Ptr(reinterpret_cast<uintptr_t>(Name)) {
+ assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXSpecialName");
+ Ptr |= StoredObjCMultiArgSelectorOrCXXName;
+ }
+
+ // Construct a declaration name from a zero- or one-argument
+ // Objective-C selector.
+ DeclarationName(IdentifierInfo *II, unsigned numArgs)
+ : Ptr(reinterpret_cast<uintptr_t>(II)) {
+ assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
+ assert(numArgs < 2 && "Use MultiKeywordSelector for >= 2 arguments");
+ if (numArgs == 0)
+ Ptr |= StoredObjCZeroArgSelector;
+ else
+ Ptr |= StoredObjCOneArgSelector;
+ }
+
+ // Construct a declaration name from an Objective-C multiple-keyword
+ // selector.
+ DeclarationName(MultiKeywordSelector *SI)
+ : Ptr(reinterpret_cast<uintptr_t>(SI)) {
+ assert((Ptr & PtrMask) == 0 && "Improperly aligned MultiKeywordSelector");
+ Ptr |= StoredObjCMultiArgSelectorOrCXXName;
+ }
+
+ /// Construct a declaration name from a raw pointer.
+ DeclarationName(uintptr_t Ptr) : Ptr(Ptr) { }
+
+ friend class DeclarationNameTable;
+
+public:
+ /// DeclarationName - Used to create an empty selector.
+ DeclarationName() : Ptr(0) { }
+
+ // Construct a declaration name from an IdentifierInfo *.
+ DeclarationName(IdentifierInfo *II) : Ptr(reinterpret_cast<uintptr_t>(II)) {
+ assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
+ }
+
+ // Construct a declaration name from an Objective-C selector.
+ DeclarationName(Selector Sel);
+
+ /// getNameKind - Determine what kind of name this is.
+ NameKind getNameKind() const;
+
+ /// getAsIdentifierInfo - Retrieve the IdentifierInfo * stored in
+ /// this declaration name, or NULL if this declaration name isn't a
+ /// simple identifier.
+ IdentifierInfo *getAsIdentifierInfo() const {
+ if (getNameKind() == Identifier)
+ return reinterpret_cast<IdentifierInfo *>(Ptr);
+ else
+ return 0;
+ }
+
+ /// getAsOpaqueInteger - Get the representation of this declaration
+ /// name as an opaque integer.
+ uintptr_t getAsOpaqueInteger() const { return Ptr; }
+
+ /// getCXXNameType - If this name is one of the C++ names (of a
+ /// constructor, destructor, or conversion function), return the
+ /// type associated with that name.
+ QualType getCXXNameType() const;
+
+ /// getObjCSelector - Get the Objective-C selector stored in this
+ /// declaration name.
+ Selector getObjCSelector() const;
+
+ /// operator== - Determine whether the specified names are identical..
+ friend bool operator==(DeclarationName LHS, DeclarationName RHS) {
+ return LHS.Ptr == RHS.Ptr;
+ }
+
+ /// operator!= - Determine whether the specified names are different.
+ friend bool operator!=(DeclarationName LHS, DeclarationName RHS) {
+ return LHS.Ptr != RHS.Ptr;
+ }
+
+ static DeclarationName getEmptyMarker() {
+ return DeclarationName(uintptr_t(-1));
+ }
+
+ static DeclarationName getTombstoneMarker() {
+ return DeclarationName(uintptr_t(-2));
+ }
+};
+
+/// Ordering on two declaration names. If both names are identifiers,
+/// this provides a lexicographical ordering.
+bool operator<(DeclarationName LHS, DeclarationName RHS);
+
+/// Ordering on two declaration names. If both names are identifiers,
+/// this provides a lexicographical ordering.
+inline bool operator>(DeclarationName LHS, DeclarationName RHS) {
+ return RHS < LHS;
+}
+
+/// Ordering on two declaration names. If both names are identifiers,
+/// this provides a lexicographical ordering.
+inline bool operator<=(DeclarationName LHS, DeclarationName RHS) {
+ return !(RHS < LHS);
+}
+
+/// Ordering on two declaration names. If both names are identifiers,
+/// this provides a lexicographical ordering.
+inline bool operator>=(DeclarationName LHS, DeclarationName RHS) {
+ return !(LHS < RHS);
+}
+
+/// DeclarationNameTable - Used to store and retrieve DeclarationName
+/// instances for the various kinds of declaration names, e.g., normal
+/// identifiers, C++ constructor names, etc. This class contains
+/// uniqued versions of each of the C++ special names, which can be
+/// retrieved using its member functions (e.g.,
+/// getCXXConstructorName).
+class DeclarationNameTable {
+ void *CXXSpecialNamesImpl; // Actually a FoldingSet<CXXSpecialName> *
+
+ DeclarationNameTable(const DeclarationNameTable&); // NONCOPYABLE
+ DeclarationNameTable& operator=(const DeclarationNameTable&); // NONCOPYABLE
+
+public:
+ DeclarationNameTable();
+ ~DeclarationNameTable();
+
+ /// getIdentifier - Create a declaration name that is a simple
+ /// identifier.
+ DeclarationName getIdentifier(IdentifierInfo *ID) {
+ return DeclarationName(ID);
+ }
+
+ /// getCXXConstructorName - Returns the name of a C++ constructor
+ /// for the given Type.
+ DeclarationName getCXXConstructorName(QualType Ty) {
+ return getCXXSpecialName(DeclarationName::CXXConstructorName, Ty);
+ }
+
+ /// getCXXDestructorName - Returns the name of a C++ destructor
+ /// for the given Type.
+ DeclarationName getCXXDestructorName(QualType Ty) {
+ return getCXXSpecialName(DeclarationName::CXXDestructorName, Ty);
+ }
+
+ /// getCXXConversionFunctionName - Returns the name of a C++
+ /// conversion function for the given Type.
+ DeclarationName getCXXConversionFunctionName(QualType Ty) {
+ return getCXXSpecialName(DeclarationName::CXXConversionFunctionName, Ty);
+ }
+
+ /// getCXXSpecialName - Returns a declaration name for special kind
+ /// of C++ name, e.g., for a constructor, destructor, or conversion
+ /// function.
+ DeclarationName getCXXSpecialName(DeclarationName::NameKind Kind,
+ QualType Ty);
+};
+
+} // end namespace clang
+
+namespace llvm {
+/// Define DenseMapInfo so that DeclarationNames can be used as keys
+/// in DenseMap and DenseSets.
+template<>
+struct DenseMapInfo<clang::DeclarationName> {
+ static inline clang::DeclarationName getEmptyKey() {
+ return clang::DeclarationName::getEmptyMarker();
+ }
+
+ static inline clang::DeclarationName getTombstoneKey() {
+ return clang::DeclarationName::getTombstoneMarker();
+ }
+
+ static unsigned getHashValue(clang::DeclarationName);
+
+ static inline bool
+ isEqual(clang::DeclarationName LHS, clang::DeclarationName RHS) {
+ return LHS == RHS;
+ }
+
+ static inline bool isPod() { return true; }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h
index f6b95ba380..a13d4ba538 100644
--- a/include/clang/Basic/IdentifierTable.h
+++ b/include/clang/Basic/IdentifierTable.h
@@ -29,10 +29,11 @@ namespace llvm {
namespace clang {
struct LangOptions;
- class MultiKeywordSelector; // a private class used by Selector.
class IdentifierInfo;
class SourceLocation;
-
+ class MultiKeywordSelector; // private class used by Selector
+ class DeclarationName; // AST class that stores declaration names
+
/// IdentifierLocPair - A simple pair of identifier info and location.
typedef std::pair<IdentifierInfo*, SourceLocation> IdentifierLocPair;
@@ -281,8 +282,9 @@ class Selector {
}
Selector(uintptr_t V) : InfoPtr(V) {}
public:
- friend class SelectorTable; // only the SelectorTable can create these.
-
+ friend class SelectorTable; // only the SelectorTable can create these
+ friend class DeclarationName; // and the AST's DeclarationName.
+
/// The default ctor should only be used when creating data structures that
/// will contain selectors.
Selector() : InfoPtr(0) {}
@@ -362,12 +364,35 @@ public:
static SelectorTable* CreateAndRegister(llvm::Deserializer& D);
};
-} // end namespace clang
+/// DeclarationNameExtra - Common base of the MultiKeywordSelector and
+/// CXXSpecialName classes, both of which are private classes that can
+/// be stored by the AST's DeclarationName class.
+class DeclarationNameExtra {
+public:
+ /// ExtraKind - The kind of "extra" information stored in the
+ /// DeclarationName. See @c ExtraKindOrNumArgs for an explanation of
+ /// how these enumerator values are used.
+ enum ExtraKind {
+ CXXConstructor = 0,
+ CXXDestructor,
+ CXXConversionFunction,
+ NUM_EXTRA_KINDS
+ };
+ /// ExtraKindOrNumArgs - Either the kind of C++ special name (if the
+ /// value is one of the CXX* enumerators of ExtraKind), in which
+ /// case the DeclarationNameExtra is also a CXXSpecialName, or
+ /// NUM_EXTRA_KINDS+NumArgs, where NumArgs is the number of
+ /// arguments in the Objective-C selector, in which case the
+ /// DeclarationNameExtra is also a MultiKeywordSelector.
+ unsigned ExtraKindOrNumArgs;
+};
+
+} // end namespace clang
+namespace llvm {
/// Define DenseMapInfo so that Selectors can be used as keys in DenseMap and
/// DenseSets.
-namespace llvm {
template <>
struct DenseMapInfo<clang::Selector> {
static inline clang::Selector getEmptyKey() {
@@ -385,6 +410,6 @@ struct DenseMapInfo<clang::Selector> {
static bool isPod() { return true; }
};
-} // end namespace llvm
+} // end namespace llvm
#endif
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 47ada4fe1a..e8bd3ac6d6 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -87,7 +87,7 @@ class Preprocessor {
/// FIXME: Make sure the lifetime of Identifiers/Selectors *isn't* tied to
/// the lifetime fo the preprocessor.
SelectorTable Selectors;
-
+
/// PragmaHandlers - This tracks all of the pragmas that the client registered
/// with this preprocessor.
PragmaNamespace *PragmaHandlers;
@@ -175,7 +175,7 @@ public:
IdentifierTable &getIdentifierTable() { return Identifiers; }
SelectorTable &getSelectorTable() { return Selectors; }
-
+
inline FullSourceLoc getFullLoc(SourceLocation Loc) const {
return FullSourceLoc(Loc, getSourceManager());
}