summaryrefslogtreecommitdiffstats
path: root/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r--lib/Sema/SemaExpr.cpp1704
1 files changed, 861 insertions, 843 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 5f46a97..80b4652 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -11,10 +11,10 @@
//
//===----------------------------------------------------------------------===//
-#include "Sema.h"
-#include "SemaInit.h"
-#include "Lookup.h"
-#include "AnalysisBasedWarnings.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Initialization.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/AnalysisBasedWarnings.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/DeclObjC.h"
@@ -29,11 +29,14 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/LiteralSupport.h"
#include "clang/Lex/Preprocessor.h"
-#include "clang/Parse/DeclSpec.h"
-#include "clang/Parse/Designator.h"
-#include "clang/Parse/Scope.h"
-#include "clang/Parse/Template.h"
+#include "clang/Sema/DeclSpec.h"
+#include "clang/Sema/Designator.h"
+#include "clang/Sema/Scope.h"
+#include "clang/Sema/ScopeInfo.h"
+#include "clang/Sema/ParsedTemplate.h"
+#include "clang/Sema/Template.h"
using namespace clang;
+using namespace sema;
/// \brief Determine whether the use of this declaration is valid, and
@@ -59,7 +62,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc) {
// See if the decl is unavailable
if (D->getAttr<UnavailableAttr>()) {
- Diag(Loc, diag::warn_unavailable) << D->getDeclName();
+ Diag(Loc, diag::err_unavailable) << D->getDeclName();
Diag(D->getLocation(), diag::note_unavailable_here) << 0;
}
@@ -192,7 +195,7 @@ void Sema::DefaultFunctionArrayConversion(Expr *&E) {
if (Ty->isFunctionType())
ImpCastExprToType(E, Context.getPointerType(Ty),
- CastExpr::CK_FunctionToPointerDecay);
+ CK_FunctionToPointerDecay);
else if (Ty->isArrayType()) {
// In C90 mode, arrays only promote to pointers if the array expression is
// an lvalue. The relevant legalese is C90 6.2.2.1p3: "an lvalue that has
@@ -208,7 +211,7 @@ void Sema::DefaultFunctionArrayConversion(Expr *&E) {
if (getLangOptions().C99 || getLangOptions().CPlusPlus ||
E->isLvalue(Context) == Expr::LV_Valid)
ImpCastExprToType(E, Context.getArrayDecayedType(Ty),
- CastExpr::CK_ArrayToPointerDecay);
+ CK_ArrayToPointerDecay);
}
}
@@ -229,7 +232,7 @@ void Sema::DefaultFunctionArrayLvalueConversion(Expr *&E) {
// If the lvalue has qualified type, the value has the unqualified
// version of the type of the lvalue; otherwise, the value has the
// type of the lvalue.
- ImpCastExprToType(E, Ty.getUnqualifiedType(), CastExpr::CK_NoOp);
+ ImpCastExprToType(E, Ty.getUnqualifiedType(), CK_NoOp);
}
}
@@ -258,12 +261,12 @@ Expr *Sema::UsualUnaryConversions(Expr *&Expr) {
// other types are unchanged by the integer promotions.
QualType PTy = Context.isPromotableBitField(Expr);
if (!PTy.isNull()) {
- ImpCastExprToType(Expr, PTy, CastExpr::CK_IntegralCast);
+ ImpCastExprToType(Expr, PTy, CK_IntegralCast);
return Expr;
}
if (Ty->isPromotableIntegerType()) {
QualType PT = Context.getPromotedIntegerType(Ty);
- ImpCastExprToType(Expr, PT, CastExpr::CK_IntegralCast);
+ ImpCastExprToType(Expr, PT, CK_IntegralCast);
return Expr;
}
@@ -281,7 +284,7 @@ void Sema::DefaultArgumentPromotion(Expr *&Expr) {
// If this is a 'float' (CVR qualified or typedef) promote to double.
if (Ty->isSpecificBuiltinType(BuiltinType::Float))
return ImpCastExprToType(Expr, Context.DoubleTy,
- CastExpr::CK_FloatingCast);
+ CK_FloatingCast);
UsualUnaryConversions(Expr);
}
@@ -355,8 +358,8 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,
QualType destType = Context.UsualArithmeticConversionsType(lhs, rhs);
if (!isCompAssign)
- ImpCastExprToType(lhsExpr, destType, CastExpr::CK_Unknown);
- ImpCastExprToType(rhsExpr, destType, CastExpr::CK_Unknown);
+ ImpCastExprToType(lhsExpr, destType, CK_Unknown);
+ ImpCastExprToType(rhsExpr, destType, CK_Unknown);
return destType;
}
@@ -371,7 +374,7 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,
/// multiple tokens. However, the common case is that StringToks points to one
/// string.
///
-Action::OwningExprResult
+ExprResult
Sema::ActOnStringLiteral(const Token *StringToks, unsigned NumStringToks) {
assert(NumStringToks && "Must have at least one string!");
@@ -459,13 +462,20 @@ static bool ShouldSnapshotBlockValueReference(Sema &S, BlockScopeInfo *CurBlock,
}
+ExprResult
+Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, SourceLocation Loc,
+ const CXXScopeSpec *SS) {
+ DeclarationNameInfo NameInfo(D->getDeclName(), Loc);
+ return BuildDeclRefExpr(D, Ty, NameInfo, SS);
+}
/// BuildDeclRefExpr - Build a DeclRefExpr.
-Sema::OwningExprResult
-Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, SourceLocation Loc,
+ExprResult
+Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty,
+ const DeclarationNameInfo &NameInfo,
const CXXScopeSpec *SS) {
if (Context.getCanonicalType(Ty) == Context.UndeducedAutoTy) {
- Diag(Loc,
+ Diag(NameInfo.getLoc(),
diag::err_auto_variable_cannot_appear_in_own_initializer)
<< D->getDeclName();
return ExprError();
@@ -479,7 +489,8 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, SourceLocation Loc,
} else if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext)) {
if (const FunctionDecl *FD = MD->getParent()->isLocalClass()) {
if (VD->hasLocalStorage() && VD->getDeclContext() != CurContext) {
- Diag(Loc, diag::err_reference_to_local_var_in_enclosing_function)
+ Diag(NameInfo.getLoc(),
+ diag::err_reference_to_local_var_in_enclosing_function)
<< D->getIdentifier() << FD->getDeclName();
Diag(D->getLocation(), diag::note_local_variable_declared_here)
<< D->getIdentifier();
@@ -489,12 +500,12 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, SourceLocation Loc,
}
}
- MarkDeclarationReferenced(Loc, D);
+ MarkDeclarationReferenced(NameInfo.getLoc(), D);
return Owned(DeclRefExpr::Create(Context,
SS? (NestedNameSpecifier *)SS->getScopeRep() : 0,
SS? SS->getRange() : SourceRange(),
- D, Loc, Ty));
+ D, NameInfo, Ty));
}
/// \brief Given a field that represents a member of an anonymous
@@ -535,7 +546,7 @@ VarDecl *Sema::BuildAnonymousStructUnionMemberPath(FieldDecl *Field,
return BaseObject;
}
-Sema::OwningExprResult
+ExprResult
Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
FieldDecl *Field,
Expr *BaseObjectExpr,
@@ -553,7 +564,6 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
if (BaseObject) {
// BaseObject is an anonymous struct/union variable (and is,
// therefore, not part of another non-anonymous record).
- if (BaseObjectExpr) BaseObjectExpr->Destroy(Context);
MarkDeclarationReferenced(Loc, BaseObject);
BaseObjectExpr = new (Context) DeclRefExpr(BaseObject,BaseObject->getType(),
SourceLocation());
@@ -640,7 +650,7 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
return Owned(Result);
}
-/// Decomposes the given name into a DeclarationName, its location, and
+/// Decomposes the given name into a DeclarationNameInfo, its location, and
/// possibly a list of template arguments.
///
/// If this produces template arguments, it is permitted to call
@@ -652,8 +662,7 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc,
static void DecomposeUnqualifiedId(Sema &SemaRef,
const UnqualifiedId &Id,
TemplateArgumentListInfo &Buffer,
- DeclarationName &Name,
- SourceLocation &NameLoc,
+ DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *&TemplateArgs) {
if (Id.getKind() == UnqualifiedId::IK_TemplateId) {
Buffer.setLAngleLoc(Id.TemplateId->LAngleLoc);
@@ -665,15 +674,12 @@ static void DecomposeUnqualifiedId(Sema &SemaRef,
SemaRef.translateTemplateArguments(TemplateArgsPtr, Buffer);
TemplateArgsPtr.release();
- TemplateName TName =
- Sema::TemplateTy::make(Id.TemplateId->Template).getAsVal<TemplateName>();
-
- Name = SemaRef.Context.getNameForTemplate(TName);
- NameLoc = Id.TemplateId->TemplateNameLoc;
+ TemplateName TName = Id.TemplateId->Template.get();
+ SourceLocation TNameLoc = Id.TemplateId->TemplateNameLoc;
+ NameInfo = SemaRef.Context.getNameForTemplate(TName, TNameLoc);
TemplateArgs = &Buffer;
} else {
- Name = SemaRef.GetNameFromUnqualifiedId(Id);
- NameLoc = Id.StartLocation;
+ NameInfo = SemaRef.GetNameFromUnqualifiedId(Id);
TemplateArgs = 0;
}
}
@@ -700,23 +706,6 @@ static bool IsFullyFormedScope(Sema &SemaRef, CXXRecordDecl *Record) {
return true;
}
-/// Determines whether we can lookup this id-expression now or whether
-/// we have to wait until template instantiation is complete.
-static bool IsDependentIdExpression(Sema &SemaRef, const CXXScopeSpec &SS) {
- DeclContext *DC = SemaRef.computeDeclContext(SS, false);
-
- // If the qualifier scope isn't computable, it's definitely dependent.
- if (!DC) return true;
-
- // If the qualifier scope doesn't name a record, we can always look into it.
- if (!isa<CXXRecordDecl>(DC)) return false;
-
- // We can't look into record types unless they're fully-formed.
- if (!IsFullyFormedScope(SemaRef, cast<CXXRecordDecl>(DC))) return true;
-
- return false;
-}
-
/// Determines if the given class is provably not derived from all of
/// the prospective base classes.
static bool IsProvablyNotDerivedFrom(Sema &SemaRef,
@@ -905,25 +894,30 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
// TODO: fixit for inserting 'Base<T>::' in the other cases.
// Actually quite difficult!
if (isInstance) {
- Diag(R.getNameLoc(), diagnostic) << Name
- << FixItHint::CreateInsertion(R.getNameLoc(), "this->");
-
UnresolvedLookupExpr *ULE = cast<UnresolvedLookupExpr>(
CallsUndergoingInstantiation.back()->getCallee());
- CXXMethodDecl *DepMethod = cast<CXXMethodDecl>(
+ CXXMethodDecl *DepMethod = cast_or_null<CXXMethodDecl>(
CurMethod->getInstantiatedFromMemberFunction());
- QualType DepThisType = DepMethod->getThisType(Context);
- CXXThisExpr *DepThis = new (Context) CXXThisExpr(R.getNameLoc(),
- DepThisType, false);
- TemplateArgumentListInfo TList;
- if (ULE->hasExplicitTemplateArgs())
- ULE->copyTemplateArgumentsInto(TList);
- CXXDependentScopeMemberExpr *DepExpr =
- CXXDependentScopeMemberExpr::Create(
- Context, DepThis, DepThisType, true, SourceLocation(),
- ULE->getQualifier(), ULE->getQualifierRange(), NULL, Name,
- R.getNameLoc(), &TList);
- CallsUndergoingInstantiation.back()->setCallee(DepExpr);
+ if (DepMethod) {
+ Diag(R.getNameLoc(), diagnostic) << Name
+ << FixItHint::CreateInsertion(R.getNameLoc(), "this->");
+ QualType DepThisType = DepMethod->getThisType(Context);
+ CXXThisExpr *DepThis = new (Context) CXXThisExpr(
+ R.getNameLoc(), DepThisType, false);
+ TemplateArgumentListInfo TList;
+ if (ULE->hasExplicitTemplateArgs())
+ ULE->copyTemplateArgumentsInto(TList);
+ CXXDependentScopeMemberExpr *DepExpr =
+ CXXDependentScopeMemberExpr::Create(
+ Context, DepThis, DepThisType, true, SourceLocation(),
+ ULE->getQualifier(), ULE->getQualifierRange(), NULL,
+ R.getLookupNameInfo(), &TList);
+ CallsUndergoingInstantiation.back()->setCallee(DepExpr);
+ } else {
+ // FIXME: we should be able to handle this case too. It is correct
+ // to add this-> here. This is a workaround for PR7947.
+ Diag(R.getNameLoc(), diagnostic) << Name;
+ }
} else {
Diag(R.getNameLoc(), diagnostic) << Name;
}
@@ -935,6 +929,8 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
// Tell the callee to try to recover.
return false;
}
+
+ R.clear();
}
}
@@ -1005,11 +1001,74 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
return true;
}
-Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
- CXXScopeSpec &SS,
- UnqualifiedId &Id,
- bool HasTrailingLParen,
- bool isAddressOfOperand) {
+static ObjCPropertyDecl *OkToSynthesizeProvisionalIvar(Sema &SemaRef,
+ IdentifierInfo *II,
+ SourceLocation NameLoc) {
+ ObjCMethodDecl *CurMeth = SemaRef.getCurMethodDecl();
+ ObjCInterfaceDecl *IDecl = CurMeth->getClassInterface();
+ if (!IDecl)
+ return 0;
+ ObjCImplementationDecl *ClassImpDecl = IDecl->getImplementation();
+ if (!ClassImpDecl)
+ return 0;
+ ObjCPropertyDecl *property = SemaRef.LookupPropertyDecl(IDecl, II);
+ if (!property)
+ return 0;
+ if (ObjCPropertyImplDecl *PIDecl = ClassImpDecl->FindPropertyImplDecl(II))
+ if (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic)
+ return 0;
+ return property;
+}
+
+static ObjCIvarDecl *SynthesizeProvisionalIvar(Sema &SemaRef,
+ LookupResult &Lookup,
+ IdentifierInfo *II,
+ SourceLocation NameLoc) {
+ ObjCMethodDecl *CurMeth = SemaRef.getCurMethodDecl();
+ bool LookForIvars;
+ if (Lookup.empty())
+ LookForIvars = true;
+ else if (CurMeth->isClassMethod())
+ LookForIvars = false;
+ else
+ LookForIvars = (Lookup.isSingleResult() &&
+ Lookup.getFoundDecl()->isDefinedOutsideFunctionOrMethod());
+ if (!LookForIvars)
+ return 0;
+
+ ObjCInterfaceDecl *IDecl = CurMeth->getClassInterface();
+ if (!IDecl)
+ return 0;
+ ObjCImplementationDecl *ClassImpDecl = IDecl->getImplementation();
+ if (!ClassImpDecl)
+ return 0;
+ bool DynamicImplSeen = false;
+ ObjCPropertyDecl *property = SemaRef.LookupPropertyDecl(IDecl, II);
+ if (!property)
+ return 0;
+ if (ObjCPropertyImplDecl *PIDecl = ClassImpDecl->FindPropertyImplDecl(II))
+ DynamicImplSeen =
+ (PIDecl->getPropertyImplementation() == ObjCPropertyImplDecl::Dynamic);
+ if (!DynamicImplSeen) {
+ QualType PropType = SemaRef.Context.getCanonicalType(property->getType());
+ ObjCIvarDecl *Ivar = ObjCIvarDecl::Create(SemaRef.Context, ClassImpDecl,
+ NameLoc,
+ II, PropType, /*Dinfo=*/0,
+ ObjCIvarDecl::Protected,
+ (Expr *)0, true);
+ ClassImpDecl->addDecl(Ivar);
+ IDecl->makeDeclVisibleInContext(Ivar, false);
+ property->setPropertyIvarDecl(Ivar);
+ return Ivar;
+ }
+ return 0;
+}
+
+ExprResult Sema::ActOnIdExpression(Scope *S,
+ CXXScopeSpec &SS,
+ UnqualifiedId &Id,
+ bool HasTrailingLParen,
+ bool isAddressOfOperand) {
assert(!(isAddressOfOperand && HasTrailingLParen) &&
"cannot be direct & operand and have a trailing lparen");
@@ -1019,13 +1078,13 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
TemplateArgumentListInfo TemplateArgsBuffer;
// Decompose the UnqualifiedId into the following data.
- DeclarationName Name;
- SourceLocation NameLoc;
+ DeclarationNameInfo NameInfo;
const TemplateArgumentListInfo *TemplateArgs;
- DecomposeUnqualifiedId(*this, Id, TemplateArgsBuffer,
- Name, NameLoc, TemplateArgs);
+ DecomposeUnqualifiedId(*this, Id, TemplateArgsBuffer, NameInfo, TemplateArgs);
+ DeclarationName Name = NameInfo.getName();
IdentifierInfo *II = Name.getAsIdentifierInfo();
+ SourceLocation NameLoc = NameInfo.getLoc();
// C++ [temp.dep.expr]p3:
// An id-expression is type-dependent if it contains:
@@ -1038,16 +1097,30 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
// names a dependent type.
// Determine whether this is a member of an unknown specialization;
// we need to handle these differently.
- if ((Name.getNameKind() == DeclarationName::CXXConversionFunctionName &&
- Name.getCXXNameType()->isDependentType()) ||
- (SS.isSet() && IsDependentIdExpression(*this, SS))) {
- return ActOnDependentIdExpression(SS, Name, NameLoc,
- isAddressOfOperand,
- TemplateArgs);
+ bool DependentID = false;
+ if (Name.getNameKind() == DeclarationName::CXXConversionFunctionName &&
+ Name.getCXXNameType()->isDependentType()) {
+ DependentID = true;
+ } else if (SS.isSet()) {
+ DeclContext *DC = computeDeclContext(SS, false);
+ if (DC) {
+ if (RequireCompleteDeclContext(SS, DC))
+ return ExprError();
+ // FIXME: We should be checking whether DC is the current instantiation.
+ if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(DC))
+ DependentID = !IsFullyFormedScope(*this, RD);
+ } else {
+ DependentID = true;
+ }
}
+ if (DependentID) {
+ return ActOnDependentIdExpression(SS, NameInfo, isAddressOfOperand,
+ TemplateArgs);
+ }
+ bool IvarLookupFollowUp = false;
// Perform the required lookup.
- LookupResult R(*this, Name, NameLoc, LookupOrdinaryName);
+ LookupResult R(*this, NameInfo, LookupOrdinaryName);
if (TemplateArgs) {
// Lookup the template name again to correctly establish the context in
// which it was found. This is really unfortunate as we already did the
@@ -1058,18 +1131,26 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
LookupTemplateName(R, S, SS, QualType(), /*EnteringContext=*/false,
MemberOfUnknownSpecialization);
} else {
- bool IvarLookupFollowUp = (!SS.isSet() && II && getCurMethodDecl());
+ IvarLookupFollowUp = (!SS.isSet() && II && getCurMethodDecl());
LookupParsedName(R, S, &SS, !IvarLookupFollowUp);
// If this reference is in an Objective-C method, then we need to do
// some special Objective-C lookup, too.
if (IvarLookupFollowUp) {
- OwningExprResult E(LookupInObjCMethod(R, S, II, true));
+ ExprResult E(LookupInObjCMethod(R, S, II, true));
if (E.isInvalid())
return ExprError();
Expr *Ex = E.takeAs<Expr>();
if (Ex) return Owned(Ex);
+ // Synthesize ivars lazily
+ if (getLangOptions().ObjCNonFragileABI2) {
+ if (SynthesizeProvisionalIvar(*this, R, II, NameLoc))
+ return ActOnIdExpression(S, SS, Id, HasTrailingLParen,
+ isAddressOfOperand);
+ }
+ // for further use, this must be set to false if in class method.
+ IvarLookupFollowUp = getCurMethodDecl()->isInstanceMethod();
}
}
@@ -1102,7 +1183,7 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
// reference the ivar.
if (ObjCIvarDecl *Ivar = R.getAsSingle<ObjCIvarDecl>()) {
R.clear();
- OwningExprResult E(LookupInObjCMethod(R, S, Ivar->getIdentifier()));
+ ExprResult E(LookupInObjCMethod(R, S, Ivar->getIdentifier()));
assert(E.isInvalid() || E.get());
return move(E);
}
@@ -1113,23 +1194,15 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
assert(!R.empty() || ADL);
if (VarDecl *Var = R.getAsSingle<VarDecl>()) {
- // Warn about constructs like:
- // if (void *X = foo()) { ... } else { X }.
- // In the else block, the pointer is always false.
- if (Var->isDeclaredInCondition() && Var->getType()->isScalarType()) {
- Scope *CheckS = S;
- while (CheckS && CheckS->getControlParent()) {
- if ((CheckS->getFlags() & Scope::ElseScope) &&
- CheckS->getControlParent()->isDeclScope(DeclPtrTy::make(Var))) {
- ExprError(Diag(NameLoc, diag::warn_value_always_zero)
- << Var->getDeclName()
- << (Var->getType()->isPointerType() ? 2 :
- Var->getType()->isBooleanType() ? 1 : 0));
- break;
- }
-
- // Move to the parent of this scope.
- CheckS = CheckS->getParent();
+ if (getLangOptions().ObjCNonFragileABI && IvarLookupFollowUp &&
+ !getLangOptions().ObjCNonFragileABI2 &&
+ Var->isFileVarDecl()) {
+ ObjCPropertyDecl *Property =
+ OkToSynthesizeProvisionalIvar(*this, II, NameLoc);
+ if (Property) {
+ Diag(NameLoc, diag::warn_ivar_variable_conflict) << Var->getDeclName();
+ Diag(Property->getLocation(), diag::note_property_declare);
+ Diag(Var->getLocation(), diag::note_global_declared_at);
}
}
} else if (FunctionDecl *Func = R.getAsSingle<FunctionDecl>()) {
@@ -1152,15 +1225,43 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
}
// Check whether this might be a C++ implicit instance member access.
- // C++ [expr.prim.general]p6:
- // Within the definition of a non-static member function, an
- // identifier that names a non-static member is transformed to a
- // class member access expression.
- // But note that &SomeClass::foo is grammatically distinct, even
- // though we don't parse it that way.
+ // C++ [class.mfct.non-static]p3:
+ // When an id-expression that is not part of a class member access
+ // syntax and not used to form a pointer to member is used in the
+ // body of a non-static member function of class X, if name lookup
+ // resolves the name in the id-expression to a non-static non-type
+ // member of some class C, the id-expression is transformed into a
+ // class member access expression using (*this) as the
+ // postfix-expression to the left of the . operator.
+ //
+ // But we don't actually need to do this for '&' operands if R
+ // resolved to a function or overloaded function set, because the
+ // expression is ill-formed if it actually works out to be a
+ // non-static member function:
+ //
+ // C++ [expr.ref]p4:
+ // Otherwise, if E1.E2 refers to a non-static member function. . .
+ // [t]he expression can be used only as the left-hand operand of a
+ // member function call.
+ //
+ // There are other safeguards against such uses, but it's important
+ // to get this right here so that we don't end up making a
+ // spuriously dependent expression if we're inside a dependent
+ // instance method.
if (!R.empty() && (*R.begin())->isCXXClassMember()) {
- bool isAbstractMemberPointer = (isAddressOfOperand && !SS.isEmpty());
- if (!isAbstractMemberPointer)
+ bool MightBeImplicitMember;
+ if (!isAddressOfOperand)
+ MightBeImplicitMember = true;
+ else if (!SS.isEmpty())
+ MightBeImplicitMember = false;
+ else if (R.isOverloadedResult())
+ MightBeImplicitMember = false;
+ else if (R.isUnresolvableResult())
+ MightBeImplicitMember = true;
+ else
+ MightBeImplicitMember = isa<FieldDecl>(R.getFoundDecl());
+
+ if (MightBeImplicitMember)
return BuildPossibleImplicitMemberExpr(SS, R, TemplateArgs);
}
@@ -1171,7 +1272,7 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S,
}
/// Builds an expression which might be an implicit member expression.
-Sema::OwningExprResult
+ExprResult
Sema::BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS,
LookupResult &R,
const TemplateArgumentListInfo *TemplateArgs) {
@@ -1210,25 +1311,25 @@ Sema::BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS,
/// declaration name, generally during template instantiation.
/// There's a large number of things which don't need to be done along
/// this path.
-Sema::OwningExprResult
+ExprResult
Sema::BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS,
- DeclarationName Name,
- SourceLocation NameLoc) {
+ const DeclarationNameInfo &NameInfo) {
DeclContext *DC;
if (!(DC = computeDeclContext(SS, false)) || DC->isDependentContext())
- return BuildDependentDeclRefExpr(SS, Name, NameLoc, 0);
+ return BuildDependentDeclRefExpr(SS, NameInfo, 0);
if (RequireCompleteDeclContext(SS, DC))
return ExprError();
- LookupResult R(*this, Name, NameLoc, LookupOrdinaryName);
+ LookupResult R(*this, NameInfo, LookupOrdinaryName);
LookupQualifiedName(R, DC);
if (R.isAmbiguous())
return ExprError();
if (R.empty()) {
- Diag(NameLoc, diag::err_no_member) << Name << DC << SS.getRange();
+ Diag(NameInfo.getLoc(), diag::err_no_member)
+ << NameInfo.getName() << DC << SS.getRange();
return ExprError();
}
@@ -1243,7 +1344,7 @@ Sema::BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS,
/// actually quite a lot of extra work involved.
///
/// Returns a null sentinel to indicate trivial success.
-Sema::OwningExprResult
+ExprResult
Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S,
IdentifierInfo *II, bool AllowBuiltinCreation) {
SourceLocation Loc = Lookup.getNameLoc();
@@ -1298,7 +1399,7 @@ Sema::LookupInObjCMethod(LookupResult &Lookup, Scope *S,
UnqualifiedId SelfName;
SelfName.setIdentifier(&II, SourceLocation());
CXXScopeSpec SelfScopeSpec;
- OwningExprResult SelfExpr = ActOnIdExpression(S, SelfScopeSpec,
+ ExprResult SelfExpr = ActOnIdExpression(S, SelfScopeSpec,
SelfName, false, false);
MarkDeclarationReferenced(Loc, IV);
return Owned(new (Context)
@@ -1403,9 +1504,8 @@ Sema::PerformObjectMemberConversion(Expr *&From,
SourceRange FromRange = From->getSourceRange();
SourceLocation FromLoc = FromRange.getBegin();
- bool isLvalue
- = (From->isLvalue(Context) == Expr::LV_Valid) && !PointerConversions;
-
+ ExprValueKind VK = CastCategory(From);
+
// C++ [class.member.lookup]p8:
// [...] Ambiguities can often be resolved by qualifying a name with its
// class name.
@@ -1435,15 +1535,15 @@ Sema::PerformObjectMemberConversion(Expr *&From,
// type of the object type, in which case we just ignore it.
// Otherwise build the appropriate casts.
if (IsDerivedFrom(FromRecordType, QRecordType)) {
- CXXBaseSpecifierArray BasePath;
+ CXXCastPath BasePath;
if (CheckDerivedToBaseConversion(FromRecordType, QRecordType,
FromLoc, FromRange, &BasePath))
return true;
if (PointerConversions)
QType = Context.getPointerType(QType);
- ImpCastExprToType(From, QType, CastExpr::CK_UncheckedDerivedToBase,
- isLvalue, BasePath);
+ ImpCastExprToType(From, QType, CK_UncheckedDerivedToBase,
+ VK, &BasePath);
FromType = QType;
FromRecordType = QRecordType;
@@ -1471,7 +1571,7 @@ Sema::PerformObjectMemberConversion(Expr *&From,
// conversion is non-trivial.
if (!Context.hasSameUnqualifiedType(FromRecordType, URecordType)) {
assert(IsDerivedFrom(FromRecordType, URecordType));
- CXXBaseSpecifierArray BasePath;
+ CXXCastPath BasePath;
if (CheckDerivedToBaseConversion(FromRecordType, URecordType,
FromLoc, FromRange, &BasePath))
return true;
@@ -1479,8 +1579,8 @@ Sema::PerformObjectMemberConversion(Expr *&From,
QualType UType = URecordType;
if (PointerConversions)
UType = Context.getPointerType(UType);
- ImpCastExprToType(From, UType, CastExpr::CK_UncheckedDerivedToBase,
- isLvalue, BasePath);
+ ImpCastExprToType(From, UType, CK_UncheckedDerivedToBase,
+ VK, &BasePath);
FromType = UType;
FromRecordType = URecordType;
}
@@ -1490,14 +1590,14 @@ Sema::PerformObjectMemberConversion(Expr *&From,
IgnoreAccess = true;
}
- CXXBaseSpecifierArray BasePath;
+ CXXCastPath BasePath;
if (CheckDerivedToBaseConversion(FromRecordType, DestRecordType,
FromLoc, FromRange, &BasePath,
IgnoreAccess))
return true;
- ImpCastExprToType(From, DestType, CastExpr::CK_UncheckedDerivedToBase,
- isLvalue, BasePath);
+ ImpCastExprToType(From, DestType, CK_UncheckedDerivedToBase,
+ VK, &BasePath);
return false;
}
@@ -1505,7 +1605,8 @@ Sema::PerformObjectMemberConversion(Expr *&From,
static MemberExpr *BuildMemberExpr(ASTContext &C, Expr *Base, bool isArrow,
const CXXScopeSpec &SS, ValueDecl *Member,
DeclAccessPair FoundDecl,
- SourceLocation Loc, QualType Ty,
+ const DeclarationNameInfo &MemberNameInfo,
+ QualType Ty,
const TemplateArgumentListInfo *TemplateArgs = 0) {
NestedNameSpecifier *Qualifier = 0;
SourceRange QualifierRange;
@@ -1515,14 +1616,15 @@ static MemberExpr *BuildMemberExpr(ASTContext &C, Expr *Base, bool isArrow,
}
return MemberExpr::Create(C, Base, isArrow, Qualifier, QualifierRange,
- Member, FoundDecl, Loc, TemplateArgs, Ty);
+ Member, FoundDecl, MemberNameInfo,
+ TemplateArgs, Ty);
}
/// Builds an implicit member access expression. The current context
/// is known to be an instance method, and the given unqualified lookup
/// set is known to contain only instance members, at least one of which
/// is from an appropriate type.
-Sema::OwningExprResult
+ExprResult
Sema::BuildImplicitMemberExpr(const CXXScopeSpec &SS,
LookupResult &R,
const TemplateArgumentListInfo *TemplateArgs,
@@ -1551,7 +1653,7 @@ Sema::BuildImplicitMemberExpr(const CXXScopeSpec &SS,
This = new (Context) CXXThisExpr(Loc, ThisType, /*isImplicit=*/true);
}
- return BuildMemberReferenceExpr(ExprArg(*this, This), ThisType,
+ return BuildMemberReferenceExpr(This, ThisType,
/*OpLoc*/ SourceLocation(),
/*IsArrow*/ true,
SS,
@@ -1638,14 +1740,15 @@ static bool CheckDeclInExpr(Sema &S, SourceLocation Loc, NamedDecl *D) {
return false;
}
-Sema::OwningExprResult
+ExprResult
Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
LookupResult &R,
bool NeedsADL) {
// If this is a single, fully-resolved result and we don't need ADL,
// just build an ordinary singleton decl ref.
if (!NeedsADL && R.isSingleResult() && !R.getAsSingle<FunctionTemplateDecl>())
- return BuildDeclarationNameExpr(SS, R.getNameLoc(), R.getFoundDecl());
+ return BuildDeclarationNameExpr(SS, R.getLookupNameInfo(),
+ R.getFoundDecl());
// We only need to check the declaration if there's exactly one
// result, because in the overloaded case the results can only be
@@ -1664,8 +1767,7 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
UnresolvedLookupExpr *ULE
= UnresolvedLookupExpr::Create(Context, Dependent, R.getNamingClass(),
(NestedNameSpecifier*) SS.getScopeRep(),
- SS.getRange(),
- R.getLookupName(), R.getNameLoc(),
+ SS.getRange(), R.getLookupNameInfo(),
NeedsADL, R.isOverloadedResult(),
R.begin(), R.end());
@@ -1674,13 +1776,15 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
/// \brief Complete semantic analysis for a reference to the given declaration.
-Sema::OwningExprResult
+ExprResult
Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
- SourceLocation Loc, NamedDecl *D) {
+ const DeclarationNameInfo &NameInfo,
+ NamedDecl *D) {
assert(D && "Cannot refer to a NULL declaration");
assert(!isa<FunctionTemplateDecl>(D) &&
"Cannot refer unambiguously to a function template");
+ SourceLocation Loc = NameInfo.getLoc();
if (CheckDeclInExpr(*this, Loc, D))
return ExprError();
@@ -1755,13 +1859,13 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
DeclRefExpr(const_cast<ValueDecl*>(BDRE->getDecl()), T,
SourceLocation());
- OwningExprResult Res = PerformCopyInitialization(
+ ExprResult Res = PerformCopyInitialization(
InitializedEntity::InitializeBlock(VD->getLocation(),
T, false),
SourceLocation(),
Owned(E));
if (!Res.isInvalid()) {
- Res = MaybeCreateCXXExprWithTemporaries(move(Res));
+ Res = MaybeCreateCXXExprWithTemporaries(Res.get());
Expr *Init = Res.takeAs<Expr>();
BDRE->setCopyConstructorExpr(Init);
}
@@ -1772,10 +1876,11 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS,
// If this reference is not in a block or if the referenced variable is
// within the block, create a normal DeclRefExpr.
- return BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), Loc, &SS);
+ return BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
+ NameInfo, &SS);
}
-Sema::OwningExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc,
+ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc,
tok::TokenKind Kind) {
PredefinedExpr::IdentType IT;
@@ -1790,6 +1895,8 @@ Sema::OwningExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc,
// string.
Decl *currentDecl = getCurFunctionOrMethodDecl();
+ if (!currentDecl && getCurBlock())
+ currentDecl = getCurBlock()->TheDecl;
if (!currentDecl) {
Diag(Loc, diag::ext_predef_outside_function);
currentDecl = Context.getTranslationUnitDecl();
@@ -1808,7 +1915,7 @@ Sema::OwningExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc,
return Owned(new (Context) PredefinedExpr(Loc, ResTy, IT));
}
-Sema::OwningExprResult Sema::ActOnCharacterConstant(const Token &Tok) {
+ExprResult Sema::ActOnCharacterConstant(const Token &Tok) {
llvm::SmallString<16> CharBuffer;
bool Invalid = false;
llvm::StringRef ThisTok = PP.getSpelling(Tok, CharBuffer, &Invalid);
@@ -1835,13 +1942,13 @@ Sema::OwningExprResult Sema::ActOnCharacterConstant(const Token &Tok) {
Ty, Tok.getLocation()));
}
-Action::OwningExprResult Sema::ActOnNumericConstant(const Token &Tok) {
+ExprResult Sema::ActOnNumericConstant(const Token &Tok) {
// Fast path for a single digit (which is quite common). A single digit
// cannot have a trigraph, escaped newline, radix prefix, or type suffix.
if (Tok.getLength() == 1) {
const char Val = PP.getSpellingOfSingleCharacterNumericConstant(Tok);
unsigned IntSize = Context.Target.getIntWidth();
- return Owned(new (Context) IntegerLiteral(llvm::APInt(IntSize, Val-'0'),
+ return Owned(IntegerLiteral::Create(Context, llvm::APInt(IntSize, Val-'0'),
Context.IntTy, Tok.getLocation()));
}
@@ -1899,7 +2006,7 @@ Action::OwningExprResult Sema::ActOnNumericConstant(const Token &Tok) {
}
bool isExact = (result == APFloat::opOK);
- Res = new (Context) FloatingLiteral(Val, isExact, Ty, Tok.getLocation());
+ Res = FloatingLiteral::Create(Context, Val, isExact, Ty, Tok.getLocation());
} else if (!Literal.isIntegerLiteral()) {
return ExprError();
@@ -1986,7 +2093,7 @@ Action::OwningExprResult Sema::ActOnNumericConstant(const Token &Tok) {
if (ResultVal.getBitWidth() != Width)
ResultVal.trunc(Width);
}
- Res = new (Context) IntegerLiteral(ResultVal, Ty, Tok.getLocation());
+ Res = IntegerLiteral::Create(Context, ResultVal, Ty, Tok.getLocation());
}
// If this is an imaginary literal, create the ImaginaryLiteral wrapper.
@@ -1997,9 +2104,8 @@ Action::OwningExprResult Sema::ActOnNumericConstant(const Token &Tok) {
return Owned(Res);
}
-Action::OwningExprResult Sema::ActOnParenExpr(SourceLocation L,
- SourceLocation R, ExprArg Val) {
- Expr *E = Val.takeAs<Expr>();
+ExprResult Sema::ActOnParenExpr(SourceLocation L,
+ SourceLocation R, Expr *E) {
assert((E != 0) && "ActOnParenExpr() missing expr");
return Owned(new (Context) ParenExpr(L, R, E));
}
@@ -2083,7 +2189,7 @@ bool Sema::CheckAlignOfExpr(Expr *E, SourceLocation OpLoc,
}
/// \brief Build a sizeof or alignof expression given a type operand.
-Action::OwningExprResult
+ExprResult
Sema::CreateSizeOfAlignOfExpr(TypeSourceInfo *TInfo,
SourceLocation OpLoc,
bool isSizeOf, SourceRange R) {
@@ -2104,7 +2210,7 @@ Sema::CreateSizeOfAlignOfExpr(TypeSourceInfo *TInfo,
/// \brief Build a sizeof or alignof expression given an expression
/// operand.
-Action::OwningExprResult
+ExprResult
Sema::CreateSizeOfAlignOfExpr(Expr *E, SourceLocation OpLoc,
bool isSizeOf, SourceRange R) {
// Verify that the operand is valid.
@@ -2132,7 +2238,7 @@ Sema::CreateSizeOfAlignOfExpr(Expr *E, SourceLocation OpLoc,
/// ActOnSizeOfAlignOfExpr - Handle @c sizeof(type) and @c sizeof @c expr and
/// the same for @c alignof and @c __alignof
/// Note that the ArgRange is invalid if isType is false.
-Action::OwningExprResult
+ExprResult
Sema::ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType,
void *TyOrEx, const SourceRange &ArgRange) {
// If error parsing type, ignore.
@@ -2140,17 +2246,14 @@ Sema::ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType,
if (isType) {
TypeSourceInfo *TInfo;
- (void) GetTypeFromParser(TyOrEx, &TInfo);
+ (void) GetTypeFromParser(ParsedType::getFromOpaquePtr(TyOrEx), &TInfo);
return CreateSizeOfAlignOfExpr(TInfo, OpLoc, isSizeof, ArgRange);
}
Expr *ArgEx = (Expr *)TyOrEx;
- Action::OwningExprResult Result
+ ExprResult Result
= CreateSizeOfAlignOfExpr(ArgEx, OpLoc, isSizeof, ArgEx->getSourceRange());
- if (Result.isInvalid())
- DeleteExpr(ArgEx);
-
return move(Result);
}
@@ -2174,32 +2277,31 @@ QualType Sema::CheckRealImagOperand(Expr *&V, SourceLocation Loc, bool isReal) {
-Action::OwningExprResult
+ExprResult
Sema::ActOnPostfixUnaryOp(Scope *S, SourceLocation OpLoc,
- tok::TokenKind Kind, ExprArg Input) {
- UnaryOperator::Opcode Opc;
+ tok::TokenKind Kind, Expr *Input) {
+ UnaryOperatorKind Opc;
switch (Kind) {
default: assert(0 && "Unknown unary op!");
- case tok::plusplus: Opc = UnaryOperator::PostInc; break;
- case tok::minusminus: Opc = UnaryOperator::PostDec; break;
+ case tok::plusplus: Opc = UO_PostInc; break;
+ case tok::minusminus: Opc = UO_PostDec; break;
}
- return BuildUnaryOp(S, OpLoc, Opc, move(Input));
+ return BuildUnaryOp(S, OpLoc, Opc, Input);
}
-Action::OwningExprResult
-Sema::ActOnArraySubscriptExpr(Scope *S, ExprArg Base, SourceLocation LLoc,
- ExprArg Idx, SourceLocation RLoc) {
+ExprResult
+Sema::ActOnArraySubscriptExpr(Scope *S, Expr *Base, SourceLocation LLoc,
+ Expr *Idx, SourceLocation RLoc) {
// Since this might be a postfix expression, get rid of ParenListExprs.
- Base = MaybeConvertParenListExprToParenExpr(S, move(Base));
+ ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Base);
+ if (Result.isInvalid()) return ExprError();
+ Base = Result.take();
- Expr *LHSExp = static_cast<Expr*>(Base.get()),
- *RHSExp = static_cast<Expr*>(Idx.get());
+ Expr *LHSExp = Base, *RHSExp = Idx;
if (getLangOptions().CPlusPlus &&
(LHSExp->isTypeDependent() || RHSExp->isTypeDependent())) {
- Base.release();
- Idx.release();
return Owned(new (Context) ArraySubscriptExpr(LHSExp, RHSExp,
Context.DependentTy, RLoc));
}
@@ -2209,18 +2311,18 @@ Sema::ActOnArraySubscriptExpr(Scope *S, ExprArg Base, SourceLocation LLoc,
LHSExp->getType()->isEnumeralType() ||
RHSExp->getType()->isRecordType() ||
RHSExp->getType()->isEnumeralType())) {
- return CreateOverloadedArraySubscriptExpr(LLoc, RLoc, move(Base),move(Idx));
+ return CreateOverloadedArraySubscriptExpr(LLoc, RLoc, Base, Idx);
}
- return CreateBuiltinArraySubscriptExpr(move(Base), LLoc, move(Idx), RLoc);
+ return CreateBuiltinArraySubscriptExpr(Base, LLoc, Idx, RLoc);
}
-Action::OwningExprResult
-Sema::CreateBuiltinArraySubscriptExpr(ExprArg Base, SourceLocation LLoc,
- ExprArg Idx, SourceLocation RLoc) {
- Expr *LHSExp = static_cast<Expr*>(Base.get());
- Expr *RHSExp = static_cast<Expr*>(Idx.get());
+ExprResult
+Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc,
+ Expr *Idx, SourceLocation RLoc) {
+ Expr *LHSExp = Base;
+ Expr *RHSExp = Idx;
// Perform default conversions.
if (!LHSExp->getType()->getAs<VectorType>())
@@ -2274,7 +2376,7 @@ Sema::CreateBuiltinArraySubscriptExpr(ExprArg Base, SourceLocation LLoc,
Diag(LHSExp->getLocStart(), diag::ext_subscript_non_lvalue) <<
LHSExp->getSourceRange();
ImpCastExprToType(LHSExp, Context.getArrayDecayedType(LHSTy),
- CastExpr::CK_ArrayToPointerDecay);
+ CK_ArrayToPointerDecay);
LHSTy = LHSExp->getType();
BaseExpr = LHSExp;
@@ -2285,7 +2387,7 @@ Sema::CreateBuiltinArraySubscriptExpr(ExprArg Base, SourceLocation LLoc,
Diag(RHSExp->getLocStart(), diag::ext_subscript_non_lvalue) <<
RHSExp->getSourceRange();
ImpCastExprToType(RHSExp, Context.getArrayDecayedType(RHSTy),
- CastExpr::CK_ArrayToPointerDecay);
+ CK_ArrayToPointerDecay);
RHSTy = RHSExp->getType();
BaseExpr = RHSExp;
@@ -2296,8 +2398,7 @@ Sema::CreateBuiltinArraySubscriptExpr(ExprArg Base, SourceLocation LLoc,
<< LHSExp->getSourceRange() << RHSExp->getSourceRange());
}
// C99 6.5.2.1p1
- if (!(IndexExpr->getType()->isIntegerType() &&
- IndexExpr->getType()->isScalarType()) && !IndexExpr->isTypeDependent())
+ if (!IndexExpr->getType()->isIntegerType() && !IndexExpr->isTypeDependent())
return ExprError(Diag(LLoc, diag::err_typecheck_subscript_not_integer)
<< IndexExpr->getSourceRange());
@@ -2329,8 +2430,6 @@ Sema::CreateBuiltinArraySubscriptExpr(ExprArg Base, SourceLocation LLoc,
return ExprError();
}
- Base.release();
- Idx.release();
return Owned(new (Context) ArraySubscriptExpr(LHSExp, RHSExp,
ResultType, RLoc));
}
@@ -2377,7 +2476,7 @@ CheckExtVectorComponent(QualType baseType, SourceLocation OpLoc,
// We didn't get to the end of the string. This means the component names
// didn't come from the same set *or* we encountered an illegal name.
Diag(OpLoc, diag::err_ext_vector_component_name_illegal)
- << std::string(compStr,compStr+1) << SourceRange(CompLoc);
+ << llvm::StringRef(compStr, 1) << SourceRange(CompLoc);
return QualType();
}
@@ -2470,15 +2569,13 @@ static Decl *FindGetterNameDecl(const ObjCObjectPointerType *QIdTy,
return GDecl;
}
-Sema::OwningExprResult
-Sema::ActOnDependentMemberExpr(ExprArg Base, QualType BaseType,
+ExprResult
+Sema::ActOnDependentMemberExpr(Expr *BaseExpr, QualType BaseType,
bool IsArrow, SourceLocation OpLoc,
const CXXScopeSpec &SS,
NamedDecl *FirstQualifierInScope,
- DeclarationName Name, SourceLocation NameLoc,
+ const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *TemplateArgs) {
- Expr *BaseExpr = Base.takeAs<Expr>();
-
// Even in dependent contexts, try to diagnose base expressions with
// obviously wrong types, e.g.:
//
@@ -2493,24 +2590,24 @@ Sema::ActOnDependentMemberExpr(ExprArg Base, QualType BaseType,
if (PT && (!getLangOptions().ObjC1 ||
PT->getPointeeType()->isRecordType())) {
assert(BaseExpr && "cannot happen with implicit member accesses");
- Diag(NameLoc, diag::err_typecheck_member_reference_struct_union)
+ Diag(NameInfo.getLoc(), diag::err_typecheck_member_reference_struct_union)
<< BaseType << BaseExpr->getSourceRange();
return ExprError();
}
}
- assert(BaseType->isDependentType() || Name.isDependentName() ||
+ assert(BaseType->isDependentType() ||
+ NameInfo.getName().isDependentName() ||
isDependentScopeSpecifier(SS));
// Get the type being accessed in BaseType. If this is an arrow, the BaseExpr
// must have pointer type, and the accessed type is the pointee.
return Owned(CXXDependentScopeMemberExpr::Create(Context, BaseExpr, BaseType,
IsArrow, OpLoc,
- static_cast<NestedNameSpecifier*>(SS.getScopeRep()),
+ SS.getScopeRep(),
SS.getRange(),
FirstQualifierInScope,
- Name, NameLoc,
- TemplateArgs));
+ NameInfo, TemplateArgs));
}
/// We know that the given qualified member reference points only to
@@ -2562,12 +2659,15 @@ bool Sema::CheckQualifiedMemberReference(Expr *BaseExpr,
return false;
// Note that we use the DC of the decl, not the underlying decl.
- CXXRecordDecl *RecordD = cast<CXXRecordDecl>((*I)->getDeclContext());
- while (RecordD->isAnonymousStructOrUnion())
- RecordD = cast<CXXRecordDecl>(RecordD->getParent());
+ DeclContext *DC = (*I)->getDeclContext();
+ while (DC->isTransparentContext())
+ DC = DC->getParent();
+ if (!DC->isRecord())
+ continue;
+
llvm::SmallPtrSet<CXXRecordDecl*,4> MemberRecord;
- MemberRecord.insert(RecordD->getCanonicalDecl());
+ MemberRecord.insert(cast<CXXRecordDecl>(DC)->getCanonicalDecl());
if (!IsProvablyNotDerivedFrom(*this, BaseRecord, MemberRecord))
return false;
@@ -2646,24 +2746,21 @@ LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R,
return false;
}
-Sema::OwningExprResult
-Sema::BuildMemberReferenceExpr(ExprArg BaseArg, QualType BaseType,
+ExprResult
+Sema::BuildMemberReferenceExpr(Expr *Base, QualType BaseType,
SourceLocation OpLoc, bool IsArrow,
CXXScopeSpec &SS,
NamedDecl *FirstQualifierInScope,
- DeclarationName Name, SourceLocation NameLoc,
+ const DeclarationNameInfo &NameInfo,
const TemplateArgumentListInfo *TemplateArgs) {
- Expr *Base = BaseArg.takeAs<Expr>();
-
if (BaseType->isDependentType() ||
(SS.isSet() && isDependentScopeSpecifier(SS)))
- return ActOnDependentMemberExpr(ExprArg(*this, Base), BaseType,
+ return ActOnDependentMemberExpr(Base, BaseType,
IsArrow, OpLoc,
SS, FirstQualifierInScope,
- Name, NameLoc,
- TemplateArgs);
+ NameInfo, TemplateArgs);
- LookupResult R(*this, Name, NameLoc, LookupMemberName);
+ LookupResult R(*this, NameInfo, LookupMemberName);
// Implicit member accesses.
if (!Base) {
@@ -2676,9 +2773,9 @@ Sema::BuildMemberReferenceExpr(ExprArg BaseArg, QualType BaseType,
// Explicit member accesses.
} else {
- OwningExprResult Result =
+ ExprResult Result =
LookupMemberExpr(R, Base, IsArrow, OpLoc,
- SS, /*ObjCImpDecl*/ DeclPtrTy(), TemplateArgs != 0);
+ SS, /*ObjCImpDecl*/ 0, TemplateArgs != 0);
if (Result.isInvalid()) {
Owned(Base);
@@ -2692,20 +2789,19 @@ Sema::BuildMemberReferenceExpr(ExprArg BaseArg, QualType BaseType,
BaseType = Base->getType();
}
- return BuildMemberReferenceExpr(ExprArg(*this, Base), BaseType,
+ return BuildMemberReferenceExpr(Base, BaseType,
OpLoc, IsArrow, SS, FirstQualifierInScope,
R, TemplateArgs);
}
-Sema::OwningExprResult
-Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType,
+ExprResult
+Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType,
SourceLocation OpLoc, bool IsArrow,
const CXXScopeSpec &SS,
NamedDecl *FirstQualifierInScope,
LookupResult &R,
const TemplateArgumentListInfo *TemplateArgs,
bool SuppressQualifierCheck) {
- Expr *BaseExpr = Base.takeAs<Expr>();
QualType BaseType = BaseExprType;
if (IsArrow) {
assert(BaseType->isPointerType());
@@ -2713,10 +2809,10 @@ Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType,
}
R.setBaseObjectType(BaseType);
- NestedNameSpecifier *Qualifier =
- static_cast<NestedNameSpecifier*>(SS.getScopeRep());
- DeclarationName MemberName = R.getLookupName();
- SourceLocation MemberLoc = R.getNameLoc();
+ NestedNameSpecifier *Qualifier = SS.getScopeRep();
+ const DeclarationNameInfo &MemberNameInfo = R.getLookupNameInfo();
+ DeclarationName MemberName = MemberNameInfo.getName();
+ SourceLocation MemberLoc = MemberNameInfo.getLoc();
if (R.isAmbiguous())
return ExprError();
@@ -2765,7 +2861,7 @@ Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType,
BaseExpr, BaseExprType,
IsArrow, OpLoc,
Qualifier, SS.getRange(),
- MemberName, MemberLoc,
+ MemberNameInfo,
TemplateArgs, R.begin(), R.end());
return Owned(MemExpr);
@@ -2787,7 +2883,7 @@ Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType,
if (!BaseExpr) {
// If this is not an instance member, convert to a non-member access.
if (!MemberDecl->isCXXInstanceMember())
- return BuildDeclarationNameExpr(SS, R.getNameLoc(), MemberDecl);
+ return BuildDeclarationNameExpr(SS, R.getLookupNameInfo(), MemberDecl);
SourceLocation Loc = R.getNameLoc();
if (SS.getRange().isValid())
@@ -2838,34 +2934,36 @@ Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType,
if (PerformObjectMemberConversion(BaseExpr, Qualifier, FoundDecl, FD))
return ExprError();
return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS,
- FD, FoundDecl, MemberLoc, MemberType));
+ FD, FoundDecl, MemberNameInfo,
+ MemberType));
}
if (VarDecl *Var = dyn_cast<VarDecl>(MemberDecl)) {
MarkDeclarationReferenced(MemberLoc, Var);
return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS,
- Var, FoundDecl, MemberLoc,
+ Var, FoundDecl, MemberNameInfo,
Var->getType().getNonReferenceType()));
}
if (FunctionDecl *MemberFn = dyn_cast<FunctionDecl>(MemberDecl)) {
MarkDeclarationReferenced(MemberLoc, MemberDecl);
return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS,
- MemberFn, FoundDecl, MemberLoc,
+ MemberFn, FoundDecl, MemberNameInfo,
MemberFn->getType()));
}
if (EnumConstantDecl *Enum = dyn_cast<EnumConstantDecl>(MemberDecl)) {
MarkDeclarationReferenced(MemberLoc, MemberDecl);
return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS,
- Enum, FoundDecl, MemberLoc, Enum->getType()));
+ Enum, FoundDecl, MemberNameInfo,
+ Enum->getType()));
}
Owned(BaseExpr);
// We found something that we didn't expect. Complain.
if (isa<TypeDecl>(MemberDecl))
- Diag(MemberLoc,diag::err_typecheck_member_reference_type)
+ Diag(MemberLoc, diag::err_typecheck_member_reference_type)
<< MemberName << BaseType << int(IsArrow);
else
Diag(MemberLoc, diag::err_typecheck_member_reference_unknown)
@@ -2887,11 +2985,11 @@ Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType,
///
/// The ObjCImpDecl bit is a gross hack that will need to be properly
/// fixed for ObjC++.
-Sema::OwningExprResult
+ExprResult
Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
bool &IsArrow, SourceLocation OpLoc,
CXXScopeSpec &SS,
- DeclPtrTy ObjCImpDecl, bool HasTemplateArgs) {
+ Decl *ObjCImpDecl, bool HasTemplateArgs) {
assert(BaseExpr && "no base expression");
// Perform default conversions.
@@ -2921,8 +3019,8 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
<< QualType(Fun, 0)
<< FixItHint::CreateInsertion(Loc, "()");
- OwningExprResult NewBase
- = ActOnCallExpr(0, ExprArg(*this, BaseExpr), Loc,
+ ExprResult NewBase
+ = ActOnCallExpr(0, BaseExpr, Loc,
MultiExprArg(*this, 0, 0), 0, Loc);
BaseExpr = 0;
if (NewBase.isInvalid())
@@ -2952,7 +3050,7 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
// is a reference to 'isa'.
if (BaseType != Context.ObjCIdRedefinitionType) {
BaseType = Context.ObjCIdRedefinitionType;
- ImpCastExprToType(BaseExpr, BaseType, CastExpr::CK_BitCast);
+ ImpCastExprToType(BaseExpr, BaseType, CK_BitCast);
}
}
@@ -2963,7 +3061,7 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
// is a reference to 'sel_id'.
if (BaseType != Context.ObjCSelRedefinitionType) {
BaseType = Context.ObjCSelRedefinitionType;
- ImpCastExprToType(BaseExpr, BaseType, CastExpr::CK_BitCast);
+ ImpCastExprToType(BaseExpr, BaseType, CK_BitCast);
}
}
@@ -3022,7 +3120,7 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
if (BaseType->isObjCClassType() &&
BaseType != Context.ObjCClassRedefinitionType) {
BaseType = Context.ObjCClassRedefinitionType;
- ImpCastExprToType(BaseExpr, BaseType, CastExpr::CK_BitCast);
+ ImpCastExprToType(BaseExpr, BaseType, CK_BitCast);
}
if (IsArrow) {
@@ -3129,12 +3227,11 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
// down the context as argument to this routine. Ideally, this context
// need be passed down in the AST node and somehow calculated from the
// AST for a function decl.
- Decl *ImplDecl = ObjCImpDecl.getAs<Decl>();
if (ObjCImplementationDecl *IMPD =
- dyn_cast<ObjCImplementationDecl>(ImplDecl))
+ dyn_cast<ObjCImplementationDecl>(ObjCImpDecl))
ClassOfMethodDecl = IMPD->getClassInterface();
else if (ObjCCategoryImplDecl* CatImplClass =
- dyn_cast<ObjCCategoryImplDecl>(ImplDecl))
+ dyn_cast<ObjCCategoryImplDecl>(ObjCImpDecl))
ClassOfMethodDecl = CatImplClass->getClassInterface();
}
@@ -3235,12 +3332,12 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
/// \param ObjCImpDecl the current ObjC @implementation decl;
/// this is an ugly hack around the fact that ObjC @implementations
/// aren't properly put in the context chain
-Sema::OwningExprResult Sema::ActOnMemberAccessExpr(Scope *S, ExprArg BaseArg,
+ExprResult Sema::ActOnMemberAccessExpr(Scope *S, Expr *Base,
SourceLocation OpLoc,
tok::TokenKind OpKind,
CXXScopeSpec &SS,
UnqualifiedId &Id,
- DeclPtrTy ObjCImpDecl,
+ Decl *ObjCImpDecl,
bool HasTrailingLParen) {
if (SS.isSet() && SS.isInvalid())
return ExprError();
@@ -3248,12 +3345,12 @@ Sema::OwningExprResult Sema::ActOnMemberAccessExpr(Scope *S, ExprArg BaseArg,
TemplateArgumentListInfo TemplateArgsBuffer;
// Decompose the name into its component parts.
- DeclarationName Name;
- SourceLocation NameLoc;
+ DeclarationNameInfo NameInfo;
const TemplateArgumentListInfo *TemplateArgs;
DecomposeUnqualifiedId(*this, Id, TemplateArgsBuffer,
- Name, NameLoc, TemplateArgs);
+ NameInfo, TemplateArgs);
+ DeclarationName Name = NameInfo.getName();
bool IsArrow = (OpKind == tok::arrow);
NamedDecl *FirstQualifierInScope
@@ -3261,19 +3358,18 @@ Sema::OwningExprResult Sema::ActOnMemberAccessExpr(Scope *S, ExprArg BaseArg,
static_cast<NestedNameSpecifier*>(SS.getScopeRep())));
// This is a postfix expression, so get rid of ParenListExprs.
- BaseArg = MaybeConvertParenListExprToParenExpr(S, move(BaseArg));
+ ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Base);
+ if (Result.isInvalid()) return ExprError();
+ Base = Result.take();
- Expr *Base = BaseArg.takeAs<Expr>();
- OwningExprResult Result(*this);
if (Base->getType()->isDependentType() || Name.isDependentName() ||
isDependentScopeSpecifier(SS)) {
- Result = ActOnDependentMemberExpr(ExprArg(*this, Base), Base->getType(),
+ Result = ActOnDependentMemberExpr(Base, Base->getType(),
IsArrow, OpLoc,
SS, FirstQualifierInScope,
- Name, NameLoc,
- TemplateArgs);
+ NameInfo, TemplateArgs);
} else {
- LookupResult R(*this, Name, NameLoc, LookupMemberName);
+ LookupResult R(*this, NameInfo, LookupMemberName);
Result = LookupMemberExpr(R, Base, IsArrow, OpLoc,
SS, ObjCImpDecl, TemplateArgs != 0);
@@ -3289,12 +3385,12 @@ Sema::OwningExprResult Sema::ActOnMemberAccessExpr(Scope *S, ExprArg BaseArg,
// call now.
if (!HasTrailingLParen &&
Id.getKind() == UnqualifiedId::IK_DestructorName)
- return DiagnoseDtorReference(NameLoc, move(Result));
+ return DiagnoseDtorReference(NameInfo.getLoc(), Result.get());
return move(Result);
}
- Result = BuildMemberReferenceExpr(ExprArg(*this, Base), Base->getType(),
+ Result = BuildMemberReferenceExpr(Base, Base->getType(),
OpLoc, IsArrow, SS, FirstQualifierInScope,
R, TemplateArgs);
}
@@ -3302,7 +3398,7 @@ Sema::OwningExprResult Sema::ActOnMemberAccessExpr(Scope *S, ExprArg BaseArg,
return move(Result);
}
-Sema::OwningExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
+ExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
FunctionDecl *FD,
ParmVarDecl *Param) {
if (Param->hasUnparsedDefaultArg()) {
@@ -3324,7 +3420,7 @@ Sema::OwningExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
InstantiatingTemplate Inst(*this, CallLoc, Param, Innermost.first,
Innermost.second);
- OwningExprResult Result = SubstExpr(UninstExpr, ArgList);
+ ExprResult Result = SubstExpr(UninstExpr, ArgList);
if (Result.isInvalid())
return ExprError();
@@ -3338,7 +3434,7 @@ Sema::OwningExprResult Sema::BuildCXXDefaultArgExpr(SourceLocation CallLoc,
InitializationSequence InitSeq(*this, Entity, Kind, &ResultE, 1);
Result = InitSeq.Perform(*this, Entity, Kind,
- MultiExprArg(*this, (void**)&ResultE, 1));
+ MultiExprArg(*this, &ResultE, 1));
if (Result.isInvalid())
return ExprError();
@@ -3457,7 +3553,7 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc,
InitializedEntity Entity =
Param? InitializedEntity::InitializeParameter(Param)
: InitializedEntity::InitializeParameter(ProtoArgType);
- OwningExprResult ArgE = PerformCopyInitialization(Entity,
+ ExprResult ArgE = PerformCopyInitialization(Entity,
SourceLocation(),
Owned(Arg));
if (ArgE.isInvalid())
@@ -3467,7 +3563,7 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc,
} else {
ParmVarDecl *Param = FDecl->getParamDecl(i);
- OwningExprResult ArgExpr =
+ ExprResult ArgExpr =
BuildCXXDefaultArgExpr(CallLoc, FDecl, Param);
if (ArgExpr.isInvalid())
return true;
@@ -3492,18 +3588,18 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc,
/// 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.
-Action::OwningExprResult
-Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
+ExprResult
+Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc,
MultiExprArg args,
SourceLocation *CommaLocs, SourceLocation RParenLoc) {
unsigned NumArgs = args.size();
// Since this might be a postfix expression, get rid of ParenListExprs.
- fn = MaybeConvertParenListExprToParenExpr(S, move(fn));
+ ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Fn);
+ if (Result.isInvalid()) return ExprError();
+ Fn = Result.take();
- Expr *Fn = fn.takeAs<Expr>();
- Expr **Args = reinterpret_cast<Expr**>(args.release());
- assert(Fn && "no function call expression");
+ Expr **Args = args.release();
if (getLangOptions().CPlusPlus) {
// If this is a pseudo-destructor expression, build the call immediately.
@@ -3515,9 +3611,6 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
SourceRange(Args[0]->getLocStart(),
Args[NumArgs-1]->getLocEnd()));
- for (unsigned I = 0; I != NumArgs; ++I)
- Args[I]->Destroy(Context);
-
NumArgs = 0;
}
@@ -3572,27 +3665,27 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
// Determine whether this is a call to a pointer-to-member function.
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(NakedFn)) {
- if (BO->getOpcode() == BinaryOperator::PtrMemD ||
- BO->getOpcode() == BinaryOperator::PtrMemI) {
+ if (BO->getOpcode() == BO_PtrMemD ||
+ BO->getOpcode() == BO_PtrMemI) {
if (const FunctionProtoType *FPT
= BO->getType()->getAs<FunctionProtoType>()) {
QualType ResultTy = FPT->getCallResultType(Context);
- ExprOwningPtr<CXXMemberCallExpr>
- TheCall(this, new (Context) CXXMemberCallExpr(Context, BO, Args,
- NumArgs, ResultTy,
- RParenLoc));
+ CXXMemberCallExpr *TheCall
+ = new (Context) CXXMemberCallExpr(Context, BO, Args,
+ NumArgs, ResultTy,
+ RParenLoc);
if (CheckCallReturnType(FPT->getResultType(),
BO->getRHS()->getSourceRange().getBegin(),
- TheCall.get(), 0))
+ TheCall, 0))
return ExprError();
- if (ConvertArgumentsForCall(&*TheCall, BO, 0, FPT, Args, NumArgs,
+ if (ConvertArgumentsForCall(TheCall, BO, 0, FPT, Args, NumArgs,
RParenLoc))
return ExprError();
- return Owned(MaybeBindToTemporary(TheCall.release()).release());
+ return MaybeBindToTemporary(TheCall);
}
return ExprError(Diag(Fn->getLocStart(),
diag::err_typecheck_call_not_function)
@@ -3625,7 +3718,7 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
/// block-pointer type.
///
/// \param NDecl the declaration being called, if available
-Sema::OwningExprResult
+ExprResult
Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
SourceLocation LParenLoc,
Expr **Args, unsigned NumArgs,
@@ -3637,10 +3730,10 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
// Make the call expr early, before semantic checks. This guarantees cleanup
// of arguments and function on error.
- ExprOwningPtr<CallExpr> TheCall(this, new (Context) CallExpr(Context, Fn,
- Args, NumArgs,
- Context.BoolTy,
- RParenLoc));
+ CallExpr *TheCall = new (Context) CallExpr(Context, Fn,
+ Args, NumArgs,
+ Context.BoolTy,
+ RParenLoc);
const FunctionType *FuncT;
if (!Fn->getType()->isBlockPointerType()) {
@@ -3661,7 +3754,7 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
// Check for a valid return type
if (CheckCallReturnType(FuncT->getResultType(),
- Fn->getSourceRange().getBegin(), TheCall.get(),
+ Fn->getSourceRange().getBegin(), TheCall,
FDecl))
return ExprError();
@@ -3669,7 +3762,7 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
TheCall->setType(FuncT->getCallResultType(Context));
if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FuncT)) {
- if (ConvertArgumentsForCall(&*TheCall, Fn, FDecl, Proto, Args, NumArgs,
+ if (ConvertArgumentsForCall(TheCall, Fn, FDecl, Proto, Args, NumArgs,
RParenLoc))
return ExprError();
} else {
@@ -3713,22 +3806,22 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
// Do special checking on direct calls to functions.
if (FDecl) {
- if (CheckFunctionCall(FDecl, TheCall.get()))
+ if (CheckFunctionCall(FDecl, TheCall))
return ExprError();
if (unsigned BuiltinID = FDecl->getBuiltinID())
- return CheckBuiltinFunctionCall(BuiltinID, TheCall.take());
+ return CheckBuiltinFunctionCall(BuiltinID, TheCall);
} else if (NDecl) {
- if (CheckBlockCall(NDecl, TheCall.get()))
+ if (CheckBlockCall(NDecl, TheCall))
return ExprError();
}
- return MaybeBindToTemporary(TheCall.take());
+ return MaybeBindToTemporary(TheCall);
}
-Action::OwningExprResult
-Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, TypeTy *Ty,
- SourceLocation RParenLoc, ExprArg InitExpr) {
+ExprResult
+Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, ParsedType Ty,
+ SourceLocation RParenLoc, Expr *InitExpr) {
assert((Ty != 0) && "ActOnCompoundLiteral(): missing type");
// FIXME: put back this assert when initializers are worked out.
//assert((InitExpr != 0) && "ActOnCompoundLiteral(): missing expression");
@@ -3738,14 +3831,13 @@ Sema::ActOnCompoundLiteral(SourceLocation LParenLoc, TypeTy *Ty,
if (!TInfo)
TInfo = Context.getTrivialTypeSourceInfo(literalType);
- return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, move(InitExpr));
+ return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, InitExpr);
}
-Action::OwningExprResult
+ExprResult
Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
- SourceLocation RParenLoc, ExprArg InitExpr) {
+ SourceLocation RParenLoc, Expr *literalExpr) {
QualType literalType = TInfo->getType();
- Expr *literalExpr = static_cast<Expr*>(InitExpr.get());
if (literalType->isArrayType()) {
if (literalType->isVariableArrayType())
@@ -3764,13 +3856,12 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
= InitializationKind::CreateCast(SourceRange(LParenLoc, RParenLoc),
/*IsCStyleCast=*/true);
InitializationSequence InitSeq(*this, Entity, Kind, &literalExpr, 1);
- OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind,
- MultiExprArg(*this, (void**)&literalExpr, 1),
+ ExprResult Result = InitSeq.Perform(*this, Entity, Kind,
+ MultiExprArg(*this, &literalExpr, 1),
&literalType);
if (Result.isInvalid())
return ExprError();
- InitExpr.release();
- literalExpr = static_cast<Expr*>(Result.get());
+ literalExpr = Result.get();
bool isFileScope = getCurFunctionOrMethodDecl() == 0;
if (isFileScope) { // 6.5.2.5p3
@@ -3778,17 +3869,15 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo,
return ExprError();
}
- Result.release();
-
return Owned(new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType,
literalExpr, isFileScope));
}
-Action::OwningExprResult
+ExprResult
Sema::ActOnInitList(SourceLocation LBraceLoc, MultiExprArg initlist,
SourceLocation RBraceLoc) {
unsigned NumInit = initlist.size();
- Expr **InitList = reinterpret_cast<Expr**>(initlist.release());
+ Expr **InitList = initlist.release();
// Semantic analysis for initializers is done by ActOnDeclarator() and
// CheckInitializer() - it requires knowledge of the object being intialized.
@@ -3799,45 +3888,45 @@ Sema::ActOnInitList(SourceLocation LBraceLoc, MultiExprArg initlist,
return Owned(E);
}
-static CastExpr::CastKind getScalarCastKind(ASTContext &Context,
+static CastKind getScalarCastKind(ASTContext &Context,
QualType SrcTy, QualType DestTy) {
if (Context.hasSameUnqualifiedType(SrcTy, DestTy))
- return CastExpr::CK_NoOp;
+ return CK_NoOp;
if (SrcTy->hasPointerRepresentation()) {
if (DestTy->hasPointerRepresentation())
return DestTy->isObjCObjectPointerType() ?
- CastExpr::CK_AnyPointerToObjCPointerCast :
- CastExpr::CK_BitCast;
+ CK_AnyPointerToObjCPointerCast :
+ CK_BitCast;
if (DestTy->isIntegerType())
- return CastExpr::CK_PointerToIntegral;
+ return CK_PointerToIntegral;
}
if (SrcTy->isIntegerType()) {
if (DestTy->isIntegerType())
- return CastExpr::CK_IntegralCast;
+ return CK_IntegralCast;
if (DestTy->hasPointerRepresentation())
- return CastExpr::CK_IntegralToPointer;
+ return CK_IntegralToPointer;
if (DestTy->isRealFloatingType())
- return CastExpr::CK_IntegralToFloating;
+ return CK_IntegralToFloating;
}
if (SrcTy->isRealFloatingType()) {
if (DestTy->isRealFloatingType())
- return CastExpr::CK_FloatingCast;
+ return CK_FloatingCast;
if (DestTy->isIntegerType())
- return CastExpr::CK_FloatingToIntegral;
+ return CK_FloatingToIntegral;
}
// FIXME: Assert here.
// assert(false && "Unhandled cast combination!");
- return CastExpr::CK_Unknown;
+ return CK_Unknown;
}
/// CheckCastTypes - Check type constraints for casting between types.
bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
- CastExpr::CastKind& Kind,
- CXXBaseSpecifierArray &BasePath,
+ CastKind& Kind,
+ CXXCastPath &BasePath,
bool FunctionalStyle) {
if (getLangOptions().CPlusPlus)
return CXXCheckCStyleCast(TyR, castType, castExpr, Kind, BasePath,
@@ -3849,10 +3938,14 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
// type needs to be scalar.
if (castType->isVoidType()) {
// Cast to void allows any expr type.
- Kind = CastExpr::CK_ToVoid;
+ Kind = CK_ToVoid;
return false;
}
+ if (RequireCompleteType(TyR.getBegin(), castType,
+ diag::err_typecheck_cast_to_incomplete))
+ return true;
+
if (!castType->isScalarType() && !castType->isVectorType()) {
if (Context.hasSameUnqualifiedType(castType, castExpr->getType()) &&
(castType->isStructureType() || castType->isUnionType())) {
@@ -3860,7 +3953,7 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
// FIXME: Check that the cast destination type is complete.
Diag(TyR.getBegin(), diag::ext_typecheck_cast_nonscalar)
<< castType << castExpr->getSourceRange();
- Kind = CastExpr::CK_NoOp;
+ Kind = CK_NoOp;
return false;
}
@@ -3880,7 +3973,7 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
if (Field == FieldEnd)
return Diag(TyR.getBegin(), diag::err_typecheck_cast_to_union_no_type)
<< castExpr->getType() << castExpr->getSourceRange();
- Kind = CastExpr::CK_ToUnion;
+ Kind = CK_ToUnion;
return false;
}
@@ -3922,11 +4015,15 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr,
}
Kind = getScalarCastKind(Context, castExpr->getType(), castType);
+
+ if (Kind == CK_Unknown || Kind == CK_BitCast)
+ CheckCastAlign(castExpr, castType, TyR);
+
return false;
}
bool Sema::CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty,
- CastExpr::CastKind &Kind) {
+ CastKind &Kind) {
assert(VectorTy->isVectorType() && "Not a vector type!");
if (Ty->isVectorType() || Ty->isIntegerType()) {
@@ -3941,12 +4038,12 @@ bool Sema::CheckVectorCast(SourceRange R, QualType VectorTy, QualType Ty,
diag::err_invalid_conversion_between_vector_and_scalar)
<< VectorTy << Ty << R;
- Kind = CastExpr::CK_BitCast;
+ Kind = CK_BitCast;
return false;
}
bool Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, Expr *&CastExpr,
- CastExpr::CastKind &Kind) {
+ CastKind &Kind) {
assert(DestTy->isExtVectorType() && "Not an extended vector type!");
QualType SrcTy = CastExpr->getType();
@@ -3957,7 +4054,7 @@ bool Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, Expr *&CastExpr,
if (Context.getTypeSize(DestTy) != Context.getTypeSize(SrcTy))
return Diag(R.getBegin(),diag::err_invalid_conversion_between_ext_vectors)
<< DestTy << SrcTy << R;
- Kind = CastExpr::CK_BitCast;
+ Kind = CK_BitCast;
return false;
}
@@ -3973,14 +4070,14 @@ bool Sema::CheckExtVectorCast(SourceRange R, QualType DestTy, Expr *&CastExpr,
ImpCastExprToType(CastExpr, DestElemTy,
getScalarCastKind(Context, SrcTy, DestElemTy));
- Kind = CastExpr::CK_VectorSplat;
+ Kind = CK_VectorSplat;
return false;
}
-Action::OwningExprResult
-Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, TypeTy *Ty,
- SourceLocation RParenLoc, ExprArg Op) {
- assert((Ty != 0) && (Op.get() != 0) &&
+ExprResult
+Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, ParsedType Ty,
+ SourceLocation RParenLoc, Expr *castExpr) {
+ assert((Ty != 0) && (castExpr != 0) &&
"ActOnCastExpr(): missing type or expr");
TypeSourceInfo *castTInfo;
@@ -3989,55 +4086,52 @@ Sema::ActOnCastExpr(Scope *S, SourceLocation LParenLoc, TypeTy *Ty,
castTInfo = Context.getTrivialTypeSourceInfo(castType);
// If the Expr being casted is a ParenListExpr, handle it specially.
- Expr *castExpr = (Expr *)Op.get();
if (isa<ParenListExpr>(castExpr))
- return ActOnCastOfParenListExpr(S, LParenLoc, RParenLoc, move(Op),
+ return ActOnCastOfParenListExpr(S, LParenLoc, RParenLoc, castExpr,
castTInfo);
- return BuildCStyleCastExpr(LParenLoc, castTInfo, RParenLoc, move(Op));
+ return BuildCStyleCastExpr(LParenLoc, castTInfo, RParenLoc, castExpr);
}
-Action::OwningExprResult
+ExprResult
Sema::BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty,
- SourceLocation RParenLoc, ExprArg Op) {
- Expr *castExpr = static_cast<Expr*>(Op.get());
-
- CastExpr::CastKind Kind = CastExpr::CK_Unknown;
- CXXBaseSpecifierArray BasePath;
+ SourceLocation RParenLoc, Expr *castExpr) {
+ CastKind Kind = CK_Unknown;
+ CXXCastPath BasePath;
if (CheckCastTypes(SourceRange(LParenLoc, RParenLoc), Ty->getType(), castExpr,
Kind, BasePath))
return ExprError();
- Op.release();
- return Owned(new (Context) CStyleCastExpr(
+ return Owned(CStyleCastExpr::Create(Context,
Ty->getType().getNonLValueExprType(Context),
- Kind, castExpr, BasePath, Ty,
- LParenLoc, RParenLoc));
+ Kind, castExpr, &BasePath, Ty,
+ LParenLoc, RParenLoc));
}
/// This is not an AltiVec-style cast, so turn the ParenListExpr into a sequence
/// of comma binary operators.
-Action::OwningExprResult
-Sema::MaybeConvertParenListExprToParenExpr(Scope *S, ExprArg EA) {
- Expr *expr = EA.takeAs<Expr>();
+ExprResult
+Sema::MaybeConvertParenListExprToParenExpr(Scope *S, Expr *expr) {
ParenListExpr *E = dyn_cast<ParenListExpr>(expr);
if (!E)
return Owned(expr);
- OwningExprResult Result(*this, E->getExpr(0));
+ ExprResult Result(E->getExpr(0));
for (unsigned i = 1, e = E->getNumExprs(); i != e && !Result.isInvalid(); ++i)
- Result = ActOnBinOp(S, E->getExprLoc(), tok::comma, move(Result),
- Owned(E->getExpr(i)));
+ Result = ActOnBinOp(S, E->getExprLoc(), tok::comma, Result.get(),
+ E->getExpr(i));
- return ActOnParenExpr(E->getLParenLoc(), E->getRParenLoc(), move(Result));
+ if (Result.isInvalid()) return ExprError();
+
+ return ActOnParenExpr(E->getLParenLoc(), E->getRParenLoc(), Result.get());
}
-Action::OwningExprResult
+ExprResult
Sema::ActOnCastOfParenListExpr(Scope *S, SourceLocation LParenLoc,
- SourceLocation RParenLoc, ExprArg Op,
+ SourceLocation RParenLoc, Expr *Op,
TypeSourceInfo *TInfo) {
- ParenListExpr *PE = (ParenListExpr *)Op.get();
+ ParenListExpr *PE = cast<ParenListExpr>(Op);
QualType Ty = TInfo->getType();
bool isAltiVecLiteral = false;
@@ -4065,24 +4159,24 @@ Sema::ActOnCastOfParenListExpr(Scope *S, SourceLocation LParenLoc,
// FIXME: This means that pretty-printing the final AST will produce curly
// braces instead of the original commas.
- Op.release();
InitListExpr *E = new (Context) InitListExpr(Context, LParenLoc,
&initExprs[0],
initExprs.size(), RParenLoc);
E->setType(Ty);
- return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, Owned(E));
+ return BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, E);
} else {
// This is not an AltiVec-style cast, so turn the ParenListExpr into a
// sequence of BinOp comma operators.
- Op = MaybeConvertParenListExprToParenExpr(S, move(Op));
- return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, move(Op));
+ ExprResult Result = MaybeConvertParenListExprToParenExpr(S, Op);
+ if (Result.isInvalid()) return ExprError();
+ return BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, Result.take());
}
}
-Action::OwningExprResult Sema::ActOnParenOrParenListExpr(SourceLocation L,
+ExprResult Sema::ActOnParenOrParenListExpr(SourceLocation L,
SourceLocation R,
MultiExprArg Val,
- TypeTy *TypeOfCast) {
+ ParsedType TypeOfCast) {
unsigned nexprs = Val.size();
Expr **exprs = reinterpret_cast<Expr**>(Val.release());
assert((exprs != 0) && "ActOnParenOrParenListExpr() missing expr list");
@@ -4148,8 +4242,8 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
if (!RHSTy->isVoidType())
Diag(LHS->getLocStart(), diag::ext_typecheck_cond_one_void)
<< LHS->getSourceRange();
- ImpCastExprToType(LHS, Context.VoidTy, CastExpr::CK_ToVoid);
- ImpCastExprToType(RHS, Context.VoidTy, CastExpr::CK_ToVoid);
+ ImpCastExprToType(LHS, Context.VoidTy, CK_ToVoid);
+ ImpCastExprToType(RHS, Context.VoidTy, CK_ToVoid);
return Context.VoidTy;
}
// C99 6.5.15p6 - "if one operand is a null pointer constant, the result has
@@ -4157,12 +4251,12 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
if ((LHSTy->isAnyPointerType() || LHSTy->isBlockPointerType()) &&
RHS->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
// promote the null to a pointer.
- ImpCastExprToType(RHS, LHSTy, CastExpr::CK_Unknown);
+ ImpCastExprToType(RHS, LHSTy, CK_Unknown);
return LHSTy;
}
if ((RHSTy->isAnyPointerType() || RHSTy->isBlockPointerType()) &&
LHS->isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNull)) {
- ImpCastExprToType(LHS, RHSTy, CastExpr::CK_Unknown);
+ ImpCastExprToType(LHS, RHSTy, CK_Unknown);
return RHSTy;
}
@@ -4178,8 +4272,8 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
if (!LHSTy->isBlockPointerType() || !RHSTy->isBlockPointerType()) {
if (LHSTy->isVoidPointerType() || RHSTy->isVoidPointerType()) {
QualType destType = Context.getPointerType(Context.VoidTy);
- ImpCastExprToType(LHS, destType, CastExpr::CK_BitCast);
- ImpCastExprToType(RHS, destType, CastExpr::CK_BitCast);
+ ImpCastExprToType(LHS, destType, CK_BitCast);
+ ImpCastExprToType(RHS, destType, CK_BitCast);
return destType;
}
Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands)
@@ -4203,13 +4297,13 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
// reason, but this is what gcc does, and we do have to pick
// to get a consistent AST.
QualType incompatTy = Context.getPointerType(Context.VoidTy);
- ImpCastExprToType(LHS, incompatTy, CastExpr::CK_BitCast);
- ImpCastExprToType(RHS, incompatTy, CastExpr::CK_BitCast);
+ ImpCastExprToType(LHS, incompatTy, CK_BitCast);
+ ImpCastExprToType(RHS, incompatTy, CK_BitCast);
return incompatTy;
}
// The block pointer types are compatible.
- ImpCastExprToType(LHS, LHSTy, CastExpr::CK_BitCast);
- ImpCastExprToType(RHS, LHSTy, CastExpr::CK_BitCast);
+ ImpCastExprToType(LHS, LHSTy, CK_BitCast);
+ ImpCastExprToType(RHS, LHSTy, CK_BitCast);
return LHSTy;
}
@@ -4226,9 +4320,9 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
= Context.getQualifiedType(lhptee, rhptee.getQualifiers());
QualType destType = Context.getPointerType(destPointee);
// Add qualifiers if necessary.
- ImpCastExprToType(LHS, destType, CastExpr::CK_NoOp);
+ ImpCastExprToType(LHS, destType, CK_NoOp);
// Promote to void*.
- ImpCastExprToType(RHS, destType, CastExpr::CK_BitCast);
+ ImpCastExprToType(RHS, destType, CK_BitCast);
return destType;
}
if (rhptee->isVoidType() && lhptee->isIncompleteOrObjectType()) {
@@ -4236,9 +4330,9 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
= Context.getQualifiedType(rhptee, lhptee.getQualifiers());
QualType destType = Context.getPointerType(destPointee);
// Add qualifiers if necessary.
- ImpCastExprToType(RHS, destType, CastExpr::CK_NoOp);
+ ImpCastExprToType(RHS, destType, CK_NoOp);
// Promote to void*.
- ImpCastExprToType(LHS, destType, CastExpr::CK_BitCast);
+ ImpCastExprToType(LHS, destType, CK_BitCast);
return destType;
}
@@ -4254,8 +4348,8 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
// reason, but this is what gcc does, and we do have to pick
// to get a consistent AST.
QualType incompatTy = Context.getPointerType(Context.VoidTy);
- ImpCastExprToType(LHS, incompatTy, CastExpr::CK_BitCast);
- ImpCastExprToType(RHS, incompatTy, CastExpr::CK_BitCast);
+ ImpCastExprToType(LHS, incompatTy, CK_BitCast);
+ ImpCastExprToType(RHS, incompatTy, CK_BitCast);
return incompatTy;
}
// The pointer types are compatible.
@@ -4265,8 +4359,8 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
// type.
// FIXME: Need to calculate the composite type.
// FIXME: Need to add qualifiers
- ImpCastExprToType(LHS, LHSTy, CastExpr::CK_BitCast);
- ImpCastExprToType(RHS, LHSTy, CastExpr::CK_BitCast);
+ ImpCastExprToType(LHS, LHSTy, CK_BitCast);
+ ImpCastExprToType(RHS, LHSTy, CK_BitCast);
return LHSTy;
}
@@ -4274,13 +4368,13 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
if (RHSTy->isPointerType() && LHSTy->isIntegerType()) {
Diag(QuestionLoc, diag::warn_typecheck_cond_pointer_integer_mismatch)
<< LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange();
- ImpCastExprToType(LHS, RHSTy, CastExpr::CK_IntegralToPointer);
+ ImpCastExprToType(LHS, RHSTy, CK_IntegralToPointer);
return RHSTy;
}
if (LHSTy->isPointerType() && RHSTy->isIntegerType()) {
Diag(QuestionLoc, diag::warn_typecheck_cond_pointer_integer_mismatch)
<< LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange();
- ImpCastExprToType(RHS, LHSTy, CastExpr::CK_IntegralToPointer);
+ ImpCastExprToType(RHS, LHSTy, CK_IntegralToPointer);
return LHSTy;
}
@@ -4302,34 +4396,34 @@ QualType Sema::FindCompositeObjCPointerType(Expr *&LHS, Expr *&RHS,
// redefinition type if an attempt is made to access its fields.
if (LHSTy->isObjCClassType() &&
(RHSTy.getDesugaredType() == Context.ObjCClassRedefinitionType)) {
- ImpCastExprToType(RHS, LHSTy, CastExpr::CK_BitCast);
+ ImpCastExprToType(RHS, LHSTy, CK_BitCast);
return LHSTy;
}
if (RHSTy->isObjCClassType() &&
(LHSTy.getDesugaredType() == Context.ObjCClassRedefinitionType)) {
- ImpCastExprToType(LHS, RHSTy, CastExpr::CK_BitCast);
+ ImpCastExprToType(LHS, RHSTy, CK_BitCast);
return RHSTy;
}
// And the same for struct objc_object* / id
if (LHSTy->isObjCIdType() &&
(RHSTy.getDesugaredType() == Context.ObjCIdRedefinitionType)) {
- ImpCastExprToType(RHS, LHSTy, CastExpr::CK_BitCast);
+ ImpCastExprToType(RHS, LHSTy, CK_BitCast);
return LHSTy;
}
if (RHSTy->isObjCIdType() &&
(LHSTy.getDesugaredType() == Context.ObjCIdRedefinitionType)) {
- ImpCastExprToType(LHS, RHSTy, CastExpr::CK_BitCast);
+ ImpCastExprToType(LHS, RHSTy, CK_BitCast);
return RHSTy;
}
// And the same for struct objc_selector* / SEL
if (Context.isObjCSelType(LHSTy) &&
(RHSTy.getDesugaredType() == Context.ObjCSelRedefinitionType)) {
- ImpCastExprToType(RHS, LHSTy, CastExpr::CK_BitCast);
+ ImpCastExprToType(RHS, LHSTy, CK_BitCast);
return LHSTy;
}
if (Context.isObjCSelType(RHSTy) &&
(LHSTy.getDesugaredType() == Context.ObjCSelRedefinitionType)) {
- ImpCastExprToType(LHS, RHSTy, CastExpr::CK_BitCast);
+ ImpCastExprToType(LHS, RHSTy, CK_BitCast);
return RHSTy;
}
// Check constraints for Objective-C object pointers types.
@@ -4378,13 +4472,13 @@ QualType Sema::FindCompositeObjCPointerType(Expr *&LHS, Expr *&RHS,
<< LHSTy << RHSTy
<< LHS->getSourceRange() << RHS->getSourceRange();
QualType incompatTy = Context.getObjCIdType();
- ImpCastExprToType(LHS, incompatTy, CastExpr::CK_BitCast);
- ImpCastExprToType(RHS, incompatTy, CastExpr::CK_BitCast);
+ ImpCastExprToType(LHS, incompatTy, CK_BitCast);
+ ImpCastExprToType(RHS, incompatTy, CK_BitCast);
return incompatTy;
}
// The object pointer types are compatible.
- ImpCastExprToType(LHS, compositeType, CastExpr::CK_BitCast);
- ImpCastExprToType(RHS, compositeType, CastExpr::CK_BitCast);
+ ImpCastExprToType(LHS, compositeType, CK_BitCast);
+ ImpCastExprToType(RHS, compositeType, CK_BitCast);
return compositeType;
}
// Check Objective-C object pointer types and 'void *'
@@ -4395,9 +4489,9 @@ QualType Sema::FindCompositeObjCPointerType(Expr *&LHS, Expr *&RHS,
= Context.getQualifiedType(lhptee, rhptee.getQualifiers());
QualType destType = Context.getPointerType(destPointee);
// Add qualifiers if necessary.
- ImpCastExprToType(LHS, destType, CastExpr::CK_NoOp);
+ ImpCastExprToType(LHS, destType, CK_NoOp);
// Promote to void*.
- ImpCastExprToType(RHS, destType, CastExpr::CK_BitCast);
+ ImpCastExprToType(RHS, destType, CK_BitCast);
return destType;
}
if (LHSTy->isObjCObjectPointerType() && RHSTy->isVoidPointerType()) {
@@ -4407,9 +4501,9 @@ QualType Sema::FindCompositeObjCPointerType(Expr *&LHS, Expr *&RHS,
= Context.getQualifiedType(rhptee, lhptee.getQualifiers());
QualType destType = Context.getPointerType(destPointee);
// Add qualifiers if necessary.
- ImpCastExprToType(RHS, destType, CastExpr::CK_NoOp);
+ ImpCastExprToType(RHS, destType, CK_NoOp);
// Promote to void*.
- ImpCastExprToType(LHS, destType, CastExpr::CK_BitCast);
+ ImpCastExprToType(LHS, destType, CK_BitCast);
return destType;
}
return QualType();
@@ -4417,30 +4511,27 @@ QualType Sema::FindCompositeObjCPointerType(Expr *&LHS, Expr *&RHS,
/// ActOnConditionalOp - Parse a ?: operation. Note that 'LHS' may be null
/// in the case of a the GNU conditional expr extension.
-Action::OwningExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc,
+ExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc,
SourceLocation ColonLoc,
- ExprArg Cond, ExprArg LHS,
- ExprArg RHS) {
- Expr *CondExpr = (Expr *) Cond.get();
- Expr *LHSExpr = (Expr *) LHS.get(), *RHSExpr = (Expr *) RHS.get();
-
+ Expr *CondExpr, Expr *LHSExpr,
+ Expr *RHSExpr) {
// If this is the gnu "x ?: y" extension, analyze the types as though the LHS
// was the condition.
bool isLHSNull = LHSExpr == 0;
- if (isLHSNull)
- LHSExpr = CondExpr;
+ Expr *SAVEExpr = 0;
+ if (isLHSNull) {
+ LHSExpr = SAVEExpr = CondExpr;
+ }
QualType result = CheckConditionalOperands(CondExpr, LHSExpr,
RHSExpr, QuestionLoc);
if (result.isNull())
return ExprError();
- Cond.release();
- LHS.release();
- RHS.release();
return Owned(new (Context) ConditionalOperator(CondExpr, QuestionLoc,
- isLHSNull ? 0 : LHSExpr,
- ColonLoc, RHSExpr, result));
+ LHSExpr, ColonLoc,
+ RHSExpr, SAVEExpr,
+ result));
}
// CheckPointerTypesForAssignment - This is a very tricky routine (despite
@@ -4506,12 +4597,12 @@ Sema::CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType) {
// "unsigned char" on systems where "char" is unsigned.
if (lhptee->isCharType())
lhptee = Context.UnsignedCharTy;
- else if (lhptee->isSignedIntegerType())
+ else if (lhptee->hasSignedIntegerRepresentation())
lhptee = Context.getCorrespondingUnsignedType(lhptee);
if (rhptee->isCharType())
rhptee = Context.UnsignedCharTy;
- else if (rhptee->isSignedIntegerType())
+ else if (rhptee->hasSignedIntegerRepresentation())
rhptee = Context.getCorrespondingUnsignedType(rhptee);
if (lhptee == rhptee) {
@@ -4668,13 +4759,18 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) {
}
if (lhsType->isVectorType() || rhsType->isVectorType()) {
- // If we are allowing lax vector conversions, and LHS and RHS are both
- // vectors, the total size only needs to be the same. This is a bitcast;
- // no bits are changed but the result type is different.
- if (getLangOptions().LaxVectorConversions &&
- lhsType->isVectorType() && rhsType->isVectorType()) {
- if (Context.getTypeSize(lhsType) == Context.getTypeSize(rhsType))
+ if (lhsType->isVectorType() && rhsType->isVectorType()) {
+ // If we are allowing lax vector conversions, and LHS and RHS are both
+ // vectors, the total size only needs to be the same. This is a bitcast;
+ // no bits are changed but the result type is different.
+ if (getLangOptions().LaxVectorConversions &&
+ (Context.getTypeSize(lhsType) == Context.getTypeSize(rhsType)))
return IncompatibleVectors;
+
+ // Allow assignments of an AltiVec vector type to an equivalent GCC
+ // vector type and vice versa
+ if (Context.areCompatibleVectorTypes(lhsType, rhsType))
+ return Compatible;
}
return Incompatible;
}
@@ -4832,14 +4928,14 @@ Sema::CheckTransparentUnionArgumentConstraints(QualType ArgType, Expr *&rExpr) {
// 2) null pointer constant
if (FromType->isPointerType())
if (FromType->getAs<PointerType>()->getPointeeType()->isVoidType()) {
- ImpCastExprToType(rExpr, it->getType(), CastExpr::CK_BitCast);
+ ImpCastExprToType(rExpr, it->getType(), CK_BitCast);
InitField = *it;
break;
}
if (rExpr->isNullPointerConstant(Context,
Expr::NPC_ValueDependentIsNull)) {
- ImpCastExprToType(rExpr, it->getType(), CastExpr::CK_IntegralToPointer);
+ ImpCastExprToType(rExpr, it->getType(), CK_IntegralToPointer);
InitField = *it;
break;
}
@@ -4883,14 +4979,14 @@ Sema::CheckSingleAssignmentConstraints(QualType lhsType, Expr *&rExpr) {
lhsType->isBlockPointerType())
&& rExpr->isNullPointerConstant(Context,
Expr::NPC_ValueDependentIsNull)) {
- ImpCastExprToType(rExpr, lhsType, CastExpr::CK_Unknown);
+ ImpCastExprToType(rExpr, lhsType, CK_Unknown);
return Compatible;
}
// This check seems unnatural, however it is necessary to ensure the proper
// conversion of functions/arrays. If the conversion were done for all
// DeclExpr's (created by ActOnIdExpression), it would mess up the unary
- // expressions that surpress this implicit conversion (&, sizeof).
+ // expressions that suppress this implicit conversion (&, sizeof).
//
// Suppress this for references: C++ 8.5.3p5.
if (!lhsType->isReferenceType())
@@ -4907,7 +5003,7 @@ Sema::CheckSingleAssignmentConstraints(QualType lhsType, Expr *&rExpr) {
// does not have reference type.
if (result != Incompatible && rExpr->getType() != lhsType)
ImpCastExprToType(rExpr, lhsType.getNonLValueExprType(Context),
- CastExpr::CK_Unknown);
+ CK_Unknown);
return result;
}
@@ -4933,22 +5029,35 @@ QualType Sema::CheckVectorOperands(SourceLocation Loc, Expr *&lex, Expr *&rex) {
// Handle the case of a vector & extvector type of the same size and element
// type. It would be nice if we only had one vector type someday.
if (getLangOptions().LaxVectorConversions) {
- // FIXME: Should we warn here?
if (const VectorType *LV = lhsType->getAs<VectorType>()) {
- if (const VectorType *RV = rhsType->getAs<VectorType>())
+ if (const VectorType *RV = rhsType->getAs<VectorType>()) {
if (LV->getElementType() == RV->getElementType() &&
LV->getNumElements() == RV->getNumElements()) {
if (lhsType->isExtVectorType()) {
- ImpCastExprToType(rex, lhsType, CastExpr::CK_BitCast);
+ ImpCastExprToType(rex, lhsType, CK_BitCast);
return lhsType;
}
- ImpCastExprToType(lex, rhsType, CastExpr::CK_BitCast);
+ ImpCastExprToType(lex, rhsType, CK_BitCast);
return rhsType;
+ } else if (Context.getTypeSize(lhsType) ==Context.getTypeSize(rhsType)){
+ // If we are allowing lax vector conversions, and LHS and RHS are both
+ // vectors, the total size only needs to be the same. This is a
+ // bitcast; no bits are changed but the result type is different.
+ ImpCastExprToType(rex, lhsType, CK_BitCast);
+ return lhsType;
}
+ }
}
}
+ // Handle the case of equivalent AltiVec and GCC vector types
+ if (lhsType->isVectorType() && rhsType->isVectorType() &&
+ Context.areCompatibleVectorTypes(lhsType, rhsType)) {
+ ImpCastExprToType(lex, rhsType, CK_BitCast);
+ return rhsType;
+ }
+
// Canonicalize the ExtVector to the LHS, remember if we swapped so we can
// swap back (so that we don't reverse the inputs to a subtract, for instance.
bool swapped = false;
@@ -4963,7 +5072,7 @@ QualType Sema::CheckVectorOperands(SourceLocation Loc, Expr *&lex, Expr *&rex) {
QualType EltTy = LV->getElementType();
if (EltTy->isIntegralType(Context) && rhsType->isIntegralType(Context)) {
if (Context.getIntegerTypeOrder(EltTy, rhsType) >= 0) {
- ImpCastExprToType(rex, lhsType, CastExpr::CK_IntegralCast);
+ ImpCastExprToType(rex, lhsType, CK_IntegralCast);
if (swapped) std::swap(rex, lex);
return lhsType;
}
@@ -4971,7 +5080,7 @@ QualType Sema::CheckVectorOperands(SourceLocation Loc, Expr *&lex, Expr *&rex) {
if (EltTy->isRealFloatingType() && rhsType->isScalarType() &&
rhsType->isRealFloatingType()) {
if (Context.getFloatingTypeOrder(EltTy, rhsType) >= 0) {
- ImpCastExprToType(rex, lhsType, CastExpr::CK_FloatingCast);
+ ImpCastExprToType(rex, lhsType, CK_FloatingCast);
if (swapped) std::swap(rex, lex);
return lhsType;
}
@@ -5008,7 +5117,8 @@ QualType Sema::CheckMultiplyDivideOperands(
QualType Sema::CheckRemainderOperands(
Expr *&lex, Expr *&rex, SourceLocation Loc, bool isCompAssign) {
if (lex->getType()->isVectorType() || rex->getType()->isVectorType()) {
- if (lex->getType()->isIntegerType() && rex->getType()->isIntegerType())
+ if (lex->getType()->hasIntegerRepresentation() &&
+ rex->getType()->hasIntegerRepresentation())
return CheckVectorOperands(Loc, lex, rex);
return InvalidOperands(Loc, lex, rex);
}
@@ -5253,7 +5363,8 @@ QualType Sema::CheckSubtractionOperands(Expr *&lex, Expr *&rex,
QualType Sema::CheckShiftOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
bool isCompAssign) {
// C99 6.5.7p2: Each of the operands shall have integer type.
- if (!lex->getType()->isIntegerType() || !rex->getType()->isIntegerType())
+ if (!lex->getType()->hasIntegerRepresentation() ||
+ !rex->getType()->hasIntegerRepresentation())
return InvalidOperands(Loc, lex, rex);
// Vector shifts promote their scalar inputs to vector type.
@@ -5269,7 +5380,7 @@ QualType Sema::CheckShiftOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
LHSTy = Context.getPromotedIntegerType(LHSTy);
}
if (!isCompAssign)
- ImpCastExprToType(lex, LHSTy, CastExpr::CK_IntegralCast);
+ ImpCastExprToType(lex, LHSTy, CK_IntegralCast);
UsualUnaryConversions(rex);
@@ -5305,7 +5416,7 @@ static bool IsWithinTemplateSpecialization(Decl *D) {
// C99 6.5.8, C++ [expr.rel]
QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
unsigned OpaqueOpc, bool isRelational) {
- BinaryOperator::Opcode Opc = (BinaryOperator::Opcode)OpaqueOpc;
+ BinaryOperatorKind Opc = (BinaryOperatorKind) OpaqueOpc;
// Handle vector comparisons separately.
if (lex->getType()->isVectorType() || rex->getType()->isVectorType())
@@ -5334,19 +5445,19 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
!IsWithinTemplateSpecialization(DRL->getDecl())) {
DiagRuntimeBehavior(Loc, PDiag(diag::warn_comparison_always)
<< 0 // self-
- << (Opc == BinaryOperator::EQ
- || Opc == BinaryOperator::LE
- || Opc == BinaryOperator::GE));
+ << (Opc == BO_EQ
+ || Opc == BO_LE
+ || Opc == BO_GE));
} else if (lType->isArrayType() && rType->isArrayType() &&
!DRL->getDecl()->getType()->isReferenceType() &&
!DRR->getDecl()->getType()->isReferenceType()) {
// what is it always going to eval to?
char always_evals_to;
switch(Opc) {
- case BinaryOperator::EQ: // e.g. array1 == array2
+ case BO_EQ: // e.g. array1 == array2
always_evals_to = 0; // false
break;
- case BinaryOperator::NE: // e.g. array1 != array2
+ case BO_NE: // e.g. array1 != array2
always_evals_to = 1; // true
break;
default:
@@ -5386,12 +5497,12 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
if (literalString) {
std::string resultComparison;
switch (Opc) {
- case BinaryOperator::LT: resultComparison = ") < 0"; break;
- case BinaryOperator::GT: resultComparison = ") > 0"; break;
- case BinaryOperator::LE: resultComparison = ") <= 0"; break;
- case BinaryOperator::GE: resultComparison = ") >= 0"; break;
- case BinaryOperator::EQ: resultComparison = ") == 0"; break;
- case BinaryOperator::NE: resultComparison = ") != 0"; break;
+ case BO_LT: resultComparison = ") < 0"; break;
+ case BO_GT: resultComparison = ") > 0"; break;
+ case BO_LE: resultComparison = ") <= 0"; break;
+ case BO_GE: resultComparison = ") >= 0"; break;
+ case BO_EQ: resultComparison = ") == 0"; break;
+ case BO_NE: resultComparison = ") != 0"; break;
default: assert(false && "Invalid comparison operator");
}
@@ -5461,7 +5572,7 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
if (isSFINAEContext())
return QualType();
- ImpCastExprToType(rex, lType, CastExpr::CK_BitCast);
+ ImpCastExprToType(rex, lType, CK_BitCast);
return ResultTy;
}
}
@@ -5487,8 +5598,8 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
<< lex->getSourceRange() << rex->getSourceRange();
}
- ImpCastExprToType(lex, T, CastExpr::CK_BitCast);
- ImpCastExprToType(rex, T, CastExpr::CK_BitCast);
+ ImpCastExprToType(lex, T, CK_BitCast);
+ ImpCastExprToType(rex, T, CK_BitCast);
return ResultTy;
}
// C99 6.5.9p2 and C99 6.5.8p2
@@ -5513,7 +5624,7 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
<< lType << rType << lex->getSourceRange() << rex->getSourceRange();
}
if (LCanPointeeTy != RCanPointeeTy)
- ImpCastExprToType(rex, lType, CastExpr::CK_BitCast);
+ ImpCastExprToType(rex, lType, CK_BitCast);
return ResultTy;
}
@@ -5523,13 +5634,19 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
if (RHSIsNull &&
(lType->isPointerType() ||
(!isRelational && lType->isMemberPointerType()))) {
- ImpCastExprToType(rex, lType, CastExpr::CK_NullToMemberPointer);
+ ImpCastExprToType(rex, lType,
+ lType->isMemberPointerType()
+ ? CK_NullToMemberPointer
+ : CK_IntegralToPointer);
return ResultTy;
}
if (LHSIsNull &&
(rType->isPointerType() ||
(!isRelational && rType->isMemberPointerType()))) {
- ImpCastExprToType(lex, rType, CastExpr::CK_NullToMemberPointer);
+ ImpCastExprToType(lex, rType,
+ rType->isMemberPointerType()
+ ? CK_NullToMemberPointer
+ : CK_IntegralToPointer);
return ResultTy;
}
@@ -5560,8 +5677,8 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
<< lex->getSourceRange() << rex->getSourceRange();
}
- ImpCastExprToType(lex, T, CastExpr::CK_BitCast);
- ImpCastExprToType(rex, T, CastExpr::CK_BitCast);
+ ImpCastExprToType(lex, T, CK_BitCast);
+ ImpCastExprToType(rex, T, CK_BitCast);
return ResultTy;
}
@@ -5580,7 +5697,7 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
Diag(Loc, diag::err_typecheck_comparison_of_distinct_blocks)
<< lType << rType << lex->getSourceRange() << rex->getSourceRange();
}
- ImpCastExprToType(rex, lType, CastExpr::CK_BitCast);
+ ImpCastExprToType(rex, lType, CK_BitCast);
return ResultTy;
}
// Allow block pointers to be compared with null pointer constants.
@@ -5595,7 +5712,7 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
Diag(Loc, diag::err_typecheck_comparison_of_distinct_blocks)
<< lType << rType << lex->getSourceRange() << rex->getSourceRange();
}
- ImpCastExprToType(rex, lType, CastExpr::CK_BitCast);
+ ImpCastExprToType(rex, lType, CK_BitCast);
return ResultTy;
}
@@ -5613,14 +5730,14 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers)
<< lType << rType << lex->getSourceRange() << rex->getSourceRange();
}
- ImpCastExprToType(rex, lType, CastExpr::CK_BitCast);
+ ImpCastExprToType(rex, lType, CK_BitCast);
return ResultTy;
}
if (lType->isObjCObjectPointerType() && rType->isObjCObjectPointerType()) {
if (!Context.areComparableObjCPointerTypes(lType, rType))
Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers)
<< lType << rType << lex->getSourceRange() << rex->getSourceRange();
- ImpCastExprToType(rex, lType, CastExpr::CK_BitCast);
+ ImpCastExprToType(rex, lType, CK_BitCast);
return ResultTy;
}
}
@@ -5648,21 +5765,21 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc,
}
if (lType->isIntegerType())
- ImpCastExprToType(lex, rType, CastExpr::CK_IntegralToPointer);
+ ImpCastExprToType(lex, rType, CK_IntegralToPointer);
else
- ImpCastExprToType(rex, lType, CastExpr::CK_IntegralToPointer);
+ ImpCastExprToType(rex, lType, CK_IntegralToPointer);
return ResultTy;
}
// Handle block pointers.
if (!isRelational && RHSIsNull
&& lType->isBlockPointerType() && rType->isIntegerType()) {
- ImpCastExprToType(rex, lType, CastExpr::CK_IntegralToPointer);
+ ImpCastExprToType(rex, lType, CK_IntegralToPointer);
return ResultTy;
}
if (!isRelational && LHSIsNull
&& lType->isIntegerType() && rType->isBlockPointerType()) {
- ImpCastExprToType(lex, rType, CastExpr::CK_IntegralToPointer);
+ ImpCastExprToType(lex, rType, CK_IntegralToPointer);
return ResultTy;
}
return InvalidOperands(Loc, lex, rex);
@@ -5707,7 +5824,7 @@ QualType Sema::CheckVectorCompareOperands(Expr *&lex, Expr *&rex,
// Return the type for the comparison, which is the same as vector type for
// integer vectors, or an integer type of identical size and number of
// elements for floating point vectors.
- if (lType->isIntegerType())
+ if (lType->hasIntegerRepresentation())
return lType;
const VectorType *VTy = lType->getAs<VectorType>();
@@ -5724,8 +5841,13 @@ QualType Sema::CheckVectorCompareOperands(Expr *&lex, Expr *&rex,
inline QualType Sema::CheckBitwiseOperands(
Expr *&lex, Expr *&rex, SourceLocation Loc, bool isCompAssign) {
- if (lex->getType()->isVectorType() || rex->getType()->isVectorType())
- return CheckVectorOperands(Loc, lex, rex);
+ if (lex->getType()->isVectorType() || rex->getType()->isVectorType()) {
+ if (lex->getType()->hasIntegerRepresentation() &&
+ rex->getType()->hasIntegerRepresentation())
+ return CheckVectorOperands(Loc, lex, rex);
+
+ return InvalidOperands(Loc, lex, rex);
+ }
QualType compType = UsualArithmeticConversions(lex, rex, isCompAssign);
@@ -5741,18 +5863,21 @@ inline QualType Sema::CheckLogicalOperands( // C99 6.5.[13,14]
// bitwise one. We do this when the LHS is a non-bool integer and the RHS
// is a constant.
if (lex->getType()->isIntegerType() && !lex->getType()->isBooleanType() &&
- rex->getType()->isIntegerType() && rex->isEvaluatable(Context) &&
- // Don't warn if the RHS is a (constant folded) boolean expression like
- // "sizeof(int) == 4".
- !rex->isKnownToHaveBooleanValue() &&
+ rex->getType()->isIntegerType() && !rex->isValueDependent() &&
// Don't warn in macros.
- !Loc.isMacroID())
- Diag(Loc, diag::warn_logical_instead_of_bitwise)
- << rex->getSourceRange()
- << (Opc == BinaryOperator::LAnd ? "&&" : "||")
- << (Opc == BinaryOperator::LAnd ? "&" : "|");
-
-
+ !Loc.isMacroID()) {
+ // If the RHS can be constant folded, and if it constant folds to something
+ // that isn't 0 or 1 (which indicate a potential logical operation that
+ // happened to fold to true/false) then warn.
+ Expr::EvalResult Result;
+ if (rex->Evaluate(Result, Context) && !Result.HasSideEffects &&
+ Result.Val.getInt() != 0 && Result.Val.getInt() != 1) {
+ Diag(Loc, diag::warn_logical_instead_of_bitwise)
+ << rex->getSourceRange()
+ << (Opc == BO_LAnd ? "&&" : "||")
+ << (Opc == BO_LAnd ? "&" : "|");
+ }
+ }
if (!Context.getLangOptions().CPlusPlus) {
UsualUnaryConversions(lex);
@@ -5907,8 +6032,8 @@ QualType Sema::CheckAssignmentOperands(Expr *LHS, Expr *&RHS,
if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(RHSCheck))
RHSCheck = ICE->getSubExpr();
if (UnaryOperator *UO = dyn_cast<UnaryOperator>(RHSCheck)) {
- if ((UO->getOpcode() == UnaryOperator::Plus ||
- UO->getOpcode() == UnaryOperator::Minus) &&
+ if ((UO->getOpcode() == UO_Plus ||
+ UO->getOpcode() == UO_Minus) &&
Loc.isFileID() && UO->getOperatorLoc().isFileID() &&
// Only if the two operators are exactly adjacent.
Loc.getFileLocWithOffset(1) == UO->getOperatorLoc() &&
@@ -5917,7 +6042,7 @@ QualType Sema::CheckAssignmentOperands(Expr *LHS, Expr *&RHS,
Loc.getFileLocWithOffset(2) != UO->getSubExpr()->getLocStart() &&
UO->getSubExpr()->getLocStart().isFileID()) {
Diag(Loc, diag::warn_not_compound_assign)
- << (UO->getOpcode() == UnaryOperator::Plus ? "+" : "-")
+ << (UO->getOpcode() == UO_Plus ? "+" : "-")
<< SourceRange(UO->getOperatorLoc(), UO->getOperatorLoc());
}
}
@@ -5938,7 +6063,7 @@ QualType Sema::CheckAssignmentOperands(Expr *LHS, Expr *&RHS,
// only handles the pattern "*null = whatever", which is a very syntactic
// check.
if (UnaryOperator *UO = dyn_cast<UnaryOperator>(LHS->IgnoreParenCasts()))
- if (UO->getOpcode() == UnaryOperator::Deref &&
+ if (UO->getOpcode() == UO_Deref &&
UO->getSubExpr()->IgnoreParenCasts()->
isNullPointerConstant(Context, Expr::NPC_ValueDependentIsNotNull) &&
!UO->getType().isVolatileQualified()) {
@@ -6083,9 +6208,9 @@ static NamedDecl *getPrimaryDecl(Expr *E) {
UnaryOperator *UO = cast<UnaryOperator>(E);
switch(UO->getOpcode()) {
- case UnaryOperator::Real:
- case UnaryOperator::Imag:
- case UnaryOperator::Extension:
+ case UO_Real:
+ case UO_Imag:
+ case UO_Extension:
return getPrimaryDecl(UO->getSubExpr());
default:
return 0;
@@ -6109,17 +6234,19 @@ static NamedDecl *getPrimaryDecl(Expr *E) {
/// operator (C99 6.3.2.1p[2-4]), and its result is never an lvalue.
/// In C++, the operand might be an overloaded function name, in which case
/// we allow the '&' but retain the overloaded-function type.
-QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
- // Make sure to ignore parentheses in subsequent checks
- op = op->IgnoreParens();
-
- if (op->isTypeDependent())
+QualType Sema::CheckAddressOfOperand(Expr *OrigOp, SourceLocation OpLoc) {
+ if (OrigOp->isTypeDependent())
return Context.DependentTy;
+ if (OrigOp->getType() == Context.OverloadTy)
+ return Context.OverloadTy;
+
+ // Make sure to ignore parentheses in subsequent checks
+ Expr *op = OrigOp->IgnoreParens();
if (getLangOptions().C99) {
// Implement C99-only parts of addressof rules.
if (UnaryOperator* uOp = dyn_cast<UnaryOperator>(op)) {
- if (uOp->getOpcode() == UnaryOperator::Deref)
+ if (uOp->getOpcode() == UO_Deref)
// Per C99 6.5.3.2, the address of a deref always returns a valid result
// (assuming the deref expression is valid).
return uOp->getSubExpr()->getType();
@@ -6130,32 +6257,41 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
NamedDecl *dcl = getPrimaryDecl(op);
Expr::isLvalueResult lval = op->isLvalue(Context);
- MemberExpr *ME = dyn_cast<MemberExpr>(op);
- if (lval == Expr::LV_MemberFunction && ME &&
- isa<CXXMethodDecl>(ME->getMemberDecl())) {
- ValueDecl *dcl = cast<MemberExpr>(op)->getMemberDecl();
- // &f where f is a member of the current object, or &o.f, or &p->f
- // All these are not allowed, and we need to catch them before the dcl
- // branch of the if, below.
- Diag(OpLoc, diag::err_unqualified_pointer_member_function)
- << dcl;
- // FIXME: Improve this diagnostic and provide a fixit.
-
- // Now recover by acting as if the function had been accessed qualified.
- return Context.getMemberPointerType(op->getType(),
- Context.getTypeDeclType(cast<RecordDecl>(dcl->getDeclContext()))
- .getTypePtr());
- }
-
if (lval == Expr::LV_ClassTemporary) {
Diag(OpLoc, isSFINAEContext()? diag::err_typecheck_addrof_class_temporary
: diag::ext_typecheck_addrof_class_temporary)
<< op->getType() << op->getSourceRange();
if (isSFINAEContext())
return QualType();
- } else if (isa<ObjCSelectorExpr>(op))
+ } else if (isa<ObjCSelectorExpr>(op)) {
return Context.getPointerType(op->getType());
- else if (lval != Expr::LV_Valid && lval != Expr::LV_IncompleteVoidType) {
+ } else if (lval == Expr::LV_MemberFunction) {
+ // If it's an instance method, make a member pointer.
+ // The expression must have exactly the form &A::foo.
+
+ // If the underlying expression isn't a decl ref, give up.
+ if (!isa<DeclRefExpr>(op)) {
+ Diag(OpLoc, diag::err_invalid_form_pointer_member_function)
+ << OrigOp->getSourceRange();
+ return QualType();
+ }
+ DeclRefExpr *DRE = cast<DeclRefExpr>(op);
+ CXXMethodDecl *MD = cast<CXXMethodDecl>(DRE->getDecl());
+
+ // The id-expression was parenthesized.
+ if (OrigOp != DRE) {
+ Diag(OpLoc, diag::err_parens_pointer_member_function)
+ << OrigOp->getSourceRange();
+
+ // The method was named without a qualifier.
+ } else if (!DRE->getQualifier()) {
+ Diag(OpLoc, diag::err_unqualified_pointer_member_function)
+ << op->getSourceRange();
+ }
+
+ return Context.getMemberPointerType(op->getType(),
+ Context.getTypeDeclType(MD->getParent()).getTypePtr());
+ } else if (lval != Expr::LV_Valid && lval != Expr::LV_IncompleteVoidType) {
// C99 6.5.3.2p1
// The operand must be either an l-value or a function designator
if (!op->getType()->isFunctionType()) {
@@ -6183,13 +6319,14 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
// FIXME: Can LHS ever be null here?
if (!CheckAddressOfOperand(CO->getTrueExpr(), OpLoc).isNull())
return CheckAddressOfOperand(CO->getFalseExpr(), OpLoc);
- } else if (isa<UnresolvedLookupExpr>(op)) {
- return Context.OverloadTy;
} else if (dcl) { // C99 6.5.3.2p1
// We have an lvalue with a decl. Make sure the decl is not declared
// with the register storage-class specifier.
if (const VarDecl *vd = dyn_cast<VarDecl>(dcl)) {
- if (vd->getStorageClass() == VarDecl::Register) {
+ // in C++ it is not error to take address of a register
+ // variable (c++03 7.1.1P3)
+ if (vd->getStorageClass() == SC_Register &&
+ !getLangOptions().CPlusPlus) {
Diag(OpLoc, diag::err_typecheck_address_of)
<< "register variable" << op->getSourceRange();
return QualType();
@@ -6214,13 +6351,6 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
Context.getTypeDeclType(cast<RecordDecl>(Ctx)).getTypePtr());
}
}
- } else if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(dcl)) {
- // Okay: we can take the address of a function.
- // As above.
- if (isa<DeclRefExpr>(op) && cast<DeclRefExpr>(op)->getQualifier() &&
- MD->isInstance())
- return Context.getMemberPointerType(op->getType(),
- Context.getTypeDeclType(MD->getParent()).getTypePtr());
} else if (!isa<FunctionDecl>(dcl))
assert(0 && "Unknown/unexpected decl type");
}
@@ -6233,6 +6363,8 @@ QualType Sema::CheckAddressOfOperand(Expr *op, SourceLocation OpLoc) {
}
// If the operand has type "type", the result has type "pointer to type".
+ if (op->getType()->isObjCObjectType())
+ return Context.getObjCObjectPointerType(op->getType());
return Context.getPointerType(op->getType());
}
@@ -6264,63 +6396,63 @@ QualType Sema::CheckIndirectionOperand(Expr *Op, SourceLocation OpLoc) {
return Result;
}
-static inline BinaryOperator::Opcode ConvertTokenKindToBinaryOpcode(
+static inline BinaryOperatorKind ConvertTokenKindToBinaryOpcode(
tok::TokenKind Kind) {
- BinaryOperator::Opcode Opc;
+ BinaryOperatorKind Opc;
switch (Kind) {
default: assert(0 && "Unknown binop!");
- case tok::periodstar: Opc = BinaryOperator::PtrMemD; break;
- case tok::arrowstar: Opc = BinaryOperator::PtrMemI; break;
- case tok::star: Opc = BinaryOperator::Mul; break;
- case tok::slash: Opc = BinaryOperator::Div; break;
- case tok::percent: Opc = BinaryOperator::Rem; break;
- case tok::plus: Opc = BinaryOperator::Add; break;
- case tok::minus: Opc = BinaryOperator::Sub; break;
- case tok::lessless: Opc = BinaryOperator::Shl; break;
- case tok::greatergreater: Opc = BinaryOperator::Shr; break;
- case tok::lessequal: Opc = BinaryOperator::LE; break;
- case tok::less: Opc = BinaryOperator::LT; break;
- case tok::greaterequal: Opc = BinaryOperator::GE; break;
- case tok::greater: Opc = BinaryOperator::GT; break;
- case tok::exclaimequal: Opc = BinaryOperator::NE; break;
- case tok::equalequal: Opc = BinaryOperator::EQ; break;
- case tok::amp: Opc = BinaryOperator::And; break;
- case tok::caret: Opc = BinaryOperator::Xor; break;
- case tok::pipe: Opc = BinaryOperator::Or; break;
- case tok::ampamp: Opc = BinaryOperator::LAnd; break;
- case tok::pipepipe: Opc = BinaryOperator::LOr; break;
- case tok::equal: Opc = BinaryOperator::Assign; break;
- case tok::starequal: Opc = BinaryOperator::MulAssign; break;
- case tok::slashequal: Opc = BinaryOperator::DivAssign; break;
- case tok::percentequal: Opc = BinaryOperator::RemAssign; break;
- case tok::plusequal: Opc = BinaryOperator::AddAssign; break;
- case tok::minusequal: Opc = BinaryOperator::SubAssign; break;
- case tok::lesslessequal: Opc = BinaryOperator::ShlAssign; break;
- case tok::greatergreaterequal: Opc = BinaryOperator::ShrAssign; break;
- case tok::ampequal: Opc = BinaryOperator::AndAssign; break;
- case tok::caretequal: Opc = BinaryOperator::XorAssign; break;
- case tok::pipeequal: Opc = BinaryOperator::OrAssign; break;
- case tok::comma: Opc = BinaryOperator::Comma; break;
+ case tok::periodstar: Opc = BO_PtrMemD; break;
+ case tok::arrowstar: Opc = BO_PtrMemI; break;
+ case tok::star: Opc = BO_Mul; break;
+ case tok::slash: Opc = BO_Div; break;
+ case tok::percent: Opc = BO_Rem; break;
+ case tok::plus: Opc = BO_Add; break;
+ case tok::minus: Opc = BO_Sub; break;
+ case tok::lessless: Opc = BO_Shl; break;
+ case tok::greatergreater: Opc = BO_Shr; break;
+ case tok::lessequal: Opc = BO_LE; break;
+ case tok::less: Opc = BO_LT; break;
+ case tok::greaterequal: Opc = BO_GE; break;
+ case tok::greater: Opc = BO_GT; break;
+ case tok::exclaimequal: Opc = BO_NE; break;
+ case tok::equalequal: Opc = BO_EQ; break;
+ case tok::amp: Opc = BO_And; break;
+ case tok::caret: Opc = BO_Xor; break;
+ case tok::pipe: Opc = BO_Or; break;
+ case tok::ampamp: Opc = BO_LAnd; break;
+ case tok::pipepipe: Opc = BO_LOr; break;
+ case tok::equal: Opc = BO_Assign; break;
+ case tok::starequal: Opc = BO_MulAssign; break;
+ case tok::slashequal: Opc = BO_DivAssign; break;
+ case tok::percentequal: Opc = BO_RemAssign; break;
+ case tok::plusequal: Opc = BO_AddAssign; break;
+ case tok::minusequal: Opc = BO_SubAssign; break;
+ case tok::lesslessequal: Opc = BO_ShlAssign; break;
+ case tok::greatergreaterequal: Opc = BO_ShrAssign; break;
+ case tok::ampequal: Opc = BO_AndAssign; break;
+ case tok::caretequal: Opc = BO_XorAssign; break;
+ case tok::pipeequal: Opc = BO_OrAssign; break;
+ case tok::comma: Opc = BO_Comma; break;
}
return Opc;
}
-static inline UnaryOperator::Opcode ConvertTokenKindToUnaryOpcode(
+static inline UnaryOperatorKind ConvertTokenKindToUnaryOpcode(
tok::TokenKind Kind) {
- UnaryOperator::Opcode Opc;
+ UnaryOperatorKind Opc;
switch (Kind) {
default: assert(0 && "Unknown unary op!");
- case tok::plusplus: Opc = UnaryOperator::PreInc; break;
- case tok::minusminus: Opc = UnaryOperator::PreDec; break;
- case tok::amp: Opc = UnaryOperator::AddrOf; break;
- case tok::star: Opc = UnaryOperator::Deref; break;
- case tok::plus: Opc = UnaryOperator::Plus; break;
- case tok::minus: Opc = UnaryOperator::Minus; break;
- case tok::tilde: Opc = UnaryOperator::Not; break;
- case tok::exclaim: Opc = UnaryOperator::LNot; break;
- case tok::kw___real: Opc = UnaryOperator::Real; break;
- case tok::kw___imag: Opc = UnaryOperator::Imag; break;
- case tok::kw___extension__: Opc = UnaryOperator::Extension; break;
+ case tok::plusplus: Opc = UO_PreInc; break;
+ case tok::minusminus: Opc = UO_PreDec; break;
+ case tok::amp: Opc = UO_AddrOf; break;
+ case tok::star: Opc = UO_Deref; break;
+ case tok::plus: Opc = UO_Plus; break;
+ case tok::minus: Opc = UO_Minus; break;
+ case tok::tilde: Opc = UO_Not; break;
+ case tok::exclaim: Opc = UO_LNot; break;
+ case tok::kw___real: Opc = UO_Real; break;
+ case tok::kw___imag: Opc = UO_Imag; break;
+ case tok::kw___extension__: Opc = UO_Extension; break;
}
return Opc;
}
@@ -6328,106 +6460,111 @@ static inline UnaryOperator::Opcode ConvertTokenKindToUnaryOpcode(
/// CreateBuiltinBinOp - Creates a new built-in binary operation with
/// operator @p Opc at location @c TokLoc. This routine only supports
/// built-in operations; ActOnBinOp handles overloaded operators.
-Action::OwningExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
- unsigned Op,
- Expr *lhs, Expr *rhs) {
+ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
+ unsigned Op,
+ Expr *lhs, Expr *rhs) {
QualType ResultTy; // Result type of the binary operator.
- BinaryOperator::Opcode Opc = (BinaryOperator::Opcode)Op;
+ BinaryOperatorKind Opc = (BinaryOperatorKind) Op;
// The following two variables are used for compound assignment operators
QualType CompLHSTy; // Type of LHS after promotions for computation
QualType CompResultTy; // Type of computation result
switch (Opc) {
- case BinaryOperator::Assign:
+ case BO_Assign:
ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, QualType());
break;
- case BinaryOperator::PtrMemD:
- case BinaryOperator::PtrMemI:
+ case BO_PtrMemD:
+ case BO_PtrMemI:
ResultTy = CheckPointerToMemberOperands(lhs, rhs, OpLoc,
- Opc == BinaryOperator::PtrMemI);
+ Opc == BO_PtrMemI);
break;
- case BinaryOperator::Mul:
- case BinaryOperator::Div:
+ case BO_Mul:
+ case BO_Div:
ResultTy = CheckMultiplyDivideOperands(lhs, rhs, OpLoc, false,
- Opc == BinaryOperator::Div);
+ Opc == BO_Div);
break;
- case BinaryOperator::Rem:
+ case BO_Rem:
ResultTy = CheckRemainderOperands(lhs, rhs, OpLoc);
break;
- case BinaryOperator::Add:
+ case BO_Add:
ResultTy = CheckAdditionOperands(lhs, rhs, OpLoc);
break;
- case BinaryOperator::Sub:
+ case BO_Sub:
ResultTy = CheckSubtractionOperands(lhs, rhs, OpLoc);
break;
- case BinaryOperator::Shl:
- case BinaryOperator::Shr:
+ case BO_Shl:
+ case BO_Shr:
ResultTy = CheckShiftOperands(lhs, rhs, OpLoc);
break;
- case BinaryOperator::LE:
- case BinaryOperator::LT:
- case BinaryOperator::GE:
- case BinaryOperator::GT:
+ case BO_LE:
+ case BO_LT:
+ case BO_GE:
+ case BO_GT:
ResultTy = CheckCompareOperands(lhs, rhs, OpLoc, Opc, true);
break;
- case BinaryOperator::EQ:
- case BinaryOperator::NE:
+ case BO_EQ:
+ case BO_NE:
ResultTy = CheckCompareOperands(lhs, rhs, OpLoc, Opc, false);
break;
- case BinaryOperator::And:
- case BinaryOperator::Xor:
- case BinaryOperator::Or:
+ case BO_And:
+ case BO_Xor:
+ case BO_Or:
ResultTy = CheckBitwiseOperands(lhs, rhs, OpLoc);
break;
- case BinaryOperator::LAnd:
- case BinaryOperator::LOr:
+ case BO_LAnd:
+ case BO_LOr:
ResultTy = CheckLogicalOperands(lhs, rhs, OpLoc, Opc);
break;
- case BinaryOperator::MulAssign:
- case BinaryOperator::DivAssign:
+ case BO_MulAssign:
+ case BO_DivAssign:
CompResultTy = CheckMultiplyDivideOperands(lhs, rhs, OpLoc, true,
- Opc == BinaryOperator::DivAssign);
+ Opc == BO_DivAssign);
CompLHSTy = CompResultTy;
if (!CompResultTy.isNull())
ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
break;
- case BinaryOperator::RemAssign:
+ case BO_RemAssign:
CompResultTy = CheckRemainderOperands(lhs, rhs, OpLoc, true);
CompLHSTy = CompResultTy;
if (!CompResultTy.isNull())
ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
break;
- case BinaryOperator::AddAssign:
+ case BO_AddAssign:
CompResultTy = CheckAdditionOperands(lhs, rhs, OpLoc, &CompLHSTy);
if (!CompResultTy.isNull())
ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
break;
- case BinaryOperator::SubAssign:
+ case BO_SubAssign:
CompResultTy = CheckSubtractionOperands(lhs, rhs, OpLoc, &CompLHSTy);
if (!CompResultTy.isNull())
ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
break;
- case BinaryOperator::ShlAssign:
- case BinaryOperator::ShrAssign:
+ case BO_ShlAssign:
+ case BO_ShrAssign:
CompResultTy = CheckShiftOperands(lhs, rhs, OpLoc, true);
CompLHSTy = CompResultTy;
if (!CompResultTy.isNull())
ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
break;
- case BinaryOperator::AndAssign:
- case BinaryOperator::XorAssign:
- case BinaryOperator::OrAssign:
+ case BO_AndAssign:
+ case BO_XorAssign:
+ case BO_OrAssign:
CompResultTy = CheckBitwiseOperands(lhs, rhs, OpLoc, true);
CompLHSTy = CompResultTy;
if (!CompResultTy.isNull())
ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy);
break;
- case BinaryOperator::Comma:
+ case BO_Comma:
ResultTy = CheckCommaOperands(lhs, rhs, OpLoc);
break;
}
if (ResultTy.isNull())
return ExprError();
+ if (ResultTy->isObjCObjectType() && LangOpts.ObjCNonFragileABI) {
+ if (Opc >= BO_Assign && Opc <= BO_OrAssign)
+ Diag(OpLoc, diag::err_assignment_requires_nonfragile_object)
+ << ResultTy;
+ }
if (CompResultTy.isNull())
return Owned(new (Context) BinaryOperator(lhs, rhs, Opc, ResultTy, OpLoc));
else
@@ -6479,7 +6616,7 @@ static void SuggestParentheses(Sema &Self, SourceLocation Loc,
/// operators are mixed in a way that suggests that the programmer forgot that
/// comparison operators have higher precedence. The most typical example of
/// such code is "flags & 0x0020 != 0", which is equivalent to "flags & 1".
-static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperator::Opcode Opc,
+static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperatorKind Opc,
SourceLocation OpLoc,Expr *lhs,Expr *rhs){
typedef BinaryOperator BinOp;
BinOp::Opcode lhsopc = static_cast<BinOp::Opcode>(-1),
@@ -6526,19 +6663,17 @@ static void DiagnoseBitwisePrecedence(Sema &Self, BinaryOperator::Opcode Opc,
/// DiagnoseBinOpPrecedence - Emit warnings for expressions with tricky
/// precedence. This currently diagnoses only "arg1 'bitwise' arg2 'eq' arg3".
/// But it could also warn about arg1 && arg2 || arg3, as GCC 4.3+ does.
-static void DiagnoseBinOpPrecedence(Sema &Self, BinaryOperator::Opcode Opc,
+static void DiagnoseBinOpPrecedence(Sema &Self, BinaryOperatorKind Opc,
SourceLocation OpLoc, Expr *lhs, Expr *rhs){
if (BinaryOperator::isBitwiseOp(Opc))
DiagnoseBitwisePrecedence(Self, Opc, OpLoc, lhs, rhs);
}
// Binary Operators. 'Tok' is the token for the operator.
-Action::OwningExprResult Sema::ActOnBinOp(Scope *S, SourceLocation TokLoc,
- tok::TokenKind Kind,
- ExprArg LHS, ExprArg RHS) {
- BinaryOperator::Opcode Opc = ConvertTokenKindToBinaryOpcode(Kind);
- Expr *lhs = LHS.takeAs<Expr>(), *rhs = RHS.takeAs<Expr>();
-
+ExprResult Sema::ActOnBinOp(Scope *S, SourceLocation TokLoc,
+ tok::TokenKind Kind,
+ Expr *lhs, Expr *rhs) {
+ BinaryOperatorKind Opc = ConvertTokenKindToBinaryOpcode(Kind);
assert((lhs != 0) && "ActOnBinOp(): missing left expression");
assert((rhs != 0) && "ActOnBinOp(): missing right expression");
@@ -6548,9 +6683,9 @@ Action::OwningExprResult Sema::ActOnBinOp(Scope *S, SourceLocation TokLoc,
return BuildBinOp(S, TokLoc, Opc, lhs, rhs);
}
-Action::OwningExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
- BinaryOperator::Opcode Opc,
- Expr *lhs, Expr *rhs) {
+ExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
+ BinaryOperatorKind Opc,
+ Expr *lhs, Expr *rhs) {
if (getLangOptions().CPlusPlus &&
(lhs->getType()->isOverloadableType() ||
rhs->getType()->isOverloadableType())) {
@@ -6573,38 +6708,32 @@ Action::OwningExprResult Sema::BuildBinOp(Scope *S, SourceLocation OpLoc,
return CreateBuiltinBinOp(OpLoc, Opc, lhs, rhs);
}
-Action::OwningExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
+ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
unsigned OpcIn,
- ExprArg InputArg) {
- UnaryOperator::Opcode Opc = static_cast<UnaryOperator::Opcode>(OpcIn);
+ Expr *Input) {
+ UnaryOperatorKind Opc = static_cast<UnaryOperatorKind>(OpcIn);
- // FIXME: Input is modified below, but InputArg is not updated appropriately.
- Expr *Input = (Expr *)InputArg.get();
QualType resultType;
switch (Opc) {
- case UnaryOperator::OffsetOf:
- assert(false && "Invalid unary operator");
- break;
-
- case UnaryOperator::PreInc:
- case UnaryOperator::PreDec:
- case UnaryOperator::PostInc:
- case UnaryOperator::PostDec:
+ case UO_PreInc:
+ case UO_PreDec:
+ case UO_PostInc:
+ case UO_PostDec:
resultType = CheckIncrementDecrementOperand(Input, OpLoc,
- Opc == UnaryOperator::PreInc ||
- Opc == UnaryOperator::PostInc,
- Opc == UnaryOperator::PreInc ||
- Opc == UnaryOperator::PreDec);
+ Opc == UO_PreInc ||
+ Opc == UO_PostInc,
+ Opc == UO_PreInc ||
+ Opc == UO_PreDec);
break;
- case UnaryOperator::AddrOf:
+ case UO_AddrOf:
resultType = CheckAddressOfOperand(Input, OpLoc);
break;
- case UnaryOperator::Deref:
+ case UO_Deref:
DefaultFunctionArrayLvalueConversion(Input);
resultType = CheckIndirectionOperand(Input, OpLoc);
break;
- case UnaryOperator::Plus:
- case UnaryOperator::Minus:
+ case UO_Plus:
+ case UO_Minus:
UsualUnaryConversions(Input);
resultType = Input->getType();
if (resultType->isDependentType())
@@ -6616,13 +6745,13 @@ Action::OwningExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
resultType->isEnumeralType())
break;
else if (getLangOptions().CPlusPlus && // C++ [expr.unary.op]p6
- Opc == UnaryOperator::Plus &&
+ Opc == UO_Plus &&
resultType->isPointerType())
break;
return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
<< resultType << Input->getSourceRange());
- case UnaryOperator::Not: // bitwise complement
+ case UO_Not: // bitwise complement
UsualUnaryConversions(Input);
resultType = Input->getType();
if (resultType->isDependentType())
@@ -6632,11 +6761,11 @@ Action::OwningExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
// C99 does not support '~' for complex conjugation.
Diag(OpLoc, diag::ext_integer_complement_complex)
<< resultType << Input->getSourceRange();
- else if (!resultType->isIntegerType())
+ else if (!resultType->hasIntegerRepresentation())
return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
<< resultType << Input->getSourceRange());
break;
- case UnaryOperator::LNot: // logical negation
+ case UO_LNot: // logical negation
// Unlike +/-/~, integer promotions aren't done here (C99 6.5.3.3p5).
DefaultFunctionArrayLvalueConversion(Input);
resultType = Input->getType();
@@ -6649,27 +6778,25 @@ Action::OwningExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
// In C++, it's bool. C++ 5.3.1p8
resultType = getLangOptions().CPlusPlus ? Context.BoolTy : Context.IntTy;
break;
- case UnaryOperator::Real:
- case UnaryOperator::Imag:
- resultType = CheckRealImagOperand(Input, OpLoc, Opc == UnaryOperator::Real);
+ case UO_Real:
+ case UO_Imag:
+ resultType = CheckRealImagOperand(Input, OpLoc, Opc == UO_Real);
break;
- case UnaryOperator::Extension:
+ case UO_Extension:
resultType = Input->getType();
break;
}
if (resultType.isNull())
return ExprError();
- InputArg.release();
return Owned(new (Context) UnaryOperator(Input, Opc, resultType, OpLoc));
}
-Action::OwningExprResult Sema::BuildUnaryOp(Scope *S, SourceLocation OpLoc,
- UnaryOperator::Opcode Opc,
- ExprArg input) {
- Expr *Input = (Expr*)input.get();
+ExprResult Sema::BuildUnaryOp(Scope *S, SourceLocation OpLoc,
+ UnaryOperatorKind Opc,
+ Expr *Input) {
if (getLangOptions().CPlusPlus && Input->getType()->isOverloadableType() &&
- Opc != UnaryOperator::Extension) {
+ UnaryOperator::getOverloadedOperator(Opc) != OO_None) {
// Find all of the overloaded operators visible from this
// point. We perform both an operator-name lookup from the local
// scope and an argument-dependent lookup based on the types of
@@ -6680,24 +6807,24 @@ Action::OwningExprResult Sema::BuildUnaryOp(Scope *S, SourceLocation OpLoc,
LookupOverloadedOperatorName(OverOp, S, Input->getType(), QualType(),
Functions);
- return CreateOverloadedUnaryOp(OpLoc, Opc, Functions, move(input));
+ return CreateOverloadedUnaryOp(OpLoc, Opc, Functions, Input);
}
- return CreateBuiltinUnaryOp(OpLoc, Opc, move(input));
+ return CreateBuiltinUnaryOp(OpLoc, Opc, Input);
}
// Unary Operators. 'Tok' is the token for the operator.
-Action::OwningExprResult Sema::ActOnUnaryOp(Scope *S, SourceLocation OpLoc,
- tok::TokenKind Op, ExprArg input) {
- return BuildUnaryOp(S, OpLoc, ConvertTokenKindToUnaryOpcode(Op), move(input));
+ExprResult Sema::ActOnUnaryOp(Scope *S, SourceLocation OpLoc,
+ tok::TokenKind Op, Expr *Input) {
+ return BuildUnaryOp(S, OpLoc, ConvertTokenKindToUnaryOpcode(Op), Input);
}
/// ActOnAddrLabel - Parse the GNU address of label extension: "&&foo".
-Sema::OwningExprResult Sema::ActOnAddrLabel(SourceLocation OpLoc,
+ExprResult Sema::ActOnAddrLabel(SourceLocation OpLoc,
SourceLocation LabLoc,
IdentifierInfo *LabelII) {
// Look up the record for this label identifier.
- LabelStmt *&LabelDecl = getLabelMap()[LabelII];
+ LabelStmt *&LabelDecl = getCurFunction()->LabelMap[LabelII];
// If we haven't seen this label yet, create a forward reference. It
// will be validated and/or cleaned up in ActOnFinishFunctionBody.
@@ -6709,10 +6836,9 @@ Sema::OwningExprResult Sema::ActOnAddrLabel(SourceLocation OpLoc,
Context.getPointerType(Context.VoidTy)));
}
-Sema::OwningExprResult
-Sema::ActOnStmtExpr(SourceLocation LPLoc, StmtArg substmt,
+ExprResult
+Sema::ActOnStmtExpr(SourceLocation LPLoc, Stmt *SubStmt,
SourceLocation RPLoc) { // "({..})"
- Stmt *SubStmt = static_cast<Stmt*>(substmt.get());
assert(SubStmt && isa<CompoundStmt>(SubStmt) && "Invalid action invocation!");
CompoundStmt *Compound = cast<CompoundStmt>(SubStmt);
@@ -6742,11 +6868,10 @@ Sema::ActOnStmtExpr(SourceLocation LPLoc, StmtArg substmt,
// FIXME: Check that expression type is complete/non-abstract; statement
// expressions are not lvalues.
- substmt.release();
return Owned(new (Context) StmtExpr(Compound, Ty, LPLoc, RPLoc));
}
-Sema::OwningExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
+ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
TypeSourceInfo *TInfo,
OffsetOfComponent *CompPtr,
unsigned NumComponents,
@@ -6865,22 +6990,27 @@ Sema::OwningExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
Diag(MemberDecl->getLocation(), diag::note_bitfield_decl);
return ExprError();
}
-
+
+ RecordDecl *Parent = MemberDecl->getParent();
+ bool AnonStructUnion = Parent->isAnonymousStructOrUnion();
+ if (AnonStructUnion) {
+ do {
+ Parent = cast<RecordDecl>(Parent->getParent());
+ } while (Parent->isAnonymousStructOrUnion());
+ }
+
// If the member was found in a base class, introduce OffsetOfNodes for
// the base class indirections.
CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
/*DetectVirtual=*/false);
- if (IsDerivedFrom(CurrentType,
- Context.getTypeDeclType(MemberDecl->getParent()),
- Paths)) {
+ if (IsDerivedFrom(CurrentType, Context.getTypeDeclType(Parent), Paths)) {
CXXBasePath &Path = Paths.front();
for (CXXBasePath::iterator B = Path.begin(), BEnd = Path.end();
B != BEnd; ++B)
Comps.push_back(OffsetOfNode(B->Base));
}
-
- if (cast<RecordDecl>(MemberDecl->getDeclContext())->
- isAnonymousStructOrUnion()) {
+
+ if (AnonStructUnion) {
llvm::SmallVector<FieldDecl*, 4> Path;
BuildAnonymousStructUnionMemberPath(MemberDecl, Path);
unsigned n = Path.size();
@@ -6897,10 +7027,10 @@ Sema::OwningExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
Exprs.data(), Exprs.size(), RParenLoc));
}
-Sema::OwningExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
+ExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
SourceLocation BuiltinLoc,
SourceLocation TypeLoc,
- TypeTy *argty,
+ ParsedType argty,
OffsetOfComponent *CompPtr,
unsigned NumComponents,
SourceLocation RPLoc) {
@@ -6910,151 +7040,32 @@ Sema::OwningExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
if (ArgTy.isNull())
return ExprError();
- if (getLangOptions().CPlusPlus) {
- if (!ArgTInfo)
- ArgTInfo = Context.getTrivialTypeSourceInfo(ArgTy, TypeLoc);
-
- return BuildBuiltinOffsetOf(BuiltinLoc, ArgTInfo, CompPtr, NumComponents,
- RPLoc);
- }
-
- // FIXME: The code below is marked for death, once we have proper CodeGen
- // support for non-constant OffsetOf expressions.
-
- bool Dependent = ArgTy->isDependentType();
-
- // We must have at least one component that refers to the type, and the first
- // one is known to be a field designator. Verify that the ArgTy represents
- // a struct/union/class.
- if (!Dependent && !ArgTy->isRecordType())
- return ExprError(Diag(TypeLoc, diag::err_offsetof_record_type) << ArgTy);
-
- // FIXME: Type must be complete per C99 7.17p3 because a declaring a variable
- // with an incomplete type would be illegal.
-
- // Otherwise, create a null pointer as the base, and iteratively process
- // the offsetof designators.
- QualType ArgTyPtr = Context.getPointerType(ArgTy);
- Expr* Res = new (Context) ImplicitValueInitExpr(ArgTyPtr);
- Res = new (Context) UnaryOperator(Res, UnaryOperator::Deref,
- ArgTy, SourceLocation());
-
- // offsetof with non-identifier designators (e.g. "offsetof(x, a.b[c])") are a
- // GCC extension, diagnose them.
- // FIXME: This diagnostic isn't actually visible because the location is in
- // a system header!
- if (NumComponents != 1)
- Diag(BuiltinLoc, diag::ext_offsetof_extended_field_designator)
- << SourceRange(CompPtr[1].LocStart, CompPtr[NumComponents-1].LocEnd);
-
- if (!Dependent) {
- bool DidWarnAboutNonPOD = false;
-
- if (RequireCompleteType(TypeLoc, Res->getType(),
- diag::err_offsetof_incomplete_type))
- return ExprError();
-
- // FIXME: Dependent case loses a lot of information here. And probably
- // leaks like a sieve.
- for (unsigned i = 0; i != NumComponents; ++i) {
- const OffsetOfComponent &OC = CompPtr[i];
- if (OC.isBrackets) {
- // Offset of an array sub-field. TODO: Should we allow vector elements?
- const ArrayType *AT = Context.getAsArrayType(Res->getType());
- if (!AT) {
- Res->Destroy(Context);
- return ExprError(Diag(OC.LocEnd, diag::err_offsetof_array_type)
- << Res->getType());
- }
-
- // FIXME: C++: Verify that operator[] isn't overloaded.
-
- // Promote the array so it looks more like a normal array subscript
- // expression.
- DefaultFunctionArrayLvalueConversion(Res);
-
- // C99 6.5.2.1p1
- Expr *Idx = static_cast<Expr*>(OC.U.E);
- // FIXME: Leaks Res
- if (!Idx->isTypeDependent() && !Idx->getType()->isIntegerType())
- return ExprError(Diag(Idx->getLocStart(),
- diag::err_typecheck_subscript_not_integer)
- << Idx->getSourceRange());
-
- Res = new (Context) ArraySubscriptExpr(Res, Idx, AT->getElementType(),
- OC.LocEnd);
- continue;
- }
-
- const RecordType *RC = Res->getType()->getAs<RecordType>();
- if (!RC) {
- Res->Destroy(Context);
- return ExprError(Diag(OC.LocEnd, diag::err_offsetof_record_type)
- << Res->getType());
- }
-
- // Get the decl corresponding to this.
- RecordDecl *RD = RC->getDecl();
- if (CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
- if (!CRD->isPOD() && !DidWarnAboutNonPOD &&
- DiagRuntimeBehavior(BuiltinLoc,
- PDiag(diag::warn_offsetof_non_pod_type)
- << SourceRange(CompPtr[0].LocStart, OC.LocEnd)
- << Res->getType()))
- DidWarnAboutNonPOD = true;
- }
-
- LookupResult R(*this, OC.U.IdentInfo, OC.LocStart, LookupMemberName);
- LookupQualifiedName(R, RD);
-
- FieldDecl *MemberDecl = R.getAsSingle<FieldDecl>();
- // FIXME: Leaks Res
- if (!MemberDecl)
- return ExprError(Diag(BuiltinLoc, diag::err_no_member)
- << OC.U.IdentInfo << RD << SourceRange(OC.LocStart, OC.LocEnd));
-
- // C99 7.17p3:
- // (If the specified member is a bit-field, the behavior is undefined.)
- //
- // We diagnose this as an error.
- if (MemberDecl->getBitWidth()) {
- Diag(OC.LocEnd, diag::err_offsetof_bitfield)
- << MemberDecl->getDeclName()
- << SourceRange(BuiltinLoc, RPLoc);
- Diag(MemberDecl->getLocation(), diag::note_bitfield_decl);
- return ExprError();
- }
-
- // FIXME: C++: Verify that MemberDecl isn't a static field.
- // FIXME: Verify that MemberDecl isn't a bitfield.
- if (cast<RecordDecl>(MemberDecl->getDeclContext())->isAnonymousStructOrUnion()) {
- Res = BuildAnonymousStructUnionMemberReference(
- OC.LocEnd, MemberDecl, Res, OC.LocEnd).takeAs<Expr>();
- } else {
- PerformObjectMemberConversion(Res, /*Qualifier=*/0,
- *R.begin(), MemberDecl);
- // MemberDecl->getType() doesn't get the right qualifiers, but it
- // doesn't matter here.
- Res = new (Context) MemberExpr(Res, false, MemberDecl, OC.LocEnd,
- MemberDecl->getType().getNonReferenceType());
- }
- }
- }
-
- return Owned(new (Context) UnaryOperator(Res, UnaryOperator::OffsetOf,
- Context.getSizeType(), BuiltinLoc));
+ if (!ArgTInfo)
+ ArgTInfo = Context.getTrivialTypeSourceInfo(ArgTy, TypeLoc);
+
+ return BuildBuiltinOffsetOf(BuiltinLoc, ArgTInfo, CompPtr, NumComponents,
+ RPLoc);
}
-Sema::OwningExprResult Sema::ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc,
- TypeTy *arg1,TypeTy *arg2,
+ExprResult Sema::ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc,
+ ParsedType arg1,ParsedType arg2,
SourceLocation RPLoc) {
- // FIXME: Preserve type source info.
- QualType argT1 = GetTypeFromParser(arg1);
- QualType argT2 = GetTypeFromParser(arg2);
+ TypeSourceInfo *argTInfo1;
+ QualType argT1 = GetTypeFromParser(arg1, &argTInfo1);
+ TypeSourceInfo *argTInfo2;
+ QualType argT2 = GetTypeFromParser(arg2, &argTInfo2);
assert((!argT1.isNull() && !argT2.isNull()) && "Missing type argument(s)");
+ return BuildTypesCompatibleExpr(BuiltinLoc, argTInfo1, argTInfo2, RPLoc);
+}
+
+ExprResult
+Sema::BuildTypesCompatibleExpr(SourceLocation BuiltinLoc,
+ TypeSourceInfo *argTInfo1,
+ TypeSourceInfo *argTInfo2,
+ SourceLocation RPLoc) {
if (getLangOptions().CPlusPlus) {
Diag(BuiltinLoc, diag::err_types_compatible_p_in_cplusplus)
<< SourceRange(BuiltinLoc, RPLoc);
@@ -7062,17 +7073,14 @@ Sema::OwningExprResult Sema::ActOnTypesCompatibleExpr(SourceLocation BuiltinLoc,
}
return Owned(new (Context) TypesCompatibleExpr(Context.IntTy, BuiltinLoc,
- argT1, argT2, RPLoc));
+ argTInfo1, argTInfo2, RPLoc));
}
-Sema::OwningExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc,
- ExprArg cond,
- ExprArg expr1, ExprArg expr2,
- SourceLocation RPLoc) {
- Expr *CondExpr = static_cast<Expr*>(cond.get());
- Expr *LHSExpr = static_cast<Expr*>(expr1.get());
- Expr *RHSExpr = static_cast<Expr*>(expr2.get());
+ExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc,
+ Expr *CondExpr,
+ Expr *LHSExpr, Expr *RHSExpr,
+ SourceLocation RPLoc) {
assert((CondExpr && LHSExpr && RHSExpr) && "Missing type argument(s)");
QualType resType;
@@ -7095,7 +7103,6 @@ Sema::OwningExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc,
: RHSExpr->isValueDependent();
}
- cond.release(); expr1.release(); expr2.release();
return Owned(new (Context) ChooseExpr(BuiltinLoc, CondExpr, LHSExpr, RHSExpr,
resType, RPLoc,
resType->isDependentType(),
@@ -7232,8 +7239,8 @@ void Sema::ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope) {
/// ActOnBlockStmtExpr - This is called when the body of a block statement
/// literal was successfully completed. ^(int x){...}
-Sema::OwningExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
- StmtArg body, Scope *CurScope) {
+ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
+ Stmt *Body, Scope *CurScope) {
// If blocks are disabled, emit an error.
if (!LangOpts.Blocks)
Diag(CaretLoc, diag::err_blocks_disable);
@@ -7295,10 +7302,10 @@ Sema::OwningExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
BlockTy = Context.getBlockPointerType(BlockTy);
// If needed, diagnose invalid gotos and switches in the block.
- if (FunctionNeedsScopeChecking() && !hasAnyErrorsInThisFunction())
- DiagnoseInvalidJumps(static_cast<CompoundStmt*>(body.get()));
+ if (getCurFunction()->NeedsScopeChecking() && !hasAnyErrorsInThisFunction())
+ DiagnoseInvalidJumps(cast<CompoundStmt>(Body));
- BSI->TheDecl->setBody(body.takeAs<CompoundStmt>());
+ BSI->TheDecl->setBody(cast<CompoundStmt>(Body));
bool Good = true;
// Check goto/label use.
@@ -7320,22 +7327,29 @@ Sema::OwningExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
return ExprError();
}
+ BlockExpr *Result = new (Context) BlockExpr(BSI->TheDecl, BlockTy,
+ BSI->hasBlockDeclRefExprs);
+
// Issue any analysis-based warnings.
const sema::AnalysisBasedWarnings::Policy &WP =
AnalysisWarnings.getDefaultPolicy();
- AnalysisWarnings.IssueWarnings(WP, BSI->TheDecl, BlockTy);
+ AnalysisWarnings.IssueWarnings(WP, Result);
- Expr *Result = new (Context) BlockExpr(BSI->TheDecl, BlockTy,
- BSI->hasBlockDeclRefExprs);
PopFunctionOrBlockScope();
return Owned(Result);
}
-Sema::OwningExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc,
- ExprArg expr, TypeTy *type,
+ExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc,
+ Expr *expr, ParsedType type,
SourceLocation RPLoc) {
- QualType T = GetTypeFromParser(type);
- Expr *E = static_cast<Expr*>(expr.get());
+ TypeSourceInfo *TInfo;
+ QualType T = GetTypeFromParser(type, &TInfo);
+ return BuildVAArgExpr(BuiltinLoc, expr, TInfo, RPLoc);
+}
+
+ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc,
+ Expr *E, TypeSourceInfo *TInfo,
+ SourceLocation RPLoc) {
Expr *OrigExpr = E;
InitBuiltinVaListType();
@@ -7367,13 +7381,11 @@ Sema::OwningExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc,
// FIXME: Check that type is complete/non-abstract
// FIXME: Warn if a non-POD type is passed in.
- expr.release();
- return Owned(new (Context) VAArgExpr(BuiltinLoc, E,
- T.getNonLValueExprType(Context),
- RPLoc));
+ QualType T = TInfo->getType().getNonLValueExprType(Context);
+ return Owned(new (Context) VAArgExpr(BuiltinLoc, E, TInfo, RPLoc, T));
}
-Sema::OwningExprResult Sema::ActOnGNUNullExpr(SourceLocation TokenLoc) {
+ExprResult Sema::ActOnGNUNullExpr(SourceLocation TokenLoc) {
// The type of __null will be int or long, depending on the size of
// pointers on the target.
QualType Ty;
@@ -7647,8 +7659,10 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) {
if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) {
unsigned TypeQuals;
if (Constructor->isImplicit() && Constructor->isDefaultConstructor()) {
- if (!Constructor->isUsed(false))
- DefineImplicitDefaultConstructor(Loc, Constructor);
+ if (Constructor->getParent()->hasTrivialConstructor())
+ return;
+ if (!Constructor->isUsed(false))
+ DefineImplicitDefaultConstructor(Loc, Constructor);
} else if (Constructor->isImplicit() &&
Constructor->isCopyConstructor(TypeQuals)) {
if (!Constructor->isUsed(false))
@@ -7696,13 +7710,20 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) {
PendingLocalImplicitInstantiations.push_back(std::make_pair(Function,
Loc));
else
- PendingImplicitInstantiations.push_back(std::make_pair(Function,
- Loc));
+ PendingInstantiations.push_back(std::make_pair(Function, Loc));
+ }
+ } else // Walk redefinitions, as some of them may be instantiable.
+ for (FunctionDecl::redecl_iterator i(Function->redecls_begin()),
+ e(Function->redecls_end()); i != e; ++i) {
+ if (!i->isUsed(false) && i->isImplicitlyInstantiable())
+ MarkDeclarationReferenced(Loc, *i);
}
- }
// FIXME: keep track of references to static functions
- Function->setUsed(true);
+
+ // Recursive functions should be marked when used from another function.
+ if (CurContext != Function)
+ Function->setUsed(true);
return;
}
@@ -7716,7 +7737,7 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) {
if (MSInfo->getPointOfInstantiation().isInvalid() &&
MSInfo->getTemplateSpecializationKind()== TSK_ImplicitInstantiation) {
MSInfo->setPointOfInstantiation(Loc);
- PendingImplicitInstantiations.push_back(std::make_pair(Var, Loc));
+ PendingInstantiations.push_back(std::make_pair(Var, Loc));
}
}
@@ -7836,7 +7857,7 @@ void Sema::DiagnoseAssignmentAsCondition(Expr *E) {
if (isa<BinaryOperator>(E)) {
BinaryOperator *Op = cast<BinaryOperator>(E);
- if (Op->getOpcode() != BinaryOperator::Assign)
+ if (Op->getOpcode() != BO_Assign)
return;
// Greylist some idioms by putting them into a warning subcategory.
@@ -7899,16 +7920,13 @@ bool Sema::CheckBooleanCondition(Expr *&E, SourceLocation Loc) {
return false;
}
-Sema::OwningExprResult Sema::ActOnBooleanCondition(Scope *S, SourceLocation Loc,
- ExprArg SubExpr) {
- Expr *Sub = SubExpr.takeAs<Expr>();
+ExprResult Sema::ActOnBooleanCondition(Scope *S, SourceLocation Loc,
+ Expr *Sub) {
if (!Sub)
return ExprError();
- if (CheckBooleanCondition(Sub, Loc)) {
- Sub->Destroy(Context);
+ if (CheckBooleanCondition(Sub, Loc))
return ExprError();
- }
return Owned(Sub);
}
OpenPOWER on IntegriCloud