[cfe-commits] r164610 - in /cfe/trunk: include/clang/Basic/IdentifierTable.h include/clang/Lex/Preprocessor.h lib/Basic/IdentifierTable.cpp lib/Lex/PPMacroExpansion.cpp lib/Serialization/ASTReader.cpp lib/Serialization/ASTWriter.cpp test/CodeCompletion/Inputs/macros.h test/CodeCompletion/macros.c

Alexander Kornienko alexfh at google.com
Tue Sep 25 10:18:14 PDT 2012


Author: alexfh
Date: Tue Sep 25 12:18:14 2012
New Revision: 164610

URL: http://llvm.org/viewvc/llvm-project?rev=164610&view=rev
Log:
Macro history (de-)serialization. Deserialization currently reads only the latest macro definition. Needs more work.

Summary: Passes all tests (+ the new one with code completion), but needs a thorough review in part related to modules.

Reviewers: doug.gregor

Reviewed By: alexfh

CC: cfe-commits, rsmith

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

Modified:
    cfe/trunk/include/clang/Basic/IdentifierTable.h
    cfe/trunk/include/clang/Lex/Preprocessor.h
    cfe/trunk/lib/Basic/IdentifierTable.cpp
    cfe/trunk/lib/Lex/PPMacroExpansion.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp
    cfe/trunk/test/CodeCompletion/Inputs/macros.h
    cfe/trunk/test/CodeCompletion/macros.c

Modified: cfe/trunk/include/clang/Basic/IdentifierTable.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/IdentifierTable.h?rev=164610&r1=164609&r2=164610&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/IdentifierTable.h (original)
+++ cfe/trunk/include/clang/Basic/IdentifierTable.h Tue Sep 25 12:18:14 2012
@@ -54,6 +54,7 @@
   // are for builtins.
   unsigned ObjCOrBuiltinID    :11;
   bool HasMacro               : 1; // True if there is a #define for this.
+  bool HadMacro               : 1; // True if there was a #define for this.
   bool IsExtension            : 1; // True if identifier is a lang extension.
   bool IsCXX11CompatKeyword   : 1; // True if identifier is a keyword in C++11.
   bool IsPoisoned             : 1; // True if identifier is poisoned.
@@ -70,8 +71,8 @@
                                    // stored externally.
   bool IsModulesImport        : 1; // True if this is the 'import' contextual
                                    // keyword.
-  // 1 bit left in 32-bit word.
-  
+  // 32-bit word is filled.
+
   void *FETokenInfo;               // Managed by the language front-end.
   llvm::StringMapEntry<IdentifierInfo*> *Entry;
 
@@ -133,10 +134,18 @@
     if (HasMacro == Val) return;
 
     HasMacro = Val;
-    if (Val)
+    if (Val) {
       NeedsHandleIdentifier = 1;
-    else
+      HadMacro = true;
+    } else {
       RecomputeNeedsHandleIdentifier();
+    }
+  }
+  /// \brief Returns true if this identifier was \#defined to some value at any
+  /// moment. In this case there should be an entry for the identifier in the
+  /// macro history table in Preprocessor.
+  bool hadMacroDefinition() const {
+    return HadMacro;
   }
 
   /// getTokenID - If this is a source-language token (e.g. 'for'), this API

Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=164610&r1=164609&r2=164610&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Tue Sep 25 12:18:14 2012
@@ -366,8 +366,6 @@
   /// allocation.
   MacroInfoChain *MICache;
 
-  MacroInfo *getInfoForMacro(IdentifierInfo *II) const;
-
 public:
   Preprocessor(DiagnosticsEngine &diags, LangOptions &opts,
                const TargetInfo *target,
@@ -467,9 +465,17 @@
     if (!II->hasMacroDefinition())
       return 0;
 
-    return getInfoForMacro(II);
+    MacroInfo *MI = getMacroInfoHistory(II);
+    assert(MI->getUndefLoc().isInvalid() && "Macro is undefined!");
+    return MI;
   }
 
+  /// \brief Given an identifier, return the (probably #undef'd) MacroInfo
+  /// representing the most recent macro definition. One can iterate over all
+  /// previous macro definitions from it. This method should only be called for
+  /// identifiers that hadMacroDefinition().
+  MacroInfo *getMacroInfoHistory(IdentifierInfo *II) const;
+
   /// \brief Specify a macro for this identifier.
   void setMacroInfo(IdentifierInfo *II, MacroInfo *MI,
                     bool LoadedFromAST = false);

