}
};
+ /// \brief RAII object to handle the state changes required to synthesize
+ /// a function body.
+ class SynthesizedFunctionScope {
+ Sema &S;
+ Sema::ContextRAII SavedContext;
+
+ public:
+ SynthesizedFunctionScope(Sema &S, DeclContext *DC)
+ : S(S), SavedContext(S, DC)
+ {
+ S.PushFunctionScope();
+ S.PushExpressionEvaluationContext(Sema::PotentiallyEvaluated);
+ }
+
+ ~SynthesizedFunctionScope() {
+ S.PopExpressionEvaluationContext();
+ S.PopFunctionScopeInfo();
+ }
+ };
+
/// WeakUndeclaredIdentifiers - Identifiers contained in
/// \#pragma weak before declared. rare. may alias another
/// identifier, declared or undeclared
return AliasDecl;
}
-namespace {
- /// \brief Scoped object used to handle the state changes required in Sema
- /// to implicitly define the body of a C++ member function;
- class ImplicitlyDefinedFunctionScope {
- Sema &S;
- Sema::ContextRAII SavedContext;
-
- public:
- ImplicitlyDefinedFunctionScope(Sema &S, CXXMethodDecl *Method)
- : S(S), SavedContext(S, Method)
- {
- S.PushFunctionScope();
- S.PushExpressionEvaluationContext(Sema::PotentiallyEvaluated);
- }
-
- ~ImplicitlyDefinedFunctionScope() {
- S.PopExpressionEvaluationContext();
- S.PopFunctionScopeInfo();
- }
- };
-}
-
Sema::ImplicitExceptionSpecification
Sema::ComputeDefaultedDefaultCtorExceptionSpec(SourceLocation Loc,
CXXMethodDecl *MD) {
CXXRecordDecl *ClassDecl = Constructor->getParent();
assert(ClassDecl && "DefineImplicitDefaultConstructor - invalid constructor");
- ImplicitlyDefinedFunctionScope Scope(*this, Constructor);
+ SynthesizedFunctionScope Scope(*this, Constructor);
DiagnosticErrorTrap Trap(Diags);
if (SetCtorInitializers(Constructor, 0, 0, /*AnyErrors=*/false) ||
Trap.hasErrorOccurred()) {
if (Destructor->isInvalidDecl())
return;
- ImplicitlyDefinedFunctionScope Scope(*this, Destructor);
+ SynthesizedFunctionScope Scope(*this, Destructor);
DiagnosticErrorTrap Trap(Diags);
MarkBaseAndMemberDestructorsReferenced(Destructor->getLocation(),
CopyAssignOperator->setUsed();
- ImplicitlyDefinedFunctionScope Scope(*this, CopyAssignOperator);
+ SynthesizedFunctionScope Scope(*this, CopyAssignOperator);
DiagnosticErrorTrap Trap(Diags);
// C++0x [class.copy]p30:
MoveAssignOperator->setUsed();
- ImplicitlyDefinedFunctionScope Scope(*this, MoveAssignOperator);
+ SynthesizedFunctionScope Scope(*this, MoveAssignOperator);
DiagnosticErrorTrap Trap(Diags);
// C++0x [class.copy]p28:
CXXRecordDecl *ClassDecl = CopyConstructor->getParent();
assert(ClassDecl && "DefineImplicitCopyConstructor - invalid constructor");
- ImplicitlyDefinedFunctionScope Scope(*this, CopyConstructor);
+ SynthesizedFunctionScope Scope(*this, CopyConstructor);
DiagnosticErrorTrap Trap(Diags);
if (SetCtorInitializers(CopyConstructor, 0, 0, /*AnyErrors=*/false) ||
CXXRecordDecl *ClassDecl = MoveConstructor->getParent();
assert(ClassDecl && "DefineImplicitMoveConstructor - invalid constructor");
- ImplicitlyDefinedFunctionScope Scope(*this, MoveConstructor);
+ SynthesizedFunctionScope Scope(*this, MoveConstructor);
DiagnosticErrorTrap Trap(Diags);
if (SetCtorInitializers(MoveConstructor, 0, 0, /*AnyErrors=*/false) ||
Conv->setUsed();
- ImplicitlyDefinedFunctionScope Scope(*this, Conv);
+ SynthesizedFunctionScope Scope(*this, Conv);
DiagnosticErrorTrap Trap(Diags);
// Return the address of the __invoke function.
{
Conv->setUsed();
- ImplicitlyDefinedFunctionScope Scope(*this, Conv);
+ SynthesizedFunctionScope Scope(*this, Conv);
DiagnosticErrorTrap Trap(Diags);
// Copy-initialize the lambda object as needed to capture it.
// For Objective-C++, need to synthesize the AST for the IVAR object to be
// returned by the getter as it must conform to C++'s copy-return rules.
// FIXME. Eventually we want to do this for Objective-C as well.
+ SynthesizedFunctionScope Scope(*this, getterMethod);
ImplicitParamDecl *SelfDecl = getterMethod->getSelfDecl();
DeclRefExpr *SelfExpr =
new (Context) DeclRefExpr(SelfDecl, false, SelfDecl->getType(),
- VK_RValue, SourceLocation());
+ VK_RValue, PropertyDiagLoc);
+ MarkDeclRefReferenced(SelfExpr);
Expr *IvarRefExpr =
- new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), AtLoc,
+ new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), PropertyDiagLoc,
SelfExpr, true, true);
ExprResult Res =
PerformCopyInitialization(InitializedEntity::InitializeResult(
- SourceLocation(),
+ PropertyDiagLoc,
getterMethod->getResultType(),
/*NRVO=*/false),
- SourceLocation(),
+ PropertyDiagLoc,
Owned(IvarRefExpr));
if (!Res.isInvalid()) {
Expr *ResExpr = Res.takeAs<Expr>();
if (getLangOpts().CPlusPlus && Synthesize && !CompleteTypeErr &&
Ivar->getType()->isRecordType()) {
// FIXME. Eventually we want to do this for Objective-C as well.
+ SynthesizedFunctionScope Scope(*this, setterMethod);
ImplicitParamDecl *SelfDecl = setterMethod->getSelfDecl();
DeclRefExpr *SelfExpr =
new (Context) DeclRefExpr(SelfDecl, false, SelfDecl->getType(),
- VK_RValue, SourceLocation());
+ VK_RValue, PropertyDiagLoc);
+ MarkDeclRefReferenced(SelfExpr);
Expr *lhs =
- new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), AtLoc,
+ new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), PropertyDiagLoc,
SelfExpr, true, true);
ObjCMethodDecl::param_iterator P = setterMethod->param_begin();
ParmVarDecl *Param = (*P);
QualType T = Param->getType().getNonReferenceType();
- Expr *rhs = new (Context) DeclRefExpr(Param, false, T,
- VK_LValue, SourceLocation());
- ExprResult Res = BuildBinOp(S, lhs->getLocEnd(),
+ DeclRefExpr *rhs = new (Context) DeclRefExpr(Param, false, T,
+ VK_LValue, PropertyDiagLoc);
+ MarkDeclRefReferenced(rhs);
+ ExprResult Res = BuildBinOp(S, PropertyDiagLoc,
BO_Assign, lhs, rhs);
if (property->getPropertyAttributes() &
ObjCPropertyDecl::OBJC_PR_atomic) {
if (const FunctionDecl *FuncDecl = CXXCE->getDirectCallee())
if (!FuncDecl->isTrivial())
if (property->getType()->isReferenceType()) {
- Diag(PropertyLoc,
+ Diag(PropertyDiagLoc,
diag::err_atomic_property_nontrivial_assign_op)
<< property->getType();
Diag(FuncDecl->getLocStart(),
@implementation SynthIncompleteRef // expected-error {{cannot synthesize property 'x' with incomplete type 'IncompleteStruct'}}
@synthesize y; // expected-error {{cannot synthesize property 'y' with incomplete type 'IncompleteStruct'}}
@end
+
+
+// Check error handling for instantiation during property synthesis.
+template<typename T> class TemplateClass1 {
+ T *x; // expected-error {{'x' declared as a pointer to a reference of type 'int &'}}
+};
+template<typename T> class TemplateClass2 {
+ TemplateClass2& operator=(TemplateClass1<T>);
+ TemplateClass2& operator=(TemplateClass2) { T(); } // expected-error {{reference to type 'int' requires an initializer}} \
+ // expected-note 2 {{implicitly declared private here}} \
+ // expected-note {{'operator=' declared here}}
+};
+__attribute__((objc_root_class)) @interface InterfaceWithTemplateProperties
+@property TemplateClass2<int&> intprop;
+@property TemplateClass2<int&> &floatprop;
+@end
+@implementation InterfaceWithTemplateProperties // expected-error 2 {{'operator=' is a private member of 'TemplateClass2<int &>'}} \
+ // expected-error {{atomic property of reference type 'TemplateClass2<int &> &' cannot have non-trivial assignment operator}} \
+ // expected-note {{in instantiation of template class}} \
+ // expected-note {{in instantiation of member function}}
+@end