summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-12-14 05:00:18 +0000
committerChris Lattner <sabre@nondot.org>2009-12-14 05:00:18 +0000
commit4c53c40a4cbd893d43ec823c95b6da25245dfc2f (patch)
tree3ef01b0925a41a401afa269d5df7d9787a65d43d /clang
parentb8132253c8e3b8930e28b63227deb31d20809072 (diff)
downloadbcm5719-llvm-4c53c40a4cbd893d43ec823c95b6da25245dfc2f.tar.gz
bcm5719-llvm-4c53c40a4cbd893d43ec823c95b6da25245dfc2f.zip
fix rdar://7466570 - Be more bug compatible with GCC when it comes to
expanding directives withing macro expansions. This is undefined behavior according to 6.10.3p11, so we might as well be undefined in ways similar to GCC. llvm-svn: 91266
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Lex/PPExpressions.cpp23
-rw-r--r--clang/test/Preprocessor/macro_fn_disable_expand.c20
2 files changed, 41 insertions, 2 deletions
diff --git a/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp
index 6422752ae92..2a6b2a72941 100644
--- a/clang/lib/Lex/PPExpressions.cpp
+++ b/clang/lib/Lex/PPExpressions.cpp
@@ -72,8 +72,8 @@ struct DefinedTracker {
};
/// EvaluateDefined - Process a 'defined(sym)' expression.
-static bool EvaluateDefined(PPValue &Result, Token &PeekTok,
- DefinedTracker &DT, bool ValueLive, Preprocessor &PP) {
+static bool EvaluateDefined(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
+ bool ValueLive, Preprocessor &PP) {
IdentifierInfo *II;
Result.setBegin(PeekTok.getLocation());
@@ -676,6 +676,15 @@ static bool EvaluateDirectiveSubExpr(PPValue &LHS, unsigned MinPrec,
/// to "!defined(X)" return X in IfNDefMacro.
bool Preprocessor::
EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) {
+ // Save the current state of 'DisableMacroExpansion' and reset it to false. If
+ // 'DisableMacroExpansion' is true, then we must be in a macro argument list
+ // in which case a directive is undefined behavior. We want macros to be able
+ // to recursively expand in order to get more gcc-list behavior, so we force
+ // DisableMacroExpansion to false and restore it when we're done parsing the
+ // expression.
+ bool DisableMacroExpansionAtStartOfDirective = DisableMacroExpansion;
+ DisableMacroExpansion = false;
+
// Peek ahead one token.
Token Tok;
Lex(Tok);
@@ -689,6 +698,9 @@ EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) {
// Parse error, skip the rest of the macro line.
if (Tok.isNot(tok::eom))
DiscardUntilEndOfDirective();
+
+ // Restore 'DisableMacroExpansion'.
+ DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
return false;
}
@@ -701,6 +713,8 @@ EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) {
if (DT.State == DefinedTracker::NotDefinedMacro)
IfNDefMacro = DT.TheMacro;
+ // Restore 'DisableMacroExpansion'.
+ DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
return ResVal.Val != 0;
}
@@ -711,6 +725,9 @@ EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) {
// Parse error, skip the rest of the macro line.
if (Tok.isNot(tok::eom))
DiscardUntilEndOfDirective();
+
+ // Restore 'DisableMacroExpansion'.
+ DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
return false;
}
@@ -721,6 +738,8 @@ EvaluateDirectiveExpression(IdentifierInfo *&IfNDefMacro) {
DiscardUntilEndOfDirective();
}
+ // Restore 'DisableMacroExpansion'.
+ DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
return ResVal.Val != 0;
}
diff --git a/clang/test/Preprocessor/macro_fn_disable_expand.c b/clang/test/Preprocessor/macro_fn_disable_expand.c
index 2c24d696d52..e2c666e6a28 100644
--- a/clang/test/Preprocessor/macro_fn_disable_expand.c
+++ b/clang/test/Preprocessor/macro_fn_disable_expand.c
@@ -8,3 +8,23 @@ foo(foo) (2)
#define w ABCD
m(m)
// CHECK: m(ABCD)
+
+
+
+// rdar://7466570
+
+// We should get '42' in the argument list for gcc compatibility.
+#define A 1
+#define B 2
+#define C(x) (x + 1)
+
+X: C(
+#ifdef A
+#if A == 1
+#if B
+ 42
+#endif
+#endif
+#endif
+ )
+// CHECK: X: (42 + 1)
OpenPOWER on IntegriCloud