summaryrefslogtreecommitdiffstats
path: root/clang/include
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2008-11-07 20:08:42 +0000
committerDouglas Gregor <dgregor@apple.com>2008-11-07 20:08:42 +0000
commitdbc5daf05882c1c1934b35d5899b6ca53ce4cff9 (patch)
treeaf766082edf0c17460eb8950a94a9b87000fec02 /clang/include
parentcb0df597e0f7f43b14cbed1f9dd1f39b22fe08be (diff)
downloadbcm5719-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.h3
-rw-r--r--clang/include/clang/AST/DeclCXX.h83
-rw-r--r--clang/include/clang/Basic/DiagnosticKinds.def25
-rw-r--r--clang/include/clang/Parse/Action.h15
-rw-r--r--clang/include/clang/Parse/DeclSpec.h19
-rw-r--r--clang/include/clang/Parse/Parser.h5
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
OpenPOWER on IntegriCloud