diff options
author | Alexey Bataev <a.bataev@hotmail.com> | 2013-03-22 06:34:35 +0000 |
---|---|---|
committer | Alexey Bataev <a.bataev@hotmail.com> | 2013-03-22 06:34:35 +0000 |
commit | c640058aa7f224a71ce3b1d2601d84e1b57f82d3 (patch) | |
tree | 9b76815ba1471c89d54aee2255d56e0d513c8049 | |
parent | 9bb4a0c195eda6e034c467a63b9ada2209a6df3f (diff) |
OpenMP threadprivate directive parsing and semantic analysis
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177705 91177308-0d34-0410-b5e6-96231b3b80d8
44 files changed, 983 insertions, 4 deletions
diff --git a/include/clang/AST/DeclOpenMP.h b/include/clang/AST/DeclOpenMP.h new file mode 100644 index 0000000000..ca92040c32 --- /dev/null +++ b/include/clang/AST/DeclOpenMP.h @@ -0,0 +1,83 @@ +//===--- OpenMP.h - Classes for representing OpenMP directives ---*- C++ -*-===// +// +// 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 defines OpenMP nodes. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_AST_OPENMP_H +#define LLVM_CLANG_AST_OPENMP_H + +#include "clang/AST/DeclBase.h" +#include "llvm/ADT/ArrayRef.h" + +namespace clang { + +class DeclRefExpr; + +/// \brief This represents '#pragma omp threadprivate ...' directive. +/// For example, in the following, both 'a' and 'A::b' are threadprivate: +/// +/// \code +/// int a; +/// #pragma omp threadprivate(a) +/// struct A { +/// static int b; +/// #pragma omp threadprivate(b) +/// }; +/// \endcode +/// +class OMPThreadPrivateDecl : public Decl { + friend class ASTDeclReader; + unsigned NumVars; + + virtual void anchor(); + + OMPThreadPrivateDecl(Kind DK, DeclContext *DC, SourceLocation L) : + Decl(DK, DC, L), NumVars(0) { } + + ArrayRef<const DeclRefExpr *> getVars() const { + return ArrayRef<const DeclRefExpr *>( + reinterpret_cast<const DeclRefExpr * const *>(this + 1), + NumVars); + } + + llvm::MutableArrayRef<DeclRefExpr *> getVars() { + return llvm::MutableArrayRef<DeclRefExpr *>( + reinterpret_cast<DeclRefExpr **>(this + 1), + NumVars); + } + + void setVars(ArrayRef<DeclRefExpr *> VL); + +public: + static OMPThreadPrivateDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L, + ArrayRef<DeclRefExpr *> VL); + static OMPThreadPrivateDecl *CreateDeserialized(ASTContext &C, + unsigned ID, unsigned N); + + typedef llvm::MutableArrayRef<DeclRefExpr *>::iterator varlist_iterator; + typedef ArrayRef<const DeclRefExpr *>::iterator varlist_const_iterator; + + unsigned varlist_size() const { return NumVars; } + bool varlist_empty() const { return NumVars == 0; } + varlist_iterator varlist_begin() { return getVars().begin(); } + varlist_iterator varlist_end() { return getVars().end(); } + varlist_const_iterator varlist_begin() const { return getVars().begin(); } + varlist_const_iterator varlist_end() const { return getVars().end(); } + + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == OMPThreadPrivate; } +}; + +} // end namespace clang + +#endif diff --git a/include/clang/AST/DeclVisitor.h b/include/clang/AST/DeclVisitor.h index 67be74bfdc..4eaae35778 100644 --- a/include/clang/AST/DeclVisitor.h +++ b/include/clang/AST/DeclVisitor.h @@ -17,6 +17,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclFriend.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclOpenMP.h" #include "clang/AST/DeclTemplate.h" namespace clang { diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index 480263e943..0191964bbf 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -18,6 +18,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclFriend.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/DeclOpenMP.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" @@ -1389,6 +1390,14 @@ DEF_TRAVERSE_DECL(UsingDirectiveDecl, { DEF_TRAVERSE_DECL(UsingShadowDecl, { }) +DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, { + for (OMPThreadPrivateDecl::varlist_iterator I = D->varlist_begin(), + E = D->varlist_end(); + I != E; ++I) { + TRY_TO(TraverseStmt(*I)); + } + }) + // A helper method for TemplateDecl's children. template<typename Derived> bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper( diff --git a/include/clang/Basic/DeclNodes.td b/include/clang/Basic/DeclNodes.td index ac7ad6fc6a..45742bc665 100644 --- a/include/clang/Basic/DeclNodes.td +++ b/include/clang/Basic/DeclNodes.td @@ -74,5 +74,6 @@ def StaticAssert : Decl; def Block : Decl, DeclContext; def ClassScopeFunctionSpecialization : Decl; def Import : Decl; +def OMPThreadPrivate : Decl; def Empty : Decl; diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td index 1238e4baa2..398471cc65 100644 --- a/include/clang/Basic/DiagnosticGroups.td +++ b/include/clang/Basic/DiagnosticGroups.td @@ -517,3 +517,6 @@ def ASMOperandWidths : DiagGroup<"asm-operand-widths">; def ASM : DiagGroup<"asm", [ ASMOperandWidths ]>; + +// OpenMP warnings. +def SourceUsesOpenMP : DiagGroup<"source-uses-openmp">; diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index 55afaa5455..c834e195b3 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -772,7 +772,18 @@ def err_seh___except_filter : Error< def err_seh___finally_block : Error< "%0 only allowed in __finally block">; - + +// OpenMP support. +def warn_pragma_omp_ignored : Warning < + "unexpected '#pragma omp ...' in program">, InGroup<SourceUsesOpenMP>, DefaultIgnore; +def warn_omp_extra_tokens_at_eol : Warning < + "extra tokens at end of '#pragma omp %0' are ignored">, + InGroup<ExtraTokens>; +def err_omp_unknown_directive : Error < + "expected an OpenMP directive">; +def err_omp_unexpected_directive : Error < + "unexpected OpenMP directive '#pragma omp %0'">; + } // end of Parse Issue category. let CategoryName = "Modules Issue" in { diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index ec06e34471..1bc3dab93e 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -6195,6 +6195,22 @@ def err_sampler_argument_required : Error< def err_wrong_sampler_addressspace: Error< "sampler type cannot be used with the __local and __global address space qualifiers">; +// OpenMP support. +def err_omp_expected_var_arg_suggest : Error< + "%0 is not a global variable, static local variable or static data member%select{|; did you mean %2?}1">; +def err_omp_global_var_arg : Error< + "arguments of '#pragma omp %0' must have %select{global storage|static storage duration}1">; +def err_omp_ref_type_arg : Error< + "arguments of '#pragma omp %0' cannot be of reference type %1">; +def err_omp_var_scope : Error< + "'#pragma omp %0' must appear in the scope of the %1 variable declaration">; +def err_omp_var_used : Error< + "'#pragma omp %0' must precede all references to variable %1">; +def err_omp_var_thread_local : Error< + "variable %0 cannot be threadprivate because it is thread-local">; +def err_omp_incomplete_type : Error< + "a threadprivate variable must not have incomplete type %0">; + } // end of sema category let CategoryName = "Related Result Type Issue" in { diff --git a/include/clang/Basic/OpenMPKinds.def b/include/clang/Basic/OpenMPKinds.def new file mode 100644 index 0000000000..f968977f64 --- /dev/null +++ b/include/clang/Basic/OpenMPKinds.def @@ -0,0 +1,23 @@ +//===--- OpenMPKinds.def - OpenMP directives and clauses list ---*- C++ -*-===// +// +// 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 defines the list of supported OpenMP directives and +/// clauses. +/// +//===----------------------------------------------------------------------===// + +#ifndef OPENMP_DIRECTIVE +# define OPENMP_DIRECTIVE(Name) +#endif + +// OpenMP directives. +OPENMP_DIRECTIVE(threadprivate) +OPENMP_DIRECTIVE(parallel) + +#undef OPENMP_DIRECTIVE diff --git a/include/clang/Basic/OpenMPKinds.h b/include/clang/Basic/OpenMPKinds.h new file mode 100644 index 0000000000..ef37db00d0 --- /dev/null +++ b/include/clang/Basic/OpenMPKinds.h @@ -0,0 +1,37 @@ +//===--- OpenMPKinds.h - OpenMP enums ---------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief Defines some OpenMP-specific enums and functions. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_BASIC_OPENMPKINDS_H +#define LLVM_CLANG_BASIC_OPENMPKINDS_H + +#include "clang/Lex/Token.h" + +namespace clang { + +/// \brief OpenMP directives. +enum OpenMPDirectiveKind { + OMPD_unknown = 0, +#define OPENMP_DIRECTIVE(Name) \ + OMPD_##Name, +#include "clang/Basic/OpenMPKinds.def" + NUM_OPENMP_DIRECTIVES +}; + +OpenMPDirectiveKind getOpenMPDirectiveKind(StringRef Str); +const char *getOpenMPDirectiveName(OpenMPDirectiveKind Kind); + +} + +#endif + diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def index 6850bd5a52..6064fc1ff9 100644 --- a/include/clang/Basic/TokenKinds.def +++ b/include/clang/Basic/TokenKinds.def @@ -646,6 +646,12 @@ ANNOTATION(pragma_fp_contract) // handles them. ANNOTATION(pragma_opencl_extension) +// Annotations for OpenMP pragma directives - #pragma omp ... +// The lexer produces these so that they only take effect when the parser +// handles #pragma omp ... directives. +ANNOTATION(pragma_openmp) +ANNOTATION(pragma_openmp_end) + #undef ANNOTATION #undef TESTING_KEYWORD #undef OBJC2_AT_KEYWORD diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 5205105434..1b81f169ba 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -14,6 +14,7 @@ #ifndef LLVM_CLANG_PARSE_PARSER_H #define LLVM_CLANG_PARSE_PARSER_H +#include "clang/Basic/OpenMPKinds.h" #include "clang/Basic/OperatorPrecedence.h" #include "clang/Basic/Specifiers.h" #include "clang/Lex/CodeCompletionHandler.h" @@ -147,6 +148,7 @@ class Parser : public CodeCompletionHandler { OwningPtr<PragmaHandler> FPContractHandler; OwningPtr<PragmaHandler> OpenCLExtensionHandler; OwningPtr<CommentHandler> CommentSemaHandler; + OwningPtr<PragmaHandler> OpenMPHandler; /// Whether the '>' token acts as an operator or not. This will be /// true except when we are parsing an expression within a C++ @@ -2104,6 +2106,11 @@ private: ParsedType ObjectType, UnqualifiedId &Result); + //===--------------------------------------------------------------------===// + // OpenMP: Directives and clauses. + DeclGroupPtrTy ParseOpenMPDeclarativeDirective(); + bool ParseOpenMPSimpleVarList(OpenMPDirectiveKind Kind, + SmallVectorImpl<DeclarationNameInfo> &IdList); public: bool ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, bool AllowDestructorName, diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 370d7d938c..a7ac5a88c7 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -132,6 +132,7 @@ namespace clang { class ObjCMethodDecl; class ObjCPropertyDecl; class ObjCProtocolDecl; + class OMPThreadPrivateDecl; class OverloadCandidateSet; class OverloadExpr; class ParenListExpr; @@ -6592,6 +6593,18 @@ public: void AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *T, unsigned SpellingListIndex, bool IsPackExpansion); + // OpenMP directives and clauses. + + /// \brief Called on well-formed '#pragma omp threadprivate'. + DeclGroupPtrTy ActOnOpenMPThreadprivateDirective( + SourceLocation Loc, + Scope *CurScope, + ArrayRef<DeclarationNameInfo> IdList); + /// \brief Build a new OpenMPThreadPrivateDecl and check its correctness. + OMPThreadPrivateDecl *CheckOMPThreadPrivateDecl( + SourceLocation Loc, + ArrayRef<DeclRefExpr *> VarList); + /// \brief The kind of conversion being performed. enum CheckedConversionKind { /// \brief An implicit conversion. diff --git a/include/clang/Sema/Template.h b/include/clang/Sema/Template.h index fd67222f0f..492e5800bd 100644 --- a/include/clang/Sema/Template.h +++ b/include/clang/Sema/Template.h @@ -430,6 +430,7 @@ namespace clang { Decl *VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D); Decl *VisitClassScopeFunctionSpecializationDecl( ClassScopeFunctionSpecializationDecl *D); + Decl *VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D); // Base case. FIXME: Remove once we can instantiate everything. Decl *VisitDecl(Decl *D) { diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index 85f88ad007..46380ed8bf 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -1036,6 +1036,8 @@ namespace clang { DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION, /// \brief An ImportDecl recording a module import. DECL_IMPORT, + /// \brief A OMPThreadPrivateDecl record. + DECL_OMP_THREADPRIVATE, /// \brief An EmptyDecl record. DECL_EMPTY }; diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt index 14bbc2f724..e804fe7205 100644 --- a/lib/AST/CMakeLists.txt +++ b/lib/AST/CMakeLists.txt @@ -22,6 +22,7 @@ add_clang_library(clangAST 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 0db520e7d6..1e60560485 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 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { 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 0000000000..c0d10a0f41 --- /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 e2a66fb8a7..54fa9ca589 100644 --- a/lib/AST/DeclPrinter.cpp +++ b/lib/AST/DeclPrinter.cpp @@ -82,6 +82,7 @@ namespace { 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 @@ void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) { // 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::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) { 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 << ")"; + } +} + diff --git a/lib/Basic/CMakeLists.txt b/lib/Basic/CMakeLists.txt index 37efcb1220..324be06ebc 100644 --- a/lib/Basic/CMakeLists.txt +++ b/lib/Basic/CMakeLists.txt @@ -11,6 +11,7 @@ add_clang_library(clangBasic LangOptions.cpp Module.cpp ObjCRuntime.cpp + OpenMPKinds.cpp OperatorPrecedence.cpp SourceLocation.cpp SourceManager.cpp diff --git a/lib/Basic/OpenMPKinds.cpp b/lib/Basic/OpenMPKinds.cpp new file mode 100644 index 0000000000..24d15ff750 --- /dev/null +++ b/lib/Basic/OpenMPKinds.cpp @@ -0,0 +1,43 @@ +//===--- OpenMPKinds.cpp - Token Kinds Support ----------------------------===// +// +// 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 the OpenMP enum and support functions. +/// +//===----------------------------------------------------------------------===// + +#include "clang/Basic/OpenMPKinds.h" +#include "clang/Basic/IdentifierTable.h" +#include "clang/Lex/Token.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/ErrorHandling.h" +#include <cassert> + +using namespace clang; + +OpenMPDirectiveKind clang::getOpenMPDirectiveKind(StringRef Str) { + return llvm::StringSwitch<OpenMPDirectiveKind>(Str) +#define OPENMP_DIRECTIVE(Name) \ + .Case(#Name, OMPD_##Name) +#include "clang/Basic/OpenMPKinds.def" + .Default(OMPD_unknown); +} + +const char *clang::getOpenMPDirectiveName(OpenMPDirectiveKind Kind) { + assert(Kind < NUM_OPENMP_DIRECTIVES); + switch (Kind) { + case OMPD_unknown: + return ("unknown"); +#define OPENMP_DIRECTIVE(Name) \ + case OMPD_##Name : return #Name; +#include "clang/Basic/OpenMPKinds.def" + default: + break; + } + llvm_unreachable("Invalid OpenMP directive kind"); +} diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index 3b33c11b04..a99fe29bda 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/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::OMPThreadPrivate: case Decl::Empty: // None of these decls require codegen support. return; diff --git a/lib/Frontend/ASTConsumers.cpp b/lib/Frontend/ASTConsumers.cpp index 936bd2f8a4..4a63d76a73 100644 --- a/lib/Frontend/ASTConsumers.cpp +++ b/lib/Frontend/ASTConsumers.cpp @@ -463,6 +463,10 @@ void DeclContextPrinter::PrintDeclContext(const DeclContext* DC, Out << "<class template> " << *CTD << '\n'; break; } + case Decl::OMPThreadPrivate: { + Out << "<omp threadprivate> " << '"' << *I << "\"\n"; + break; + } default: Out << "DeclKind: " << DK << '"' << *I << "\"\n"; llvm_unreachable("decl unhandled"); diff --git a/lib/Parse/CMakeLists.txt b/lib/Parse/CMakeLists.txt index 55e2aebca8..939998ecb1 100644 --- a/lib/Parse/CMakeLists.txt +++ b/lib/Parse/CMakeLists.txt @@ -7,6 +7,7 @@ add_clang_library(clangParse ParseExprCXX.cpp ParseInit.cpp ParseObjc.cpp + ParseOpenMP.cpp ParsePragma.cpp ParseStmt.cpp ParseTemplate.cpp |