summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaExprCXX.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaExprCXX.cpp')
-rw-r--r--lib/Sema/SemaExprCXX.cpp186
1 files changed, 35 insertions, 151 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index d4d031f..4868c14 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -22,41 +22,6 @@
#include "llvm/ADT/STLExtras.h"
using namespace clang;
-/// ActOnCXXConversionFunctionExpr - Parse a C++ conversion function
-/// name (e.g., 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.
-Sema::OwningExprResult
-Sema::ActOnCXXConversionFunctionExpr(Scope *S, SourceLocation OperatorLoc,
- TypeTy *Ty, bool HasTrailingLParen,
- const CXXScopeSpec &SS,
- bool isAddressOfOperand) {
- //FIXME: Preserve type source info.
- QualType ConvType = GetTypeFromParser(Ty);
- CanQualType ConvTypeCanon = Context.getCanonicalType(ConvType);
- DeclarationName ConvName
- = Context.DeclarationNames.getCXXConversionFunctionName(ConvTypeCanon);
- return ActOnDeclarationNameExpr(S, OperatorLoc, ConvName, HasTrailingLParen,
- &SS, isAddressOfOperand);
-}
-
-/// ActOnCXXOperatorFunctionIdExpr - 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.
-Sema::OwningExprResult
-Sema::ActOnCXXOperatorFunctionIdExpr(Scope *S, SourceLocation OperatorLoc,
- OverloadedOperatorKind Op,
- bool HasTrailingLParen,
- const CXXScopeSpec &SS,
- bool isAddressOfOperand) {
- DeclarationName Name = Context.DeclarationNames.getCXXOperatorName(Op);
- return ActOnDeclarationNameExpr(S, OperatorLoc, Name, HasTrailingLParen, &SS,
- isAddressOfOperand);
-}
-
/// ActOnCXXTypeidOfType - Parse typeid( type-id ).
Action::OwningExprResult
Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
@@ -212,7 +177,7 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep,
PDiag(diag::err_invalid_incomplete_type_use)
<< FullRange))
return ExprError();
-
+
if (RequireNonAbstractType(TyBeginLoc, Ty,
diag::err_allocation_of_abstract_type))
return ExprError();
@@ -288,7 +253,6 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep,
<< FullRange);
assert(NumExprs == 0 && "Expected 0 expressions");
-
// C++ [expr.type.conv]p2:
// The expression T(), where T is a simple-type-specifier for a non-array
// complete object type or the (possibly cv-qualified) void type, creates an
@@ -312,7 +276,6 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
MultiExprArg ConstructorArgs,
SourceLocation ConstructorRParen) {
Expr *ArraySize = 0;
- unsigned Skip = 0;
// If the specified type is an array, unwrap it and save the expression.
if (D.getNumTypeObjects() > 0 &&
D.getTypeObject(0).Kind == DeclaratorChunk::Array) {
@@ -323,14 +286,25 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
if (!Chunk.Arr.NumElts)
return ExprError(Diag(Chunk.Loc, diag::err_array_new_needs_size)
<< D.getSourceRange());
+
+ if (ParenTypeId) {
+ // Can't have dynamic array size when the type-id is in parentheses.
+ Expr *NumElts = (Expr *)Chunk.Arr.NumElts;
+ if (!NumElts->isTypeDependent() && !NumElts->isValueDependent() &&
+ !NumElts->isIntegerConstantExpr(Context)) {
+ Diag(D.getTypeObject(0).Loc, diag::err_new_paren_array_nonconst)
+ << NumElts->getSourceRange();
+ return ExprError();
+ }
+ }
+
ArraySize = static_cast<Expr*>(Chunk.Arr.NumElts);
- Skip = 1;
+ D.DropFirstTypeObject();
}
// Every dimension shall be of constant size.
- if (D.getNumTypeObjects() > 0 &&
- D.getTypeObject(0).Kind == DeclaratorChunk::Array) {
- for (unsigned I = 1, N = D.getNumTypeObjects(); I < N; ++I) {
+ if (ArraySize) {
+ for (unsigned I = 0, N = D.getNumTypeObjects(); I < N; ++I) {
if (D.getTypeObject(I).Kind != DeclaratorChunk::Array)
break;
@@ -345,10 +319,10 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
}
}
}
-
+
//FIXME: Store DeclaratorInfo in CXXNew expression.
DeclaratorInfo *DInfo = 0;
- QualType AllocType = GetTypeForDeclarator(D, /*Scope=*/0, &DInfo, Skip);
+ QualType AllocType = GetTypeForDeclarator(D, /*Scope=*/0, &DInfo);
if (D.isInvalidType())
return ExprError();
@@ -935,7 +909,7 @@ Sema::ActOnCXXConditionDeclarationExpr(Scope *S, SourceLocation StartLoc,
// FIXME: Store DeclaratorInfo in the expression.
DeclaratorInfo *DInfo = 0;
TagDecl *OwnedTag = 0;
- QualType Ty = GetTypeForDeclarator(D, S, &DInfo, /*Skip=*/0, &OwnedTag);
+ QualType Ty = GetTypeForDeclarator(D, S, &DInfo, &OwnedTag);
if (Ty->isFunctionType()) { // The declarator shall not specify a function...
// We exit without creating a CXXConditionDeclExpr because a FunctionDecl
@@ -1139,6 +1113,10 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
From = CastArg.takeAs<Expr>();
return BuildCXXDerivedToBaseExpr(From, CastKind, ICS, Flavor);
}
+
+ if (ICS.UserDefined.After.Second == ICK_Pointer_Member &&
+ ToType.getNonReferenceType()->isMemberFunctionPointerType())
+ CastKind = CastExpr::CK_BaseToDerivedMemberPointer;
From = new (Context) ImplicitCastExpr(ToType.getNonReferenceType(),
CastKind, CastArg.takeAs<Expr>(),
@@ -1390,7 +1368,8 @@ QualType Sema::CheckPointerToMemberOperands(
LType = Ptr->getPointeeType().getNonReferenceType();
else {
Diag(Loc, diag::err_bad_memptr_lhs)
- << OpSpelling << 1 << LType << lex->getSourceRange();
+ << OpSpelling << 1 << LType
+ << CodeModificationHint::CreateReplacement(SourceRange(Loc), ".*");
return QualType();
}
}
@@ -1403,8 +1382,10 @@ QualType Sema::CheckPointerToMemberOperands(
// overkill?
if (!IsDerivedFrom(LType, Class, Paths) ||
Paths.isAmbiguous(Context.getCanonicalType(Class))) {
+ const char *ReplaceStr = isIndirect ? ".*" : "->*";
Diag(Loc, diag::err_bad_memptr_lhs) << OpSpelling
- << (int)isIndirect << lex->getType() << lex->getSourceRange();
+ << (int)isIndirect << lex->getType() <<
+ CodeModificationHint::CreateReplacement(SourceRange(Loc), ReplaceStr);
return QualType();
}
}
@@ -2105,110 +2086,6 @@ Sema::ActOnStartCXXMemberReference(Scope *S, ExprArg Base, SourceLocation OpLoc,
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 = QualType::getFromOpaquePtr(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 =
@@ -2333,6 +2210,7 @@ bool Sema::isImplicitMemberReference(const CXXScopeSpec *SS, NamedDecl *D,
if (!Method && (FunTmpl = dyn_cast<FunctionTemplateDecl>(*Ovl)))
Method = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
+ // FIXME: Do we have to know if there are explicit template arguments?
if (Method && !Method->isStatic()) {
Ctx = Method->getParent();
if (isa<CXXMethodDecl>(D) && !FunTmpl)
@@ -2350,6 +2228,12 @@ bool Sema::isImplicitMemberReference(const CXXScopeSpec *SS, NamedDecl *D,
// Determine whether the declaration(s) we found are actually in a base
// class. If not, this isn't an implicit member reference.
ThisType = MD->getThisType(Context);
+
+ // If the type of "this" is dependent, we can't tell if the member is in a
+ // base class or not, so treat this as a dependent implicit member reference.
+ if (ThisType->isDependentType())
+ return true;
+
QualType CtxType = Context.getTypeDeclType(cast<CXXRecordDecl>(Ctx));
QualType ClassType
= Context.getTypeDeclType(cast<CXXRecordDecl>(MD->getParent()));
OpenPOWER on IntegriCloud