示例#1
0
CXCompletionString clang_getCursorCompletionString(CXCursor cursor) {
  enum CXCursorKind kind = clang_getCursorKind(cursor);
  if (clang_isDeclaration(kind)) {
    Decl *decl = getCursorDecl(cursor);
    if (isa<NamedDecl>(decl)) {
      NamedDecl *namedDecl = (NamedDecl *)decl;
      ASTUnit *unit = getCursorASTUnit(cursor);
      if (unit->hasSema()) {
        Sema &S = unit->getSema();
        CodeCompletionAllocator *Allocator 
          = unit->getCursorCompletionAllocator().getPtr();
        CodeCompletionResult Result(namedDecl);
        CodeCompletionString *String 
          = Result.CreateCodeCompletionString(S, *Allocator);
        return String;
      }
    }
  }
  else if (kind == CXCursor_MacroDefinition) {
    MacroDefinition *definition = getCursorMacroDefinition(cursor);
    const IdentifierInfo *MacroInfo = definition->getName();
    ASTUnit *unit = getCursorASTUnit(cursor);
    if (unit->hasSema()) {
      Sema &S = unit->getSema();
      CodeCompletionAllocator *Allocator
        = unit->getCursorCompletionAllocator().getPtr();
      CodeCompletionResult Result(const_cast<IdentifierInfo *>(MacroInfo));
      CodeCompletionString *String 
        = Result.CreateCodeCompletionString(S, *Allocator);
      return String;
    }
  }
  return NULL;
}
void PreprocessingRecord::Ifndef(SourceLocation Loc, const Token &MacroNameTok,
                                 const MacroDefinition &MD) {
  // This is not actually a macro expansion but record it as a macro reference.
  if (MD)
    addMacroExpansion(MacroNameTok, MD.getMacroInfo(),
                      MacroNameTok.getLocation());
}
ParameterDefinition *MacroParameterNode::getParameterDefinition(
				boolean includeDummies)
{
    MacroDefinition *md = this->getNetwork()->getDefinition();

    //
    // During deletion of a MacroDefinition, there is no MacroDefinition
    // for this node and therefore no ParameterDefinition.  So return NULL.
    //
    if (!md)
	return NULL;

    int idx = this->getIndex();
    if (idx <= 0)
	return NULL;

    if (this->isInput()) {
	ASSERT(this->isInputRepeatable() == FALSE);
 	if (idx > md->getInputCount())
	    return NULL;
    } else {
	ASSERT(this->isOutputRepeatable() == FALSE);
	if (idx > md->getOutputCount())
	    return NULL;
    }

    ParameterDefinition *pd;
    if (this->isInput()) {
	if (includeDummies)
	    pd = md->getInputDefinition(idx);
	else  
	    pd = md->getNonDummyInputDefinition(idx);
    } else {
	if (includeDummies)
	    pd = md->getOutputDefinition(idx);
	else  
	    pd = md->getNonDummyOutputDefinition(idx);
    }

    return pd;
}
void MacroRepeatedPPCallbacks::MacroExpands(const Token &MacroNameTok,
                                            const MacroDefinition &MD,
                                            SourceRange Range,
                                            const MacroArgs *Args) {
  // Ignore macro argument expansions.
  if (!Range.getBegin().isFileID())
    return;

  const MacroInfo *MI = MD.getMacroInfo();

  // Bail out if the contents of the macro are containing keywords that are
  // making the macro too complex.
  if (std::find_if(
          MI->tokens().begin(), MI->tokens().end(), [](const Token &T) {
            return T.isOneOf(tok::kw_if, tok::kw_else, tok::kw_switch,
                             tok::kw_case, tok::kw_break, tok::kw_while,
                             tok::kw_do, tok::kw_for, tok::kw_continue,
                             tok::kw_goto, tok::kw_return);
          }) != MI->tokens().end())
    return;

  for (unsigned ArgNo = 0U; ArgNo < MI->getNumArgs(); ++ArgNo) {
    const IdentifierInfo *Arg = *(MI->arg_begin() + ArgNo);
    const Token *ResultArgToks = Args->getUnexpArgument(ArgNo);

    if (hasSideEffects(ResultArgToks) &&
        countArgumentExpansions(MI, Arg) >= 2) {
      Check.diag(ResultArgToks->getLocation(),
                 "side effects in the %ordinal0 macro argument '%1' are "
                 "repeated in macro expansion")
          << (ArgNo + 1) << Arg->getName();
      Check.diag(MI->getDefinitionLoc(), "macro %0 defined here",
                 DiagnosticIDs::Note)
          << MacroNameTok.getIdentifierInfo();
    }
  }
}
void MacroParameterNode::switchNetwork(Network *from, Network *to, boolean silently)
{
    MacroDefinition *md = from->getDefinition();
    ParameterDefinition *pd = this->getParameterDefinition();
    ParameterDefinition *dummyPd;
    int n;

    dummyPd = new ParameterDefinition(-1);
    dummyPd->setDummy(TRUE);
    dummyPd->addType(new DXType(DXType::ObjectType));

    if(this->isInput())
	md->replaceInput(dummyPd, pd);
    else
	md->replaceOutput(dummyPd, pd);

    //
    // Switch the Network pointers
    //
    this->UniqueNameNode::switchNetwork(from, to, silently);

    //
    // Make sure we are a macro
    //
    to->makeMacro(TRUE);

    md = to->getDefinition();

    if(this->isInput())
    {
	n = md->getFirstAvailableInputPosition();

	if (n <= md->getInputCount()) {
	    dummyPd = md->getInputDefinition(n);
	    ASSERT(dummyPd->isDummy());
	    md->replaceInput(pd,dummyPd);
	} else {
	    md->addInput(pd);
	}
	this->setIndex(n);
    }
    else
    {
	n = md->getFirstAvailableOutputPosition();

	if (n <= md->getOutputCount()) {
	    ParameterDefinition *dummyPd = md->getOutputDefinition(n);
	    ASSERT(dummyPd->isDummy());
	    md->replaceOutput(pd,dummyPd);
	} else {
	    md->addOutput(pd);
	}
	this->setIndex(n);
    }

    //
    // See if the input is named input_%d or output_%d
    // and if so, change it to match the possibly new index.
    //
    pd = this->getParameterDefinition();
    char buf[64];
    if (this->isInput()) {
	strcpy(buf,"input_");
    } else {
	strcpy(buf,"output_");
    }
    int buflen = strlen(buf);
    const char* current_name = pd->getNameString();
    const char* new_name = NUL(char*);
    boolean name_reset = FALSE;
    if (EqualSubstring(current_name, buf, buflen)) {
	int endint = 0;
	const char *end = &current_name[strlen(current_name)];
	if (IsInteger(current_name+buflen,endint) &&
	    ((current_name+buflen+endint) == end)) {
		sprintf(buf+buflen,"%d",this->getIndex());
		pd->setName(buf);
		name_reset = TRUE;
	}
    }

    //
    // Resolve name conflicts with other nodes using global names.
    //
    if (!name_reset) {
	int name_clash=0, i;
	if (this->isInput()) {
	    int count = to->getInputCount();
	    for (i=1 ; !name_clash && (i <= count) ; i++) {
		ParameterDefinition *opd = to->getInputDefinition(i);
		if ((i != this->getIndex()) &&
		    EqualString(current_name,opd->getNameString()))
		    name_clash = i;
	    }
	} else {
	    int count = to->getOutputCount();
	    for (i=1 ; !name_clash && (i <= count) ; i++) {
		ParameterDefinition *opd = to->getOutputDefinition(i);
		if ((i != this->getIndex()) &&
		    EqualString(current_name,opd->getNameString()))
		    name_clash = i;
	    }
	}

	if (name_clash) {
	    char name_buf[64];
	    if (this->isInput()) {
		sprintf(name_buf,"input_%d", this->getIndex());
	    } else {
		sprintf(name_buf,"output_%d", this->getIndex());
	    }
	    new_name = name_buf;

	    if (!silently) 
		WarningMessage (
		    "Parameter name `%s' is the same name used by parameter #%d.\n"
		    "Your macro %s has been renamed \"%s\".",
		    current_name, name_clash, (this->isInput()? "Input" : "Output"),
		    new_name
		);
	    pd->setName(name_buf);
	    name_reset = TRUE;
	}
    }

    if (!name_reset) {
	const char* conflict = to->nameConflictExists(this, this->getUniqueName());
	if (conflict) {
	    char name_buf[64];
	    if (this->isInput()) {
		sprintf(name_buf,"input_%d", this->getIndex());
	    } else {
		sprintf(name_buf,"output_%d", this->getIndex());
	    }
	    new_name = name_buf;

	    if (!silently)
		WarningMessage (
		    "A %s with name \"%s\" already exists.\n"
		    "Your macro %s has been renamed \"%s\".",
		    conflict, this->getUniqueName(), (this->isInput()? "Input" : "Output"),
		    name_buf
		);
	    pd->setName(name_buf);
	    name_reset = TRUE;
	}
    }
}
	MacroParameterNode::~MacroParameterNode()
	{
		Network *net = this->getNetwork();
		MacroDefinition *md = net->getDefinition();
		Parameter *p;
		ParameterDefinition *pd = this->getParameterDefinition();

		if (this->isInput())
		{

			if (pd && !net->isDeleted() || net == theDXApplication->network)
			{
				if(!net->isDeleted())
				{
					if (this->index != net->getInputCount())
					{
						int newIndex = net->getInputCount()+1;
						this->moveIndex(newIndex, FALSE);
					}
					else
					{
						for (int i = this->index; i > 1; --i)
							if (!this->moveIndex(i - 1, FALSE))
								break;
						// this->index = i;
					}
				}
				if (md) md->removeInput(pd);
				if (pd) delete pd; 
			}
			p = this->getOutputParameter(1);
		}
		else
		{
			if (pd && !net->isDeleted() || net == theDXApplication->network)
			{
				if(!net->isDeleted())
				{
					if (this->index != net->getOutputCount())
					{
						int newIndex = net->getOutputCount()+1;
						this->moveIndex(newIndex, FALSE);
					}
					else
					{
						for (int i = this->index; i > 1; --i)
							if (!this->moveIndex(i - 1, FALSE))
								break;
					}
				}
				if (md) md->removeOutput(pd);
				if (pd) delete pd; 
			}
			p = this->getInputParameter(1);
		}

		if(p) delete p->getDefinition();

		if (net == theDXApplication->network)
		{
			if (md && md->getInputCount() == 0 && md->getOutputCount() == 0)
				net->makeMacro(FALSE);
		}
	}
