ABataev retitled this revision from "[ATTR] Automatic line feed after
pragma-like attribute, NFC." to "[ATTR] Automatic line feed after pragma-like
attribute.".
ABataev updated this revision to Diff 36850.
ABataev added a comment.
Printing of pragma-like attributes for declarations did not worked at all.
Fixed it and added test for printing #pragma init_seg.
http://reviews.llvm.org/D13546
Files:
include/clang/Basic/Attr.td
lib/AST/DeclPrinter.cpp
test/SemaCXX/pragma-init_seg.cpp
utils/TableGen/ClangAttrEmitter.cpp
Index: lib/AST/DeclPrinter.cpp
===================================================================
--- lib/AST/DeclPrinter.cpp
+++ lib/AST/DeclPrinter.cpp
@@ -95,7 +95,7 @@
void PrintTemplateParameters(const TemplateParameterList *Params,
const TemplateArgumentList *Args = nullptr);
- void prettyPrintAttributes(Decl *D);
+ void prettyPrintAttributes(Decl *D, bool PrintPragmas = false);
void printDeclType(QualType T, StringRef DeclName, bool Pack = false);
};
}
@@ -194,15 +194,27 @@
return Out;
}
-void DeclPrinter::prettyPrintAttributes(Decl *D) {
+void DeclPrinter::prettyPrintAttributes(Decl *D, bool PrintPragmas) {
if (Policy.PolishForDeclaration)
return;
-
+
if (D->hasAttrs()) {
AttrVec &Attrs = D->getAttrs();
- for (AttrVec::const_iterator i=Attrs.begin(), e=Attrs.end(); i!=e; ++i) {
- Attr *A = *i;
- A->printPretty(Out, Policy);
+ for (auto *A : Attrs) {
+ switch (A->getKind()) {
+#define ATTR(X)
+#define PRAGMA_SPELLING_ATTR(X) case attr::X:
+#include "clang/Basic/AttrList.inc"
+ if (PrintPragmas) {
+ A->printPretty(Out, Policy);
+ Indent();
+ }
+ break;
+ default:
+ if (!PrintPragmas)
+ A->printPretty(Out, Policy);
+ break;
+ }
}
}
}
@@ -408,6 +420,10 @@
}
void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
+ if (!D->getDescribedFunctionTemplate() &&
+ !D->isFunctionTemplateSpecialization())
+ prettyPrintAttributes(D, /*PrintPragmas=*/true);
+
CXXConstructorDecl *CDecl = dyn_cast<CXXConstructorDecl>(D);
CXXConversionDecl *ConversionDecl = dyn_cast<CXXConversionDecl>(D);
if (!Policy.SuppressSpecifiers) {
@@ -643,6 +659,7 @@
}
void DeclPrinter::VisitFieldDecl(FieldDecl *D) {
+ // FIXME: add printing of pragma attributes if required.
if (!Policy.SuppressSpecifiers && D->isMutable())
Out << "mutable ";
if (!Policy.SuppressSpecifiers && D->isModulePrivate())
@@ -672,6 +689,7 @@
}
void DeclPrinter::VisitVarDecl(VarDecl *D) {
+ prettyPrintAttributes(D, /*PrintPragmas=*/true);
if (!Policy.SuppressSpecifiers) {
StorageClass SC = D->getStorageClass();
if (SC != SC_None)
@@ -779,6 +797,7 @@
}
void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) {
+ // FIXME: add printing of pragma attributes if required.
if (!Policy.SuppressSpecifiers && D->isModulePrivate())
Out << "__module_private__ ";
Out << D->getKindName();
@@ -914,11 +933,13 @@
if (PrintInstantiation) {
TemplateParameterList *Params = D->getTemplateParameters();
for (auto *I : D->specializations()) {
+ prettyPrintAttributes(I, /*PrintPragmas=*/true);
PrintTemplateParameters(Params, I->getTemplateSpecializationArgs());
Visit(I);
}
}
+ prettyPrintAttributes(D->getTemplatedDecl(), /*PrintPragmas=*/true);
return VisitRedeclarableTemplateDecl(D);
}
Index: utils/TableGen/ClangAttrEmitter.cpp
===================================================================
--- utils/TableGen/ClangAttrEmitter.cpp
+++ utils/TableGen/ClangAttrEmitter.cpp
@@ -1180,6 +1180,7 @@
if (Variety == "Pragma") {
OS << " \";\n";
OS << " printPrettyPragma(OS, Policy);\n";
+ OS << " OS << \"\\n\";";
OS << " break;\n";
OS << " }\n";
continue;
Index: include/clang/Basic/Attr.td
===================================================================
--- include/clang/Basic/Attr.td
+++ include/clang/Basic/Attr.td
@@ -2048,17 +2048,15 @@
unsigned SpellingIndex = getSpellingListIndex();
// For "#pragma unroll" and "#pragma nounroll" the string "unroll" or
// "nounroll" is already emitted as the pragma name.
- if (SpellingIndex == Pragma_nounroll) {
- OS << "\n";
+ if (SpellingIndex == Pragma_nounroll)
return;
- }
else if (SpellingIndex == Pragma_unroll) {
- OS << getValueString(Policy) << "\n";
+ OS << getValueString(Policy);
return;
}
assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling");
- OS << getOptionName(option) << getValueString(Policy) << "\n";
+ OS << getOptionName(option) << getValueString(Policy);
}
// Return a string containing the loop hint argument including the
Index: test/SemaCXX/pragma-init_seg.cpp
===================================================================
--- test/SemaCXX/pragma-init_seg.cpp
+++ test/SemaCXX/pragma-init_seg.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s -triple x86_64-pc-win32
+// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s -triple x86_64-pc-win32 -ast-print | FileCheck %s
// RUN: %clang_cc1 -fsyntax-only -verify -fms-extensions %s -triple i386-apple-darwin13.3.0
#ifndef __APPLE__
@@ -18,4 +18,6 @@
#endif
int f();
+// CHECK: #pragma init_seg (.CRT$XCC)
+// CHECK-NEXT: int x = f() __declspec(thread);
int __declspec(thread) x = f(); // expected-error {{initializer for thread-local variable must be a constant expression}}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits