This change seems to break parsing of the guarded_by attribute using the
C++11 syntax:
*$ cat test.cc*
class __attribute__((lockable)) Mutex {};
struct Cxx11Style {
Mutex cxx11_mutex;
int i [[gnu::guarded_by(cxx11_mutex)]];
};
*$ clang -fsyntax-only -std=c++11 test.cc*
test.cc:5:11: warning: unknown attribute 'guarded_by' ignored [-Wattributes]
int i [[gnu::guarded_by(cxx11_mutex)]];
^
1 warning generated.
Is it intentional?
On Thu, Jan 9, 2014 at 8:39 PM, Aaron Ballman <[email protected]>wrote:
> Author: aaronballman
> Date: Thu Jan 9 13:39:35 2014
> New Revision: 198883
>
> URL: http://llvm.org/viewvc/llvm-project?rev=198883&view=rev
> Log:
> Removing a bit of custom parsing functionality used by the thread safety
> analysis APIs. Now using tablegen to determine whether an attribute's
> arguments should be parsed in an unevaluated context instead of relying on
> a separate, hard-coded list of attributes.
>
> Modified:
> cfe/trunk/include/clang/Basic/Attr.td
> cfe/trunk/include/clang/Parse/CMakeLists.txt
> cfe/trunk/include/clang/Parse/Makefile
> cfe/trunk/include/clang/Parse/Parser.h
> cfe/trunk/lib/Parse/CMakeLists.txt
> cfe/trunk/lib/Parse/ParseDecl.cpp
> cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
> cfe/trunk/utils/TableGen/TableGen.cpp
> cfe/trunk/utils/TableGen/TableGenBackends.h
>
> Modified: cfe/trunk/include/clang/Basic/Attr.td
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=198883&r1=198882&r2=198883&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/Attr.td (original)
> +++ cfe/trunk/include/clang/Basic/Attr.td Thu Jan 9 13:39:35 2014
> @@ -168,6 +168,9 @@ class Attr {
> // content. Eg) It parses 3 args, but semantically takes 4 args. Opts
> out of
> // common attribute error checking.
> bit HasCustomParsing = 0;
> + // Set to true if all of the attribute's arguments should be parsed in
> an
> + // unevaluated context.
> + bit ParseArgumentsAsUnevaluated = 0;
> // Lists language options, one of which is required to be true for the
> // attribute to be applicable. If empty, no language options are
> required.
> list<LangOpt> LangOpts = [];
> @@ -1008,6 +1011,7 @@ def GuardedBy : InheritableAttr {
> let Args = [ExprArgument<"Arg">];
> let LateParsed = 1;
> let TemplateDependent = 1;
> + let ParseArgumentsAsUnevaluated = 1;
> let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
> "ExpectedFieldOrGlobalVar">;
> }
> @@ -1017,6 +1021,7 @@ def PtGuardedBy : InheritableAttr {
> let Args = [ExprArgument<"Arg">];
> let LateParsed = 1;
> let TemplateDependent = 1;
> + let ParseArgumentsAsUnevaluated = 1;
> let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
> "ExpectedFieldOrGlobalVar">;
> }
> @@ -1026,6 +1031,7 @@ def AcquiredAfter : InheritableAttr {
> let Args = [VariadicExprArgument<"Args">];
> let LateParsed = 1;
> let TemplateDependent = 1;
> + let ParseArgumentsAsUnevaluated = 1;
> let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
> "ExpectedFieldOrGlobalVar">;
> }
> @@ -1035,6 +1041,7 @@ def AcquiredBefore : InheritableAttr {
> let Args = [VariadicExprArgument<"Args">];
> let LateParsed = 1;
> let TemplateDependent = 1;
> + let ParseArgumentsAsUnevaluated = 1;
> let Subjects = SubjectList<[Field, SharedVar], WarnDiag,
> "ExpectedFieldOrGlobalVar">;
> }
> @@ -1044,6 +1051,7 @@ def ExclusiveLockFunction : InheritableA
> let Args = [VariadicExprArgument<"Args">];
> let LateParsed = 1;
> let TemplateDependent = 1;
> + let ParseArgumentsAsUnevaluated = 1;
> let Subjects = SubjectList<[Function, FunctionTemplate]>;
> }
>
> @@ -1052,6 +1060,7 @@ def SharedLockFunction : InheritableAttr
> let Args = [VariadicExprArgument<"Args">];
> let LateParsed = 1;
> let TemplateDependent = 1;
> + let ParseArgumentsAsUnevaluated = 1;
> let Subjects = SubjectList<[Function, FunctionTemplate]>;
> }
>
> @@ -1060,6 +1069,7 @@ def AssertExclusiveLock : InheritableAtt
> let Args = [VariadicExprArgument<"Args">];
> let LateParsed = 1;
> let TemplateDependent = 1;
> + let ParseArgumentsAsUnevaluated = 1;
> let Subjects = SubjectList<[Function, FunctionTemplate]>;
> }
>
> @@ -1068,6 +1078,7 @@ def AssertSharedLock : InheritableAttr {
> let Args = [VariadicExprArgument<"Args">];
> let LateParsed = 1;
> let TemplateDependent = 1;
> + let ParseArgumentsAsUnevaluated = 1;
> let Subjects = SubjectList<[Function, FunctionTemplate]>;
> }
>
> @@ -1078,6 +1089,7 @@ def ExclusiveTrylockFunction : Inheritab
> let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">];
> let LateParsed = 1;
> let TemplateDependent = 1;
> + let ParseArgumentsAsUnevaluated = 1;
> let Subjects = SubjectList<[Function, FunctionTemplate]>;
> }
>
> @@ -1088,6 +1100,7 @@ def SharedTrylockFunction : InheritableA
> let Args = [ExprArgument<"SuccessValue">, VariadicExprArgument<"Args">];
> let LateParsed = 1;
> let TemplateDependent = 1;
> + let ParseArgumentsAsUnevaluated = 1;
> let Subjects = SubjectList<[Function, FunctionTemplate]>;
> }
>
> @@ -1096,6 +1109,7 @@ def UnlockFunction : InheritableAttr {
> let Args = [VariadicExprArgument<"Args">];
> let LateParsed = 1;
> let TemplateDependent = 1;
> + let ParseArgumentsAsUnevaluated = 1;
> let Subjects = SubjectList<[Function, FunctionTemplate]>;
> }
>
> @@ -1104,6 +1118,7 @@ def LockReturned : InheritableAttr {
> let Args = [ExprArgument<"Arg">];
> let LateParsed = 1;
> let TemplateDependent = 1;
> + let ParseArgumentsAsUnevaluated = 1;
> let Subjects = SubjectList<[Function, FunctionTemplate]>;
> }
>
> @@ -1112,6 +1127,7 @@ def LocksExcluded : InheritableAttr {
> let Args = [VariadicExprArgument<"Args">];
> let LateParsed = 1;
> let TemplateDependent = 1;
> + let ParseArgumentsAsUnevaluated = 1;
> let Subjects = SubjectList<[Function, FunctionTemplate]>;
> }
>
> @@ -1120,6 +1136,7 @@ def ExclusiveLocksRequired : Inheritable
> let Args = [VariadicExprArgument<"Args">];
> let LateParsed = 1;
> let TemplateDependent = 1;
> + let ParseArgumentsAsUnevaluated = 1;
> let Subjects = SubjectList<[Function, FunctionTemplate]>;
> }
>
> @@ -1128,6 +1145,7 @@ def SharedLocksRequired : InheritableAtt
> let Args = [VariadicExprArgument<"Args">];
> let LateParsed = 1;
> let TemplateDependent = 1;
> + let ParseArgumentsAsUnevaluated = 1;
> let Subjects = SubjectList<[Function, FunctionTemplate]>;
> }
>
>
> Modified: cfe/trunk/include/clang/Parse/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/CMakeLists.txt?rev=198883&r1=198882&r2=198883&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Parse/CMakeLists.txt (original)
> +++ cfe/trunk/include/clang/Parse/CMakeLists.txt Thu Jan 9 13:39:35 2014
> @@ -12,3 +12,8 @@ clang_tablegen(AttrLateParsed.inc -gen-c
> -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
> SOURCE ../Basic/Attr.td
> TARGET ClangAttrLateParsed)
> +
> +clang_tablegen(AttrArgContext.inc -gen-clang-attr-arg-context-list
> + -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
> + SOURCE ../Basic/Attr.td
> + TARGET ClangAttrArgContext)
>
> Modified: cfe/trunk/include/clang/Parse/Makefile
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Makefile?rev=198883&r1=198882&r2=198883&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Parse/Makefile (original)
> +++ cfe/trunk/include/clang/Parse/Makefile Thu Jan 9 13:39:35 2014
> @@ -1,6 +1,6 @@
> CLANG_LEVEL := ../../..
> TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
> -BUILT_SOURCES = AttrIdentifierArg.inc AttrLateParsed.inc AttrTypeArg.inc
> +BUILT_SOURCES = AttrIdentifierArg.inc AttrLateParsed.inc AttrTypeArg.inc
> AttrArgContext.inc
>
> TABLEGEN_INC_FILES_COMMON = 1
>
> @@ -23,3 +23,9 @@ $(ObjDir)/AttrLateParsed.inc.tmp : $(TD_
> $(Echo) "Building Clang attribute late-parsed table with tblgen"
> $(Verb) $(ClangTableGen) -gen-clang-attr-late-parsed-list -o
> $(call SYSPATH, $@) \
> -I $(PROJ_SRC_DIR)/../../ $<
> +
> +$(ObjDir)/AttrArgContext.inc.tmp : $(TD_SRC_DIR)/Attr.td $(CLANG_TBLGEN) \
> + $(ObjDir)/.dir
> + $(Echo) "Building Clang attribute argument context table with
> tblgen"
> + $(Verb) $(ClangTableGen) -gen-clang-attr-arg-context-list -o
> $(call SYSPATH, $@) \
> + -I $(PROJ_SRC_DIR)/../../ $<
>
> Modified: cfe/trunk/include/clang/Parse/Parser.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=198883&r1=198882&r2=198883&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Parse/Parser.h (original)
> +++ cfe/trunk/include/clang/Parse/Parser.h Thu Jan 9 13:39:35 2014
> @@ -2058,10 +2058,6 @@ private:
> SourceLocation *endLoc);
>
> bool IsThreadSafetyAttribute(StringRef AttrName);
> - void ParseThreadSafetyAttribute(IdentifierInfo &AttrName,
> - SourceLocation AttrNameLoc,
> - ParsedAttributes &Attrs,
> - SourceLocation *EndLoc);
>
> void ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName,
> SourceLocation AttrNameLoc,
>
> Modified: cfe/trunk/lib/Parse/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/CMakeLists.txt?rev=198883&r1=198882&r2=198883&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Parse/CMakeLists.txt (original)
> +++ cfe/trunk/lib/Parse/CMakeLists.txt Thu Jan 9 13:39:35 2014
> @@ -33,6 +33,7 @@ add_dependencies(clangParse
> ClangDiagnosticCommon
> ClangDiagnosticParse
> ClangStmtNodes
> + ClangAttrArgContext
> )
>
> target_link_libraries(clangParse
>
> Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=198883&r1=198882&r2=198883&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
> +++ cfe/trunk/lib/Parse/ParseDecl.cpp Thu Jan 9 13:39:35 2014
> @@ -207,6 +207,14 @@ static bool attributeIsTypeArgAttr(const
> .Default(false);
> }
>
> +/// \brief Determine whether the given attribute requires parsing its
> arguments
> +/// in an unevaluated context or not.
> +static bool attributeParsedArgsUnevaluated(const IdentifierInfo &II) {
> + return llvm::StringSwitch<bool>(normalizeAttrName(II.getName()))
> +#include "clang/Parse/AttrArgContext.inc"
> + .Default(false);
> +}
> +
> IdentifierLoc *Parser::ParseIdentifierLoc() {
> assert(Tok.is(tok::identifier) && "expected an identifier");
> IdentifierLoc *IL = IdentifierLoc::create(Actions.Context,
> @@ -270,13 +278,6 @@ void Parser::ParseGNUAttributeArgs(Ident
> return;
> }
>
> - // Thread safety attributes are parsed in an unevaluated context.
> - // FIXME: Share the bulk of the parsing code here and just pull out
> - // the unevaluated context.
> - if (IsThreadSafetyAttribute(AttrName->getName())) {
> - ParseThreadSafetyAttribute(*AttrName, AttrNameLoc, Attrs, EndLoc);
> - return;
> - }
> // Type safety attributes have their own grammar.
> if (AttrKind == AttributeList::AT_TypeTagForDatatype) {
> ParseTypeTagForDatatypeAttribute(*AttrName, AttrNameLoc, Attrs,
> EndLoc);
> @@ -291,8 +292,13 @@ void Parser::ParseGNUAttributeArgs(Ident
> // Ignore the left paren location for now.
> ConsumeParen();
>
> + OwningPtr<EnterExpressionEvaluationContext> Unevaluated;
> ArgsVector ArgExprs;
>
> + if (attributeParsedArgsUnevaluated(*AttrName))
> + Unevaluated.reset(new EnterExpressionEvaluationContext(Actions,
> +
> Sema::Unevaluated));
> +
> if (Tok.is(tok::identifier)) {
> // If this attribute wants an 'identifier' argument, make it so.
> bool IsIdentifierArg = attributeHasIdentifierArg(*AttrName);
> @@ -1215,54 +1221,6 @@ bool Parser::IsThreadSafetyAttribute(Str
> .Default(false);
> }
>
> -/// \brief Parse the contents of thread safety attributes. These
> -/// should always be parsed as an expression list.
> -///
> -/// We need to special case the parsing due to the fact that if the first
> token
> -/// of the first argument is an identifier, the main parse loop will store
> -/// that token as a "parameter" and the rest of
> -/// the arguments will be added to a list of "arguments". However,
> -/// subsequent tokens in the first argument are lost. We instead parse
> each
> -/// argument as an expression and add all arguments to the list of
> "arguments".
> -/// In future, we will take advantage of this special case to also
> -/// deal with some argument scoping issues here (for example, referring
> to a
> -/// function parameter in the attribute on that function).
> -void Parser::ParseThreadSafetyAttribute(IdentifierInfo &AttrName,
> - SourceLocation AttrNameLoc,
> - ParsedAttributes &Attrs,
> - SourceLocation *EndLoc) {
> - assert(Tok.is(tok::l_paren) && "Attribute arg list not starting with
> '('");
> -
> - BalancedDelimiterTracker T(*this, tok::l_paren);
> - T.consumeOpen();
> -
> - ArgsVector ArgExprs;
> - bool ArgExprsOk = true;
> -
> - // now parse the list of expressions
> - while (Tok.isNot(tok::r_paren)) {
> - EnterExpressionEvaluationContext Unevaluated(Actions,
> Sema::Unevaluated);
> - ExprResult ArgExpr(ParseAssignmentExpression());
> - if (ArgExpr.isInvalid()) {
> - ArgExprsOk = false;
> - T.consumeClose();
> - break;
> - } else {
> - ArgExprs.push_back(ArgExpr.release());
> - }
> - // Eat the comma, move to the next argument
> - if (!TryConsumeToken(tok::comma))
> - break;
> - }
> - // Match the ')'.
> - if (ArgExprsOk && !T.consumeClose()) {
> - Attrs.addNew(&AttrName, AttrNameLoc, 0, AttrNameLoc, ArgExprs.data(),
> - ArgExprs.size(), AttributeList::AS_GNU);
> - }
> - if (EndLoc)
> - *EndLoc = T.getCloseLocation();
> -}
> -
> void Parser::ParseTypeTagForDatatypeAttribute(IdentifierInfo &AttrName,
> SourceLocation AttrNameLoc,
> ParsedAttributes &Attrs,
>
> Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=198883&r1=198882&r2=198883&view=diff
>
> ==============================================================================
> --- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original)
> +++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Thu Jan 9 13:39:35 2014
> @@ -1291,6 +1291,33 @@ void EmitClangAttrTypeArgList(RecordKeep
> }
> }
>
> +/// \brief Emits the parse-arguments-in-unevaluated-context property for
> +/// attributes.
> +void EmitClangAttrArgContextList(RecordKeeper &Records, raw_ostream &OS) {
> + emitSourceFileHeader("StringSwitch code to match attributes which
> require "
> + "an unevaluated context", OS);
> +
> + ParsedAttrMap Attrs = getParsedAttrList(Records);
> + for (ParsedAttrMap::const_iterator I = Attrs.begin(), E = Attrs.end();
> + I != E; ++I) {
> + const Record &Attr = *I->second;
> +
> + if (!Attr.getValueAsBit("ParseArgumentsAsUnevaluated"))
> + continue;
> +
> + // All these spellings take are parsed unevaluated.
> + std::vector<Record *> Spellings =
> Attr.getValueAsListOfDefs("Spellings");
> + std::set<std::string> Emitted;
> + for (std::vector<Record*>::const_iterator I = Spellings.begin(),
> + E = Spellings.end(); I != E; ++I) {
> + if (Emitted.insert((*I)->getValueAsString("Name")).second)
> + OS << ".Case(\"" << (*I)->getValueAsString("Name") << "\", "
> + << "true" << ")\n";
> + }
> +
> + }
> +}
> +
> // Emits the first-argument-is-identifier property for attributes.
> void EmitClangAttrIdentifierArgList(RecordKeeper &Records, raw_ostream
> &OS) {
> emitSourceFileHeader("llvm::StringSwitch code to match attributes with "
>
> Modified: cfe/trunk/utils/TableGen/TableGen.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/TableGen.cpp?rev=198883&r1=198882&r2=198883&view=diff
>
> ==============================================================================
> --- cfe/trunk/utils/TableGen/TableGen.cpp (original)
> +++ cfe/trunk/utils/TableGen/TableGen.cpp Thu Jan 9 13:39:35 2014
> @@ -25,6 +25,7 @@ using namespace clang;
> enum ActionType {
> GenClangAttrClasses,
> GenClangAttrIdentifierArgList,
> + GenClangAttrArgContextList,
> GenClangAttrTypeArgList,
> GenClangAttrImpl,
> GenClangAttrList,
> @@ -66,6 +67,10 @@ cl::opt<ActionType> Action(
> "gen-clang-attr-identifier-arg-list",
> "Generate a list of attributes that take an "
> "identifier as their first argument"),
> + clEnumValN(GenClangAttrArgContextList,
> + "gen-clang-attr-arg-context-list",
> + "Generate a list of attributes that parse their
> arguments "
> + "in an unevaluated context"),
> clEnumValN(GenClangAttrTypeArgList,
> "gen-clang-attr-type-arg-list",
> "Generate a list of attributes that take a type as
> their "
> @@ -154,6 +159,9 @@ bool ClangTableGenMain(raw_ostream &OS,
> case GenClangAttrIdentifierArgList:
> EmitClangAttrIdentifierArgList(Records, OS);
> break;
> + case GenClangAttrArgContextList:
> + EmitClangAttrArgContextList(Records, OS);
> + break;
> case GenClangAttrTypeArgList:
> EmitClangAttrTypeArgList(Records, OS);
> break;
>
> Modified: cfe/trunk/utils/TableGen/TableGenBackends.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/TableGenBackends.h?rev=198883&r1=198882&r2=198883&view=diff
>
> ==============================================================================
> --- cfe/trunk/utils/TableGen/TableGenBackends.h (original)
> +++ cfe/trunk/utils/TableGen/TableGenBackends.h Thu Jan 9 13:39:35 2014
> @@ -31,6 +31,7 @@ void EmitClangASTNodes(RecordKeeper &RK,
>
> void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS);
> void EmitClangAttrIdentifierArgList(RecordKeeper &Records, raw_ostream
> &OS);
> +void EmitClangAttrArgContextList(RecordKeeper &Records, raw_ostream &OS);
> void EmitClangAttrTypeArgList(RecordKeeper &Records, raw_ostream &OS);
> void EmitClangAttrImpl(RecordKeeper &Records, raw_ostream &OS);
> void EmitClangAttrList(RecordKeeper &Records, raw_ostream &OS);
>
>
> _______________________________________________
> cfe-commits mailing list
> [email protected]
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits