diff options
author | Caitlin Sadowski <supertri@google.com> | 2011-09-08 17:42:22 +0000 |
---|---|---|
committer | Caitlin Sadowski <supertri@google.com> | 2011-09-08 17:42:22 +0000 |
commit | 9385dd7415826abe3484d49caa30fe97c7df1407 (patch) | |
tree | ad2e7f11ed20ca4a79dcfbecc9c462efff10b0de /clang/lib/Parse/ParseDeclCXX.cpp | |
parent | f774712782d69d8affff56453f0bea30d9d591e4 (diff) | |
download | bcm5719-llvm-9385dd7415826abe3484d49caa30fe97c7df1407.tar.gz bcm5719-llvm-9385dd7415826abe3484d49caa30fe97c7df1407.zip |
Thread Safety: Patch to implement delayed parsing of attributes within a
class scope.
This patch was also written by DeLesley Hutchins.
llvm-svn: 139301
Diffstat (limited to 'clang/lib/Parse/ParseDeclCXX.cpp')
-rw-r--r-- | clang/lib/Parse/ParseDeclCXX.cpp | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 385683abd6a..0dacf3c8a39 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -1707,6 +1707,9 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, VirtSpecifiers VS; ExprResult Init; + // Hold late-parsed attributes so we can attach a Decl to them later. + LateParsedAttrList LateParsedAttrs; + if (Tok.isNot(tok::colon)) { // Don't parse FOO:BAR as if it were a typo for FOO::BAR. ColonProtectionRAIIObject X(*this); @@ -1725,7 +1728,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, ParseOptionalCXX0XVirtSpecifierSeq(VS); // If attributes exist after the declarator, but before an '{', parse them. - MaybeParseGNUAttributes(DeclaratorInfo); + MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs); // MSVC permits pure specifier on inline functions declared at class scope. // Hence check for =0 before checking for function definition. @@ -1782,7 +1785,13 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, return; } - ParseCXXInlineMethodDef(AS, DeclaratorInfo, TemplateInfo, VS, Init); + Decl *FunDecl = + ParseCXXInlineMethodDef(AS, DeclaratorInfo, TemplateInfo, VS, Init); + + for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) { + LateParsedAttrs[i]->setDecl(FunDecl); + } + LateParsedAttrs.clear(); // Consume the ';' - it's optional unless we have a delete or default if (Tok.is(tok::semi)) { @@ -1824,7 +1833,7 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, } // If attributes exist after the declarator, parse them. - MaybeParseGNUAttributes(DeclaratorInfo); + MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs); // FIXME: When g++ adds support for this, we'll need to check whether it // goes before or after the GNU attributes and __asm__. @@ -1882,6 +1891,12 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, DeclaratorInfo.complete(ThisDecl); + // Set the Decl for any late parsed attributes + for (unsigned i = 0, ni = LateParsedAttrs.size(); i < ni; ++i) { + LateParsedAttrs[i]->setDecl(ThisDecl); + } + LateParsedAttrs.clear(); + if (HasDeferredInitializer) { if (!getLang().CPlusPlus0x) Diag(Tok, diag::warn_nonstatic_member_init_accepted_as_extension); @@ -2153,8 +2168,10 @@ void Parser::ParseCXXMemberSpecification(SourceLocation RecordLoc, if (TagDecl && NonNestedClass) { // We are not inside a nested class. This class and its nested classes // are complete and we can parse the delayed portions of method - // declarations and the lexed inline method definitions. + // declarations and the lexed inline method definitions, along with any + // delayed attributes. SourceLocation SavedPrevTokLocation = PrevTokLocation; + ParseLexedAttributes(getCurrentClass()); ParseLexedMethodDeclarations(getCurrentClass()); ParseLexedMemberInitializers(getCurrentClass()); ParseLexedMethodDefs(getCurrentClass()); |