boolean
MacroParameterNode::initialize()
{
    this->UniqueNameNode::initialize();
    Network *net = this->getNetwork();
    if (!net->isMacro())
	net->makeMacro(TRUE);
    MacroDefinition *md = net->getDefinition();
    ParameterDefinition *param=NULL;

    boolean input = this->isInput();
    if (!md->isReadingNet()) {
	param = new ParameterDefinition(-1);
	param->addType(new DXType(DXType::ObjectType));
    }

    char s[100];
    if (input)
    {
	if (!md->isReadingNet()) {
	    int n = md->getFirstAvailableInputPosition();
	    param->markAsInput();
	    if (n <= md->getInputCount()) {
		ParameterDefinition *dummyPd = md->getInputDefinition(n);
		ASSERT(dummyPd->isDummy());
		md->replaceInput(param,dummyPd);
	    } else {
		md->addInput(param);
	    }
	    this->setIndex(n);
	    sprintf(s, "input_%d", this->index);
	    param->setName(s);
	    param->setDefaultValue("(no default)");
	}

	//
	// The Parameter  must have its own ParameterDefinition since
	// it may change depending upon what we are connected to.
	// FIXME: ParameterDefinition should have a dup() method.
	//
	Parameter *p = this->getOutputParameter(1);
	ParameterDefinition *pd = p->getDefinition();
#if 11
	ParameterDefinition *newpd = pd->duplicate();
#else
	ParameterDefinition *newpd = 
	    new ParameterDefinition(pd->getNameSymbol());
	List *l = pd->getTypes();
	DXType *dxt;
	for (ListIterator li(*l); dxt = (DXType*)li.getNext();)
	    newpd->addType(dxt);
	newpd->markAsOutput();
	newpd->setDefaultVisibility(pd->getDefaultVisibility());
	newpd->setViewability(pd->isViewable());
	newpd->setDescription(pd->getDescription());
	newpd->setWriteableCacheability(pd->hasWriteableCacheability());
	newpd->setDefaultCacheability(pd->getDefaultCacheability());
	if (pd->isRequired())
	    newpd->setRequired();
	else
	    newpd->setNotRequired();
	if (pd->isDefaultValue())
	    newpd->setDefaultValue(pd->getDefaultValue());
	else
	    newpd->setDescriptiveValue(pd->getDefaultValue());
#endif
	p->setDefinition(newpd);
    }
    else
    {
	if (!md->isReadingNet()) {
	    int n = md->getFirstAvailableOutputPosition();
	    param->markAsOutput();
	    if (n <= md->getOutputCount()) {
		ParameterDefinition *dummyPd = md->getOutputDefinition(n);
		ASSERT(dummyPd->isDummy());
		md->replaceOutput(param,dummyPd);
	    } else {
		md->addOutput(param);
	    }
	    this->setIndex(n);
	    sprintf(s, "output_%d", this->index);
	    param->setName(s);
	    param->setDefaultValue("(no default)");
	}

	//
	// The Parameter  must have its own ParameterDefinition since
	// it may change depending upon what we are connected to.
	// FIXME: ParameterDefinition should have a dup() method.
	//
	Parameter *p = this->getInputParameter(1);
	ParameterDefinition *pd = p->getDefinition();
#if 11
	ParameterDefinition *newpd = pd->duplicate();
#else
	ParameterDefinition *newpd =
	    new ParameterDefinition(pd->getNameSymbol());
	List *l = pd->getTypes();
	DXType *dxt;
	for (ListIterator li(*l); dxt = (DXType*)li.getNext();)
	    newpd->addType(dxt);
	newpd->markAsInput();
	newpd->setDefaultVisibility(pd->getDefaultVisibility());
	newpd->setViewability(pd->isViewable());
	newpd->setDescription(pd->getDescription());
	newpd->setWriteableCacheability(pd->hasWriteableCacheability());
	newpd->setDefaultCacheability(pd->getDefaultCacheability());
	if (pd->isRequired())
	    newpd->setRequired();
	else
	    newpd->setNotRequired();
	if (pd->isDefaultValue())
	    newpd->setDefaultValue(pd->getDefaultValue());
	else
	    newpd->setDescriptiveValue(pd->getDefaultValue());
#endif
	p->setDefinition(newpd);
    }
    return TRUE;
}
void PreprocessingRecord::MacroUndefined(const Token &Id,
                                         const MacroDefinition &MD,
                                         const MacroDirective *Undef) {
  MD.forAllDefinitions([&](MacroInfo *MI) { MacroDefinitions.erase(MI); });
}
void PreprocessingRecord::MacroExpands(const Token &Id,
                                       const MacroDefinition &MD,
                                       SourceRange Range,
                                       const MacroArgs *Args) {
  addMacroExpansion(Id, MD.getMacroInfo(), Range);
}
示例#10
0
/// EvaluateDefined - Process a 'defined(sym)' expression.
static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
                            bool ValueLive, Preprocessor &PP) {
  SourceLocation beginLoc(PeekTok.getLocation());
  Result.setBegin(beginLoc);

  // Get the next token, don't expand it.
  PP.LexUnexpandedNonComment(PeekTok);

  // Two options, it can either be a pp-identifier or a (.
  SourceLocation LParenLoc;
  if (PeekTok.is(tok::l_paren)) {
    // Found a paren, remember we saw it and skip it.
    LParenLoc = PeekTok.getLocation();
    PP.LexUnexpandedNonComment(PeekTok);
  }

  if (PeekTok.is(tok::code_completion)) {
    if (PP.getCodeCompletionHandler())
      PP.getCodeCompletionHandler()->CodeCompleteMacroName(false);
    PP.setCodeCompletionReached();
    PP.LexUnexpandedNonComment(PeekTok);
  }

  // If we don't have a pp-identifier now, this is an error.
  if (PP.CheckMacroName(PeekTok, MU_Other))
    return true;

  // Otherwise, we got an identifier, is it defined to something?
  IdentifierInfo *II = PeekTok.getIdentifierInfo();
  MacroDefinition Macro = PP.getMacroDefinition(II);
  Result.Val = !!Macro;
  Result.Val.setIsUnsigned(false); // Result is signed intmax_t.

  // If there is a macro, mark it used.
  if (Result.Val != 0 && ValueLive)
    PP.markMacroAsUsed(Macro.getMacroInfo());

  // Save macro token for callback.
  Token macroToken(PeekTok);

  // If we are in parens, ensure we have a trailing ).
  if (LParenLoc.isValid()) {
    // Consume identifier.
    Result.setEnd(PeekTok.getLocation());
    PP.LexUnexpandedNonComment(PeekTok);

    if (PeekTok.isNot(tok::r_paren)) {
      PP.Diag(PeekTok.getLocation(), diag::err_pp_expected_after)
          << "'defined'" << tok::r_paren;
      PP.Diag(LParenLoc, diag::note_matching) << tok::l_paren;
      return true;
    }
    // Consume the ).
    Result.setEnd(PeekTok.getLocation());
    PP.LexNonComment(PeekTok);
  } else {
    // Consume identifier.
    Result.setEnd(PeekTok.getLocation());
    PP.LexNonComment(PeekTok);
  }

  // Invoke the 'defined' callback.
  if (PPCallbacks *Callbacks = PP.getPPCallbacks()) {
    Callbacks->Defined(macroToken, Macro,
                       SourceRange(beginLoc, PeekTok.getLocation()));
  }

  // Success, remember that we saw defined(X).
  DT.State = DefinedTracker::DefinedMacro;
  DT.TheMacro = II;
  return false;
}
示例#11
0
/// EvaluateDefined - Process a 'defined(sym)' expression.
static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
                            bool ValueLive, Preprocessor &PP) {
  SourceLocation beginLoc(PeekTok.getLocation());
  Result.setBegin(beginLoc);

  // Get the next token, don't expand it.
  PP.LexUnexpandedNonComment(PeekTok);

  // Two options, it can either be a pp-identifier or a (.
  SourceLocation LParenLoc;
  if (PeekTok.is(tok::l_paren)) {
    // Found a paren, remember we saw it and skip it.
    LParenLoc = PeekTok.getLocation();
    PP.LexUnexpandedNonComment(PeekTok);
  }

  if (PeekTok.is(tok::code_completion)) {
    if (PP.getCodeCompletionHandler())
      PP.getCodeCompletionHandler()->CodeCompleteMacroName(false);
    PP.setCodeCompletionReached();
    PP.LexUnexpandedNonComment(PeekTok);
  }

  // If we don't have a pp-identifier now, this is an error.
  if (PP.CheckMacroName(PeekTok, MU_Other))
    return true;

  // Otherwise, we got an identifier, is it defined to something?
  IdentifierInfo *II = PeekTok.getIdentifierInfo();
  MacroDefinition Macro = PP.getMacroDefinition(II);
  Result.Val = !!Macro;
  Result.Val.setIsUnsigned(false); // Result is signed intmax_t.

  // If there is a macro, mark it used.
  if (Result.Val != 0 && ValueLive)
    PP.markMacroAsUsed(Macro.getMacroInfo());

  // Save macro token for callback.
  Token macroToken(PeekTok);

  // If we are in parens, ensure we have a trailing ).
  if (LParenLoc.isValid()) {
    // Consume identifier.
    Result.setEnd(PeekTok.getLocation());
    PP.LexUnexpandedNonComment(PeekTok);

    if (PeekTok.isNot(tok::r_paren)) {
      PP.Diag(PeekTok.getLocation(), diag::err_pp_expected_after)
          << "'defined'" << tok::r_paren;
      PP.Diag(LParenLoc, diag::note_matching) << tok::l_paren;
      return true;
    }
    // Consume the ).
    Result.setEnd(PeekTok.getLocation());
    PP.LexNonComment(PeekTok);
  } else {
    // Consume identifier.
    Result.setEnd(PeekTok.getLocation());
    PP.LexNonComment(PeekTok);
  }

  // [cpp.cond]p4:
  //   Prior to evaluation, macro invocations in the list of preprocessing
  //   tokens that will become the controlling constant expression are replaced
  //   (except for those macro names modified by the 'defined' unary operator),
  //   just as in normal text. If the token 'defined' is generated as a result
  //   of this replacement process or use of the 'defined' unary operator does
  //   not match one of the two specified forms prior to macro replacement, the
  //   behavior is undefined.
  // This isn't an idle threat, consider this program:
  //   #define FOO
  //   #define BAR defined(FOO)
  //   #if BAR
  //   ...
  //   #else
  //   ...
  //   #endif
  // clang and gcc will pick the #if branch while Visual Studio will take the
  // #else branch.  Emit a warning about this undefined behavior.
  if (beginLoc.isMacroID()) {
    bool IsFunctionTypeMacro =
        PP.getSourceManager()
            .getSLocEntry(PP.getSourceManager().getFileID(beginLoc))
            .getExpansion()
            .isFunctionMacroExpansion();
    // For object-type macros, it's easy to replace
    //   #define FOO defined(BAR)
    // with
    //   #if defined(BAR)
    //   #define FOO 1
    //   #else
    //   #define FOO 0
    //   #endif
    // and doing so makes sense since compilers handle this differently in
    // practice (see example further up).  But for function-type macros,
    // there is no good way to write
    //   # define FOO(x) (defined(M_ ## x) && M_ ## x)
    // in a different way, and compilers seem to agree on how to behave here.
    // So warn by default on object-type macros, but only warn in -pedantic
    // mode on function-type macros.
    if (IsFunctionTypeMacro)
      PP.Diag(beginLoc, diag::warn_defined_in_function_type_macro);
    else
      PP.Diag(beginLoc, diag::warn_defined_in_object_type_macro);
  }

  // Invoke the 'defined' callback.
  if (PPCallbacks *Callbacks = PP.getPPCallbacks()) {
    Callbacks->Defined(macroToken, Macro,
                       SourceRange(beginLoc, PeekTok.getLocation()));
  }

  // Success, remember that we saw defined(X).
  DT.State = DefinedTracker::DefinedMacro;
  DT.TheMacro = II;
  return false;
}
示例#12
0
/// HandleMacroExpandedIdentifier - If an identifier token is read that is to be
/// expanded as a macro, handle it and return the next token as 'Identifier'.
bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
                                                 const MacroDefinition &M) {
  MacroInfo *MI = M.getMacroInfo();

  // If this is a macro expansion in the "#if !defined(x)" line for the file,
  // then the macro could expand to different things in other contexts, we need
  // to disable the optimization in this case.
  if (CurPPLexer) CurPPLexer->MIOpt.ExpandedMacro();

  // If this is a builtin macro, like __LINE__ or _Pragma, handle it specially.
  if (MI->isBuiltinMacro()) {
    ExpandBuiltinMacro(Identifier);
    return true;
  }

  /// Args - If this is a function-like macro expansion, this contains,
  /// for each macro argument, the list of tokens that were provided to the
  /// invocation.
  MacroArgs *Args = nullptr;

  // Remember where the end of the expansion occurred.  For an object-like
  // macro, this is the identifier.  For a function-like macro, this is the ')'.
  SourceLocation ExpansionEnd = Identifier.getLocation();

  // If this is a function-like macro, read the arguments.
  if (MI->isFunctionLike()) {
    // Remember that we are now parsing the arguments to a macro invocation.
    // Preprocessor directives used inside macro arguments are not portable, and
    // this enables the warning.
    InMacroArgs = true;
    Args = ReadMacroCallArgumentList(Identifier, MI, ExpansionEnd);

    // Finished parsing args.
    InMacroArgs = false;

    // If there was an error parsing the arguments, bail out.
    if (!Args) return true;

    ++NumFnMacroExpanded;
  } else {
    ++NumMacroExpanded;
  }

  // Notice that this macro has been used.
  markMacroAsUsed(MI);

  // Remember where the token is expanded.
  SourceLocation ExpandLoc = Identifier.getLocation();
  SourceRange ExpansionRange(ExpandLoc, ExpansionEnd);


  // If the macro definition is ambiguous, complain.
  if (M.isAmbiguous()) {
    Diag(Identifier, diag::warn_pp_ambiguous_macro)
      << Identifier.getIdentifierInfo();
    Diag(MI->getDefinitionLoc(), diag::note_pp_ambiguous_macro_chosen)
      << Identifier.getIdentifierInfo();
    M.forAllDefinitions([&](const MacroInfo *OtherMI) {
      if (OtherMI != MI)
        Diag(OtherMI->getDefinitionLoc(), diag::note_pp_ambiguous_macro_other)
          << Identifier.getIdentifierInfo();
    });
  }

  // If we started lexing a macro, enter the macro expansion body.

  // If this macro expands to no tokens, don't bother to push it onto the
  // expansion stack, only to take it right back off.
  if (MI->getNumTokens() == 0) {
    // No need for arg info.
    if (Args) Args->destroy(*this);

    // Propagate whitespace info as if we had pushed, then popped,
    // a macro context.
    Identifier.setFlag(Token::LeadingEmptyMacro);
    PropagateLineStartLeadingSpaceInfo(Identifier);
    ++NumFastMacroExpanded;
    return false;
  } else if (MI->getNumTokens() == 1 &&
             isTrivialSingleTokenExpansion(MI, Identifier.getIdentifierInfo(),
                                           *this)) {
    // Otherwise, if this macro expands into a single trivially-expanded
    // token: expand it now.  This handles common cases like
    // "#define VAL 42".

    // No need for arg info.
    if (Args) Args->destroy(*this);

    // Propagate the isAtStartOfLine/hasLeadingSpace markers of the macro
    // identifier to the expanded token.
    bool isAtStartOfLine = Identifier.isAtStartOfLine();
    bool hasLeadingSpace = Identifier.hasLeadingSpace();

    // Replace the result token.
    Identifier = MI->getReplacementToken(0);

    // Restore the StartOfLine/LeadingSpace markers.
    Identifier.setFlagValue(Token::StartOfLine , isAtStartOfLine);
    Identifier.setFlagValue(Token::LeadingSpace, hasLeadingSpace);

    // Update the tokens location to include both its expansion and physical
    // locations.
    SourceLocation Loc =
      SourceMgr.createExpansionLoc(Identifier.getLocation(), ExpandLoc,
                                   ExpansionEnd,Identifier.getLength());
    Identifier.setLocation(Loc);

    // If this is a disabled macro or #define X X, we must mark the result as
    // unexpandable.
    if (IdentifierInfo *NewII = Identifier.getIdentifierInfo()) {
      if (MacroInfo *NewMI = getMacroInfo(NewII))
        if (!NewMI->isEnabled() || NewMI == MI) {
          Identifier.setFlag(Token::DisableExpand);
          // Don't warn for "#define X X" like "#define bool bool" from
          // stdbool.h.
          if (NewMI != MI || MI->isFunctionLike())
            Diag(Identifier, diag::pp_disabled_macro_expansion);
        }
    }

    // Since this is not an identifier token, it can't be macro expanded, so
    // we're done.
    ++NumFastMacroExpanded;
    return true;
  }

  // Start expanding the macro.
  EnterMacro(Identifier, ExpansionEnd, MI, Args);
  return false;
}