//===--- ImportMacro.cpp - Import Clang preprocessor macros ---------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file implements support for translating some kinds of C preprocessor
// macros into Swift declarations.
//
//===----------------------------------------------------------------------===//

#include "ImporterImpl.h"
#include "llvm/ADT/SmallString.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Expr.h"
#include "clang/Lex/MacroInfo.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Sema/DelayedDiagnostic.h"
#include "clang/Sema/Sema.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/Expr.h"
#include "swift/AST/Stmt.h"
#include "swift/AST/Types.h"
#include "swift/Basic/PrettyStackTrace.h"
#include "swift/ClangImporter/ClangModule.h"

using namespace swift;
using namespace importer;

template <typename T = clang::Expr>
static const T *
parseNumericLiteral(ClangImporter::Implementation &impl,
                    const clang::Token &tok) {
  auto result = impl.getClangSema().ActOnNumericConstant(tok);
  if (result.isUsable())
    return dyn_cast<T>(result.get());
  return nullptr;
}

// FIXME: Duplicated from ImportDecl.cpp.
static bool isInSystemModule(DeclContext *D) {
  return cast<ClangModuleUnit>(D->getModuleScopeContext())->isSystemModule();
}

static ValueDecl *
createMacroConstant(ClangImporter::Implementation &Impl,
                    const clang::MacroInfo *macro,
                    Identifier name,
                    DeclContext *dc,
                    Type type,
                    const clang::APValue &value,
                    ConstantConvertKind convertKind,
                    bool isStatic,
                    ClangNode ClangN) {
  Impl.ImportedMacroConstants[macro] = {value, type};
  return Impl.createConstant(name, dc, type, value, convertKind, isStatic,
                             ClangN);
}

static ValueDecl *importNumericLiteral(ClangImporter::Implementation &Impl,
                                       DeclContext *DC,
                                       const clang::MacroInfo *MI,
                                       Identifier name,
                                       const clang::Token *signTok,
                                       const clang::Token &tok,
                                       ClangNode ClangN,
                                       clang::QualType castType) {
  assert(tok.getKind() == clang::tok::numeric_constant &&
         "not a numeric token");
  {
    // Temporary hack to reject literals with ud-suffix.
    // FIXME: remove this when the following radar is implemented:
    // <rdar://problem/16445608> Swift should set up a DiagnosticConsumer for
    // Clang
    llvm::SmallString<32> SpellingBuffer;
    bool Invalid = false;
    StringRef TokSpelling =
        Impl.getClangPreprocessor().getSpelling(tok, SpellingBuffer, &Invalid);
    if (Invalid)
      return nullptr;
    if (TokSpelling.find('_') != StringRef::npos)
      return nullptr;
  }

  if (const clang::Expr *parsed = parseNumericLiteral<>(Impl, tok)) {
    auto clangTy = parsed->getType();
    auto literalType = Impl.importTypeIgnoreIUO(
        clangTy, ImportTypeKind::Value, isInSystemModule(DC),
        Bridgeability::None);
    if (!literalType)
      return nullptr;

    Type constantType;
    if (castType.isNull()) {
      constantType = literalType;
    } else {
      constantType = Impl.importTypeIgnoreIUO(
          castType, ImportTypeKind::Value, isInSystemModule(DC),
          Bridgeability::None);
      if (!constantType)
        return nullptr;
    }

    if (auto *integer = dyn_cast<clang::IntegerLiteral>(parsed)) {
      // Determine the value.
      llvm::APSInt value{integer->getValue(), clangTy->isUnsignedIntegerType()};

      // If there was a - sign, negate the value.
      // If there was a ~, flip all bits.
      if (signTok) {
        if (signTok->is(clang::tok::minus)) {
          if (!value.isMinSignedValue())
            value = -value;
        } else if (signTok->is(clang::tok::tilde)) {
          value.flipAllBits();
        }
      }

      return createMacroConstant(Impl, MI, name, DC, constantType,
                                 clang::APValue(value),
                                 ConstantConvertKind::Coerce,
                                 /*static*/ false, ClangN);
    }

    if (auto *floating = dyn_cast<clang::FloatingLiteral>(parsed)) {
      // ~ doesn't make sense with floating-point literals.
      if (signTok && signTok->is(clang::tok::tilde))
        return nullptr;

      llvm::APFloat value = floating->getValue();

      // If there was a - sign, negate the value.
      if (signTok && signTok->is(clang::tok::minus)) {
        value.changeSign();
      }

      return createMacroConstant(Impl, MI, name, DC, constantType,
                                 clang::APValue(value),
                                 ConstantConvertKind::Coerce,
                                 /*static*/ false, ClangN);
    }
    // TODO: Other numeric literals (complex, imaginary, etc.)
  }
  return nullptr;
}