Modified: cfe/trunk/lib/Basic/IdentifierTable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/IdentifierTable.cpp?rev=164610&r1=164609&r2=164610&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/IdentifierTable.cpp (original)
+++ cfe/trunk/lib/Basic/IdentifierTable.cpp Tue Sep 25 12:18:14 2012
@@ -33,6 +33,7 @@
   TokenID = tok::identifier;
   ObjCOrBuiltinID = 0;
   HasMacro = false;
+  HadMacro = false;
   IsExtension = false;
   IsCXX11CompatKeyword = false;
   IsPoisoned = false;

Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=164610&r1=164609&r2=164610&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)
+++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Tue Sep 25 12:18:14 2012
@@ -32,8 +32,8 @@
 #include <ctime>
 using namespace clang;
 
-MacroInfo *Preprocessor::getInfoForMacro(IdentifierInfo *II) const {
-  assert(II->hasMacroDefinition() && "Identifier is not a macro!");
+MacroInfo *Preprocessor::getMacroInfoHistory(IdentifierInfo *II) const {
+  assert(II->hadMacroDefinition() && "Identifier has not been not a macro!");
 
   macro_iterator Pos = Macros.find(II);
   if (Pos == Macros.end()) {
@@ -42,7 +42,6 @@
     Pos = Macros.find(II);
   }
   assert(Pos != Macros.end() && "Identifier macro info is missing!");
-  assert(Pos->second->getUndefLoc().isInvalid() && "Macro is undefined!");
   return Pos->second;
 }
 
@@ -51,9 +50,11 @@
 void Preprocessor::setMacroInfo(IdentifierInfo *II, MacroInfo *MI,
                                 bool LoadedFromAST) {
   assert(MI && "MacroInfo should be non-zero!");
+  assert((LoadedFromAST || MI->getUndefLoc().isInvalid()) &&
+         "Undefined macros can only be registered when just LoadedFromAST");
   MI->setPreviousDefinition(Macros[II]);
   Macros[II] = MI;
-  II->setHasMacroDefinition(true);
+  II->setHasMacroDefinition(MI->getUndefLoc().isInvalid());
   if (II->isFromAST() && !LoadedFromAST)
     II->setChangedSinceDeserialization();
 }

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=164610&r1=164609&r2=164610&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Tue Sep 25 12:18:14 2012
@@ -527,6 +527,7 @@
     return II;
   }
 
+  unsigned ObjCOrBuiltinID = ReadUnalignedLE16(d);
   unsigned Bits = ReadUnalignedLE16(d);
   bool CPlusPlusOperatorKeyword = Bits & 0x01;
   Bits >>= 1;
@@ -536,13 +537,13 @@
   Bits >>= 1;
   bool ExtensionToken = Bits & 0x01;
   Bits >>= 1;
+  bool hadMacroDefinition = Bits & 0x01;
+  Bits >>= 1;
   bool hasMacroDefinition = Bits & 0x01;
   Bits >>= 1;
-  unsigned ObjCOrBuiltinID = Bits & 0x7FF;
-  Bits >>= 11;
 
   assert(Bits == 0 && "Extra bits in the identifier?");
-  DataLen -= 6;
+  DataLen -= 8;
 
   // Build the IdentifierInfo itself and link the identifier ID with
   // the new IdentifierInfo.
@@ -570,7 +571,7 @@
 
   // If this identifier is a macro, deserialize the macro
   // definition.
-  if (hasMacroDefinition) {
+  if (hadMacroDefinition) {
     // FIXME: Check for conflicts?
     uint32_t Offset = ReadUnalignedLE32(d);
     unsigned LocalSubmoduleID = ReadUnalignedLE32(d);
@@ -590,10 +591,10 @@
           // module is not yet visible.
           Reader.HiddenNamesMap[Owner].push_back(II);
         }
-      } 
+      }
     }
-    
-    Reader.setIdentifierIsMacro(II, F, Offset, Visible);
+
+    Reader.setIdentifierIsMacro(II, F, Offset, Visible && hasMacroDefinition);
     DataLen -= 8;
   }
 
