OpenMP threadprivate directive parsing and semantic analysis
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177705 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt
index 14bbc2f..e804fe7 100644
--- a/lib/AST/CMakeLists.txt
+++ b/lib/AST/CMakeLists.txt
@@ -22,6 +22,7 @@
DeclFriend.cpp
DeclGroup.cpp
DeclObjC.cpp
+ DeclOpenMP.cpp
DeclPrinter.cpp
DeclTemplate.cpp
DumpXML.cpp
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 0db520e..1e60560 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -20,6 +20,7 @@
#include "clang/AST/DeclContextInternals.h"
#include "clang/AST/DeclFriend.h"
#include "clang/AST/DeclObjC.h"
+#include "clang/AST/DeclOpenMP.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DependentDiagnostic.h"
#include "clang/AST/ExternalASTSource.h"
@@ -561,6 +562,7 @@
case ObjCCategory:
case ObjCCategoryImpl:
case Import:
+ case OMPThreadPrivate:
case Empty:
// Never looked up by name.
return 0;
diff --git a/lib/AST/DeclOpenMP.cpp b/lib/AST/DeclOpenMP.cpp
new file mode 100644
index 0000000..c0d10a0
--- /dev/null
+++ b/lib/AST/DeclOpenMP.cpp
@@ -0,0 +1,60 @@
+//===--- DeclOpenMP.cpp - Declaration OpenMP AST Node Implementation ------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+/// \brief This file implements OMPThreadPrivateDecl class.
+///
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclBase.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclOpenMP.h"
+#include "clang/AST/Expr.h"
+
+using namespace clang;
+
+//===----------------------------------------------------------------------===//
+// OMPThreadPrivateDecl Implementation.
+//===----------------------------------------------------------------------===//
+
+void OMPThreadPrivateDecl::anchor() { }
+
+OMPThreadPrivateDecl *OMPThreadPrivateDecl::Create(ASTContext &C,
+ DeclContext *DC,
+ SourceLocation L,
+ ArrayRef<DeclRefExpr *> VL) {
+ unsigned Size = sizeof(OMPThreadPrivateDecl) +
+ (VL.size() * sizeof(DeclRefExpr *));
+
+ void *Mem = C.Allocate(Size, llvm::alignOf<OMPThreadPrivateDecl>());
+ OMPThreadPrivateDecl *D = new (Mem) OMPThreadPrivateDecl(OMPThreadPrivate,
+ DC, L);
+ D->NumVars = VL.size();
+ D->setVars(VL);
+ return D;
+}
+
+OMPThreadPrivateDecl *OMPThreadPrivateDecl::CreateDeserialized(ASTContext &C,
+ unsigned ID,
+ unsigned N) {
+ unsigned Size = sizeof(OMPThreadPrivateDecl) + (N * sizeof(DeclRefExpr *));
+
+ void *Mem = AllocateDeserializedDecl(C, ID, Size);
+ OMPThreadPrivateDecl *D = new (Mem) OMPThreadPrivateDecl(OMPThreadPrivate,
+ 0, SourceLocation());
+ D->NumVars = N;
+ return D;
+}
+
+void OMPThreadPrivateDecl::setVars(ArrayRef<DeclRefExpr *> VL) {
+ assert(VL.size() == NumVars &&
+ "Number of variables is not the same as the preallocated buffer");
+ DeclRefExpr **Vars = reinterpret_cast<DeclRefExpr **>(this + 1);
+ std::copy(VL.begin(), VL.end(), Vars);
+}
diff --git a/lib/AST/DeclPrinter.cpp b/lib/AST/DeclPrinter.cpp
index e2a66fb..54fa9ca 100644
--- a/lib/AST/DeclPrinter.cpp
+++ b/lib/AST/DeclPrinter.cpp
@@ -82,6 +82,7 @@
void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
void VisitUsingDecl(UsingDecl *D);
void VisitUsingShadowDecl(UsingShadowDecl *D);
+ void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
void PrintTemplateParameters(const TemplateParameterList *Params,
const TemplateArgumentList *Args = 0);
@@ -291,8 +292,10 @@
// FIXME: Need to be able to tell the DeclPrinter when
const char *Terminator = 0;
- if (isa<FunctionDecl>(*D) &&
- cast<FunctionDecl>(*D)->isThisDeclarationADefinition())
+ if (isa<OMPThreadPrivateDecl>(*D))
+ Terminator = 0;
+ else if (isa<FunctionDecl>(*D) &&
+ cast<FunctionDecl>(*D)->isThisDeclarationADefinition())
Terminator = 0;
else if (isa<ObjCMethodDecl>(*D) && cast<ObjCMethodDecl>(*D)->getBody())
Terminator = 0;
@@ -1150,3 +1153,17 @@
void DeclPrinter::VisitUsingShadowDecl(UsingShadowDecl *D) {
// ignore
}
+
+void DeclPrinter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {
+ Out << "#pragma omp threadprivate";
+ if (!D->varlist_empty()) {
+ for (OMPThreadPrivateDecl::varlist_iterator I = D->varlist_begin(),
+ E = D->varlist_end();
+ I != E; ++I) {
+ Out << (I == D->varlist_begin() ? '(' : ',')
+ << *cast<NamedDecl>((*I)->getDecl());
+ }
+ Out << ")";
+ }
+}
+