diff options
Diffstat (limited to 'lib/Lex/MacroInfo.cpp')
| -rw-r--r-- | lib/Lex/MacroInfo.cpp | 32 | 
1 files changed, 32 insertions, 0 deletions
| diff --git a/lib/Lex/MacroInfo.cpp b/lib/Lex/MacroInfo.cpp index 66d87a19386a..0a16a2567219 100644 --- a/lib/Lex/MacroInfo.cpp +++ b/lib/Lex/MacroInfo.cpp @@ -25,6 +25,7 @@ MacroInfo::MacroInfo(SourceLocation DefLoc) : Location(DefLoc) {    IsUsed = false;    IsAllowRedefinitionsWithoutWarning = false;    IsWarnIfUnused = false; +  IsDefinitionLengthCached = false;    ArgumentList = 0;    NumArguments = 0; @@ -43,11 +44,42 @@ MacroInfo::MacroInfo(const MacroInfo &MI, llvm::BumpPtrAllocator &PPAllocator) {    IsUsed = MI.IsUsed;    IsAllowRedefinitionsWithoutWarning = MI.IsAllowRedefinitionsWithoutWarning;    IsWarnIfUnused = MI.IsWarnIfUnused; +  IsDefinitionLengthCached = MI.IsDefinitionLengthCached; +  DefinitionLength = MI.DefinitionLength;    ArgumentList = 0;    NumArguments = 0;    setArgumentList(MI.ArgumentList, MI.NumArguments, PPAllocator);  } +unsigned MacroInfo::getDefinitionLengthSlow(SourceManager &SM) const { +  assert(!IsDefinitionLengthCached); +  IsDefinitionLengthCached = true; + +  if (ReplacementTokens.empty()) +    return (DefinitionLength = 0); + +  const Token &firstToken = ReplacementTokens.front(); +  const Token &lastToken = ReplacementTokens.back(); +  SourceLocation macroStart = firstToken.getLocation(); +  SourceLocation macroEnd = lastToken.getLocation(); +  assert(macroStart.isValid() && macroEnd.isValid()); +  assert((macroStart.isFileID() || firstToken.is(tok::comment)) && +         "Macro defined in macro?"); +  assert((macroEnd.isFileID() || lastToken.is(tok::comment)) && +         "Macro defined in macro?"); +  std::pair<FileID, unsigned> +      startInfo = SM.getDecomposedInstantiationLoc(macroStart); +  std::pair<FileID, unsigned> +      endInfo = SM.getDecomposedInstantiationLoc(macroEnd); +  assert(startInfo.first == endInfo.first && +         "Macro definition spanning multiple FileIDs ?"); +  assert(startInfo.second <= endInfo.second); +  DefinitionLength = endInfo.second - startInfo.second; +  DefinitionLength += lastToken.getLength(); + +  return DefinitionLength; +} +  /// isIdenticalTo - Return true if the specified macro definition is equal to  /// this macro in spelling, arguments, and whitespace.  This is used to emit  /// duplicate definition warnings.  This implements the rules in C99 6.10.3. | 
