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.

Aaron Ballman aaron at aaronballman.com
Thu Jan 9 11:39:35 PST 2014


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);





More information about the cfe-commits mailing list