RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext());
// Allow 'this' within late-parsed attributes.
- Sema::CXXThisScopeRAII ThisScope(Actions, RD,
- /*TypeQuals=*/0,
- ND && RD && ND->isCXXInstanceMember());
+ Sema::CXXThisScopeRAII ThisScope(Actions, RD, /*TypeQuals=*/0,
+ ND && ND->isCXXInstanceMember());
if (LA.Decls.size() == 1) {
// If the Decl is templatized, add template parameters to scope.
E = LateAttrs.end(); I != E; ++I) {
assert(CurrentInstantiationScope == Instantiator.getStartingScope());
CurrentInstantiationScope = I->Scope;
+
+ // Allow 'this' within late-parsed attributes.
+ NamedDecl *ND = dyn_cast<NamedDecl>(I->NewDecl);
+ CXXRecordDecl *ThisContext =
+ dyn_cast_or_null<CXXRecordDecl>(ND->getDeclContext());
+ CXXThisScopeRAII ThisScope(*this, ThisContext, /*TypeQuals*/0,
+ ND && ND->isCXXInstanceMember());
+
Attr *NewAttr =
instantiateTemplateAttribute(I->TmplAttr, Context, *this, TemplateArgs);
I->NewDecl->addAttr(NewAttr);
Saved = CurrentInstantiationScope->cloneScopes(OuterMostScope);
LateAttrs->push_back(LateInstantiatedAttribute(TmplAttr, Saved, New));
} else {
+ // Allow 'this' within late-parsed attributes.
+ NamedDecl *ND = dyn_cast<NamedDecl>(New);
+ CXXRecordDecl *ThisContext =
+ dyn_cast_or_null<CXXRecordDecl>(ND->getDeclContext());
+ CXXThisScopeRAII ThisScope(*this, ThisContext, /*TypeQuals*/0,
+ ND && ND->isCXXInstanceMember());
+
Attr *NewAttr = sema::instantiateTemplateAttribute(TmplAttr, Context,
*this, TemplateArgs);
if (NewAttr)
CXXRecordDecl *ThisContext = 0;
unsigned ThisTypeQuals = 0;
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
- ThisContext = Method->getParent();
+ ThisContext = cast<CXXRecordDecl>(Owner);
ThisTypeQuals = Method->getTypeQualifiers();
}
bool Expand = false;
bool RetainExpansion = false;
- Optional<unsigned> NumExpansions
- = PackExpansion->getNumExpansions();
+ Optional<unsigned> NumExpansions = PackExpansion->getNumExpansions();
if (SemaRef.CheckParameterPacksForExpansion(New->getLocation(),
SourceRange(),
Unexpanded,
template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
- DeclContext *DC = getSema().getFunctionLevelDeclContext();
- QualType T;
- if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(DC))
- T = MD->getThisType(getSema().Context);
- else if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(DC)) {
- T = getSema().Context.getPointerType(
- getSema().Context.getRecordType(Record));
- } else {
- assert(SemaRef.Context.getDiagnostics().hasErrorOccurred() &&
- "this in the wrong scope?");
- return ExprError();
- }
+ QualType T = getSema().getCurrentThisType();
if (!getDerived().AlwaysRebuild() && T == E->getType()) {
// Make sure that we capture 'this'.
float &f(T*) const noexcept;
T* ptr;
- auto g1() noexcept(noexcept(f(ptr))) -> decltype(f((*this).ptr));
+ auto g1() noexcept(noexcept(f(ptr))) -> decltype(f(ptr));
auto g2() const noexcept(noexcept(f(((this))->ptr))) -> decltype(f(ptr));
+ auto g3() noexcept(noexcept(f(this->ptr))) -> decltype(f((*this).ptr));
+ auto g4() const noexcept(noexcept(f(((this))->ptr))) -> decltype(f(this->ptr));
+ auto g5() noexcept(noexcept(this->f(ptr))) -> decltype(this->f(ptr));
+ auto g6() const noexcept(noexcept(this->f(((this))->ptr))) -> decltype(this->f(ptr));
+ auto g7() noexcept(noexcept(this->f(this->ptr))) -> decltype(this->f((*this).ptr));
+ auto g8() const noexcept(noexcept(this->f(((this))->ptr))) -> decltype(this->f(this->ptr));
};
void test_C(C<int> ci) {
- int *p = 0;
int &ir = ci.g1();
float &fr = ci.g2();
+ int &ir2 = ci.g3();
+ float &fr2 = ci.g4();
+ int &ir3 = ci.g5();
+ float &fr3 = ci.g6();
+ int &ir4 = ci.g7();
+ float &fr4 = ci.g8();
static_assert(!noexcept(ci.g1()), "exception-specification failure");
static_assert(noexcept(ci.g2()), "exception-specification failure");
+ static_assert(!noexcept(ci.g3()), "exception-specification failure");
+ static_assert(noexcept(ci.g4()), "exception-specification failure");
+ static_assert(!noexcept(ci.g5()), "exception-specification failure");
+ static_assert(noexcept(ci.g6()), "exception-specification failure");
+ static_assert(!noexcept(ci.g7()), "exception-specification failure");
+ static_assert(noexcept(ci.g8()), "exception-specification failure");
+}
+
+namespace PR14263 {
+ template<typename T> struct X {
+ void f();
+ T f() const;
+
+ auto g() -> decltype(this->f()) { return f(); }
+ auto g() const -> decltype(this->f()) { return f(); }
+ };
+ template struct X<int>;
}
namespace PR10036 {