static bool isStringToken(const clang::Token &tok) {
  return tok.is(clang::tok::string_literal) ||
         tok.is(clang::tok::utf8_string_literal);
}

// Describes the kind of string literal we're importing.
enum class MappedStringLiteralKind {
  CString,  // "string"
  NSString, // @"string"
  CFString  // CFSTR("string")
};

static ValueDecl *importStringLiteral(ClangImporter::Implementation &Impl,
                                      DeclContext *DC,
                                      const clang::MacroInfo *MI,
                                      Identifier name,
                                      const clang::Token &tok,
                                      MappedStringLiteralKind kind,
                                      ClangNode ClangN) {
  assert(isStringToken(tok));

  clang::ActionResult<clang::Expr*> result =
    Impl.getClangSema().ActOnStringLiteral(tok);
  if (!result.isUsable())
    return nullptr;

  auto parsed = dyn_cast<clang::StringLiteral>(result.get());
  if (!parsed)
    return nullptr;

  Type importTy = Impl.getNamedSwiftType(Impl.getStdlibModule(), "String");
  if (!importTy)
    return nullptr;

  return Impl.createConstant(name, DC, importTy, parsed->getString(),
                             ConstantConvertKind::Coerce, /*static*/ false,
                             ClangN);
}

static ValueDecl *importLiteral(ClangImporter::Implementation &Impl,
                                DeclContext *DC,
                                const clang::MacroInfo *MI,
                                Identifier name,
                                const clang::Token &tok,
                                ClangNode ClangN,
                                clang::QualType castType) {
  switch (tok.getKind()) {
  case clang::tok::numeric_constant:
    return importNumericLiteral(Impl, DC, MI, name, /*signTok*/nullptr, tok,
                                ClangN, castType);

  case clang::tok::string_literal:
  case clang::tok::utf8_string_literal:
    return importStringLiteral(Impl, DC, MI, name, tok,
                               MappedStringLiteralKind::CString, ClangN);

  // TODO: char literals.
  default:
    return nullptr;
  }
}

static ValueDecl *importNil(ClangImporter::Implementation &Impl,
                            DeclContext *DC, Identifier name,
                            ClangNode clangN) {
  // We use a dummy type since we don't have a convenient type for 'nil'.  Any
  // use of this will be an error anyway.
  auto type = TupleType::getEmpty(Impl.SwiftContext);
  return Impl.createUnavailableDecl(name, DC, type,
                                    "use 'nil' instead of this imported macro",
                                    /*isStatic=*/false, clangN);
}

static bool isSignToken(const clang::Token &tok) {
  return tok.is(clang::tok::plus) || tok.is(clang::tok::minus) ||
         tok.is(clang::tok::tilde);
}

static Optional<clang::QualType> builtinTypeForToken(const clang::Token &tok,
    const clang::ASTContext &context) {
  switch (tok.getKind()) {
  case clang::tok::kw_short:
    return clang::QualType(context.ShortTy);
  case clang::tok::kw_long:
    return clang::QualType(context.LongTy);
  case clang::tok::kw___int64:
    return clang::QualType(context.LongLongTy);
  case clang::tok::kw___int128:
    return clang::QualType(context.Int128Ty);
  case clang::tok::kw_signed:
    return clang::QualType(context.IntTy);
  case clang::tok::kw_unsigned:
    return clang::QualType(context.UnsignedIntTy);
  case clang::tok::kw_void:
    return clang::QualType(context.VoidTy);
  case clang::tok::kw_char:
    return clang::QualType(context.CharTy);
  case clang::tok::kw_int:
    return clang::QualType(context.IntTy);
  case clang::tok::kw_float:
    return clang::QualType(context.FloatTy);
  case clang::tok::kw_double:
    return clang::QualType(context.DoubleTy);
  case clang::tok::kw_wchar_t:
    return clang::QualType(context.WCharTy);
  case clang::tok::kw_bool:
    return clang::QualType(context.BoolTy);
  case clang::tok::kw_char16_t:
    return clang::QualType(context.Char16Ty);
  case clang::tok::kw_char32_t:
    return clang::QualType(context.Char32Ty);
  default:
    return llvm::None;
  }
}

