r175900 - [Sema] Semantic analysis for empty-declaration and attribute-declaration.

Michael Han fragmentshaders at gmail.com
Fri Feb 22 09:15:32 PST 2013


Author: hanm
Date: Fri Feb 22 11:15:32 2013
New Revision: 175900

URL: http://llvm.org/viewvc/llvm-project?rev=175900&view=rev
Log:
[Sema] Semantic analysis for empty-declaration and attribute-declaration.

Introduce a new AST Decl node "EmptyDecl" to model empty-declaration. Have attributes from attribute-declaration appertain
to the EmptyDecl node by creating the AST representations of these attributes and attach them to the EmptyDecl node so these
attributes can be sema checked just as attributes attached to "normal" declarations.


Modified:
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
    cfe/trunk/include/clang/Basic/DeclNodes.td
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/include/clang/Serialization/ASTBitCodes.h
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/AST/DeclBase.cpp
    cfe/trunk/lib/AST/DeclPrinter.cpp
    cfe/trunk/lib/CodeGen/CGDecl.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/Parse/Parser.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Serialization/ASTCommon.cpp
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
    cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
    cfe/trunk/test/Parser/cxx0x-attributes.cpp
    cfe/trunk/test/SemaCXX/cxx11-ast-print.cpp
    cfe/trunk/tools/libclang/RecursiveASTVisitor.h

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=175900&r1=175899&r2=175900&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Fri Feb 22 11:15:32 2013
@@ -3297,7 +3297,21 @@ public:
   static bool classof(const Decl *D) { return classofKind(D->getKind()); }
   static bool classofKind(Kind K) { return K == Import; }
 };
-  
+
+/// \brief Represents an empty-declaration.
+class EmptyDecl : public Decl {
+  virtual void anchor();
+  EmptyDecl(DeclContext *DC, SourceLocation L)
+    : Decl(Empty, DC, L) { }
+
+public:
+  static EmptyDecl *Create(ASTContext &C, DeclContext *DC,
+                           SourceLocation L);
+  static EmptyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == Empty; }
+};
 
 /// Insertion operator for diagnostics.  This allows sending NamedDecl's
 /// into a diagnostic with <<.

Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=175900&r1=175899&r2=175900&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Fri Feb 22 11:15:32 2013
@@ -1257,6 +1257,8 @@ DEF_TRAVERSE_DECL(BlockDecl, {
     return true;
   })
 
+DEF_TRAVERSE_DECL(EmptyDecl, { })
+
 DEF_TRAVERSE_DECL(FileScopeAsmDecl, {
     TRY_TO(TraverseStmt(D->getAsmString()));
   })

Modified: cfe/trunk/include/clang/Basic/DeclNodes.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DeclNodes.td?rev=175900&r1=175899&r2=175900&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DeclNodes.td (original)
+++ cfe/trunk/include/clang/Basic/DeclNodes.td Fri Feb 22 11:15:32 2013
@@ -74,4 +74,5 @@ def StaticAssert : Decl;
 def Block : Decl, DeclContext;
 def ClassScopeFunctionSpecialization : Decl;
 def Import : Decl;
+def Empty : Decl;
 

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=175900&r1=175899&r2=175900&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Feb 22 11:15:32 2013
@@ -1916,8 +1916,6 @@ def warn_attribute_not_on_decl : Warning
   "%0 attribute ignored when parsing type">, InGroup<IgnoredAttributes>;
 def err_base_specifier_attribute : Error<
   "%0 attribute cannot be applied to a base specifier">;
-def err_attribute_declaration : Error<
-  "%0 attribute cannot be used in an attribute declaration">;
 
 // Availability attribute
 def warn_availability_unknown_platform : Warning<

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=175900&r1=175899&r2=175900&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Feb 22 11:15:32 2013
@@ -1447,8 +1447,10 @@ public:
                               SourceLocation AsmLoc,
                               SourceLocation RParenLoc);
 
