Introduction the DeclarationName class, as a single, general method of
representing the names of declarations in the C family of
languages. DeclarationName is used in NamedDecl to store the name of
the declaration (naturally), and ObjCMethodDecl is now a NamedDecl.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59441 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index e84cc4b..ee57816 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -33,7 +33,7 @@
unsigned size_reserve) :
CFConstantStringTypeDecl(0), ObjCFastEnumerationStateTypeDecl(0),
SourceMgr(SM), LangOpts(LOpts), Target(t),
- Idents(idents), Selectors(sels)
+ Idents(idents), Selectors(sels)
{
if (size_reserve > 0) Types.reserve(size_reserve);
InitBuiltinTypes();
@@ -996,7 +996,7 @@
/// 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 @@
// 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 @@
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);
diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt
index a58b3b1..4ac6a6e 100644
--- a/lib/AST/CMakeLists.txt
+++ b/lib/AST/CMakeLists.txt
@@ -5,6 +5,7 @@
ASTContext.cpp
Builtins.cpp
CFG.cpp
+ DeclarationName.cpp
DeclBase.cpp
Decl.cpp
DeclCXX.cpp
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index fa5e9ce..dc4d602 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -133,9 +133,47 @@
// NamedDecl Implementation
//===----------------------------------------------------------------------===//
-const char *NamedDecl::getName() const {
- if (const IdentifierInfo *II = getIdentifier())
- return II->getName();
+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 "";
}
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 1de6407..8855e99 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -27,20 +27,20 @@
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 @@
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 @@
(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 @@
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,
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 0d006d6..558156c 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -758,11 +758,11 @@
// 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;
}
diff --git a/lib/AST/DeclSerialization.cpp b/lib/AST/DeclSerialization.cpp
index 3df942e..5137b72 100644
--- a/lib/AST/DeclSerialization.cpp
+++ b/lib/AST/DeclSerialization.cpp
@@ -129,12 +129,58 @@
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 @@
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::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);
diff --git a/lib/AST/DeclarationName.cpp b/lib/AST/DeclarationName.cpp
new file mode 100644
index 0000000..96e194b
--- /dev/null
+++ b/lib/AST/DeclarationName.cpp
@@ -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);
+}
+
diff --git a/lib/AST/StmtDumper.cpp b/lib/AST/StmtDumper.cpp
index 0b9e62d..a992efb 100644
--- a/lib/AST/StmtDumper.cpp
+++ b/lib/AST/StmtDumper.cpp
@@ -202,7 +202,7 @@
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 @@
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::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 @@
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 @@
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());
}
}