[cfe-commits] r85930 - in /cfe/trunk: include/clang/Basic/DiagnosticParseKinds.td include/clang/Basic/DiagnosticSemaKinds.td include/clang/Parse/Action.h include/clang/Parse/Parser.h lib/Parse/ParseDecl.cpp lib/Parse/ParseExpr.cpp lib/Parse/ParseExprCXX.cpp lib/Sema/Sema.h lib/Sema/SemaExpr.cpp lib/Sema/SemaExprCXX.cpp lib/Sema/SemaTemplate.cpp lib/Sema/TreeTransform.h test/SemaCXX/invalid-member-expr.cpp
Douglas Gregor
dgregor at apple.com
Tue Nov 3 11:44:04 PST 2009
Author: dgregor
Date: Tue Nov 3 13:44:04 2009
New Revision: 85930
URL: http://llvm.org/viewvc/llvm-project?rev=85930&view=rev
Log:
Replace the code that parses member access expressions after "." or
"->" with a use of ParseUnqualifiedId. Collapse
ActOnMemberReferenceExpr, ActOnDestructorReferenceExpr (both of them),
ActOnOverloadedOperatorReferenceExpr,
ActOnConversionOperatorReferenceExpr, and
ActOnMemberTemplateIdReferenceExpr into a single, new action
ActOnMemberAccessExpr that does the same thing more cleanly (and can
keep more source-location information).
Modified:
cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Parse/Action.h
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseExpr.cpp
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/lib/Sema/TreeTransform.h
cfe/trunk/test/SemaCXX/invalid-member-expr.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=85930&r1=85929&r2=85930&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Tue Nov 3 13:44:04 2009
@@ -216,7 +216,8 @@
def err_no_matching_param : Error<"parameter named %0 is missing">;
/// C++ parser diagnostics
-def err_expected_unqualified_id : Error<"expected unqualified-id">;
+def err_expected_unqualified_id : Error<
+ "expected %select{identifier|unqualified-id}0">;
def err_func_def_no_params : Error<
"function definition does not declare parameters">;
def err_expected_lparen_after_type : Error<
@@ -233,6 +234,8 @@
def err_expected_lbrace_or_comma : Error<"expected '{' or ','">;
def err_using_namespace_in_class : Error<
"'using namespace' in class not allowed">;
+def err_ident_in_pseudo_dtor_not_a_type : Error<
+ "identifier %0 in pseudo-destructor expression does not name a type">;
// C++ derived classes
def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">;
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=85930&r1=85929&r2=85930&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Nov 3 13:44:04 2009
@@ -1725,8 +1725,6 @@
def err_return_in_constructor_handler : Error<
"return in the catch of a function try block of a constructor is illegal">;
-def err_ident_in_pseudo_dtor_not_a_type : Error<
- "identifier %0 in pseudo-destructor expression does not name a type">;
def err_operator_arrow_circular : Error<
"circular pointer delegation detected">;
def err_pseudo_dtor_base_not_scalar : Error<
Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=85930&r1=85929&r2=85930&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Tue Nov 3 13:44:04 2009
@@ -922,16 +922,42 @@
SourceLocation RLoc) {
return ExprEmpty();
}
- virtual OwningExprResult ActOnMemberReferenceExpr(Scope *S, ExprArg Base,
- SourceLocation OpLoc,
- tok::TokenKind OpKind,
- SourceLocation MemberLoc,
- IdentifierInfo &Member,
- DeclPtrTy ObjCImpDecl,
- const CXXScopeSpec *SS = 0) {
+
+ /// \brief Parsed a member access expresion (C99 6.5.2.3, C++ [expr.ref])
+ /// of the form \c x.m or \c p->m.
+ ///
+ /// \param S the scope in which the member access expression occurs.
+ ///
+ /// \param Base the class or pointer to class into which this member
+ /// access expression refers, e.g., \c x in \c x.m.
+ ///
+ /// \param OpLoc the location of the "." or "->" operator.
+ ///
+ /// \param OpKind the kind of member access operator, which will be either
+ /// tok::arrow ("->") or tok::period (".").
+ ///
+ /// \param SS in C++, the nested-name-specifier that precedes the member
+ /// name, if any.
+ ///
+ /// \param Member the name of the member that we are referring to. In C,
+ /// this will always store an identifier; in C++, we may also have operator
+ /// names, conversion function names, destructors, and template names.
+ ///
+ /// \param ObjCImpDecl the Objective-C implementation declaration.
+ /// FIXME: Do we really need this?
+ ///
+ /// \param HasTrailingLParen whether this member name is immediately followed
+ /// by a left parentheses ('(').
+ virtual OwningExprResult ActOnMemberAccessExpr(Scope *S, ExprArg Base,
+ SourceLocation OpLoc,
+ tok::TokenKind OpKind,
+ const CXXScopeSpec &SS,
+ UnqualifiedId &Member,
+ DeclPtrTy ObjCImpDecl,
+ bool HasTrailingLParen) {
return ExprEmpty();
}
-
+
/// ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
/// This provides the location of the left/right parens and a list of comma
/// locations. There are guaranteed to be one fewer commas than arguments,
@@ -1361,123 +1387,6 @@
return ExprEmpty();
}
- /// ActOnDestructorReferenceExpr - Parsed a destructor reference, for example:
- ///
- /// t->~T();
- virtual OwningExprResult
- ActOnDestructorReferenceExpr(Scope *S, ExprArg Base,
- SourceLocation OpLoc,
- tok::TokenKind OpKind,
- SourceLocation ClassNameLoc,
- IdentifierInfo *ClassName,
- const CXXScopeSpec &SS,
- bool HasTrailingLParen) {
- return ExprEmpty();
- }
-
- /// \brief Parsed a C++ destructor reference that refers to a type.
- ///
- /// This action is used when parsing a destructor reference that uses a
- /// template-id, e.g.,
- ///
- /// \code
- /// t->~Tmpl<T1, T2>
- /// \endcode
- ///
- /// \param S the scope in which the destructor reference occurs.
- /// \param Base the base object of the destructor reference expression.
- /// \param OpLoc the location of the operator ('.' or '->').
- /// \param OpKind the kind of the destructor reference operator ('.' or '->').
- /// \param TypeRange the source range that covers the destructor type.
- /// \param Type the type that is being destroyed.
- /// \param SS the scope specifier that precedes the destructor name.
- /// \param HasTrailingLParen whether the destructor name is followed by a '('.
- virtual OwningExprResult
- ActOnDestructorReferenceExpr(Scope *S, ExprArg Base,
- SourceLocation OpLoc,
- tok::TokenKind OpKind,
- SourceRange TypeRange,
- TypeTy *Type,
- const CXXScopeSpec &SS,
- bool HasTrailingLParen) {
- return ExprEmpty();
- }
-
- /// ActOnOverloadedOperatorReferenceExpr - Parsed an overloaded operator
- /// reference, for example:
- ///
- /// t.operator++();
- virtual OwningExprResult
- ActOnOverloadedOperatorReferenceExpr(Scope *S, ExprArg Base,
- SourceLocation OpLoc,
- tok::TokenKind OpKind,
- SourceLocation ClassNameLoc,
- OverloadedOperatorKind OverOpKind,
- const CXXScopeSpec *SS = 0) {
- return ExprEmpty();
- }
-
- /// ActOnConversionOperatorReferenceExpr - Parsed an overloaded conversion
- /// function reference, for example:
- ///
- /// t.operator int();
- virtual OwningExprResult
- ActOnConversionOperatorReferenceExpr(Scope *S, ExprArg Base,
- SourceLocation OpLoc,
- tok::TokenKind OpKind,
- SourceLocation ClassNameLoc,
- TypeTy *Ty,
- const CXXScopeSpec *SS = 0) {
- return ExprEmpty();
- }
-
- /// \brief Parsed a reference to a member template-id.
- ///
- /// This callback will occur instead of ActOnMemberReferenceExpr() when the
- /// member in question is a template for which the code provides an
- /// explicitly-specified template argument list, e.g.,
- ///
- /// \code
- /// x.f<int>()
- /// \endcode
- ///
- /// \param S the scope in which the member reference expression occurs
- ///
- /// \param Base the expression to the left of the "." or "->".
- ///
- /// \param OpLoc the location of the "." or "->".
- ///
- /// \param OpKind the kind of operator, which will be "." or "->".
- ///
- /// \param SS the scope specifier that precedes the template-id in, e.g.,
- /// \c x.Base::f<int>().
- ///
- /// \param Template the declaration of the template that is being referenced.
- ///
- /// \param TemplateNameLoc the location of the template name referred to by
- /// \p Template.
- ///
- /// \param LAngleLoc the location of the left angle bracket ('<')
- ///
- /// \param TemplateArgs the (possibly-empty) template argument list provided
- /// as part of the member reference.
- ///
- /// \param RAngleLoc the location of the right angle bracket ('>')
- virtual OwningExprResult
- ActOnMemberTemplateIdReferenceExpr(Scope *S, ExprArg Base,
- SourceLocation OpLoc,
- tok::TokenKind OpKind,
- const CXXScopeSpec &SS,
- // FIXME: "template" keyword?
- TemplateTy Template,
- SourceLocation TemplateNameLoc,
- SourceLocation LAngleLoc,
- ASTTemplateArgsPtr TemplateArgs,
- SourceLocation *TemplateArgLocs,
- SourceLocation RAngleLoc) {
- return ExprEmpty();
- }
-
/// ActOnFinishFullExpr - Called whenever a full expression has been parsed.
/// (C++ [intro.execution]p12).
virtual OwningExprResult ActOnFinishFullExpr(ExprArg Expr) {
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=85930&r1=85929&r2=85930&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Tue Nov 3 13:44:04 2009
@@ -1216,10 +1216,12 @@
IdentifierInfo *Name,
SourceLocation NameLoc,
bool EnteringContext,
+ TypeTy *ObjectType,
UnqualifiedId &Id);
bool ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
bool AllowDestructorName,
bool AllowConstructorName,
+ TypeTy *ObjectType,
UnqualifiedId &Result);
//===--------------------------------------------------------------------===//
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=85930&r1=85929&r2=85930&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Tue Nov 3 13:44:04 2009
@@ -2314,6 +2314,7 @@
/*EnteringContext=*/true,
/*AllowDestructorName=*/true,
/*AllowConstructorName=*/!D.getDeclSpec().hasTypeSpecifier(),
+ /*ObjectType=*/0,
D.getName())) {
D.SetIdentifier(0, Tok.getLocation());
D.setInvalidType(true);
@@ -2348,7 +2349,7 @@
Diag(Tok, diag::err_expected_member_name_or_semi)
<< D.getDeclSpec().getSourceRange();
else if (getLang().CPlusPlus)
- Diag(Tok, diag::err_expected_unqualified_id);
+ Diag(Tok, diag::err_expected_unqualified_id) << getLang().CPlusPlus;
else
Diag(Tok, diag::err_expected_ident_lparen);
D.SetIdentifier(0, Tok.getLocation());
Modified: cfe/trunk/lib/Parse/ParseExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExpr.cpp?rev=85930&r1=85929&r2=85930&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExpr.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExpr.cpp Tue Nov 3 13:44:04 2009
@@ -968,6 +968,21 @@
ConsumeToken();
}
+ UnqualifiedId Name;
+ if (ParseUnqualifiedId(SS,
+ /*EnteringContext=*/false,
+ /*AllowDestructorName=*/true,
+ /*AllowConstructorName=*/false,
+ ObjectType,
+ Name))
+ return ExprError();
+
+ if (!LHS.isInvalid())
+ LHS = Actions.ActOnMemberAccessExpr(CurScope, move(LHS), OpLoc, OpKind,
+ SS, Name, ObjCImpDecl,
+ Tok.is(tok::l_paren));
+
+#if 0
if (Tok.is(tok::identifier)) {
if (!LHS.isInvalid())
LHS = Actions.ActOnMemberReferenceExpr(CurScope, move(LHS), OpLoc,
@@ -1072,6 +1087,7 @@
Diag(Tok, diag::err_expected_ident);
return ExprError();
}
+#endif
break;
}
case tok::plusplus: // postfix-expression: postfix-expression '++'
Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=85930&r1=85929&r2=85930&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Tue Nov 3 13:44:04 2009
@@ -315,76 +315,13 @@
/*EnteringContext=*/false,
/*AllowDestructorName=*/false,
/*AllowConstructorName=*/false,
+ /*ObjectType=*/0,
Name))
return ExprError();
return Actions.ActOnIdExpression(CurScope, SS, Name, Tok.is(tok::l_paren),
isAddressOfOperand);
-#if 0
- // unqualified-id:
- // identifier
- // operator-function-id
- // conversion-function-id
- // '~' class-name [TODO]
- // template-id
- //
- switch (Tok.getKind()) {
- default:
- return ExprError(Diag(Tok, diag::err_expected_unqualified_id));
-
- case tok::identifier: {
- // Consume the identifier so that we can see if it is followed by a '('.
- IdentifierInfo &II = *Tok.getIdentifierInfo();
- SourceLocation L = ConsumeToken();
- return Actions.ActOnIdentifierExpr(CurScope, L, II, Tok.is(tok::l_paren),
- &SS, isAddressOfOperand);
- }
-
- case tok::kw_operator: {
- SourceLocation OperatorLoc = Tok.getLocation();
- if (OverloadedOperatorKind Op = TryParseOperatorFunctionId())
- return Actions.ActOnCXXOperatorFunctionIdExpr(
- CurScope, OperatorLoc, Op, Tok.is(tok::l_paren), SS,
- isAddressOfOperand);
- if (TypeTy *Type = ParseConversionFunctionId())
- return Actions.ActOnCXXConversionFunctionExpr(CurScope, OperatorLoc, Type,
- Tok.is(tok::l_paren), SS,
- isAddressOfOperand);
-
- // We already complained about a bad conversion-function-id,
- // above.
- return ExprError();
- }
-
- case tok::annot_template_id: {
- TemplateIdAnnotation *TemplateId
- = static_cast<TemplateIdAnnotation *>(Tok.getAnnotationValue());
- assert((TemplateId->Kind == TNK_Function_template ||
- TemplateId->Kind == TNK_Dependent_template_name) &&
- "A template type name is not an ID expression");
-
- ASTTemplateArgsPtr TemplateArgsPtr(Actions,
- TemplateId->getTemplateArgs(),
- TemplateId->getTemplateArgIsType(),
- TemplateId->NumArgs);
-
- OwningExprResult Result
- = Actions.ActOnTemplateIdExpr(SS,
- TemplateTy::make(TemplateId->Template),
- TemplateId->TemplateNameLoc,
- TemplateId->LAngleLoc,
- TemplateArgsPtr,
- TemplateId->getTemplateArgLocations(),
- TemplateId->RAngleLoc);
- ConsumeToken(); // Consume the template-id token
- return move(Result);
- }
-
- } // switch.
-
- assert(0 && "The switch was supposed to take care everything.");
-#endif
}
/// ParseCXXCasts - This handles the various ways to cast expressions to another
@@ -806,6 +743,7 @@
IdentifierInfo *Name,
SourceLocation NameLoc,
bool EnteringContext,
+ TypeTy *ObjectType,
UnqualifiedId &Id) {
assert(Tok.is(tok::less) && "Expected '<' to finish parsing a template-id");
@@ -814,14 +752,13 @@
switch (Id.getKind()) {
case UnqualifiedId::IK_Identifier:
TNK = Actions.isTemplateName(CurScope, *Id.Identifier, Id.StartLocation,
- &SS, /*ObjectType=*/0, EnteringContext,
- Template);
+ &SS, ObjectType, EnteringContext, Template);
break;
case UnqualifiedId::IK_OperatorFunctionId: {
// FIXME: Temporary hack: warn that we are completely ignoring the
// template arguments for now.
- // Parse the enclosed template argument list.
+ // Parse the enclosed template argument list and throw it away.
SourceLocation LAngleLoc, RAngleLoc;
TemplateArgList TemplateArgs;
TemplateArgIsTypeList TemplateArgIsType;
@@ -840,15 +777,32 @@
}
case UnqualifiedId::IK_ConstructorName:
- TNK = Actions.isTemplateName(CurScope, *Name, NameLoc,
- &SS, /*ObjectType=*/0, EnteringContext,
- Template);
+ TNK = Actions.isTemplateName(CurScope, *Name, NameLoc, &SS, ObjectType,
+ EnteringContext, Template);
break;
case UnqualifiedId::IK_DestructorName:
- TNK = Actions.isTemplateName(CurScope, *Name, NameLoc,
- &SS, /*ObjectType=*/0, EnteringContext,
- Template);
+ if (ObjectType) {
+ Template = Actions.ActOnDependentTemplateName(SourceLocation(), *Name,
+ NameLoc, SS, ObjectType);
+ TNK = TNK_Dependent_template_name;
+ if (!Template.get())
+ return true;
+ } else {
+ TNK = Actions.isTemplateName(CurScope, *Name, NameLoc, &SS, ObjectType,
+ EnteringContext, Template);
+
+ if (TNK == TNK_Non_template && Id.DestructorName == 0) {
+ // The identifier following the destructor did not refer to a template
+ // or to a type. Complain.
+ if (ObjectType)
+ Diag(NameLoc, diag::err_ident_in_pseudo_dtor_not_a_type)
+ << Name;
+ else
+ Diag(NameLoc, diag::err_destructor_class_name);
+ return true;
+ }
+ }
break;
default:
@@ -974,6 +928,7 @@
bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext,
bool AllowDestructorName,
bool AllowConstructorName,
+ TypeTy *ObjectType,
UnqualifiedId &Result) {
// unqualified-id:
// identifier
@@ -997,7 +952,7 @@
// If the next token is a '<', we may have a template.
if (Tok.is(tok::less))
return ParseUnqualifiedIdTemplateId(SS, Id, IdLoc, EnteringContext,
- Result);
+ ObjectType, Result);
return false;
}
@@ -1110,7 +1065,8 @@
// If the next token is a '<', we may have a template.
if (Tok.is(tok::less))
return ParseUnqualifiedIdTemplateId(SS, 0, SourceLocation(),
- EnteringContext, Result);
+ EnteringContext, ObjectType,
+ Result);
return false;
}
@@ -1166,24 +1122,30 @@
IdentifierInfo *ClassName = Tok.getIdentifierInfo();
SourceLocation ClassNameLoc = ConsumeToken();
+ if (Tok.is(tok::less)) {
+ Result.setDestructorName(TildeLoc, 0, ClassNameLoc);
+ return ParseUnqualifiedIdTemplateId(SS, ClassName, ClassNameLoc,
+ EnteringContext, ObjectType, Result);
+ }
+
// Note that this is a destructor name.
Action::TypeTy *Ty = Actions.getTypeName(*ClassName, ClassNameLoc,
CurScope, &SS);
if (!Ty) {
- Diag(ClassNameLoc, diag::err_destructor_class_name);
+ if (ObjectType)
+ Diag(ClassNameLoc, diag::err_ident_in_pseudo_dtor_not_a_type)
+ << ClassName;
+ else
+ Diag(ClassNameLoc, diag::err_destructor_class_name);
return true;
}
Result.setDestructorName(TildeLoc, Ty, ClassNameLoc);
-
- if (Tok.is(tok::less))
- return ParseUnqualifiedIdTemplateId(SS, ClassName, ClassNameLoc,
- EnteringContext, Result);
-
return false;
}
- Diag(Tok, diag::err_expected_unqualified_id);
+ Diag(Tok, diag::err_expected_unqualified_id)
+ << getLang().CPlusPlus;
return true;
}
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=85930&r1=85929&r2=85930&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Nov 3 13:44:04 2009
@@ -1714,13 +1714,14 @@
const CXXScopeSpec *SS,
NamedDecl *FirstQualifierInScope = 0);
- virtual OwningExprResult ActOnMemberReferenceExpr(Scope *S, ExprArg Base,
- SourceLocation OpLoc,
- tok::TokenKind OpKind,
- SourceLocation MemberLoc,
- IdentifierInfo &Member,
- DeclPtrTy ImplDecl,
- const CXXScopeSpec *SS = 0);
+ virtual OwningExprResult ActOnMemberAccessExpr(Scope *S, ExprArg Base,
+ SourceLocation OpLoc,
+ tok::TokenKind OpKind,
+ const CXXScopeSpec &SS,
+ UnqualifiedId &Member,
+ DeclPtrTy ObjCImpDecl,
+ bool HasTrailingLParen);
+
virtual void ActOnDefaultCtorInitializers(DeclPtrTy CDtorDecl);
bool ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
FunctionDecl *FDecl,
@@ -2096,52 +2097,6 @@
tok::TokenKind OpKind,
TypeTy *&ObjectType);
- virtual OwningExprResult
- ActOnDestructorReferenceExpr(Scope *S, ExprArg Base,
- SourceLocation OpLoc,
- tok::TokenKind OpKind,
- SourceLocation ClassNameLoc,
- IdentifierInfo *ClassName,
- const CXXScopeSpec &SS,
- bool HasTrailingLParen);
-
- virtual OwningExprResult
- ActOnDestructorReferenceExpr(Scope *S, ExprArg Base,
- SourceLocation OpLoc,
- tok::TokenKind OpKind,
- SourceRange TypeRange,
- TypeTy *Type,
- const CXXScopeSpec &SS,
- bool HasTrailingLParen);
-
- virtual OwningExprResult
- ActOnOverloadedOperatorReferenceExpr(Scope *S, ExprArg Base,
- SourceLocation OpLoc,
- tok::TokenKind OpKind,
- SourceLocation ClassNameLoc,
- OverloadedOperatorKind OverOpKind,
- const CXXScopeSpec *SS = 0);
- virtual OwningExprResult
- ActOnConversionOperatorReferenceExpr(Scope *S, ExprArg Base,
- SourceLocation OpLoc,
- tok::TokenKind OpKind,
- SourceLocation ClassNameLoc,
- TypeTy *Ty,
- const CXXScopeSpec *SS = 0);
-
- virtual OwningExprResult
- ActOnMemberTemplateIdReferenceExpr(Scope *S, ExprArg Base,
- SourceLocation OpLoc,
- tok::TokenKind OpKind,
- const CXXScopeSpec &SS,
- // FIXME: "template" keyword?
- TemplateTy Template,
- SourceLocation TemplateNameLoc,
- SourceLocation LAngleLoc,
- ASTTemplateArgsPtr TemplateArgs,
- SourceLocation *TemplateArgLocs,
- SourceLocation RAngleLoc);
-
/// MaybeCreateCXXExprWithTemporaries - If the list of temporaries is
/// non-empty, will create a new CXXExprWithTemporaries expression.
/// Otherwise, just returs the passed in expression.
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=85930&r1=85929&r2=85930&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Nov 3 13:44:04 2009
@@ -2479,13 +2479,72 @@
return ExprError();
}
-Action::OwningExprResult
-Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
- tok::TokenKind OpKind, SourceLocation MemberLoc,
- IdentifierInfo &Member,
- DeclPtrTy ObjCImpDecl, const CXXScopeSpec *SS) {
- return BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind, MemberLoc,
- DeclarationName(&Member), ObjCImpDecl, SS);
+Sema::OwningExprResult Sema::ActOnMemberAccessExpr(Scope *S, ExprArg Base,
+ SourceLocation OpLoc,
+ tok::TokenKind OpKind,
+ const CXXScopeSpec &SS,
+ UnqualifiedId &Member,
+ DeclPtrTy ObjCImpDecl,
+ bool HasTrailingLParen) {
+ if (Member.getKind() == UnqualifiedId::IK_TemplateId) {
+ TemplateName Template
+ = TemplateName::getFromVoidPointer(Member.TemplateId->Template);
+
+ // FIXME: We're going to end up looking up the template based on its name,
+ // twice!
+ DeclarationName Name;
+ if (TemplateDecl *ActualTemplate = Template.getAsTemplateDecl())
+ Name = ActualTemplate->getDeclName();
+ else if (OverloadedFunctionDecl *Ovl = Template.getAsOverloadedFunctionDecl())
+ Name = Ovl->getDeclName();
+ else
+ Name = Template.getAsDependentTemplateName()->getName();
+
+ // Translate the parser's template argument list in our AST format.
+ ASTTemplateArgsPtr TemplateArgsPtr(*this,
+ Member.TemplateId->getTemplateArgs(),
+ Member.TemplateId->getTemplateArgIsType(),
+ Member.TemplateId->NumArgs);
+
+ llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
+ translateTemplateArguments(TemplateArgsPtr,
+ Member.TemplateId->getTemplateArgLocations(),
+ TemplateArgs);
+ TemplateArgsPtr.release();
+
+ // Do we have the save the actual template name? We might need it...
+ return BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind,
+ Member.TemplateId->TemplateNameLoc,
+ Name, true, Member.TemplateId->LAngleLoc,
+ TemplateArgs.data(), TemplateArgs.size(),
+ Member.TemplateId->RAngleLoc, DeclPtrTy(),
+ &SS);
+ }
+
+ // FIXME: We lose a lot of source information by mapping directly to the
+ // DeclarationName.
+ OwningExprResult Result
+ = BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind,
+ Member.getSourceRange().getBegin(),
+ GetNameFromUnqualifiedId(Member),
+ ObjCImpDecl, &SS);
+
+ if (Result.isInvalid() || HasTrailingLParen ||
+ Member.getKind() != UnqualifiedId::IK_DestructorName)
+ return move(Result);
+
+ // The only way a reference to a destructor can be used is to
+ // immediately call them. Since the next token is not a '(', produce a
+ // diagnostic and build the call now.
+ Expr *E = (Expr *)Result.get();
+ SourceLocation ExpectedLParenLoc
+ = PP.getLocForEndOfToken(Member.getSourceRange().getEnd());
+ Diag(E->getLocStart(), diag::err_dtor_expr_without_call)
+ << isa<CXXPseudoDestructorExpr>(E)
+ << CodeModificationHint::CreateInsertion(ExpectedLParenLoc, "()");
+
+ return ActOnCallExpr(0, move(Result), ExpectedLParenLoc,
+ MultiExprArg(*this, 0, 0), 0, ExpectedLParenLoc);
}
Sema::OwningExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=85930&r1=85929&r2=85930&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Tue Nov 3 13:44:04 2009
@@ -2114,110 +2114,6 @@
return move(Base);
}
-Sema::OwningExprResult
-Sema::ActOnDestructorReferenceExpr(Scope *S, ExprArg Base,
- SourceLocation OpLoc,
- tok::TokenKind OpKind,
- SourceLocation ClassNameLoc,
- IdentifierInfo *ClassName,
- const CXXScopeSpec &SS,
- bool HasTrailingLParen) {
- if (SS.isInvalid())
- return ExprError();
-
- QualType BaseType;
- if (isUnknownSpecialization(SS))
- BaseType = Context.getTypenameType((NestedNameSpecifier *)SS.getScopeRep(),
- ClassName);
- else {
- TypeTy *BaseTy = getTypeName(*ClassName, ClassNameLoc, S, &SS);
-
- // FIXME: If Base is dependent, we might not be able to resolve it here.
- if (!BaseTy) {
- Diag(ClassNameLoc, diag::err_ident_in_pseudo_dtor_not_a_type)
- << ClassName;
- return ExprError();
- }
-
- BaseType = GetTypeFromParser(BaseTy);
- }
-
- return ActOnDestructorReferenceExpr(S, move(Base), OpLoc, OpKind,
- SourceRange(ClassNameLoc),
- BaseType.getAsOpaquePtr(),
- SS, HasTrailingLParen);
-}
-
-Sema::OwningExprResult
-Sema::ActOnDestructorReferenceExpr(Scope *S, ExprArg Base,
- SourceLocation OpLoc,
- tok::TokenKind OpKind,
- SourceRange TypeRange,
- TypeTy *T,
- const CXXScopeSpec &SS,
- bool HasTrailingLParen) {
- QualType Type = GetTypeFromParser(T);
- CanQualType CanType = Context.getCanonicalType(Type);
- DeclarationName DtorName =
- Context.DeclarationNames.getCXXDestructorName(CanType);
-
- OwningExprResult Result
- = BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind,
- TypeRange.getBegin(), DtorName, DeclPtrTy(),
- &SS);
- if (Result.isInvalid() || HasTrailingLParen)
- return move(Result);
-
- // The only way a reference to a destructor can be used is to
- // immediately call them. Since the next token is not a '(', produce a
- // diagnostic and build the call now.
- Expr *E = (Expr *)Result.get();
- SourceLocation ExpectedLParenLoc = PP.getLocForEndOfToken(TypeRange.getEnd());
- Diag(E->getLocStart(), diag::err_dtor_expr_without_call)
- << isa<CXXPseudoDestructorExpr>(E)
- << CodeModificationHint::CreateInsertion(ExpectedLParenLoc, "()");
-
- return ActOnCallExpr(0, move(Result), ExpectedLParenLoc,
- MultiExprArg(*this, 0, 0), 0, ExpectedLParenLoc);
-}
-
-Sema::OwningExprResult
-Sema::ActOnOverloadedOperatorReferenceExpr(Scope *S, ExprArg Base,
- SourceLocation OpLoc,
- tok::TokenKind OpKind,
- SourceLocation ClassNameLoc,
- OverloadedOperatorKind OverOpKind,
- const CXXScopeSpec *SS) {
- if (SS && SS->isInvalid())
- return ExprError();
-
- DeclarationName Name =
- Context.DeclarationNames.getCXXOperatorName(OverOpKind);
-
- return BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind, ClassNameLoc,
- Name, DeclPtrTy(), SS);
-}
-
-Sema::OwningExprResult
-Sema::ActOnConversionOperatorReferenceExpr(Scope *S, ExprArg Base,
- SourceLocation OpLoc,
- tok::TokenKind OpKind,
- SourceLocation ClassNameLoc,
- TypeTy *Ty,
- const CXXScopeSpec *SS) {
- if (SS && SS->isInvalid())
- return ExprError();
-
- //FIXME: Preserve type source info.
- QualType ConvType = GetTypeFromParser(Ty);
- CanQualType ConvTypeCanon = Context.getCanonicalType(ConvType);
- DeclarationName ConvName =
- Context.DeclarationNames.getCXXConversionFunctionName(ConvTypeCanon);
-
- return BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind, ClassNameLoc,
- ConvName, DeclPtrTy(), SS);
-}
-
CXXMemberCallExpr *Sema::BuildCXXMemberCallExpr(Expr *Exp,
CXXMethodDecl *Method) {
MemberExpr *ME =
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=85930&r1=85929&r2=85930&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Tue Nov 3 13:44:04 2009
@@ -1336,41 +1336,6 @@
RAngleLoc);
}
-Sema::OwningExprResult
-Sema::ActOnMemberTemplateIdReferenceExpr(Scope *S, ExprArg Base,
- SourceLocation OpLoc,
- tok::TokenKind OpKind,
- const CXXScopeSpec &SS,
- TemplateTy TemplateD,
- SourceLocation TemplateNameLoc,
- SourceLocation LAngleLoc,
- ASTTemplateArgsPtr TemplateArgsIn,
- SourceLocation *TemplateArgLocs,
- SourceLocation RAngleLoc) {
- TemplateName Template = TemplateD.getAsVal<TemplateName>();
-
- // FIXME: We're going to end up looking up the template based on its name,
- // twice!
- DeclarationName Name;
- if (TemplateDecl *ActualTemplate = Template.getAsTemplateDecl())
- Name = ActualTemplate->getDeclName();
- else if (OverloadedFunctionDecl *Ovl = Template.getAsOverloadedFunctionDecl())
- Name = Ovl->getDeclName();
- else
- Name = Template.getAsDependentTemplateName()->getName();
-
- // Translate the parser's template argument list in our AST format.
- llvm::SmallVector<TemplateArgumentLoc, 16> TemplateArgs;
- translateTemplateArguments(TemplateArgsIn, TemplateArgLocs, TemplateArgs);
- TemplateArgsIn.release();
-
- // Do we have the save the actual template name? We might need it...
- return BuildMemberReferenceExpr(S, move(Base), OpLoc, OpKind, TemplateNameLoc,
- Name, true, LAngleLoc,
- TemplateArgs.data(), TemplateArgs.size(),
- RAngleLoc, DeclPtrTy(), &SS);
-}
-
/// \brief Form a dependent template name.
///
/// This action forms a dependent template name given the template
Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=85930&r1=85929&r2=85930&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Tue Nov 3 13:44:04 2009
@@ -1034,9 +1034,9 @@
SourceLocation OpLoc,
SourceLocation AccessorLoc,
IdentifierInfo &Accessor) {
- return getSema().ActOnMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
+ return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
tok::period, AccessorLoc,
- Accessor,
+ DeclarationName(&Accessor),
/*FIXME?*/Sema::DeclPtrTy::make((Decl*)0));
}
@@ -1568,7 +1568,7 @@
SS.setScopeRep(Qualifier);
// FIXME: We're going to end up looking up the template based on its name,
- // twice! Also, duplicates part of Sema::ActOnMemberTemplateIdReferenceExpr.
+ // twice! Also, duplicates part of Sema::BuildMemberAccessExpr.
DeclarationName Name;
if (TemplateDecl *ActualTemplate = Template.getAsTemplateDecl())
Name = ActualTemplate->getDeclName();
Modified: cfe/trunk/test/SemaCXX/invalid-member-expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/invalid-member-expr.cpp?rev=85930&r1=85929&r2=85930&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/invalid-member-expr.cpp (original)
+++ cfe/trunk/test/SemaCXX/invalid-member-expr.cpp Tue Nov 3 13:44:04 2009
@@ -5,8 +5,8 @@
void test() {
X x;
- x.int; // expected-error{{expected identifier}}
- x.~int(); // expected-error{{expected identifier}}
+ x.int; // expected-error{{expected unqualified-id}}
+ x.~int(); // expected-error{{expected the class name}}
x.operator; // expected-error{{missing type specifier after 'operator'}}
x.operator typedef; // expected-error{{missing type specifier after 'operator'}}
}
@@ -14,8 +14,8 @@
void test2() {
X *x;
- x->int; // expected-error{{expected identifier}}
- x->~int(); // expected-error{{expected identifier}}
+ x->int; // expected-error{{expected unqualified-id}}
+ x->~int(); // expected-error{{expected the class name}}
x->operator; // expected-error{{missing type specifier after 'operator'}}
x->operator typedef; // expected-error{{missing type specifier after 'operator'}}
}
More information about the cfe-commits
mailing list