diff options
author | Douglas Gregor <dgregor@apple.com> | 2008-11-18 14:39:36 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2008-11-18 14:39:36 +0000 |
commit | 163c58502abf01db880cefb8a6c0b55c88142446 (patch) | |
tree | 68da1673552e303c25be80e9913ceb666eb3d6e1 /clang/lib/AST | |
parent | 383ccc1e75427d78f13ffb10698ba3f8c7b601df (diff) | |
download | bcm5719-llvm-163c58502abf01db880cefb8a6c0b55c88142446.tar.gz bcm5719-llvm-163c58502abf01db880cefb8a6c0b55c88142446.zip |
Extend DeclarationName to support C++ overloaded operators, e.g.,
operator+, directly, using the same mechanism as all other special
names.
Removed the "special" identifiers for the overloaded operators from
the identifier table and IdentifierInfo data structure. IdentifierInfo
is back to representing only real identifiers.
Added a new Action, ActOnOperatorFunctionIdExpr, that builds an
expression from an parsed operator-function-id (e.g., "operator
+"). ActOnIdentifierExpr used to do this job, but
operator-function-ids are no longer represented by IdentifierInfo's.
Extended Declarator to store overloaded operator names.
Sema::GetNameForDeclarator now knows how to turn the operator
name into a DeclarationName for the overloaded operator.
Except for (perhaps) consolidating the functionality of
ActOnIdentifier, ActOnOperatorFunctionIdExpr, and
ActOnConversionFunctionExpr into a common routine that builds an
appropriate DeclRefExpr by looking up a DeclarationName, all of the
work on normalizing declaration names should be complete with this
commit.
llvm-svn: 59526
Diffstat (limited to 'clang/lib/AST')
-rw-r--r-- | clang/lib/AST/Decl.cpp | 4 | ||||
-rw-r--r-- | clang/lib/AST/DeclSerialization.cpp | 14 | ||||
-rw-r--r-- | clang/lib/AST/DeclarationName.cpp | 66 | ||||
-rw-r--r-- | clang/lib/AST/ExprCXX.cpp | 4 |
4 files changed, 81 insertions, 7 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index eee934bebba..194f47f96c4 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -226,8 +226,8 @@ unsigned FunctionDecl::getMinRequiredArguments() const { /// getOverloadedOperator - Which C++ overloaded operator this /// function represents, if any. OverloadedOperatorKind FunctionDecl::getOverloadedOperator() const { - if (getIdentifier()) - return getIdentifier()->getOverloadedOperatorID(); + if (getDeclName().getNameKind() == DeclarationName::CXXOperatorName) + return getDeclName().getCXXOverloadedOperator(); else return OO_None; } diff --git a/clang/lib/AST/DeclSerialization.cpp b/clang/lib/AST/DeclSerialization.cpp index 5137b720c5b..8a4612b6745 100644 --- a/clang/lib/AST/DeclSerialization.cpp +++ b/clang/lib/AST/DeclSerialization.cpp @@ -147,6 +147,10 @@ void NamedDecl::EmitInRec(Serializer& S) const { case DeclarationName::CXXConversionFunctionName: Name.getCXXNameType().Emit(S); break; + + case DeclarationName::CXXOperatorName: + S.EmitInt(Name.getCXXOverloadedOperator()); + break; } } @@ -178,8 +182,16 @@ void NamedDecl::ReadInRec(Deserializer& D, ASTContext& C) { break; case DeclarationName::CXXConversionFunctionName: - Name = C.DeclarationNames.getCXXConversionFunctionName(QualType::ReadVal(D)); + Name + = C.DeclarationNames.getCXXConversionFunctionName(QualType::ReadVal(D)); break; + + case DeclarationName::CXXOperatorName: { + OverloadedOperatorKind Op + = static_cast<OverloadedOperatorKind>(D.ReadInt()); + Name = C.DeclarationNames.getCXXOperatorName(Op); + break; + } } } diff --git a/clang/lib/AST/DeclarationName.cpp b/clang/lib/AST/DeclarationName.cpp index d58016a44cc..3a9e7c84e3d 100644 --- a/clang/lib/AST/DeclarationName.cpp +++ b/clang/lib/AST/DeclarationName.cpp @@ -40,6 +40,15 @@ public: } }; +/// CXXOperatorIdName - Contains extra information for the name of an +/// overloaded operator in C++, such as "operator+. +class CXXOperatorIdName : public DeclarationNameExtra { +public: + /// FETokenInfo - Extra information associated with this operator + /// name that can be used by the front end. + void *FETokenInfo; +}; + bool operator<(DeclarationName LHS, DeclarationName RHS) { if (IdentifierInfo *LhsId = LHS.getAsIdentifierInfo()) if (IdentifierInfo *RhsId = RHS.getAsIdentifierInfo()) @@ -64,7 +73,7 @@ DeclarationName::DeclarationName(Selector Sel) { default: Ptr = Sel.InfoPtr & ~Selector::ArgFlags; - Ptr |= StoredObjCMultiArgSelectorOrCXXName; + Ptr |= StoredDeclarationNameExtra; break; } } @@ -75,7 +84,7 @@ DeclarationName::NameKind DeclarationName::getNameKind() const { case StoredObjCZeroArgSelector: return ObjCZeroArgSelector; case StoredObjCOneArgSelector: return ObjCOneArgSelector; - case StoredObjCMultiArgSelectorOrCXXName: + case StoredDeclarationNameExtra: switch (getExtra()->ExtraKindOrNumArgs) { case DeclarationNameExtra::CXXConstructor: return CXXConstructorName; @@ -87,6 +96,11 @@ DeclarationName::NameKind DeclarationName::getNameKind() const { return CXXConversionFunctionName; default: + // Check if we have one of the CXXOperator* enumeration values. + if (getExtra()->ExtraKindOrNumArgs < + DeclarationNameExtra::NUM_EXTRA_KINDS) + return CXXOperatorName; + return ObjCMultiArgSelector; } break; @@ -125,6 +139,23 @@ std::string DeclarationName::getAsString() const { return Result; } + case CXXOperatorName: { + static const char *OperatorNames[NUM_OVERLOADED_OPERATORS] = { + 0, +#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ + Spelling, +#include "clang/Basic/OperatorKinds.def" + }; + const char *OpName = OperatorNames[getCXXOverloadedOperator()]; + assert(OpName && "not an overloaded operator"); + + std::string Result = "operator"; + if (OpName[0] >= 'a' && OpName[0] <= 'z') + Result += ' '; + Result += OpName; + return Result; + } + case CXXConversionFunctionName: { std::string Result = "operator "; QualType Type = getCXXNameType(); @@ -147,6 +178,16 @@ QualType DeclarationName::getCXXNameType() const { return QualType(); } +OverloadedOperatorKind DeclarationName::getCXXOverloadedOperator() const { + if (CXXOperatorIdName *CXXOp = getAsCXXOperatorIdName()) { + unsigned value + = CXXOp->ExtraKindOrNumArgs - DeclarationNameExtra::CXXConversionFunction; + return static_cast<OverloadedOperatorKind>(value); + } else { + return OO_None; + } +} + Selector DeclarationName::getObjCSelector() const { switch (getNameKind()) { case ObjCZeroArgSelector: @@ -175,6 +216,9 @@ void *DeclarationName::getFETokenInfoAsVoid() const { case CXXConversionFunctionName: return getAsCXXSpecialName()->FETokenInfo; + case CXXOperatorName: + return getAsCXXOperatorIdName()->FETokenInfo; + default: assert(false && "Declaration name has no FETokenInfo"); } @@ -193,6 +237,10 @@ void DeclarationName::setFETokenInfo(void *T) { getAsCXXSpecialName()->FETokenInfo = T; break; + case CXXOperatorName: + getAsCXXOperatorIdName()->FETokenInfo = T; + break; + default: assert(false && "Declaration name has no FETokenInfo"); } @@ -200,10 +248,19 @@ void DeclarationName::setFETokenInfo(void *T) { DeclarationNameTable::DeclarationNameTable() { CXXSpecialNamesImpl = new llvm::FoldingSet<CXXSpecialName>; + + // Initialize the overloaded operator names. + CXXOperatorNames = new CXXOperatorIdName[NUM_OVERLOADED_OPERATORS]; + for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) { + CXXOperatorNames[Op].ExtraKindOrNumArgs + = Op + DeclarationNameExtra::CXXConversionFunction; + CXXOperatorNames[Op].FETokenInfo = 0; + } } DeclarationNameTable::~DeclarationNameTable() { delete static_cast<llvm::FoldingSet<CXXSpecialName>*>(CXXSpecialNamesImpl); + delete [] CXXOperatorNames; } DeclarationName @@ -249,3 +306,8 @@ DeclarationNameTable::getCXXSpecialName(DeclarationName::NameKind Kind, return DeclarationName(SpecialName); } +DeclarationName +DeclarationNameTable::getCXXOperatorName(OverloadedOperatorKind Op) { + return DeclarationName(&CXXOperatorNames[(unsigned)Op]); +} + diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index 22f30f451e5..1155a4b9c6b 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -90,10 +90,10 @@ OverloadedOperatorKind CXXOperatorCallExpr::getOperator() const { return OO_None; if (const FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl())) - return FDecl->getIdentifier()->getOverloadedOperatorID(); + return FDecl->getDeclName().getCXXOverloadedOperator(); else if (const OverloadedFunctionDecl *Ovl = dyn_cast<OverloadedFunctionDecl>(DRE->getDecl())) - return Ovl->getIdentifier()->getOverloadedOperatorID(); + return Ovl->getDeclName().getCXXOverloadedOperator(); else return OO_None; } |