diff options
author | Leonard Chan <leonardchan@google.com> | 2019-05-07 03:20:17 +0000 |
---|---|---|
committer | Leonard Chan <leonardchan@google.com> | 2019-05-07 03:20:17 +0000 |
commit | 8ad70e473414cc639f35b6e61ed3af1db334d845 (patch) | |
tree | aa111eaab38e0ec00d0d241413b2299a32d9f523 /lib/Parse/ParseDecl.cpp | |
parent | 8797a17455a3930f894e2888f3f51135d6781d02 (diff) | |
download | clang-8ad70e473414cc639f35b6e61ed3af1db334d845.tar.gz |
Recommit r359859 "[Attribute/Diagnostics] Print macro if definition is an attribute declaration"
Updated with fix for read of uninitialized memory.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@360109 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseDecl.cpp')
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index c4f02b9b99..21a656319c 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -85,6 +85,23 @@ static bool isAttributeLateParsed(const IdentifierInfo &II) { #undef CLANG_ATTR_LATE_PARSED_LIST } +/// Check if the a start and end source location expand to the same macro. +bool FindLocsWithCommonFileID(Preprocessor &PP, SourceLocation StartLoc, + SourceLocation EndLoc) { + if (!StartLoc.isMacroID() || !EndLoc.isMacroID()) + return false; + + SourceManager &SM = PP.getSourceManager(); + if (SM.getFileID(StartLoc) != SM.getFileID(EndLoc)) + return false; + + bool AttrStartIsInMacro = + Lexer::isAtStartOfMacroExpansion(StartLoc, SM, PP.getLangOpts()); + bool AttrEndIsInMacro = + Lexer::isAtEndOfMacroExpansion(EndLoc, SM, PP.getLangOpts()); + return AttrStartIsInMacro && AttrEndIsInMacro; +} + /// ParseGNUAttributes - Parse a non-empty attributes list. /// /// [GNU] attributes: @@ -133,7 +150,10 @@ void Parser::ParseGNUAttributes(ParsedAttributes &attrs, assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!"); while (Tok.is(tok::kw___attribute)) { - ConsumeToken(); + SourceLocation AttrTokLoc = ConsumeToken(); + unsigned OldNumAttrs = attrs.size(); + unsigned OldNumLateAttrs = LateAttrs ? LateAttrs->size() : 0; + if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, "attribute")) { SkipUntil(tok::r_paren, StopAtSemi); // skip until ) or ; @@ -201,6 +221,24 @@ void Parser::ParseGNUAttributes(ParsedAttributes &attrs, SkipUntil(tok::r_paren, StopAtSemi); if (endLoc) *endLoc = Loc; + + // If this was declared in a macro, attach the macro IdentifierInfo to the + // parsed attribute. + if (FindLocsWithCommonFileID(PP, AttrTokLoc, Loc)) { + auto &SM = PP.getSourceManager(); + CharSourceRange ExpansionRange = SM.getExpansionRange(AttrTokLoc); + StringRef FoundName = + Lexer::getSourceText(ExpansionRange, SM, PP.getLangOpts()); + IdentifierInfo *MacroII = PP.getIdentifierInfo(FoundName); + + for (unsigned i = OldNumAttrs; i < attrs.size(); ++i) + attrs[i].setMacroIdentifier(MacroII, ExpansionRange.getBegin()); + + if (LateAttrs) { + for (unsigned i = OldNumLateAttrs; i < LateAttrs->size(); ++i) + (*LateAttrs)[i]->MacroII = MacroII; + } + } } } |