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 | e94ca9e4371c022329270436b3dd77adc4ddfa8f (patch) | |
tree | 88577be07029db31b21b7b0c8e3dbcf593dff4a4 /include | |
parent | db0e15ae3e2b5e180541eec35e2bce54359ca7d8 (diff) |
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.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@59526 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r-- | include/clang/AST/DeclarationName.h | 63 | ||||
-rw-r--r-- | include/clang/Basic/IdentifierTable.h | 40 | ||||
-rw-r--r-- | include/clang/Parse/Action.h | 15 | ||||
-rw-r--r-- | include/clang/Parse/DeclSpec.h | 27 | ||||
-rw-r--r-- | include/clang/Parse/Parser.h | 2 |
5 files changed, 94 insertions, 53 deletions
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h index 877d23566b..4c7a17096e 100644 --- a/include/clang/AST/DeclarationName.h +++ b/include/clang/AST/DeclarationName.h @@ -23,6 +23,7 @@ namespace llvm { namespace clang { class CXXSpecialName; // a private class used by DeclarationName + class CXXOperatorIdName; // 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 @@ -43,7 +44,8 @@ public: ObjCMultiArgSelector, CXXConstructorName, CXXDestructorName, - CXXConversionFunctionName + CXXConversionFunctionName, + CXXOperatorName }; private: @@ -53,7 +55,7 @@ private: StoredIdentifier = 0, StoredObjCZeroArgSelector, StoredObjCOneArgSelector, - StoredObjCMultiArgSelectorOrCXXName, + StoredDeclarationNameExtra, PtrMask = 0x03 }; @@ -62,22 +64,21 @@ private: /// 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. + /// StoredIdentifier - 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. + /// StoredObjCZeroArgSelector - 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. + /// StoredObjCOneArgSelector - 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. + /// StoredDeclarationNameExtra - Ptr is actually a pointer to a + /// DeclarationNameExtra structure, whose first value will tell us + /// whether this is an Objective-C selector, C++ operator-id name, + /// or special C++ name. uintptr_t Ptr; /// getStoredNameKind - Return the kind of object that is stored in @@ -89,7 +90,7 @@ private: /// getExtra - Get the "extra" information associated with this /// multi-argument selector or C++ special name. DeclarationNameExtra *getExtra() const { - assert(getStoredNameKind() == StoredObjCMultiArgSelectorOrCXXName && + assert(getStoredNameKind() == StoredDeclarationNameExtra && "Declaration name does not store an Extra structure"); return reinterpret_cast<DeclarationNameExtra *>(Ptr & ~PtrMask); } @@ -105,12 +106,28 @@ private: return 0; } + /// getAsCXXOperatorIdName + CXXOperatorIdName *getAsCXXOperatorIdName() const { + if (getNameKind() == CXXOperatorName) + return reinterpret_cast<CXXOperatorIdName *>(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; + Ptr |= StoredDeclarationNameExtra; + } + + // Construct a declaration name from the name of a C++ overloaded + // operator. + DeclarationName(CXXOperatorIdName *Name) + : Ptr(reinterpret_cast<uintptr_t>(Name)) { + assert((Ptr & PtrMask) == 0 && "Improperly aligned CXXOperatorId"); + Ptr |= StoredDeclarationNameExtra; } // Construct a declaration name from a zero- or one-argument @@ -130,7 +147,7 @@ private: DeclarationName(MultiKeywordSelector *SI) : Ptr(reinterpret_cast<uintptr_t>(SI)) { assert((Ptr & PtrMask) == 0 && "Improperly aligned MultiKeywordSelector"); - Ptr |= StoredObjCMultiArgSelectorOrCXXName; + Ptr |= StoredDeclarationNameExtra; } /// Construct a declaration name from a raw pointer. @@ -186,6 +203,11 @@ public: /// type associated with that name. QualType getCXXNameType() const; + /// getCXXOverloadedOperator - If this name is the name of an + /// overloadable operator in C++ (e.g., @c operator+), retrieve the + /// kind of overloaded operator. + OverloadedOperatorKind getCXXOverloadedOperator() const; + /// getObjCSelector - Get the Objective-C selector stored in this /// declaration name. Selector getObjCSelector() const; @@ -248,6 +270,7 @@ inline bool operator>=(DeclarationName LHS, DeclarationName RHS) { /// getCXXConstructorName). class DeclarationNameTable { void *CXXSpecialNamesImpl; // Actually a FoldingSet<CXXSpecialName> * + CXXOperatorIdName *CXXOperatorNames; // Operator names DeclarationNameTable(const DeclarationNameTable&); // NONCOPYABLE DeclarationNameTable& operator=(const DeclarationNameTable&); // NONCOPYABLE @@ -285,6 +308,10 @@ public: /// function. DeclarationName getCXXSpecialName(DeclarationName::NameKind Kind, QualType Ty); + + /// getCXXOperatorName - Get the name of the overloadable C++ + /// operator corresponding to Op. + DeclarationName getCXXOperatorName(OverloadedOperatorKind Op); }; } // end namespace clang diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h index 58ad133e3b..cbd27547ac 100644 --- a/include/clang/Basic/IdentifierTable.h +++ b/include/clang/Basic/IdentifierTable.h @@ -51,12 +51,11 @@ class IdentifierInfo { // First NUM_OBJC_KEYWORDS values are for Objective-C, the remaining values // are for builtins. unsigned ObjCOrBuiltinID :10; - unsigned OperatorID : 6; // C++ overloaded operator. bool HasMacro : 1; // True if there is a #define for this. bool IsExtension : 1; // True if identifier is a lang extension. bool IsPoisoned : 1; // True if identifier is poisoned. bool IsCPPOperatorKeyword : 1; // True if ident is a C++ operator keyword. - // 4 bits left in 32-bit word. + // 10 bits left in 32-bit word. void *FETokenInfo; // Managed by the language front-end. IdentifierInfo(const IdentifierInfo&); // NONCOPYABLE. void operator=(const IdentifierInfo&); // NONASSIGNABLE. @@ -123,16 +122,6 @@ public: && "ID too large for field!"); } - /// getOverloadedOperatorID - Get the C++ overloaded operator that - /// corresponds to this identifier. - OverloadedOperatorKind getOverloadedOperatorID() const { - return OverloadedOperatorKind(OperatorID); - } - void setOverloadedOperatorID(OverloadedOperatorKind ID) { - OperatorID = ID; - assert(OperatorID == (unsigned)ID && "ID too large for field!"); - } - /// get/setExtension - Initialize information about whether or not this /// language token is an extension. This controls extension warnings, and is /// only valid if a custom token ID is set. @@ -175,10 +164,6 @@ class IdentifierTable { typedef llvm::StringMap<IdentifierInfo, llvm::BumpPtrAllocator> HashTableTy; HashTableTy HashTable; - /// OverloadedOperators - Identifiers corresponding to each of the - /// overloadable operators in C++. - IdentifierInfo *OverloadedOperators[NUM_OVERLOADED_OPERATORS]; - public: /// IdentifierTable ctor - Create the identifier table, populating it with /// info about the language keywords for the language specified by LangOpts. @@ -199,11 +184,6 @@ public: return get(NameBytes, NameBytes+Name.size()); } - /// getOverloadedOperator - Retrieve the identifier - IdentifierInfo &getOverloadedOperator(OverloadedOperatorKind Op) { - return *OverloadedOperators[Op]; - } - typedef HashTableTy::const_iterator iterator; typedef HashTableTy::const_iterator const_iterator; @@ -217,7 +197,6 @@ public: void PrintStats() const; void AddKeywords(const LangOptions &LangOpts); - void AddOverloadedOperators(); /// Emit - Serialize this IdentifierTable to a bitstream. This should /// be called AFTER objects that externally reference the identifiers in the @@ -342,9 +321,9 @@ 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. +/// DeclarationNameExtra - Common base of the MultiKeywordSelector, +/// CXXSpecialName, and CXXOperatorIdName classes, all of which are +/// private classes that describe different kinds of names. class DeclarationNameExtra { public: /// ExtraKind - The kind of "extra" information stored in the @@ -354,12 +333,17 @@ public: CXXConstructor = 0, CXXDestructor, CXXConversionFunction, +#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ + CXXOperator##Name, +#include "clang/Basic/OperatorKinds.def" 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 + /// ExtraKindOrNumArgs - Either the kind of C++ special name or + /// operator-id (if the value is one of the CXX* enumerators of + /// ExtraKind), in which case the DeclarationNameExtra is also a + /// CXXSpecialName (for CXXConstructor, CXXDestructor, or + /// CXXConversionFunction) or CXXOperatorIdName, otherwise it is /// 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. diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index 215893e2e6..8e1a23f6e7 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -463,9 +463,22 @@ public: const CXXScopeSpec *SS = 0) { return 0; } + + /// ActOnOperatorFunctionIdExpr - Parse a C++ overloaded operator + /// name (e.g., @c operator+ ) as an expression. This is very + /// similar to ActOnIdentifierExpr, except that instead of providing + /// an identifier the parser provides the kind of overloaded + /// operator that was parsed. + virtual ExprResult ActOnOperatorFunctionIdExpr(Scope *S, + SourceLocation OperatorLoc, + OverloadedOperatorKind Op, + bool HasTrailingLParen, + const CXXScopeSpec *SS = 0) { + return 0; + } /// ActOnConversionFunctionExpr - Parse a C++ conversion function - /// name (e.g., operator void const *) as an expression. This is + /// name (e.g., @c operator void const *) as an expression. This is /// very similar to ActOnIdentifierExpr, except that instead of /// providing an identifier the parser provides the type of the /// conversion function. diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h index 46629637bc..4ec9c55012 100644 --- a/include/clang/Parse/DeclSpec.h +++ b/include/clang/Parse/DeclSpec.h @@ -647,6 +647,7 @@ public: DK_Normal, // A normal declarator (has an identifier). DK_Constructor, // A C++ constructor (identifier is the class name) DK_Destructor, // A C++ destructor (identifier is ~class name) + DK_Operator, // A C++ overloaded operator name DK_Conversion // A C++ conversion function (identifier is // "operator " then the type name) }; @@ -677,10 +678,16 @@ private: /// AsmLabel - The asm label, if specified. Action::ExprTy *AsmLabel; - // When Kind is DK_Constructor, DK_Destructor, or DK_Conversion, the - // type associated with the constructor, destructor, or conversion - // operator. - Action::TypeTy *Type; + union { + // When Kind is DK_Constructor, DK_Destructor, or DK_Conversion, the + // type associated with the constructor, destructor, or conversion + // operator. + Action::TypeTy *Type; + + /// When Kind is DK_Operator, this is the actual overloaded + /// operator that this declarator names. + OverloadedOperatorKind OperatorKind; + }; public: Declarator(const DeclSpec &ds, TheContext C) @@ -802,7 +809,7 @@ public: } // setConversionFunction - Set this declarator to be a C++ - // conversion function declarator. + // conversion function declarator (e.g., @c operator int const *). void setConversionFunction(Action::TypeTy *Ty, SourceLocation Loc) { Identifier = 0; IdentifierLoc = Loc; @@ -810,6 +817,14 @@ public: Type = Ty; } + // setOverloadedOperator - Set this declaration to be a C++ + // overloaded operator declarator (e.g., @c operator+). + void setOverloadedOperator(OverloadedOperatorKind Op, SourceLocation Loc) { + IdentifierLoc = Loc; + Kind = DK_Operator; + OperatorKind = Op; + } + void AddTypeInfo(const DeclaratorChunk &TI) { DeclTypeInfo.push_back(TI); } @@ -859,6 +874,8 @@ public: Action::TypeTy *getDeclaratorIdType() const { return Type; } + OverloadedOperatorKind getOverloadedOperator() const { return OperatorKind; } + void setInvalidType(bool flag) { InvalidType = flag; } bool getInvalidType() const { return InvalidType; } diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 3beb36c7af..ad6244fe4c 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -789,7 +789,7 @@ private: //===--------------------------------------------------------------------===// // C++ 13.5: Overloaded operators [over.oper] - IdentifierInfo *TryParseOperatorFunctionId(); + OverloadedOperatorKind TryParseOperatorFunctionId(); TypeTy *ParseConversionFunctionId(); }; |