Fixed a problem with #pragma push_macro/pop_macro implementation.

Summary:
The problem was with the following sequence:
  #pragma push_macro("long")
  #undef long
  #pragma pop_macro("long")
in case when "long" didn't represent a macro.
Fixed crash and removed code duplication for #undef/pop_macro case. Added regression tests.

Reviewers: doug.gregor, klimek

Reviewed By: doug.gregor

CC: cfe-commits, chapuni

Differential Revision: http://llvm-reviews.chandlerc.com/D31

llvm-svn: 162845
This commit is contained in:
Alexander Kornienko 2012-08-29 16:56:24 +00:00
parent 771f160758
commit c0b4928df8
5 changed files with 37 additions and 7 deletions

View File

@ -470,6 +470,8 @@ public:
/// \brief Specify a macro for this identifier.
void setMacroInfo(IdentifierInfo *II, MacroInfo *MI,
bool LoadedFromAST = false);
/// \brief Undefine a macro for this identifier.
void clearMacroInfo(IdentifierInfo *II);
/// macro_iterator/macro_begin/macro_end - This allows you to walk the macro
/// history table. Currently defined macros have

View File

@ -1921,10 +1921,7 @@ void Preprocessor::HandleUndefDirective(Token &UndefTok) {
WarnUnusedMacroLocs.erase(MI->getDefinitionLoc());
MI->setUndefLoc(MacroNameTok.getLocation());
IdentifierInfo *II = MacroNameTok.getIdentifierInfo();
II->setHasMacroDefinition(false);
if (II->isFromAST())
II->setChangedSinceDeserialization();
clearMacroInfo(MacroNameTok.getIdentifierInfo());
}

View File

@ -57,6 +57,15 @@ void Preprocessor::setMacroInfo(IdentifierInfo *II, MacroInfo *MI,
II->setChangedSinceDeserialization();
}
/// \brief Undefine a macro for this identifier.
void Preprocessor::clearMacroInfo(IdentifierInfo *II) {
assert(II->hasMacroDefinition() && "Macro is not defined!");
assert(Macros[II]->getUndefLoc().isValid() && "Macro is still defined!");
II->setHasMacroDefinition(false);
if (II->isFromAST())
II->setChangedSinceDeserialization();
}
/// RegisterBuiltinMacro - Register the specified identifier in the identifier
/// table and mark it as a builtin macro to be expanded.
static IdentifierInfo *RegisterBuiltinMacro(Preprocessor &PP, const char *Name){

View File

@ -737,13 +737,18 @@ void Preprocessor::HandlePragmaPopMacro(Token &PopMacroTok) {
if (MacroInfo *CurrentMI = getMacroInfo(IdentInfo)) {
if (CurrentMI->isWarnIfUnused())
WarnUnusedMacroLocs.erase(CurrentMI->getDefinitionLoc());
CurrentMI->setUndefLoc(MessageLoc);
}
// Get the MacroInfo we want to reinstall.
MacroInfo *MacroToReInstall = iter->second.back();
if (MacroToReInstall) {
// Reinstall the previously pushed macro.
setMacroInfo(IdentInfo, MacroToReInstall);
} else if (IdentInfo->hasMacroDefinition()) {
clearMacroInfo(IdentInfo);
}
// Pop PragmaPushMacroInfo stack.
iter->second.pop_back();

View File

@ -31,6 +31,22 @@ int pmy1 = Y;
#define Y 4
int pmy2 = Y;
// The sequence push, define/undef, pop caused problems if macro was not
// previously defined.
#pragma push_macro("PREVIOUSLY_UNDEFINED1")
#undef PREVIOUSLY_UNDEFINED1
#pragma pop_macro("PREVIOUSLY_UNDEFINED1")
#ifndef PREVIOUSLY_UNDEFINED1
int Q;
#endif
#pragma push_macro("PREVIOUSLY_UNDEFINED2")
#define PREVIOUSLY_UNDEFINED2
#pragma pop_macro("PREVIOUSLY_UNDEFINED2")
#ifndef PREVIOUSLY_UNDEFINED2
int P;
#endif
// CHECK: int pmx0 = 1
// CHECK: int pmy0 = 2
// CHECK: int pmx1 = 1
@ -38,4 +54,5 @@ int pmy2 = Y;
// CHECK: int pmx3 = 1
// CHECK: int pmy1 = 3
// CHECK: int pmy2 = 4
// CHECK: int Q;
// CHECK: int P;