aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2008-11-18 14:39:36 +0000
committerDouglas Gregor <dgregor@apple.com>2008-11-18 14:39:36 +0000
commite94ca9e4371c022329270436b3dd77adc4ddfa8f (patch)
tree88577be07029db31b21b7b0c8e3dbcf593dff4a4 /include
parentdb0e15ae3e2b5e180541eec35e2bce54359ca7d8 (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.h63
-rw-r--r--include/clang/Basic/IdentifierTable.h40
-rw-r--r--include/clang/Parse/Action.h15
-rw-r--r--include/clang/Parse/DeclSpec.h27
-rw-r--r--include/clang/Parse/Parser.h2
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();
};