aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/ASTContext.cpp8
-rw-r--r--lib/AST/CommentSema.cpp24
-rw-r--r--lib/AST/RawCommentList.cpp4
-rw-r--r--lib/Lex/Preprocessor.cpp33
-rw-r--r--lib/Sema/AnalysisBasedWarnings.cpp66
-rw-r--r--lib/Sema/SemaDecl.cpp2
6 files changed, 71 insertions, 66 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index f19a2aaaf7..83f3f9ca11 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -355,7 +355,9 @@ const RawComment *ASTContext::getRawCommentForAnyRedecl(
return RC;
}
-comments::FullComment *ASTContext::getCommentForDecl(const Decl *D) const {
+comments::FullComment *ASTContext::getCommentForDecl(
+ const Decl *D,
+ const Preprocessor *PP) const {
D = adjustDeclToTemplate(D);
const Decl *Canonical = D->getCanonicalDecl();
llvm::DenseMap<const Decl *, comments::FullComment *>::iterator Pos =
@@ -373,9 +375,9 @@ comments::FullComment *ASTContext::getCommentForDecl(const Decl *D) const {
// because comments can contain references to parameter names which can be
// different across redeclarations.
if (D != OriginalDecl)
- return getCommentForDecl(OriginalDecl);
+ return getCommentForDecl(OriginalDecl, PP);
- comments::FullComment *FC = RC->parse(*this, D);
+ comments::FullComment *FC = RC->parse(*this, PP, D);
ParsedComments[Canonical] = FC;
return FC;
}
diff --git a/lib/AST/CommentSema.cpp b/lib/AST/CommentSema.cpp
index 4f9f1f241c..dd746ad119 100644
--- a/lib/AST/CommentSema.cpp
+++ b/lib/AST/CommentSema.cpp
@@ -13,7 +13,9 @@
#include "clang/AST/Decl.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/Basic/SourceManager.h"
+#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/StringSwitch.h"
+#include "llvm/ADT/SmallString.h"
namespace clang {
namespace comments {
@@ -23,9 +25,10 @@ namespace {
} // unnamed namespace
Sema::Sema(llvm::BumpPtrAllocator &Allocator, const SourceManager &SourceMgr,
- DiagnosticsEngine &Diags, CommandTraits &Traits) :
+ DiagnosticsEngine &Diags, CommandTraits &Traits,
+ const Preprocessor *PP) :
Allocator(Allocator), SourceMgr(SourceMgr), Diags(Diags), Traits(Traits),
- ThisDeclInfo(NULL), BriefCommand(NULL), ReturnsCommand(NULL) {
+ PP(PP), ThisDeclInfo(NULL), BriefCommand(NULL), ReturnsCommand(NULL) {
}
void Sema::setDecl(const Decl *D) {
@@ -527,10 +530,25 @@ void Sema::checkDeprecatedCommand(const BlockCommandComment *Command) {
FD->doesThisDeclarationHaveABody())
return;
+ StringRef AttributeSpelling = "__attribute__((deprecated))";
+ if (PP) {
+ TokenValue Tokens[] = {
+ tok::kw___attribute, tok::l_paren, tok::l_paren,
+ PP->getIdentifierInfo("deprecated"),
+ tok::r_paren, tok::r_paren
+ };
+ StringRef MacroName = PP->getLastMacroWithSpelling(FD->getLocation(),
+ Tokens);
+ if (!MacroName.empty())
+ AttributeSpelling = MacroName;
+ }
+
+ SmallString<64> TextToInsert(" ");
+ TextToInsert += AttributeSpelling;
Diag(FD->getLocEnd(),
diag::note_add_deprecation_attr)
<< FixItHint::CreateInsertion(FD->getLocEnd().getLocWithOffset(1),
- " __attribute__((deprecated))");
+ TextToInsert);
}
}
diff --git a/lib/AST/RawCommentList.cpp b/lib/AST/RawCommentList.cpp
index 28ef6112b8..80b627293e 100644
--- a/lib/AST/RawCommentList.cpp
+++ b/lib/AST/RawCommentList.cpp
@@ -159,6 +159,7 @@ const char *RawComment::extractBriefText(const ASTContext &Context) const {
}
comments::FullComment *RawComment::parse(const ASTContext &Context,
+ const Preprocessor *PP,
const Decl *D) const {
// Make sure that RawText is valid.
getRawText(Context.getSourceManager());
@@ -168,7 +169,8 @@ comments::FullComment *RawComment::parse(const ASTContext &Context,
RawText.begin(), RawText.end());
comments::Sema S(Context.getAllocator(), Context.getSourceManager(),
Context.getDiagnostics(),
- Context.getCommentCommandTraits());
+ Context.getCommentCommandTraits(),
+ PP);
S.setDecl(D);
comments::Parser P(L, S, Context.getAllocator(), Context.getSourceManager(),
Context.getDiagnostics(),
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index 872cda390a..a0fc265b6b 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -285,6 +285,39 @@ Preprocessor::macro_end(bool IncludeExternalMacros) const {
return Macros.end();
}
+/// \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());
+}
+
+StringRef Preprocessor::getLastMacroWithSpelling(
+ SourceLocation Loc,
+ ArrayRef<TokenValue> Tokens) const {
+ SourceLocation BestLocation;
+ StringRef BestSpelling;
+ for (Preprocessor::macro_iterator I = macro_begin(), E = macro_end();
+ I != E; ++I) {
+ if (!I->second->isObjectLike())
+ continue;
+ const MacroInfo *MI = I->second->findDefinitionAtLoc(Loc, SourceMgr);
+ if (!MI)
+ continue;
+ if (!MacroDefinitionEquals(MI, Tokens))
+ continue;
+ SourceLocation Location = I->second->getDefinitionLoc();
+ // Choose the macro defined latest.
+ if (BestLocation.isInvalid() ||
+ (Location.isValid() &&
+ SourceMgr.isBeforeInTranslationUnit(BestLocation, Location))) {
+ BestLocation = Location;
+ BestSpelling = I->first->getName();
+ }
+ }
+ return BestSpelling;
+}
+
void Preprocessor::recomputeCurLexerKind() {
if (CurLexer)
CurLexerKind = CLK_Lexer;
diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp
index ad5c739037..67d290b73c 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 @@ static bool DiagnoseUninitializedUse(Sema &S, const VarDecl *VD,
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 @@ static void DiagnoseSwitchLabelsFallthrough(Sema &S, AnalysisDeclContext &AC,
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) <<
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 592956b9db..019a7f141a 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -7266,7 +7266,7 @@ void Sema::ActOnDocumentableDecls(Decl **Group, unsigned NumDecls) {
// the lookahead in the lexer: we've consumed the semicolon and looked
// ahead through comments.
for (unsigned i = 0; i != NumDecls; ++i)
- Context.getCommentForDecl(Group[i]);
+ Context.getCommentForDecl(Group[i], &PP);
}
}