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