diff options
author | Aaron Ballman <aaron@aaronballman.com> | 2014-11-14 13:44:02 +0000 |
---|---|---|
committer | Aaron Ballman <aaron@aaronballman.com> | 2014-11-14 13:44:02 +0000 |
commit | a0344c5d7b9b748a2244dce393ceb55e83b495d6 (patch) | |
tree | 41c8abfdc700d4744b5da95832035d84aa13ffa7 /clang/lib | |
parent | c670688addc0a1e8a14b6174ff3626dce82f88ab (diff) | |
download | bcm5719-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.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Lex/PPMacroExpansion.cpp | 30 |
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 || |