diff options
author | Douglas Gregor <dgregor@apple.com> | 2008-11-17 14:58:09 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2008-11-17 14:58:09 +0000 |
commit | 2e1cd4264d363ca869bf37ef160902f211d21b8c (patch) | |
tree | b4e6314529ad811be3463a668f8b4e515f66fbcc /include/clang | |
parent | b8abbdc90f902a2c09c566193b900c2c45a46672 (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.h | 5 | ||||
-rw-r--r-- | include/clang/AST/Decl.h | 63 | ||||
-rw-r--r-- | include/clang/AST/DeclBase.h | 2 | ||||
-rw-r--r-- | include/clang/AST/DeclCXX.h | 63 | ||||
-rw-r--r-- | include/clang/AST/DeclObjC.h | 11 | ||||
-rw-r--r-- | include/clang/AST/DeclarationName.h | 294 | ||||
-rw-r--r-- | include/clang/Basic/IdentifierTable.h | 39 | ||||
-rw-r--r-- | include/clang/Lex/Preprocessor.h | 4 |
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()); } |