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 #include "ModularizeUtilities.h"
255 
256 namespace Modularize {
257 
258 // Forwards.
259 class PreprocessorTrackerImpl;
260 
261 // Some handle types
262 typedef llvm::PooledStringPtr StringHandle;
263 
264 typedef int HeaderHandle;
265 const HeaderHandle HeaderHandleInvalid = -1;
266 
267 typedef int InclusionPathHandle;
268 const InclusionPathHandle InclusionPathHandleInvalid = -1;
269 
270 // Some utility functions.
271 
272 // Get a "file:line:column" source location string.
273 static std::string getSourceLocationString(clang::Preprocessor &PP,
274                                            clang::SourceLocation Loc) {
275   if (Loc.isInvalid())
276     return std::string("(none)");
277   else
278     return Loc.printToString(PP.getSourceManager());
279 }
280 
281 // Get just the file name from a source location.
282 static std::string getSourceLocationFile(clang::Preprocessor &PP,
283                                          clang::SourceLocation Loc) {
284   std::string Source(getSourceLocationString(PP, Loc));
285   size_t Offset = Source.find(':', 2);
286   if (Offset == std::string::npos)
287     return Source;
288   return Source.substr(0, Offset);
289 }
290 
291 // Get just the line and column from a source location.
292 static void getSourceLocationLineAndColumn(clang::Preprocessor &PP,
293                                            clang::SourceLocation Loc, int &Line,
294                                            int &Column) {
295   clang::PresumedLoc PLoc = PP.getSourceManager().getPresumedLoc(Loc);
296   if (PLoc.isInvalid()) {
297     Line = 0;
298     Column = 0;
299     return;
300   }
301   Line = PLoc.getLine();
302   Column = PLoc.getColumn();
303 }
304 
305 // Retrieve source snippet from file image.
306 std::string getSourceString(clang::Preprocessor &PP, clang::SourceRange Range) {
307   clang::SourceLocation BeginLoc = Range.getBegin();
308   clang::SourceLocation EndLoc = Range.getEnd();
309   const char *BeginPtr = PP.getSourceManager().getCharacterData(BeginLoc);
310   const char *EndPtr = PP.getSourceManager().getCharacterData(EndLoc);
311   size_t Length = EndPtr - BeginPtr;
312   return llvm::StringRef(BeginPtr, Length).trim().str();
313 }
314 
315 // Retrieve source line from file image given a location.
316 std::string getSourceLine(clang::Preprocessor &PP, clang::SourceLocation Loc) {
317   const llvm::MemoryBuffer *MemBuffer =
318       PP.getSourceManager().getBuffer(PP.getSourceManager().getFileID(Loc));
319   const char *Buffer = MemBuffer->getBufferStart();
320   const char *BufferEnd = MemBuffer->getBufferEnd();
321   const char *BeginPtr = PP.getSourceManager().getCharacterData(Loc);
322   const char *EndPtr = BeginPtr;
323   while (BeginPtr > Buffer) {
324     if (*BeginPtr == '\n') {
325       BeginPtr++;
326       break;
327     }
328     BeginPtr--;
329   }
330   while (EndPtr < BufferEnd) {
331     if (*EndPtr == '\n') {
332       break;
333     }
334     EndPtr++;
335   }
336   size_t Length = EndPtr - BeginPtr;
337   return llvm::StringRef(BeginPtr, Length).str();
338 }
339 
340 // Retrieve source line from file image given a file ID and line number.
341 std::string getSourceLine(clang::Preprocessor &PP, clang::FileID FileID,
342                           int Line) {
343   const llvm::MemoryBuffer *MemBuffer = PP.getSourceManager().getBuffer(FileID);
344   const char *Buffer = MemBuffer->getBufferStart();
345   const char *BufferEnd = MemBuffer->getBufferEnd();
346   const char *BeginPtr = Buffer;
347   const char *EndPtr = BufferEnd;
348   int LineCounter = 1;
349   if (Line == 1)
350     BeginPtr = Buffer;
351   else {
352     while (Buffer < BufferEnd) {
353       if (*Buffer == '\n') {
354         if (++LineCounter == Line) {
355           BeginPtr = Buffer++ + 1;
356           break;
357         }
358       }
359       Buffer++;
360     }
361   }
362   while (Buffer < BufferEnd) {
363     if (*Buffer == '\n') {
364       EndPtr = Buffer;
365       break;
366     }
367     Buffer++;
368   }
369   size_t Length = EndPtr - BeginPtr;
370   return llvm::StringRef(BeginPtr, Length).str();
371 }
372 
373 // Get the string for the Unexpanded macro instance.
374 // The soureRange is expected to end at the last token
375 // for the macro instance, which in the case of a function-style
376 // macro will be a ')', but for an object-style macro, it
377 // will be the macro name itself.
378 std::string getMacroUnexpandedString(clang::SourceRange Range,
379                                      clang::Preprocessor &PP,
380                                      llvm::StringRef MacroName,
381                                      const clang::MacroInfo *MI) {
382   clang::SourceLocation BeginLoc(Range.getBegin());
383   const char *BeginPtr = PP.getSourceManager().getCharacterData(BeginLoc);
384   size_t Length;
385   std::string Unexpanded;
386   if (MI->isFunctionLike()) {
387     clang::SourceLocation EndLoc(Range.getEnd());
388     const char *EndPtr = PP.getSourceManager().getCharacterData(EndLoc) + 1;
389     Length = (EndPtr - BeginPtr) + 1; // +1 is ')' width.
390   } else
391     Length = MacroName.size();
392   return llvm::StringRef(BeginPtr, Length).trim().str();
393 }
394 
395 // Get the expansion for a macro instance, given the information
396 // provided by PPCallbacks.
397 // FIXME: This doesn't support function-style macro instances
398 // passed as arguments to another function-style macro. However,
399 // since it still expands the inner arguments, it still
400 // allows modularize to effectively work with respect to macro
401 // consistency checking, although it displays the incorrect
402 // expansion in error messages.
403 std::string getMacroExpandedString(clang::Preprocessor &PP,
404                                    llvm::StringRef MacroName,
405                                    const clang::MacroInfo *MI,
406                                    const clang::MacroArgs *Args) {
407   std::string Expanded;
408   // Walk over the macro Tokens.
409   typedef clang::MacroInfo::tokens_iterator Iter;
410   for (Iter I = MI->tokens_begin(), E = MI->tokens_end(); I != E; ++I) {
411     clang::IdentifierInfo *II = I->getIdentifierInfo();
412     int ArgNo = (II && Args ? MI->getArgumentNum(II) : -1);
413     if (ArgNo == -1) {
414       // This isn't an argument, just add it.
415       if (II == nullptr)
416         Expanded += PP.getSpelling((*I)); // Not an identifier.
417       else {
418         // Token is for an identifier.
419         std::string Name = II->getName().str();
420         // Check for nexted macro references.
421         clang::MacroInfo *MacroInfo = PP.getMacroInfo(II);
422         if (MacroInfo)
423           Expanded += getMacroExpandedString(PP, Name, MacroInfo, nullptr);
424         else
425           Expanded += Name;
426       }
427       continue;
428     }
429     // We get here if it's a function-style macro with arguments.
430     const clang::Token *ResultArgToks;
431     const clang::Token *ArgTok = Args->getUnexpArgument(ArgNo);
432     if (Args->ArgNeedsPreexpansion(ArgTok, PP))
433       ResultArgToks = &(const_cast<clang::MacroArgs *>(Args))
434           ->getPreExpArgument(ArgNo, MI, PP)[0];
435     else
436       ResultArgToks = ArgTok; // Use non-preexpanded Tokens.
437     // If the arg token didn't expand into anything, ignore it.
438     if (ResultArgToks->is(clang::tok::eof))
439       continue;
440     unsigned NumToks = clang::MacroArgs::getArgLength(ResultArgToks);
441     // Append the resulting argument expansions.
442     for (unsigned ArgumentIndex = 0; ArgumentIndex < NumToks; ++ArgumentIndex) {
443       const clang::Token &AT = ResultArgToks[ArgumentIndex];
444       clang::IdentifierInfo *II = AT.getIdentifierInfo();
445       if (II == nullptr)
446         Expanded += PP.getSpelling(AT); // Not an identifier.
447       else {
448         // It's an identifier.  Check for further expansion.
449         std::string Name = II->getName().str();
450         clang::MacroInfo *MacroInfo = PP.getMacroInfo(II);
451         if (MacroInfo)
452           Expanded += getMacroExpandedString(PP, Name, MacroInfo, nullptr);
453         else
454           Expanded += Name;
455       }
456     }
457   }
458   return Expanded;
459 }
460 
461 // Get the string representing a vector of Tokens.
462 std::string
463 getTokensSpellingString(clang::Preprocessor &PP,
464                         llvm::SmallVectorImpl<clang::Token> &Tokens) {
465   std::string Expanded;
466   // Walk over the macro Tokens.
467   typedef llvm::SmallVectorImpl<clang::Token>::iterator Iter;
468   for (Iter I = Tokens.begin(), E = Tokens.end(); I != E; ++I)
469     Expanded += PP.getSpelling(*I); // Not an identifier.
470   return llvm::StringRef(Expanded).trim().str();
471 }
472 
473 // Get the expansion for a macro instance, given the information
474 // provided by PPCallbacks.
475 std::string getExpandedString(clang::Preprocessor &PP,
476                               llvm::StringRef MacroName,
477                               const clang::MacroInfo *MI,
478                               const clang::MacroArgs *Args) {
479   std::string Expanded;
480   // Walk over the macro Tokens.
481   typedef clang::MacroInfo::tokens_iterator Iter;
482   for (Iter I = MI->tokens_begin(), E = MI->tokens_end(); I != E; ++I) {
483     clang::IdentifierInfo *II = I->getIdentifierInfo();
484     int ArgNo = (II && Args ? MI->getArgumentNum(II) : -1);
485     if (ArgNo == -1) {
486       // This isn't an argument, just add it.
487       if (II == nullptr)
488         Expanded += PP.getSpelling((*I)); // Not an identifier.
489       else {
490         // Token is for an identifier.
491         std::string Name = II->getName().str();
492         // Check for nexted macro references.
493         clang::MacroInfo *MacroInfo = PP.getMacroInfo(II);
494         if (MacroInfo)
495           Expanded += getMacroExpandedString(PP, Name, MacroInfo, nullptr);
496         else
497           Expanded += Name;
498       }
499       continue;
500     }
501     // We get here if it's a function-style macro with arguments.
502     const clang::Token *ResultArgToks;
503     const clang::Token *ArgTok = Args->getUnexpArgument(ArgNo);
504     if (Args->ArgNeedsPreexpansion(ArgTok, PP))
505       ResultArgToks = &(const_cast<clang::MacroArgs *>(Args))
506           ->getPreExpArgument(ArgNo, MI, PP)[0];
507     else
508       ResultArgToks = ArgTok; // Use non-preexpanded Tokens.
509     // If the arg token didn't expand into anything, ignore it.
510     if (ResultArgToks->is(clang::tok::eof))
511       continue;
512     unsigned NumToks = clang::MacroArgs::getArgLength(ResultArgToks);
513     // Append the resulting argument expansions.
514     for (unsigned ArgumentIndex = 0; ArgumentIndex < NumToks; ++ArgumentIndex) {
515       const clang::Token &AT = ResultArgToks[ArgumentIndex];
516       clang::IdentifierInfo *II = AT.getIdentifierInfo();
517       if (II == nullptr)
518         Expanded += PP.getSpelling(AT); // Not an identifier.
519       else {
520         // It's an identifier.  Check for further expansion.
521         std::string Name = II->getName().str();
522         clang::MacroInfo *MacroInfo = PP.getMacroInfo(II);
523         if (MacroInfo)
524           Expanded += getMacroExpandedString(PP, Name, MacroInfo, nullptr);
525         else
526           Expanded += Name;
527       }
528     }
529   }
530   return Expanded;
531 }
532 
533 // ConditionValueKind strings.
534 const char *
535 ConditionValueKindStrings[] = {
536   "(not evaluated)", "false", "true"
537 };
538 
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 
552 // Preprocessor item key.
553 //
554 // This class represents a location in a source file, for use
555 // as a key representing a unique name/file/line/column quadruplet,
556 // which in this case is used to identify a macro expansion instance,
557 // but could be used for other things as well.
558 // The file is a header file handle, the line is a line number,
559 // and the column is a column number.
560 class PPItemKey {
561 public:
562   PPItemKey(clang::Preprocessor &PP, StringHandle Name, HeaderHandle File,
563             clang::SourceLocation Loc)
564       : Name(Name), File(File) {
565     getSourceLocationLineAndColumn(PP, Loc, Line, Column);
566   }
567   PPItemKey(StringHandle Name, HeaderHandle File, int Line, int Column)
568       : Name(Name), File(File), Line(Line), Column(Column) {}
569   PPItemKey(const PPItemKey &Other)
570       : Name(Other.Name), File(Other.File), Line(Other.Line),
571         Column(Other.Column) {}
572   PPItemKey() : File(HeaderHandleInvalid), Line(0), Column(0) {}
573   bool operator==(const PPItemKey &Other) const {
574     if (Name != Other.Name)
575       return false;
576     if (File != Other.File)
577       return false;
578     if (Line != Other.Line)
579       return false;
580     return Column == Other.Column;
581   }
582   bool operator<(const PPItemKey &Other) const {
583     if (Name < Other.Name)
584       return true;
585     else if (Name > Other.Name)
586       return false;
587     if (File < Other.File)
588       return true;
589     else if (File > Other.File)
590       return false;
591     if (Line < Other.Line)
592       return true;
593     else if (Line > Other.Line)
594       return false;
595     return Column < Other.Column;
596   }
597   StringHandle Name;
598   HeaderHandle File;
599   int Line;
600   int Column;
601 };
602 
603 // Header inclusion path.
604 class HeaderInclusionPath {
605 public:
606   HeaderInclusionPath(std::vector<HeaderHandle> HeaderInclusionPath)
607       : Path(HeaderInclusionPath) {}
608   HeaderInclusionPath(const HeaderInclusionPath &Other) : Path(Other.Path) {}
609   HeaderInclusionPath() {}
610   std::vector<HeaderHandle> Path;
611 };
612 
613 // Macro expansion instance.
614 //
615 // This class represents an instance of a macro expansion with a
616 // unique value.  It also stores the unique header inclusion paths
617 // for use in telling the user the nested include path to the header.
618 class MacroExpansionInstance {
619 public:
620   MacroExpansionInstance(StringHandle MacroExpanded,
621                          PPItemKey &DefinitionLocation,
622                          StringHandle DefinitionSourceLine,
623                          InclusionPathHandle H)
624       : MacroExpanded(MacroExpanded), DefinitionLocation(DefinitionLocation),
625         DefinitionSourceLine(DefinitionSourceLine) {
626     InclusionPathHandles.push_back(H);
627   }
628   MacroExpansionInstance() {}
629 
630   // Check for the presence of a header inclusion path handle entry.
631   // Return false if not found.
632   bool haveInclusionPathHandle(InclusionPathHandle H) {
633     for (std::vector<InclusionPathHandle>::iterator
634              I = InclusionPathHandles.begin(),
635              E = InclusionPathHandles.end();
636          I != E; ++I) {
637       if (*I == H)
638         return true;
639     }
640     return InclusionPathHandleInvalid;
641   }
642   // Add a new header inclusion path entry, if not already present.
643   void addInclusionPathHandle(InclusionPathHandle H) {
644     if (!haveInclusionPathHandle(H))
645       InclusionPathHandles.push_back(H);
646   }
647 
648   // A string representing the macro instance after preprocessing.
649   StringHandle MacroExpanded;
650   // A file/line/column triplet representing the macro definition location.
651   PPItemKey DefinitionLocation;
652   // A place to save the macro definition line string.
653   StringHandle DefinitionSourceLine;
654   // The header inclusion path handles for all the instances.
655   std::vector<InclusionPathHandle> InclusionPathHandles;
656 };
657 
658 // Macro expansion instance tracker.
659 //
660 // This class represents one macro expansion, keyed by a PPItemKey.
661 // It stores a string representing the macro reference in the source,
662 // and a list of ConditionalExpansionInstances objects representing
663 // the unique values the condition expands to in instances of the header.
664 class MacroExpansionTracker {
665 public:
666   MacroExpansionTracker(StringHandle MacroUnexpanded,
667                         StringHandle MacroExpanded,
668                         StringHandle InstanceSourceLine,
669                         PPItemKey &DefinitionLocation,
670                         StringHandle DefinitionSourceLine,
671                         InclusionPathHandle InclusionPathHandle)
672       : MacroUnexpanded(MacroUnexpanded),
673         InstanceSourceLine(InstanceSourceLine) {
674     addMacroExpansionInstance(MacroExpanded, DefinitionLocation,
675                               DefinitionSourceLine, InclusionPathHandle);
676   }
677   MacroExpansionTracker() {}
678 
679   // Find a matching macro expansion instance.
680   MacroExpansionInstance *
681   findMacroExpansionInstance(StringHandle MacroExpanded,
682                              PPItemKey &DefinitionLocation) {
683     for (std::vector<MacroExpansionInstance>::iterator
684              I = MacroExpansionInstances.begin(),
685              E = MacroExpansionInstances.end();
686          I != E; ++I) {
687       if ((I->MacroExpanded == MacroExpanded) &&
688           (I->DefinitionLocation == DefinitionLocation)) {
689         return &*I; // Found.
690       }
691     }
692     return nullptr; // Not found.
693   }
694 
695   // Add a macro expansion instance.
696   void addMacroExpansionInstance(StringHandle MacroExpanded,
697                                  PPItemKey &DefinitionLocation,
698                                  StringHandle DefinitionSourceLine,
699                                  InclusionPathHandle InclusionPathHandle) {
700     MacroExpansionInstances.push_back(
701         MacroExpansionInstance(MacroExpanded, DefinitionLocation,
702                                DefinitionSourceLine, InclusionPathHandle));
703   }
704 
705   // Return true if there is a mismatch.
706   bool hasMismatch() { return MacroExpansionInstances.size() > 1; }
707 
708   // A string representing the macro instance without expansion.
709   StringHandle MacroUnexpanded;
710   // A place to save the macro instance source line string.
711   StringHandle InstanceSourceLine;
712   // The macro expansion instances.
713   // If all instances of the macro expansion expand to the same value,
714   // This vector will only have one instance.
715   std::vector<MacroExpansionInstance> MacroExpansionInstances;
716 };
717 
718 // Conditional expansion instance.
719 //
720 // This class represents an instance of a condition exoression result
721 // with a unique value.  It also stores the unique header inclusion paths
722 // for use in telling the user the nested include path to the header.
723 class ConditionalExpansionInstance {
724 public:
725   ConditionalExpansionInstance(clang::PPCallbacks::ConditionValueKind ConditionValue, InclusionPathHandle H)
726       : ConditionValue(ConditionValue) {
727     InclusionPathHandles.push_back(H);
728   }
729   ConditionalExpansionInstance() {}
730 
731   // Check for the presence of a header inclusion path handle entry.
732   // Return false if not found.
733   bool haveInclusionPathHandle(InclusionPathHandle H) {
734     for (std::vector<InclusionPathHandle>::iterator
735              I = InclusionPathHandles.begin(),
736              E = InclusionPathHandles.end();
737          I != E; ++I) {
738       if (*I == H)
739         return true;
740     }
741     return InclusionPathHandleInvalid;
742   }
743   // Add a new header inclusion path entry, if not already present.
744   void addInclusionPathHandle(InclusionPathHandle H) {
745     if (!haveInclusionPathHandle(H))
746       InclusionPathHandles.push_back(H);
747   }
748 
749   // A flag representing the evaluated condition value.
750   clang::PPCallbacks::ConditionValueKind ConditionValue;
751   // The header inclusion path handles for all the instances.
752   std::vector<InclusionPathHandle> InclusionPathHandles;
753 };
754 
755 // Conditional directive instance tracker.
756 //
757 // This class represents one conditional directive, keyed by a PPItemKey.
758 // It stores a string representing the macro reference in the source,
759 // and a list of ConditionExpansionInstance objects representing
760 // the unique value the condition expression expands to in instances of
761 // the header.
762 class ConditionalTracker {
763 public:
764   ConditionalTracker(clang::tok::PPKeywordKind DirectiveKind,
765                      clang::PPCallbacks::ConditionValueKind ConditionValue,
766                      StringHandle ConditionUnexpanded,
767                      InclusionPathHandle InclusionPathHandle)
768       : DirectiveKind(DirectiveKind), ConditionUnexpanded(ConditionUnexpanded) {
769     addConditionalExpansionInstance(ConditionValue, InclusionPathHandle);
770   }
771   ConditionalTracker() {}
772 
773   // Find a matching condition expansion instance.
774   ConditionalExpansionInstance *
775   findConditionalExpansionInstance(clang::PPCallbacks::ConditionValueKind ConditionValue) {
776     for (std::vector<ConditionalExpansionInstance>::iterator
777              I = ConditionalExpansionInstances.begin(),
778              E = ConditionalExpansionInstances.end();
779          I != E; ++I) {
780       if (I->ConditionValue == ConditionValue) {
781         return &*I; // Found.
782       }
783     }
784     return nullptr; // Not found.
785   }
786 
787   // Add a conditional expansion instance.
788   void
789   addConditionalExpansionInstance(clang::PPCallbacks::ConditionValueKind ConditionValue,
790                                   InclusionPathHandle InclusionPathHandle) {
791     ConditionalExpansionInstances.push_back(
792         ConditionalExpansionInstance(ConditionValue, InclusionPathHandle));
793   }
794 
795   // Return true if there is a mismatch.
796   bool hasMismatch() { return ConditionalExpansionInstances.size() > 1; }
797 
798   // The kind of directive.
799   clang::tok::PPKeywordKind DirectiveKind;
800   // A string representing the macro instance without expansion.
801   StringHandle ConditionUnexpanded;
802   // The condition expansion instances.
803   // If all instances of the conditional expression expand to the same value,
804   // This vector will only have one instance.
805   std::vector<ConditionalExpansionInstance> ConditionalExpansionInstances;
806 };
807 
808 // Preprocessor callbacks for modularize.
809 //
810 // This class derives from the Clang PPCallbacks class to track preprocessor
811 // actions, such as changing files and handling preprocessor directives and
812 // macro expansions.  It has to figure out when a new header file is entered
813 // and left, as the provided handler is not particularly clear about it.
814 class PreprocessorCallbacks : public clang::PPCallbacks {
815 public:
816   PreprocessorCallbacks(PreprocessorTrackerImpl &ppTracker,
817                         clang::Preprocessor &PP, llvm::StringRef rootHeaderFile)
818       : PPTracker(ppTracker), PP(PP), RootHeaderFile(rootHeaderFile) {}
819   ~PreprocessorCallbacks() {}
820 
821   // Overridden handlers.
822   void InclusionDirective(clang::SourceLocation HashLoc,
823                           const clang::Token &IncludeTok,
824                           llvm::StringRef FileName, bool IsAngled,
825                           clang::CharSourceRange FilenameRange,
826                           const clang::FileEntry *File,
827                           llvm::StringRef SearchPath,
828                           llvm::StringRef RelativePath,
829                           const clang::Module *Imported);
830   void FileChanged(clang::SourceLocation Loc,
831                    clang::PPCallbacks::FileChangeReason Reason,
832                    clang::SrcMgr::CharacteristicKind FileType,
833                    clang::FileID PrevFID = clang::FileID());
834   void MacroExpands(const clang::Token &MacroNameTok,
835                     const clang::MacroDirective *MD, clang::SourceRange Range,
836                     const clang::MacroArgs *Args);
837   void Defined(const clang::Token &MacroNameTok,
838                const clang::MacroDirective *MD, clang::SourceRange Range);
839   void If(clang::SourceLocation Loc, clang::SourceRange ConditionRange,
840           clang::PPCallbacks::ConditionValueKind ConditionResult);
841   void Elif(clang::SourceLocation Loc, clang::SourceRange ConditionRange,
842             clang::PPCallbacks::ConditionValueKind ConditionResult, clang::SourceLocation IfLoc);
843   void Ifdef(clang::SourceLocation Loc, const clang::Token &MacroNameTok,
844              const clang::MacroDirective *MD);
845   void Ifndef(clang::SourceLocation Loc, const clang::Token &MacroNameTok,
846               const clang::MacroDirective *MD);
847 
848 private:
849   PreprocessorTrackerImpl &PPTracker;
850   clang::Preprocessor &PP;
851   std::string RootHeaderFile;
852 };
853 
854 // Preprocessor macro expansion item map types.
855 typedef std::map<PPItemKey, MacroExpansionTracker> MacroExpansionMap;
856 typedef std::map<PPItemKey, MacroExpansionTracker>::iterator
857 MacroExpansionMapIter;
858 
859 // Preprocessor conditional expansion item map types.
860 typedef std::map<PPItemKey, ConditionalTracker> ConditionalExpansionMap;
861 typedef std::map<PPItemKey, ConditionalTracker>::iterator
862 ConditionalExpansionMapIter;
863 
864 // Preprocessor tracker for modularize.
865 //
866 // This class stores information about all the headers processed in the
867 // course of running modularize.
868 class PreprocessorTrackerImpl : public PreprocessorTracker {
869 public:
870   PreprocessorTrackerImpl(llvm::SmallVector<std::string, 32> &Headers,
871         bool DoBlockCheckHeaderListOnly)
872       : BlockCheckHeaderListOnly(DoBlockCheckHeaderListOnly),
873         CurrentInclusionPathHandle(InclusionPathHandleInvalid),
874         InNestedHeader(false) {
875     // Use canonical header path representation.
876     for (llvm::ArrayRef<std::string>::iterator I = Headers.begin(),
877       E = Headers.end();
878       I != E; ++I) {
879       HeaderList.push_back(getCanonicalPath(*I));
880     }
881   }
882 
883   ~PreprocessorTrackerImpl() {}
884 
885   // Handle entering a preprocessing session.
886   void handlePreprocessorEntry(clang::Preprocessor &PP,
887                                llvm::StringRef rootHeaderFile) {
888     HeadersInThisCompile.clear();
889     assert((HeaderStack.size() == 0) && "Header stack should be empty.");
890     pushHeaderHandle(addHeader(rootHeaderFile));
891     PP.addPPCallbacks(llvm::make_unique<PreprocessorCallbacks>(*this, PP,
892                                                                rootHeaderFile));
893   }
894   // Handle exiting a preprocessing session.
895   void handlePreprocessorExit() { HeaderStack.clear(); }
896 
897   // Handle include directive.
898   // This function is called every time an include directive is seen by the
899   // preprocessor, for the purpose of later checking for 'extern "" {}' or
900   // "namespace {}" blocks containing #include directives.
901   void handleIncludeDirective(llvm::StringRef DirectivePath, int DirectiveLine,
902                               int DirectiveColumn, llvm::StringRef TargetPath) {
903     // If it's not a header in the header list, ignore it with respect to
904     // the check.
905     if (BlockCheckHeaderListOnly && !isHeaderListHeader(TargetPath))
906       return;
907     HeaderHandle CurrentHeaderHandle = findHeaderHandle(DirectivePath);
908     StringHandle IncludeHeaderHandle = addString(TargetPath);
909     for (std::vector<PPItemKey>::const_iterator I = IncludeDirectives.begin(),
910                                                 E = IncludeDirectives.end();
911          I != E; ++I) {
912       // If we already have an entry for this directive, return now.
913       if ((I->File == CurrentHeaderHandle) && (I->Line == DirectiveLine))
914         return;
915     }
916     PPItemKey IncludeDirectiveItem(IncludeHeaderHandle, CurrentHeaderHandle,
917                                    DirectiveLine, DirectiveColumn);
918     IncludeDirectives.push_back(IncludeDirectiveItem);
919   }
920 
921   // Check for include directives within the given source line range.
922   // Report errors if any found.  Returns true if no include directives
923   // found in block.
924   bool checkForIncludesInBlock(clang::Preprocessor &PP,
925                                clang::SourceRange BlockSourceRange,
926                                const char *BlockIdentifierMessage,
927                                llvm::raw_ostream &OS) {
928     clang::SourceLocation BlockStartLoc = BlockSourceRange.getBegin();
929     clang::SourceLocation BlockEndLoc = BlockSourceRange.getEnd();
930     // Use block location to get FileID of both the include directive
931     // and block statement.
932     clang::FileID FileID = PP.getSourceManager().getFileID(BlockStartLoc);
933     std::string SourcePath = getSourceLocationFile(PP, BlockStartLoc);
934     SourcePath = ModularizeUtilities::getCanonicalPath(SourcePath);
935     HeaderHandle SourceHandle = findHeaderHandle(SourcePath);
936     if (SourceHandle == -1)
937       return true;
938     int BlockStartLine, BlockStartColumn, BlockEndLine, BlockEndColumn;
939     bool returnValue = true;
940     getSourceLocationLineAndColumn(PP, BlockStartLoc, BlockStartLine,
941                                    BlockStartColumn);
942     getSourceLocationLineAndColumn(PP, BlockEndLoc, BlockEndLine,
943                                    BlockEndColumn);
944     for (std::vector<PPItemKey>::const_iterator I = IncludeDirectives.begin(),
945                                                 E = IncludeDirectives.end();
946          I != E; ++I) {
947       // If we find an entry within the block, report an error.
948       if ((I->File == SourceHandle) && (I->Line >= BlockStartLine) &&
949           (I->Line < BlockEndLine)) {
950         returnValue = false;
951         OS << SourcePath << ":" << I->Line << ":" << I->Column << ":\n";
952         OS << getSourceLine(PP, FileID, I->Line) << "\n";
953         if (I->Column > 0)
954           OS << std::string(I->Column - 1, ' ') << "^\n";
955         OS << "error: Include directive within " << BlockIdentifierMessage
956            << ".\n";
957         OS << SourcePath << ":" << BlockStartLine << ":" << BlockStartColumn
958            << ":\n";
959         OS << getSourceLine(PP, BlockStartLoc) << "\n";
960         if (BlockStartColumn > 0)
961           OS << std::string(BlockStartColumn - 1, ' ') << "^\n";
962         OS << "The \"" << BlockIdentifierMessage << "\" block is here.\n";
963       }
964     }
965     return returnValue;
966   }
967 
968   // Handle entering a header source file.
969   void handleHeaderEntry(clang::Preprocessor &PP, llvm::StringRef HeaderPath) {
970     // Ignore <built-in> and <command-line> to reduce message clutter.
971     if (HeaderPath.startswith("<"))
972       return;
973     HeaderHandle H = addHeader(HeaderPath);
974     if (H != getCurrentHeaderHandle())
975       pushHeaderHandle(H);
976     // Check for nested header.
977     if (!InNestedHeader)
978       InNestedHeader = !HeadersInThisCompile.insert(H).second;
979   }
980 
981   // Handle exiting a header source file.
982   void handleHeaderExit(llvm::StringRef HeaderPath) {
983     // Ignore <built-in> and <command-line> to reduce message clutter.
984     if (HeaderPath.startswith("<"))
985       return;
986     HeaderHandle H = findHeaderHandle(HeaderPath);
987     HeaderHandle TH;
988     if (isHeaderHandleInStack(H)) {
989       do {
990         TH = getCurrentHeaderHandle();
991         popHeaderHandle();
992       } while ((TH != H) && (HeaderStack.size() != 0));
993     }
994     InNestedHeader = false;
995   }
996 
997   // Lookup/add string.
998   StringHandle addString(llvm::StringRef Str) { return Strings.intern(Str); }
999 
1000   // Convert to a canonical path.
1001   std::string getCanonicalPath(llvm::StringRef path) const {
1002     std::string CanonicalPath(path);
1003     std::replace(CanonicalPath.begin(), CanonicalPath.end(), '\\', '/');
1004     return CanonicalPath;
1005   }
1006 
1007   // Return true if the given header is in the header list.
1008   bool isHeaderListHeader(llvm::StringRef HeaderPath) const {
1009     std::string CanonicalPath = getCanonicalPath(HeaderPath);
1010     for (llvm::ArrayRef<std::string>::iterator I = HeaderList.begin(),
1011         E = HeaderList.end();
1012         I != E; ++I) {
1013       if (*I == CanonicalPath)
1014         return true;
1015     }
1016     return false;
1017   }
1018 
1019   // Get the handle of a header file entry.
1020   // Return HeaderHandleInvalid if not found.
1021   HeaderHandle findHeaderHandle(llvm::StringRef HeaderPath) const {
1022     std::string CanonicalPath = getCanonicalPath(HeaderPath);
1023     HeaderHandle H = 0;
1024     for (std::vector<StringHandle>::const_iterator I = HeaderPaths.begin(),
1025                                                    E = HeaderPaths.end();
1026          I != E; ++I, ++H) {
1027       if (**I == CanonicalPath)
1028         return H;
1029     }
1030     return HeaderHandleInvalid;
1031   }
1032 
1033   // Add a new header file entry, or return existing handle.
1034   // Return the header handle.
1035   HeaderHandle addHeader(llvm::StringRef HeaderPath) {
1036     std::string CanonicalPath = getCanonicalPath(HeaderPath);
1037     HeaderHandle H = findHeaderHandle(CanonicalPath);
1038     if (H == HeaderHandleInvalid) {
1039       H = HeaderPaths.size();
1040       HeaderPaths.push_back(addString(CanonicalPath));
1041     }
1042     return H;
1043   }
1044 
1045   // Return a header file path string given its handle.
1046   StringHandle getHeaderFilePath(HeaderHandle H) const {
1047     if ((H >= 0) && (H < (HeaderHandle)HeaderPaths.size()))
1048       return HeaderPaths[H];
1049     return StringHandle();
1050   }
1051 
1052   // Returns a handle to the inclusion path.
1053   InclusionPathHandle pushHeaderHandle(HeaderHandle H) {
1054     HeaderStack.push_back(H);
1055     return CurrentInclusionPathHandle = addInclusionPathHandle(HeaderStack);
1056   }
1057   // Pops the last header handle from the stack;
1058   void popHeaderHandle() {
1059     // assert((HeaderStack.size() != 0) && "Header stack already empty.");
1060     if (HeaderStack.size() != 0) {
1061       HeaderStack.pop_back();
1062       CurrentInclusionPathHandle = addInclusionPathHandle(HeaderStack);
1063     }
1064   }
1065   // Get the top handle on the header stack.
1066   HeaderHandle getCurrentHeaderHandle() const {
1067     if (HeaderStack.size() != 0)
1068       return HeaderStack.back();
1069     return HeaderHandleInvalid;
1070   }
1071 
1072   // Check for presence of header handle in the header stack.
1073   bool isHeaderHandleInStack(HeaderHandle H) const {
1074     for (std::vector<HeaderHandle>::const_iterator I = HeaderStack.begin(),
1075                                                    E = HeaderStack.end();
1076          I != E; ++I) {
1077       if (*I == H)
1078         return true;
1079     }
1080     return false;
1081   }
1082 
1083   // Get the handle of a header inclusion path entry.
1084   // Return InclusionPathHandleInvalid if not found.
1085   InclusionPathHandle
1086   findInclusionPathHandle(const std::vector<HeaderHandle> &Path) const {
1087     InclusionPathHandle H = 0;
1088     for (std::vector<HeaderInclusionPath>::const_iterator
1089              I = InclusionPaths.begin(),
1090              E = InclusionPaths.end();
1091          I != E; ++I, ++H) {
1092       if (I->Path == Path)
1093         return H;
1094     }
1095     return HeaderHandleInvalid;
1096   }
1097   // Add a new header inclusion path entry, or return existing handle.
1098   // Return the header inclusion path entry handle.
1099   InclusionPathHandle
1100   addInclusionPathHandle(const std::vector<HeaderHandle> &Path) {
1101     InclusionPathHandle H = findInclusionPathHandle(Path);
1102     if (H == HeaderHandleInvalid) {
1103       H = InclusionPaths.size();
1104       InclusionPaths.push_back(HeaderInclusionPath(Path));
1105     }
1106     return H;
1107   }
1108   // Return the current inclusion path handle.
1109   InclusionPathHandle getCurrentInclusionPathHandle() const {
1110     return CurrentInclusionPathHandle;
1111   }
1112 
1113   // Return an inclusion path given its handle.
1114   const std::vector<HeaderHandle> &
1115   getInclusionPath(InclusionPathHandle H) const {
1116     if ((H >= 0) && (H <= (InclusionPathHandle)InclusionPaths.size()))
1117       return InclusionPaths[H].Path;
1118     static std::vector<HeaderHandle> Empty;
1119     return Empty;
1120   }
1121 
1122   // Add a macro expansion instance.
1123   void addMacroExpansionInstance(clang::Preprocessor &PP, HeaderHandle H,
1124                                  clang::SourceLocation InstanceLoc,
1125                                  clang::SourceLocation DefinitionLoc,
1126                                  clang::IdentifierInfo *II,
1127                                  llvm::StringRef MacroUnexpanded,
1128                                  llvm::StringRef MacroExpanded,
1129                                  InclusionPathHandle InclusionPathHandle) {
1130     if (InNestedHeader)
1131       return;
1132     StringHandle MacroName = addString(II->getName());
1133     PPItemKey InstanceKey(PP, MacroName, H, InstanceLoc);
1134     PPItemKey DefinitionKey(PP, MacroName, H, DefinitionLoc);
1135     MacroExpansionMapIter I = MacroExpansions.find(InstanceKey);
1136     // If existing instance of expansion not found, add one.
1137     if (I == MacroExpansions.end()) {
1138       std::string InstanceSourceLine =
1139           getSourceLocationString(PP, InstanceLoc) + ":\n" +
1140           getSourceLine(PP, InstanceLoc) + "\n";
1141       std::string DefinitionSourceLine =
1142           getSourceLocationString(PP, DefinitionLoc) + ":\n" +
1143           getSourceLine(PP, DefinitionLoc) + "\n";
1144       MacroExpansions[InstanceKey] = MacroExpansionTracker(
1145           addString(MacroUnexpanded), addString(MacroExpanded),
1146           addString(InstanceSourceLine), DefinitionKey,
1147           addString(DefinitionSourceLine), InclusionPathHandle);
1148     } else {
1149       // We've seen the macro before.  Get its tracker.
1150       MacroExpansionTracker &CondTracker = I->second;
1151       // Look up an existing instance value for the macro.
1152       MacroExpansionInstance *MacroInfo =
1153           CondTracker.findMacroExpansionInstance(addString(MacroExpanded),
1154                                                  DefinitionKey);
1155       // If found, just add the inclusion path to the instance.
1156       if (MacroInfo)
1157         MacroInfo->addInclusionPathHandle(InclusionPathHandle);
1158       else {
1159         // Otherwise add a new instance with the unique value.
1160         std::string DefinitionSourceLine =
1161             getSourceLocationString(PP, DefinitionLoc) + ":\n" +
1162             getSourceLine(PP, DefinitionLoc) + "\n";
1163         CondTracker.addMacroExpansionInstance(
1164             addString(MacroExpanded), DefinitionKey,
1165             addString(DefinitionSourceLine), InclusionPathHandle);
1166       }
1167     }
1168   }
1169 
1170   // Add a conditional expansion instance.
1171   void
1172   addConditionalExpansionInstance(clang::Preprocessor &PP, HeaderHandle H,
1173                                   clang::SourceLocation InstanceLoc,
1174                                   clang::tok::PPKeywordKind DirectiveKind,
1175                                   clang::PPCallbacks::ConditionValueKind ConditionValue,
1176                                   llvm::StringRef ConditionUnexpanded,
1177                                   InclusionPathHandle InclusionPathHandle) {
1178     // Ignore header guards, assuming the header guard is the only conditional.
1179     if (InNestedHeader)
1180       return;
1181     StringHandle ConditionUnexpandedHandle(addString(ConditionUnexpanded));
1182     PPItemKey InstanceKey(PP, ConditionUnexpandedHandle, H, InstanceLoc);
1183     ConditionalExpansionMapIter I = ConditionalExpansions.find(InstanceKey);
1184     // If existing instance of condition not found, add one.
1185     if (I == ConditionalExpansions.end()) {
1186       std::string InstanceSourceLine =
1187           getSourceLocationString(PP, InstanceLoc) + ":\n" +
1188           getSourceLine(PP, InstanceLoc) + "\n";
1189       ConditionalExpansions[InstanceKey] =
1190           ConditionalTracker(DirectiveKind, ConditionValue,
1191                              ConditionUnexpandedHandle, InclusionPathHandle);
1192     } else {
1193       // We've seen the conditional before.  Get its tracker.
1194       ConditionalTracker &CondTracker = I->second;
1195       // Look up an existing instance value for the condition.
1196       ConditionalExpansionInstance *MacroInfo =
1197           CondTracker.findConditionalExpansionInstance(ConditionValue);
1198       // If found, just add the inclusion path to the instance.
1199       if (MacroInfo)
1200         MacroInfo->addInclusionPathHandle(InclusionPathHandle);
1201       else {
1202         // Otherwise add a new instance with the unique value.
1203         CondTracker.addConditionalExpansionInstance(ConditionValue,
1204                                                     InclusionPathHandle);
1205       }
1206     }
1207   }
1208 
1209   // Report on inconsistent macro instances.
1210   // Returns true if any mismatches.
1211   bool reportInconsistentMacros(llvm::raw_ostream &OS) {
1212     bool ReturnValue = false;
1213     // Walk all the macro expansion trackers in the map.
1214     for (MacroExpansionMapIter I = MacroExpansions.begin(),
1215                                E = MacroExpansions.end();
1216          I != E; ++I) {
1217       const PPItemKey &ItemKey = I->first;
1218       MacroExpansionTracker &MacroExpTracker = I->second;
1219       // If no mismatch (only one instance value) continue.
1220       if (!MacroExpTracker.hasMismatch())
1221         continue;
1222       // Tell caller we found one or more errors.
1223       ReturnValue = true;
1224       // Start the error message.
1225       OS << *MacroExpTracker.InstanceSourceLine;
1226       if (ItemKey.Column > 0)
1227         OS << std::string(ItemKey.Column - 1, ' ') << "^\n";
1228       OS << "error: Macro instance '" << *MacroExpTracker.MacroUnexpanded
1229          << "' has different values in this header, depending on how it was "
1230             "included.\n";
1231       // Walk all the instances.
1232       for (std::vector<MacroExpansionInstance>::iterator
1233                IMT = MacroExpTracker.MacroExpansionInstances.begin(),
1234                EMT = MacroExpTracker.MacroExpansionInstances.end();
1235            IMT != EMT; ++IMT) {
1236         MacroExpansionInstance &MacroInfo = *IMT;
1237         OS << "  '" << *MacroExpTracker.MacroUnexpanded << "' expanded to: '"
1238            << *MacroInfo.MacroExpanded
1239            << "' with respect to these inclusion paths:\n";
1240         // Walk all the inclusion path hierarchies.
1241         for (std::vector<InclusionPathHandle>::iterator
1242                  IIP = MacroInfo.InclusionPathHandles.begin(),
1243                  EIP = MacroInfo.InclusionPathHandles.end();
1244              IIP != EIP; ++IIP) {
1245           const std::vector<HeaderHandle> &ip = getInclusionPath(*IIP);
1246           int Count = (int)ip.size();
1247           for (int Index = 0; Index < Count; ++Index) {
1248             HeaderHandle H = ip[Index];
1249             OS << std::string((Index * 2) + 4, ' ') << *getHeaderFilePath(H)
1250                << "\n";
1251           }
1252         }
1253         // For a macro that wasn't defined, we flag it by using the
1254         // instance location.
1255         // If there is a definition...
1256         if (MacroInfo.DefinitionLocation.Line != ItemKey.Line) {
1257           OS << *MacroInfo.DefinitionSourceLine;
1258           if (MacroInfo.DefinitionLocation.Column > 0)
1259             OS << std::string(MacroInfo.DefinitionLocation.Column - 1, ' ')
1260                << "^\n";
1261           OS << "Macro defined here.\n";
1262         } else
1263           OS << "(no macro definition)"
1264              << "\n";
1265       }
1266     }
1267     return ReturnValue;
1268   }
1269 
1270   // Report on inconsistent conditional instances.
1271   // Returns true if any mismatches.
1272   bool reportInconsistentConditionals(llvm::raw_ostream &OS) {
1273     bool ReturnValue = false;
1274     // Walk all the conditional trackers in the map.
1275     for (ConditionalExpansionMapIter I = ConditionalExpansions.begin(),
1276                                      E = ConditionalExpansions.end();
1277          I != E; ++I) {
1278       const PPItemKey &ItemKey = I->first;
1279       ConditionalTracker &CondTracker = I->second;
1280       if (!CondTracker.hasMismatch())
1281         continue;
1282       // Tell caller we found one or more errors.
1283       ReturnValue = true;
1284       // Start the error message.
1285       OS << *HeaderPaths[ItemKey.File] << ":" << ItemKey.Line << ":"
1286          << ItemKey.Column << "\n";
1287       OS << "#" << getDirectiveSpelling(CondTracker.DirectiveKind) << " "
1288          << *CondTracker.ConditionUnexpanded << "\n";
1289       OS << "^\n";
1290       OS << "error: Conditional expression instance '"
1291          << *CondTracker.ConditionUnexpanded
1292          << "' has different values in this header, depending on how it was "
1293             "included.\n";
1294       // Walk all the instances.
1295       for (std::vector<ConditionalExpansionInstance>::iterator
1296                IMT = CondTracker.ConditionalExpansionInstances.begin(),
1297                EMT = CondTracker.ConditionalExpansionInstances.end();
1298            IMT != EMT; ++IMT) {
1299         ConditionalExpansionInstance &MacroInfo = *IMT;
1300         OS << "  '" << *CondTracker.ConditionUnexpanded << "' expanded to: '"
1301            << ConditionValueKindStrings[MacroInfo.ConditionValue]
1302            << "' with respect to these inclusion paths:\n";
1303         // Walk all the inclusion path hierarchies.
1304         for (std::vector<InclusionPathHandle>::iterator
1305                  IIP = MacroInfo.InclusionPathHandles.begin(),
1306                  EIP = MacroInfo.InclusionPathHandles.end();
1307              IIP != EIP; ++IIP) {
1308           const std::vector<HeaderHandle> &ip = getInclusionPath(*IIP);
1309           int Count = (int)ip.size();
1310           for (int Index = 0; Index < Count; ++Index) {
1311             HeaderHandle H = ip[Index];
1312             OS << std::string((Index * 2) + 4, ' ') << *getHeaderFilePath(H)
1313                << "\n";
1314           }
1315         }
1316       }
1317     }
1318     return ReturnValue;
1319   }
1320 
1321   // Get directive spelling.
1322   static const char *getDirectiveSpelling(clang::tok::PPKeywordKind kind) {
1323     switch (kind) {
1324     case clang::tok::pp_if:
1325       return "if";
1326     case clang::tok::pp_elif:
1327       return "elif";
1328     case clang::tok::pp_ifdef:
1329       return "ifdef";
1330     case clang::tok::pp_ifndef:
1331       return "ifndef";
1332     default:
1333       return "(unknown)";
1334     }
1335   }
1336 
1337 private:
1338   llvm::SmallVector<std::string, 32> HeaderList;
1339   // Only do extern, namespace check for headers in HeaderList.
1340   bool BlockCheckHeaderListOnly;
1341   llvm::StringPool Strings;
1342   std::vector<StringHandle> HeaderPaths;
1343   std::vector<HeaderHandle> HeaderStack;
1344   std::vector<HeaderInclusionPath> InclusionPaths;
1345   InclusionPathHandle CurrentInclusionPathHandle;
1346   llvm::SmallSet<HeaderHandle, 128> HeadersInThisCompile;
1347   std::vector<PPItemKey> IncludeDirectives;
1348   MacroExpansionMap MacroExpansions;
1349   ConditionalExpansionMap ConditionalExpansions;
1350   bool InNestedHeader;
1351 };
1352 
1353 // PreprocessorTracker functions.
1354 
1355 // PreprocessorTracker desctructor.
1356 PreprocessorTracker::~PreprocessorTracker() {}
1357 
1358 // Create instance of PreprocessorTracker.
1359 PreprocessorTracker *PreprocessorTracker::create(
1360     llvm::SmallVector<std::string, 32> &Headers,
1361     bool DoBlockCheckHeaderListOnly) {
1362   return new PreprocessorTrackerImpl(Headers, DoBlockCheckHeaderListOnly);
1363 }
1364 
1365 // Preprocessor callbacks for modularize.
1366 
1367 // Handle include directive.
1368 void PreprocessorCallbacks::InclusionDirective(
1369     clang::SourceLocation HashLoc, const clang::Token &IncludeTok,
1370     llvm::StringRef FileName, bool IsAngled,
1371     clang::CharSourceRange FilenameRange, const clang::FileEntry *File,
1372     llvm::StringRef SearchPath, llvm::StringRef RelativePath,
1373     const clang::Module *Imported) {
1374   int DirectiveLine, DirectiveColumn;
1375   std::string HeaderPath = getSourceLocationFile(PP, HashLoc);
1376   getSourceLocationLineAndColumn(PP, HashLoc, DirectiveLine, DirectiveColumn);
1377   PPTracker.handleIncludeDirective(HeaderPath, DirectiveLine, DirectiveColumn,
1378                                    FileName);
1379 }
1380 
1381 // Handle file entry/exit.
1382 void PreprocessorCallbacks::FileChanged(
1383     clang::SourceLocation Loc, clang::PPCallbacks::FileChangeReason Reason,
1384     clang::SrcMgr::CharacteristicKind FileType, clang::FileID PrevFID) {
1385   switch (Reason) {
1386   case EnterFile:
1387     PPTracker.handleHeaderEntry(PP, getSourceLocationFile(PP, Loc));
1388     break;
1389   case ExitFile: {
1390     const clang::FileEntry *F =
1391         PP.getSourceManager().getFileEntryForID(PrevFID);
1392     if (F)
1393       PPTracker.handleHeaderExit(F->getName());
1394   } break;
1395   case SystemHeaderPragma:
1396   case RenameFile:
1397     break;
1398   }
1399 }
1400 
1401 // Handle macro expansion.
1402 void PreprocessorCallbacks::MacroExpands(const clang::Token &MacroNameTok,
1403                                          const clang::MacroDirective *MD,
1404                                          clang::SourceRange Range,
1405                                          const clang::MacroArgs *Args) {
1406   clang::SourceLocation Loc = Range.getBegin();
1407   // Ignore macro argument expansions.
1408   if (!Loc.isFileID())
1409     return;
1410   clang::IdentifierInfo *II = MacroNameTok.getIdentifierInfo();
1411   const clang::MacroInfo *MI = PP.getMacroInfo(II);
1412   std::string MacroName = II->getName().str();
1413   std::string Unexpanded(getMacroUnexpandedString(Range, PP, MacroName, MI));
1414   std::string Expanded(getMacroExpandedString(PP, MacroName, MI, Args));
1415   PPTracker.addMacroExpansionInstance(
1416       PP, PPTracker.getCurrentHeaderHandle(), Loc, MI->getDefinitionLoc(), II,
1417       Unexpanded, Expanded, PPTracker.getCurrentInclusionPathHandle());
1418 }
1419 
1420 void PreprocessorCallbacks::Defined(const clang::Token &MacroNameTok,
1421                                     const clang::MacroDirective *MD,
1422                                     clang::SourceRange Range) {
1423   clang::SourceLocation Loc(Range.getBegin());
1424   clang::IdentifierInfo *II = MacroNameTok.getIdentifierInfo();
1425   const clang::MacroInfo *MI = PP.getMacroInfo(II);
1426   std::string MacroName = II->getName().str();
1427   std::string Unexpanded(getSourceString(PP, Range));
1428   PPTracker.addMacroExpansionInstance(
1429       PP, PPTracker.getCurrentHeaderHandle(), Loc,
1430       (MI ? MI->getDefinitionLoc() : Loc), II, Unexpanded,
1431       (MI ? "true" : "false"), PPTracker.getCurrentInclusionPathHandle());
1432 }
1433 
1434 void PreprocessorCallbacks::If(clang::SourceLocation Loc,
1435                                clang::SourceRange ConditionRange,
1436                                clang::PPCallbacks::ConditionValueKind ConditionResult) {
1437   std::string Unexpanded(getSourceString(PP, ConditionRange));
1438   PPTracker.addConditionalExpansionInstance(
1439       PP, PPTracker.getCurrentHeaderHandle(), Loc, clang::tok::pp_if,
1440       ConditionResult, Unexpanded, PPTracker.getCurrentInclusionPathHandle());
1441 }
1442 
1443 void PreprocessorCallbacks::Elif(clang::SourceLocation Loc,
1444                                  clang::SourceRange ConditionRange,
1445                                  clang::PPCallbacks::ConditionValueKind ConditionResult,
1446                                  clang::SourceLocation IfLoc) {
1447   std::string Unexpanded(getSourceString(PP, ConditionRange));
1448   PPTracker.addConditionalExpansionInstance(
1449       PP, PPTracker.getCurrentHeaderHandle(), Loc, clang::tok::pp_elif,
1450       ConditionResult, Unexpanded, PPTracker.getCurrentInclusionPathHandle());
1451 }
1452 
1453 void PreprocessorCallbacks::Ifdef(clang::SourceLocation Loc,
1454                                   const clang::Token &MacroNameTok,
1455                                   const clang::MacroDirective *MD) {
1456   clang::PPCallbacks::ConditionValueKind IsDefined =
1457     (MD ? clang::PPCallbacks::CVK_True : clang::PPCallbacks::CVK_False );
1458   PPTracker.addConditionalExpansionInstance(
1459       PP, PPTracker.getCurrentHeaderHandle(), Loc, clang::tok::pp_ifdef,
1460       IsDefined, PP.getSpelling(MacroNameTok),
1461       PPTracker.getCurrentInclusionPathHandle());
1462 }
1463 
1464 void PreprocessorCallbacks::Ifndef(clang::SourceLocation Loc,
1465                                    const clang::Token &MacroNameTok,
1466                                    const clang::MacroDirective *MD) {
1467   clang::PPCallbacks::ConditionValueKind IsNotDefined =
1468     (!MD ? clang::PPCallbacks::CVK_True : clang::PPCallbacks::CVK_False );
1469   PPTracker.addConditionalExpansionInstance(
1470       PP, PPTracker.getCurrentHeaderHandle(), Loc, clang::tok::pp_ifndef,
1471       IsNotDefined, PP.getSpelling(MacroNameTok),
1472       PPTracker.getCurrentInclusionPathHandle());
1473 }
1474 } // end namespace Modularize
1475