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.

llvm-svn: 59441
This commit is contained in:
Douglas Gregor 2008-11-17 14:58:09 +00:00
parent d1f5e5d304
commit 77324f3854
29 changed files with 890 additions and 202 deletions

View File

@ -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);
}

View File

@ -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.

View File

@ -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>
@ -442,6 +443,107 @@ the low bit of the pointer to the Type object. This means that QualType is
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>
<!-- ======================================================================= -->

View File

@ -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,6 +112,7 @@ public:
TargetInfo &Target;
IdentifierTable &Idents;
SelectorTable &Selectors;
DeclarationNameTable DeclarationNames;
SourceManager& getSourceManager() { return SourceMgr; }
llvm::MallocAllocator &getAllocator() { return Allocator; }

View File

@ -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,18 +57,50 @@ 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) {}
IdentifierInfo *getIdentifier() const { return Identifier; }
virtual const char *getName() const;
/// 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;
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) {}

View File

@ -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,

View File

@ -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.

View File

@ -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; }

View File

@ -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

View File

@ -29,9 +29,10 @@ 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,7 +282,8 @@ 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.
@ -362,12 +364,35 @@ public:
static SelectorTable* CreateAndRegister(llvm::Deserializer& D);
};
/// 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

View File

@ -996,7 +996,7 @@ QualType ASTContext::getObjCInterfaceType(ObjCInterfaceDecl *Decl) {
/// alphabetically.
static bool CmpProtocolNames(const ObjCProtocolDecl *LHS,
const ObjCProtocolDecl *RHS) {
return strcmp(LHS->getName(), RHS->getName()) < 0;
return LHS->getDeclName() < RHS->getDeclName();
}
static void SortAndUniqueProtocols(ObjCProtocolDecl **&Protocols,
@ -1449,7 +1449,7 @@ QualType ASTContext::getObjCFastEnumerationStateType()
// typedef <type> BOOL;
static bool isTypeTypedefedAsBOOL(QualType T) {
if (const TypedefType *TT = dyn_cast<TypedefType>(T))
return !strcmp(TT->getDecl()->getName(), "BOOL");
return !strcmp(TT->getDecl()->getIdentifierName(), "BOOL");
return false;
}
@ -2260,7 +2260,8 @@ ASTContext* ASTContext::Create(llvm::Deserializer& D) {
unsigned size_reserve = D.ReadInt();
ASTContext* A = new ASTContext(LOpts, SM, t, idents, sels, size_reserve);
ASTContext* A = new ASTContext(LOpts, SM, t, idents, sels,
size_reserve);
for (unsigned i = 0; i < size_reserve; ++i)
Type::Create(*A,i,D);

View File

@ -5,6 +5,7 @@ add_clang_library(clangAST
ASTContext.cpp
Builtins.cpp
CFG.cpp
DeclarationName.cpp
DeclBase.cpp
Decl.cpp
DeclCXX.cpp

View File

@ -133,10 +133,48 @@ FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C,
// NamedDecl Implementation
//===----------------------------------------------------------------------===//
const char *NamedDecl::getName() const {
if (const IdentifierInfo *II = getIdentifier())
std::string NamedDecl::getName() const {
switch (Name.getNameKind()) {
case DeclarationName::Identifier:
if (const IdentifierInfo *II = Name.getAsIdentifierInfo())
return II->getName();
return "";
case DeclarationName::ObjCZeroArgSelector:
case DeclarationName::ObjCOneArgSelector:
case DeclarationName::ObjCMultiArgSelector:
return Name.getObjCSelector().getName();
case DeclarationName::CXXConstructorName: {
QualType ClassType = Name.getCXXNameType();
if (const RecordType *ClassRec = ClassType->getAsRecordType())
return ClassRec->getDecl()->getName();
return ClassType.getAsString();
}
case DeclarationName::CXXDestructorName: {
std::string Result = "~";
QualType Type = Name.getCXXNameType();
if (const RecordType *Rec = Type->getAsRecordType())
Result += Rec->getDecl()->getName();
else
Result += Type.getAsString();
return Result;
}
case DeclarationName::CXXConversionFunctionName: {
std::string Result = "operator ";
QualType Type = Name.getCXXNameType();
if (const RecordType *Rec = Type->getAsRecordType())
Result += Rec->getDecl()->getName();
else
Result += Type.getAsString();
return Result;
}
}
assert(false && "Unexpected declaration name kind");
return "";
}
//===----------------------------------------------------------------------===//

View File

@ -27,20 +27,20 @@ CXXFieldDecl *CXXFieldDecl::Create(ASTContext &C, CXXRecordDecl *RD,
return new (Mem) CXXFieldDecl(RD, L, Id, T, BW);
}
CXXRecordDecl::CXXRecordDecl(ASTContext &C, TagKind TK, DeclContext *DC,
CXXRecordDecl::CXXRecordDecl(TagKind TK, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id)
: RecordDecl(CXXRecord, TK, DC, L, Id), DeclContext(CXXRecord),
UserDeclaredConstructor(false), UserDeclaredCopyConstructor(false),
Aggregate(true), Polymorphic(false), Bases(0), NumBases(0),
Constructors(DC, &C.Idents.getConstructorId()),
Constructors(DC, DeclarationName()),
Destructor(0),
Conversions(DC, &C.Idents.getConversionFunctionId()) { }
Conversions(DC, DeclarationName()) { }
CXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id,
CXXRecordDecl* PrevDecl) {
void *Mem = C.getAllocator().Allocate<CXXRecordDecl>();
CXXRecordDecl* R = new (Mem) CXXRecordDecl(C, TK, DC, L, Id);
CXXRecordDecl* R = new (Mem) CXXRecordDecl(TK, DC, L, Id);
C.getTypeDeclType(R, PrevDecl);
return R;
}
@ -178,11 +178,13 @@ CXXBaseOrMemberInitializer::~CXXBaseOrMemberInitializer() {
CXXConstructorDecl *
CXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, IdentifierInfo *Id,
SourceLocation L, DeclarationName N,
QualType T, bool isExplicit,
bool isInline, bool isImplicitlyDeclared) {
assert(N.getNameKind() == DeclarationName::CXXConstructorName &&
"Name must refer to a constructor");
void *Mem = C.getAllocator().Allocate<CXXConstructorDecl>();
return new (Mem) CXXConstructorDecl(RD, L, Id, T, isExplicit, isInline,
return new (Mem) CXXConstructorDecl(RD, L, N, T, isExplicit, isInline,
isImplicitlyDeclared);
}
@ -242,54 +244,26 @@ bool CXXConstructorDecl::isConvertingConstructor() const {
(getNumParams() > 1 && getParamDecl(1)->getDefaultArg() != 0);
}
const char *CXXConstructorDecl::getName() const {
return getParent()->getName();
}
CXXDestructorDecl *
CXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, IdentifierInfo *Id,
SourceLocation L, DeclarationName N,
QualType T, bool isInline,
bool isImplicitlyDeclared) {
assert(N.getNameKind() == DeclarationName::CXXDestructorName &&
"Name must refer to a destructor");
void *Mem = C.getAllocator().Allocate<CXXDestructorDecl>();
return new (Mem) CXXDestructorDecl(RD, L, Id, T, isInline,
return new (Mem) CXXDestructorDecl(RD, L, N, T, isInline,
isImplicitlyDeclared);
}
CXXDestructorDecl::~CXXDestructorDecl() {
delete [] Name;
}
const char *CXXDestructorDecl::getName() const {
if (!Name) {
std::string Builder = "~";
Builder += getParent()->getName();
Name = new char[Builder.size()+1];
strcpy(Name, Builder.c_str());
}
return Name;
}
CXXConversionDecl::~CXXConversionDecl() {
delete [] Name;
}
const char *CXXConversionDecl::getName() const {
if (!Name) {
std::string Builder = "operator ";
Builder += getConversionType().getAsString();
Name = new char[Builder.size()+1];
strcpy(Name, Builder.c_str());
}
return Name;
}
CXXConversionDecl *
CXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD,
SourceLocation L, IdentifierInfo *Id,
SourceLocation L, DeclarationName N,
QualType T, bool isInline, bool isExplicit) {
assert(N.getNameKind() == DeclarationName::CXXConversionFunctionName &&
"Name must refer to a conversion function");
void *Mem = C.getAllocator().Allocate<CXXConversionDecl>();
return new (Mem) CXXConversionDecl(RD, L, Id, T, isInline, isExplicit);
return new (Mem) CXXConversionDecl(RD, L, N, T, isInline, isExplicit);
}
CXXClassVarDecl *CXXClassVarDecl::Create(ASTContext &C, CXXRecordDecl *RD,
@ -301,9 +275,9 @@ CXXClassVarDecl *CXXClassVarDecl::Create(ASTContext &C, CXXRecordDecl *RD,
OverloadedFunctionDecl *
OverloadedFunctionDecl::Create(ASTContext &C, DeclContext *DC,
IdentifierInfo *Id) {
DeclarationName N) {
void *Mem = C.getAllocator().Allocate<OverloadedFunctionDecl>();
return new (Mem) OverloadedFunctionDecl(DC, Id);
return new (Mem) OverloadedFunctionDecl(DC, N);
}
LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,

View File

@ -758,11 +758,11 @@ unsigned ObjCMethodDecl::getSynthesizedMethodSize() const {
// syntesized method name is a concatenation of -/+[class-name selector]
// Get length of this name.
unsigned length = 3; // _I_ or _C_
length += strlen(getClassInterface()->getName()) +1; // extra for _
length += strlen(getClassInterface()->getIdentifierName()) +1; // extra for _
NamedDecl *MethodContext = getMethodContext();
if (ObjCCategoryImplDecl *CID =
dyn_cast<ObjCCategoryImplDecl>(MethodContext))
length += strlen(CID->getName()) +1;
length += strlen(CID->getIdentifierName()) +1;
length += getSelector().getName().size(); // selector name
return length;
}

View File

@ -129,12 +129,58 @@ void DeclContext::ReadOutRec(Deserializer& D, ASTContext& C) {
void NamedDecl::EmitInRec(Serializer& S) const {
Decl::EmitInRec(S);
S.EmitPtr(getIdentifier()); // From NamedDecl.
S.EmitInt(Name.getNameKind());
switch (Name.getNameKind()) {
case DeclarationName::Identifier:
S.EmitPtr(Name.getAsIdentifierInfo());
break;
case DeclarationName::ObjCZeroArgSelector:
case DeclarationName::ObjCOneArgSelector:
case DeclarationName::ObjCMultiArgSelector:
Name.getObjCSelector().Emit(S);
break;
case DeclarationName::CXXConstructorName:
case DeclarationName::CXXDestructorName:
case DeclarationName::CXXConversionFunctionName:
Name.getCXXNameType().Emit(S);
break;
}
}
void NamedDecl::ReadInRec(Deserializer& D, ASTContext& C) {
Decl::ReadInRec(D, C);
D.ReadPtr(Identifier); // From NamedDecl.
DeclarationName::NameKind Kind
= static_cast<DeclarationName::NameKind>(D.ReadInt());
switch (Kind) {
case DeclarationName::Identifier: {
IdentifierInfo *Identifier;
D.ReadPtr(Identifier);
Name = Identifier;
break;
}
case DeclarationName::ObjCZeroArgSelector:
case DeclarationName::ObjCOneArgSelector:
case DeclarationName::ObjCMultiArgSelector:
Name = Selector::ReadVal(D);
break;
case DeclarationName::CXXConstructorName:
Name = C.DeclarationNames.getCXXConstructorName(QualType::ReadVal(D));
break;
case DeclarationName::CXXDestructorName:
Name = C.DeclarationNames.getCXXDestructorName(QualType::ReadVal(D));
break;
case DeclarationName::CXXConversionFunctionName:
Name = C.DeclarationNames.getCXXConversionFunctionName(QualType::ReadVal(D));
break;
}
}
//===----------------------------------------------------------------------===//
@ -434,7 +480,7 @@ FunctionDecl* FunctionDecl::CreateImpl(Deserializer& D, ASTContext& C) {
void *Mem = C.getAllocator().Allocate<FunctionDecl>();
FunctionDecl* decl = new (Mem)
FunctionDecl(Function, 0, SourceLocation(), NULL,
FunctionDecl(Function, 0, SourceLocation(), DeclarationName(),
QualType(), SClass, IsInline, 0);
decl->ValueDecl::ReadInRec(D, C);
@ -495,7 +541,7 @@ OverloadedFunctionDecl *
OverloadedFunctionDecl::CreateImpl(Deserializer& D, ASTContext& C) {
void *Mem = C.getAllocator().Allocate<OverloadedFunctionDecl>();
OverloadedFunctionDecl* decl = new (Mem)
OverloadedFunctionDecl(0, NULL);
OverloadedFunctionDecl(0, DeclarationName());
decl->NamedDecl::ReadInRec(D, C);

View File

@ -0,0 +1,166 @@
//===-- DeclarationName.cpp - Declaration names implementation --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the DeclarationName and DeclarationNameTable
// classes.
//
//===----------------------------------------------------------------------===//
#include "clang/AST/DeclarationName.h"
#include "clang/Basic/IdentifierTable.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/Bitcode/Serialize.h"
#include "llvm/Bitcode/Deserialize.h"
using namespace clang;
namespace clang {
/// CXXSpecialName - Records the type associated with one of the
/// "special" kinds of declaration names in C++, e.g., constructors,
/// destructors, and conversion functions.
class CXXSpecialName
: public DeclarationNameExtra, public llvm::FoldingSetNode {
public:
QualType Type;
void Profile(llvm::FoldingSetNodeID &ID) {
ID.AddInteger(ExtraKindOrNumArgs);
ID.AddPointer(Type.getAsOpaquePtr());
}
};
bool operator<(DeclarationName LHS, DeclarationName RHS) {
if (IdentifierInfo *LhsId = LHS.getAsIdentifierInfo())
if (IdentifierInfo *RhsId = RHS.getAsIdentifierInfo())
return strcmp(LhsId->getName(), RhsId->getName()) < 0;
return LHS.getAsOpaqueInteger() < RHS.getAsOpaqueInteger();
}
} // end namespace clang
DeclarationName::DeclarationName(Selector Sel) {
switch (Sel.getNumArgs()) {
case 0:
Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
Ptr |= StoredObjCZeroArgSelector;
break;
case 1:
Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
Ptr |= StoredObjCOneArgSelector;
break;
default:
Ptr = Sel.InfoPtr & ~Selector::ArgFlags;
Ptr |= StoredObjCMultiArgSelectorOrCXXName;
break;
}
}
DeclarationName::NameKind DeclarationName::getNameKind() const {
switch (getStoredNameKind()) {
case StoredIdentifier: return Identifier;
case StoredObjCZeroArgSelector: return ObjCZeroArgSelector;
case StoredObjCOneArgSelector: return ObjCOneArgSelector;
case StoredObjCMultiArgSelectorOrCXXName:
switch (getExtra()->ExtraKindOrNumArgs) {
case DeclarationNameExtra::CXXConstructor:
return CXXConstructorName;
case DeclarationNameExtra::CXXDestructor:
return CXXDestructorName;
case DeclarationNameExtra::CXXConversionFunction:
return CXXConversionFunctionName;
default:
return ObjCMultiArgSelector;
}
break;
}
// Can't actually get here.
return Identifier;
}
QualType DeclarationName::getCXXNameType() const {
if (CXXSpecialName *CXXName = getAsCXXSpecialName())
return CXXName->Type;
else
return QualType();
}
Selector DeclarationName::getObjCSelector() const {
switch (getNameKind()) {
case ObjCZeroArgSelector:
return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 0);
case ObjCOneArgSelector:
return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 1);
case ObjCMultiArgSelector:
return Selector(reinterpret_cast<MultiKeywordSelector *>(Ptr & ~PtrMask));
default:
break;
}
return Selector();
}
DeclarationNameTable::DeclarationNameTable() {
CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>;
}
DeclarationNameTable::~DeclarationNameTable() {
delete static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
}
DeclarationName
DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind,
QualType Ty) {
assert(Kind >= DeclarationName::CXXConstructorName &&
Kind <= DeclarationName::CXXConversionFunctionName &&
"Kind must be a C++ special name kind");
llvm::FoldingSet<CXXSpecialName> *SpecialNames
= static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl);
DeclarationNameExtra::ExtraKind EKind;
switch (Kind) {
case DeclarationName::CXXConstructorName:
EKind = DeclarationNameExtra::CXXConstructor;
break;
case DeclarationName::CXXDestructorName:
EKind = DeclarationNameExtra::CXXDestructor;
break;
case DeclarationName::CXXConversionFunctionName:
EKind = DeclarationNameExtra::CXXConversionFunction;
break;
default:
return DeclarationName();
}
// Unique selector, to guarantee there is one per name.
llvm::FoldingSetNodeID ID;
ID.AddInteger(EKind);
ID.AddPointer(Ty.getAsOpaquePtr());
void *InsertPos = 0;
if (CXXSpecialName *Name = SpecialNames->FindNodeOrInsertPos(ID, InsertPos))
return DeclarationName(Name);
CXXSpecialName *SpecialName = new CXXSpecialName;
SpecialName->ExtraKindOrNumArgs = EKind;
SpecialName->Type = Ty;
SpecialNames->InsertNode(SpecialName, InsertPos);
return DeclarationName(SpecialName);
}

View File

@ -202,7 +202,7 @@ void StmtDumper::DumpDeclarator(Decl *D) {
if (TypedefDecl *localType = dyn_cast<TypedefDecl>(D)) {
fprintf(F, "\"typedef %s %s\"",
localType->getUnderlyingType().getAsString().c_str(),
localType->getName());
localType->getIdentifierName());
} else if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
fprintf(F, "\"");
// Emit storage class for vardecls.
@ -295,14 +295,16 @@ void StmtDumper::VisitDeclRefExpr(DeclRefExpr *Node) {
default: fprintf(F,"Decl"); break;
}
fprintf(F, "='%s' %p", Node->getDecl()->getName(), (void*)Node->getDecl());
fprintf(F, "='%s' %p", Node->getDecl()->getName().c_str(),
(void*)Node->getDecl());
}
void StmtDumper::VisitObjCIvarRefExpr(ObjCIvarRefExpr *Node) {
DumpExpr(Node);
fprintf(F, " %sDecl='%s' %p", Node->getDecl()->getDeclKindName(),
Node->getDecl()->getName(), (void*)Node->getDecl());
Node->getDecl()->getIdentifierName(),
(void*)Node->getDecl());
if (Node->isFreeIvar())
fprintf(F, " isFreeIvar");
}
@ -373,7 +375,8 @@ void StmtDumper::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *Node) {
void StmtDumper::VisitMemberExpr(MemberExpr *Node) {
DumpExpr(Node);
fprintf(F, " %s%s %p", Node->isArrow() ? "->" : ".",
Node->getMemberDecl()->getName(), (void*)Node->getMemberDecl());
Node->getMemberDecl()->getName().c_str(),
(void*)Node->getMemberDecl());
}
void StmtDumper::VisitExtVectorElementExpr(ExtVectorElementExpr *Node) {
DumpExpr(Node);
@ -461,7 +464,7 @@ void StmtDumper::VisitObjCProtocolExpr(ObjCProtocolExpr *Node) {
DumpExpr(Node);
fprintf(F, " ");
fprintf(F, "%s", Node->getProtocol()->getName());
fprintf(F, "%s", Node->getProtocol()->getIdentifierName());
}
void StmtDumper::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
@ -474,7 +477,8 @@ void StmtDumper::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *Node) {
Getter->getSelector().getName().c_str(),
Setter ? Setter->getSelector().getName().c_str() : "(null)");
} else {
fprintf(F, " Kind=PropertyRef Property=\"%s\"", Node->getProperty()->getName());
fprintf(F, " Kind=PropertyRef Property=\"%s\"",
Node->getProperty()->getIdentifierName());
}
}

View File

@ -297,22 +297,22 @@ unsigned llvm::DenseMapInfo<clang::Selector>::getHashValue(clang::Selector S) {
return DenseMapInfo<void*>::getHashValue(S.getAsOpaquePtr());
}
namespace clang {
/// MultiKeywordSelector - One of these variable length records is kept for each
/// selector containing more than one keyword. We use a folding set
/// to unique aggregate names (keyword selectors in ObjC parlance). Access to
/// this class is provided strictly through Selector.
namespace clang {
class MultiKeywordSelector : public llvm::FoldingSetNode {
class MultiKeywordSelector
: public DeclarationNameExtra, public llvm::FoldingSetNode {
friend SelectorTable* SelectorTable::CreateAndRegister(llvm::Deserializer&);
MultiKeywordSelector(unsigned nKeys) : NumArgs(nKeys) {}
MultiKeywordSelector(unsigned nKeys) {
ExtraKindOrNumArgs = NUM_EXTRA_KINDS + nKeys;
}
public:
unsigned NumArgs;
// Constructor for keyword selectors.
MultiKeywordSelector(unsigned nKeys, IdentifierInfo **IIV) {
assert((nKeys > 1) && "not a multi-keyword selector");
NumArgs = nKeys;
ExtraKindOrNumArgs = NUM_EXTRA_KINDS + nKeys;
// Fill in the trailing keyword array.
IdentifierInfo **KeyInfo = reinterpret_cast<IdentifierInfo **>(this+1);
@ -323,17 +323,17 @@ public:
// getName - Derive the full selector name and return it.
std::string getName() const;
unsigned getNumArgs() const { return NumArgs; }
unsigned getNumArgs() const { return ExtraKindOrNumArgs - NUM_EXTRA_KINDS; }
typedef IdentifierInfo *const *keyword_iterator;
keyword_iterator keyword_begin() const {
return reinterpret_cast<keyword_iterator>(this+1);
}
keyword_iterator keyword_end() const {
return keyword_begin()+NumArgs;
return keyword_begin()+getNumArgs();
}
IdentifierInfo *getIdentifierInfoForSlot(unsigned i) const {
assert(i < NumArgs && "getIdentifierInfoForSlot(): illegal index");
assert(i < getNumArgs() && "getIdentifierInfoForSlot(): illegal index");
return keyword_begin()[i];
}
static void Profile(llvm::FoldingSetNodeID &ID,
@ -343,7 +343,7 @@ public:
ID.AddPointer(ArgTys[i]);
}
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, keyword_begin(), NumArgs);
Profile(ID, keyword_begin(), getNumArgs());
}
};
} // end namespace clang.

View File

@ -152,7 +152,7 @@ llvm::DIType CGDebugInfo::CreateType(const TypedefType *Ty,
// We don't set size information, but do specify where the typedef was
// declared.
const char *TyName = Ty->getDecl()->getName();
const char *TyName = Ty->getDecl()->getIdentifierName();
SourceLocation DefLoc = Ty->getDecl()->getLocation();
llvm::DICompileUnit DefUnit = getOrCreateCompileUnit(DefLoc);
@ -206,7 +206,7 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty,
SourceManager &SM = M->getContext().getSourceManager();
// Get overall information about the record type for the debug info.
const char *Name = Decl->getName();
const char *Name = Decl->getIdentifierName();
if (Name == 0) Name = "";
llvm::DICompileUnit DefUnit = getOrCreateCompileUnit(Decl->getLocation());
@ -242,7 +242,7 @@ llvm::DIType CGDebugInfo::CreateType(const RecordType *Ty,
FieldDecl *Field = *I;
llvm::DIType FieldTy = getOrCreateType(Field->getType(), Unit);
const char *FieldName = Field->getName();
const char *FieldName = Field->getIdentifierName();
if (FieldName == 0) FieldName = "";
// Get the location for the field.
@ -301,7 +301,8 @@ llvm::DIType CGDebugInfo::CreateType(const EnumType *Ty,
llvm::DIArray EltArray =
DebugFactory.GetOrCreateArray(&Enumerators[0], Enumerators.size());
const char *EnumName = Decl->getName() ? Decl->getName() : "";
const char *EnumName
= Decl->getIdentifierName() ? Decl->getIdentifierName() : "";
SourceLocation DefLoc = Decl->getLocation();
llvm::DICompileUnit DefUnit = getOrCreateCompileUnit(DefLoc);
SourceManager &SM = M->getContext().getSourceManager();
@ -515,7 +516,7 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
llvm::DICompileUnit Unit = getOrCreateCompileUnit(Decl->getLocation());
SourceManager &SM = M->getContext().getSourceManager();
uint64_t LineNo = SM.getLogicalLineNumber(Decl->getLocation());
const char *Name = Decl->getName();
const char *Name = Decl->getIdentifierName();
DebugFactory.CreateGlobalVariable(Unit, Name, Name, "", Unit, LineNo,
getOrCreateType(Decl->getType(), Unit),

View File

@ -146,7 +146,7 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {
if (!Target.useGlobalsForAutomaticVariables()) {
// A normal fixed sized variable becomes an alloca in the entry block.
const llvm::Type *LTy = ConvertType(Ty);
llvm::AllocaInst * Alloc = CreateTempAlloca(LTy, D.getName());
llvm::AllocaInst * Alloc = CreateTempAlloca(LTy, D.getIdentifierName());
unsigned align = getContext().getTypeAlign(Ty);
if (const AlignedAttr* AA = D.getAttr<AlignedAttr>())
align = std::max(align, AA->getAlignment());
@ -164,7 +164,7 @@ void CodeGenFunction::EmitLocalBlockVarDecl(const VarDecl &D) {
// FIXME: VLA: Add VLA support. For now just make up enough to let
// the compile go through.
const llvm::Type *LTy = ConvertType(Ty);
llvm::AllocaInst * Alloc = CreateTempAlloca(LTy, D.getName());
llvm::AllocaInst * Alloc = CreateTempAlloca(LTy, D.getIdentifierName());
DeclPtr = Alloc;
}

View File

@ -561,7 +561,7 @@ llvm::Value *CGObjCGNU::GenerateProtocolRef(CGBuilderTy &Builder,
void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) {
ASTContext &Context = CGM.getContext();
const char *ProtocolName = PD->getName();
const char *ProtocolName = PD->getIdentifierName();
llvm::SmallVector<std::string, 16> Protocols;
for (ObjCProtocolDecl::protocol_iterator PI = PD->protocol_begin(),
E = PD->protocol_end(); PI != E; ++PI)
@ -616,8 +616,8 @@ void CGObjCGNU::GenerateProtocol(const ObjCProtocolDecl *PD) {
}
void CGObjCGNU::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
const char *ClassName = OCD->getClassInterface()->getName();
const char *CategoryName = OCD->getName();
const char *ClassName = OCD->getClassInterface()->getIdentifierName();
const char *CategoryName = OCD->getIdentifierName();
// Collect information about instance methods
llvm::SmallVector<Selector, 16> InstanceMethodSels;
llvm::SmallVector<llvm::Constant*, 16> InstanceMethodTypes;
@ -675,12 +675,12 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
OID->getClassInterface()->getSuperClass();
const char * SuperClassName = NULL;
if (SuperClassDecl) {
SuperClassName = SuperClassDecl->getName();
SuperClassName = SuperClassDecl->getIdentifierName();
}
// Get the class name
ObjCInterfaceDecl * ClassDecl = (ObjCInterfaceDecl*)OID->getClassInterface();
const char * ClassName = ClassDecl->getName();
const char * ClassName = ClassDecl->getIdentifierName();
// Get the size of instances. For runtimes that support late-bound instances
// this should probably be something different (size just of instance

View File

@ -638,7 +638,7 @@ llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) {
// over.
LazySymbols.insert(&CGM.getContext().Idents.get("Protocol"));
const char *ProtocolName = PD->getName();
const char *ProtocolName = PD->getIdentifierName();
// Construct method lists.
std::vector<llvm::Constant*> InstanceMethods, ClassMethods;
@ -1050,7 +1050,7 @@ static bool IsClassHidden(const ObjCInterfaceDecl *ID) {
void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) {
DefinedSymbols.insert(ID->getIdentifier());
const char *ClassName = ID->getName();
const char *ClassName = ID->getIdentifierName();
// FIXME: Gross
ObjCInterfaceDecl *Interface =
const_cast<ObjCInterfaceDecl*>(ID->getClassInterface());
@ -1143,7 +1143,7 @@ llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID,
llvm::Constant *Protocols,
const llvm::Type *InterfaceTy,
const ConstantVector &Methods) {
const char *ClassName = ID->getName();
const char *ClassName = ID->getIdentifierName();
unsigned Flags = eClassFlags_Meta;
unsigned Size = CGM.getTargetData().getABITypeSize(ObjCTypes.ClassTy);

View File

@ -121,7 +121,7 @@ void CodeGenFunction::StartFunction(const Decl *D, QualType RetTy,
if (CGDebugInfo *DI = CGM.getDebugInfo()) {
DI->setLocation(StartLoc);
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
DI->EmitFunctionStart(FD->getName(), RetTy, CurFn, Builder);
DI->EmitFunctionStart(FD->getIdentifierName(), RetTy, CurFn, Builder);
} else {
// Just use LLVM function name.
DI->EmitFunctionStart(Fn->getName().c_str(),

View File

@ -877,9 +877,13 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) {
bool isInvalidDecl = CheckConstructorDeclarator(D, R, SC);
// Create the new declaration
QualType ClassType = Context.getTypeDeclType(cast<CXXRecordDecl>(DC));
ClassType = Context.getCanonicalType(ClassType);
DeclarationName ConName
= Context.DeclarationNames.getCXXConstructorName(ClassType);
NewFD = CXXConstructorDecl::Create(Context,
cast<CXXRecordDecl>(DC),
D.getIdentifierLoc(), II, R,
D.getIdentifierLoc(), ConName, R,
isExplicit, isInline,
/*isImplicitlyDeclared=*/false);
@ -890,9 +894,14 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) {
if (DC->isCXXRecord()) {
bool isInvalidDecl = CheckDestructorDeclarator(D, R, SC);
QualType ClassType = Context.getTypeDeclType(cast<CXXRecordDecl>(DC));
ClassType = Context.getCanonicalType(ClassType);
DeclarationName DesName
= Context.DeclarationNames.getCXXDestructorName(ClassType);
NewFD = CXXDestructorDecl::Create(Context,
cast<CXXRecordDecl>(DC),
D.getIdentifierLoc(), II, R,
D.getIdentifierLoc(), DesName, R,
isInline,
/*isImplicitlyDeclared=*/false);
@ -916,9 +925,14 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) {
} else {
bool isInvalidDecl = CheckConversionDeclarator(D, R, SC);
QualType ConvType = R->getAsFunctionType()->getResultType();
ConvType = Context.getCanonicalType(ConvType);
DeclarationName ConvName
= Context.DeclarationNames.getCXXConversionFunctionName(ConvType);
NewFD = CXXConversionDecl::Create(Context,
cast<CXXRecordDecl>(DC),
D.getIdentifierLoc(), II, R,
D.getIdentifierLoc(), ConvName, R,
isInline, isExplicit);
if (isInvalidDecl)

View File

@ -725,6 +725,9 @@ void Sema::ActOnFinishCXXMemberSpecification(Scope* S, SourceLocation RLoc,
/// [special]p1). This routine can only be executed just before the
/// definition of the class is complete.
void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) {
QualType ClassType = Context.getTypeDeclType(ClassDecl);
ClassType = Context.getCanonicalType(ClassType);
if (!ClassDecl->hasUserDeclaredConstructor()) {
// C++ [class.ctor]p5:
// A default constructor for a class X is a constructor of class X
@ -732,10 +735,11 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) {
// user-declared constructor for class X, a default constructor is
// implicitly declared. An implicitly-declared default constructor
// is an inline public member of its class.
DeclarationName Name
= Context.DeclarationNames.getCXXConstructorName(ClassType);
CXXConstructorDecl *DefaultCon =
CXXConstructorDecl::Create(Context, ClassDecl,
ClassDecl->getLocation(),
&Context.Idents.getConstructorId(),
ClassDecl->getLocation(), Name,
Context.getFunctionType(Context.VoidTy,
0, 0, false, 0),
/*isExplicit=*/false,
@ -798,10 +802,11 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) {
// An implicitly-declared copy constructor is an inline public
// member of its class.
DeclarationName Name
= Context.DeclarationNames.getCXXConstructorName(ClassType);
CXXConstructorDecl *CopyConstructor
= CXXConstructorDecl::Create(Context, ClassDecl,
ClassDecl->getLocation(),
&Context.Idents.getConstructorId(),
ClassDecl->getLocation(), Name,
Context.getFunctionType(Context.VoidTy,
&ArgType, 1,
false, 0),
@ -825,10 +830,11 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) {
// If a class has no user-declared destructor, a destructor is
// declared implicitly. An implicitly-declared destructor is an
// inline public member of its class.
DeclarationName Name
= Context.DeclarationNames.getCXXDestructorName(ClassType);
CXXDestructorDecl *Destructor
= CXXDestructorDecl::Create(Context, ClassDecl,
ClassDecl->getLocation(),
&Context.Idents.getConstructorId(),
ClassDecl->getLocation(), Name,
Context.getFunctionType(Context.VoidTy,
0, 0, false, 0),
/*isInline=*/true,

View File

@ -302,7 +302,8 @@ Sema::ComparePropertiesInBaseAndSuper(ObjCInterfaceDecl *IDecl) {
E = IDecl->classprop_end(); I != E; ++I) {
ObjCPropertyDecl *PDecl = (*I);
if (SuperPDecl->getIdentifier() == PDecl->getIdentifier())
DiagnosePropertyMismatch(PDecl, SuperPDecl, SDecl->getName());
DiagnosePropertyMismatch(PDecl, SuperPDecl,
SDecl->getIdentifierName());
}
}
}
@ -329,7 +330,7 @@ Sema::MergeOneProtocolPropertiesIntoClass(ObjCInterfaceDecl *IDecl,
mergeProperties.push_back(Pr);
else
// Property protocol already exist in class. Diagnose any mismatch.
DiagnosePropertyMismatch((*CP), Pr, PDecl->getName());
DiagnosePropertyMismatch((*CP), Pr, PDecl->getIdentifierName());
}
IDecl->mergeProperties(&mergeProperties[0], mergeProperties.size());
}

View File

@ -209,7 +209,7 @@ void UserDefinedConversionSequence::DebugPrint() const {
Before.DebugPrint();
fprintf(stderr, " -> ");
}
fprintf(stderr, "'%s'", ConversionFunction->getName());
fprintf(stderr, "'%s'", ConversionFunction->getName().c_str());
if (After.First || After.Second || After.Third) {
fprintf(stderr, " -> ");
After.DebugPrint();