/// Finds the tokens that are consecutive (from the same FileID) /// creates a single SLocEntry, and assigns SourceLocations to each token that /// point to that SLocEntry. e.g for /// assert(foo == bar); /// There will be a single SLocEntry for the "foo == bar" chunk and locations /// for the 'foo', '==', 'bar' tokens will point inside that chunk. /// /// \arg begin_tokens will be updated to a position past all the found /// consecutive tokens. static void updateConsecutiveMacroArgTokens(SourceManager &SM, SourceLocation InstLoc, Token *&begin_tokens, Token * end_tokens) { assert(begin_tokens < end_tokens); SourceLocation FirstLoc = begin_tokens->getLocation(); SourceLocation CurLoc = FirstLoc; // Compare the source location offset of tokens and group together tokens that // are close, even if their locations point to different FileIDs. e.g. // // |bar | foo | cake | (3 tokens from 3 consecutive FileIDs) // ^ ^ // |bar foo cake| (one SLocEntry chunk for all tokens) // // we can perform this "merge" since the token's spelling location depends // on the relative offset. Token *NextTok = begin_tokens + 1; for (; NextTok < end_tokens; ++NextTok) { SourceLocation NextLoc = NextTok->getLocation(); if (CurLoc.isFileID() != NextLoc.isFileID()) break; // Token from different kind of FileID. int RelOffs; if (!SM.isInSameSLocAddrSpace(CurLoc, NextLoc, &RelOffs)) break; // Token from different local/loaded location. // Check that token is not before the previous token or more than 50 // "characters" away. if (RelOffs < 0 || RelOffs > 50) break; if (CurLoc.isMacroID() && !SM.isWrittenInSameFile(CurLoc, NextLoc)) break; // Token from a different macro. CurLoc = NextLoc; } // For the consecutive tokens, find the length of the SLocEntry to contain // all of them. Token &LastConsecutiveTok = *(NextTok-1); int LastRelOffs = 0; SM.isInSameSLocAddrSpace(FirstLoc, LastConsecutiveTok.getLocation(), &LastRelOffs); unsigned FullLength = LastRelOffs + LastConsecutiveTok.getLength(); // Create a macro expansion SLocEntry that will "contain" all of the tokens. SourceLocation Expansion = SM.createMacroArgExpansionLoc(FirstLoc, InstLoc,FullLength); // Change the location of the tokens from the spelling location to the new // expanded location. for (; begin_tokens < NextTok; ++begin_tokens) { Token &Tok = *begin_tokens; int RelOffs = 0; SM.isInSameSLocAddrSpace(FirstLoc, Tok.getLocation(), &RelOffs); Tok.setLocation(Expansion.getLocWithOffset(RelOffs)); } }