static Optional<std::pair<llvm::APSInt, Type>>
  getIntegerConstantForMacroToken(ClangImporter::Implementation &impl,
                                  DeclContext *DC,
                                  const clang::Token &token) {

  // Integer literal.
  if (token.is(clang::tok::numeric_constant)) {
    if (auto literal = parseNumericLiteral<clang::IntegerLiteral>(impl,token)) {
      auto value = llvm::APSInt { literal->getValue(),
                                  literal->getType()->isUnsignedIntegerType() };
      auto type = impl.importTypeIgnoreIUO(
          literal->getType(), ImportTypeKind::Value, isInSystemModule(DC),
          Bridgeability::None);
      return {{ value, type }};
    }

  // Macro identifier.
  } else if (token.is(clang::tok::identifier) &&
             token.getIdentifierInfo()->hasMacroDefinition()) {

    auto rawID = token.getIdentifierInfo();
    auto definition = impl.getClangPreprocessor().getMacroDefinition(rawID);
    if (!definition)
      return None;

    ClangNode macroNode;
    const clang::MacroInfo *macroInfo;
    if (definition.getModuleMacros().empty()) {
      macroInfo = definition.getMacroInfo();
      macroNode = macroInfo;
    } else {
      // Follow MacroDefinition::getMacroInfo in preferring the last ModuleMacro
      // rather than the first.
      const clang::ModuleMacro *moduleMacro =
          definition.getModuleMacros().back();
      macroInfo = moduleMacro->getMacroInfo();
      macroNode = moduleMacro;
    }
    auto importedID = impl.getNameImporter().importMacroName(rawID, macroInfo);
    (void)impl.importMacro(importedID, macroNode);

    auto searcher = impl.ImportedMacroConstants.find(macroInfo);
    if (searcher == impl.ImportedMacroConstants.end()) {
      return None;
    }
    auto importedConstant = searcher->second;
    if (!importedConstant.first.isInt()) {
      return None;
    }
    return {{ importedConstant.first.getInt(), importedConstant.second }};
  }

  return None;
}