-  /// \brief Handle a C++11 attribute-declaration.
-  void ActOnAttributeDeclaration(AttributeList *AttrList);
+  /// \brief Handle a C++11 empty-declaration and attribute-declaration.
+  Decl *ActOnEmptyDeclaration(Scope *S,
+                              AttributeList *AttrList,
+                              SourceLocation SemiLoc);
 
   /// \brief The parser has processed a module import declaration.
   ///

Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=175900&r1=175899&r2=175900&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Fri Feb 22 11:15:32 2013
@@ -1031,7 +1031,9 @@ namespace clang {
       /// function specialization. (Microsoft extension).
       DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION,
       /// \brief An ImportDecl recording a module import.
-      DECL_IMPORT
+      DECL_IMPORT,
+      /// \brief An EmptyDecl record.
+      DECL_EMPTY
     };
 
     /// \brief Record codes for each kind of statement or expression.

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=175900&r1=175899&r2=175900&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Fri Feb 22 11:15:32 2013
@@ -3343,6 +3343,17 @@ FileScopeAsmDecl *FileScopeAsmDecl::Crea
   return new (Mem) FileScopeAsmDecl(0, 0, SourceLocation(), SourceLocation());
 }
 
+void EmptyDecl::anchor() {}
+
+EmptyDecl *EmptyDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) {
+  return new (C) EmptyDecl(DC, L);
+}
+
+EmptyDecl *EmptyDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
+  void *Mem = AllocateDeserializedDecl(C, ID, sizeof(EmptyDecl));
+  return new (Mem) EmptyDecl(0, SourceLocation());
+}
+
 //===----------------------------------------------------------------------===//
 // ImportDecl Implementation
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=175900&r1=175899&r2=175900&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Fri Feb 22 11:15:32 2013
@@ -558,6 +558,7 @@ unsigned Decl::getIdentifierNamespaceFor
     case ObjCCategory:
     case ObjCCategoryImpl:
     case Import:
+    case Empty:
       // Never looked up by name.
       return 0;
   }

Modified: cfe/trunk/lib/AST/DeclPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclPrinter.cpp?rev=175900&r1=175899&r2=175900&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclPrinter.cpp (original)
+++ cfe/trunk/lib/AST/DeclPrinter.cpp Fri Feb 22 11:15:32 2013
@@ -51,6 +51,7 @@ namespace {
     void VisitEnumDecl(EnumDecl *D);
     void VisitRecordDecl(RecordDecl *D);
     void VisitEnumConstantDecl(EnumConstantDecl *D);
+    void VisitEmptyDecl(EmptyDecl *D);
     void VisitFunctionDecl(FunctionDecl *D);
     void VisitFriendDecl(FriendDecl *D);
     void VisitFieldDecl(FieldDecl *D);
@@ -723,6 +724,11 @@ void DeclPrinter::VisitNamespaceAliasDec
   Out << *D->getAliasedNamespace();
 }
 
