diff options
| author | Douglas Gregor <dgregor@apple.com> | 2008-11-07 20:08:42 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2008-11-07 20:08:42 +0000 |
| commit | dbc5daf05882c1c1934b35d5899b6ca53ce4cff9 (patch) | |
| tree | af766082edf0c17460eb8950a94a9b87000fec02 /clang/include | |
| parent | cb0df597e0f7f43b14cbed1f9dd1f39b22fe08be (diff) | |
| download | bcm5719-llvm-dbc5daf05882c1c1934b35d5899b6ca53ce4cff9.tar.gz bcm5719-llvm-dbc5daf05882c1c1934b35d5899b6ca53ce4cff9.zip | |
Parsing, ASTs, and semantic analysis for the declaration of conversion
functions in C++, e.g.,
struct X {
operator bool() const;
};
Note that these conversions don't actually do anything, since we don't
yet have the ability to use them for implicit or explicit conversions.
llvm-svn: 58860
Diffstat (limited to 'clang/include')
| -rw-r--r-- | clang/include/clang/AST/DeclBase.h | 3 | ||||
| -rw-r--r-- | clang/include/clang/AST/DeclCXX.h | 83 | ||||
| -rw-r--r-- | clang/include/clang/Basic/DiagnosticKinds.def | 25 | ||||
| -rw-r--r-- | clang/include/clang/Parse/Action.h | 15 | ||||
| -rw-r--r-- | clang/include/clang/Parse/DeclSpec.h | 19 | ||||
| -rw-r--r-- | clang/include/clang/Parse/Parser.h | 5 |
6 files changed, 138 insertions, 12 deletions
diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 5a07c48d4ab..c44515eaa46 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -68,6 +68,7 @@ public: CXXMethod, CXXConstructor, CXXDestructor, + CXXConversion, Var, ImplicitParam, CXXClassVar, @@ -91,7 +92,7 @@ public: TagFirst = Enum , TagLast = CXXRecord, RecordFirst = Record , RecordLast = CXXRecord, ValueFirst = EnumConstant , ValueLast = ParmVar, - FunctionFirst = Function , FunctionLast = CXXDestructor, + FunctionFirst = Function , FunctionLast = CXXConversion, VarFirst = Var , VarLast = ParmVar }; diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index 7be7197080c..0c230e76754 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -21,6 +21,7 @@ namespace clang { class CXXRecordDecl; class CXXConstructorDecl; class CXXDestructorDecl; +class CXXConversionDecl; /// OverloadedFunctionDecl - An instance of this class represents a /// set of overloaded functions. All of the functions have the same @@ -53,8 +54,9 @@ public: void addOverload(FunctionDecl *FD) { assert((!getNumFunctions() || (FD->getDeclContext() == getDeclContext())) && "Overloaded functions must all be in the same context"); - assert(FD->getIdentifier() == getIdentifier() && - "Overloaded functions must have the same name."); + assert((FD->getIdentifier() == getIdentifier() || + isa<CXXConversionDecl>(FD)) && + "Overloaded functions must have the same name or be conversions."); Functions.push_back(FD); } @@ -238,12 +240,18 @@ class CXXRecordDecl : public RecordDecl, public DeclContext { // Destructor - The destructor of this C++ class. CXXDestructorDecl *Destructor; + /// Conversions - Overload set containing the conversion functions + /// of this C++ class (but not its inherited conversion + /// functions). Each of the entries in this overload set is a + /// CXXConversionDecl. + OverloadedFunctionDecl Conversions; + 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, Id), Destructor(0) { } + Constructors(DC, Id), Destructor(0), Conversions(DC, Id) { } ~CXXRecordDecl(); @@ -321,6 +329,19 @@ public: this->Destructor = Destructor; } + /// getConversions - Retrieve the overload set containing all of the + /// conversion functions in this class. + OverloadedFunctionDecl *getConversionFunctions() { + return &Conversions; + } + const OverloadedFunctionDecl *getConversionFunctions() const { + return &Conversions; + } + + /// addConversionFunction - Add a new conversion function to the + /// list of conversion functions. + void addConversionFunction(ASTContext &Context, CXXConversionDecl *ConvDecl); + /// isAggregate - Whether this class is an aggregate (C++ /// [dcl.init.aggr]), which is a class with no user-declared /// constructors, no private or protected non-static data members, @@ -418,7 +439,7 @@ public: // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { - return D->getKind() >= CXXMethod && D->getKind() <= CXXConstructor; + return D->getKind() >= CXXMethod && D->getKind() <= CXXConversion; } static bool classof(const CXXMethodDecl *D) { return true; } @@ -720,6 +741,60 @@ public: static CXXDestructorDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C); }; +/// CXXConversionDecl - Represents a C++ conversion function within a +/// class. For example: +/// +/// @code +/// class X { +/// public: +/// operator bool(); +/// }; +/// @endcode +class CXXConversionDecl : public CXXMethodDecl { + /// Explicit - Whether this conversion function is marked + /// "explicit", meaning that it can only be applied when the user + /// explicitly wrote a cast. This is a C++0x feature. + bool Explicit : 1; + + CXXConversionDecl(CXXRecordDecl *RD, SourceLocation L, + IdentifierInfo *Id, QualType T, + bool isInline, bool isExplicit) + : CXXMethodDecl(CXXConversion, RD, L, Id, T, false, isInline, + /*PrevDecl=*/0), + Explicit(isExplicit) { } + +public: + static CXXConversionDecl *Create(ASTContext &C, CXXRecordDecl *RD, + SourceLocation L, IdentifierInfo *Id, + QualType T, bool isInline, + bool isExplicit); + + /// isExplicit - Whether this is an explicit conversion operator + /// (C++0x only). Explicit conversion operators are only considered + /// when the user has explicitly written a cast. + bool isExplicit() const { return Explicit; } + + /// getConversionType - Returns the type that this conversion + /// function is converting to. + QualType getConversionType() const { + return getType()->getAsFunctionType()->getResultType(); + } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { + return D->getKind() == CXXConversion; + } + static bool classof(const CXXConversionDecl *D) { return true; } + + /// EmitImpl - Serialize this CXXConversionDecl. Called by Decl::Emit. + // FIXME: Implement this. + //virtual void EmitImpl(llvm::Serializer& S) const; + + /// CreateImpl - Deserialize a CXXConversionDecl. Called by Decl::Create. + // FIXME: Implement this. + static CXXConversionDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C); +}; + /// CXXClassVarDecl - Represents a static data member of a struct/union/class. class CXXClassVarDecl : public VarDecl { diff --git a/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def index 64afc4683f6..b3b6e81f9f1 100644 --- a/clang/include/clang/Basic/DiagnosticKinds.def +++ b/clang/include/clang/Basic/DiagnosticKinds.def @@ -1309,6 +1309,31 @@ DIAG(err_operator_overload_must_be_member, ERROR, "overloaded operator '%0' must be a non-static member function") DIAG(err_operator_overload_post_incdec_must_be_int, ERROR, "%0parameter of overloaded post-%1 operator must have type 'int' (not '%2')") +DIAG(err_operator_missing_type_specifier, ERROR, + "missing type specifier after 'operator'") + +// C++ conversion functions +DIAG(err_conv_function_not_member, ERROR, + "conversion function must be a non-static member function") +DIAG(err_conv_function_return_type, ERROR, + "conversion function cannot have a return type") +DIAG(err_conv_function_with_params, ERROR, + "conversion function cannot have any parameters") +DIAG(err_conv_function_variadic, ERROR, + "conversion function cannot be variadic") +DIAG(err_conv_function_to_array, ERROR, + "conversion function cannot convert to an array type") +DIAG(err_conv_function_to_function, ERROR, + "conversion function cannot convert to a function type") +DIAG(err_conv_function_redeclared, ERROR, + "conversion function cannot be redeclared") +DIAG(warn_conv_to_self_not_used, WARNING, + "conversion function converting '%0' to itself will never be used") +DIAG(warn_conv_to_base_not_used, WARNING, + "conversion function converting '%0' to its base class '%1' will never be used") +DIAG(warn_conv_to_void_not_used, WARNING, + "conversion function converting '%0' to '%1' will never be used") + DIAG(warn_not_compound_assign, WARNING, "use of unary operator that may be intended as compound assignment (%0=)") diff --git a/clang/include/clang/Parse/Action.h b/clang/include/clang/Parse/Action.h index 423150ff76c..698feff0b94 100644 --- a/clang/include/clang/Parse/Action.h +++ b/clang/include/clang/Parse/Action.h @@ -42,9 +42,10 @@ namespace clang { /// the parser has just done or is about to do when the method is called. They /// are not requests that the actions module do the specified action. /// -/// All of the methods here are optional except isTypeName(), which must be -/// specified in order for the parse to complete accurately. The MinimalAction -/// class does this bare-minimum of tracking to implement this functionality. +/// All of the methods here are optional except isTypeName() and +/// isCurrentClassName(), which must be specified in order for the +/// parse to complete accurately. The MinimalAction class does this +/// bare-minimum of tracking to implement this functionality. class Action { public: /// Out-of-line virtual destructor to provide home for this class. @@ -108,6 +109,14 @@ public: /// name of the innermost C++ class type currently being defined. virtual bool isCurrentClassName(const IdentifierInfo &II, Scope *S) = 0; + /// getTypeAsString - Returns a string that describes the given + /// type. This callback is used in C++ to form identifiers for + /// special declarations that otherwise don't have simple names, + /// such as constructors, destructors, and conversion functions. + virtual std::string getTypeAsString(TypeTy *Type) { + return "<unknown type>"; + } + /// ActOnDeclarator - This callback is invoked when a declarator is parsed and /// 'Init' specifies the initializer if any. This is for things like: /// "int X = 4" or "typedef int foo". diff --git a/clang/include/clang/Parse/DeclSpec.h b/clang/include/clang/Parse/DeclSpec.h index fab6ec3c34f..76e3e7ba892 100644 --- a/clang/include/clang/Parse/DeclSpec.h +++ b/clang/include/clang/Parse/DeclSpec.h @@ -610,7 +610,9 @@ public: DK_Abstract, // An abstract declarator (has no identifier) DK_Normal, // A normal declarator (has an identifier). DK_Constructor, // A C++ constructor (identifier is the class name) - DK_Destructor // A C++ destructor (has no identifier) + DK_Destructor, // A C++ destructor (identifier is ~class name) + DK_Conversion // A C++ conversion function (identifier is + // "operator " then the type name) }; private: @@ -639,8 +641,9 @@ private: /// AsmLabel - The asm label, if specified. Action::ExprTy *AsmLabel; - // When Kind is DK_Constructor or DK_Destructor, the type associated - // with the constructor or destructor. + // When Kind is DK_Constructor, DK_Destructor, or DK_Conversion, the + // type associated with the constructor, destructor, or conversion + // operator. Action::TypeTy *Type; public: @@ -755,6 +758,16 @@ public: Type = Ty; } + // SetConversionFunction - Set this declarator to be a C++ + // conversion function declarator. + void SetConversionFunction(Action::TypeTy *Ty, IdentifierInfo *ID, + SourceLocation Loc) { + Identifier = ID; + IdentifierLoc = Loc; + Kind = DK_Conversion; + Type = Ty; + } + void AddTypeInfo(const DeclaratorChunk &TI) { DeclTypeInfo.push_back(TI); } diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index f46d901cdb4..f9b233ca0eb 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -475,6 +475,8 @@ private: /// simple-type-specifier. void ParseCXXSimpleTypeSpecifier(DeclSpec &DS); + bool ParseCXXTypeSpecifierSeq(DeclSpec &DS); + //===--------------------------------------------------------------------===// // C++ if/switch/while/for condition expression. ExprResult ParseCXXCondition(); @@ -701,7 +703,7 @@ private: /// ParseDeclarator - Parse and verify a newly-initialized declarator. void ParseDeclarator(Declarator &D); - void ParseDeclaratorInternal(Declarator &D); + void ParseDeclaratorInternal(Declarator &D, bool PtrOperator = false); void ParseTypeQualifierListOpt(DeclSpec &DS); void ParseDirectDeclarator(Declarator &D); void ParseParenDeclarator(Declarator &D); @@ -737,6 +739,7 @@ private: //===--------------------------------------------------------------------===// // C++ 13.5: Overloaded operators [over.oper] IdentifierInfo *MaybeParseOperatorFunctionId(); + TypeTy *ParseConversionFunctionId(); }; } // end namespace clang |

