Move the 'find macro by spelling' infrastructure to the Preprocessor class and
use it to suggest appropriate macro for __attribute__((deprecated)) in
-Wdocumentation-deprecated-sync.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164892 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp
index ad5c739..67d290b 100644
--- a/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/lib/Sema/AnalysisBasedWarnings.cpp
@@ -41,6 +41,7 @@
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/ImmutableMap.h"
#include "llvm/ADT/PostOrderIterator.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
@@ -679,61 +680,6 @@
return true;
}
-/// \brief Stores token information for comparing actual tokens with
-/// predefined values. Only handles simple tokens and identifiers.
-class TokenValue {
- tok::TokenKind Kind;
- IdentifierInfo *II;
-
-public:
- TokenValue(tok::TokenKind Kind) : Kind(Kind), II(0) {
- assert(Kind != tok::raw_identifier && "Raw identifiers are not supported.");
- assert(Kind != tok::identifier &&
- "Identifiers should be created by TokenValue(IdentifierInfo *)");
- assert(!tok::isLiteral(Kind) && "Literals are not supported.");
- assert(!tok::isAnnotation(Kind) && "Annotations are not supported.");
- }
- TokenValue(IdentifierInfo *II) : Kind(tok::identifier), II(II) {}
- bool operator==(const Token &Tok) const {
- return Tok.getKind() == Kind &&
- (!II || II == Tok.getIdentifierInfo());
- }
-};
-
-/// \brief Compares macro tokens with a specified token value sequence.
-static bool MacroDefinitionEquals(const MacroInfo *MI,
- llvm::ArrayRef<TokenValue> Tokens) {
- return Tokens.size() == MI->getNumTokens() &&
- std::equal(Tokens.begin(), Tokens.end(), MI->tokens_begin());
-}
-
-static std::string GetSuitableSpelling(Preprocessor &PP, SourceLocation L,
- llvm::ArrayRef<TokenValue> Tokens,
- const char *Spelling) {
- SourceManager &SM = PP.getSourceManager();
- SourceLocation BestLocation;
- std::string BestSpelling = Spelling;
- for (Preprocessor::macro_iterator I = PP.macro_begin(), E = PP.macro_end();
- I != E; ++I) {
- if (!I->second->isObjectLike())
- continue;
- const MacroInfo *MI = I->second->findDefinitionAtLoc(L, SM);
- if (!MI)
- continue;
- if (!MacroDefinitionEquals(MI, Tokens))
- continue;
- SourceLocation Location = I->second->getDefinitionLoc();
- // Choose the macro defined latest.
- if (BestLocation.isInvalid() ||
- (Location.isValid() &&
- SM.isBeforeInTranslationUnit(BestLocation, Location))) {
- BestLocation = Location;
- BestSpelling = I->first->getName();
- }
- }
- return BestSpelling;
-}
-
namespace {
class FallthroughMapper : public RecursiveASTVisitor<FallthroughMapper> {
public:
@@ -914,11 +860,15 @@
tok::coloncolon, PP.getIdentifierInfo("fallthrough"),
tok::r_square, tok::r_square
};
- std::string AnnotationSpelling = GetSuitableSpelling(
- PP, L, Tokens, "[[clang::fallthrough]]");
+ StringRef AnnotationSpelling = "[[clang::fallthrough]]";
+ StringRef MacroName = PP.getLastMacroWithSpelling(L, Tokens);
+ if (!MacroName.empty())
+ AnnotationSpelling = MacroName;
+ SmallString<64> TextToInsert(AnnotationSpelling);
+ TextToInsert += "; ";
S.Diag(L, diag::note_insert_fallthrough_fixit) <<
AnnotationSpelling <<
- FixItHint::CreateInsertion(L, AnnotationSpelling + "; ");
+ FixItHint::CreateInsertion(L, TextToInsert);
}
}
S.Diag(L, diag::note_insert_break_fixit) <<