summaryrefslogtreecommitdiff
path: root/lib/Parse/ParseDecl.cpp
diff options
context:
space:
mode:
authorLeonard Chan <leonardchan@google.com>2019-05-07 03:20:17 +0000
committerLeonard Chan <leonardchan@google.com>2019-05-07 03:20:17 +0000
commit8ad70e473414cc639f35b6e61ed3af1db334d845 (patch)
treeaa111eaab38e0ec00d0d241413b2299a32d9f523 /lib/Parse/ParseDecl.cpp
parent8797a17455a3930f894e2888f3f51135d6781d02 (diff)
downloadclang-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.cpp40
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;
+ }
+ }
}
}