@@ -1312,18 +1313,21 @@
         Error("macro must have a name in AST file");
         return;
       }
-      
-      SourceLocation Loc = ReadSourceLocation(F, Record[1]);
-      bool isUsed = Record[2];
 
+      unsigned NextIndex = 1;
+      SourceLocation Loc = ReadSourceLocation(F, Record, NextIndex);
       MacroInfo *MI = PP.AllocateMacroInfo(Loc);
-      MI->setIsUsed(isUsed);
+
+      SourceLocation UndefLoc = ReadSourceLocation(F, Record, NextIndex);
+      if (UndefLoc.isValid())
+        MI->setUndefLoc(UndefLoc);
+
+      MI->setIsUsed(Record[NextIndex++]);
       MI->setIsFromAST();
 
-      bool IsPublic = Record[3];
-      unsigned NextIndex = 4;
+      bool IsPublic = Record[NextIndex++];
       MI->setVisibility(IsPublic, ReadSourceLocation(F, Record, NextIndex));
-      
+
       if (RecType == PP_MACRO_FUNCTION_LIKE) {
         // Decode function-like macro info.
         bool isC99VarArgs = Record[NextIndex++];
@@ -2551,6 +2555,7 @@
       D->Hidden = false;
     else {
       IdentifierInfo *II = Names[I].get<IdentifierInfo *>();
+      // FIXME: Check if this works correctly with macro history.
       if (!II->hasMacroDefinition()) {
         // Make sure that this macro hasn't been #undef'd in the mean-time.
         llvm::DenseMap<IdentifierInfo*, MacroInfo*>::iterator Known

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=164610&r1=164609&r2=164610&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Tue Sep 25 12:18:14 2012
@@ -1674,102 +1674,112 @@
   SmallVector<std::pair<const IdentifierInfo *, MacroInfo *>, 2> 
     MacrosToEmit;
   llvm::SmallPtrSet<const IdentifierInfo*, 4> MacroDefinitionsSeen;
-  for (Preprocessor::macro_iterator I = PP.macro_begin(Chain == 0), 
+  for (Preprocessor::macro_iterator I = PP.macro_begin(Chain == 0),
                                     E = PP.macro_end(Chain == 0);
        I != E; ++I) {
-    // FIXME: We'll need to store macro history in PCH.
-    if (I->first->hasMacroDefinition()) {
-      if (!IsModule || I->second->isPublic()) {
-        MacroDefinitionsSeen.insert(I->first);
-        MacrosToEmit.push_back(std::make_pair(I->first, I->second));
-      }
+    if (!IsModule || I->second->isPublic()) {
+      MacroDefinitionsSeen.insert(I->first);
+      MacrosToEmit.push_back(std::make_pair(I->first, I->second));
     }
   }
-  
+
   // Sort the set of macro definitions that need to be serialized by the
   // name of the macro, to provide a stable ordering.
-  llvm::array_pod_sort(MacrosToEmit.begin(), MacrosToEmit.end(), 
+  llvm::array_pod_sort(MacrosToEmit.begin(), MacrosToEmit.end(),
                        &compareMacroDefinitions);
-  
+
   // Resolve any identifiers that defined macros at the time they were
   // deserialized, adding them to the list of macros to emit (if appropriate).
   for (unsigned I = 0, N = DeserializedMacroNames.size(); I != N; ++I) {
     IdentifierInfo *Name
       = const_cast<IdentifierInfo *>(DeserializedMacroNames[I]);
-    if (Name->hasMacroDefinition() && MacroDefinitionsSeen.insert(Name))
+    if (Name->hadMacroDefinition() && MacroDefinitionsSeen.insert(Name))
       MacrosToEmit.push_back(std::make_pair(Name, PP.getMacroInfo(Name)));
   }
-  
+
   for (unsigned I = 0, N = MacrosToEmit.size(); I != N; ++I) {
     const IdentifierInfo *Name = MacrosToEmit[I].first;
     MacroInfo *MI = MacrosToEmit[I].second;
     if (!MI)
       continue;
-    
-    // Don't emit builtin macros like __LINE__ to the AST file unless they have
-    // been redefined by the header (in which case they are not isBuiltinMacro).
-    // Also skip macros from a AST file if we're chaining.
-
-    // FIXME: There is a (probably minor) optimization we could do here, if
-    // the macro comes from the original PCH but the identifier comes from a
-    // chained PCH, by storing the offset into the original PCH rather than
-    // writing the macro definition a second time.
-    if (MI->isBuiltinMacro() ||
-        (Chain && 
-         Name->isFromAST() && !Name->hasChangedSinceDeserialization() && 
-         MI->isFromAST() && !MI->hasChangedAfterLoad()))
-      continue;
 
-    AddIdentifierRef(Name, Record);
-    MacroOffsets[Name] = Stream.GetCurrentBitNo();
-    Record.push_back(MI->getDefinitionLoc().getRawEncoding());
-    Record.push_back(MI->isUsed());
-    Record.push_back(MI->isPublic());
-    AddSourceLocation(MI->getVisibilityLocation(), Record);
-    unsigned Code;
-    if (MI->isObjectLike()) {
-      Code = PP_MACRO_OBJECT_LIKE;
-    } else {
-      Code = PP_MACRO_FUNCTION_LIKE;
+    // History of macro definitions for this identifier in chronological order.
+    SmallVector<MacroInfo*, 8> MacroHistory;
+    while (MI) {
+      MacroHistory.push_back(MI);
+      MI = MI->getPreviousDefinition();
+    }
+
+    while (!MacroHistory.empty()) {
+      MI = MacroHistory.pop_back_val();
+
+      // Don't emit builtin macros like __LINE__ to the AST file unless they
+      // have been redefined by the header (in which case they are not
+      // isBuiltinMacro).
+      // Also skip macros from a AST file if we're chaining.
+
+      // FIXME: There is a (probably minor) optimization we could do here, if
+      // the macro comes from the original PCH but the identifier comes from a
+      // chained PCH, by storing the offset into the original PCH rather than
+      // writing the macro definition a second time.
+      if (MI->isBuiltinMacro() ||
+          (Chain &&
+           Name->isFromAST() && !Name->hasChangedSinceDeserialization() &&
+           MI->isFromAST() && !MI->hasChangedAfterLoad()))
+        continue;
 
-      Record.push_back(MI->isC99Varargs());
-      Record.push_back(MI->isGNUVarargs());
-      Record.push_back(MI->getNumArgs());
-      for (MacroInfo::arg_iterator I = MI->arg_begin(), E = MI->arg_end();
-           I != E; ++I)
-        AddIdentifierRef(*I, Record);
-    }
+      AddIdentifierRef(Name, Record);
+      MacroOffsets[Name] = Stream.GetCurrentBitNo();
+      AddSourceLocation(MI->getDefinitionLoc(), Record);
+      AddSourceLocation(MI->getUndefLoc(), Record);
+      Record.push_back(MI->isUsed());
+      Record.push_back(MI->isPublic());
+      AddSourceLocation(MI->getVisibilityLocation(), Record);
+      unsigned Code;
+      if (MI->isObjectLike()) {
+        Code = PP_MACRO_OBJECT_LIKE;
+      } else {
+        Code = PP_MACRO_FUNCTION_LIKE;
+
+        Record.push_back(MI->isC99Varargs());
+        Record.push_back(MI->isGNUVarargs());
+        Record.push_back(MI->getNumArgs());
+        for (MacroInfo::arg_iterator I = MI->arg_begin(), E = MI->arg_end();
+             I != E; ++I)
+          AddIdentifierRef(*I, Record);
+      }
 
-    // If we have a detailed preprocessing record, record the macro definition
-    // ID that corresponds to this macro.
-    if (PPRec)
-      Record.push_back(MacroDefinitions[PPRec->findMacroDefinition(MI)]);
+      // If we have a detailed preprocessing record, record the macro definition
+      // ID that corresponds to this macro.
+      if (PPRec)
+        Record.push_back(MacroDefinitions[PPRec->findMacroDefinition(MI)]);
 
-    Stream.EmitRecord(Code, Record);
-    Record.clear();
+      Stream.EmitRecord(Code, Record);
+      Record.clear();
 
-    // Emit the tokens array.
-    for (unsigned TokNo = 0, e = MI->getNumTokens(); TokNo != e; ++TokNo) {
-      // Note that we know that the preprocessor does not have any annotation
-      // tokens in it because they are created by the parser, and thus can't be
-      // in a macro definition.
-      const Token &Tok = MI->getReplacementToken(TokNo);
-
-      Record.push_back(Tok.getLocation().getRawEncoding());
-      Record.push_back(Tok.getLength());
-
-      // FIXME: When reading literal tokens, reconstruct the literal pointer if
-      // it is needed.
-      AddIdentifierRef(Tok.getIdentifierInfo(), Record);
-      // FIXME: Should translate token kind to a stable encoding.
-      Record.push_back(Tok.getKind());
-      // FIXME: Should translate token flags to a stable encoding.
-      Record.push_back(Tok.getFlags());
+      // Emit the tokens array.
+      for (unsigned TokNo = 0, e = MI->getNumTokens(); TokNo != e; ++TokNo) {
+        // Note that we know that the preprocessor does not have any annotation
+        // tokens in it because they are created by the parser, and thus can't
+        // be in a macro definition.
+        const Token &Tok = MI->getReplacementToken(TokNo);
+
+        Record.push_back(Tok.getLocation().getRawEncoding());
+        Record.push_back(Tok.getLength());
+
+        // FIXME: When reading literal tokens, reconstruct the literal pointer
+        // if it is needed.
+        AddIdentifierRef(Tok.getIdentifierInfo(), Record);
+        // FIXME: Should translate token kind to a stable encoding.
+        Record.push_back(Tok.getKind());
+        // FIXME: Should translate token flags to a stable encoding.
+        Record.push_back(Tok.getFlags());
 
-      Stream.EmitRecord(PP_TOKEN, Record);
-      Record.clear();
+        Stream.EmitRecord(PP_TOKEN, Record);
+        Record.clear();
+      }
+      ++NumMacros;
     }
-    ++NumMacros;
   }
   Stream.ExitBlock();
 }
@@ -2496,17 +2506,17 @@
         II->getFETokenInfo<void>())
       return true;
 
-    return hasMacroDefinition(II, Macro);
+    return hadMacroDefinition(II, Macro);
   }
-  
-  bool hasMacroDefinition(IdentifierInfo *II, MacroInfo *&Macro) {
-    if (!II->hasMacroDefinition())
+
+  bool hadMacroDefinition(IdentifierInfo *II, MacroInfo *&Macro) {
+    if (!II->hadMacroDefinition())
       return false;
-    
-    if (Macro || (Macro = PP.getMacroInfo(II)))
+
+    if (Macro || (Macro = PP.getMacroInfoHistory(II)))
       return !Macro->isBuiltinMacro() && (!IsModule || Macro->isPublic());
-    
-    return false;    
+
+    return false;
   }
 
 public:
@@ -2530,10 +2540,11 @@
     unsigned DataLen = 4; // 4 bytes for the persistent ID << 1
     MacroInfo *Macro = 0;
     if (isInterestingIdentifier(II, Macro)) {
-      DataLen += 2; // 2 bytes for builtin ID, flags
-      if (hasMacroDefinition(II, Macro))
+      DataLen += 2; // 2 bytes for builtin ID
+      DataLen += 2; // 2 bytes for flags
+      if (hadMacroDefinition(II, Macro))
         DataLen += 8;
-      
+
       for (IdentifierResolver::iterator D = IdResolver.begin(II),
                                      DEnd = IdResolver.end();
            D != DEnd; ++D)
@@ -2564,23 +2575,26 @@
     }
 
     clang::io::Emit32(Out, (ID << 1) | 0x01);
-    uint32_t Bits = 0;
-    bool HasMacroDefinition = hasMacroDefinition(II, Macro);
-    Bits = (uint32_t)II->getObjCOrBuiltinID();
-    assert((Bits & 0x7ff) == Bits && "ObjCOrBuiltinID too big for ASTReader.");
+    uint32_t Bits = (uint32_t)II->getObjCOrBuiltinID();
+    assert((Bits & 0xffff) == Bits && "ObjCOrBuiltinID too big for ASTReader.");
+    clang::io::Emit16(Out, Bits);
+    Bits = 0;
+    bool HadMacroDefinition = hadMacroDefinition(II, Macro);
+    bool HasMacroDefinition = HadMacroDefinition && II->hasMacroDefinition();
     Bits = (Bits << 1) | unsigned(HasMacroDefinition);
+    Bits = (Bits << 1) | unsigned(HadMacroDefinition);
     Bits = (Bits << 1) | unsigned(II->isExtensionToken());
     Bits = (Bits << 1) | unsigned(II->isPoisoned());
     Bits = (Bits << 1) | unsigned(II->hasRevertedTokenIDToIdentifier());
     Bits = (Bits << 1) | unsigned(II->isCPlusPlusOperatorKeyword());
     clang::io::Emit16(Out, Bits);
 
-    if (HasMacroDefinition) {
+    if (HadMacroDefinition) {
       clang::io::Emit32(Out, Writer.getMacroOffset(II));
-      clang::io::Emit32(Out, 
+      clang::io::Emit32(Out,
         Writer.inferSubmoduleIDFromLocation(Macro->getDefinitionLoc()));
     }
-    
+
     // Emit the declaration IDs in reverse order, because the
     // IdentifierResolver provides the declarations as they would be
     // visible (e.g., the function "stat" would come before the struct
@@ -4447,7 +4461,7 @@
 
 void ASTWriter::IdentifierRead(IdentID ID, IdentifierInfo *II) {
   IdentifierIDs[II] = ID;
-  if (II->hasMacroDefinition())
+  if (II->hadMacroDefinition())
     DeserializedMacroNames.push_back(II);
 }
 

Modified: cfe/trunk/test/CodeCompletion/Inputs/macros.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeCompletion/Inputs/macros.h?rev=164610&r1=164609&r2=164610&view=diff
==============================================================================
--- cfe/trunk/test/CodeCompletion/Inputs/macros.h (original)
+++ cfe/trunk/test/CodeCompletion/Inputs/macros.h Tue Sep 25 12:18:14 2012
@@ -2,3 +2,10 @@
 #define BAR(X, Y) X, Y
 #define IDENTITY(X) X
 #define WIBBLE(...)
+#define DEAD_MACRO
+#undef DEAD_MACRO
+#define MACRO_WITH_HISTORY a
+#undef MACRO_WITH_HISTORY
+#define MACRO_WITH_HISTORY b, c
+#undef MACRO_WITH_HISTORY
+#define MACRO_WITH_HISTORY(X, Y) X->Y

Modified: cfe/trunk/test/CodeCompletion/macros.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeCompletion/macros.c?rev=164610&r1=164609&r2=164610&view=diff
==============================================================================
--- cfe/trunk/test/CodeCompletion/macros.c (original)
+++ cfe/trunk/test/CodeCompletion/macros.c Tue Sep 25 12:18:14 2012
@@ -13,11 +13,15 @@
   // RUN: %clang_cc1 -include %S/Inputs/macros.h -fsyntax-only -code-completion-macros -code-completion-at=%s:14:9 %s -o - | FileCheck -check-prefix=CC2 %s
     case 
   }
+  // RUN: %clang_cc1 -include %S/Inputs/macros.h -fsyntax-only -code-completion-macros -code-completion-at=%s:17:7 %s -o - | FileCheck -check-prefix=CC3 %s
+#ifdef Q
+#endif
 
   // Run the same tests, this time with macros loaded from the PCH file.
   // RUN: %clang_cc1 -emit-pch -o %t %S/Inputs/macros.h
   // RUN: %clang_cc1 -include-pch %t -fsyntax-only -code-completion-macros -code-completion-at=%s:12:14 %s -o - | FileCheck -check-prefix=CC1 %s
   // RUN: %clang_cc1 -include-pch %t -fsyntax-only -code-completion-macros -code-completion-at=%s:14:9 %s -o - | FileCheck -check-prefix=CC2 %s
+  // RUN: %clang_cc1 -include-pch %t -fsyntax-only -code-completion-macros -code-completion-at=%s:17:7 %s -o - | FileCheck -check-prefix=CC3 %s
 
   // CC1: color
   // CC1: x
@@ -29,6 +33,14 @@
   // CC2: FOO
   // CC2: Green
   // CC2: IDENTITY(<#X#>)
+  // CC2: MACRO_WITH_HISTORY(<#X#>, <#Y#>)
   // CC2: Red
   // CC2: WIBBLE
+
+  // CC3: BAR
+  // CC3: DEAD_MACRO
+  // CC3: FOO
+  // CC3: IDENTITY
+  // CC3: MACRO_WITH_HISTORY
+  // CC3: WIBBLE
 }





More information about the cfe-commits mailing list