]> granicus.if.org Git - clang/commitdiff
[ATTR] Automatic line feed after pragma-like attribute.
authorAlexey Bataev <a.bataev@hotmail.com>
Mon, 12 Oct 2015 06:59:48 +0000 (06:59 +0000)
committerAlexey Bataev <a.bataev@hotmail.com>
Mon, 12 Oct 2015 06:59:48 +0000 (06:59 +0000)
Automatically insert line feed after pretty printing of all pragma-like attributes + fix printing of pragma-like pragmas on declarations.
Differential Revision: http://reviews.llvm.org/D13546

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@250017 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/Attr.td
lib/AST/DeclPrinter.cpp
test/Misc/ast-print-pragmas.cpp
utils/TableGen/ClangAttrEmitter.cpp

index 9da59c99ab41cd80a1639efd4e695a4cd07f6f8d..bed9218adaa73252c98916e6af42045b9028f152 100644 (file)
@@ -2048,17 +2048,15 @@ def LoopHint : Attr {
     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 e09c331d4f72c81f1906ea2452ca3213401a04cf..5c6002d55c0f8db1c2d195d0919b5c50961dbc72 100644 (file)
@@ -96,6 +96,7 @@ namespace {
     void PrintTemplateParameters(const TemplateParameterList *Params,
                                  const TemplateArgumentList *Args = nullptr);
     void prettyPrintAttributes(Decl *D);
+    void prettyPrintPragmas(Decl *D);
     void printDeclType(QualType T, StringRef DeclName, bool Pack = false);
   };
 }
@@ -197,12 +198,40 @@ raw_ostream& DeclPrinter::Indent(unsigned Indentation) {
 void DeclPrinter::prettyPrintAttributes(Decl *D) {
   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"
+        break;
+      default:
+        A->printPretty(Out, Policy);
+        break;
+      }
+    }
+  }
+}
+
+void DeclPrinter::prettyPrintPragmas(Decl *D) {
+  if (Policy.PolishForDeclaration)
+    return;
+
+  if (D->hasAttrs()) {
+    AttrVec &Attrs = D->getAttrs();
+    for (auto *A : Attrs) {
+      switch (A->getKind()) {
+#define ATTR(X)
+#define PRAGMA_SPELLING_ATTR(X) case attr::X:
+#include "clang/Basic/AttrList.inc"
+        A->printPretty(Out, Policy);
+        Indent();
+        break;
+      default:
+        break;
+      }
     }
   }
 }
@@ -408,6 +437,10 @@ void DeclPrinter::VisitEnumConstantDecl(EnumConstantDecl *D) {
 }
 
 void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
+  if (!D->getDescribedFunctionTemplate() &&
+      !D->isFunctionTemplateSpecialization())
+    prettyPrintPragmas(D);
+
   CXXConstructorDecl *CDecl = dyn_cast<CXXConstructorDecl>(D);
   CXXConversionDecl *ConversionDecl = dyn_cast<CXXConversionDecl>(D);
   if (!Policy.SuppressSpecifiers) {
@@ -643,6 +676,7 @@ void DeclPrinter::VisitFriendDecl(FriendDecl *D) {
 }
 
 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 +706,7 @@ void DeclPrinter::VisitLabelDecl(LabelDecl *D) {
 }
 
 void DeclPrinter::VisitVarDecl(VarDecl *D) {
+  prettyPrintPragmas(D);
   if (!Policy.SuppressSpecifiers) {
     StorageClass SC = D->getStorageClass();
     if (SC != SC_None)
@@ -779,6 +814,7 @@ void DeclPrinter::VisitEmptyDecl(EmptyDecl *D) {
 }
 
 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 +950,13 @@ void DeclPrinter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
   if (PrintInstantiation) {
     TemplateParameterList *Params = D->getTemplateParameters();
     for (auto *I : D->specializations()) {
+      prettyPrintPragmas(I);
       PrintTemplateParameters(Params, I->getTemplateSpecializationArgs());
       Visit(I);
     }
   }
 
+  prettyPrintPragmas(D->getTemplatedDecl());
   return VisitRedeclarableTemplateDecl(D);
 }
 
index 23f533fc37660b45d2fa43b2046fac6c684cb7aa..c4fe1e23b1e62e922e19cbc7fef81994b952449c 100644 (file)
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -ast-print %s -o - | FileCheck %s
+// RUN: %clang_cc1 -DMS_EXT -fsyntax-only -fms-extensions %s -triple x86_64-pc-win32 -ast-print | FileCheck %s --check-prefix=MS-EXT
 
 // FIXME: A bug in ParsedAttributes causes the order of the attributes to be
 // reversed. The checks are consequently in the reverse order below.
@@ -53,3 +54,11 @@ void test_nontype_template_param(int *List, int Length) {
 void test_templates(int *List, int Length) {
   test_nontype_template_param<2, 4>(List, Length);
 }
+
+#ifdef MS_EXT
+#pragma init_seg(compiler)
+// MS-EXT: #pragma init_seg (.CRT$XCC)
+// MS-EXT-NEXT: int x = 3 __declspec(thread);
+int __declspec(thread) x = 3;
+#endif //MS_EXT
+
index a5bd419017ad7cd9b6841d95a241640e2320f0a0..d3e67ba91bb9548df55fb3fdf62d2a0d2acab66d 100644 (file)
@@ -1180,6 +1180,7 @@ writePrettyPrintFunction(Record &R,
     if (Variety == "Pragma") {
       OS << " \";\n";
       OS << "    printPrettyPragma(OS, Policy);\n";
+      OS << "    OS << \"\\n\";";
       OS << "    break;\n";
       OS << "  }\n";
       continue;