diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 63 |
1 files changed, 34 insertions, 29 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 4d33106aa85..4129950ea6e 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -851,10 +851,6 @@ void Parser::ParseLexedAttributes(ParsingClass &Class) { Actions.ActOnStartDelayedMemberDeclarations(getCurScope(), Class.TagOrTemplate); if (!Class.LateParsedDeclarations.empty()) { - // Allow 'this' within late-parsed attributes. - Sema::CXXThisScopeRAII ThisScope(Actions, Class.TagOrTemplate, - /*TypeQuals=*/0); - for (unsigned i = 0, ni = Class.LateParsedDeclarations.size(); i < ni; ++i){ Class.LateParsedDeclarations[i]->ParseLexedAttributes(); } @@ -904,34 +900,43 @@ void Parser::ParseLexedAttribute(LateParsedAttribute &LA, ParsedAttributes Attrs(AttrFactory); SourceLocation endLoc; - if (LA.Decls.size() == 1) { + if (LA.Decls.size() > 0) { Decl *D = LA.Decls[0]; + NamedDecl *ND = dyn_cast<NamedDecl>(D); + RecordDecl *RD = dyn_cast_or_null<RecordDecl>(D->getDeclContext()); - // If the Decl is templatized, add template parameters to scope. - bool HasTemplateScope = EnterScope && D->isTemplateDecl(); - ParseScope TempScope(this, Scope::TemplateParamScope, HasTemplateScope); - if (HasTemplateScope) - Actions.ActOnReenterTemplateScope(Actions.CurScope, D); - - // If the Decl is on a function, add function parameters to the scope. - bool HasFunctionScope = EnterScope && D->isFunctionOrFunctionTemplate(); - ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope, HasFunctionScope); - if (HasFunctionScope) - Actions.ActOnReenterFunctionContext(Actions.CurScope, D); - - ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc); - - if (HasFunctionScope) { - Actions.ActOnExitFunctionContext(); - FnScope.Exit(); // Pop scope, and remove Decls from IdResolver - } - if (HasTemplateScope) { - TempScope.Exit(); + // Allow 'this' within late-parsed attributes. + Sema::CXXThisScopeRAII ThisScope(Actions, RD, + /*TypeQuals=*/0, + ND && RD && ND->isCXXInstanceMember()); + + if (LA.Decls.size() == 1) { + // If the Decl is templatized, add template parameters to scope. + bool HasTemplateScope = EnterScope && D->isTemplateDecl(); + ParseScope TempScope(this, Scope::TemplateParamScope, HasTemplateScope); + if (HasTemplateScope) + Actions.ActOnReenterTemplateScope(Actions.CurScope, D); + + // If the Decl is on a function, add function parameters to the scope. + bool HasFunScope = EnterScope && D->isFunctionOrFunctionTemplate(); + ParseScope FnScope(this, Scope::FnScope|Scope::DeclScope, HasFunScope); + if (HasFunScope) + Actions.ActOnReenterFunctionContext(Actions.CurScope, D); + + ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc); + + if (HasFunScope) { + Actions.ActOnExitFunctionContext(); + FnScope.Exit(); // Pop scope, and remove Decls from IdResolver + } + if (HasTemplateScope) { + TempScope.Exit(); + } + } else { + // If there are multiple decls, then the decl cannot be within the + // function scope. + ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc); } - } else if (LA.Decls.size() > 0) { - // If there are multiple decls, then the decl cannot be within the - // function scope. - ParseGNUAttributeArgs(&LA.AttrName, LA.AttrNameLoc, Attrs, &endLoc); } else { Diag(Tok, diag::warn_attribute_no_decl) << LA.AttrName.getName(); } |