static ValueDecl *importMacro(ClangImporter::Implementation &impl,
                              DeclContext *DC,
                              Identifier name,
                              const clang::MacroInfo *macro,
                              ClangNode ClangN,
                              clang::QualType castType) {
  if (name.empty()) return nullptr;

  auto numTokens = macro->getNumTokens();
  auto tokenI = macro->tokens_begin(), tokenE = macro->tokens_end();

  // Drop one layer of parentheses.
  if (numTokens > 2 &&
      tokenI[0].is(clang::tok::l_paren) &&
      tokenE[-1].is(clang::tok::r_paren)) {
    ++tokenI;
    --tokenE;
    numTokens -= 2;
  }

  // Handle tokens starting with a type cast
  bool castTypeIsId = false;
  if (numTokens > 3 &&
      tokenI[0].is(clang::tok::l_paren) &&
      (tokenI[1].is(clang::tok::identifier) ||
        impl.getClangSema().isSimpleTypeSpecifier(tokenI[1].getKind())) &&
      tokenI[2].is(clang::tok::r_paren)) {
    if (!castType.isNull()) {
      // this is a nested cast
      return nullptr;
    }

    if (tokenI[1].is(clang::tok::identifier)) {
      auto identifierInfo = tokenI[1].getIdentifierInfo();
      if (identifierInfo->isStr("id")) {
        castTypeIsId = true;
      }
      auto identifierName = identifierInfo->getName();
      auto &identifier = impl.getClangASTContext().Idents.get(identifierName);

      clang::sema::DelayedDiagnosticPool diagPool{
          impl.getClangSema().DelayedDiagnostics.getCurrentPool()};
      auto diagState = impl.getClangSema().DelayedDiagnostics.push(diagPool);
      auto parsedType = impl.getClangSema().getTypeName(identifier,
                                                        clang::SourceLocation(),
                                                        /*scope*/nullptr);
      impl.getClangSema().DelayedDiagnostics.popWithoutEmitting(diagState);

      if (parsedType && diagPool.empty()) {
        castType = parsedType.get();
      } else {
        return nullptr;
      }
      if (!castType->isBuiltinType() && !castTypeIsId) {
        return nullptr;
      }
    } else {
      auto builtinType = builtinTypeForToken(tokenI[1],
                                             impl.getClangASTContext());
      if (builtinType) {
        castType = builtinType.getValue();
      } else {
        return nullptr;
      }
    }
    tokenI += 3;
    numTokens -= 3;
  }

  // FIXME: Ask Clang to try to parse and evaluate the expansion as a constant
  // expression instead of doing these special-case pattern matches.
  switch (numTokens) {
  case 1: {
    // Check for a single-token expansion of the form <literal>.
    // TODO: or <identifier>.
    const clang::Token &tok = *tokenI;

    if (castTypeIsId && tok.is(clang::tok::numeric_constant)) {
      auto *integerLiteral =
        parseNumericLiteral<clang::IntegerLiteral>(impl, tok);
      if (integerLiteral && integerLiteral->getValue() == 0)
        return importNil(impl, DC, name, ClangN);
    }

    // If it's a literal token, we might be able to translate the literal.
    if (tok.isLiteral()) {
      return importLiteral(impl, DC, macro, name, tok, ClangN, castType);
    }

    if (tok.is(clang::tok::identifier)) {
      auto clangID = tok.getIdentifierInfo();

      // If it's an identifier that is itself a macro, look into that macro.
      if (clangID->hasMacroDefinition()) {
        auto isNilMacro =
          llvm::StringSwitch<bool>(clangID->getName())
#define NIL_MACRO(NAME) .Case(#NAME, true)
#include "MacroTable.def"
          .Default(false);
        if (isNilMacro)
          return importNil(impl, DC, name, ClangN);

        auto macroID = impl.getClangPreprocessor().getMacroInfo(clangID);
        if (macroID && macroID != macro) {
          // FIXME: This was clearly intended to pass the cast type down, but
          // doing so would be a behavior change.
          return importMacro(impl, DC, name, macroID, ClangN, /*castType*/{});
        }
      }

      // FIXME: If the identifier refers to a declaration, alias it?
    }
    return nullptr;
  }
  case 2: {
    // Check for a two-token expansion of the form +<number> or -<number>.
    // These are technically subtly wrong without parentheses because they
    // allow things like:
    //   #define EOF -1
    //   int pred(int x) { return x EOF; }
    // but are pervasive in C headers anyway.
    clang::Token const &first = tokenI[0];
    clang::Token const &second = tokenI[1];

    if (isSignToken(first) && second.is(clang::tok::numeric_constant))
      return importNumericLiteral(impl, DC, macro, name, &first, second, ClangN,
                                  castType);

    // We also allow @"string".
    if (first.is(clang::tok::at) && isStringToken(second))
      return importStringLiteral(impl, DC, macro, name, second,
                                 MappedStringLiteralKind::NSString, ClangN);
    break;
  }
  case 3: {
    // Check for infix operations between two integer constants.
    // Import the result as another integer constant:
    //   #define INT3 (INT1 <op> INT2)
    // Doesn't allow inner parentheses.

    // Parse INT1.
    llvm::APSInt firstValue;
    Type firstSwiftType = nullptr;
    if (auto firstInt = getIntegerConstantForMacroToken(impl, DC, tokenI[0])) {
      firstValue     = firstInt->first;
      firstSwiftType = firstInt->second;
    } else {
      return nullptr;
    }

    // Parse INT2.
    llvm::APSInt secondValue;
    Type secondSwiftType = nullptr;
    if (auto secondInt = getIntegerConstantForMacroToken(impl, DC, tokenI[2])) {
      secondValue     = secondInt->first;
      secondSwiftType = secondInt->second;
    } else {
      return nullptr;
    }

    llvm::APSInt resultValue;
    Type resultSwiftType = nullptr;

    // Resolve width and signedness differences and find the type of the result.
    auto firstIntSpec  = clang::ento::APSIntType(firstValue);
    auto secondIntSpec = clang::ento::APSIntType(secondValue);
    if (firstIntSpec == std::max(firstIntSpec, secondIntSpec)) {
      firstIntSpec.apply(secondValue);
      resultSwiftType = firstSwiftType;
    } else {
      secondIntSpec.apply(firstValue);
      resultSwiftType = secondSwiftType;
    }

    // Addition.
    if (tokenI[1].is(clang::tok::plus)) {
      resultValue = firstValue + secondValue;

    // Subtraction.
    } else if (tokenI[1].is(clang::tok::minus)) {
      resultValue = firstValue - secondValue;

    // Multiplication.
    } else if (tokenI[1].is(clang::tok::star)) {
      resultValue = firstValue * secondValue;

    // Division.
    } else if (tokenI[1].is(clang::tok::slash)) {
      if (secondValue == 0) { return nullptr; }
      resultValue = firstValue / secondValue;

    // Left-shift.
    } else if (tokenI[1].is(clang::tok::lessless)) {
      // Shift by a negative number is UB in C. Don't import.
      if (secondValue.isNegative()) { return nullptr; }
      resultValue = llvm::APSInt { firstValue.shl(secondValue),
                                   firstValue.isUnsigned() };

    // Right-shift.
    } else if (tokenI[1].is(clang::tok::greatergreater)) {
      // Shift by a negative number is UB in C. Don't import.
      if (secondValue.isNegative()) { return nullptr; }
      if (firstValue.isUnsigned()) {
        resultValue = llvm::APSInt { firstValue.lshr(secondValue),
                                     /*isUnsigned*/ true };
      } else {
        resultValue = llvm::APSInt { firstValue.ashr(secondValue),
                                     /*isUnsigned*/ false };
      }

    // Bitwise OR.
    } else if (tokenI[1].is(clang::tok::pipe)) {
      firstValue.setIsUnsigned(true);
      secondValue.setIsUnsigned(true);
      resultValue = llvm::APSInt { firstValue | secondValue,
                                   /*isUnsigned*/ true };

    // Bitwise AND.
    } else if (tokenI[1].is(clang::tok::amp)) {
      firstValue.setIsUnsigned(true);
      secondValue.setIsUnsigned(true);
      resultValue = llvm::APSInt { firstValue & secondValue,
                                   /*isUnsigned*/ true };

    // XOR.
    } else if (tokenI[1].is(clang::tok::caret)) {
      firstValue.setIsUnsigned(true);
      secondValue.setIsUnsigned(true);
      resultValue = llvm::APSInt { firstValue ^ secondValue,
                                   /*isUnsigned*/ true };

    // Logical OR.
    } else if (tokenI[1].is(clang::tok::pipepipe)) {
      bool result  = firstValue.getBoolValue() || secondValue.getBoolValue();
      resultValue  = llvm::APSInt::get(result);
      resultSwiftType = impl.SwiftContext.getBoolDecl()->getDeclaredType();

    // Logical AND.
    } else if (tokenI[1].is(clang::tok::ampamp)) {
      bool result  = firstValue.getBoolValue() && secondValue.getBoolValue();
      resultValue  = llvm::APSInt::get(result);
      resultSwiftType = impl.SwiftContext.getBoolDecl()->getDeclaredType();

    // Equality.
    } else if (tokenI[1].is(clang::tok::equalequal)) {
      resultValue     = llvm::APSInt::get(firstValue == secondValue);
      resultSwiftType = impl.SwiftContext.getBoolDecl()->getDeclaredType();

    // Less than.
    } else if (tokenI[1].is(clang::tok::less)) {
      resultValue     = llvm::APSInt::get(firstValue < secondValue);
      resultSwiftType = impl.SwiftContext.getBoolDecl()->getDeclaredType();

    // Less than or equal.
    } else if (tokenI[1].is(clang::tok::lessequal)) {
      resultValue     = llvm::APSInt::get(firstValue <= secondValue);
      resultSwiftType = impl.SwiftContext.getBoolDecl()->getDeclaredType();

    // Greater than.
    } else if (tokenI[1].is(clang::tok::greater)) {
      resultValue     = llvm::APSInt::get(firstValue > secondValue);
      resultSwiftType = impl.SwiftContext.getBoolDecl()->getDeclaredType();

    // Greater than or equal.
    } else if (tokenI[1].is(clang::tok::greaterequal)) {
      resultValue     = llvm::APSInt::get(firstValue >= secondValue);
      resultSwiftType = impl.SwiftContext.getBoolDecl()->getDeclaredType();

    // Unhandled operators.
    } else {
      return nullptr;
    }

    return createMacroConstant(impl, macro, name, DC, resultSwiftType,
                               clang::APValue(resultValue),
                               ConstantConvertKind::Coerce,
                               /*isStatic=*/false, ClangN);
  }
  case 4: {
    // Check for a CFString literal of the form CFSTR("string").
    if (tokenI[0].is(clang::tok::identifier) &&
        tokenI[0].getIdentifierInfo()->isStr("CFSTR") &&
        tokenI[1].is(clang::tok::l_paren) &&
        isStringToken(tokenI[2]) &&
        tokenI[3].is(clang::tok::r_paren)) {
      return importStringLiteral(impl, DC, macro, name, tokenI[2],
                                 MappedStringLiteralKind::CFString, ClangN);
    }
    // FIXME: Handle BIT_MASK(pos) helper macros which expand to a constant?
    break;
  }
  case 5:
    // Check for the literal series of tokens (void*)0. (We've already stripped
    // one layer of parentheses.)
    if (tokenI[0].is(clang::tok::l_paren) &&
        tokenI[1].is(clang::tok::kw_void) &&
        tokenI[2].is(clang::tok::star) &&
        tokenI[3].is(clang::tok::r_paren) &&
        tokenI[4].is(clang::tok::numeric_constant)) {
      auto *integerLiteral =
        parseNumericLiteral<clang::IntegerLiteral>(impl, tokenI[4]);
      if (!integerLiteral || integerLiteral->getValue() != 0)
        break;
      return importNil(impl, DC, name, ClangN);
    }
    break;
  default:
    break;
  }

  return nullptr;
}

