diff options
author | Douglas Gregor <dgregor@apple.com> | 2008-11-17 14:58:09 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2008-11-17 14:58:09 +0000 |
commit | 2e1cd4264d363ca869bf37ef160902f211d21b8c (patch) | |
tree | b4e6314529ad811be3463a668f8b4e515f66fbcc /lib/AST | |
parent | b8abbdc90f902a2c09c566193b900c2c45a46672 (diff) |
Introduction the DeclarationName class, as a single, general method of
representing the names of declarations in the C family of
languages. DeclarationName is used in NamedDecl to store the name of
the declaration (naturally), and ObjCMethodDecl is now a NamedDecl.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59441 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST')
-rw-r--r-- | lib/AST/ASTContext.cpp | 9 | ||||
-rw-r--r-- | lib/AST/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/AST/Decl.cpp | 44 | ||||
-rw-r--r-- | lib/AST/DeclCXX.cpp | 62 | ||||
-rw-r--r-- | lib/AST/DeclObjC.cpp | 4 | ||||
-rw-r--r-- | lib/AST/DeclSerialization.cpp | 54 | ||||
-rw-r--r-- | lib/AST/DeclarationName.cpp | 166 | ||||
-rw-r--r-- | lib/AST/StmtDumper.cpp | 16 |
8 files changed, 293 insertions, 63 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index e84cc4b307..ee57816da3 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -33,7 +33,7 @@ ASTContext::ASTContext(const LangOptions& LOpts, SourceManager &SM, 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 @@ 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); diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt index a58b3b162f..4ac6a6e98e 100644 --- a/lib/AST/CMakeLists.txt +++ b/lib/AST/CMakeLists.txt @@ -5,6 +5,7 @@ add_clang_library(clangAST 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 fa5e9ce36e..dc4d6027ee 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -133,9 +133,47 @@ FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, // 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 1de640743d..8855e99a26 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -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, diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index 0d006d676d..558156c4a0 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -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; } diff --git a/lib/AST/DeclSerialization.cpp b/lib/AST/DeclSerialization.cpp index 3df942e8f1..5137b720c5 100644 --- a/lib/AST/DeclSerialization.cpp +++ b/lib/AST/DeclSerialization.cpp @@ -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); diff --git a/lib/AST/DeclarationName.cpp b/lib/AST/DeclarationName.cpp new file mode 100644 index 0000000000..96e194be8c --- /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 0b9e62d2c5..a992efba50 100644 --- a/lib/AST/StmtDumper.cpp +++ b/lib/AST/StmtDumper.cpp @@ -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()); } } |