1 //===--- PreprocessorTracker.cpp - Preprocessor tracking -*- C++ -*------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===--------------------------------------------------------------------===//
9 //
10 // The Basic Idea
11 //
12 // Basically we install a PPCallbacks-derived object to track preprocessor
13 // activity, namely when a header file is entered/exited, when a macro
14 // is expanded, when "defined" is used, and when #if, #elif, #ifdef,
15 // and #ifndef are used.  We save the state of macro and "defined"
16 // expressions in a map, keyed on a name/file/line/column quadruple.
17 // The map entries store the different states (values) that a macro expansion,
18 // "defined" expression, or condition expression has in the course of
19 // processing for the one location in the one header containing it,
20 // plus a list of the nested include stacks for the states.  When a macro
21 // or "defined" expression evaluates to the same value, which is the
22 // desired case, only one state is stored.  Similarly, for conditional
23 // directives, we save the condition expression states in a separate map.
24 //
25 // This information is collected as modularize compiles all the headers
26 // given to it to process.  After all the compilations are performed,
27 // a check is performed for any entries in the maps that contain more
28 // than one different state, and for these an output message is generated.
29 //
30 // For example:
31 //
32 //   (...)/SubHeader.h:11:5:
33 //   #if SYMBOL == 1
34 //       ^
35 //   error: Macro instance 'SYMBOL' has different values in this header,
36 //          depending on how it was included.
37 //     'SYMBOL' expanded to: '1' with respect to these inclusion paths:
38 //       (...)/Header1.h
39 //         (...)/SubHeader.h
40 //   (...)/SubHeader.h:3:9:
41 //   #define SYMBOL 1
42 //             ^
43 //   Macro defined here.
44 //     'SYMBOL' expanded to: '2' with respect to these inclusion paths:
45 //       (...)/Header2.h
46 //           (...)/SubHeader.h
47 //   (...)/SubHeader.h:7:9:
48 //   #define SYMBOL 2
49 //             ^
50 //   Macro defined here.
51 //
52 // Design and Implementation Details
53 //
54 // A PreprocessorTrackerImpl class implements the PreprocessorTracker
55 // interface. It uses a PreprocessorCallbacks class derived from PPCallbacks
56 // to track preprocessor activity, namely entering/exiting a header, macro
57 // expansions, use of "defined" expressions, and #if, #elif, #ifdef, and
58 // #ifndef conditional directives. PreprocessorTrackerImpl stores a map
59 // of MacroExpansionTracker objects keyed on a name/file/line/column
60 // value represented by a light-weight PPItemKey value object. This
61 // is the key top-level data structure tracking the values of macro
62 // expansion instances.  Similarly, it stores a map of ConditionalTracker
63 // objects with the same kind of key, for tracking preprocessor conditional
64 // directives.
65 //
66 // The MacroExpansionTracker object represents one macro reference or use
67 // of a "defined" expression in a header file. It stores a handle to a
68 // string representing the unexpanded macro instance, a handle to a string
69 // representing the unpreprocessed source line containing the unexpanded
70 // macro instance, and a vector of one or more MacroExpansionInstance
71 // objects.
72 //
73 // The MacroExpansionInstance object represents one or more expansions
74 // of a macro reference, for the case where the macro expands to the same
75 // value. MacroExpansionInstance stores a handle to a string representing
76 // the expanded macro value, a PPItemKey representing the file/line/column
77 // where the macro was defined, a handle to a string representing the source
78 // line containing the macro definition, and a vector of InclusionPathHandle
79 // values that represents the hierarchies of include files for each case
80 // where the particular header containing the macro reference was referenced
81 // or included.
82 
83 // In the normal case where a macro instance always expands to the same
84 // value, the MacroExpansionTracker object will only contain one
85 // MacroExpansionInstance representing all the macro expansion instances.
86 // If a case was encountered where a macro instance expands to a value
87 // that is different from that seen before, or the macro was defined in
88 // a different place, a new MacroExpansionInstance object representing
89 // that case will be added to the vector in MacroExpansionTracker. If a
90 // macro instance expands to a value already seen before, the
91 // InclusionPathHandle representing that case's include file hierarchy
92 // will be added to the existing MacroExpansionInstance object.
93 
94 // For checking conditional directives, the ConditionalTracker class
95 // functions similarly to MacroExpansionTracker, but tracks an #if,
96 // #elif, #ifdef, or #ifndef directive in a header file.  It stores
97 // a vector of one or two ConditionalExpansionInstance objects,
98 // representing the cases where the conditional expression evaluates
99 // to true or false.  This latter object stores the evaluated value
100 // of the condition expression (a bool) and a vector of
101 // InclusionPathHandles.
102 //
103 // To reduce the instances of string and object copying, the
104 // PreprocessorTrackerImpl class uses a StringPool to save all stored
105 // strings, and defines a StringHandle type to abstract the references
106 // to the strings.
107 //
108 // PreprocessorTrackerImpl also maintains a list representing the unique
109 // headers, which is just a vector of StringHandle's for the header file
110 // paths. A HeaderHandle abstracts a reference to a header, and is simply
111 // the index of the stored header file path.
112 //
113 // A HeaderInclusionPath class abstracts a unique hierarchy of header file
114 // inclusions. It simply stores a vector of HeaderHandles ordered from the
115 // top-most header (the one from the header list passed to modularize) down
116 // to the header containing the macro reference. PreprocessorTrackerImpl
117 // stores a vector of these objects. An InclusionPathHandle typedef
118 // abstracts a reference to one of the HeaderInclusionPath objects, and is
119 // simply the index of the stored HeaderInclusionPath object. The
120 // MacroExpansionInstance object stores a vector of these handles so that
121 // the reporting function can display the include hierarchies for the macro
122 // expansion instances represented by that object, to help the user
123 // understand how the header was included. (A future enhancement might
124 // be to associate a line number for the #include directives, but I
125 // think not doing so is good enough for the present.)
126 //
127 // A key reason for using these opaque handles was to try to keep all the
128 // internal objects light-weight value objects, in order to reduce string
129 // and object copying overhead, and to abstract this implementation detail.
130 //
131 // The key data structures are built up while modularize runs the headers
132 // through the compilation. A PreprocessorTracker instance is created and
133 // passed down to the AST action and consumer objects in modularize. For
134 // each new compilation instance, the consumer calls the
135 // PreprocessorTracker's handleNewPreprocessorEntry function, which sets
136 // up a PreprocessorCallbacks object for the preprocessor. At the end of
137 // the compilation instance, the PreprocessorTracker's
138 // handleNewPreprocessorExit function handles cleaning up with respect
139 // to the preprocessing instance.
140 //
141 // The PreprocessorCallbacks object uses an overidden FileChanged callback
142 // to determine when a header is entered and exited (including exiting the
143 // header during #include directives). It calls PreprocessorTracker's
144 // handleHeaderEntry and handleHeaderExit functions upon entering and
145 // exiting a header. These functions manage a stack of header handles
146 // representing by a vector, pushing and popping header handles as headers
147 // are entered and exited. When a HeaderInclusionPath object is created,
148 // it simply copies this stack.
149 //
150 // The PreprocessorCallbacks object uses an overridden MacroExpands callback
151 // to track when a macro expansion is performed. It calls a couple of helper
152 // functions to get the unexpanded and expanded macro values as strings, but
153 // then calls PreprocessorTrackerImpl's addMacroExpansionInstance function to
154 // do the rest of the work. The getMacroExpandedString function uses the
155 // preprocessor's getSpelling to convert tokens to strings using the
156 // information passed to the MacroExpands callback, and simply concatenates
157 // them. It makes recursive calls to itself to handle nested macro
158 // definitions, and also handles function-style macros.
159 //
160 // PreprocessorTrackerImpl's addMacroExpansionInstance function looks for
161 // an existing MacroExpansionTracker entry in its map of MacroExampleTracker
162 // objects. If none exists, it adds one with one MacroExpansionInstance and
163 // returns. If a MacroExpansionTracker object already exists, it looks for
164 // an existing MacroExpansionInstance object stored in the
165 // MacroExpansionTracker object, one that matches the macro expanded value
166 // and the macro definition location. If a matching MacroExpansionInstance
167 // object is found, it just adds the current HeaderInclusionPath object to
168 // it. If not found, it creates and stores a new MacroExpantionInstance
169 // object. The addMacroExpansionInstance function calls a couple of helper
170 // functions to get the pre-formatted location and source line strings for
171 // the macro reference and the macro definition stored as string handles.
172 // These helper functions use the current source manager from the
173 // preprocessor. This is done in advance at this point in time because the
174 // source manager doesn't exist at the time of the reporting.
175 //
176 // For conditional check, the PreprocessorCallbacks class overrides the
177 // PPCallbacks handlers for #if, #elif, #ifdef, and #ifndef.  These handlers
178 // call the addConditionalExpansionInstance method of
179 // PreprocessorTrackerImpl.  The process is similar to that of macros, but
180 // with some different data and error messages.  A lookup is performed for
181 // the conditional, and if a ConditionalTracker object doesn't yet exist for
182 // the conditional, a new one is added, including adding a
183 // ConditionalExpansionInstance object to it to represent the condition
184 // expression state.  If a ConditionalTracker for the conditional does
185 // exist, a lookup is made for a ConditionalExpansionInstance object
186 // matching the condition expression state.  If one exists, a
187 // HeaderInclusionPath is added to it.  Otherwise a new
188 // ConditionalExpansionInstance  entry is made.  If a ConditionalTracker
189 // has two ConditionalExpansionInstance objects, it means there was a
190 // conflict, meaning the conditional expression evaluated differently in
191 // one or more cases.
192 //
193 // After modularize has performed all the compilations, it enters a phase
194 // of error reporting. This new feature adds to this reporting phase calls
195 // to the PreprocessorTracker's reportInconsistentMacros and
196 // reportInconsistentConditionals functions. These functions walk the maps
197 // of MacroExpansionTracker's and ConditionalTracker's respectively. If
198 // any of these objects have more than one MacroExpansionInstance or
199 // ConditionalExpansionInstance objects, it formats and outputs an error
200 // message like the example shown previously, using the stored data.
201 //
202 // A potential issue is that there is some overlap between the #if/#elif
203 // conditional and macro reporting.  I could disable the #if and #elif,
204 // leaving just the #ifdef and #ifndef, since these don't overlap.  Or,
205 // to make clearer the separate reporting phases, I could add an output
206 // message marking the phases.
207 //
208 // Future Directions
209 //
210 // We probably should add options to disable any of the checks, in case
211 // there is some problem with them, or the messages get too verbose.
212 //
213 // With the map of all the macro and conditional expansion instances,
214 // it might be possible to add to the existing modularize error messages
215 // (the second part referring to definitions being different), attempting
216 // to tie them to the last macro conflict encountered with respect to the
217 // order of the code encountered.
218 //
219 //===--------------------------------------------------------------------===//
220 
221 #include "clang/Lex/LexDiagnostic.h"
222 #include "clang/Lex/MacroArgs.h"
223 #include "clang/Lex/PPCallbacks.h"
224 #include "llvm/Support/raw_ostream.h"
225 #include "llvm/Support/StringPool.h"
226 #include "llvm/ADT/SmallSet.h"
227 #include "PreprocessorTracker.h"
228 
229 namespace Modularize {
230 
231 // Forwards.
232 class PreprocessorTrackerImpl;
233 
234 // Some handle types
235 typedef llvm::PooledStringPtr StringHandle;
236 
237 typedef int HeaderHandle;
238 const HeaderHandle HeaderHandleInvalid = -1;
239 
240 typedef int InclusionPathHandle;
241 const InclusionPathHandle InclusionPathHandleInvalid = -1;
242 
243 // Some utility functions.
244 
245 // Get a "file:line:column" source location string.
246 static std::string getSourceLocationString(clang::Preprocessor &PP,
247                                            clang::SourceLocation Loc) {
248   if (Loc.isInvalid())
249     return std::string("(none)");
250   else
251     return Loc.printToString(PP.getSourceManager());
252 }
253 
254 // Get just the file name from a source location.
255 static std::string getSourceLocationFile(clang::Preprocessor &PP,
256                                          clang::SourceLocation Loc) {
257   std::string Source(getSourceLocationString(PP, Loc));
258   size_t Offset = Source.find(':', 2);
259   if (Offset == std::string::npos)
260     return Source;
261   return Source.substr(0, Offset);
262 }
263 
264 // Get just the line and column from a source location.
265 static void getSourceLocationLineAndColumn(clang::Preprocessor &PP,
266                                            clang::SourceLocation Loc, int &Line,
267                                            int &Column) {
268   clang::PresumedLoc PLoc = PP.getSourceManager().getPresumedLoc(Loc);
269   if (PLoc.isInvalid()) {
270     Line = 0;
271     Column = 0;
272     return;
273   }
274   Line = PLoc.getLine();
275   Column = PLoc.getColumn();
276 }
277 
278 // Retrieve source snippet from file image.
279 std::string getSourceString(clang::Preprocessor &PP, clang::SourceRange Range) {
280   clang::SourceLocation BeginLoc = Range.getBegin();
281   clang::SourceLocation EndLoc = Range.getEnd();
282   const char *BeginPtr = PP.getSourceManager().getCharacterData(BeginLoc);
283   const char *EndPtr = PP.getSourceManager().getCharacterData(EndLoc);
284   size_t Length = EndPtr - BeginPtr;
285   return llvm::StringRef(BeginPtr, Length).trim().str();
286 }
287 
288 // Retrieve source line from file image.
289 std::string getSourceLine(clang::Preprocessor &PP, clang::SourceLocation Loc) {
290   const llvm::MemoryBuffer *MemBuffer =
291       PP.getSourceManager().getBuffer(PP.getSourceManager().getFileID(Loc));
292   const char *Buffer = MemBuffer->getBufferStart();
293   const char *BufferEnd = MemBuffer->getBufferEnd();
294   const char *BeginPtr = PP.getSourceManager().getCharacterData(Loc);
295   const char *EndPtr = BeginPtr;
296   while (BeginPtr > Buffer) {
297     if (*BeginPtr == '\n') {
298       BeginPtr++;
299       break;
300     }
301     BeginPtr--;
302   }
303   while (EndPtr < BufferEnd) {
304     if (*EndPtr == '\n') {
305       break;
306     }
307     EndPtr++;
308   }
309   size_t Length = EndPtr - BeginPtr;
310   return llvm::StringRef(BeginPtr, Length).str();
311 }
312 
313 // Get the string for the Unexpanded macro instance.
314 // The soureRange is expected to end at the last token
315 // for the macro instance, which in the case of a function-style
316 // macro will be a ')', but for an object-style macro, it
317 // will be the macro name itself.
318 std::string getMacroUnexpandedString(clang::SourceRange Range,
319                                      clang::Preprocessor &PP,
320                                      llvm::StringRef MacroName,
321                                      const clang::MacroInfo *MI) {
322   clang::SourceLocation BeginLoc(Range.getBegin());
323   const char *BeginPtr = PP.getSourceManager().getCharacterData(BeginLoc);
324   size_t Length;
325   std::string Unexpanded;
326   if (MI->isFunctionLike()) {
327     clang::SourceLocation EndLoc(Range.getEnd());
328     const char *EndPtr = PP.getSourceManager().getCharacterData(EndLoc) + 1;
329     Length = (EndPtr - BeginPtr) + 1; // +1 is ')' width.
330   } else
331     Length = MacroName.size();
332   return llvm::StringRef(BeginPtr, Length).trim().str();
333 }
334 
335 // Get the expansion for a macro instance, given the information
336 // provided by PPCallbacks.
337 // FIXME: This doesn't support function-style macro instances
338 // passed as arguments to another function-style macro. However,
339 // since it still expands the inner arguments, it still
340 // allows modularize to effectively work with respect to macro
341 // consistency checking, although it displays the incorrect
342 // expansion in error messages.
343 std::string getMacroExpandedString(clang::Preprocessor &PP,
344                                    llvm::StringRef MacroName,
345                                    const clang::MacroInfo *MI,
346                                    const clang::MacroArgs *Args) {
347   std::string Expanded;
348   // Walk over the macro Tokens.
349   typedef clang::MacroInfo::tokens_iterator Iter;
350   for (Iter I = MI->tokens_begin(), E = MI->tokens_end(); I != E; ++I) {
351     clang::IdentifierInfo *II = I->getIdentifierInfo();
352     int ArgNo = (II && Args ? MI->getArgumentNum(II) : -1);
353     if (ArgNo == -1) {
354       // This isn't an argument, just add it.
355       if (II == NULL)
356         Expanded += PP.getSpelling((*I)); // Not an identifier.
357       else {
358         // Token is for an identifier.
359         std::string Name = II->getName().str();
360         // Check for nexted macro references.
361         clang::MacroInfo *MacroInfo = PP.getMacroInfo(II);
362         if (MacroInfo != NULL)
363           Expanded += getMacroExpandedString(PP, Name, MacroInfo, NULL);
364         else
365           Expanded += Name;
366       }
367       continue;
368     }
369     // We get here if it's a function-style macro with arguments.
370     const clang::Token *ResultArgToks;
371     const clang::Token *ArgTok = Args->getUnexpArgument(ArgNo);
372     if (Args->ArgNeedsPreexpansion(ArgTok, PP))
373       ResultArgToks = &(const_cast<clang::MacroArgs *>(Args))
374           ->getPreExpArgument(ArgNo, MI, PP)[0];
375     else
376       ResultArgToks = ArgTok; // Use non-preexpanded Tokens.
377     // If the arg token didn't expand into anything, ignore it.
378     if (ResultArgToks->is(clang::tok::eof))
379       continue;
380     unsigned NumToks = clang::MacroArgs::getArgLength(ResultArgToks);
381     // Append the resulting argument expansions.
382     for (unsigned ArgumentIndex = 0; ArgumentIndex < NumToks; ++ArgumentIndex) {
383       const clang::Token &AT = ResultArgToks[ArgumentIndex];
384       clang::IdentifierInfo *II = AT.getIdentifierInfo();
385       if (II == NULL)
386         Expanded += PP.getSpelling(AT); // Not an identifier.
387       else {
388         // It's an identifier.  Check for further expansion.
389         std::string Name = II->getName().str();
390         clang::MacroInfo *MacroInfo = PP.getMacroInfo(II);
391         if (MacroInfo != NULL)
392           Expanded += getMacroExpandedString(PP, Name, MacroInfo, NULL);
393         else
394           Expanded += Name;
395       }
396     }
397   }
398   return Expanded;
399 }
400 
401 // Get the string representing a vector of Tokens.
402 std::string
403 getTokensSpellingString(clang::Preprocessor &PP,
404                         llvm::SmallVectorImpl<clang::Token> &Tokens) {
405   std::string Expanded;
406   // Walk over the macro Tokens.
407   typedef llvm::SmallVectorImpl<clang::Token>::iterator Iter;
408   for (Iter I = Tokens.begin(), E = Tokens.end(); I != E; ++I)
409     Expanded += PP.getSpelling(*I); // Not an identifier.
410   return llvm::StringRef(Expanded).trim().str();
411 }
412 
413 // Get the expansion for a macro instance, given the information
414 // provided by PPCallbacks.
415 std::string getExpandedString(clang::Preprocessor &PP,
416                               llvm::StringRef MacroName,
417                               const clang::MacroInfo *MI,
418                               const clang::MacroArgs *Args) {
419   std::string Expanded;
420   // Walk over the macro Tokens.
421   typedef clang::MacroInfo::tokens_iterator Iter;
422   for (Iter I = MI->tokens_begin(), E = MI->tokens_end(); I != E; ++I) {
423     clang::IdentifierInfo *II = I->getIdentifierInfo();
424     int ArgNo = (II && Args ? MI->getArgumentNum(II) : -1);
425     if (ArgNo == -1) {
426       // This isn't an argument, just add it.
427       if (II == NULL)
428         Expanded += PP.getSpelling((*I)); // Not an identifier.
429       else {
430         // Token is for an identifier.
431         std::string Name = II->getName().str();
432         // Check for nexted macro references.
433         clang::MacroInfo *MacroInfo = PP.getMacroInfo(II);
434         if (MacroInfo != NULL)
435           Expanded += getMacroExpandedString(PP, Name, MacroInfo, NULL);
436         else
437           Expanded += Name;
438       }
439       continue;
440     }
441     // We get here if it's a function-style macro with arguments.
442     const clang::Token *ResultArgToks;
443     const clang::Token *ArgTok = Args->getUnexpArgument(ArgNo);
444     if (Args->ArgNeedsPreexpansion(ArgTok, PP))
445       ResultArgToks = &(const_cast<clang::MacroArgs *>(Args))
446           ->getPreExpArgument(ArgNo, MI, PP)[0];
447     else
448       ResultArgToks = ArgTok; // Use non-preexpanded Tokens.
449     // If the arg token didn't expand into anything, ignore it.
450     if (ResultArgToks->is(clang::tok::eof))
451       continue;
452     unsigned NumToks = clang::MacroArgs::getArgLength(ResultArgToks);
453     // Append the resulting argument expansions.
454     for (unsigned ArgumentIndex = 0; ArgumentIndex < NumToks; ++ArgumentIndex) {
455       const clang::Token &AT = ResultArgToks[ArgumentIndex];
456       clang::IdentifierInfo *II = AT.getIdentifierInfo();
457       if (II == NULL)
458         Expanded += PP.getSpelling(AT); // Not an identifier.
459       else {
460         // It's an identifier.  Check for further expansion.
461         std::string Name = II->getName().str();
462         clang::MacroInfo *MacroInfo = PP.getMacroInfo(II);
463         if (MacroInfo != NULL)
464           Expanded += getMacroExpandedString(PP, Name, MacroInfo, NULL);
465         else
466           Expanded += Name;
467       }
468     }
469   }
470   return Expanded;
471 }
472 
473 // We need some operator overloads for string handles.
474 bool operator==(const StringHandle &H1, const StringHandle &H2) {
475   const char *S1 = (H1 ? *H1 : "");
476   const char *S2 = (H2 ? *H2 : "");
477   int Diff = strcmp(S1, S2);
478   return Diff == 0;
479 }
480 bool operator!=(const StringHandle &H1, const StringHandle &H2) {
481   const char *S1 = (H1 ? *H1 : "");
482   const char *S2 = (H2 ? *H2 : "");
483   int Diff = strcmp(S1, S2);
484   return Diff != 0;
485 }
486 bool operator<(const StringHandle &H1, const StringHandle &H2) {
487   const char *S1 = (H1 ? *H1 : "");
488   const char *S2 = (H2 ? *H2 : "");
489   int Diff = strcmp(S1, S2);
490   return Diff < 0;
491 }
492 bool operator>(const StringHandle &H1, const StringHandle &H2) {
493   const char *S1 = (H1 ? *H1 : "");
494   const char *S2 = (H2 ? *H2 : "");
495   int Diff = strcmp(S1, S2);
496   return Diff > 0;
497 }
498 
499 // Preprocessor item key.
500 //
501 // This class represents a location in a source file, for use
502 // as a key representing a unique name/file/line/column quadruplet,
503 // which in this case is used to identify a macro expansion instance,
504 // but could be used for other things as well.
505 // The file is a header file handle, the line is a line number,
506 // and the column is a column number.
507 class PPItemKey {
508 public:
509   PPItemKey(clang::Preprocessor &PP, StringHandle Name, HeaderHandle File,
510             clang::SourceLocation Loc)
511       : Name(Name), File(File) {
512     getSourceLocationLineAndColumn(PP, Loc, Line, Column);
513   }
514   PPItemKey(StringHandle Name, HeaderHandle File, int Line, int Column)
515       : Name(Name), File(File), Line(Line), Column(Column) {}
516   PPItemKey(const PPItemKey &Other)
517       : Name(Other.Name), File(Other.File), Line(Other.Line),
518         Column(Other.Column) {}
519   PPItemKey() : File(HeaderHandleInvalid), Line(0), Column(0) {}
520   bool operator==(const PPItemKey &Other) const {
521     if (Name != Other.Name)
522       return false;
523     if (File != Other.File)
524       return false;
525     if (Line != Other.Line)
526       return false;
527     return Column == Other.Column;
528   }
529   bool operator<(const PPItemKey &Other) const {
530     if (Name < Other.Name)
531       return true;
532     else if (Name > Other.Name)
533       return false;
534     if (File < Other.File)
535       return true;
536     else if (File > Other.File)
537       return false;
538     if (Line < Other.Line)
539       return true;
540     else if (Line > Other.Line)
541       return false;
542     return Column < Other.Column;
543   }
544   StringHandle Name;
545   HeaderHandle File;
546   int Line;
547   int Column;
548 };
549 
550 // Header inclusion path.
551 class HeaderInclusionPath {
552 public:
553   HeaderInclusionPath(std::vector<HeaderHandle> HeaderInclusionPath)
554       : Path(HeaderInclusionPath) {}
555   HeaderInclusionPath(const HeaderInclusionPath &Other) : Path(Other.Path) {}
556   HeaderInclusionPath() {}
557   std::vector<HeaderHandle> Path;
558 };
559 
560 // Macro expansion instance.
561 //
562 // This class represents an instance of a macro expansion with a
563 // unique value.  It also stores the unique header inclusion paths
564 // for use in telling the user the nested include path to the header.
565 class MacroExpansionInstance {
566 public:
567   MacroExpansionInstance(StringHandle MacroExpanded,
568                          PPItemKey &DefinitionLocation,
569                          StringHandle DefinitionSourceLine,
570                          InclusionPathHandle H)
571       : MacroExpanded(MacroExpanded), DefinitionLocation(DefinitionLocation),
572         DefinitionSourceLine(DefinitionSourceLine) {
573     InclusionPathHandles.push_back(H);
574   }
575   MacroExpansionInstance() {}
576 
577   // Check for the presence of a header inclusion path handle entry.
578   // Return false if not found.
579   bool haveInclusionPathHandle(InclusionPathHandle H) {
580     for (std::vector<InclusionPathHandle>::iterator
581              I = InclusionPathHandles.begin(),
582              E = InclusionPathHandles.end();
583          I != E; ++I) {
584       if (*I == H)
585         return true;
586     }
587     return InclusionPathHandleInvalid;
588   }
589   // Add a new header inclusion path entry, if not already present.
590   void addInclusionPathHandle(InclusionPathHandle H) {
591     if (!haveInclusionPathHandle(H))
592       InclusionPathHandles.push_back(H);
593   }
594 
595   // A string representing the macro instance after preprocessing.
596   StringHandle MacroExpanded;
597   // A file/line/column triplet representing the macro definition location.
598   PPItemKey DefinitionLocation;
599   // A place to save the macro definition line string.
600   StringHandle DefinitionSourceLine;
601   // The header inclusion path handles for all the instances.
602   std::vector<InclusionPathHandle> InclusionPathHandles;
603 };
604 
605 // Macro expansion instance tracker.
606 //
607 // This class represents one macro expansion, keyed by a PPItemKey.
608 // It stores a string representing the macro reference in the source,
609 // and a list of ConditionalExpansionInstances objects representing
610 // the unique values the condition expands to in instances of the header.
611 class MacroExpansionTracker {
612 public:
613   MacroExpansionTracker(StringHandle MacroUnexpanded,
614                         StringHandle MacroExpanded,
615                         StringHandle InstanceSourceLine,
616                         PPItemKey &DefinitionLocation,
617                         StringHandle DefinitionSourceLine,
618                         InclusionPathHandle InclusionPathHandle)
619       : MacroUnexpanded(MacroUnexpanded),
620         InstanceSourceLine(InstanceSourceLine) {
621     addMacroExpansionInstance(MacroExpanded, DefinitionLocation,
622                               DefinitionSourceLine, InclusionPathHandle);
623   }
624   MacroExpansionTracker() {}
625 
626   // Find a matching macro expansion instance.
627   MacroExpansionInstance *
628   findMacroExpansionInstance(StringHandle MacroExpanded,
629                              PPItemKey &DefinitionLocation) {
630     for (std::vector<MacroExpansionInstance>::iterator
631              I = MacroExpansionInstances.begin(),
632              E = MacroExpansionInstances.end();
633          I != E; ++I) {
634       if ((I->MacroExpanded == MacroExpanded) &&
635           (I->DefinitionLocation == DefinitionLocation)) {
636         return &*I; // Found.
637       }
638     }
639     return NULL; // Not found.
640   }
641 
642   // Add a macro expansion instance.
643   void addMacroExpansionInstance(StringHandle MacroExpanded,
644                                  PPItemKey &DefinitionLocation,
645                                  StringHandle DefinitionSourceLine,
646                                  InclusionPathHandle InclusionPathHandle) {
647     MacroExpansionInstances.push_back(
648         MacroExpansionInstance(MacroExpanded, DefinitionLocation,
649                                DefinitionSourceLine, InclusionPathHandle));
650   }
651 
652   // Return true if there is a mismatch.
653   bool hasMismatch() { return MacroExpansionInstances.size() > 1; }
654 
655   // A string representing the macro instance without expansion.
656   StringHandle MacroUnexpanded;
657   // A place to save the macro instance source line string.
658   StringHandle InstanceSourceLine;
659   // The macro expansion instances.
660   // If all instances of the macro expansion expand to the same value,
661   // This vector will only have one instance.
662   std::vector<MacroExpansionInstance> MacroExpansionInstances;
663 };
664 
665 // Conditional expansion instance.
666 //
667 // This class represents an instance of a condition exoression result
668 // with a unique value.  It also stores the unique header inclusion paths
669 // for use in telling the user the nested include path to the header.
670 class ConditionalExpansionInstance {
671 public:
672   ConditionalExpansionInstance(bool ConditionValue, InclusionPathHandle H)
673       : ConditionValue(ConditionValue) {
674     InclusionPathHandles.push_back(H);
675   }
676   ConditionalExpansionInstance() {}
677 
678   // Check for the presence of a header inclusion path handle entry.
679   // Return false if not found.
680   bool haveInclusionPathHandle(InclusionPathHandle H) {
681     for (std::vector<InclusionPathHandle>::iterator
682              I = InclusionPathHandles.begin(),
683              E = InclusionPathHandles.end();
684          I != E; ++I) {
685       if (*I == H)
686         return true;
687     }
688     return InclusionPathHandleInvalid;
689   }
690   // Add a new header inclusion path entry, if not already present.
691   void addInclusionPathHandle(InclusionPathHandle H) {
692     if (!haveInclusionPathHandle(H))
693       InclusionPathHandles.push_back(H);
694   }
695 
696   // A flag representing the evaluated condition value.
697   bool ConditionValue;
698   // The header inclusion path handles for all the instances.
699   std::vector<InclusionPathHandle> InclusionPathHandles;
700 };
701 
702 // Conditional directive instance tracker.
703 //
704 // This class represents one conditional directive, keyed by a PPItemKey.
705 // It stores a string representing the macro reference in the source,
706 // and a list of ConditionExpansionInstance objects representing
707 // the unique value the condition expression expands to in instances of
708 // the header.
709 class ConditionalTracker {
710 public:
711   ConditionalTracker(clang::tok::PPKeywordKind DirectiveKind,
712                      bool ConditionValue, StringHandle ConditionUnexpanded,
713                      InclusionPathHandle InclusionPathHandle)
714       : DirectiveKind(DirectiveKind), ConditionUnexpanded(ConditionUnexpanded) {
715     addConditionalExpansionInstance(ConditionValue, InclusionPathHandle);
716   }
717   ConditionalTracker() {}
718 
719   // Find a matching condition expansion instance.
720   ConditionalExpansionInstance *
721   findConditionalExpansionInstance(bool ConditionValue) {
722     for (std::vector<ConditionalExpansionInstance>::iterator
723              I = ConditionalExpansionInstances.begin(),
724              E = ConditionalExpansionInstances.end();
725          I != E; ++I) {
726       if (I->ConditionValue == ConditionValue) {
727         return &*I; // Found.
728       }
729     }
730     return NULL; // Not found.
731   }
732 
733   // Add a conditional expansion instance.
734   void
735   addConditionalExpansionInstance(bool ConditionValue,
736                                   InclusionPathHandle InclusionPathHandle) {
737     ConditionalExpansionInstances.push_back(
738         ConditionalExpansionInstance(ConditionValue, InclusionPathHandle));
739   }
740 
741   // Return true if there is a mismatch.
742   bool hasMismatch() { return ConditionalExpansionInstances.size() > 1; }
743 
744   // The kind of directive.
745   clang::tok::PPKeywordKind DirectiveKind;
746   // A string representing the macro instance without expansion.
747   StringHandle ConditionUnexpanded;
748   // The condition expansion instances.
749   // If all instances of the conditional expression expand to the same value,
750   // This vector will only have one instance.
751   std::vector<ConditionalExpansionInstance> ConditionalExpansionInstances;
752 };
753 
754 // Preprocessor callbacks for modularize.
755 //
756 // This class derives from the Clang PPCallbacks class to track preprocessor
757 // actions, such as changing files and handling preprocessor directives and
758 // macro expansions.  It has to figure out when a new header file is entered
759 // and left, as the provided handler is not particularly clear about it.
760 class PreprocessorCallbacks : public clang::PPCallbacks {
761 public:
762   PreprocessorCallbacks(PreprocessorTrackerImpl &ppTracker,
763                         clang::Preprocessor &PP, llvm::StringRef rootHeaderFile)
764       : PPTracker(ppTracker), PP(PP), RootHeaderFile(rootHeaderFile) {}
765   ~PreprocessorCallbacks() {}
766 
767   // Overridden handlers.
768   void FileChanged(clang::SourceLocation Loc,
769                    clang::PPCallbacks::FileChangeReason Reason,
770                    clang::SrcMgr::CharacteristicKind FileType,
771                    clang::FileID PrevFID = clang::FileID());
772   void MacroExpands(const clang::Token &MacroNameTok,
773                     const clang::MacroDirective *MD, clang::SourceRange Range,
774                     const clang::MacroArgs *Args);
775   void Defined(const clang::Token &MacroNameTok,
776                const clang::MacroDirective *MD, clang::SourceRange Range);
777   void If(clang::SourceLocation Loc, clang::SourceRange ConditionRange,
778           bool ConditionResult);
779   void Elif(clang::SourceLocation Loc, clang::SourceRange ConditionRange,
780             bool ConditionResult, clang::SourceLocation IfLoc);
781   void Ifdef(clang::SourceLocation Loc, const clang::Token &MacroNameTok,
782              const clang::MacroDirective *MD);
783   void Ifndef(clang::SourceLocation Loc, const clang::Token &MacroNameTok,
784               const clang::MacroDirective *MD);
785 
786 private:
787   PreprocessorTrackerImpl &PPTracker;
788   clang::Preprocessor &PP;
789   std::string RootHeaderFile;
790 };
791 
792 // Preprocessor macro expansion item map types.
793 typedef std::map<PPItemKey, MacroExpansionTracker> MacroExpansionMap;
794 typedef std::map<PPItemKey, MacroExpansionTracker>::iterator
795 MacroExpansionMapIter;
796 
797 // Preprocessor conditional expansion item map types.
798 typedef std::map<PPItemKey, ConditionalTracker> ConditionalExpansionMap;
799 typedef std::map<PPItemKey, ConditionalTracker>::iterator
800 ConditionalExpansionMapIter;
801 
802 // Preprocessor tracker for modularize.
803 //
804 // This class stores information about all the headers processed in the
805 // course of running modularize.
806 class PreprocessorTrackerImpl : public PreprocessorTracker {
807 public:
808   PreprocessorTrackerImpl()
809       : CurrentInclusionPathHandle(InclusionPathHandleInvalid),
810         InNestedHeader(false) {}
811   ~PreprocessorTrackerImpl() {}
812 
813   // Handle entering a preprocessing session.
814   void handlePreprocessorEntry(clang::Preprocessor &PP,
815                                llvm::StringRef rootHeaderFile) {
816     HeadersInThisCompile.clear();
817     assert((HeaderStack.size() == 0) && "Header stack should be empty.");
818     pushHeaderHandle(addHeader(rootHeaderFile));
819     PP.addPPCallbacks(new PreprocessorCallbacks(*this, PP, rootHeaderFile));
820   }
821   // Handle exiting a preprocessing session.
822   void handlePreprocessorExit() { HeaderStack.clear(); }
823 
824   // Handle entering a header source file.
825   void handleHeaderEntry(clang::Preprocessor &PP, llvm::StringRef HeaderPath) {
826     // Ignore <built-in> and <command-line> to reduce message clutter.
827     if (HeaderPath.startswith("<"))
828       return;
829     HeaderHandle H = addHeader(HeaderPath);
830     if (H != getCurrentHeaderHandle())
831       pushHeaderHandle(H);
832     // Check for nested header.
833     if (!InNestedHeader)
834       InNestedHeader = !HeadersInThisCompile.insert(H);
835   }
836   // Handle exiting a header source file.
837   void handleHeaderExit(llvm::StringRef HeaderPath) {
838     // Ignore <built-in> and <command-line> to reduce message clutter.
839     if (HeaderPath.startswith("<"))
840       return;
841     HeaderHandle H = findHeaderHandle(HeaderPath);
842     if (isHeaderHandleInStack(H)) {
843       while ((H != getCurrentHeaderHandle()) && (HeaderStack.size() != 0))
844         popHeaderHandle();
845     }
846     InNestedHeader = false;
847   }
848 
849   // Lookup/add string.
850   StringHandle addString(llvm::StringRef Str) { return Strings.intern(Str); }
851 
852   // Get the handle of a header file entry.
853   // Return HeaderHandleInvalid if not found.
854   HeaderHandle findHeaderHandle(llvm::StringRef HeaderPath) const {
855     std::string CanonicalPath(HeaderPath);
856     std::replace(CanonicalPath.begin(), CanonicalPath.end(), '\\', '/');
857     HeaderHandle H = 0;
858     for (std::vector<StringHandle>::const_iterator I = HeaderPaths.begin(),
859                                                    E = HeaderPaths.end();
860          I != E; ++I, ++H) {
861       if (**I == CanonicalPath)
862         return H;
863     }
864     return HeaderHandleInvalid;
865   }
866 
867   // Add a new header file entry, or return existing handle.
868   // Return the header handle.
869   HeaderHandle addHeader(llvm::StringRef HeaderPath) {
870     std::string CanonicalPath(HeaderPath);
871     std::replace(CanonicalPath.begin(), CanonicalPath.end(), '\\', '/');
872     HeaderHandle H = findHeaderHandle(CanonicalPath);
873     if (H == HeaderHandleInvalid) {
874       H = HeaderPaths.size();
875       HeaderPaths.push_back(addString(CanonicalPath));
876     }
877     return H;
878   }
879 
880   // Return a header file path string given its handle.
881   StringHandle getHeaderFilePath(HeaderHandle H) const {
882     if ((H >= 0) && (H < (HeaderHandle)HeaderPaths.size()))
883       return HeaderPaths[H];
884     return StringHandle();
885   }
886 
887   // Returns a handle to the inclusion path.
888   InclusionPathHandle pushHeaderHandle(HeaderHandle H) {
889     HeaderStack.push_back(H);
890     return CurrentInclusionPathHandle = addInclusionPathHandle(HeaderStack);
891   }
892   // Pops the last header handle from the stack;
893   void popHeaderHandle() {
894     // assert((HeaderStack.size() != 0) && "Header stack already empty.");
895     if (HeaderStack.size() != 0) {
896       HeaderStack.pop_back();
897       CurrentInclusionPathHandle = addInclusionPathHandle(HeaderStack);
898     }
899   }
900   // Get the top handle on the header stack.
901   HeaderHandle getCurrentHeaderHandle() const {
902     if (HeaderStack.size() != 0)
903       return HeaderStack.back();
904     return HeaderHandleInvalid;
905   }
906 
907   // Check for presence of header handle in the header stack.
908   bool isHeaderHandleInStack(HeaderHandle H) const {
909     for (std::vector<HeaderHandle>::const_iterator I = HeaderStack.begin(),
910                                                    E = HeaderStack.end();
911          I != E; ++I) {
912       if (*I == H)
913         return true;
914     }
915     return false;
916   }
917 
918   // Get the handle of a header inclusion path entry.
919   // Return InclusionPathHandleInvalid if not found.
920   InclusionPathHandle
921   findInclusionPathHandle(const std::vector<HeaderHandle> &Path) const {
922     InclusionPathHandle H = 0;
923     for (std::vector<HeaderInclusionPath>::const_iterator
924              I = InclusionPaths.begin(),
925              E = InclusionPaths.end();
926          I != E; ++I, ++H) {
927       if (I->Path == Path)
928         return H;
929     }
930     return HeaderHandleInvalid;
931   }
932   // Add a new header inclusion path entry, or return existing handle.
933   // Return the header inclusion path entry handle.
934   InclusionPathHandle
935   addInclusionPathHandle(const std::vector<HeaderHandle> &Path) {
936     InclusionPathHandle H = findInclusionPathHandle(Path);
937     if (H == HeaderHandleInvalid) {
938       H = InclusionPaths.size();
939       InclusionPaths.push_back(HeaderInclusionPath(Path));
940     }
941     return H;
942   }
943   // Return the current inclusion path handle.
944   InclusionPathHandle getCurrentInclusionPathHandle() const {
945     return CurrentInclusionPathHandle;
946   }
947 
948   // Return an inclusion path given its handle.
949   const std::vector<HeaderHandle> &
950   getInclusionPath(InclusionPathHandle H) const {
951     if ((H >= 0) && (H <= (InclusionPathHandle)InclusionPaths.size()))
952       return InclusionPaths[H].Path;
953     static std::vector<HeaderHandle> Empty;
954     return Empty;
955   }
956 
957   // Add a macro expansion instance.
958   void addMacroExpansionInstance(clang::Preprocessor &PP, HeaderHandle H,
959                                  clang::SourceLocation InstanceLoc,
960                                  clang::SourceLocation DefinitionLoc,
961                                  clang::IdentifierInfo *II,
962                                  llvm::StringRef MacroUnexpanded,
963                                  llvm::StringRef MacroExpanded,
964                                  InclusionPathHandle InclusionPathHandle) {
965     StringHandle MacroName = addString(II->getName());
966     PPItemKey InstanceKey(PP, MacroName, H, InstanceLoc);
967     PPItemKey DefinitionKey(PP, MacroName, H, DefinitionLoc);
968     MacroExpansionMapIter I = MacroExpansions.find(InstanceKey);
969     // If existing instance of expansion not found, add one.
970     if (I == MacroExpansions.end()) {
971       std::string InstanceSourceLine =
972           getSourceLocationString(PP, InstanceLoc) + ":\n" +
973           getSourceLine(PP, InstanceLoc) + "\n";
974       std::string DefinitionSourceLine =
975           getSourceLocationString(PP, DefinitionLoc) + ":\n" +
976           getSourceLine(PP, DefinitionLoc) + "\n";
977       MacroExpansions[InstanceKey] = MacroExpansionTracker(
978           addString(MacroUnexpanded), addString(MacroExpanded),
979           addString(InstanceSourceLine), DefinitionKey,
980           addString(DefinitionSourceLine), InclusionPathHandle);
981     } else {
982       // We've seen the macro before.  Get its tracker.
983       MacroExpansionTracker &CondTracker = I->second;
984       // Look up an existing instance value for the macro.
985       MacroExpansionInstance *MacroInfo =
986           CondTracker.findMacroExpansionInstance(addString(MacroExpanded),
987                                                  DefinitionKey);
988       // If found, just add the inclusion path to the instance.
989       if (MacroInfo != NULL)
990         MacroInfo->addInclusionPathHandle(InclusionPathHandle);
991       else {
992         // Otherwise add a new instance with the unique value.
993         std::string DefinitionSourceLine =
994             getSourceLocationString(PP, DefinitionLoc) + ":\n" +
995             getSourceLine(PP, DefinitionLoc) + "\n";
996         CondTracker.addMacroExpansionInstance(
997             addString(MacroExpanded), DefinitionKey,
998             addString(DefinitionSourceLine), InclusionPathHandle);
999       }
1000     }
1001   }
1002 
1003   // Add a conditional expansion instance.
1004   void
1005   addConditionalExpansionInstance(clang::Preprocessor &PP, HeaderHandle H,
1006                                   clang::SourceLocation InstanceLoc,
1007                                   clang::tok::PPKeywordKind DirectiveKind,
1008                                   bool ConditionValue,
1009                                   llvm::StringRef ConditionUnexpanded,
1010                                   InclusionPathHandle InclusionPathHandle) {
1011     // Ignore header guards, assuming the header guard is the only conditional.
1012     if (InNestedHeader)
1013       return;
1014     StringHandle ConditionUnexpandedHandle(addString(ConditionUnexpanded));
1015     PPItemKey InstanceKey(PP, ConditionUnexpandedHandle, H, InstanceLoc);
1016     ConditionalExpansionMapIter I = ConditionalExpansions.find(InstanceKey);
1017     // If existing instance of condition not found, add one.
1018     if (I == ConditionalExpansions.end()) {
1019       std::string InstanceSourceLine =
1020           getSourceLocationString(PP, InstanceLoc) + ":\n" +
1021           getSourceLine(PP, InstanceLoc) + "\n";
1022       ConditionalExpansions[InstanceKey] =
1023           ConditionalTracker(DirectiveKind, ConditionValue,
1024                              ConditionUnexpandedHandle,
1025                              InclusionPathHandle);
1026     } else {
1027       // We've seen the conditional before.  Get its tracker.
1028       ConditionalTracker &CondTracker = I->second;
1029       // Look up an existing instance value for the condition.
1030       ConditionalExpansionInstance *MacroInfo =
1031           CondTracker.findConditionalExpansionInstance(ConditionValue);
1032       // If found, just add the inclusion path to the instance.
1033       if (MacroInfo != NULL)
1034         MacroInfo->addInclusionPathHandle(InclusionPathHandle);
1035       else {
1036         // Otherwise add a new instance with the unique value.
1037         CondTracker.addConditionalExpansionInstance(ConditionValue,
1038                                                     InclusionPathHandle);
1039       }
1040     }
1041   }
1042 
1043   // Report on inconsistent macro instances.
1044   // Returns true if any mismatches.
1045   bool reportInconsistentMacros(llvm::raw_ostream &OS) {
1046     bool ReturnValue = false;
1047     // Walk all the macro expansion trackers in the map.
1048     for (MacroExpansionMapIter I = MacroExpansions.begin(),
1049                                E = MacroExpansions.end();
1050          I != E; ++I) {
1051       const PPItemKey &ItemKey = I->first;
1052       MacroExpansionTracker &MacroExpTracker = I->second;
1053       // If no mismatch (only one instance value) continue.
1054       if (!MacroExpTracker.hasMismatch())
1055         continue;
1056       // Tell caller we found one or more errors.
1057       ReturnValue = true;
1058       // Start the error message.
1059       OS << *MacroExpTracker.InstanceSourceLine;
1060       if (ItemKey.Column > 0)
1061         OS << std::string(ItemKey.Column - 1, ' ') << "^\n";
1062       OS << "error: Macro instance '" << *MacroExpTracker.MacroUnexpanded
1063          << "' has different values in this header, depending on how it was "
1064             "included.\n";
1065       // Walk all the instances.
1066       for (std::vector<MacroExpansionInstance>::iterator
1067                IMT = MacroExpTracker.MacroExpansionInstances.begin(),
1068                EMT = MacroExpTracker.MacroExpansionInstances.end();
1069            IMT != EMT; ++IMT) {
1070         MacroExpansionInstance &MacroInfo = *IMT;
1071         OS << "  '" << *MacroExpTracker.MacroUnexpanded << "' expanded to: '"
1072            << *MacroInfo.MacroExpanded
1073            << "' with respect to these inclusion paths:\n";
1074         // Walk all the inclusion path hierarchies.
1075         for (std::vector<InclusionPathHandle>::iterator
1076                  IIP = MacroInfo.InclusionPathHandles.begin(),
1077                  EIP = MacroInfo.InclusionPathHandles.end();
1078              IIP != EIP; ++IIP) {
1079           const std::vector<HeaderHandle> &ip = getInclusionPath(*IIP);
1080           int Count = (int)ip.size();
1081           for (int Index = 0; Index < Count; ++Index) {
1082             HeaderHandle H = ip[Index];
1083             OS << std::string((Index * 2) + 4, ' ') << *getHeaderFilePath(H)
1084                << "\n";
1085           }
1086         }
1087         // For a macro that wasn't defined, we flag it by using the
1088         // instance location.
1089         // If there is a definition...
1090         if (MacroInfo.DefinitionLocation.Line != ItemKey.Line) {
1091           OS << *MacroInfo.DefinitionSourceLine;
1092           if (MacroInfo.DefinitionLocation.Column > 0)
1093             OS << std::string(MacroInfo.DefinitionLocation.Column - 1, ' ')
1094                << "^\n";
1095           OS << "Macro defined here.\n";
1096         } else
1097           OS << "(no macro definition)"
1098              << "\n";
1099       }
1100     }
1101     return ReturnValue;
1102   }
1103 
1104   // Report on inconsistent conditional instances.
1105   // Returns true if any mismatches.
1106   bool reportInconsistentConditionals(llvm::raw_ostream &OS) {
1107     bool ReturnValue = false;
1108     // Walk all the conditional trackers in the map.
1109     for (ConditionalExpansionMapIter I = ConditionalExpansions.begin(),
1110                                      E = ConditionalExpansions.end();
1111          I != E; ++I) {
1112       const PPItemKey &ItemKey = I->first;
1113       ConditionalTracker &CondTracker = I->second;
1114       if (!CondTracker.hasMismatch())
1115         continue;
1116       // Tell caller we found one or more errors.
1117       ReturnValue = true;
1118       // Start the error message.
1119       OS << *HeaderPaths[ItemKey.File] << ":" << ItemKey.Line << ":"
1120          << ItemKey.Column << "\n";
1121       OS << "#" << getDirectiveSpelling(CondTracker.DirectiveKind) << " "
1122          << *CondTracker.ConditionUnexpanded << "\n";
1123       OS << "^\n";
1124       OS << "error: Conditional expression instance '"
1125          << *CondTracker.ConditionUnexpanded
1126          << "' has different values in this header, depending on how it was "
1127             "included.\n";
1128       // Walk all the instances.
1129       for (std::vector<ConditionalExpansionInstance>::iterator
1130                IMT = CondTracker.ConditionalExpansionInstances.begin(),
1131                EMT = CondTracker.ConditionalExpansionInstances.end();
1132            IMT != EMT; ++IMT) {
1133         ConditionalExpansionInstance &MacroInfo = *IMT;
1134         OS << "  '" << *CondTracker.ConditionUnexpanded << "' expanded to: '"
1135            << (MacroInfo.ConditionValue ? "true" : "false")
1136            << "' with respect to these inclusion paths:\n";
1137         // Walk all the inclusion path hierarchies.
1138         for (std::vector<InclusionPathHandle>::iterator
1139                  IIP = MacroInfo.InclusionPathHandles.begin(),
1140                  EIP = MacroInfo.InclusionPathHandles.end();
1141              IIP != EIP; ++IIP) {
1142           const std::vector<HeaderHandle> &ip = getInclusionPath(*IIP);
1143           int Count = (int)ip.size();
1144           for (int Index = 0; Index < Count; ++Index) {
1145             HeaderHandle H = ip[Index];
1146             OS << std::string((Index * 2) + 4, ' ') << *getHeaderFilePath(H)
1147                << "\n";
1148           }
1149         }
1150       }
1151     }
1152     return ReturnValue;
1153   }
1154 
1155   // Get directive spelling.
1156   static const char *getDirectiveSpelling(clang::tok::PPKeywordKind kind) {
1157     switch (kind) {
1158     case clang::tok::pp_if:
1159       return "if";
1160     case clang::tok::pp_elif:
1161       return "elif";
1162     case clang::tok::pp_ifdef:
1163       return "ifdef";
1164     case clang::tok::pp_ifndef:
1165       return "ifndef";
1166     default:
1167       return "(unknown)";
1168     }
1169   }
1170 
1171 private:
1172   llvm::StringPool Strings;
1173   std::vector<StringHandle> HeaderPaths;
1174   std::vector<HeaderHandle> HeaderStack;
1175   std::vector<HeaderInclusionPath> InclusionPaths;
1176   InclusionPathHandle CurrentInclusionPathHandle;
1177   llvm::SmallSet<HeaderHandle, 128> HeadersInThisCompile;
1178   MacroExpansionMap MacroExpansions;
1179   ConditionalExpansionMap ConditionalExpansions;
1180   bool InNestedHeader;
1181 };
1182 
1183 // PreprocessorTracker functions.
1184 
1185 // PreprocessorTracker desctructor.
1186 PreprocessorTracker::~PreprocessorTracker() {}
1187 
1188 // Create instance of PreprocessorTracker.
1189 PreprocessorTracker *PreprocessorTracker::create() {
1190   return new PreprocessorTrackerImpl();
1191 }
1192 
1193 // Preprocessor callbacks for modularize.
1194 
1195 // Handle file entry/exit.
1196 void PreprocessorCallbacks::FileChanged(
1197     clang::SourceLocation Loc, clang::PPCallbacks::FileChangeReason Reason,
1198     clang::SrcMgr::CharacteristicKind FileType, clang::FileID PrevFID) {
1199   switch (Reason) {
1200   case EnterFile:
1201     PPTracker.handleHeaderEntry(PP, getSourceLocationFile(PP, Loc));
1202     break;
1203   case ExitFile:
1204     {
1205       const clang::FileEntry *F =
1206         PP.getSourceManager().getFileEntryForID(PrevFID);
1207       if (F != NULL)
1208         PPTracker.handleHeaderExit(F->getName());
1209     }
1210     break;
1211   case SystemHeaderPragma:
1212   case RenameFile:
1213     break;
1214   }
1215 }
1216 
1217 // Handle macro expansion.
1218 void PreprocessorCallbacks::MacroExpands(const clang::Token &MacroNameTok,
1219                                          const clang::MacroDirective *MD,
1220                                          clang::SourceRange Range,
1221                                          const clang::MacroArgs *Args) {
1222   clang::SourceLocation Loc = Range.getBegin();
1223   // Ignore macro argument expansions.
1224   if (!Loc.isFileID())
1225     return;
1226   clang::IdentifierInfo *II = MacroNameTok.getIdentifierInfo();
1227   const clang::MacroInfo *MI = PP.getMacroInfo(II);
1228   std::string MacroName = II->getName().str();
1229   std::string Unexpanded(getMacroUnexpandedString(Range, PP, MacroName, MI));
1230   std::string Expanded(getMacroExpandedString(PP, MacroName, MI, Args));
1231   PPTracker.addMacroExpansionInstance(
1232       PP, PPTracker.getCurrentHeaderHandle(), Loc, MI->getDefinitionLoc(), II,
1233       Unexpanded, Expanded, PPTracker.getCurrentInclusionPathHandle());
1234 }
1235 
1236 void PreprocessorCallbacks::Defined(const clang::Token &MacroNameTok,
1237                                     const clang::MacroDirective *MD,
1238                                     clang::SourceRange Range) {
1239   clang::SourceLocation Loc(Range.getBegin());
1240   clang::IdentifierInfo *II = MacroNameTok.getIdentifierInfo();
1241   const clang::MacroInfo *MI = PP.getMacroInfo(II);
1242   std::string MacroName = II->getName().str();
1243   std::string Unexpanded(getSourceString(PP, Range));
1244   PPTracker.addMacroExpansionInstance(
1245       PP, PPTracker.getCurrentHeaderHandle(), Loc,
1246       (MI ? MI->getDefinitionLoc() : Loc), II, Unexpanded,
1247       (MI ? "true" : "false"), PPTracker.getCurrentInclusionPathHandle());
1248 }
1249 
1250 void PreprocessorCallbacks::If(clang::SourceLocation Loc,
1251                                clang::SourceRange ConditionRange,
1252                                bool ConditionResult) {
1253   std::string Unexpanded(getSourceString(PP, ConditionRange));
1254   PPTracker.addConditionalExpansionInstance(
1255       PP, PPTracker.getCurrentHeaderHandle(), Loc, clang::tok::pp_if,
1256       ConditionResult, Unexpanded, PPTracker.getCurrentInclusionPathHandle());
1257 }
1258 
1259 void PreprocessorCallbacks::Elif(clang::SourceLocation Loc,
1260                                  clang::SourceRange ConditionRange,
1261                                  bool ConditionResult,
1262                                  clang::SourceLocation IfLoc) {
1263   std::string Unexpanded(getSourceString(PP, ConditionRange));
1264   PPTracker.addConditionalExpansionInstance(
1265       PP, PPTracker.getCurrentHeaderHandle(), Loc, clang::tok::pp_elif,
1266       ConditionResult, Unexpanded, PPTracker.getCurrentInclusionPathHandle());
1267 }
1268 
1269 void PreprocessorCallbacks::Ifdef(clang::SourceLocation Loc,
1270                                   const clang::Token &MacroNameTok,
1271                                   const clang::MacroDirective *MD) {
1272   bool IsDefined = (MD != 0);
1273   PPTracker.addConditionalExpansionInstance(
1274       PP, PPTracker.getCurrentHeaderHandle(), Loc, clang::tok::pp_ifdef,
1275       IsDefined, PP.getSpelling(MacroNameTok),
1276       PPTracker.getCurrentInclusionPathHandle());
1277 }
1278 
1279 void PreprocessorCallbacks::Ifndef(clang::SourceLocation Loc,
1280                                    const clang::Token &MacroNameTok,
1281                                    const clang::MacroDirective *MD) {
1282   bool IsNotDefined = (MD == 0);
1283   PPTracker.addConditionalExpansionInstance(
1284       PP, PPTracker.getCurrentHeaderHandle(), Loc, clang::tok::pp_ifndef,
1285       IsNotDefined, PP.getSpelling(MacroNameTok),
1286       PPTracker.getCurrentInclusionPathHandle());
1287 }
1288 } // end namespace Modularize
1289