summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorAaron Ballman <aaron@aaronballman.com>2014-11-14 13:44:02 +0000
committerAaron Ballman <aaron@aaronballman.com>2014-11-14 13:44:02 +0000
commita0344c5d7b9b748a2244dce393ceb55e83b495d6 (patch)
tree41c8abfdc700d4744b5da95832035d84aa13ffa7 /clang/lib
parentc670688addc0a1e8a14b6174ff3626dce82f88ab (diff)
downloadbcm5719-llvm-a0344c5d7b9b748a2244dce393ceb55e83b495d6.tar.gz
bcm5719-llvm-a0344c5d7b9b748a2244dce393ceb55e83b495d6.zip
Complete support for the SD-6 standing document (based off N4200) with support for __has_cpp_attribute.
llvm-svn: 221991
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Basic/Attributes.cpp4
-rw-r--r--clang/lib/Lex/PPMacroExpansion.cpp30
2 files changed, 27 insertions, 7 deletions
diff --git a/clang/lib/Basic/Attributes.cpp b/clang/lib/Basic/Attributes.cpp
index a05ad053db0..da9ac793f16 100644
--- a/clang/lib/Basic/Attributes.cpp
+++ b/clang/lib/Basic/Attributes.cpp
@@ -3,7 +3,7 @@
#include "llvm/ADT/StringSwitch.h"
using namespace clang;
-bool clang::hasAttribute(AttrSyntax Syntax, const IdentifierInfo *Scope,
+int clang::hasAttribute(AttrSyntax Syntax, const IdentifierInfo *Scope,
const IdentifierInfo *Attr, const llvm::Triple &T,
const LangOptions &LangOpts) {
StringRef Name = Attr->getName();
@@ -13,5 +13,5 @@ bool clang::hasAttribute(AttrSyntax Syntax, const IdentifierInfo *Scope,
#include "clang/Basic/AttrHasAttributeImpl.inc"
- return false;
+ return 0;
}
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index eb1417660e2..225a3fafd3c 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -96,6 +96,9 @@ void Preprocessor::RegisterBuiltinMacros() {
Ident__COUNTER__ = RegisterBuiltinMacro(*this, "__COUNTER__");
Ident_Pragma = RegisterBuiltinMacro(*this, "_Pragma");
+ // C++ Standing Document Extensions.
+ Ident__has_cpp_attribute = RegisterBuiltinMacro(*this, "__has_cpp_attribute");
+
// GCC Extensions.
Ident__BASE_FILE__ = RegisterBuiltinMacro(*this, "__BASE_FILE__");
Ident__INCLUDE_LEVEL__ = RegisterBuiltinMacro(*this, "__INCLUDE_LEVEL__");
@@ -1374,12 +1377,14 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
II == Ident__has_extension ||
II == Ident__has_builtin ||
II == Ident__is_identifier ||
- II == Ident__has_attribute) {
+ II == Ident__has_attribute ||
+ II == Ident__has_cpp_attribute) {
// The argument to these builtins should be a parenthesized identifier.
SourceLocation StartLoc = Tok.getLocation();
bool IsValid = false;
IdentifierInfo *FeatureII = nullptr;
+ IdentifierInfo *ScopeII = nullptr;
// Read the '('.
LexUnexpandedToken(Tok);
@@ -1387,14 +1392,26 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
// Read the identifier
LexUnexpandedToken(Tok);
if ((FeatureII = Tok.getIdentifierInfo())) {
- // Read the ')'.
+ // If we're checking __has_cpp_attribute, it is possible to receive a
+ // scope token. Read the "::", if it's available.
LexUnexpandedToken(Tok);
- if (Tok.is(tok::r_paren))
+ bool IsScopeValid = true;
+ if (II == Ident__has_cpp_attribute && Tok.is(tok::coloncolon)) {
+ LexUnexpandedToken(Tok);
+ // The first thing we read was not the feature, it was the scope.
+ ScopeII = FeatureII;
+ if (FeatureII = Tok.getIdentifierInfo())
+ LexUnexpandedToken(Tok);
+ else
+ IsScopeValid = false;
+ }
+ // Read the closing paren.
+ if (IsScopeValid && Tok.is(tok::r_paren))
IsValid = true;
}
}
- bool Value = false;
+ int Value = 0;
if (!IsValid)
Diag(StartLoc, diag::err_feature_check_malformed);
else if (II == Ident__is_identifier)
@@ -1405,6 +1422,9 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
} else if (II == Ident__has_attribute)
Value = hasAttribute(AttrSyntax::Generic, nullptr, FeatureII,
getTargetInfo().getTriple(), getLangOpts());
+ else if (II == Ident__has_cpp_attribute)
+ Value = hasAttribute(AttrSyntax::CXX, ScopeII, FeatureII,
+ getTargetInfo().getTriple(), getLangOpts());
else if (II == Ident__has_extension)
Value = HasExtension(*this, FeatureII);
else {
@@ -1412,7 +1432,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
Value = HasFeature(*this, FeatureII);
}
- OS << (int)Value;
+ OS << Value;
if (IsValid)
Tok.setKind(tok::numeric_constant);
} else if (II == Ident__has_include ||
OpenPOWER on IntegriCloud