forked from OSchip/llvm-project
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:
parent
771f160758
commit
c0b4928df8
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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){
|
||||
|
|
|
@ -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();
|
||||
|
||||
// Reinstall the previously pushed macro.
|
||||
setMacroInfo(IdentInfo, MacroToReInstall);
|
||||
if (MacroToReInstall) {
|
||||
// Reinstall the previously pushed macro.
|
||||
setMacroInfo(IdentInfo, MacroToReInstall);
|
||||
} else if (IdentInfo->hasMacroDefinition()) {
|
||||
clearMacroInfo(IdentInfo);
|
||||
}
|
||||
|
||||
// Pop PragmaPushMacroInfo stack.
|
||||
iter->second.pop_back();
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue