aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Driver/RewriteBlocks.cpp11
-rw-r--r--Driver/RewriteObjC.cpp40
-rw-r--r--docs/InternalsManual.html104
-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
-rw-r--r--lib/AST/ASTContext.cpp9
-rw-r--r--lib/AST/CMakeLists.txt1
-rw-r--r--lib/AST/Decl.cpp44
-rw-r--r--lib/AST/DeclCXX.cpp62
-rw-r--r--lib/AST/DeclObjC.cpp4
-rw-r--r--lib/AST/DeclSerialization.cpp54
-rw-r--r--lib/AST/DeclarationName.cpp166
-rw-r--r--lib/AST/StmtDumper.cpp16
-rw-r--r--lib/Basic/IdentifierTable.cpp22
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp11
-rw-r--r--lib/CodeGen/CGDecl.cpp4
-rw-r--r--lib/CodeGen/CGObjCGNU.cpp10
-rw-r--r--lib/CodeGen/CGObjCMac.cpp6
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp2
-rw-r--r--lib/Sema/SemaDecl.cpp20
-rw-r--r--lib/Sema/SemaDeclCXX.cpp18
-rw-r--r--lib/Sema/SemaDeclObjC.cpp5
-rw-r--r--lib/Sema/SemaOverload.cpp2
29 files changed, 890 insertions, 202 deletions
diff --git a/Driver/RewriteBlocks.cpp b/Driver/RewriteBlocks.cpp
index d8e347fafb..535915344c 100644
--- a/Driver/RewriteBlocks.cpp
+++ b/Driver/RewriteBlocks.cpp
@@ -618,7 +618,7 @@ void RewriteBlocks::SynthesizeBlockLiterals(SourceLocation FunLocStart,
void RewriteBlocks::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) {
SourceLocation FunLocStart = FD->getTypeSpecStartLoc();
- const char *FuncName = FD->getName();
+ const char *FuncName = FD->getIdentifierName();
SynthesizeBlockLiterals(FunLocStart, FuncName);
}
@@ -675,13 +675,13 @@ std::string RewriteBlocks::SynthesizeBlockCall(CallExpr *Exp) {
const BlockPointerType *CPT = 0;
if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Exp->getCallee())) {
- closureName = DRE->getDecl()->getName();
+ closureName = DRE->getDecl()->getIdentifierName();
CPT = DRE->getType()->getAsBlockPointerType();
} else if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(Exp->getCallee())) {
- closureName = CDRE->getDecl()->getName();
+ closureName = CDRE->getDecl()->getIdentifierName();
CPT = CDRE->getType()->getAsBlockPointerType();
} else if (MemberExpr *MExpr = dyn_cast<MemberExpr>(Exp->getCallee())) {
- closureName = MExpr->getMemberDecl()->getName();
+ closureName = MExpr->getMemberDecl()->getIdentifierName();
CPT = MExpr->getType()->getAsBlockPointerType();
} else {
assert(1 && "RewriteBlockClass: Bad type");
@@ -1109,7 +1109,8 @@ void RewriteBlocks::HandleDeclInMainFile(Decl *D) {
std::string Init = SynthesizeBlockInitExpr(CBE, VD);
// Do the rewrite, using S.size() which contains the rewritten size.
ReplaceText(CBE->getLocStart(), S.size(), Init.c_str(), Init.size());
- SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(), VD->getName());
+ SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(),
+ VD->getIdentifierName());
} else if (CastExpr *CE = dyn_cast<CastExpr>(VD->getInit())) {
RewriteCastExpr(CE);
}
diff --git a/Driver/RewriteObjC.cpp b/Driver/RewriteObjC.cpp
index 2903f998a0..69aedcc2dd 100644
--- a/Driver/RewriteObjC.cpp
+++ b/Driver/RewriteObjC.cpp
@@ -506,7 +506,7 @@ void RewriteObjC::HandleTopLevelDecl(Decl *D) {
RewriteFunctionDecl(FD);
} else if (VarDecl *FVD = dyn_cast<VarDecl>(D)) {
// declared in <Foundation/NSString.h>
- if (strcmp(FVD->getName(), "_NSConstantStringClassReference") == 0) {
+ if (strcmp(FVD->getIdentifierName(), "_NSConstantStringClassReference") == 0) {
ConstantStringClassReference = FVD;
return;
}
@@ -1088,13 +1088,13 @@ Stmt *RewriteObjC::RewriteObjCForCollectionStmt(ObjCForCollectionStmt *S,
elementTypeAsString = ElementType.getAsString();
buf += elementTypeAsString;
buf += " ";
- elementName = D->getName();
+ elementName = D->getIdentifierName();
buf += elementName;
buf += ";\n\t";
}
else {
DeclRefExpr *DR = cast<DeclRefExpr>(S->getElement());
- elementName = DR->getDecl()->getName();
+ elementName = DR->getDecl()->getIdentifierName();
elementTypeAsString
= cast<ValueDecl>(DR->getDecl())->getType().getAsString();
}
@@ -1694,7 +1694,7 @@ void RewriteObjC::SynthGetProtocolFunctionDecl() {
void RewriteObjC::RewriteFunctionDecl(FunctionDecl *FD) {
// declared in <objc/objc.h>
- if (strcmp(FD->getName(), "sel_registerName") == 0) {
+ if (strcmp(FD->getIdentifierName(), "sel_registerName") == 0) {
SelGetUidFunctionDecl = FD;
return;
}
@@ -2299,8 +2299,8 @@ Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) {
// Create a call to objc_getProtocol("ProtocolName").
llvm::SmallVector<Expr*, 8> ProtoExprs;
QualType argType = Context->getPointerType(Context->CharTy);
- ProtoExprs.push_back(new StringLiteral(Exp->getProtocol()->getName(),
- strlen(Exp->getProtocol()->getName()),
+ ProtoExprs.push_back(new StringLiteral(Exp->getProtocol()->getIdentifierName(),
+ strlen(Exp->getProtocol()->getIdentifierName()),
false, argType, SourceLocation(),
SourceLocation()));
CallExpr *ProtoExp = SynthesizeCallToFunctionDecl(GetProtocolFunctionDecl,
@@ -2343,7 +2343,8 @@ bool RewriteObjC::BufferContainsPPDirectives(const char *startBuf,
void RewriteObjC::SynthesizeObjCInternalStruct(ObjCInterfaceDecl *CDecl,
std::string &Result) {
assert(CDecl && "Class missing in SynthesizeObjCInternalStruct");
- assert(CDecl->getName() && "Name missing in SynthesizeObjCInternalStruct");
+ assert(CDecl->getIdentifierName() &&
+ "Name missing in SynthesizeObjCInternalStruct");
// Do not synthesize more than once.
if (ObjCSynthesizedStructs.count(CDecl))
return;
@@ -2922,15 +2923,15 @@ void RewriteObjC::RewriteObjCClassMetaData(ObjCImplementationDecl *IDecl,
// Build _objc_method_list for class's instance methods if needed
RewriteObjCMethodsMetaData(IDecl->instmeth_begin(), IDecl->instmeth_end(),
- true, "", IDecl->getName(), Result);
+ true, "", IDecl->getIdentifierName(), Result);
// Build _objc_method_list for class's class methods if needed
RewriteObjCMethodsMetaData(IDecl->classmeth_begin(), IDecl->classmeth_end(),
- false, "", IDecl->getName(), Result);
+ false, "", IDecl->getIdentifierName(), Result);
// Protocols referenced in class declaration?
RewriteObjCProtocolsMetaData(CDecl->getReferencedProtocols(),
- "CLASS", CDecl->getName(), Result);
+ "CLASS", CDecl->getIdentifierName(), Result);
// Declaration of class/meta-class metadata
@@ -3429,7 +3430,7 @@ void RewriteObjC::SynthesizeBlockLiterals(SourceLocation FunLocStart,
void RewriteObjC::InsertBlockLiteralsWithinFunction(FunctionDecl *FD) {
SourceLocation FunLocStart = FD->getTypeSpecStartLoc();
- const char *FuncName = FD->getName();
+ const char *FuncName = FD->getIdentifierName();
SynthesizeBlockLiterals(FunLocStart, FuncName);
}
@@ -3489,13 +3490,13 @@ Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp) {
const BlockPointerType *CPT = 0;
if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Exp->getCallee())) {
- closureName = DRE->getDecl()->getName();
+ closureName = DRE->getDecl()->getIdentifierName();
CPT = DRE->getType()->getAsBlockPointerType();
} else if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(Exp->getCallee())) {
- closureName = CDRE->getDecl()->getName();
+ closureName = CDRE->getDecl()->getIdentifierName();
CPT = CDRE->getType()->getAsBlockPointerType();
} else if (MemberExpr *MExpr = dyn_cast<MemberExpr>(Exp->getCallee())) {
- closureName = MExpr->getMemberDecl()->getName();
+ closureName = MExpr->getMemberDecl()->getIdentifierName();
CPT = MExpr->getType()->getAsBlockPointerType();
} else {
assert(1 && "RewriteBlockClass: Bad type");
@@ -3812,15 +3813,15 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp) {
E = BlockByCopyDecls.end(); I != E; ++I) {
if (isObjCType((*I)->getType())) {
// FIXME: Conform to ABI ([[obj retain] autorelease]).
- FD = SynthBlockInitFunctionDecl((*I)->getName());
+ FD = SynthBlockInitFunctionDecl((*I)->getIdentifierName());
Exp = new DeclRefExpr(FD, FD->getType(), SourceLocation());
} else if (isBlockPointerType((*I)->getType())) {
- FD = SynthBlockInitFunctionDecl((*I)->getName());
+ FD = SynthBlockInitFunctionDecl((*I)->getIdentifierName());
Arg = new DeclRefExpr(FD, FD->getType(), SourceLocation());
Exp = new CStyleCastExpr(Context->VoidPtrTy, Arg,
Context->VoidPtrTy, SourceLocation(), SourceLocation());
} else {
- FD = SynthBlockInitFunctionDecl((*I)->getName());
+ FD = SynthBlockInitFunctionDecl((*I)->getIdentifierName());
Exp = new DeclRefExpr(FD, FD->getType(), SourceLocation());
}
InitExprs.push_back(Exp);
@@ -3828,7 +3829,7 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp) {
// Output all "by ref" declarations.
for (llvm::SmallPtrSet<ValueDecl*,8>::iterator I = BlockByRefDecls.begin(),
E = BlockByRefDecls.end(); I != E; ++I) {
- FD = SynthBlockInitFunctionDecl((*I)->getName());
+ FD = SynthBlockInitFunctionDecl((*I)->getIdentifierName());
Exp = new DeclRefExpr(FD, FD->getType(), SourceLocation());
Exp = new UnaryOperator(Exp, UnaryOperator::AddrOf,
Context->getPointerType(Exp->getType()),
@@ -4064,7 +4065,8 @@ void RewriteObjC::HandleDeclInMainFile(Decl *D) {
if (VD->getInit()) {
GlobalVarDecl = VD;
RewriteFunctionBodyOrGlobalInitializer(VD->getInit());
- SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(), VD->getName());
+ SynthesizeBlockLiterals(VD->getTypeSpecStartLoc(),
+ VD->getIdentifierName());
GlobalVarDecl = 0;
// This is needed for blocks.
diff --git a/docs/InternalsManual.html b/docs/InternalsManual.html
index 1e1fc990ad..adfa7c3e74 100644
--- a/docs/InternalsManual.html
+++ b/docs/InternalsManual.html
@@ -37,6 +37,7 @@
<ul>
<li><a href="#Type">The Type class and its subclasses</a></li>
<li><a href="#QualType">The QualType class</a></li>
+ <li><a href="#DeclarationName">Declaration names</a></li>
<li><a href="#CFG">The CFG class</a></li>
<li><a href="#Constants">Constant Folding in the Clang AST</a></li>
</ul>
@@ -443,6 +444,107 @@ exactly the same size as a pointer, and this works fine on any system where
malloc'd objects are at least 8 byte aligned.</p>
<!-- ======================================================================= -->
+<h3 id="DeclarationName">Declaration names</h3>
+<!-- ======================================================================= -->
+
+<p>The <tt>DeclarationName</tt> class represents the name of a
+ declaration in Clang. Declarations in the C family of languages can
+ take several different forms. Most declarations are named by are
+ simple identifiers, e.g., "<code>f</code>" and "<code>x</code>" in
+ the function declaration <code>f(int x)</code>. In C++, declaration
+ names can also name class constructors ("<code>Class</code>"
+ in <code>struct Class { Class(); }</code>), class destructors
+ ("<code>~Class</code>"), overloaded operator names ("operator+"),
+ and conversion functions ("<code>operator void const *</code>"). In
+ Objective-C, declaration names can refer to the names of Objective-C
+ methods, which involve the method name and the parameters,
+ collectively called a <i>selector</i>, e.g..,
+ "<code>setWidth:height:</code>". Since all of these kinds of
+ entities--variables, functions, Objective-C methods, C++
+ constructors, destructors, and operators---are represented as
+ subclasses of Clang's common <code>NamedDecl</code>
+ class, <code>DeclarationName</code> is designed to efficiently
+ represent any kind of name.</p>
+
+<p>Given
+ a <code>DeclarationName</code> <code>N</code>, <code>N.getNameKind()</code>
+ will produce a valid that describes what kind of name <code>N</code>
+ stores. There are 7 options (all of the names are inside
+ the <code>DeclarationName</code> class)</p>
+<dl>
+ <dt>Identifier</dt>
+ <dd>The name is a simple
+ identifier. Use <code>N.getAsIdentifierInfo()</code> to retrieve the
+ corresponding <code>IdentifierInfo*</code> pointing to the actual
+ identifier. Note that C++ overloaded operators (e.g.,
+ "<code>operator+</code>") are represented as special kinds of
+ identifiers. Use <code>IdentifierInfo</code>'s <code>getOverloadedOperatorID</code>
+ function to determine whether an identifier is an overloaded
+ operator name.</dd>
+
+ <dt>ObjCZeroArgSelector, ObjCOneArgSelector,
+ ObjCMultiArgSelector</dt>
+ <dd>The name is an Objective-C selector, which can be retrieved as a
+ <code>Selector</code> instance
+ via <code>N.getObjCSelector()</code>. The three possible name
+ kinds for Objective-C reflect an optimization within
+ the <code>DeclarationName</code> class: both zero- and
+ one-argument selectors are stored as a
+ masked <code>IdentifierInfo</code> pointer, and therefore require
+ very little space, since zero- and one-argument selectors are far
+ more common than multi-argument selectors (which use a different
+ structure).</dd>
+
+ <dt>CXXConstructorName</dt>
+ <dd>The name is a C++ constructor
+ name. Use <code>N.getCXXNameType()</code> to retrieve
+ the <a href="#QualType">type</a> that this constructor is meant to
+ construct. The type is always the canonical type, since all
+ constructors for a given type have the same name.</dd>
+
+ <dt>CXXDestructorName</dt>
+ <dd>The name is a C++ destructor
+ name. Use <code>N.getCXXNameType()</code> to retrieve
+ the <a href="#QualType">type</a> whose destructor is being
+ named. This type is always a canonical type.</dd>
+
+ <dt>CXXConversionFunctionName</dt>
+ <dd>The name is a C++ conversion function. Conversion functions are
+ named according to the type they convert to, e.g., "<code>operator void
+ const *</code>". Use <code>N.getCXXNameType()</code> to retrieve
+ the type that this conversion function converts to. This type is
+ always a canonical type.</dd>
+</dl>
+
+<p><code>DeclarationName</code>s are cheap to create, copy, and
+ compare. They require only a single pointer's worth of storage in
+ the common cases (identifiers, C++ overloaded operator names, zero-
+ and one-argument Objective-C selectors) and use dense, uniqued
+ storage for the other kinds of
+ names. Two <code>DeclarationName</code>s can be compared for
+ equality (<code>==</code>, <code>!=</code>) using a simple bitwise
+ comparison, can be ordered
+ with <code>&lt;</code>, <code>&gt;</code>, <code>&lt;=</code>,
+ and <code>&gt;=</code> (which provide a lexicographical ordering for
+ normal identifiers but an unspecified ordering for other kinds of
+ names), and can be placed into LLVM <code>DenseMap</code>s
+ and <code>DenseSet</code>s.</p>
+
+<p><code>DeclarationName</code> instances can be created in different
+ ways depending on what kind of name the instance will store. Normal
+ identifiers (<code>IdentifierInfo</code> pointers), including
+ overloaded operator names, and Objective-C selectors
+ (<code>Selector</code>) can be implicitly converted
+ to <code>DeclarationName</code>s. Names for C++ constructors,
+ destructors, and conversion functions can be retrieved from
+ the <code>DeclarationNameTable</code>, an instance of which is
+ available as <code>ASTContext::DeclarationNames</code>. The member
+ functions <code>getCXXConstructorName</code>, <code>getCXXDestructorName</code>,
+ and <code>getCXXConversionFunctionName</code>, respectively,
+ return <code>DeclarationName</code> instances for the three kinds of
+ C++ special function names.</p>
+
+<!-- ======================================================================= -->
<h3 id="CFG">The <tt>CFG</tt> class</h3>
<!-- ======================================================================= -->
@@ -736,4 +838,4 @@ interacts with constant evaluation:</p>
</div>
</body>
-</html> \ No newline at end of file
+</html>
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++ -*-===//
+//
+//