r198883 - 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.

Alexander Kornienko alexfh at google.com
Fri Jan 10 08:20:45 PST 2014


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 <aaron at aaronballman.com>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
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140110/db3539ad/attachment.html>


More information about the cfe-commits mailing list