ValueDecl *ClangImporter::Implementation::importMacro(Identifier name,
                                                      ClangNode macroNode) {
  const clang::MacroInfo *macro = macroNode.getAsMacro();
  if (!macro)
    return nullptr;

  PrettyStackTraceStringAction stackRAII{"importing macro", name.str()};

  // Look for macros imported with the same name.
  auto known = ImportedMacros.find(name);
  if (known == ImportedMacros.end()) {
    // Push in a placeholder to break circularity.
    ImportedMacros[name].push_back({macro, nullptr});
  } else {
    // Check whether this macro has already been imported.
    for (const auto &entry : known->second) {
      if (entry.first == macro) return entry.second;
    }

    // Otherwise, check whether this macro is identical to a macro that has
    // already been imported.
    auto &clangPP = getClangPreprocessor();
    for (const auto &entry : known->second) {
      // If the macro is equal to an existing macro, map down to the same
      // declaration.
      if (macro->isIdenticalTo(*entry.first, clangPP, true)) {
        ValueDecl *result = entry.second;
        known->second.push_back({macro, result});
        return result;
      }
    }

    // If not, push in a placeholder to break circularity.
    known->second.push_back({macro, nullptr});
  }

  ImportingEntityRAII ImportingEntity(*this);
  // We haven't tried to import this macro yet. Do so now, and cache the
  // result.

  DeclContext *DC;
  if (const clang::Module *module = getClangOwningModule(macroNode)) {
    // Get the parent module because currently we don't model Clang submodules
    // in Swift.
    DC = getWrapperForModule(module->getTopLevelModule());
  } else {
    DC = ImportedHeaderUnit;
  }

  auto valueDecl = ::importMacro(*this, DC, name, macro, macroNode,
                                 /*castType*/{});

  // Update the entry for the value we just imported.
  // It's /probably/ the last entry in ImportedMacros[name], but there's an
  // outside chance more macros with the same name have been imported
  // re-entrantly since this method started.
  if (valueDecl) {
    auto entryIter = llvm::find_if(llvm::reverse(ImportedMacros[name]),
        [macro](std::pair<const clang::MacroInfo *, ValueDecl *> entry) {
      return entry.first == macro;
    });
    assert(entryIter != llvm::reverse(ImportedMacros[name]).end() &&
           "placeholder not found");
    entryIter->second = valueDecl;
  }

  return valueDecl;
}
