247 #include "clang/Lex/LexDiagnostic.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"
256 namespace Modularize {
271 clang::SourceLocation
Loc) {
273 return std::string(
"(none)");
275 return Loc.printToString(PP.getSourceManager());
280 clang::SourceLocation
Loc) {
282 size_t Offset = Source.find(
':', 2);
283 if (Offset == std::string::npos)
285 return Source.substr(0, Offset);
290 clang::SourceLocation
Loc,
int &
Line,
292 clang::PresumedLoc PLoc = PP.getSourceManager().getPresumedLoc(Loc);
293 if (PLoc.isInvalid()) {
298 Line = PLoc.getLine();
299 Column = PLoc.getColumn();
304 clang::SourceRange
Range) {
305 clang::SourceLocation BeginLoc = Range.getBegin();
306 clang::SourceLocation EndLoc = Range.getEnd();
307 const char *BeginPtr = PP.getSourceManager().getCharacterData(BeginLoc);
308 const char *EndPtr = PP.getSourceManager().getCharacterData(EndLoc);
309 size_t Length = EndPtr - BeginPtr;
310 return llvm::StringRef(BeginPtr, Length).trim().str();
315 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') {
329 while (EndPtr < BufferEnd) {
330 if (*EndPtr ==
'\n') {
335 size_t Length = EndPtr - BeginPtr;
336 return llvm::StringRef(BeginPtr, Length).str();
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;
351 while (Buffer < BufferEnd) {
352 if (*Buffer ==
'\n') {
353 if (++LineCounter == Line) {
354 BeginPtr = Buffer++ + 1;
361 while (Buffer < BufferEnd) {
362 if (*Buffer ==
'\n') {
368 size_t Length = EndPtr - BeginPtr;
369 return llvm::StringRef(BeginPtr, Length).str();
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);
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;
390 Length = MacroName.size();
391 return llvm::StringRef(BeginPtr, Length).trim().str();
403 llvm::StringRef MacroName,
404 const clang::MacroInfo *MI,
405 const clang::MacroArgs *Args) {
406 std::string Expanded;
408 for (
const auto &T : MI->tokens()) {
409 clang::IdentifierInfo *II = T.getIdentifierInfo();
410 int ArgNo = (II && Args ? MI->getParameterNum(II) : -1);
414 Expanded += PP.getSpelling(T);
417 std::string
Name = II->getName().str();
419 clang::MacroInfo *MacroInfo = PP.getMacroInfo(II);
420 if (MacroInfo && (Name != MacroName))
428 const clang::Token *ResultArgToks;
429 const clang::Token *ArgTok = Args->getUnexpArgument(ArgNo);
430 if (Args->ArgNeedsPreexpansion(ArgTok, PP))
431 ResultArgToks = &(const_cast<clang::MacroArgs *>(Args))
432 ->getPreExpArgument(ArgNo, MI, PP)[0];
434 ResultArgToks = ArgTok;
436 if (ResultArgToks->is(clang::tok::eof))
438 unsigned NumToks = clang::MacroArgs::getArgLength(ResultArgToks);
440 for (
unsigned ArgumentIndex = 0; ArgumentIndex < NumToks; ++ArgumentIndex) {
441 const clang::Token &AT = ResultArgToks[ArgumentIndex];
442 clang::IdentifierInfo *II = AT.getIdentifierInfo();
444 Expanded += PP.getSpelling(AT);
447 std::string
Name = II->getName().str();
448 clang::MacroInfo *MacroInfo = PP.getMacroInfo(II);
464 "(not evaluated)",
"false",
"true"
468 const char *S1 = (H1 ? *H1 :
"");
469 const char *S2 = (H2 ? *H2 :
"");
470 int Diff = strcmp(S1, S2);
474 const char *S1 = (H1 ? *H1 :
"");
475 const char *S2 = (H2 ? *H2 :
"");
476 int Diff = strcmp(S1, S2);
491 clang::SourceLocation
Loc)
492 : Name(Name), File(File) {
496 : Name(Name), File(File), Line(Line), Column(Column) {}
497 PPItemKey(
const PPItemKey &Other)
501 bool operator==(
const PPItemKey &Other)
const {
502 if (
Name != Other.Name)
504 if (
File != Other.File)
506 if (
Line != Other.Line)
508 return Column == Other.Column;
510 bool operator<(
const PPItemKey &Other)
const {
511 if (
Name < Other.Name)
513 else if (
Name > Other.Name)
515 if (
File < Other.File)
517 else if (
File > Other.File)
519 if (
Line < Other.Line)
521 else if (
Line > Other.Line)
523 return Column < Other.Column;
532 class HeaderInclusionPath {
534 HeaderInclusionPath(std::vector<HeaderHandle> HeaderInclusionPath)
535 :
Path(HeaderInclusionPath) {}
536 HeaderInclusionPath(
const HeaderInclusionPath &Other) :
Path(Other.
Path) {}
537 HeaderInclusionPath() {}
538 std::vector<HeaderHandle>
Path;
546 class MacroExpansionInstance {
556 MacroExpansionInstance() {}
570 if (!haveInclusionPathHandle(H))
590 class MacroExpansionTracker {
595 PPItemKey &DefinitionLocation,
600 addMacroExpansionInstance(MacroExpanded, DefinitionLocation,
601 DefinitionSourceLine, InclusionPathHandle);
603 MacroExpansionTracker() {}
606 MacroExpansionInstance *
608 PPItemKey &DefinitionLocation) {
612 if ((I->MacroExpanded == MacroExpanded) &&
621 void addMacroExpansionInstance(
StringHandle MacroExpanded,
622 PPItemKey &DefinitionLocation,
624 InclusionPathHandle InclusionPathHandle) {
626 MacroExpansionInstance(MacroExpanded, DefinitionLocation,
627 DefinitionSourceLine, InclusionPathHandle));
648 class ConditionalExpansionInstance {
650 ConditionalExpansionInstance(clang::PPCallbacks::ConditionValueKind
ConditionValue, InclusionPathHandle H)
654 ConditionalExpansionInstance() {}
658 bool haveInclusionPathHandle(InclusionPathHandle H) {
667 void addInclusionPathHandle(InclusionPathHandle H) {
668 if (!haveInclusionPathHandle(H))
685 class ConditionalTracker {
688 clang::PPCallbacks::ConditionValueKind ConditionValue,
690 InclusionPathHandle InclusionPathHandle)
692 addConditionalExpansionInstance(ConditionValue, InclusionPathHandle);
694 ConditionalTracker() {}
697 ConditionalExpansionInstance *
698 findConditionalExpansionInstance(clang::PPCallbacks::ConditionValueKind ConditionValue) {
702 if (I->ConditionValue == ConditionValue) {
711 addConditionalExpansionInstance(clang::PPCallbacks::ConditionValueKind ConditionValue,
712 InclusionPathHandle InclusionPathHandle) {
714 ConditionalExpansionInstance(ConditionValue, InclusionPathHandle));
730 class PreprocessorTrackerImpl;
738 class PreprocessorCallbacks :
public clang::PPCallbacks {
740 PreprocessorCallbacks(PreprocessorTrackerImpl &ppTracker,
741 clang::Preprocessor &
PP, llvm::StringRef rootHeaderFile)
743 ~PreprocessorCallbacks()
override {}
746 void InclusionDirective(clang::SourceLocation HashLoc,
747 const clang::Token &IncludeTok,
748 llvm::StringRef FileName,
bool IsAngled,
749 clang::CharSourceRange FilenameRange,
750 const clang::FileEntry *
File,
751 llvm::StringRef SearchPath,
752 llvm::StringRef RelativePath,
753 const clang::Module *Imported)
override;
754 void FileChanged(clang::SourceLocation
Loc,
755 clang::PPCallbacks::FileChangeReason Reason,
756 clang::SrcMgr::CharacteristicKind FileType,
757 clang::FileID PrevFID = clang::FileID())
override;
758 void MacroExpands(
const clang::Token &MacroNameTok,
759 const clang::MacroDefinition &MD, clang::SourceRange
Range,
760 const clang::MacroArgs *Args)
override;
761 void Defined(
const clang::Token &MacroNameTok,
762 const clang::MacroDefinition &MD,
763 clang::SourceRange
Range)
override;
764 void If(clang::SourceLocation Loc, clang::SourceRange ConditionRange,
765 clang::PPCallbacks::ConditionValueKind ConditionResult)
override;
766 void Elif(clang::SourceLocation Loc, clang::SourceRange ConditionRange,
767 clang::PPCallbacks::ConditionValueKind ConditionResult,
768 clang::SourceLocation IfLoc)
override;
769 void Ifdef(clang::SourceLocation Loc,
const clang::Token &MacroNameTok,
770 const clang::MacroDefinition &MD)
override;
771 void Ifndef(clang::SourceLocation Loc,
const clang::Token &MacroNameTok,
772 const clang::MacroDefinition &MD)
override;
776 clang::Preprocessor &
PP;
781 typedef std::map<PPItemKey, MacroExpansionTracker> MacroExpansionMap;
782 typedef std::map<PPItemKey, MacroExpansionTracker>::iterator
783 MacroExpansionMapIter;
786 typedef std::map<PPItemKey, ConditionalTracker> ConditionalExpansionMap;
787 typedef std::map<PPItemKey, ConditionalTracker>::iterator
788 ConditionalExpansionMapIter;
794 class PreprocessorTrackerImpl :
public PreprocessorTracker {
796 PreprocessorTrackerImpl(llvm::SmallVector<std::string, 32> &Headers,
797 bool DoBlockCheckHeaderListOnly)
802 for (llvm::ArrayRef<std::string>::iterator I = Headers.begin(),
809 ~PreprocessorTrackerImpl()
override {}
812 void handlePreprocessorEntry(clang::Preprocessor &
PP,
813 llvm::StringRef rootHeaderFile)
override {
815 assert((
HeaderStack.size() == 0) &&
"Header stack should be empty.");
816 pushHeaderHandle(addHeader(rootHeaderFile));
817 PP.addPPCallbacks(llvm::make_unique<PreprocessorCallbacks>(*
this, PP,
821 void handlePreprocessorExit()
override {
HeaderStack.clear(); }
827 void handleIncludeDirective(llvm::StringRef DirectivePath,
int DirectiveLine,
829 llvm::StringRef TargetPath)
override {
834 HeaderHandle CurrentHeaderHandle = findHeaderHandle(DirectivePath);
835 StringHandle IncludeHeaderHandle = addString(TargetPath);
840 if ((I->File == CurrentHeaderHandle) && (I->Line == DirectiveLine))
843 PPItemKey IncludeDirectiveItem(IncludeHeaderHandle, CurrentHeaderHandle,
844 DirectiveLine, DirectiveColumn);
851 bool checkForIncludesInBlock(clang::Preprocessor &PP,
852 clang::SourceRange BlockSourceRange,
853 const char *BlockIdentifierMessage,
854 llvm::raw_ostream &OS)
override {
855 clang::SourceLocation BlockStartLoc = BlockSourceRange.getBegin();
856 clang::SourceLocation BlockEndLoc = BlockSourceRange.getEnd();
859 clang::FileID FileID = PP.getSourceManager().getFileID(BlockStartLoc);
862 HeaderHandle SourceHandle = findHeaderHandle(SourcePath);
863 if (SourceHandle == -1)
865 int BlockStartLine, BlockStartColumn, BlockEndLine, BlockEndColumn;
866 bool returnValue =
true;
875 if ((I->File == SourceHandle) && (I->Line >= BlockStartLine) &&
876 (I->Line < BlockEndLine)) {
878 OS << SourcePath <<
":" << I->Line <<
":" << I->Column <<
":\n";
881 OS << std::string(I->Column - 1,
' ') <<
"^\n";
882 OS <<
"error: Include directive within " << BlockIdentifierMessage
884 OS << SourcePath <<
":" << BlockStartLine <<
":" << BlockStartColumn
887 if (BlockStartColumn > 0)
888 OS << std::string(BlockStartColumn - 1,
' ') <<
"^\n";
889 OS <<
"The \"" << BlockIdentifierMessage <<
"\" block is here.\n";
896 void handleHeaderEntry(clang::Preprocessor &PP, llvm::StringRef HeaderPath) {
898 if (HeaderPath.startswith(
"<"))
901 if (H != getCurrentHeaderHandle())
909 void handleHeaderExit(llvm::StringRef HeaderPath) {
911 if (HeaderPath.startswith(
"<"))
915 if (isHeaderHandleInStack(H)) {
917 TH = getCurrentHeaderHandle();
928 std::string getCanonicalPath(llvm::StringRef path)
const {
929 std::string CanonicalPath(path);
930 std::replace(CanonicalPath.begin(), CanonicalPath.end(),
'\\',
'/');
931 return CanonicalPath;
935 bool isHeaderListHeader(llvm::StringRef HeaderPath)
const {
936 std::string CanonicalPath = getCanonicalPath(HeaderPath);
937 for (llvm::ArrayRef<std::string>::iterator I =
HeaderList.begin(),
940 if (*I == CanonicalPath)
948 HeaderHandle findHeaderHandle(llvm::StringRef HeaderPath)
const {
949 std::string CanonicalPath = getCanonicalPath(HeaderPath);
953 if (**I == CanonicalPath)
962 std::string CanonicalPath = getCanonicalPath(HeaderPath);
984 void popHeaderHandle() {
1010 findInclusionPathHandle(
const std::vector<HeaderHandle> &
Path)
const {
1011 InclusionPathHandle H = 0;
1014 if (I->Path == Path)
1022 addInclusionPathHandle(
const std::vector<HeaderHandle> &Path) {
1023 InclusionPathHandle H = findInclusionPathHandle(Path);
1031 InclusionPathHandle getCurrentInclusionPathHandle()
const {
1036 const std::vector<HeaderHandle> &
1037 getInclusionPath(InclusionPathHandle H)
const {
1038 if ((H >= 0) && (H <= (InclusionPathHandle)
InclusionPaths.size()))
1040 static std::vector<HeaderHandle> Empty;
1045 void addMacroExpansionInstance(clang::Preprocessor &PP,
HeaderHandle H,
1046 clang::SourceLocation InstanceLoc,
1047 clang::SourceLocation DefinitionLoc,
1048 clang::IdentifierInfo *II,
1049 llvm::StringRef MacroUnexpanded,
1050 llvm::StringRef MacroExpanded,
1051 InclusionPathHandle InclusionPathHandle) {
1055 PPItemKey InstanceKey(PP, MacroName, H, InstanceLoc);
1056 PPItemKey DefinitionKey(PP, MacroName, H, DefinitionLoc);
1060 std::string InstanceSourceLine =
1063 std::string DefinitionSourceLine =
1067 addString(MacroUnexpanded), addString(MacroExpanded),
1068 addString(InstanceSourceLine), DefinitionKey,
1069 addString(DefinitionSourceLine), InclusionPathHandle);
1072 MacroExpansionTracker &CondTracker = I->second;
1074 MacroExpansionInstance *MacroInfo =
1075 CondTracker.findMacroExpansionInstance(addString(MacroExpanded),
1079 MacroInfo->addInclusionPathHandle(InclusionPathHandle);
1082 std::string DefinitionSourceLine =
1085 CondTracker.addMacroExpansionInstance(
1086 addString(MacroExpanded), DefinitionKey,
1087 addString(DefinitionSourceLine), InclusionPathHandle);
1094 addConditionalExpansionInstance(clang::Preprocessor &PP,
HeaderHandle H,
1095 clang::SourceLocation InstanceLoc,
1096 clang::tok::PPKeywordKind DirectiveKind,
1097 clang::PPCallbacks::ConditionValueKind ConditionValue,
1098 llvm::StringRef ConditionUnexpanded,
1099 InclusionPathHandle InclusionPathHandle) {
1103 StringHandle ConditionUnexpandedHandle(addString(ConditionUnexpanded));
1104 PPItemKey InstanceKey(PP, ConditionUnexpandedHandle, H, InstanceLoc);
1108 std::string InstanceSourceLine =
1112 ConditionalTracker(DirectiveKind, ConditionValue,
1113 ConditionUnexpandedHandle, InclusionPathHandle);
1116 ConditionalTracker &CondTracker = I->second;
1118 ConditionalExpansionInstance *MacroInfo =
1119 CondTracker.findConditionalExpansionInstance(ConditionValue);
1122 MacroInfo->addInclusionPathHandle(InclusionPathHandle);
1125 CondTracker.addConditionalExpansionInstance(ConditionValue,
1126 InclusionPathHandle);
1133 bool reportInconsistentMacros(llvm::raw_ostream &OS)
override {
1134 bool ReturnValue =
false;
1138 const PPItemKey &ItemKey = I->first;
1139 MacroExpansionTracker &MacroExpTracker = I->second;
1141 if (!MacroExpTracker.hasMismatch())
1146 OS << *MacroExpTracker.InstanceSourceLine;
1147 if (ItemKey.Column > 0)
1148 OS << std::string(ItemKey.Column - 1,
' ') <<
"^\n";
1149 OS <<
"error: Macro instance '" << *MacroExpTracker.MacroUnexpanded
1150 <<
"' has different values in this header, depending on how it was "
1153 for (
auto IMT = MacroExpTracker.MacroExpansionInstances.begin(),
1154 EMT = MacroExpTracker.MacroExpansionInstances.end();
1155 IMT != EMT; ++IMT) {
1156 MacroExpansionInstance &MacroInfo = *IMT;
1157 OS <<
" '" << *MacroExpTracker.MacroUnexpanded <<
"' expanded to: '"
1158 << *MacroInfo.MacroExpanded
1159 <<
"' with respect to these inclusion paths:\n";
1161 for (
auto IIP = MacroInfo.InclusionPathHandles.begin(),
1162 EIP = MacroInfo.InclusionPathHandles.end();
1163 IIP != EIP; ++IIP) {
1164 const std::vector<HeaderHandle> &ip = getInclusionPath(*IIP);
1165 auto Count = (int)ip.size();
1166 for (
int Index = 0; Index < Count; ++Index) {
1168 OS << std::string((Index * 2) + 4,
' ') << *getHeaderFilePath(H)
1175 if (MacroInfo.DefinitionLocation.Line != ItemKey.Line) {
1176 OS << *MacroInfo.DefinitionSourceLine;
1177 if (MacroInfo.DefinitionLocation.Column > 0)
1178 OS << std::string(MacroInfo.DefinitionLocation.Column - 1,
' ')
1180 OS <<
"Macro defined here.\n";
1182 OS <<
"(no macro definition)"
1191 bool reportInconsistentConditionals(llvm::raw_ostream &OS)
override {
1192 bool ReturnValue =
false;
1197 const PPItemKey &ItemKey = I->first;
1198 ConditionalTracker &CondTracker = I->second;
1199 if (!CondTracker.hasMismatch())
1204 OS << *
HeaderPaths[ItemKey.File] <<
":" << ItemKey.Line <<
":"
1205 << ItemKey.Column <<
"\n";
1206 OS <<
"#" << getDirectiveSpelling(CondTracker.DirectiveKind) <<
" "
1207 << *CondTracker.ConditionUnexpanded <<
"\n";
1209 OS <<
"error: Conditional expression instance '"
1210 << *CondTracker.ConditionUnexpanded
1211 <<
"' has different values in this header, depending on how it was "
1214 for (
auto IMT = CondTracker.ConditionalExpansionInstances.begin(),
1215 EMT = CondTracker.ConditionalExpansionInstances.end();
1216 IMT != EMT; ++IMT) {
1217 ConditionalExpansionInstance &MacroInfo = *IMT;
1218 OS <<
" '" << *CondTracker.ConditionUnexpanded <<
"' expanded to: '"
1219 << ConditionValueKindStrings[MacroInfo.ConditionValue]
1220 <<
"' with respect to these inclusion paths:\n";
1222 for (
auto IIP = MacroInfo.InclusionPathHandles.begin(),
1223 EIP = MacroInfo.InclusionPathHandles.end();
1224 IIP != EIP; ++IIP) {
1225 const std::vector<HeaderHandle> &ip = getInclusionPath(*IIP);
1226 auto Count = (int)ip.size();
1227 for (
int Index = 0; Index < Count; ++Index) {
1229 OS << std::string((Index * 2) + 4,
' ') << *getHeaderFilePath(H)
1239 static const char *getDirectiveSpelling(clang::tok::PPKeywordKind kind) {
1241 case clang::tok::pp_if:
1243 case clang::tok::pp_elif:
1245 case clang::tok::pp_ifdef:
1247 case clang::tok::pp_ifndef:
1279 llvm::SmallVector<std::string, 32> &Headers,
1280 bool DoBlockCheckHeaderListOnly) {
1281 return new PreprocessorTrackerImpl(Headers, DoBlockCheckHeaderListOnly);
1287 void PreprocessorCallbacks::InclusionDirective(
1288 clang::SourceLocation HashLoc,
const clang::Token &IncludeTok,
1289 llvm::StringRef FileName,
bool IsAngled,
1290 clang::CharSourceRange FilenameRange,
const clang::FileEntry *
File,
1291 llvm::StringRef SearchPath, llvm::StringRef RelativePath,
1292 const clang::Module *Imported) {
1293 int DirectiveLine, DirectiveColumn;
1296 PPTracker.handleIncludeDirective(HeaderPath, DirectiveLine, DirectiveColumn,
1301 void PreprocessorCallbacks::FileChanged(
1302 clang::SourceLocation
Loc, clang::PPCallbacks::FileChangeReason Reason,
1303 clang::SrcMgr::CharacteristicKind FileType, clang::FileID PrevFID) {
1309 const clang::FileEntry *F =
1310 PP.getSourceManager().getFileEntryForID(PrevFID);
1312 PPTracker.handleHeaderExit(F->getName());
1314 case SystemHeaderPragma:
1321 void PreprocessorCallbacks::MacroExpands(
const clang::Token &MacroNameTok,
1322 const clang::MacroDefinition &MD,
1323 clang::SourceRange
Range,
1324 const clang::MacroArgs *Args) {
1325 clang::SourceLocation Loc = Range.getBegin();
1327 if (!Loc.isFileID())
1329 clang::IdentifierInfo *II = MacroNameTok.getIdentifierInfo();
1330 const clang::MacroInfo *MI = MD.getMacroInfo();
1331 std::string MacroName = II->getName().str();
1335 PP,
PPTracker.getCurrentHeaderHandle(),
Loc, MI->getDefinitionLoc(), II,
1336 Unexpanded, Expanded,
PPTracker.getCurrentInclusionPathHandle());
1339 void PreprocessorCallbacks::Defined(
const clang::Token &MacroNameTok,
1340 const clang::MacroDefinition &MD,
1341 clang::SourceRange Range) {
1342 clang::SourceLocation
Loc(Range.getBegin());
1343 clang::IdentifierInfo *II = MacroNameTok.getIdentifierInfo();
1344 const clang::MacroInfo *MI = MD.getMacroInfo();
1345 std::string MacroName = II->getName().str();
1349 (MI ? MI->getDefinitionLoc() :
Loc), II, Unexpanded,
1350 (MI ?
"true" :
"false"),
PPTracker.getCurrentInclusionPathHandle());
1353 void PreprocessorCallbacks::If(clang::SourceLocation Loc,
1354 clang::SourceRange ConditionRange,
1355 clang::PPCallbacks::ConditionValueKind ConditionResult) {
1357 PPTracker.addConditionalExpansionInstance(
1358 PP,
PPTracker.getCurrentHeaderHandle(),
Loc, clang::tok::pp_if,
1359 ConditionResult, Unexpanded,
PPTracker.getCurrentInclusionPathHandle());
1362 void PreprocessorCallbacks::Elif(clang::SourceLocation Loc,
1363 clang::SourceRange ConditionRange,
1364 clang::PPCallbacks::ConditionValueKind ConditionResult,
1365 clang::SourceLocation IfLoc) {
1367 PPTracker.addConditionalExpansionInstance(
1368 PP,
PPTracker.getCurrentHeaderHandle(),
Loc, clang::tok::pp_elif,
1369 ConditionResult, Unexpanded,
PPTracker.getCurrentInclusionPathHandle());
1372 void PreprocessorCallbacks::Ifdef(clang::SourceLocation Loc,
1373 const clang::Token &MacroNameTok,
1374 const clang::MacroDefinition &MD) {
1375 clang::PPCallbacks::ConditionValueKind IsDefined =
1376 (MD ? clang::PPCallbacks::CVK_True : clang::PPCallbacks::CVK_False );
1377 PPTracker.addConditionalExpansionInstance(
1378 PP,
PPTracker.getCurrentHeaderHandle(),
Loc, clang::tok::pp_ifdef,
1379 IsDefined, PP.getSpelling(MacroNameTok),
1380 PPTracker.getCurrentInclusionPathHandle());
1383 void PreprocessorCallbacks::Ifndef(clang::SourceLocation Loc,
1384 const clang::Token &MacroNameTok,
1385 const clang::MacroDefinition &MD) {
1386 clang::PPCallbacks::ConditionValueKind IsNotDefined =
1387 (!MD ? clang::PPCallbacks::CVK_True : clang::PPCallbacks::CVK_False );
1388 PPTracker.addConditionalExpansionInstance(
1389 PP,
PPTracker.getCurrentHeaderHandle(),
Loc, clang::tok::pp_ifndef,
1390 IsNotDefined, PP.getSpelling(MacroNameTok),
1391 PPTracker.getCurrentInclusionPathHandle());
StringHandle DefinitionSourceLine
SourceLocation Loc
'#' location in the include directive
StringHandle InstanceSourceLine
static std::string getCanonicalPath(llvm::StringRef FilePath)
Convert header path to canonical form.
static std::string getSourceString(clang::Preprocessor &PP, clang::SourceRange Range)
std::string RootHeaderFile
static void getSourceLocationLineAndColumn(clang::Preprocessor &PP, clang::SourceLocation Loc, int &Line, int &Column)
virtual ~PreprocessorTracker()
const HeaderHandle HeaderHandleInvalid
llvm::SmallSet< HeaderHandle, 32 > HeadersInThisCompile
std::vector< HeaderHandle > Path
static std::string getSourceLocationFile(clang::Preprocessor &PP, clang::SourceLocation Loc)
MacroExpansionMap MacroExpansions
ModularizeUtilities class definition.
static std::string getMacroUnexpandedString(clang::SourceRange Range, clang::Preprocessor &PP, llvm::StringRef MacroName, const clang::MacroInfo *MI)
clang::tok::PPKeywordKind DirectiveKind
StringHandle MacroUnexpanded
std::vector< HeaderInclusionPath > InclusionPaths
const InclusionPathHandle InclusionPathHandleInvalid
StringHandle MacroExpanded
std::vector< MacroExpansionInstance > MacroExpansionInstances
std::vector< HeaderHandle > HeaderStack
std::vector< PPItemKey > IncludeDirectives
bool IsAngled
true if this was an include with angle brackets
static std::string getSourceLine(clang::Preprocessor &PP, clang::SourceLocation Loc)
StringHandle ConditionUnexpanded
PreprocessorTrackerImpl & PPTracker
std::vector< InclusionPathHandle > InclusionPathHandles
InclusionPathHandle CurrentInclusionPathHandle
clang::PPCallbacks::ConditionValueKind ConditionValue
static PreprocessorTracker * create(llvm::SmallVector< std::string, 32 > &Headers, bool DoBlockCheckHeaderListOnly)
PPItemKey DefinitionLocation
static const char *const ConditionValueKindStrings[]
CharSourceRange Range
SourceRange for the file name.
ConditionalExpansionMap ConditionalExpansions
Macro expansions and preprocessor conditional consistency checker.
static std::string getSourceLocationString(clang::Preprocessor &PP, clang::SourceLocation Loc)
static std::string getMacroExpandedString(clang::Preprocessor &PP, llvm::StringRef MacroName, const clang::MacroInfo *MI, const clang::MacroArgs *Args)
llvm::SmallVector< std::string, 32 > HeaderList
std::vector< StringHandle > HeaderPaths
Preprocessor tracker for modularize.
bool BlockCheckHeaderListOnly
std::vector< ConditionalExpansionInstance > ConditionalExpansionInstances
llvm::PooledStringPtr StringHandle