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.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91266 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Lex/PPExpressions.cpp b/lib/Lex/PPExpressions.cpp
index 6422752..2a6b2a7 100644
--- a/lib/Lex/PPExpressions.cpp
+++ b/lib/Lex/PPExpressions.cpp
@@ -72,8 +72,8 @@
 };
 
 /// 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 @@
 /// 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 @@
     // 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 @@
     if (DT.State == DefinedTracker::NotDefinedMacro)
       IfNDefMacro = DT.TheMacro;
 
+    // Restore 'DisableMacroExpansion'.
+    DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
     return ResVal.Val != 0;
   }
 
@@ -711,6 +725,9 @@
     // 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 @@
     DiscardUntilEndOfDirective();
   }
 
+  // Restore 'DisableMacroExpansion'.
+  DisableMacroExpansion = DisableMacroExpansionAtStartOfDirective;
   return ResVal.Val != 0;
 }
 
diff --git a/test/Preprocessor/macro_fn_disable_expand.c b/test/Preprocessor/macro_fn_disable_expand.c
index 2c24d69..e2c666e 100644
--- a/test/Preprocessor/macro_fn_disable_expand.c
+++ b/test/Preprocessor/macro_fn_disable_expand.c
@@ -8,3 +8,23 @@
 #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)