2008-11-17 22:58:09 +08:00
|
|
|
//===-- 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:
|
2008-11-18 04:34:05 +08:00
|
|
|
/// Type - The type associated with this declaration name.
|
2008-11-17 22:58:09 +08:00
|
|
|
QualType Type;
|
|
|
|
|
2008-11-18 04:34:05 +08:00
|
|
|
/// FETokenInfo - Extra information associated with this declaration
|
|
|
|
/// name that can be used by the front end.
|
|
|
|
void *FETokenInfo;
|
|
|
|
|
2008-11-17 22:58:09 +08:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2008-11-18 04:34:05 +08:00
|
|
|
void *DeclarationName::getFETokenInfoAsVoid() const {
|
|
|
|
switch (getNameKind()) {
|
|
|
|
case Identifier:
|
|
|
|
return getAsIdentifierInfo()->getFETokenInfo<void>();
|
|
|
|
|
|
|
|
case CXXConstructorName:
|
|
|
|
case CXXDestructorName:
|
|
|
|
case CXXConversionFunctionName:
|
|
|
|
return getAsCXXSpecialName()->FETokenInfo;
|
|
|
|
|
|
|
|
default:
|
|
|
|
assert(false && "Declaration name has no FETokenInfo");
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DeclarationName::setFETokenInfo(void *T) {
|
|
|
|
switch (getNameKind()) {
|
|
|
|
case Identifier:
|
|
|
|
getAsIdentifierInfo()->setFETokenInfo(T);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case CXXConstructorName:
|
|
|
|
case CXXDestructorName:
|
|
|
|
case CXXConversionFunctionName:
|
|
|
|
getAsCXXSpecialName()->FETokenInfo = T;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
assert(false && "Declaration name has no FETokenInfo");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-11-17 22:58:09 +08:00
|
|
|
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;
|
2008-11-18 04:34:05 +08:00
|
|
|
SpecialName->FETokenInfo = 0;
|
2008-11-17 22:58:09 +08:00
|
|
|
|
|
|
|
SpecialNames->InsertNode(SpecialName, InsertPos);
|
|
|
|
return DeclarationName(SpecialName);
|
|
|
|
}
|
|
|
|
|