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->getArgumentNum(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() {}
561 for (std::vector<InclusionPathHandle>::iterator
572 if (!haveInclusionPathHandle(H))
592 class MacroExpansionTracker {
597 PPItemKey &DefinitionLocation,
602 addMacroExpansionInstance(MacroExpanded, DefinitionLocation,
603 DefinitionSourceLine, InclusionPathHandle);
605 MacroExpansionTracker() {}
608 MacroExpansionInstance *
610 PPItemKey &DefinitionLocation) {
611 for (std::vector<MacroExpansionInstance>::iterator
615 if ((I->MacroExpanded == MacroExpanded) &&
624 void addMacroExpansionInstance(
StringHandle MacroExpanded,
625 PPItemKey &DefinitionLocation,
627 InclusionPathHandle InclusionPathHandle) {
629 MacroExpansionInstance(MacroExpanded, DefinitionLocation,
630 DefinitionSourceLine, InclusionPathHandle));
651 class ConditionalExpansionInstance {
653 ConditionalExpansionInstance(clang::PPCallbacks::ConditionValueKind
ConditionValue, InclusionPathHandle H)
657 ConditionalExpansionInstance() {}
661 bool haveInclusionPathHandle(InclusionPathHandle H) {
662 for (std::vector<InclusionPathHandle>::iterator
672 void addInclusionPathHandle(InclusionPathHandle H) {
673 if (!haveInclusionPathHandle(H))
690 class ConditionalTracker {
693 clang::PPCallbacks::ConditionValueKind ConditionValue,
695 InclusionPathHandle InclusionPathHandle)
697 addConditionalExpansionInstance(ConditionValue, InclusionPathHandle);
699 ConditionalTracker() {}
702 ConditionalExpansionInstance *
703 findConditionalExpansionInstance(clang::PPCallbacks::ConditionValueKind ConditionValue) {
704 for (std::vector<ConditionalExpansionInstance>::iterator
708 if (I->ConditionValue == ConditionValue) {
717 addConditionalExpansionInstance(clang::PPCallbacks::ConditionValueKind ConditionValue,
718 InclusionPathHandle InclusionPathHandle) {
720 ConditionalExpansionInstance(ConditionValue, InclusionPathHandle));
736 class PreprocessorTrackerImpl;
744 class PreprocessorCallbacks :
public clang::PPCallbacks {
746 PreprocessorCallbacks(PreprocessorTrackerImpl &ppTracker,
747 clang::Preprocessor &
PP, llvm::StringRef rootHeaderFile)
749 ~PreprocessorCallbacks()
override {}
752 void InclusionDirective(clang::SourceLocation HashLoc,
753 const clang::Token &IncludeTok,
754 llvm::StringRef FileName,
bool IsAngled,
755 clang::CharSourceRange FilenameRange,
756 const clang::FileEntry *
File,
757 llvm::StringRef SearchPath,
758 llvm::StringRef RelativePath,
759 const clang::Module *Imported)
override;
760 void FileChanged(clang::SourceLocation
Loc,
761 clang::PPCallbacks::FileChangeReason Reason,
762 clang::SrcMgr::CharacteristicKind FileType,
763 clang::FileID PrevFID = clang::FileID())
override;
764 void MacroExpands(
const clang::Token &MacroNameTok,
765 const clang::MacroDefinition &MD, clang::SourceRange
Range,
766 const clang::MacroArgs *Args)
override;
767 void Defined(
const clang::Token &MacroNameTok,
768 const clang::MacroDefinition &MD,
769 clang::SourceRange
Range)
override;
770 void If(clang::SourceLocation Loc, clang::SourceRange ConditionRange,
771 clang::PPCallbacks::ConditionValueKind ConditionResult)
override;
772 void Elif(clang::SourceLocation Loc, clang::SourceRange ConditionRange,
773 clang::PPCallbacks::ConditionValueKind ConditionResult,
774 clang::SourceLocation IfLoc)
override;
775 void Ifdef(clang::SourceLocation Loc,
const clang::Token &MacroNameTok,
776 const clang::MacroDefinition &MD)
override;
777 void Ifndef(clang::SourceLocation Loc,
const clang::Token &MacroNameTok,
778 const clang::MacroDefinition &MD)
override;
782 clang::Preprocessor &
PP;
787 typedef std::map<PPItemKey, MacroExpansionTracker> MacroExpansionMap;
788 typedef std::map<PPItemKey, MacroExpansionTracker>::iterator
789 MacroExpansionMapIter;
792 typedef std::map<PPItemKey, ConditionalTracker> ConditionalExpansionMap;
793 typedef std::map<PPItemKey, ConditionalTracker>::iterator
794 ConditionalExpansionMapIter;
800 class PreprocessorTrackerImpl :
public PreprocessorTracker {
802 PreprocessorTrackerImpl(llvm::SmallVector<std::string, 32> &Headers,
803 bool DoBlockCheckHeaderListOnly)
808 for (llvm::ArrayRef<std::string>::iterator I = Headers.begin(),
815 ~PreprocessorTrackerImpl()
override {}
818 void handlePreprocessorEntry(clang::Preprocessor &
PP,
819 llvm::StringRef rootHeaderFile)
override {
821 assert((
HeaderStack.size() == 0) &&
"Header stack should be empty.");
822 pushHeaderHandle(addHeader(rootHeaderFile));
823 PP.addPPCallbacks(llvm::make_unique<PreprocessorCallbacks>(*
this, PP,
827 void handlePreprocessorExit()
override {
HeaderStack.clear(); }
833 void handleIncludeDirective(llvm::StringRef DirectivePath,
int DirectiveLine,
835 llvm::StringRef TargetPath)
override {
840 HeaderHandle CurrentHeaderHandle = findHeaderHandle(DirectivePath);
841 StringHandle IncludeHeaderHandle = addString(TargetPath);
846 if ((I->File == CurrentHeaderHandle) && (I->Line == DirectiveLine))
849 PPItemKey IncludeDirectiveItem(IncludeHeaderHandle, CurrentHeaderHandle,
850 DirectiveLine, DirectiveColumn);
857 bool checkForIncludesInBlock(clang::Preprocessor &PP,
858 clang::SourceRange BlockSourceRange,
859 const char *BlockIdentifierMessage,
860 llvm::raw_ostream &OS)
override {
861 clang::SourceLocation BlockStartLoc = BlockSourceRange.getBegin();
862 clang::SourceLocation BlockEndLoc = BlockSourceRange.getEnd();
865 clang::FileID FileID = PP.getSourceManager().getFileID(BlockStartLoc);
868 HeaderHandle SourceHandle = findHeaderHandle(SourcePath);
869 if (SourceHandle == -1)
871 int BlockStartLine, BlockStartColumn, BlockEndLine, BlockEndColumn;
872 bool returnValue =
true;
881 if ((I->File == SourceHandle) && (I->Line >= BlockStartLine) &&
882 (I->Line < BlockEndLine)) {
884 OS << SourcePath <<
":" << I->Line <<
":" << I->Column <<
":\n";
887 OS << std::string(I->Column - 1,
' ') <<
"^\n";
888 OS <<
"error: Include directive within " << BlockIdentifierMessage
890 OS << SourcePath <<
":" << BlockStartLine <<
":" << BlockStartColumn
893 if (BlockStartColumn > 0)
894 OS << std::string(BlockStartColumn - 1,
' ') <<
"^\n";
895 OS <<
"The \"" << BlockIdentifierMessage <<
"\" block is here.\n";
902 void handleHeaderEntry(clang::Preprocessor &PP, llvm::StringRef HeaderPath) {
904 if (HeaderPath.startswith(
"<"))
907 if (H != getCurrentHeaderHandle())
915 void handleHeaderExit(llvm::StringRef HeaderPath) {
917 if (HeaderPath.startswith(
"<"))
921 if (isHeaderHandleInStack(H)) {
923 TH = getCurrentHeaderHandle();
934 std::string getCanonicalPath(llvm::StringRef path)
const {
935 std::string CanonicalPath(path);
936 std::replace(CanonicalPath.begin(), CanonicalPath.end(),
'\\',
'/');
937 return CanonicalPath;
941 bool isHeaderListHeader(llvm::StringRef HeaderPath)
const {
942 std::string CanonicalPath = getCanonicalPath(HeaderPath);
943 for (llvm::ArrayRef<std::string>::iterator I =
HeaderList.begin(),
946 if (*I == CanonicalPath)
954 HeaderHandle findHeaderHandle(llvm::StringRef HeaderPath)
const {
955 std::string CanonicalPath = getCanonicalPath(HeaderPath);
957 for (std::vector<StringHandle>::const_iterator I =
HeaderPaths.begin(),
960 if (**I == CanonicalPath)
969 std::string CanonicalPath = getCanonicalPath(HeaderPath);
991 void popHeaderHandle() {
1007 for (std::vector<HeaderHandle>::const_iterator I =
HeaderStack.begin(),
1019 findInclusionPathHandle(
const std::vector<HeaderHandle> &
Path)
const {
1020 InclusionPathHandle H = 0;
1021 for (std::vector<HeaderInclusionPath>::const_iterator
1025 if (I->Path == Path)
1033 addInclusionPathHandle(
const std::vector<HeaderHandle> &Path) {
1034 InclusionPathHandle H = findInclusionPathHandle(Path);
1042 InclusionPathHandle getCurrentInclusionPathHandle()
const {
1047 const std::vector<HeaderHandle> &
1048 getInclusionPath(InclusionPathHandle H)
const {
1049 if ((H >= 0) && (H <= (InclusionPathHandle)
InclusionPaths.size()))
1051 static std::vector<HeaderHandle> Empty;
1056 void addMacroExpansionInstance(clang::Preprocessor &PP,
HeaderHandle H,
1057 clang::SourceLocation InstanceLoc,
1058 clang::SourceLocation DefinitionLoc,
1059 clang::IdentifierInfo *II,
1060 llvm::StringRef MacroUnexpanded,
1061 llvm::StringRef MacroExpanded,
1062 InclusionPathHandle InclusionPathHandle) {
1066 PPItemKey InstanceKey(PP, MacroName, H, InstanceLoc);
1067 PPItemKey DefinitionKey(PP, MacroName, H, DefinitionLoc);
1071 std::string InstanceSourceLine =
1074 std::string DefinitionSourceLine =
1078 addString(MacroUnexpanded), addString(MacroExpanded),
1079 addString(InstanceSourceLine), DefinitionKey,
1080 addString(DefinitionSourceLine), InclusionPathHandle);
1083 MacroExpansionTracker &CondTracker = I->second;
1085 MacroExpansionInstance *MacroInfo =
1086 CondTracker.findMacroExpansionInstance(addString(MacroExpanded),
1090 MacroInfo->addInclusionPathHandle(InclusionPathHandle);
1093 std::string DefinitionSourceLine =
1096 CondTracker.addMacroExpansionInstance(
1097 addString(MacroExpanded), DefinitionKey,
1098 addString(DefinitionSourceLine), InclusionPathHandle);
1105 addConditionalExpansionInstance(clang::Preprocessor &PP,
HeaderHandle H,
1106 clang::SourceLocation InstanceLoc,
1107 clang::tok::PPKeywordKind DirectiveKind,
1108 clang::PPCallbacks::ConditionValueKind ConditionValue,
1109 llvm::StringRef ConditionUnexpanded,
1110 InclusionPathHandle InclusionPathHandle) {
1114 StringHandle ConditionUnexpandedHandle(addString(ConditionUnexpanded));
1115 PPItemKey InstanceKey(PP, ConditionUnexpandedHandle, H, InstanceLoc);
1119 std::string InstanceSourceLine =
1123 ConditionalTracker(DirectiveKind, ConditionValue,
1124 ConditionUnexpandedHandle, InclusionPathHandle);
1127 ConditionalTracker &CondTracker = I->second;
1129 ConditionalExpansionInstance *MacroInfo =
1130 CondTracker.findConditionalExpansionInstance(ConditionValue);
1133 MacroInfo->addInclusionPathHandle(InclusionPathHandle);
1136 CondTracker.addConditionalExpansionInstance(ConditionValue,
1137 InclusionPathHandle);
1144 bool reportInconsistentMacros(llvm::raw_ostream &OS)
override {
1145 bool ReturnValue =
false;
1150 const PPItemKey &ItemKey = I->first;
1151 MacroExpansionTracker &MacroExpTracker = I->second;
1153 if (!MacroExpTracker.hasMismatch())
1158 OS << *MacroExpTracker.InstanceSourceLine;
1159 if (ItemKey.Column > 0)
1160 OS << std::string(ItemKey.Column - 1,
' ') <<
"^\n";
1161 OS <<
"error: Macro instance '" << *MacroExpTracker.MacroUnexpanded
1162 <<
"' has different values in this header, depending on how it was "
1165 for (std::vector<MacroExpansionInstance>::iterator
1166 IMT = MacroExpTracker.MacroExpansionInstances.begin(),
1167 EMT = MacroExpTracker.MacroExpansionInstances.end();
1168 IMT != EMT; ++IMT) {
1169 MacroExpansionInstance &MacroInfo = *IMT;
1170 OS <<
" '" << *MacroExpTracker.MacroUnexpanded <<
"' expanded to: '"
1171 << *MacroInfo.MacroExpanded
1172 <<
"' with respect to these inclusion paths:\n";
1174 for (std::vector<InclusionPathHandle>::iterator
1175 IIP = MacroInfo.InclusionPathHandles.begin(),
1176 EIP = MacroInfo.InclusionPathHandles.end();
1177 IIP != EIP; ++IIP) {
1178 const std::vector<HeaderHandle> &ip = getInclusionPath(*IIP);
1179 int Count = (int)ip.size();
1180 for (
int Index = 0; Index < Count; ++Index) {
1182 OS << std::string((Index * 2) + 4,
' ') << *getHeaderFilePath(H)
1189 if (MacroInfo.DefinitionLocation.Line != ItemKey.Line) {
1190 OS << *MacroInfo.DefinitionSourceLine;
1191 if (MacroInfo.DefinitionLocation.Column > 0)
1192 OS << std::string(MacroInfo.DefinitionLocation.Column - 1,
' ')
1194 OS <<
"Macro defined here.\n";
1196 OS <<
"(no macro definition)"
1205 bool reportInconsistentConditionals(llvm::raw_ostream &OS)
override {
1206 bool ReturnValue =
false;
1211 const PPItemKey &ItemKey = I->first;
1212 ConditionalTracker &CondTracker = I->second;
1213 if (!CondTracker.hasMismatch())
1218 OS << *
HeaderPaths[ItemKey.File] <<
":" << ItemKey.Line <<
":"
1219 << ItemKey.Column <<
"\n";
1220 OS <<
"#" << getDirectiveSpelling(CondTracker.DirectiveKind) <<
" "
1221 << *CondTracker.ConditionUnexpanded <<
"\n";
1223 OS <<
"error: Conditional expression instance '"
1224 << *CondTracker.ConditionUnexpanded
1225 <<
"' has different values in this header, depending on how it was "
1228 for (std::vector<ConditionalExpansionInstance>::iterator
1229 IMT = CondTracker.ConditionalExpansionInstances.begin(),
1230 EMT = CondTracker.ConditionalExpansionInstances.end();
1231 IMT != EMT; ++IMT) {
1232 ConditionalExpansionInstance &MacroInfo = *IMT;
1233 OS <<
" '" << *CondTracker.ConditionUnexpanded <<
"' expanded to: '"
1234 << ConditionValueKindStrings[MacroInfo.ConditionValue]
1235 <<
"' with respect to these inclusion paths:\n";
1237 for (std::vector<InclusionPathHandle>::iterator
1238 IIP = MacroInfo.InclusionPathHandles.begin(),
1239 EIP = MacroInfo.InclusionPathHandles.end();
1240 IIP != EIP; ++IIP) {
1241 const std::vector<HeaderHandle> &ip = getInclusionPath(*IIP);
1242 int Count = (int)ip.size();
1243 for (
int Index = 0; Index < Count; ++Index) {
1245 OS << std::string((Index * 2) + 4,
' ') << *getHeaderFilePath(H)
1255 static const char *getDirectiveSpelling(clang::tok::PPKeywordKind kind) {
1257 case clang::tok::pp_if:
1259 case clang::tok::pp_elif:
1261 case clang::tok::pp_ifdef:
1263 case clang::tok::pp_ifndef:
1295 llvm::SmallVector<std::string, 32> &Headers,
1296 bool DoBlockCheckHeaderListOnly) {
1297 return new PreprocessorTrackerImpl(Headers, DoBlockCheckHeaderListOnly);
1303 void PreprocessorCallbacks::InclusionDirective(
1304 clang::SourceLocation HashLoc,
const clang::Token &IncludeTok,
1305 llvm::StringRef FileName,
bool IsAngled,
1306 clang::CharSourceRange FilenameRange,
const clang::FileEntry *
File,
1307 llvm::StringRef SearchPath, llvm::StringRef RelativePath,
1308 const clang::Module *Imported) {
1309 int DirectiveLine, DirectiveColumn;
1312 PPTracker.handleIncludeDirective(HeaderPath, DirectiveLine, DirectiveColumn,
1317 void PreprocessorCallbacks::FileChanged(
1318 clang::SourceLocation
Loc, clang::PPCallbacks::FileChangeReason Reason,
1319 clang::SrcMgr::CharacteristicKind FileType, clang::FileID PrevFID) {
1325 const clang::FileEntry *F =
1326 PP.getSourceManager().getFileEntryForID(PrevFID);
1328 PPTracker.handleHeaderExit(F->getName());
1330 case SystemHeaderPragma:
1337 void PreprocessorCallbacks::MacroExpands(
const clang::Token &MacroNameTok,
1338 const clang::MacroDefinition &MD,
1339 clang::SourceRange
Range,
1340 const clang::MacroArgs *Args) {
1341 clang::SourceLocation Loc = Range.getBegin();
1343 if (!Loc.isFileID())
1345 clang::IdentifierInfo *II = MacroNameTok.getIdentifierInfo();
1346 const clang::MacroInfo *MI = MD.getMacroInfo();
1347 std::string MacroName = II->getName().str();
1351 PP,
PPTracker.getCurrentHeaderHandle(),
Loc, MI->getDefinitionLoc(), II,
1352 Unexpanded, Expanded,
PPTracker.getCurrentInclusionPathHandle());
1355 void PreprocessorCallbacks::Defined(
const clang::Token &MacroNameTok,
1356 const clang::MacroDefinition &MD,
1357 clang::SourceRange Range) {
1358 clang::SourceLocation
Loc(Range.getBegin());
1359 clang::IdentifierInfo *II = MacroNameTok.getIdentifierInfo();
1360 const clang::MacroInfo *MI = MD.getMacroInfo();
1361 std::string MacroName = II->getName().str();
1365 (MI ? MI->getDefinitionLoc() :
Loc), II, Unexpanded,
1366 (MI ?
"true" :
"false"),
PPTracker.getCurrentInclusionPathHandle());
1369 void PreprocessorCallbacks::If(clang::SourceLocation Loc,
1370 clang::SourceRange ConditionRange,
1371 clang::PPCallbacks::ConditionValueKind ConditionResult) {
1373 PPTracker.addConditionalExpansionInstance(
1374 PP,
PPTracker.getCurrentHeaderHandle(),
Loc, clang::tok::pp_if,
1375 ConditionResult, Unexpanded,
PPTracker.getCurrentInclusionPathHandle());
1378 void PreprocessorCallbacks::Elif(clang::SourceLocation Loc,
1379 clang::SourceRange ConditionRange,
1380 clang::PPCallbacks::ConditionValueKind ConditionResult,
1381 clang::SourceLocation IfLoc) {
1383 PPTracker.addConditionalExpansionInstance(
1384 PP,
PPTracker.getCurrentHeaderHandle(),
Loc, clang::tok::pp_elif,
1385 ConditionResult, Unexpanded,
PPTracker.getCurrentInclusionPathHandle());
1388 void PreprocessorCallbacks::Ifdef(clang::SourceLocation Loc,
1389 const clang::Token &MacroNameTok,
1390 const clang::MacroDefinition &MD) {
1391 clang::PPCallbacks::ConditionValueKind IsDefined =
1392 (MD ? clang::PPCallbacks::CVK_True : clang::PPCallbacks::CVK_False );
1393 PPTracker.addConditionalExpansionInstance(
1394 PP,
PPTracker.getCurrentHeaderHandle(),
Loc, clang::tok::pp_ifdef,
1395 IsDefined, PP.getSpelling(MacroNameTok),
1396 PPTracker.getCurrentInclusionPathHandle());
1399 void PreprocessorCallbacks::Ifndef(clang::SourceLocation Loc,
1400 const clang::Token &MacroNameTok,
1401 const clang::MacroDefinition &MD) {
1402 clang::PPCallbacks::ConditionValueKind IsNotDefined =
1403 (!MD ? clang::PPCallbacks::CVK_True : clang::PPCallbacks::CVK_False );
1404 PPTracker.addConditionalExpansionInstance(
1405 PP,
PPTracker.getCurrentHeaderHandle(),
Loc, clang::tok::pp_ifndef,
1406 IsNotDefined, PP.getSpelling(MacroNameTok),
1407 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
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
llvm::SmallSet< HeaderHandle, 128 > HeadersInThisCompile
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