summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorMichael Han <fragmentshaders@gmail.com>2013-02-22 17:15:32 +0000
committerMichael Han <fragmentshaders@gmail.com>2013-02-22 17:15:32 +0000
commit84324357b8e3870166bd29adf4c4eb83686644d4 (patch)
tree0d8c2a31b6bc5fe50f6d0d95f7d5df284176565f /clang/lib
parentadc1b070020c8badc664302b6bf2ac39bdf1b494 (diff)
downloadbcm5719-llvm-84324357b8e3870166bd29adf4c4eb83686644d4.tar.gz
bcm5719-llvm-84324357b8e3870166bd29adf4c4eb83686644d4.zip
[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. llvm-svn: 175900
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/Decl.cpp11
-rw-r--r--clang/lib/AST/DeclBase.cpp1
-rw-r--r--clang/lib/AST/DeclPrinter.cpp6
-rw-r--r--clang/lib/CodeGen/CGDecl.cpp1
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp1
-rw-r--r--clang/lib/Parse/Parser.cpp12
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp28
-rw-r--r--clang/lib/Serialization/ASTCommon.cpp1
-rw-r--r--clang/lib/Serialization/ASTReaderDecl.cpp8
-rw-r--r--clang/lib/Serialization/ASTWriterDecl.cpp6
10 files changed, 50 insertions, 25 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 0dbb0d30aa2..d2a9f84cd4f 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -3343,6 +3343,17 @@ FileScopeAsmDecl *FileScopeAsmDecl::CreateDeserialized(ASTContext &C,
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
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index f675436fc5f..cdf150595c3 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -558,6 +558,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
case ObjCCategory:
case ObjCCategoryImpl:
case Import:
+ case Empty:
// Never looked up by name.
return 0;
}
diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp
index dce4f9af258..2be0b6c8046 100644
--- a/clang/lib/AST/DeclPrinter.cpp
+++ b/clang/lib/AST/DeclPrinter.cpp
@@ -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::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
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__ ";
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index a4d673b8c32..9c523149bdf 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -83,6 +83,7 @@ void CodeGenFunction::EmitDecl(const Decl &D) {
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;
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 60ec3232031..6442f04070d 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2742,6 +2742,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
case Decl::TypeAliasTemplate:
case Decl::NamespaceAlias:
case Decl::Block:
+ case Decl::Empty:
break;
case Decl::CXXConstructor:
// Skip function templates
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index d9772755bd2..24849edd63b 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -626,15 +626,11 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
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();
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 8198856547c..ce526a9ed39 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -10085,23 +10085,17 @@ Decl *Sema::ActOnFinishLinkageSpecification(Scope *S,
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;
-
- Diag(AttrList->getLoc(),
- AttrList->getKind() == AttributeList::UnknownAttribute
- ? diag::warn_unknown_attribute_ignored
- : diag::err_attribute_declaration)
- << AttrList->getName();
- }
+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);
+
+ CurContext->addDecl(ED);
+ return ED;
}
/// \brief Perform semantic analysis for the variable declaration that
diff --git a/clang/lib/Serialization/ASTCommon.cpp b/clang/lib/Serialization/ASTCommon.cpp
index 9f1514bdff2..3319cc36412 100644
--- a/clang/lib/Serialization/ASTCommon.cpp
+++ b/clang/lib/Serialization/ASTCommon.cpp
@@ -168,6 +168,7 @@ bool serialization::isRedeclarableDeclKind(unsigned Kind) {
case Decl::TypeAliasTemplate:
case Decl::ObjCProtocol:
case Decl::ObjCInterface:
+ case Decl::Empty:
return true;
// Never redeclarable.
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index f4d03cf7755..504c2e6588b 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -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::VisitStaticAssertDecl(StaticAssertDecl *D) {
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 ID) {
// 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");
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp
index 3795e21bdf6..6c63a149c2b 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -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::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
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());
OpenPOWER on IntegriCloud