+void DeclPrinter::VisitEmptyDecl(EmptyDecl *D) {
+  prettyPrintAttributes(D);
+  Out << ";\n";
+}
+
 void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) {
   if (!Policy.SuppressSpecifiers && D->isModulePrivate())
     Out << "__module_private__ ";

Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=175900&r1=175899&r2=175900&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Fri Feb 22 11:15:32 2013
@@ -83,6 +83,7 @@ void CodeGenFunction::EmitDecl(const Dec
   case Decl::StaticAssert: // static_assert(X, ""); [C++0x]
   case Decl::Label:        // __label__ x;
   case Decl::Import:
+  case Decl::Empty:
     // None of these decls require codegen support.
     return;
 

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=175900&r1=175899&r2=175900&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Fri Feb 22 11:15:32 2013
@@ -2742,6 +2742,7 @@ void CodeGenModule::EmitTopLevelDecl(Dec
   case Decl::TypeAliasTemplate:
   case Decl::NamespaceAlias:
   case Decl::Block:
+  case Decl::Empty:
     break;
   case Decl::CXXConstructor:
     // Skip function templates

Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=175900&r1=175899&r2=175900&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Fri Feb 22 11:15:32 2013
@@ -626,15 +626,11 @@ Parser::ParseExternalDeclaration(ParsedA
     return DeclGroupPtrTy();
   case tok::semi:
     // Either a C++11 empty-declaration or attribute-declaration.
-    if (attrs.Range.isValid()) {
-      // FIXME: Add an AST representation for this.
-      Actions.ActOnAttributeDeclaration(attrs.getList());
-      return DeclGroupPtrTy();
-    }
-
+    SingleDecl = Actions.ActOnEmptyDeclaration(getCurScope(),
+                                               attrs.getList(),
+                                               Tok.getLocation());
     ConsumeExtraSemi(OutsideFunction);
-    // TODO: Invoke action for top-level semicolon.
-    return DeclGroupPtrTy();
+    break;
   case tok::r_brace:
     Diag(Tok, diag::err_extraneous_closing_brace);
     ConsumeBrace();

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=175900&r1=175899&r2=175900&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Fri Feb 22 11:15:32 2013
@@ -10085,23 +10085,17 @@ Decl *Sema::ActOnFinishLinkageSpecificat
   return LinkageSpec;
 }
 
-/// \brief Perform semantic checks on a C++11 attribute-declaration.
-void Sema::ActOnAttributeDeclaration(AttributeList *AttrList) {
-  // FIXME: Build an AST node for an attribute declaration and return it.
-  
-  // Since we do not support any attributes which can be used in an attribute
-  // declaration, just diagnose standard and unknown attributes appropriately.
-  for (/**/; AttrList; AttrList = AttrList->getNext()) {
-    if (AttrList->getKind() == AttributeList::IgnoredAttribute ||
-        AttrList->isInvalid())
-      continue;
+Decl *Sema::ActOnEmptyDeclaration(Scope *S,
+                                  AttributeList *AttrList,
+                                  SourceLocation SemiLoc) {
+  Decl *ED = EmptyDecl::Create(Context, CurContext, SemiLoc);
+  // Attribute declarations appertain to empty declaration so we handle
+  // them here.
+  if (AttrList)
+    ProcessDeclAttributeList(S, ED, AttrList);
 
-    Diag(AttrList->getLoc(),
-         AttrList->getKind() == AttributeList::UnknownAttribute
-           ? diag::warn_unknown_attribute_ignored
-           : diag::err_attribute_declaration)
-      << AttrList->getName();
-  }
+  CurContext->addDecl(ED);
+  return ED;
 }
 
 /// \brief Perform semantic analysis for the variable declaration that

Modified: cfe/trunk/lib/Serialization/ASTCommon.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTCommon.cpp?rev=175900&r1=175899&r2=175900&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTCommon.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTCommon.cpp Fri Feb 22 11:15:32 2013
@@ -168,6 +168,7 @@ bool serialization::isRedeclarableDeclKi
   case Decl::TypeAliasTemplate:
   case Decl::ObjCProtocol:
   case Decl::ObjCInterface:
+  case Decl::Empty:
     return true;
 
   // Never redeclarable.

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=175900&r1=175899&r2=175900&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Fri Feb 22 11:15:32 2013
@@ -265,6 +265,7 @@ namespace clang {
     void VisitFriendTemplateDecl(FriendTemplateDecl *D);
     void VisitStaticAssertDecl(StaticAssertDecl *D);
     void VisitBlockDecl(BlockDecl *BD);
+    void VisitEmptyDecl(EmptyDecl *D);
 
     std::pair<uint64_t, uint64_t> VisitDeclContext(DeclContext *DC);
     
@@ -1526,6 +1527,10 @@ void ASTDeclReader::VisitStaticAssertDec
   D->RParenLoc = ReadSourceLocation(Record, Idx);
 }
 
+void ASTDeclReader::VisitEmptyDecl(EmptyDecl *D) {
+  VisitDecl(D);
+}
+
 std::pair<uint64_t, uint64_t>
 ASTDeclReader::VisitDeclContext(DeclContext *DC) {
   uint64_t LexicalOffset = Record[Idx++];
@@ -2129,6 +2134,9 @@ Decl *ASTReader::ReadDeclRecord(DeclID I
     // locations.
     D = ImportDecl::CreateDeserialized(Context, ID, Record.back());
     break;
+  case DECL_EMPTY:
+    D = EmptyDecl::CreateDeserialized(Context, ID);
+    break;
   }
 
   assert(D && "Unknown declaration reading AST file");

Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=175900&r1=175899&r2=175900&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Fri Feb 22 11:15:32 2013
@@ -102,6 +102,7 @@ namespace clang {
     void VisitFriendTemplateDecl(FriendTemplateDecl *D);
     void VisitStaticAssertDecl(StaticAssertDecl *D);
     void VisitBlockDecl(BlockDecl *D);
+    void VisitEmptyDecl(EmptyDecl *D);
 
     void VisitDeclContext(DeclContext *DC, uint64_t LexicalOffset,
                           uint64_t VisibleOffset);
@@ -780,6 +781,11 @@ void ASTDeclWriter::VisitFileScopeAsmDec
   Code = serialization::DECL_FILE_SCOPE_ASM;
 }
 
+void ASTDeclWriter::VisitEmptyDecl(EmptyDecl *D) {
+  VisitDecl(D);
+  Code = serialization::DECL_EMPTY;
+}
+
 void ASTDeclWriter::VisitBlockDecl(BlockDecl *D) {
   VisitDecl(D);
   Writer.AddStmt(D->getBody());

Modified: cfe/trunk/test/Parser/cxx0x-attributes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-attributes.cpp?rev=175900&r1=175899&r2=175900&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx0x-attributes.cpp (original)
+++ cfe/trunk/test/Parser/cxx0x-attributes.cpp Fri Feb 22 11:15:32 2013
@@ -279,4 +279,5 @@ int v4[2][[gnu::unused]]; // expected-wa
 int v5()[[gnu::unused]]; // expected-warning {{attribute 'unused' ignored}}
 
 [[attribute_declaration]]; // expected-warning {{unknown attribute 'attribute_declaration' ignored}}
-[[noreturn]]; // expected-error {{'noreturn' attribute cannot be used in an attribute declaration}}
+[[noreturn]]; // expected-error {{'noreturn' attribute only applies to functions and methods}}
+[[carries_dependency]]; // expected-error {{'carries_dependency' attribute only applies to functions, methods, and parameters}}

Modified: cfe/trunk/test/SemaCXX/cxx11-ast-print.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx11-ast-print.cpp?rev=175900&r1=175899&r2=175900&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx11-ast-print.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx11-ast-print.cpp Fri Feb 22 11:15:32 2013
@@ -38,3 +38,5 @@ const char *p8 = 4.9_quux;
 const char *p9 = 0x42e3F_fritz;
 // CHECK: const char *p10 = 3.300e+15_fritz;
 const char *p10 = 3.300e+15_fritz;
+// CHECK: ;
+;

Modified: cfe/trunk/tools/libclang/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/RecursiveASTVisitor.h?rev=175900&r1=175899&r2=175900&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/RecursiveASTVisitor.h (original)
+++ cfe/trunk/tools/libclang/RecursiveASTVisitor.h Fri Feb 22 11:15:32 2013
@@ -1199,6 +1199,8 @@ DEF_TRAVERSE_DECL(BlockDecl, {
     return true;
   })
 
+DEF_TRAVERSE_DECL(EmptyDecl, { })
+
 DEF_TRAVERSE_DECL(FileScopeAsmDecl, {
     TRY_TO(TraverseStmt(D->getAsmString()));
   })





More information about the cfe-commits mailing list