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

Reply via email to