r289701 - [DebugInfo] Changed DIBuilder::createCompileUnit() to take DIFile instead of FileName and Directory.

2016-12-14 Thread Amjad Aboud via cfe-commits
Author: aaboud
Date: Wed Dec 14 14:24:40 2016
New Revision: 289701

URL: http://llvm.org/viewvc/llvm-project?rev=289701&view=rev
Log:
[DebugInfo] Changed DIBuilder::createCompileUnit() to take DIFile instead of 
FileName and Directory.
This way it will be easier to expand DIFile (e.g., to contain checksum) without 
the need to modify the createCompileUnit() API.

Reviewers: cfe-commits, rnk

Differential Revision: https://reviews.llvm.org/D27763

Modified:
cfe/trunk/lib/CodeGen/CGDebugInfo.cpp

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=289701&r1=289700&r2=289701&view=diff
==
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Wed Dec 14 14:24:40 2016
@@ -466,7 +466,8 @@ void CGDebugInfo::CreateCompileUnit() {
   // Create new compile unit.
   // FIXME - Eliminate TheCU.
   TheCU = DBuilder.createCompileUnit(
-  LangTag, remapDIPath(MainFileName), remapDIPath(getCurrentDirname()),
+  LangTag, DBuilder.createFile(remapDIPath(MainFileName),
+remapDIPath(getCurrentDirname())),
   Producer, LO.Optimize, CGM.getCodeGenOpts().DwarfDebugFlags, RuntimeVers,
   CGM.getCodeGenOpts().SplitDwarfFile, EmissionKind, 0 /* DWOid */,
   CGM.getCodeGenOpts().SplitDwarfInlining);
@@ -1977,10 +1978,11 @@ CGDebugInfo::getOrCreateModuleRef(Extern
 // but LLVM detects skeleton CUs by looking for a non-zero DWO id.
 uint64_t Signature = Mod.getSignature() ? Mod.getSignature() : ~1ULL;
 llvm::DIBuilder DIB(CGM.getModule());
-DIB.createCompileUnit(TheCU->getSourceLanguage(), Mod.getModuleName(),
-  Mod.getPath(), TheCU->getProducer(), true,
-  StringRef(), 0, Mod.getASTFile(),
-  llvm::DICompileUnit::FullDebug, Signature);
+DIB.createCompileUnit(TheCU->getSourceLanguage(),
+  DIB.createFile(Mod.getModuleName(), Mod.getPath()),
+  TheCU->getProducer(), true, StringRef(), 0,
+  Mod.getASTFile(), llvm::DICompileUnit::FullDebug,
+  Signature);
 DIB.finalize();
   }
   llvm::DIModule *Parent =


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r290515 - [DebugInfo] Added support for Checksum debug info feature.

2016-12-25 Thread Amjad Aboud via cfe-commits
Author: aaboud
Date: Sun Dec 25 04:12:27 2016
New Revision: 290515

URL: http://llvm.org/viewvc/llvm-project?rev=290515&view=rev
Log:
[DebugInfo] Added support for Checksum debug info feature.

Differential Revision: https://reviews.llvm.org/D27641

Added:
cfe/trunk/test/CodeGen/Inputs/debug-info-file-checksum.c
cfe/trunk/test/CodeGen/debug-info-file-checksum.c
Modified:
cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
cfe/trunk/lib/CodeGen/CGDebugInfo.h

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=290515&r1=290514&r2=290515&view=diff
==
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Sun Dec 25 04:12:27 2016
@@ -41,6 +41,7 @@
 #include "llvm/IR/Intrinsics.h"
 #include "llvm/IR/Module.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MD5.h"
 #include "llvm/Support/Path.h"
 using namespace clang;
 using namespace clang::CodeGen;
@@ -320,11 +321,36 @@ StringRef CGDebugInfo::getClassName(cons
   return StringRef();
 }
 
+llvm::DIFile::ChecksumKind
+CGDebugInfo::computeChecksum(FileID FID, SmallString<32> &Checksum) const {
+  Checksum.clear();
+
+  if (!CGM.getCodeGenOpts().EmitCodeView)
+return llvm::DIFile::CSK_None;
+
+  SourceManager &SM = CGM.getContext().getSourceManager();
+  bool Invalid;
+  llvm::MemoryBuffer *MemBuffer = SM.getBuffer(FID, &Invalid);
+  if (Invalid)
+return llvm::DIFile::CSK_None;
+
+  llvm::MD5 Hash;
+  llvm::MD5::MD5Result Result;
+
+  Hash.update(MemBuffer->getBuffer());
+  Hash.final(Result);
+
+  Hash.stringifyResult(Result, Checksum);
+  return llvm::DIFile::CSK_MD5;
+}
+
 llvm::DIFile *CGDebugInfo::getOrCreateFile(SourceLocation Loc) {
   if (!Loc.isValid())
 // If Location is not valid then use main input file.
 return DBuilder.createFile(remapDIPath(TheCU->getFilename()),
-   remapDIPath(TheCU->getDirectory()));
+   remapDIPath(TheCU->getDirectory()),
+   TheCU->getFile()->getChecksumKind(),
+   TheCU->getFile()->getChecksum());
 
   SourceManager &SM = CGM.getContext().getSourceManager();
   PresumedLoc PLoc = SM.getPresumedLoc(Loc);
@@ -332,7 +358,9 @@ llvm::DIFile *CGDebugInfo::getOrCreateFi
   if (PLoc.isInvalid() || StringRef(PLoc.getFilename()).empty())
 // If the location is not valid then use main input file.
 return DBuilder.createFile(remapDIPath(TheCU->getFilename()),
-   remapDIPath(TheCU->getDirectory()));
+   remapDIPath(TheCU->getDirectory()),
+   TheCU->getFile()->getChecksumKind(),
+   TheCU->getFile()->getChecksum());
 
   // Cache the results.
   const char *fname = PLoc.getFilename();
@@ -344,8 +372,13 @@ llvm::DIFile *CGDebugInfo::getOrCreateFi
   return cast(V);
   }
 
+  SmallString<32> Checksum;
+  llvm::DIFile::ChecksumKind CSKind =
+  computeChecksum(SM.getFileID(Loc), Checksum);
+
   llvm::DIFile *F = DBuilder.createFile(remapDIPath(PLoc.getFilename()),
-remapDIPath(getCurrentDirname()));
+remapDIPath(getCurrentDirname()),
+CSKind, Checksum);
 
   DIFileCache[fname].reset(F);
   return F;
@@ -353,7 +386,9 @@ llvm::DIFile *CGDebugInfo::getOrCreateFi
 
 llvm::DIFile *CGDebugInfo::getOrCreateMainFile() {
   return DBuilder.createFile(remapDIPath(TheCU->getFilename()),
- remapDIPath(TheCU->getDirectory()));
+ remapDIPath(TheCU->getDirectory()),
+ TheCU->getFile()->getChecksumKind(),
+ TheCU->getFile()->getChecksum());
 }
 
 std::string CGDebugInfo::remapDIPath(StringRef Path) const {
@@ -396,6 +431,8 @@ StringRef CGDebugInfo::getCurrentDirname
 }
 
 void CGDebugInfo::CreateCompileUnit() {
+  SmallString<32> Checksum;
+  llvm::DIFile::ChecksumKind CSKind = llvm::DIFile::CSK_None;
 
   // Should we be asking the SourceManager for the main file name, instead of
   // accepting it as an argument? This just causes the main file name to
@@ -422,6 +459,7 @@ void CGDebugInfo::CreateCompileUnit() {
   llvm::sys::path::append(MainFileDirSS, MainFileName);
   MainFileName = MainFileDirSS.str();
 }
+CSKind = computeChecksum(SM.getMainFileID(), Checksum);
   }
 
   llvm::dwarf::SourceLanguage LangTag;
@@ -467,7 +505,8 @@ void CGDebugInfo::CreateCompileUnit() {
   // FIXME - Eliminate TheCU.
   TheCU = DBuilder.createCompileUnit(
   LangTag, DBuilder.createFile(remapDIPath(MainFileName),
-remapDIPath(getCurrentDirname())),
+   remapDIPath(getCurrentDirname()), CSKind,
+ 

r294637 - [DebugInfo] Added support to Clang FE for generating debug info for preprocessor macros.

2017-02-09 Thread Amjad Aboud via cfe-commits
Author: aaboud
Date: Thu Feb  9 16:07:24 2017
New Revision: 294637

URL: http://llvm.org/viewvc/llvm-project?rev=294637&view=rev
Log:
[DebugInfo] Added support to Clang FE for generating debug info for 
preprocessor macros.

Added "-fdebug-macro" flag (and "-fno-debug-macro" flag) to enable (and to 
disable) emitting macro debug info.
Added CC1 "-debug-info-macro" flag that enables emitting macro debug info.

Differential Revision: https://reviews.llvm.org/D16135

Added:
cfe/trunk/lib/CodeGen/MacroPPCallbacks.cpp
cfe/trunk/lib/CodeGen/MacroPPCallbacks.h
cfe/trunk/test/CodeGen/debug-info-macro.c
cfe/trunk/test/CodeGen/include/debug-info-macro.h
Modified:
cfe/trunk/docs/UsersManual.rst
cfe/trunk/include/clang/CodeGen/ModuleBuilder.h
cfe/trunk/include/clang/Driver/CC1Options.td
cfe/trunk/include/clang/Driver/Options.td
cfe/trunk/include/clang/Frontend/CodeGenOptions.def
cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
cfe/trunk/lib/CodeGen/CGDebugInfo.h
cfe/trunk/lib/CodeGen/CMakeLists.txt
cfe/trunk/lib/CodeGen/CodeGenAction.cpp
cfe/trunk/lib/CodeGen/ModuleBuilder.cpp
cfe/trunk/lib/Driver/Tools.cpp
cfe/trunk/lib/Frontend/CompilerInvocation.cpp
cfe/trunk/test/Driver/debug-options.c

Modified: cfe/trunk/docs/UsersManual.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/UsersManual.rst?rev=294637&r1=294636&r2=294637&view=diff
==
--- cfe/trunk/docs/UsersManual.rst (original)
+++ cfe/trunk/docs/UsersManual.rst Thu Feb  9 16:07:24 2017
@@ -1696,6 +1696,22 @@ below. If multiple flags are present, th
 
   Generate complete debug info.
 
+Controlling Macro Debug Info Generation
+^^^
+
+Debug info for C preprocessor macros increases the size of debug information in
+the binary. Macro debug info generated by Clang can be controlled by the flags
+listed below.
+
+.. option:: -fdebug-macro
+
+  Generate debug info for preprocessor macros. This flag is discarded when
+  **-g0** is enabled.
+
+.. option:: -fno-debug-macro
+
+  Do not generate debug info for preprocessor macros (default).
+
 Controlling Debugger "Tuning"
 ^
 

Modified: cfe/trunk/include/clang/CodeGen/ModuleBuilder.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/CodeGen/ModuleBuilder.h?rev=294637&r1=294636&r2=294637&view=diff
==
--- cfe/trunk/include/clang/CodeGen/ModuleBuilder.h (original)
+++ cfe/trunk/include/clang/CodeGen/ModuleBuilder.h Thu Feb  9 16:07:24 2017
@@ -35,6 +35,7 @@ namespace clang {
 
 namespace CodeGen {
   class CodeGenModule;
+  class CGDebugInfo;
 }
 
 /// The primary public interface to the Clang code generator.
@@ -65,6 +66,9 @@ public:
   /// CodeGenerator after releasing its module.
   llvm::Module *ReleaseModule();
 
+  /// Return debug info code generator.
+  CodeGen::CGDebugInfo *getCGDebugInfo();
+
   /// Given a mangled name, return a declaration which mangles that way
   /// which has been added to this code generator via a Handle method.
   ///

Modified: cfe/trunk/include/clang/Driver/CC1Options.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=294637&r1=294636&r2=294637&view=diff
==
--- cfe/trunk/include/clang/Driver/CC1Options.td (original)
+++ cfe/trunk/include/clang/Driver/CC1Options.td Thu Feb  9 16:07:24 2017
@@ -136,6 +136,8 @@ def migrator_no_finalize_removal : Flag<
 let Flags = [CC1Option, CC1AsOption, NoDriverOption] in {
 
 def debug_info_kind_EQ : Joined<["-"], "debug-info-kind=">;
+def debug_info_macro : Flag<["-"], "debug-info-macro">,
+  HelpText<"Emit macro debug information">;
 def dwarf_version_EQ : Joined<["-"], "dwarf-version=">;
 def debugger_tuning_EQ : Joined<["-"], "debugger-tuning=">;
 def fdebug_compilation_dir : Separate<["-"], "fdebug-compilation-dir">,

Modified: cfe/trunk/include/clang/Driver/Options.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=294637&r1=294636&r2=294637&view=diff
==
--- cfe/trunk/include/clang/Driver/Options.td (original)
+++ cfe/trunk/include/clang/Driver/Options.td Thu Feb  9 16:07:24 2017
@@ -1322,6 +1322,10 @@ def fno_standalone_debug : Flag<["-"], "
   HelpText<"Limit debug information produced to reduce size of debug binary">;
 def flimit_debug_info : Flag<["-"], "flimit-debug-info">, Flags<[CoreOption]>, 
Alias;
 def fno_limit_debug_info : Flag<["-"], "fno-limit-debug-info">, 
Flags<[CoreOption]>, Alias;
+def fdebug_macro : Flag<["-"], "fdebug-macro">, Group, 
Flags<[CoreOption]>,
+  HelpText<"Emit macro debug information">;
+def fno_debug_macro : Flag<["-"], "fno-debug-macro">, Group, 
Flags<[CoreOption]>,
+  HelpText<"Do not emit m

[PATCH] D16135: Macro Debug Info support in Clang

2016-11-03 Thread Amjad Aboud via cfe-commits
aaboud added a comment.

Thanks Richard for reviewing the patch and for the comments.
Please, see answers below.

Regards,
Amjad




Comment at: include/clang/AST/ASTConsumer.h:163
+  /// The caller takes ownership on the returned pointer.
+  virtual std::unique_ptr 
CreatePreprocessorCallbacks(Preprocessor &PP);
 };

rsmith wrote:
> aaboud wrote:
> > Richard,
> > I know that you suggested not to introduce the Preprocessor in anyway to 
> > the ASTConsumer.
> > However, as I could not understand the other way to support macros in Clang 
> > without applying a huge redesign, I decided to upload the code I suggested 
> > in the proposal.
> > http://lists.llvm.org/pipermail/llvm-dev/2015-November/092449.html
> > 
> > If you still think that this approach is not the right one, I would 
> > appreciate it if you can explain again how to implement the macro support 
> > differently.
> Don't add this to `ASTConsumer`; an AST consumer and a PP consumer are two 
> largely separate ideas. Instead, you could create and register a 
> `PPCallbacks` object directly from `CodeGenAction::CreateASTConsumer`. In 
> fact, if you look there, a `PPCallbacks` subclass is already registered (for 
> code coverage); you can do something similar to register your 
> `MacroPPCallbacks` object.
Thanks, I will try this approach, it is indeed cleaner.



Comment at: lib/CodeGen/CMakeLists.txt:76
   ItaniumCXXABI.cpp
+  MacroPPCallbacks.cpp
   MicrosoftCXXABI.cpp

rsmith wrote:
> This file is missing from the diff.
Sorry about that, it seems when I updated the code these files were removed 
from the patch.
Also, I need to improve the implementation in these two files.

By the way, you can find an old version of them in the previous diff.

I will update them and upload them to the review together with the above 
suggestion of yours.


https://reviews.llvm.org/D16135



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D13014: [X86] Add XSAVE intrinsics (Clang part)

2015-09-21 Thread Amjad Aboud via cfe-commits
aaboud created this revision.
aaboud added reviewers: mkuper, delena, craig.topper.
aaboud added a subscriber: cfe-commits.
aaboud set the repository for this revision to rL LLVM.

Add intrinsics for the XSAVE instructions:
XSAVE, XSAVE64
XRSTOR, XRSTOR64
XSAVEOPT, XSAVEOPT64
XRSTORS, XRSTORS64
XSAVEC, XSAVEC64
XSAVES, XSAVES64

These were previously declared in Intrin.h for MSVC compatibility, but now
that we have them implemented, these declarations can be removed.

Repository:
  rL LLVM

http://reviews.llvm.org/D13014

Files:
  include/clang/Basic/BuiltinsX86.def
  lib/CodeGen/CGBuiltin.cpp
  lib/Headers/CMakeLists.txt
  lib/Headers/Intrin.h
  lib/Headers/immintrin.h
  lib/Headers/xsavecintrin.h
  lib/Headers/xsaveintrin.h
  lib/Headers/xsaveoptintrin.h
  lib/Headers/xsavesintrin.h
  test/CodeGen/builtins-x86.c

Index: lib/Headers/xsaveintrin.h
===
--- lib/Headers/xsaveintrin.h
+++ lib/Headers/xsaveintrin.h
@@ -0,0 +1,58 @@
+/*=== xsaveintrin.h - XSAVE intrinsic ===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===---===
+ */
+
+#ifndef __IMMINTRIN_H
+#error "Never use  directly; include  instead."
+#endif
+
+#ifndef __XSAVEINTRIN_H
+#define __XSAVEINTRIN_H
+
+/* Define the default attributes for the functions in this file. */
+#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__,  __target__("xsave")))
+
+static __inline__ void __DEFAULT_FN_ATTRS
+_xsave(void *__p, unsigned long long __m) {
+  return __builtin_ia32_xsave(__p, __m);
+}
+
+static __inline__ void __DEFAULT_FN_ATTRS
+_xrstor(void *__p, unsigned long long __m) {
+  return __builtin_ia32_xrstor(__p, __m);
+}
+
+#ifdef __x86_64__
+static __inline__ void __DEFAULT_FN_ATTRS
+_xsave64(void *__p, unsigned long long __m) {
+  return __builtin_ia32_xsave64(__p, __m);
+}
+
+static __inline__ void __DEFAULT_FN_ATTRS
+_xrstor64(void *__p, unsigned long long __m) {
+  return __builtin_ia32_xrstor64(__p, __m);
+}
+#endif
+
+#undef __DEFAULT_FN_ATTRS
+
+#endif
Index: lib/Headers/CMakeLists.txt
===
--- lib/Headers/CMakeLists.txt
+++ lib/Headers/CMakeLists.txt
@@ -66,6 +66,10 @@
   x86intrin.h
   xmmintrin.h
   xopintrin.h
+  xsaveintrin.h
+  xsaveoptintrin.h
+  xsavecintrin.h
+  xsavesintrin.h
   xtestintrin.h
   )
 
Index: lib/Headers/immintrin.h
===
--- lib/Headers/immintrin.h
+++ lib/Headers/immintrin.h
@@ -144,6 +144,14 @@
 
 #include 
 
+#include 
+
+#include 
+
+#include 
+
+#include 
+
 /* Some intrinsics inside adxintrin.h are available only on processors with ADX,
  * whereas others are also available at all times. */
 #include 
Index: lib/Headers/xsavesintrin.h
===
--- lib/Headers/xsavesintrin.h
+++ lib/Headers/xsavesintrin.h
@@ -0,0 +1,58 @@
+/*=== xsavesintrin.h - XSAVES intrinsic ===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO E

Re: [PATCH] D13014: [X86] Add XSAVE intrinsics (Clang part)

2015-10-12 Thread Amjad Aboud via cfe-commits
aaboud added a comment.

In http://reviews.llvm.org/D13014#264638, @delena wrote:

> Do you need to add some tests for clang?


I thought I did (see "builtins-x86.c").
This is how other intrinsic instructions are tested by clang, am I missing 
something?


Repository:
  rL LLVM

http://reviews.llvm.org/D13014



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D13014: [X86] Add XSAVE intrinsics (Clang part)

2015-10-12 Thread Amjad Aboud via cfe-commits
aaboud updated this revision to Diff 37108.
aaboud added a comment.

Added two LIT tests to check the xsave intrinsic instructions.


Repository:
  rL LLVM

http://reviews.llvm.org/D13014

Files:
  include/clang/Basic/BuiltinsX86.def
  lib/CodeGen/CGBuiltin.cpp
  lib/Headers/CMakeLists.txt
  lib/Headers/Intrin.h
  lib/Headers/immintrin.h
  lib/Headers/xsavecintrin.h
  lib/Headers/xsaveintrin.h
  lib/Headers/xsaveoptintrin.h
  lib/Headers/xsavesintrin.h
  test/CodeGen/builtins-x86.c
  test/CodeGen/x86_32-xsave.c
  test/CodeGen/x86_64-xsave.c

Index: lib/Headers/xsaveintrin.h
===
--- lib/Headers/xsaveintrin.h
+++ lib/Headers/xsaveintrin.h
@@ -0,0 +1,58 @@
+/*=== xsaveintrin.h - XSAVE intrinsic ===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===---===
+ */
+
+#ifndef __IMMINTRIN_H
+#error "Never use  directly; include  instead."
+#endif
+
+#ifndef __XSAVEINTRIN_H
+#define __XSAVEINTRIN_H
+
+/* Define the default attributes for the functions in this file. */
+#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__,  __target__("xsave")))
+
+static __inline__ void __DEFAULT_FN_ATTRS
+_xsave(void *__p, unsigned long long __m) {
+  return __builtin_ia32_xsave(__p, __m);
+}
+
+static __inline__ void __DEFAULT_FN_ATTRS
+_xrstor(void *__p, unsigned long long __m) {
+  return __builtin_ia32_xrstor(__p, __m);
+}
+
+#ifdef __x86_64__
+static __inline__ void __DEFAULT_FN_ATTRS
+_xsave64(void *__p, unsigned long long __m) {
+  return __builtin_ia32_xsave64(__p, __m);
+}
+
+static __inline__ void __DEFAULT_FN_ATTRS
+_xrstor64(void *__p, unsigned long long __m) {
+  return __builtin_ia32_xrstor64(__p, __m);
+}
+#endif
+
+#undef __DEFAULT_FN_ATTRS
+
+#endif
Index: lib/Headers/CMakeLists.txt
===
--- lib/Headers/CMakeLists.txt
+++ lib/Headers/CMakeLists.txt
@@ -66,6 +66,10 @@
   x86intrin.h
   xmmintrin.h
   xopintrin.h
+  xsaveintrin.h
+  xsaveoptintrin.h
+  xsavecintrin.h
+  xsavesintrin.h
   xtestintrin.h
   )
 
Index: lib/Headers/immintrin.h
===
--- lib/Headers/immintrin.h
+++ lib/Headers/immintrin.h
@@ -144,6 +144,14 @@
 
 #include 
 
+#include 
+
+#include 
+
+#include 
+
+#include 
+
 /* Some intrinsics inside adxintrin.h are available only on processors with ADX,
  * whereas others are also available at all times. */
 #include 
Index: lib/Headers/xsavesintrin.h
===
--- lib/Headers/xsavesintrin.h
+++ lib/Headers/xsavesintrin.h
@@ -0,0 +1,58 @@
+/*=== xsavesintrin.h - XSAVES intrinsic ===
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ *===-

r250158 - [X86] Add XSAVE intrinsic family

2015-10-13 Thread Amjad Aboud via cfe-commits
Author: aaboud
Date: Tue Oct 13 07:29:35 2015
New Revision: 250158

URL: http://llvm.org/viewvc/llvm-project?rev=250158&view=rev
Log:
[X86] Add XSAVE intrinsic family

Add intrinsics for the
  XSAVE instructions (XSAVE/XSAVE64/XRSTOR/XRSTOR64)
  XSAVEOPT instructions (XSAVEOPT/XSAVEOPT64)
  XSAVEC instructions (XSAVEC/XSAVEC64)
  XSAVES instructions (XSAVES/XSAVES64/XRSTORS/XRSTORS64)

Differential Revision: http://reviews.llvm.org/D13014

Added:
cfe/trunk/lib/Headers/xsavecintrin.h
cfe/trunk/lib/Headers/xsaveintrin.h
cfe/trunk/lib/Headers/xsaveoptintrin.h
cfe/trunk/lib/Headers/xsavesintrin.h
cfe/trunk/test/CodeGen/x86_32-xsave.c
cfe/trunk/test/CodeGen/x86_64-xsave.c
Modified:
cfe/trunk/include/clang/Basic/BuiltinsX86.def
cfe/trunk/lib/CodeGen/CGBuiltin.cpp
cfe/trunk/lib/Headers/CMakeLists.txt
cfe/trunk/lib/Headers/Intrin.h
cfe/trunk/lib/Headers/immintrin.h
cfe/trunk/test/CodeGen/builtins-x86.c

Modified: cfe/trunk/include/clang/Basic/BuiltinsX86.def
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/BuiltinsX86.def?rev=250158&r1=250157&r2=250158&view=diff
==
--- cfe/trunk/include/clang/Basic/BuiltinsX86.def (original)
+++ cfe/trunk/include/clang/Basic/BuiltinsX86.def Tue Oct 13 07:29:35 2015
@@ -665,6 +665,20 @@ BUILTIN(__builtin_ia32_fxrstor64, "vv*",
 BUILTIN(__builtin_ia32_fxsave, "vv*", "")
 BUILTIN(__builtin_ia32_fxsave64, "vv*", "")
 
+// XSAVE
+BUILTIN(__builtin_ia32_xsave, "vv*ULLi", "")
+BUILTIN(__builtin_ia32_xsave64, "vv*ULLi", "")
+BUILTIN(__builtin_ia32_xrstor, "vv*ULLi", "")
+BUILTIN(__builtin_ia32_xrstor64, "vv*ULLi", "")
+BUILTIN(__builtin_ia32_xsaveopt, "vv*ULLi", "")
+BUILTIN(__builtin_ia32_xsaveopt64, "vv*ULLi", "")
+BUILTIN(__builtin_ia32_xrstors, "vv*ULLi", "")
+BUILTIN(__builtin_ia32_xrstors64, "vv*ULLi", "")
+BUILTIN(__builtin_ia32_xsavec, "vv*ULLi", "")
+BUILTIN(__builtin_ia32_xsavec64, "vv*ULLi", "")
+BUILTIN(__builtin_ia32_xsaves, "vv*ULLi", "")
+BUILTIN(__builtin_ia32_xsaves64, "vv*ULLi", "")
+
 // ADX
 TARGET_BUILTIN(__builtin_ia32_addcarryx_u32, "UcUcUiUiUi*", "", "adx")
 TARGET_BUILTIN(__builtin_ia32_addcarryx_u64, "UcUcULLiULLiULLi*", "", "adx")

Modified: cfe/trunk/lib/CodeGen/CGBuiltin.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBuiltin.cpp?rev=250158&r1=250157&r2=250158&view=diff
==
--- cfe/trunk/lib/CodeGen/CGBuiltin.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBuiltin.cpp Tue Oct 13 07:29:35 2015
@@ -6083,6 +6083,46 @@ Value *CodeGenFunction::EmitX86BuiltinEx
Builder.CreateBitCast(Tmp.getPointer(), Int8PtrTy));
 return Builder.CreateLoad(Tmp, "stmxcsr");
   }
+  case X86::BI__builtin_ia32_xsave:
+  case X86::BI__builtin_ia32_xsave64:
+  case X86::BI__builtin_ia32_xrstor:
+  case X86::BI__builtin_ia32_xrstor64:
+  case X86::BI__builtin_ia32_xsaveopt:
+  case X86::BI__builtin_ia32_xsaveopt64:
+  case X86::BI__builtin_ia32_xrstors:
+  case X86::BI__builtin_ia32_xrstors64:
+  case X86::BI__builtin_ia32_xsavec:
+  case X86::BI__builtin_ia32_xsavec64:
+  case X86::BI__builtin_ia32_xsaves:
+  case X86::BI__builtin_ia32_xsaves64: {
+Intrinsic::ID ID;
+#define INTRINSIC_X86_XSAVE_ID(NAME) \
+case X86::BI__builtin_ia32_##NAME: \
+  ID = Intrinsic::x86_##NAME; \
+  break
+switch (BuiltinID) {
+default: llvm_unreachable("Unsupported intrinsic!");
+INTRINSIC_X86_XSAVE_ID(xsave);
+INTRINSIC_X86_XSAVE_ID(xsave64);
+INTRINSIC_X86_XSAVE_ID(xrstor);
+INTRINSIC_X86_XSAVE_ID(xrstor64);
+INTRINSIC_X86_XSAVE_ID(xsaveopt);
+INTRINSIC_X86_XSAVE_ID(xsaveopt64);
+INTRINSIC_X86_XSAVE_ID(xrstors);
+INTRINSIC_X86_XSAVE_ID(xrstors64);
+INTRINSIC_X86_XSAVE_ID(xsavec);
+INTRINSIC_X86_XSAVE_ID(xsavec64);
+INTRINSIC_X86_XSAVE_ID(xsaves);
+INTRINSIC_X86_XSAVE_ID(xsaves64);
+}
+#undef INTRINSIC_X86_XSAVE_ID
+Value *Mhi = Builder.CreateTrunc(
+  Builder.CreateLShr(Ops[1], ConstantInt::get(Int64Ty, 32)), Int32Ty);
+Value *Mlo = Builder.CreateTrunc(Ops[1], Int32Ty);
+Ops[1] = Mhi;
+Ops.push_back(Mlo);
+return Builder.CreateCall(CGM.getIntrinsic(ID), Ops);
+  }
   case X86::BI__builtin_ia32_storehps:
   case X86::BI__builtin_ia32_storelps: {
 llvm::Type *PtrTy = llvm::PointerType::getUnqual(Int64Ty);

Modified: cfe/trunk/lib/Headers/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/CMakeLists.txt?rev=250158&r1=250157&r2=250158&view=diff
==
--- cfe/trunk/lib/Headers/CMakeLists.txt (original)
+++ cfe/trunk/lib/Headers/CMakeLists.txt Tue Oct 13 07:29:35 2015
@@ -66,6 +66,10 @@ set(files
   x86intrin.h
   xmmintrin.h
   xopintrin.h
+  xsaveintrin.h
+  xsaveoptintrin.h
+  xsavecintrin.h
+  xsavesintrin.h
   xtestintrin.h
   )
 

Modified: cf

Re: [PATCH] D13014: [X86] Add XSAVE intrinsics (Clang part)

2015-10-13 Thread Amjad Aboud via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL250158: [X86] Add XSAVE intrinsic family (authored by 
aaboud).

Changed prior to commit:
  http://reviews.llvm.org/D13014?vs=37108&id=37238#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D13014

Files:
  cfe/trunk/include/clang/Basic/BuiltinsX86.def
  cfe/trunk/lib/CodeGen/CGBuiltin.cpp
  cfe/trunk/lib/Headers/CMakeLists.txt
  cfe/trunk/lib/Headers/Intrin.h
  cfe/trunk/lib/Headers/immintrin.h
  cfe/trunk/lib/Headers/xsavecintrin.h
  cfe/trunk/lib/Headers/xsaveintrin.h
  cfe/trunk/lib/Headers/xsaveoptintrin.h
  cfe/trunk/lib/Headers/xsavesintrin.h
  cfe/trunk/test/CodeGen/builtins-x86.c
  cfe/trunk/test/CodeGen/x86_32-xsave.c
  cfe/trunk/test/CodeGen/x86_64-xsave.c

Index: cfe/trunk/test/CodeGen/x86_32-xsave.c
===
--- cfe/trunk/test/CodeGen/x86_32-xsave.c
+++ cfe/trunk/test/CodeGen/x86_32-xsave.c
@@ -0,0 +1,72 @@
+// RUN: %clang_cc1 %s -DTEST_XSAVE -O0 -triple=i686-unknown-unknown -target-feature +xsave -emit-llvm -o - -Werror | FileCheck %s --check-prefix=XSAVE
+// RUN: %clang_cc1 %s -DTEST_XSAVE -O0 -triple=i686-unknown-unknown -target-feature +xsave -fno-signed-char -emit-llvm -o - -Werror | FileCheck %s --check-prefix=XSAVE
+
+// RUN: %clang_cc1 %s -DTEST_XSAVEOPT -O0 -triple=i686-unknown-unknown -target-feature +xsave,+xsaveopt -emit-llvm -o - -Werror | FileCheck %s --check-prefix=XSAVEOPT
+// RUN: %clang_cc1 %s -DTEST_XSAVEOPT -O0 -triple=i686-unknown-unknown -target-feature +xsave,+xsaveopt -fno-signed-char -emit-llvm -o - -Werror | FileCheck %s --check-prefix=XSAVEOPT
+
+// RUN: %clang_cc1 %s -DTEST_XSAVEC -O0 -triple=i686-unknown-unknown -target-feature +xsave,+xsavec -emit-llvm -o - -Werror | FileCheck %s --check-prefix=XSAVEC
+// RUN: %clang_cc1 %s -DTEST_XSAVEC -O0 -triple=i686-unknown-unknown -target-feature +xsave,+xsavec -fno-signed-char -emit-llvm -o - -Werror | FileCheck %s --check-prefix=XSAVEC
+
+// RUN: %clang_cc1 %s -DTEST_XSAVES -O0 -triple=i686-unknown-unknown -target-feature +xsave,+xsaves -emit-llvm -o - -Werror | FileCheck %s --check-prefix=XSAVES
+// RUN: %clang_cc1 %s -DTEST_XSAVES -O0 -triple=i686-unknown-unknown -target-feature +xsave,+xsaves -fno-signed-char -emit-llvm -o - -Werror | FileCheck %s --check-prefix=XSAVES
+
+void test() {
+  unsigned long long tmp_ULLi;
+  void*  tmp_vp;
+
+#ifdef TEST_XSAVE
+// XSAVE: [[tmp_vp_1:%[0-9a-zA-z]+]] = load i8*, i8** %tmp_vp, align 4
+// XSAVE: [[tmp_ULLi_1:%[0-9a-zA-z]+]] = load i64, i64* %tmp_ULLi, align 8
+// XSAVE: [[high64_1:%[0-9a-zA-z]+]] = lshr i64 [[tmp_ULLi_1]], 32
+// XSAVE: [[high32_1:%[0-9a-zA-z]+]] = trunc i64 [[high64_1]] to i32
+// XSAVE: [[low32_1:%[0-9a-zA-z]+]] = trunc i64 [[tmp_ULLi_1]] to i32
+// XSAVE: call void @llvm.x86.xsave(i8* [[tmp_vp_1]], i32 [[high32_1]], i32 [[low32_1]])
+  (void)__builtin_ia32_xsave(tmp_vp, tmp_ULLi);
+
+// XSAVE: [[tmp_vp_3:%[0-9a-zA-z]+]] = load i8*, i8** %tmp_vp, align 4
+// XSAVE: [[tmp_ULLi_3:%[0-9a-zA-z]+]] = load i64, i64* %tmp_ULLi, align 8
+// XSAVE: [[high64_3:%[0-9a-zA-z]+]] = lshr i64 [[tmp_ULLi_3]], 32
+// XSAVE: [[high32_3:%[0-9a-zA-z]+]] = trunc i64 [[high64_3]] to i32
+// XSAVE: [[low32_3:%[0-9a-zA-z]+]] = trunc i64 [[tmp_ULLi_3]] to i32
+// XSAVE: call void @llvm.x86.xrstor(i8* [[tmp_vp_3]], i32 [[high32_3]], i32 [[low32_3]])
+  (void)__builtin_ia32_xrstor(tmp_vp, tmp_ULLi);
+#endif
+
+#ifdef TEST_XSAVEOPT
+// XSAVEOPT: [[tmp_vp_1:%[0-9a-zA-z]+]] = load i8*, i8** %tmp_vp, align 4
+// XSAVEOPT: [[tmp_ULLi_1:%[0-9a-zA-z]+]] = load i64, i64* %tmp_ULLi, align 8
+// XSAVEOPT: [[high64_1:%[0-9a-zA-z]+]] = lshr i64 [[tmp_ULLi_1]], 32
+// XSAVEOPT: [[high32_1:%[0-9a-zA-z]+]] = trunc i64 [[high64_1]] to i32
+// XSAVEOPT: [[low32_1:%[0-9a-zA-z]+]] = trunc i64 [[tmp_ULLi_1]] to i32
+// XSAVEOPT: call void @llvm.x86.xsaveopt(i8* [[tmp_vp_1]], i32 [[high32_1]], i32 [[low32_1]])
+  (void)__builtin_ia32_xsaveopt(tmp_vp, tmp_ULLi);
+#endif
+
+#ifdef TEST_XSAVEC
+// XSAVEC: [[tmp_vp_1:%[0-9a-zA-z]+]] = load i8*, i8** %tmp_vp, align 4
+// XSAVEC: [[tmp_ULLi_1:%[0-9a-zA-z]+]] = load i64, i64* %tmp_ULLi, align 8
+// XSAVEC: [[high64_1:%[0-9a-zA-z]+]] = lshr i64 [[tmp_ULLi_1]], 32
+// XSAVEC: [[high32_1:%[0-9a-zA-z]+]] = trunc i64 [[high64_1]] to i32
+// XSAVEC: [[low32_1:%[0-9a-zA-z]+]] = trunc i64 [[tmp_ULLi_1]] to i32
+// XSAVEC: call void @llvm.x86.xsavec(i8* [[tmp_vp_1]], i32 [[high32_1]], i32 [[low32_1]])
+  (void)__builtin_ia32_xsavec(tmp_vp, tmp_ULLi);
+#endif
+
+#ifdef TEST_XSAVES
+// XSAVES: [[tmp_vp_1:%[0-9a-zA-z]+]] = load i8*, i8** %tmp_vp, align 4
+// XSAVES: [[tmp_ULLi_1:%[0-9a-zA-z]+]] = load i64, i64* %tmp_ULLi, align 8
+// XSAVES: [[high64_1:%[0-9a-zA-z]+]] = lshr i64 [[tmp_ULLi_1]], 32
+// XSAVES: [[high32_1:%[0-9a-zA-z]+]] = trunc i64 [[high64_1]] to i32
+// XSAVES: [[low32_1:%[0-9a-zA-z]+]] = trunc i64 [[tmp_ULLi_1]] to i32
+// XSAVES: call void @llvm.x86.xsaves(i8* [[tmp_vp_1]], i32 [[high32_1]], i

Re: [PATCH] D22045: [X86] Support of no_caller_saved_registers attribute (Clang part)

2016-07-24 Thread Amjad Aboud via cfe-commits
aaboud marked an inline comment as done.


Comment at: include/clang/Basic/Attr.td:1657
@@ +1656,3 @@
+   TargetSpecificAttr {
+  let Spellings = [GNU<"no_caller_saved_registers">];
+  let Subjects = SubjectList<[FunctionLike], WarnDiag, "ExpectedFunction">;

aaron.ballman wrote:
> Any particular reason this isn't (also) a C++-style attribute under the clang 
> namespace?
I am not sure about that, I was just following the way the "interrupt" 
attribute was defined.
Do you think we should change both to consider C++ style attribute as well?


Comment at: include/clang/Basic/AttrDocs.td:2177
@@ +2176,3 @@
+Use this attribute to indicate that the specified function has no
+caller-saved registers.  That is, all registers are callee-saved.
+The compiler generates proper function entry and exit sequences to

aaron.ballman wrote:
> How does this interact with calling convention attributes? For instance, if I 
> have a function that is explicitly marked cdecl and has this attribute, what 
> is the behavior for EAX, ECX, and EDX?
> 
> Also, why is this an attribute rather than a calling convention? I'm 
> wondering how this works through function pointers, for instance (whether it 
> is intended to work or not).
Please, correct me if I am mistaken, but calling convention determine not only 
what the callee and the caller function saved registers are, but also how we 
move parameters to the called function, right?

The idea behind no_caller_saved_registers attribute, is that it can be combined 
with any other calling convention, and it only override the callee/caller saved 
register list, but not the way parameters are passed to the called function.

So, using a calling convention for this attribute will not be right.

H.J., can you confirm this?


https://reviews.llvm.org/D22045



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D22045: [X86] Support of no_caller_saved_registers attribute (Clang part)

2016-07-24 Thread Amjad Aboud via cfe-commits
aaboud updated this revision to Diff 65269.
aaboud added a comment.

Updated test according to comments.


https://reviews.llvm.org/D22045

Files:
  include/clang/Basic/Attr.td
  include/clang/Basic/AttrDocs.td
  lib/CodeGen/CGCall.cpp
  lib/Sema/SemaDeclAttr.cpp
  test/CodeGenCXX/attr-x86-no_caller_saved_registers.cpp
  test/SemaCXX/attr-x86-no_caller_saved_registers.cpp

Index: lib/CodeGen/CGCall.cpp
===
--- lib/CodeGen/CGCall.cpp
+++ lib/CodeGen/CGCall.cpp
@@ -1673,6 +1673,8 @@
   RetAttrs.addAttribute(llvm::Attribute::NoAlias);
 if (TargetDecl->hasAttr())
   RetAttrs.addAttribute(llvm::Attribute::NonNull);
+if (TargetDecl->hasAttr())
+  FuncAttrs.addAttribute("no_caller_saved_registers");
 
 HasAnyX86InterruptAttr = TargetDecl->hasAttr();
 HasOptnone = TargetDecl->hasAttr();
Index: lib/Sema/SemaDeclAttr.cpp
===
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -5910,6 +5910,10 @@
 handleTypeTagForDatatypeAttr(S, D, Attr);
 break;
 
+  case AttributeList::AT_AnyX86NoCallerSavedRegisters:
+handleSimpleAttribute(S, D, Attr);
+break;
+
   case AttributeList::AT_RenderScriptKernel:
 handleSimpleAttribute(S, D, Attr);
 break;
Index: include/clang/Basic/AttrDocs.td
===
--- include/clang/Basic/AttrDocs.td
+++ include/clang/Basic/AttrDocs.td
@@ -2170,6 +2170,20 @@
   }];
 }
 
+def AnyX86NoCallerSavedRegistersDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+Use this attribute to indicate that the specified function has no
+caller-saved registers.  That is, all registers are callee-saved.
+The compiler generates proper function entry and exit sequences to
+save and restore any modified registers.
+
+The user can call functions specified with the 'no_caller_saved_registers'
+attribute from an interrupt handler without saving and restoring all
+call clobbered registers.
+  }];
+}
+
 def SwiftCallDocs : Documentation {
   let Category = DocCatVariable;
   let Content = [{
Index: include/clang/Basic/Attr.td
===
--- include/clang/Basic/Attr.td
+++ include/clang/Basic/Attr.td
@@ -1652,6 +1652,13 @@
   let Documentation = [AnyX86InterruptDocs];
 }
 
+def AnyX86NoCallerSavedRegisters : InheritableAttr,
+   TargetSpecificAttr {
+  let Spellings = [GNU<"no_caller_saved_registers">];
+  let Subjects = SubjectList<[FunctionLike], WarnDiag, "ExpectedFunction">;
+  let Documentation = [AnyX86NoCallerSavedRegistersDocs];
+}
+
 def X86ForceAlignArgPointer : InheritableAttr, TargetSpecificAttr {
   let Spellings = [GNU<"force_align_arg_pointer">];
   // Technically, this appertains to a FunctionDecl, but the target-specific
Index: test/SemaCXX/attr-x86-no_caller_saved_registers.cpp
===
--- test/SemaCXX/attr-x86-no_caller_saved_registers.cpp
+++ test/SemaCXX/attr-x86-no_caller_saved_registers.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple i386-unknown-linux-gnu -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple x86_64-pc-win32 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple i386-pc-win32 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnux32 -fsyntax-only -verify %s
+
+struct a {
+  int b __attribute__((no_caller_saved_registers)); // expected-warning {{'no_caller_saved_registers' attribute only applies to functions}}
+  static void foo(int *a) __attribute__((no_caller_saved_registers)) {}
+};
+
+struct a test __attribute__((no_caller_saved_registers)); // expected-warning {{'no_caller_saved_registers' attribute only applies to functions}}
+
+__attribute__((no_caller_saved_registers(999))) void bar(int *) {} // expected-error {{'no_caller_saved_registers' attribute takes no arguments}}
+
+__attribute__((no_caller_saved_registers)) void foo(int *) {}
+
+int main(int argc, char **argv) {
+  a::foo(&argc);
+  foo(&argc);
+  return 0;
+}
Index: test/CodeGenCXX/attr-x86-no_caller_saved_registers.cpp
===
--- test/CodeGenCXX/attr-x86-no_caller_saved_registers.cpp
+++ test/CodeGenCXX/attr-x86-no_caller_saved_registers.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i386-unknown-linux-gnu %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-pc-win32 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i386-pc-win32 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnux32 %s -emit-llvm -o - | FileCheck %s
+
+// CHECK: foo{{[^#]*}}#[[ATTRS:[0-9]+]]
+__attribute__((no_caller_saved_registe

Re: [PATCH] D16135: Macro Debug Info support in Clang

2016-07-26 Thread Amjad Aboud via cfe-commits
aaboud added reviewers: erichkeane, bwyma.
aaboud updated this revision to Diff 65551.
aaboud added a comment.

Updated patch to top of trunk (r276746) - Thanks to Ranjeet Singh.

Please, provide your feedback.


https://reviews.llvm.org/D16135

Files:
  include/clang/AST/ASTConsumer.h
  lib/AST/ASTConsumer.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CGDebugInfo.h
  lib/CodeGen/CMakeLists.txt
  lib/CodeGen/CodeGenAction.cpp
  lib/CodeGen/CodeGenModule.cpp
  lib/CodeGen/CodeGenModule.h
  lib/CodeGen/ModuleBuilder.cpp
  lib/Parse/ParseAST.cpp

Index: lib/Parse/ParseAST.cpp
===
--- lib/Parse/ParseAST.cpp
+++ lib/Parse/ParseAST.cpp
@@ -127,6 +127,12 @@
   new Parser(S.getPreprocessor(), S, SkipFunctionBodies));
   Parser &P = *ParseOP.get();
 
+  std::unique_ptr Callbacks =
+  Consumer->CreatePreprocessorCallbacks(S.getPreprocessor());
+  if (Callbacks) {
+S.getPreprocessor().addPPCallbacks(std::move(Callbacks));
+  }
+
   llvm::CrashRecoveryContextCleanupRegistrar
   CleanupPrettyStack(llvm::SavePrettyStackState());
   PrettyStackTraceParserEntry CrashInfo(P);
Index: lib/CodeGen/ModuleBuilder.cpp
===
--- lib/CodeGen/ModuleBuilder.cpp
+++ lib/CodeGen/ModuleBuilder.cpp
@@ -20,6 +20,7 @@
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Frontend/CodeGenOptions.h"
+#include "clang/Lex/PPCallbacks.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/LLVMContext.h"
@@ -130,6 +131,11 @@
 Builder->AppendLinkerOptions(Opt);
 }
 
+std::unique_ptr
+CreatePreprocessorCallbacks(Preprocessor &PP) override {
+  return Builder->createPreprocessorCallbacks(PP);
+}
+
 void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override {
   if (Diags.hasErrorOccurred())
 return;
Index: lib/CodeGen/CodeGenModule.cpp
===
--- lib/CodeGen/CodeGenModule.cpp
+++ lib/CodeGen/CodeGenModule.cpp
@@ -25,6 +25,7 @@
 #include "CodeGenPGO.h"
 #include "CodeGenTBAA.h"
 #include "CoverageMappingGen.h"
+#include "MacroPPCallbacks.h"
 #include "TargetInfo.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CharUnits.h"
@@ -204,6 +205,16 @@
   CUDARuntime.reset(CreateNVCUDARuntime(*this));
 }
 
+std::unique_ptr
+CodeGenModule::createPreprocessorCallbacks(Preprocessor &PP) {
+  // Enable generating macro debug info only in FullDebugInfo mode.
+  if (CodeGenOpts.getDebugInfo() < codegenoptions::FullDebugInfo ||
+  !getModuleDebugInfo())
+return nullptr;
+
+  return llvm::make_unique(*getModuleDebugInfo(), PP);
+}
+
 void CodeGenModule::addReplacement(StringRef Name, llvm::Constant *C) {
   Replacements[Name] = C;
 }
Index: lib/CodeGen/CMakeLists.txt
===
--- lib/CodeGen/CMakeLists.txt
+++ lib/CodeGen/CMakeLists.txt
@@ -73,6 +73,7 @@
   CodeGenTypes.cpp
   CoverageMappingGen.cpp
   ItaniumCXXABI.cpp
+  MacroPPCallbacks.cpp
   MicrosoftCXXABI.cpp
   ModuleBuilder.cpp
   ObjectFilePCHContainerOperations.cpp
Index: lib/CodeGen/CGDebugInfo.h
===
--- lib/CodeGen/CGDebugInfo.h
+++ lib/CodeGen/CGDebugInfo.h
@@ -386,6 +386,16 @@
 
   void completeTemplateDefinition(const ClassTemplateSpecializationDecl &SD);
 
+  /// Get Macro debug info.
+  llvm::DIMacro *CreateMacro(llvm::DIMacroFile *Parent, unsigned MType,
+ SourceLocation LineLoc, StringRef Name,
+ StringRef Value);
+
+  /// Get Macro File debug info.
+  llvm::DIMacroFile *CreateMacroFile(llvm::DIMacroFile *Parent,
+ SourceLocation LineLoc,
+ SourceLocation FileLoc);
+
 private:
   /// Emit call to llvm.dbg.declare for a variable declaration.
   void EmitDeclare(const VarDecl *decl, llvm::Value *AI,
Index: lib/CodeGen/CodeGenAction.cpp
===
--- lib/CodeGen/CodeGenAction.cpp
+++ lib/CodeGen/CodeGenAction.cpp
@@ -222,6 +222,11 @@
   Gen->HandleVTable(RD);
 }
 
+std::unique_ptr
+CreatePreprocessorCallbacks(Preprocessor &PP) override {
+  return Gen->CreatePreprocessorCallbacks(PP);
+}
+
 static void InlineAsmDiagHandler(const llvm::SMDiagnostic &SM,void *Context,
  unsigned LocCookie) {
   SourceLocation Loc = SourceLocation::getFromRawEncoding(LocCookie);
Index: lib/CodeGen/CGDebugInfo.cpp
===
--- lib/CodeGen/CGDebugInfo.cpp
+++ lib/CodeGen/CGDebugInfo.cpp
@@ -2264,6 +2264,22 @@
 FullName);
 }
 
+llvm::DIMacro *CGDebugInfo::CreateMacro(llvm::DIMacroFile *Parent,
+   

Re: [PATCH] D22900: Revert r244207 - Mark calls in thunk functions as tail-call optimization

2016-07-31 Thread Amjad Aboud via cfe-commits
aaboud added a comment.

Reverting https://reviews.llvm.org/rL244207, would be fine if we assure that 
PR24235, is fixed in another way.
I added Reid who helped reviewing the original patch 
https://reviews.llvm.org/D11476.


https://reviews.llvm.org/D22900



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D22900: Revert r244207 - Mark calls in thunk functions as tail-call optimization

2016-07-31 Thread Amjad Aboud via cfe-commits
aaboud added a comment.

> ISTM that the DWARF spec intended such thunks to be encoded as 
> `DW_AT_trampoline`.  That seems more appropriate than relying on codegen 
> emitting a tailcall.  This way the debugger can make the policy decision of 
> whether or not thunks should show up in the backtrace.

> 

> In any case, correctness must always trump all else.  Reverting to green 
> should take precedence over a QoI bug like PR24235.


I agree to the revert, though I am not sure about the new test, it looks too 
complected, especially the command line.
I will let David decide on accepting that test or ask for improvement.

Regards,
Amjad


https://reviews.llvm.org/D22900



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D22045: [X86] Support of no_caller_saved_registers attribute (Clang part)

2016-08-04 Thread Amjad Aboud via cfe-commits
aaboud updated this revision to Diff 66810.
aaboud added a comment.

Made "no_caller_saved_registers" part of function prototype.
This will allow Clang to yell a warning when there is a mismatch between 
function pointer and assigned function value.

Thanks to Erich for implementing this addition change.


https://reviews.llvm.org/D22045

Files:
  include/clang/AST/Type.h
  include/clang/Basic/Attr.td
  include/clang/Basic/AttrDocs.td
  include/clang/CodeGen/CGFunctionInfo.h
  include/clang/Sema/Sema.h
  lib/AST/ASTContext.cpp
  lib/AST/TypePrinter.cpp
  lib/CodeGen/CGCall.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaDeclAttr.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTReader.cpp
  lib/Serialization/ASTWriter.cpp
  test/CodeGenCXX/attr-x86-no_caller_saved_registers.cpp
  test/SemaCXX/attr-x86-no_caller_saved_registers.cpp

Index: lib/Serialization/ASTWriter.cpp
===
--- lib/Serialization/ASTWriter.cpp
+++ lib/Serialization/ASTWriter.cpp
@@ -221,6 +221,7 @@
   // FIXME: need to stabilize encoding of calling convention...
   Record.push_back(C.getCC());
   Record.push_back(C.getProducesResult());
+  Record.push_back(C.getNoCallerSavedRegs());
 
   if (C.getHasRegParm() || C.getRegParm() || C.getProducesResult())
 AbbrevToUse = 0;
@@ -731,6 +732,7 @@
   Abv->Add(BitCodeAbbrevOp(0)); // RegParm
   Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // CC
   Abv->Add(BitCodeAbbrevOp(0)); // ProducesResult
+  Abv->Add(BitCodeAbbrevOp(0)); // NoCallerSavedRegs
   // FunctionProtoType
   Abv->Add(BitCodeAbbrevOp(0)); // IsVariadic
   Abv->Add(BitCodeAbbrevOp(0)); // HasTrailingReturn
Index: lib/Serialization/ASTReader.cpp
===
--- lib/Serialization/ASTReader.cpp
+++ lib/Serialization/ASTReader.cpp
@@ -5368,13 +5368,14 @@
   }
 
   case TYPE_FUNCTION_NO_PROTO: {
-if (Record.size() != 6) {
+if (Record.size() != 7) {
   Error("incorrect encoding of no-proto function type");
   return QualType();
 }
 QualType ResultType = readType(*Loc.F, Record, Idx);
 FunctionType::ExtInfo Info(Record[1], Record[2], Record[3],
-   (CallingConv)Record[4], Record[5]);
+   (CallingConv)Record[4], Record[5],
+   Record[6]);
 return Context.getFunctionNoProtoType(ResultType, Info);
   }
 
@@ -5386,9 +5387,10 @@
 /*hasregparm*/ Record[2],
 /*regparm*/ Record[3],
 static_cast(Record[4]),
-/*produces*/ Record[5]);
+/*produces*/ Record[5],
+/*nocallersavedregs*/ Record[6]);
 
-unsigned Idx = 6;
+unsigned Idx = 7;
 
 EPI.Variadic = Record[Idx++];
 EPI.HasTrailingReturn = Record[Idx++];
Index: lib/CodeGen/CGCall.cpp
===
--- lib/CodeGen/CGCall.cpp
+++ lib/CodeGen/CGCall.cpp
@@ -746,6 +746,7 @@
   FI->ChainCall = chainCall;
   FI->NoReturn = info.getNoReturn();
   FI->ReturnsRetained = info.getProducesResult();
+  FI->NoCallerSavedRegs = info.getNoCallerSavedRegs();
   FI->Required = required;
   FI->HasRegParm = info.getHasRegParm();
   FI->RegParm = info.getRegParm();
@@ -1673,6 +1674,8 @@
   RetAttrs.addAttribute(llvm::Attribute::NoAlias);
 if (TargetDecl->hasAttr())
   RetAttrs.addAttribute(llvm::Attribute::NonNull);
+if (TargetDecl->hasAttr())
+  FuncAttrs.addAttribute("no_caller_saved_registers");
 
 HasAnyX86InterruptAttr = TargetDecl->hasAttr();
 HasOptnone = TargetDecl->hasAttr();
Index: lib/AST/ASTContext.cpp
===
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -7564,6 +7564,8 @@
 
   if (lbaseInfo.getProducesResult() != rbaseInfo.getProducesResult())
 return QualType();
+  if (lbaseInfo.getNoCallerSavedRegs() != rbaseInfo.getNoCallerSavedRegs())
+return QualType();
 
   // FIXME: some uses, e.g. conditional exprs, really want this to be 'both'.
   bool NoReturn = lbaseInfo.getNoReturn() || rbaseInfo.getNoReturn();
Index: lib/AST/TypePrinter.cpp
===
--- lib/AST/TypePrinter.cpp
+++ lib/AST/TypePrinter.cpp
@@ -745,6 +745,8 @@
   if (Info.getRegParm())
 OS << " __attribute__((regparm ("
<< Info.getRegParm() << ")))";
+  if (Info.getNoCallerSavedRegs())
+OS << "__attribute__((no_caller_saved_registers))";
 
   if (unsigned quals = T->getTypeQuals()) {
 OS << ' ';
Index: lib/Sema/SemaType.cpp
===
--- lib/Sema/

Re: [PATCH] D22045: [X86] Support of no_caller_saved_registers attribute (Clang part)

2016-08-07 Thread Amjad Aboud via cfe-commits
aaboud marked 3 inline comments as done.
aaboud added a comment.

In https://reviews.llvm.org/D22045#506996, @joerg wrote:

> For what it is worth, this certainly seems to be misnamed. By nature, if it 
> doesn't preserve at least the stack pointer, there is no way to recover on 
> return, right?


I am not sure I understand what you mean!
When you  said "if it does not preserve the stack pointer", did you mean the 
"caller"?

Maybe it need more clarification on that, but stack pointer should be saved by 
the caller (via the call instruction), but even in this case the callee must 
preserve the stack pointer, right? otherwise the return will not work. So, from 
callee point of view it still cannot assume that any register is a scratch 
register and it need to preserve it before modifying.


https://reviews.llvm.org/D22045



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D22045: [X86] Support of no_caller_saved_registers attribute (Clang part)

2016-08-07 Thread Amjad Aboud via cfe-commits
aaboud marked an inline comment as not done.


Comment at: include/clang/Basic/Attr.td:1674
@@ +1673,3 @@
+   TargetSpecificAttr {
+  let Spellings = [GNU<"no_caller_saved_registers">];
+  let Subjects = SubjectList<[FunctionLike], WarnDiag, "ExpectedFunction">;

aaron.ballman wrote:
> Yes, though interrupt should be handled in a separate patch since it's a 
> logically separate change.
How about using GCC Spelling instead of GNU and C++?

1. These attributes are compatible with GCC.
2. This is what is said about GCC class:

```
// The GCC spelling implies GNU and CXX11<"gnu", name> and also
// sets KnownToGCC to 1. This spelling should be used for any GCC-compatible
// attributes.
class GCC : Spelling {
  let KnownToGCC = 1;
}
```


https://reviews.llvm.org/D22045



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D15977: [Clang] Supporting all entities declared in lexical scope in LLVM debug info

2016-02-02 Thread Amjad Aboud via cfe-commits
aaboud marked an inline comment as done.
aaboud added a comment.

Thanks David for the comments.
See answer below.



Comment at: lib/CodeGen/CGDebugInfo.cpp:1489
@@ +1488,3 @@
+  if (I != LexicalBlockMap.end()) {
+RetainedTypes.push_back(Ty.getAsOpaquePtr());
+return I->second;

dblaikie wrote:
> aaboud wrote:
> > dblaikie wrote:
> > > Why does the type need to be added to the retained types list?
> > Excellent question :)
> > This was your suggestion few months ago.
> > The reason is that backend will need to know what types are declared in 
> > lexical blocks.
> > Imported entities are collected in the import entity list, while types are 
> > collected in the retained types.
> > 
> > Check line 518 at DwarfDebug.cpp (http://reviews.llvm.org/D15976#51cfb106)
> Not quite following - could we discover the types lazily as we're generating 
> DWARF in the backend - if we happen to emit a variable of that type & 
> generate the DIE* for the type, etc? (so that if a type becomes unused it's 
> able to be dropped - rather than being preserved only when the type is local)
> 
> I suppose that would make it difficult to choose which scopes we had to 
> preserve when emitting debug info in the backend (if we didn't see a type 
> until after the scope was created - we wouldn't've known whether to 
> emit/create that scope or collapse it into its parent, etc) - so this 
> probably isn't possible/practical.
Your analysis is correct.
I just tried to re-check how we can discover types lazily, but I could not 
figure out how to make sure the lexical scope would be created for these types.

I guess we can revisit this issue later and re-think a better implementation 
that make sure optimized types will not be emitted in the debug info. However, 
I think we can do that in a separate (following) patch.


Comment at: test/CodeGenCXX/debug-info-lb.cpp:14
@@ +13,3 @@
+static int bar = 0;
+{
+  X a(x);

dblaikie wrote:
> This block seems unnecessary, and its contents are probably more complicated 
> than needed. This seems to suffice:
> 
>   X a;
>   Y b;
> 
> & the global variable is emitted without referencing it anyway.
> 
> (you could drop the int return and x parameter, too - no need to return 
> anything from the function, and the if (x) could be removed - the scope can 
> remain & still produce the same debug info I think)
OK, I simplify the test, and it is still does what I needed.

The only thing that I need to clarify is the extra block scope that I added to 
wrap the "a" and "b" variable definition.
The reason I did that is to test the case where the types "X" and "Y" are 
defined in a different scope than they are used at.
Without handling this case correctly, the LLVM IR could mistakenly associate 
"X" and "Y" to the scope of the usage and not the definition, i.e. the scope of 
"a" and "b", to test that I had to have different scope as in the example.
I added a comment in the test explaining that.


http://reviews.llvm.org/D15977



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D15977: [Clang] Supporting all entities declared in lexical scope in LLVM debug info

2016-02-02 Thread Amjad Aboud via cfe-commits
aaboud updated this revision to Diff 46708.
aaboud added a comment.

Reduced the LIT tests and added comment explaining part of it.


http://reviews.llvm.org/D15977

Files:
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CGDebugInfo.h
  lib/CodeGen/CGDecl.cpp
  test/CodeGenCXX/debug-info-lb.cpp

Index: lib/CodeGen/CGDecl.cpp
===
--- lib/CodeGen/CGDecl.cpp
+++ lib/CodeGen/CGDecl.cpp
@@ -83,26 +83,30 @@
   case Decl::UsingShadow:
   case Decl::ObjCTypeParam:
 llvm_unreachable("Declaration should not be in declstmts!");
-  case Decl::Function:  // void X();
-  case Decl::Record:// struct/union/class X;
-  case Decl::Enum:  // enum X;
-  case Decl::EnumConstant: // enum ? { X = ? }
-  case Decl::CXXRecord: // struct/union/class X; [C++]
+  case Decl::Function: // void X();
   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;
 
+  case Decl::Record:   // struct/union/class X;
+  case Decl::Enum: // enum X;
+  case Decl::EnumConstant: // enum ? { X = ? }
+  case Decl::CXXRecord:// struct/union/class X; [C++]
+if (CGDebugInfo *DI = getDebugInfo())
+  DI->recordDeclarationLexicalScope(D);
+return;
+
   case Decl::NamespaceAlias:
 if (CGDebugInfo *DI = getDebugInfo())
-DI->EmitNamespaceAlias(cast(D));
+  DI->EmitNamespaceAlias(cast(D));
 return;
   case Decl::Using:  // using X; [C++]
 if (CGDebugInfo *DI = getDebugInfo())
-DI->EmitUsingDecl(cast(D));
+  DI->EmitUsingDecl(cast(D));
 return;
   case Decl::UsingDirective: // using namespace X; [C++]
 if (CGDebugInfo *DI = getDebugInfo())
@@ -120,6 +124,9 @@
 const TypedefNameDecl &TD = cast(D);
 QualType Ty = TD.getUnderlyingType();
 
+if (CGDebugInfo *DI = getDebugInfo())
+  DI->recordDeclarationLexicalScope(D);
+
 if (Ty->isVariablyModifiedType())
   EmitVariablyModifiedType(Ty);
   }
Index: lib/CodeGen/CGDebugInfo.h
===
--- lib/CodeGen/CGDebugInfo.h
+++ lib/CodeGen/CGDebugInfo.h
@@ -114,6 +114,11 @@
 
   /// Keep track of our current nested lexical block.
   std::vector> LexicalBlockStack;
+
+  /// Map of AST declaration to its lexical block scope.
+  llvm::DenseMap>
+  LexicalBlockMap;
+
   llvm::DenseMap RegionMap;
   /// Keep track of LexicalBlockStack counter at the beginning of a
   /// function. This is used to pop unbalanced regions at the end of a
@@ -365,6 +370,12 @@
   /// Emit an Objective-C interface type standalone debug info.
   llvm::DIType *getOrCreateInterfaceType(QualType Ty, SourceLocation Loc);
 
+  /// Map AST declaration to its lexical block scope if available.
+  void recordDeclarationLexicalScope(const Decl &D);
+
+  /// Get lexical scope of AST declaration.
+  llvm::DIScope *getDeclarationLexicalScope(const Decl &D, QualType Ty);
+
   /// Emit standalone debug info for a type.
   llvm::DIType *getOrCreateStandaloneType(QualType Ty, SourceLocation Loc);
 
Index: lib/CodeGen/CGDebugInfo.cpp
===
--- lib/CodeGen/CGDebugInfo.cpp
+++ lib/CodeGen/CGDebugInfo.cpp
@@ -831,15 +831,18 @@
 
 llvm::DIType *CGDebugInfo::CreateType(const TypedefType *Ty,
   llvm::DIFile *Unit) {
+  TypedefNameDecl *TD = Ty->getDecl();
   // We don't set size information, but do specify where the typedef was
   // declared.
-  SourceLocation Loc = Ty->getDecl()->getLocation();
+  SourceLocation Loc = TD->getLocation();
+
+  llvm::DIScope *TDContext = getDeclarationLexicalScope(*TD, QualType(Ty, 0));
 
   // Typedefs are derived from some other type.
   return DBuilder.createTypedef(
   getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
   Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
-  getDeclContextDescriptor(Ty->getDecl()));
+  TDContext);
 }
 
 llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty,
@@ -1472,6 +1475,23 @@
   return T;
 }
 
+void CGDebugInfo::recordDeclarationLexicalScope(const Decl &D) {
+  assert(LexicalBlockMap.find(&D) == LexicalBlockMap.end() &&
+ "D is already mapped to lexical block scope");
+  if (!LexicalBlockStack.empty())
+LexicalBlockMap[&D] = LexicalBlockStack.back();
+}
+
+llvm::DIScope *CGDebugInfo::getDeclarationLexicalScope(const Decl &D,
+   QualType Ty) {
+  auto I = LexicalBlockMap.find(&D);
+  if (I != LexicalBlockMap.end()) {
+RetainedTypes.push_back(Ty.getAsOpaquePtr());
+return I->second;
+  }
+  return getDeclContextDescriptor(cast(&D));
+}
+
 void CGDebugInfo::completeType(const EnumDecl *ED) {
   if (DebugKind <= CodeGenOptions::DebugLineTablesOnly)
 return;
@@ -2043,7 

Re: [PATCH] D15977: [Clang] Supporting all entities declared in lexical scope in LLVM debug info

2016-02-15 Thread Amjad Aboud via cfe-commits
aaboud updated this revision to Diff 47988.
aaboud added a comment.

Simplified LIT tests according to David comment.


http://reviews.llvm.org/D15977

Files:
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CGDebugInfo.h
  lib/CodeGen/CGDecl.cpp
  test/CodeGenCXX/debug-info-lb.cpp

Index: lib/CodeGen/CGDecl.cpp
===
--- lib/CodeGen/CGDecl.cpp
+++ lib/CodeGen/CGDecl.cpp
@@ -83,26 +83,30 @@
   case Decl::UsingShadow:
   case Decl::ObjCTypeParam:
 llvm_unreachable("Declaration should not be in declstmts!");
-  case Decl::Function:  // void X();
-  case Decl::Record:// struct/union/class X;
-  case Decl::Enum:  // enum X;
-  case Decl::EnumConstant: // enum ? { X = ? }
-  case Decl::CXXRecord: // struct/union/class X; [C++]
+  case Decl::Function: // void X();
   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;
 
+  case Decl::Record:   // struct/union/class X;
+  case Decl::Enum: // enum X;
+  case Decl::EnumConstant: // enum ? { X = ? }
+  case Decl::CXXRecord:// struct/union/class X; [C++]
+if (CGDebugInfo *DI = getDebugInfo())
+  DI->recordDeclarationLexicalScope(D);
+return;
+
   case Decl::NamespaceAlias:
 if (CGDebugInfo *DI = getDebugInfo())
-DI->EmitNamespaceAlias(cast(D));
+  DI->EmitNamespaceAlias(cast(D));
 return;
   case Decl::Using:  // using X; [C++]
 if (CGDebugInfo *DI = getDebugInfo())
-DI->EmitUsingDecl(cast(D));
+  DI->EmitUsingDecl(cast(D));
 return;
   case Decl::UsingDirective: // using namespace X; [C++]
 if (CGDebugInfo *DI = getDebugInfo())
@@ -120,6 +124,9 @@
 const TypedefNameDecl &TD = cast(D);
 QualType Ty = TD.getUnderlyingType();
 
+if (CGDebugInfo *DI = getDebugInfo())
+  DI->recordDeclarationLexicalScope(D);
+
 if (Ty->isVariablyModifiedType())
   EmitVariablyModifiedType(Ty);
   }
Index: lib/CodeGen/CGDebugInfo.h
===
--- lib/CodeGen/CGDebugInfo.h
+++ lib/CodeGen/CGDebugInfo.h
@@ -114,6 +114,11 @@
 
   /// Keep track of our current nested lexical block.
   std::vector> LexicalBlockStack;
+
+  /// Map of AST declaration to its lexical block scope.
+  llvm::DenseMap>
+  LexicalBlockMap;
+
   llvm::DenseMap RegionMap;
   /// Keep track of LexicalBlockStack counter at the beginning of a
   /// function. This is used to pop unbalanced regions at the end of a
@@ -365,6 +370,12 @@
   /// Emit an Objective-C interface type standalone debug info.
   llvm::DIType *getOrCreateInterfaceType(QualType Ty, SourceLocation Loc);
 
+  /// Map AST declaration to its lexical block scope if available.
+  void recordDeclarationLexicalScope(const Decl &D);
+
+  /// Get lexical scope of AST declaration.
+  llvm::DIScope *getDeclarationLexicalScope(const Decl &D, QualType Ty);
+
   /// Emit standalone debug info for a type.
   llvm::DIType *getOrCreateStandaloneType(QualType Ty, SourceLocation Loc);
 
Index: lib/CodeGen/CGDebugInfo.cpp
===
--- lib/CodeGen/CGDebugInfo.cpp
+++ lib/CodeGen/CGDebugInfo.cpp
@@ -831,15 +831,18 @@
 
 llvm::DIType *CGDebugInfo::CreateType(const TypedefType *Ty,
   llvm::DIFile *Unit) {
+  TypedefNameDecl *TD = Ty->getDecl();
   // We don't set size information, but do specify where the typedef was
   // declared.
-  SourceLocation Loc = Ty->getDecl()->getLocation();
+  SourceLocation Loc = TD->getLocation();
+
+  llvm::DIScope *TDContext = getDeclarationLexicalScope(*TD, QualType(Ty, 0));
 
   // Typedefs are derived from some other type.
   return DBuilder.createTypedef(
   getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
   Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
-  getDeclContextDescriptor(Ty->getDecl()));
+  TDContext);
 }
 
 llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty,
@@ -1472,6 +1475,23 @@
   return T;
 }
 
+void CGDebugInfo::recordDeclarationLexicalScope(const Decl &D) {
+  assert(LexicalBlockMap.find(&D) == LexicalBlockMap.end() &&
+ "D is already mapped to lexical block scope");
+  if (!LexicalBlockStack.empty())
+LexicalBlockMap[&D] = LexicalBlockStack.back();
+}
+
+llvm::DIScope *CGDebugInfo::getDeclarationLexicalScope(const Decl &D,
+   QualType Ty) {
+  auto I = LexicalBlockMap.find(&D);
+  if (I != LexicalBlockMap.end()) {
+RetainedTypes.push_back(Ty.getAsOpaquePtr());
+return I->second;
+  }
+  return getDeclContextDescriptor(cast(&D));
+}
+
 void CGDebugInfo::completeType(const EnumDecl *ED) {
   if (DebugKind <= CodeGenOptions::DebugLineTablesOnly)
 return;
@@ -2043,7 +2063,7 @@
   

Re: [PATCH] D16135: Macro Debug Info support in Clang

2016-02-15 Thread Amjad Aboud via cfe-commits
aaboud updated this revision to Diff 47997.
aaboud marked an inline comment as done.
aaboud added a comment.

Applied Adrian comment.


http://reviews.llvm.org/D16135

Files:
  include/clang/AST/ASTConsumer.h
  lib/AST/ASTConsumer.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CGDebugInfo.h
  lib/CodeGen/CMakeLists.txt
  lib/CodeGen/CodeGenAction.cpp
  lib/CodeGen/CodeGenModule.cpp
  lib/CodeGen/CodeGenModule.h
  lib/CodeGen/MacroPPCallbacks.cpp
  lib/CodeGen/MacroPPCallbacks.h
  lib/CodeGen/ModuleBuilder.cpp
  lib/Parse/ParseAST.cpp

Index: lib/Parse/ParseAST.cpp
===
--- lib/Parse/ParseAST.cpp
+++ lib/Parse/ParseAST.cpp
@@ -128,6 +128,12 @@
   new Parser(S.getPreprocessor(), S, SkipFunctionBodies));
   Parser &P = *ParseOP.get();
 
+  std::unique_ptr Callbacks =
+  Consumer->CreatePreprocessorCallbacks(S.getPreprocessor());
+  if (Callbacks) {
+S.getPreprocessor().addPPCallbacks(std::move(Callbacks));
+  }
+
   llvm::CrashRecoveryContextCleanupRegistrar
   CleanupPrettyStack(llvm::SavePrettyStackState());
   PrettyStackTraceParserEntry CrashInfo(P);
Index: lib/CodeGen/ModuleBuilder.cpp
===
--- lib/CodeGen/ModuleBuilder.cpp
+++ lib/CodeGen/ModuleBuilder.cpp
@@ -20,6 +20,7 @@
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Frontend/CodeGenOptions.h"
+#include "clang/Lex/PPCallbacks.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/LLVMContext.h"
@@ -234,6 +235,11 @@
 void HandleDependentLibrary(llvm::StringRef Lib) override {
   Builder->AddDependentLib(Lib);
 }
+
+std::unique_ptr
+CreatePreprocessorCallbacks(Preprocessor &PP) override {
+  return Builder->createPreprocessorCallbacks(PP);
+}
   };
 }
 
Index: lib/CodeGen/CodeGenModule.cpp
===
--- lib/CodeGen/CodeGenModule.cpp
+++ lib/CodeGen/CodeGenModule.cpp
@@ -24,6 +24,7 @@
 #include "CodeGenPGO.h"
 #include "CodeGenTBAA.h"
 #include "CoverageMappingGen.h"
+#include "MacroPPCallbacks.h"
 #include "TargetInfo.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CharUnits.h"
@@ -208,6 +209,16 @@
   CUDARuntime = CreateNVCUDARuntime(*this);
 }
 
+std::unique_ptr
+CodeGenModule::createPreprocessorCallbacks(Preprocessor &PP) {
+  // Enable generating macro debug info only in FullDebugInfo mode.
+  if (CodeGenOpts.getDebugInfo() < CodeGenOptions::FullDebugInfo ||
+  !getModuleDebugInfo())
+return nullptr;
+
+  return std::make_unique(*getModuleDebugInfo(), PP);
+}
+
 void CodeGenModule::addReplacement(StringRef Name, llvm::Constant *C) {
   Replacements[Name] = C;
 }
Index: lib/CodeGen/MacroPPCallbacks.h
===
--- lib/CodeGen/MacroPPCallbacks.h
+++ lib/CodeGen/MacroPPCallbacks.h
@@ -0,0 +1,82 @@
+//===--- MacroPPCallbacks.h -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+//
+//  This file defines implementation for the macro preprocessors callbacks.
+//
+//===--===//
+
+#include "clang/Lex/PPCallbacks.h"
+#include "clang/Parse/Parser.h"
+#include 
+
+namespace llvm {
+class DIMacroFile;
+}
+namespace clang {
+
+namespace CodeGen {
+class CGDebugInfo;
+}
+class MacroPPCallbacks : public PPCallbacks {
+  /// Debug info code generator
+  CodeGen::CGDebugInfo &DebugInfo;
+  /// Preprocessor
+  Preprocessor &PP;
+  /// Location (used for line number) for recent included file.
+  SourceLocation LastHashLoc;
+  /// Location (used for file name) for first included file (source main).
+  SourceLocation FirstIncludeFile;
+  /// Indicates that first file inclusion occurred.
+  bool FirstInclude;
+  /// Indicates that DIMacroFile entry was created for first included file.
+  bool FirstIncludeDone;
+  /// Counts current number of command line included files, which was entered
+  /// and was not exited yet.
+  int CommandIncludeFiles;
+  /// Number of fake files that should skip that were not exited yet.
+  int SkipFiles;
+  /// Parent contains all entered files that were not exited yet according to
+  /// the inclusion order.
+  std::vector Parents;
+
+  /// Use the passed preprocessor to calculate the macro name and value from
+  /// the given macro info and identifier info.
+  static void getMacroDefinition(const IdentifierInfo &II, const MacroInfo &MI,
+ Preprocessor &PP, raw_ostream &Name,
+ raw_ostream &Value);
+
+public:
+  MacroPPCallbacks(CodeGen::CGDebugInfo &DI, Preprocessor &PP)

r261634 - Supporting all entities declared in lexical scope in LLVM debug info.

2016-02-23 Thread Amjad Aboud via cfe-commits
Author: aaboud
Date: Tue Feb 23 07:37:18 2016
New Revision: 261634

URL: http://llvm.org/viewvc/llvm-project?rev=261634&view=rev
Log:
Supporting all entities declared in lexical scope in LLVM debug info.

Differential Revision: http://reviews.llvm.org/D15977

Added:
cfe/trunk/test/CodeGenCXX/debug-info-lb.cpp
Modified:
cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
cfe/trunk/lib/CodeGen/CGDebugInfo.h
cfe/trunk/lib/CodeGen/CGDecl.cpp
cfe/trunk/test/CodeGenCXX/debug-info-anon-union-vars.cpp

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=261634&r1=261633&r2=261634&view=diff
==
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Tue Feb 23 07:37:18 2016
@@ -831,15 +831,18 @@ llvm::DIType *CGDebugInfo::CreateType(co
 
 llvm::DIType *CGDebugInfo::CreateType(const TypedefType *Ty,
   llvm::DIFile *Unit) {
+  TypedefNameDecl *TD = Ty->getDecl();
   // We don't set size information, but do specify where the typedef was
   // declared.
-  SourceLocation Loc = Ty->getDecl()->getLocation();
+  SourceLocation Loc = TD->getLocation();
+
+  llvm::DIScope *TDContext = getDeclarationLexicalScope(*TD, QualType(Ty, 0));
 
   // Typedefs are derived from some other type.
   return DBuilder.createTypedef(
   getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
   Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
-  getDeclContextDescriptor(Ty->getDecl()));
+  TDContext);
 }
 
 llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty,
@@ -1472,6 +1475,23 @@ llvm::DIType *CGDebugInfo::getOrCreateSt
   return T;
 }
 
+void CGDebugInfo::recordDeclarationLexicalScope(const Decl &D) {
+  assert(LexicalBlockMap.find(&D) == LexicalBlockMap.end() &&
+ "D is already mapped to lexical block scope");
+  if (!LexicalBlockStack.empty())
+LexicalBlockMap[&D] = LexicalBlockStack.back();
+}
+
+llvm::DIScope *CGDebugInfo::getDeclarationLexicalScope(const Decl &D,
+   QualType Ty) {
+  auto I = LexicalBlockMap.find(&D);
+  if (I != LexicalBlockMap.end()) {
+RetainedTypes.push_back(Ty.getAsOpaquePtr());
+return I->second;
+  }
+  return getDeclContextDescriptor(cast(&D));
+}
+
 void CGDebugInfo::completeType(const EnumDecl *ED) {
   if (DebugKind <= codegenoptions::DebugLineTablesOnly)
 return;
@@ -2068,7 +2088,8 @@ llvm::DIType *CGDebugInfo::CreateEnumTyp
 // Cache the enum type so it is available when building the declcontext
 // and replace the declcontect with the real thing.
 TypeCache[Ty].reset(RetTy);
-TmpContext->replaceAllUsesWith(getDeclContextDescriptor(ED));
+TmpContext->replaceAllUsesWith(
+getDeclarationLexicalScope(*ED, QualType(Ty, 0)));
 
 ReplaceMap.emplace_back(
 std::piecewise_construct, std::make_tuple(Ty),
@@ -2103,7 +2124,7 @@ llvm::DIType *CGDebugInfo::CreateTypeDef
 
   llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
   unsigned Line = getLineNumber(ED->getLocation());
-  llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
+  llvm::DIScope *EnumContext = getDeclarationLexicalScope(*ED, QualType(Ty, 
0));
   llvm::DIType *ClassTy =
   ED->isFixed() ? getOrCreateType(ED->getIntegerType(), DefUnit) : nullptr;
   return DBuilder.createEnumerationType(EnumContext, ED->getName(), DefUnit,
@@ -2364,7 +2385,7 @@ llvm::DICompositeType *CGDebugInfo::Crea
   unsigned Line = getLineNumber(RD->getLocation());
   StringRef RDName = getClassName(RD);
 
-  llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
+  llvm::DIScope *RDContext = getDeclarationLexicalScope(*RD, QualType(Ty, 0));
 
   // If we ended up creating the type during the context chain construction,
   // just return that.
@@ -2511,8 +2532,15 @@ void CGDebugInfo::collectVarDeclProps(co
   if (DC->isRecord())
 DC = CGM.getContext().getTranslationUnitDecl();
 
- llvm::DIScope *Mod = getParentModuleOrNull(VD);
- VDContext = getContextDescriptor(cast(DC), Mod ? Mod : TheCU);
+  if (VD->isStaticLocal()) {
+// Get context for static locals (that are technically globals) the same 
way
+// we do for "local" locals -- by using current lexical block.
+assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack 
empty!");
+VDContext = LexicalBlockStack.back();
+  } else {
+llvm::DIScope *Mod = getParentModuleOrNull(VD);
+VDContext = getContextDescriptor(cast(DC), Mod ? Mod : TheCU);
+  }
 }
 
 llvm::DISubprogram *

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.h?rev=261634&r1=261633&r2=261634&view=diff
==
--- cfe/trunk/lib/CodeGen/CGDebugInfo.h (original)
+++ cfe/trunk

Re: [PATCH] D15977: [Clang] Supporting all entities declared in lexical scope in LLVM debug info

2016-02-23 Thread Amjad Aboud via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL261634: Supporting all entities declared in lexical scope in 
LLVM debug info. (authored by aaboud).

Changed prior to commit:
  http://reviews.llvm.org/D15977?vs=47988&id=48808#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D15977

Files:
  cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
  cfe/trunk/lib/CodeGen/CGDebugInfo.h
  cfe/trunk/lib/CodeGen/CGDecl.cpp
  cfe/trunk/test/CodeGenCXX/debug-info-anon-union-vars.cpp
  cfe/trunk/test/CodeGenCXX/debug-info-lb.cpp

Index: cfe/trunk/lib/CodeGen/CGDebugInfo.h
===
--- cfe/trunk/lib/CodeGen/CGDebugInfo.h
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.h
@@ -116,6 +116,11 @@
 
   /// Keep track of our current nested lexical block.
   std::vector> LexicalBlockStack;
+
+  /// Map of AST declaration to its lexical block scope.
+  llvm::DenseMap>
+  LexicalBlockMap;
+
   llvm::DenseMap RegionMap;
   /// Keep track of LexicalBlockStack counter at the beginning of a
   /// function. This is used to pop unbalanced regions at the end of a
@@ -378,6 +383,12 @@
   /// Emit an Objective-C interface type standalone debug info.
   llvm::DIType *getOrCreateInterfaceType(QualType Ty, SourceLocation Loc);
 
+  /// Map AST declaration to its lexical block scope if available.
+  void recordDeclarationLexicalScope(const Decl &D);
+
+  /// Get lexical scope of AST declaration.
+  llvm::DIScope *getDeclarationLexicalScope(const Decl &D, QualType Ty);
+
   /// Emit standalone debug info for a type.
   llvm::DIType *getOrCreateStandaloneType(QualType Ty, SourceLocation Loc);
 
Index: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
===
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
@@ -831,15 +831,18 @@
 
 llvm::DIType *CGDebugInfo::CreateType(const TypedefType *Ty,
   llvm::DIFile *Unit) {
+  TypedefNameDecl *TD = Ty->getDecl();
   // We don't set size information, but do specify where the typedef was
   // declared.
-  SourceLocation Loc = Ty->getDecl()->getLocation();
+  SourceLocation Loc = TD->getLocation();
+
+  llvm::DIScope *TDContext = getDeclarationLexicalScope(*TD, QualType(Ty, 0));
 
   // Typedefs are derived from some other type.
   return DBuilder.createTypedef(
   getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
   Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
-  getDeclContextDescriptor(Ty->getDecl()));
+  TDContext);
 }
 
 llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty,
@@ -1472,6 +1475,23 @@
   return T;
 }
 
+void CGDebugInfo::recordDeclarationLexicalScope(const Decl &D) {
+  assert(LexicalBlockMap.find(&D) == LexicalBlockMap.end() &&
+ "D is already mapped to lexical block scope");
+  if (!LexicalBlockStack.empty())
+LexicalBlockMap[&D] = LexicalBlockStack.back();
+}
+
+llvm::DIScope *CGDebugInfo::getDeclarationLexicalScope(const Decl &D,
+   QualType Ty) {
+  auto I = LexicalBlockMap.find(&D);
+  if (I != LexicalBlockMap.end()) {
+RetainedTypes.push_back(Ty.getAsOpaquePtr());
+return I->second;
+  }
+  return getDeclContextDescriptor(cast(&D));
+}
+
 void CGDebugInfo::completeType(const EnumDecl *ED) {
   if (DebugKind <= codegenoptions::DebugLineTablesOnly)
 return;
@@ -2068,7 +2088,8 @@
 // Cache the enum type so it is available when building the declcontext
 // and replace the declcontect with the real thing.
 TypeCache[Ty].reset(RetTy);
-TmpContext->replaceAllUsesWith(getDeclContextDescriptor(ED));
+TmpContext->replaceAllUsesWith(
+getDeclarationLexicalScope(*ED, QualType(Ty, 0)));
 
 ReplaceMap.emplace_back(
 std::piecewise_construct, std::make_tuple(Ty),
@@ -2103,7 +2124,7 @@
 
   llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
   unsigned Line = getLineNumber(ED->getLocation());
-  llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
+  llvm::DIScope *EnumContext = getDeclarationLexicalScope(*ED, QualType(Ty, 0));
   llvm::DIType *ClassTy =
   ED->isFixed() ? getOrCreateType(ED->getIntegerType(), DefUnit) : nullptr;
   return DBuilder.createEnumerationType(EnumContext, ED->getName(), DefUnit,
@@ -2364,7 +2385,7 @@
   unsigned Line = getLineNumber(RD->getLocation());
   StringRef RDName = getClassName(RD);
 
-  llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
+  llvm::DIScope *RDContext = getDeclarationLexicalScope(*RD, QualType(Ty, 0));
 
   // If we ended up creating the type during the context chain construction,
   // just return that.
@@ -2511,8 +2532,15 @@
   if (DC->isRecord())
 DC = CGM.getContext().getTranslationUnitDecl();
 
- llvm::DIScope *Mod = getParentModuleOrNull(VD);
- VDContext = getContextDescriptor(cast(DC), Mod ? Mod : TheCU);
+  if (VD->isStaticLocal()) {
+

r268055 - Recommitted r264281 "Supporting all entities declared in lexical scope in LLVM debug info."

2016-04-29 Thread Amjad Aboud via cfe-commits
Author: aaboud
Date: Fri Apr 29 11:08:08 2016
New Revision: 268055

URL: http://llvm.org/viewvc/llvm-project?rev=268055&view=rev
Log:
Recommitted r264281 "Supporting all entities declared in lexical scope in LLVM 
debug info."
After fixing PR26942 in r267004.

Added:
cfe/trunk/test/CodeGenCXX/debug-info-lb.cpp
Modified:
cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
cfe/trunk/lib/CodeGen/CGDebugInfo.h
cfe/trunk/lib/CodeGen/CGDecl.cpp
cfe/trunk/test/CodeGenCXX/debug-info-anon-union-vars.cpp

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=268055&r1=268054&r2=268055&view=diff
==
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Fri Apr 29 11:08:08 2016
@@ -814,15 +814,18 @@ llvm::DIType *CGDebugInfo::CreateType(co
 
 llvm::DIType *CGDebugInfo::CreateType(const TypedefType *Ty,
   llvm::DIFile *Unit) {
+  TypedefNameDecl *TD = Ty->getDecl();
   // We don't set size information, but do specify where the typedef was
   // declared.
-  SourceLocation Loc = Ty->getDecl()->getLocation();
+  SourceLocation Loc = TD->getLocation();
+
+  llvm::DIScope *TDContext = getDeclarationLexicalScope(*TD, QualType(Ty, 0));
 
   // Typedefs are derived from some other type.
   return DBuilder.createTypedef(
   getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
   Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
-  getDeclContextDescriptor(Ty->getDecl()));
+  TDContext);
 }
 
 llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty,
@@ -1457,6 +1460,23 @@ llvm::DIType *CGDebugInfo::getOrCreateSt
   return T;
 }
 
+void CGDebugInfo::recordDeclarationLexicalScope(const Decl &D) {
+  assert(LexicalBlockMap.find(&D) == LexicalBlockMap.end() &&
+ "D is already mapped to lexical block scope");
+  if (!LexicalBlockStack.empty())
+LexicalBlockMap[&D] = LexicalBlockStack.back();
+}
+
+llvm::DIScope *CGDebugInfo::getDeclarationLexicalScope(const Decl &D,
+   QualType Ty) {
+  auto I = LexicalBlockMap.find(&D);
+  if (I != LexicalBlockMap.end()) {
+RetainedTypes.push_back(Ty.getAsOpaquePtr());
+return I->second;
+  }
+  return getDeclContextDescriptor(cast(&D));
+}
+
 void CGDebugInfo::completeType(const EnumDecl *ED) {
   if (DebugKind <= codegenoptions::DebugLineTablesOnly)
 return;
@@ -2060,7 +2080,7 @@ llvm::DIType *CGDebugInfo::CreateEnumTyp
 // entered into the ReplaceMap: finalize() will replace the first
 // FwdDecl with the second and then replace the second with
 // complete type.
-llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
+llvm::DIScope *EDContext = getDeclarationLexicalScope(*ED, QualType(Ty, 
0));
 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
 llvm::dwarf::DW_TAG_enumeration_type, "", TheCU, DefUnit, 0));
@@ -2104,7 +2124,7 @@ llvm::DIType *CGDebugInfo::CreateTypeDef
 
   llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
   unsigned Line = getLineNumber(ED->getLocation());
-  llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
+  llvm::DIScope *EnumContext = getDeclarationLexicalScope(*ED, QualType(Ty, 
0));
   llvm::DIType *ClassTy =
   ED->isFixed() ? getOrCreateType(ED->getIntegerType(), DefUnit) : nullptr;
   return DBuilder.createEnumerationType(EnumContext, ED->getName(), DefUnit,
@@ -2365,7 +2385,7 @@ llvm::DICompositeType *CGDebugInfo::Crea
   unsigned Line = getLineNumber(RD->getLocation());
   StringRef RDName = getClassName(RD);
 
-  llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
+  llvm::DIScope *RDContext = getDeclarationLexicalScope(*RD, QualType(Ty, 0));
 
   // If we ended up creating the type during the context chain construction,
   // just return that.
@@ -2536,8 +2556,15 @@ void CGDebugInfo::collectVarDeclProps(co
   if (DC->isRecord())
 DC = CGM.getContext().getTranslationUnitDecl();
 
- llvm::DIScope *Mod = getParentModuleOrNull(VD);
- VDContext = getContextDescriptor(cast(DC), Mod ? Mod : TheCU);
+  if (VD->isStaticLocal()) {
+// Get context for static locals (that are technically globals) the same 
way
+// we do for "local" locals -- by using current lexical block.
+assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack 
empty!");
+VDContext = LexicalBlockStack.back();
+  } else {
+llvm::DIScope *Mod = getParentModuleOrNull(VD);
+VDContext = getContextDescriptor(cast(DC), Mod ? Mod : TheCU);
+  }
 }
 
 llvm::DISubprogram *

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.h?rev=268055&r1=268054&r2=268055&view=diff
=

Re: [PATCH] D19727: [MS] Improved implementation #pragma pack (MS pragmas, part 2)

2016-04-29 Thread Amjad Aboud via cfe-commits
aaboud added a subscriber: aaboud.


Comment at: cfe/trunk/lib/Sema/SemaAttr.cpp:110
@@ -200,3 +109,3 @@
 
   case POAK_Reset:
 // Reset just pops the top of the stack, or resets the current alignment to

You forgot to initialize "Alignment" in this case.
This is causing a build failure:
http://lab.llvm.org:8011/builders/sanitizer-ppc64be-linux/builds/1758


Repository:
  rL LLVM

http://reviews.llvm.org/D19727



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r268151 - Reverting 268055 as it caused PR27579.

2016-04-29 Thread Amjad Aboud via cfe-commits
Author: aaboud
Date: Fri Apr 29 20:44:38 2016
New Revision: 268151

URL: http://llvm.org/viewvc/llvm-project?rev=268151&view=rev
Log:
Reverting 268055 as it caused PR27579.

Removed:
cfe/trunk/test/CodeGenCXX/debug-info-lb.cpp
Modified:
cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
cfe/trunk/lib/CodeGen/CGDebugInfo.h
cfe/trunk/lib/CodeGen/CGDecl.cpp
cfe/trunk/test/CodeGenCXX/debug-info-anon-union-vars.cpp

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=268151&r1=268150&r2=268151&view=diff
==
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Fri Apr 29 20:44:38 2016
@@ -814,18 +814,15 @@ llvm::DIType *CGDebugInfo::CreateType(co
 
 llvm::DIType *CGDebugInfo::CreateType(const TypedefType *Ty,
   llvm::DIFile *Unit) {
-  TypedefNameDecl *TD = Ty->getDecl();
   // We don't set size information, but do specify where the typedef was
   // declared.
-  SourceLocation Loc = TD->getLocation();
-
-  llvm::DIScope *TDContext = getDeclarationLexicalScope(*TD, QualType(Ty, 0));
+  SourceLocation Loc = Ty->getDecl()->getLocation();
 
   // Typedefs are derived from some other type.
   return DBuilder.createTypedef(
   getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
   Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
-  TDContext);
+  getDeclContextDescriptor(Ty->getDecl()));
 }
 
 llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty,
@@ -1460,23 +1457,6 @@ llvm::DIType *CGDebugInfo::getOrCreateSt
   return T;
 }
 
-void CGDebugInfo::recordDeclarationLexicalScope(const Decl &D) {
-  assert(LexicalBlockMap.find(&D) == LexicalBlockMap.end() &&
- "D is already mapped to lexical block scope");
-  if (!LexicalBlockStack.empty())
-LexicalBlockMap[&D] = LexicalBlockStack.back();
-}
-
-llvm::DIScope *CGDebugInfo::getDeclarationLexicalScope(const Decl &D,
-   QualType Ty) {
-  auto I = LexicalBlockMap.find(&D);
-  if (I != LexicalBlockMap.end()) {
-RetainedTypes.push_back(Ty.getAsOpaquePtr());
-return I->second;
-  }
-  return getDeclContextDescriptor(cast(&D));
-}
-
 void CGDebugInfo::completeType(const EnumDecl *ED) {
   if (DebugKind <= codegenoptions::DebugLineTablesOnly)
 return;
@@ -2080,7 +2060,7 @@ llvm::DIType *CGDebugInfo::CreateEnumTyp
 // entered into the ReplaceMap: finalize() will replace the first
 // FwdDecl with the second and then replace the second with
 // complete type.
-llvm::DIScope *EDContext = getDeclarationLexicalScope(*ED, QualType(Ty, 
0));
+llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
 llvm::dwarf::DW_TAG_enumeration_type, "", TheCU, DefUnit, 0));
@@ -2124,7 +2104,7 @@ llvm::DIType *CGDebugInfo::CreateTypeDef
 
   llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
   unsigned Line = getLineNumber(ED->getLocation());
-  llvm::DIScope *EnumContext = getDeclarationLexicalScope(*ED, QualType(Ty, 
0));
+  llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
   llvm::DIType *ClassTy =
   ED->isFixed() ? getOrCreateType(ED->getIntegerType(), DefUnit) : nullptr;
   return DBuilder.createEnumerationType(EnumContext, ED->getName(), DefUnit,
@@ -2385,7 +2365,7 @@ llvm::DICompositeType *CGDebugInfo::Crea
   unsigned Line = getLineNumber(RD->getLocation());
   StringRef RDName = getClassName(RD);
 
-  llvm::DIScope *RDContext = getDeclarationLexicalScope(*RD, QualType(Ty, 0));
+  llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
 
   // If we ended up creating the type during the context chain construction,
   // just return that.
@@ -2556,15 +2536,8 @@ void CGDebugInfo::collectVarDeclProps(co
   if (DC->isRecord())
 DC = CGM.getContext().getTranslationUnitDecl();
 
-  if (VD->isStaticLocal()) {
-// Get context for static locals (that are technically globals) the same 
way
-// we do for "local" locals -- by using current lexical block.
-assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack 
empty!");
-VDContext = LexicalBlockStack.back();
-  } else {
-llvm::DIScope *Mod = getParentModuleOrNull(VD);
-VDContext = getContextDescriptor(cast(DC), Mod ? Mod : TheCU);
-  }
+ llvm::DIScope *Mod = getParentModuleOrNull(VD);
+ VDContext = getContextDescriptor(cast(DC), Mod ? Mod : TheCU);
 }
 
 llvm::DISubprogram *

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.h?rev=268151&r1=268150&r2=268151&view=diff
==
--- cfe/trunk/lib/CodeGen/CGDebugInfo.h (original)

[PATCH] D21766: [codeview][clang] Added support for unnamed bitfield type.

2016-06-27 Thread Amjad Aboud via cfe-commits
aaboud created this revision.
aaboud added reviewers: rnk, majnemer.
aaboud added subscribers: cfe-commits, bwyma.

Allow creating DI metadata for non-zero width unnamed bitfield members when 
emitting CodeView.
This is needed for patch D21489.

http://reviews.llvm.org/D21766

Files:
  lib/CodeGen/CGDebugInfo.cpp

Index: lib/CodeGen/CGDebugInfo.cpp
===
--- lib/CodeGen/CGDebugInfo.cpp
+++ lib/CodeGen/CGDebugInfo.cpp
@@ -1010,14 +1010,20 @@
 const RecordDecl *RD) {
   StringRef name = field->getName();
   QualType type = field->getType();
+  bool EmitCodeView = CGM.getCodeGenOpts().EmitCodeView;
 
   // Ignore unnamed fields unless they're anonymous structs/unions.
   if (name.empty() && !type->isRecordType())
-return;
+// Do not ignore anonymous bitfield when emitting CodeView.
+if(!EmitCodeView || !field->isBitField())
+  return;
 
   uint64_t SizeInBitsOverride = 0;
   if (field->isBitField()) {
 SizeInBitsOverride = field->getBitWidthValue(CGM.getContext());
+if (!SizeInBitsOverride && name.empty())
+  // Ignore unnamed 0-width bitfield.
+  return;
 assert(SizeInBitsOverride && "found named 0-width bitfield");
   }
 


Index: lib/CodeGen/CGDebugInfo.cpp
===
--- lib/CodeGen/CGDebugInfo.cpp
+++ lib/CodeGen/CGDebugInfo.cpp
@@ -1010,14 +1010,20 @@
 const RecordDecl *RD) {
   StringRef name = field->getName();
   QualType type = field->getType();
+  bool EmitCodeView = CGM.getCodeGenOpts().EmitCodeView;
 
   // Ignore unnamed fields unless they're anonymous structs/unions.
   if (name.empty() && !type->isRecordType())
-return;
+// Do not ignore anonymous bitfield when emitting CodeView.
+if(!EmitCodeView || !field->isBitField())
+  return;
 
   uint64_t SizeInBitsOverride = 0;
   if (field->isBitField()) {
 SizeInBitsOverride = field->getBitWidthValue(CGM.getContext());
+if (!SizeInBitsOverride && name.empty())
+  // Ignore unnamed 0-width bitfield.
+  return;
 assert(SizeInBitsOverride && "found named 0-width bitfield");
   }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D21783: [CodeView] Implement support for bitfields in Clang

2016-06-28 Thread Amjad Aboud via cfe-commits
aaboud added a comment.

Looks good, one minor comments below.



Comment at: lib/CodeGen/CGDebugInfo.h:243
@@ +242,3 @@
+   llvm::DIScope *RecordTy,
+   const RecordDecl *RD, SourceLocation Loc);
+

You have a mismatch between definition and this declaration, definition does 
not take SourceLocation parameter!


http://reviews.llvm.org/D21783



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D21783: [CodeView] Implement support for bitfields in Clang

2016-06-28 Thread Amjad Aboud via cfe-commits
aaboud accepted this revision.
aaboud added a comment.
This revision is now accepted and ready to land.

LGTM.
Please update PR28162.


http://reviews.llvm.org/D21783



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D21766: [codeview][clang] Added support for unnamed bitfield type.

2016-07-05 Thread Amjad Aboud via cfe-commits
aaboud abandoned this revision.
aaboud added a comment.

Different implementation was committed at http://reviews.llvm.org/rL274201.


http://reviews.llvm.org/D21766



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D22045: [X86] Support of no_caller_saved_registers attribute (Clang part)

2016-07-06 Thread Amjad Aboud via cfe-commits
aaboud created this revision.
aaboud added reviewers: ABataev, DavidKreitzer, hjl.tools, qcolombet.
aaboud added a subscriber: cfe-commits.

This patch implements the Clang part for no_caller_saved_registers attribute as 
appear in [[ 
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=5ed3cc7b66af4758f7849ed6f65f4365be8223be
 | interrupt and exception handler proposal ]]


http://reviews.llvm.org/D22045

Files:
  include/clang/Basic/Attr.td
  include/clang/Basic/AttrDocs.td
  lib/CodeGen/CGCall.cpp
  lib/Sema/SemaDeclAttr.cpp
  test/CodeGenCXX/attr-x86-no_caller_saved_registers.cpp
  test/SemaCXX/attr-x86-no_caller_saved_registers.cpp

Index: lib/CodeGen/CGCall.cpp
===
--- lib/CodeGen/CGCall.cpp
+++ lib/CodeGen/CGCall.cpp
@@ -1673,6 +1673,8 @@
   RetAttrs.addAttribute(llvm::Attribute::NoAlias);
 if (TargetDecl->hasAttr())
   RetAttrs.addAttribute(llvm::Attribute::NonNull);
+if (TargetDecl->hasAttr())
+  FuncAttrs.addAttribute("no_caller_saved_registers");
 
 HasAnyX86InterruptAttr = TargetDecl->hasAttr();
 HasOptnone = TargetDecl->hasAttr();
Index: lib/Sema/SemaDeclAttr.cpp
===
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -5910,6 +5910,10 @@
 handleTypeTagForDatatypeAttr(S, D, Attr);
 break;
 
+  case AttributeList::AT_AnyX86NoCallerSavedRegisters:
+handleSimpleAttribute(S, D, Attr);
+break;
+
   case AttributeList::AT_RenderScriptKernel:
 handleSimpleAttribute(S, D, Attr);
 break;
Index: include/clang/Basic/AttrDocs.td
===
--- include/clang/Basic/AttrDocs.td
+++ include/clang/Basic/AttrDocs.td
@@ -2170,6 +2170,20 @@
   }];
 }
 
+def AnyX86NoCallerSavedRegistersDocs : Documentation {
+  let Category = DocCatFunction;
+  let Content = [{
+Use this attribute to indicate that the specified function has no
+caller-saved registers.  That is, all registers are callee-saved.
+The compiler generates proper function entry and exit sequences to
+save and restore any modified registers.
+
+The user can call functions specified with the 'no_caller_saved_registers'
+attribute from an interrupt handler without saving and restoring all
+call clobbered registers.
+  }];
+}
+
 def SwiftCallDocs : Documentation {
   let Category = DocCatVariable;
   let Content = [{
Index: include/clang/Basic/Attr.td
===
--- include/clang/Basic/Attr.td
+++ include/clang/Basic/Attr.td
@@ -1652,6 +1652,13 @@
   let Documentation = [AnyX86InterruptDocs];
 }
 
+def AnyX86NoCallerSavedRegisters : InheritableAttr,
+   TargetSpecificAttr {
+  let Spellings = [GNU<"no_caller_saved_registers">];
+  let Subjects = SubjectList<[FunctionLike], WarnDiag, "ExpectedFunction">;
+  let Documentation = [AnyX86NoCallerSavedRegistersDocs];
+}
+
 def X86ForceAlignArgPointer : InheritableAttr, TargetSpecificAttr {
   let Spellings = [GNU<"force_align_arg_pointer">];
   // Technically, this appertains to a FunctionDecl, but the target-specific
Index: test/SemaCXX/attr-x86-no_caller_saved_registers.cpp
===
--- test/SemaCXX/attr-x86-no_caller_saved_registers.cpp
+++ test/SemaCXX/attr-x86-no_caller_saved_registers.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple i386-unknown-linux-gnu -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple x86_64-pc-win32 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple i386-pc-win32 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnux32 -fsyntax-only -verify %s
+
+struct a {
+  int b __attribute__((no_caller_saved_registers)); // expected-warning {{'no_caller_saved_registers' attribute only applies to functions}}
+  static void foo(int *a) __attribute__((no_caller_saved_registers)) {}
+};
+
+struct a test __attribute__((no_caller_saved_registers)); // expected-warning {{'no_caller_saved_registers' attribute only applies to functions}}
+
+__attribute__((no_caller_saved_registers)) void foo(int *) {}
+
+int main(int argc, char **argv) {
+  a::foo(&argc);
+  foo(&argc);
+  return 0;
+}
Index: test/CodeGenCXX/attr-x86-no_caller_saved_registers.cpp
===
--- test/CodeGenCXX/attr-x86-no_caller_saved_registers.cpp
+++ test/CodeGenCXX/attr-x86-no_caller_saved_registers.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i386-unknown-linux-gnu %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-pc-win32 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple i386-pc-win32 %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnux32 %

[PATCH] D17853: Disable tail-call optimization for X86 interrupt handlers

2016-03-03 Thread Amjad Aboud via cfe-commits
aaboud created this revision.
aaboud added reviewers: hjl.tools, DavidKreitzer, ABataev.
aaboud added a subscriber: cfe-commits.

Resolved Bug 26414.
https://llvm.org/bugs/show_bug.cgi?id=26414

Since interrupt handler must be returned with iretq, tail call can't be used.


http://reviews.llvm.org/D17853

Files:
  lib/CodeGen/CGCall.cpp
  test/CodeGen/attr-x86-interrupt.c

Index: lib/CodeGen/CGCall.cpp
===
--- lib/CodeGen/CGCall.cpp
+++ lib/CodeGen/CGCall.cpp
@@ -1451,6 +1451,7 @@
 
   const Decl *TargetDecl = CalleeInfo.getCalleeDecl();
 
+  bool HasAnyX86InterruptAttr = false;
   // FIXME: handle sseregparm someday...
   if (TargetDecl) {
 if (TargetDecl->hasAttr())
@@ -1488,6 +1489,7 @@
 if (TargetDecl->hasAttr())
   RetAttrs.addAttribute(llvm::Attribute::NonNull);
 
+HasAnyX86InterruptAttr = TargetDecl->hasAttr();
 HasOptnone = TargetDecl->hasAttr();
   }
 
@@ -1527,10 +1529,11 @@
 }
 
 bool DisableTailCalls =
-CodeGenOpts.DisableTailCalls ||
+CodeGenOpts.DisableTailCalls || HasAnyX86InterruptAttr ||
 (TargetDecl && TargetDecl->hasAttr());
-FuncAttrs.addAttribute("disable-tail-calls",
-   llvm::toStringRef(DisableTailCalls));
+FuncAttrs.addAttribute(
+"disable-tail-calls",
+llvm::toStringRef(DisableTailCalls));
 
 FuncAttrs.addAttribute("less-precise-fpmad",
llvm::toStringRef(CodeGenOpts.LessPreciseFPMAD));
Index: test/CodeGen/attr-x86-interrupt.c
===
--- test/CodeGen/attr-x86-interrupt.c
+++ test/CodeGen/attr-x86-interrupt.c
@@ -15,12 +15,20 @@
 // X86_64_LINUX: @llvm.used = appending global [2 x i8*] [i8* bitcast (void 
(i32*, i64)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section 
"llvm.metadata"
 // X86_64_LINUX: define x86_intrcc void @foo7(i32* %{{.+}}, i64 %{{.+}})
 // X86_64_LINUX: define x86_intrcc void @foo8(i32* %{{.+}})
+// X86_64_LINUX: "disable-tail-calls"="true"
+// X86_64_LINUX-NOT: "disable-tail-calls"="false"
 // X86_LINUX: @llvm.used = appending global [2 x i8*] [i8* bitcast (void 
(i32*, i32)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section 
"llvm.metadata"
 // X86_LINUX: define x86_intrcc void @foo7(i32* %{{.+}}, i32 %{{.+}})
 // X86_LINUX: define x86_intrcc void @foo8(i32* %{{.+}})
+// X86_LINUX: "disable-tail-calls"="true"
+// X86_LINUX-NOT: "disable-tail-calls"="false"
 // X86_64_WIN: @llvm.used = appending global [2 x i8*] [i8* bitcast (void 
(i32*, i64)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section 
"llvm.metadata"
 // X86_64_WIN: define x86_intrcc void @foo7(i32* %{{.+}}, i64 %{{.+}})
 // X86_64_WIN: define x86_intrcc void @foo8(i32* %{{.+}})
+// X86_64_Win: "disable-tail-calls"="true"
+// X86_64_Win-NOT: "disable-tail-calls"="false"
 // X86_WIN: @llvm.used = appending global [2 x i8*] [i8* bitcast (void (i32*, 
i32)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section 
"llvm.metadata"
 // X86_WIN: define x86_intrcc void @foo7(i32* %{{.+}}, i32 %{{.+}})
 // X86_WIN: define x86_intrcc void @foo8(i32* %{{.+}})
+// X86_Win: "disable-tail-calls"="true"
+// X86_Win-NOT: "disable-tail-calls"="false"


Index: lib/CodeGen/CGCall.cpp
===
--- lib/CodeGen/CGCall.cpp
+++ lib/CodeGen/CGCall.cpp
@@ -1451,6 +1451,7 @@
 
   const Decl *TargetDecl = CalleeInfo.getCalleeDecl();
 
+  bool HasAnyX86InterruptAttr = false;
   // FIXME: handle sseregparm someday...
   if (TargetDecl) {
 if (TargetDecl->hasAttr())
@@ -1488,6 +1489,7 @@
 if (TargetDecl->hasAttr())
   RetAttrs.addAttribute(llvm::Attribute::NonNull);
 
+HasAnyX86InterruptAttr = TargetDecl->hasAttr();
 HasOptnone = TargetDecl->hasAttr();
   }
 
@@ -1527,10 +1529,11 @@
 }
 
 bool DisableTailCalls =
-CodeGenOpts.DisableTailCalls ||
+CodeGenOpts.DisableTailCalls || HasAnyX86InterruptAttr ||
 (TargetDecl && TargetDecl->hasAttr());
-FuncAttrs.addAttribute("disable-tail-calls",
-   llvm::toStringRef(DisableTailCalls));
+FuncAttrs.addAttribute(
+"disable-tail-calls",
+llvm::toStringRef(DisableTailCalls));
 
 FuncAttrs.addAttribute("less-precise-fpmad",
llvm::toStringRef(CodeGenOpts.LessPreciseFPMAD));
Index: test/CodeGen/attr-x86-interrupt.c
===
--- test/CodeGen/attr-x86-interrupt.c
+++ test/CodeGen/attr-x86-interrupt.c
@@ -15,12 +15,20 @@
 // X86_64_LINUX: @llvm.used = appending global [2 x i8*] [i8* bitcast (void (i32*, i64)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section "llvm.metadata"
 // X86_64_LINUX: define x86_intrcc void @foo7(i32* %{{.+}}, i64 %{{.+}})
 // X86_64_LINUX: define x86_intrcc void @foo8(i32* %{{.+}})
+// X86_64_LINUX: "disable-ta

Re: [PATCH] D17853: Disable tail-call optimization for X86 interrupt handlers

2016-03-07 Thread Amjad Aboud via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL262830: Resolved Bug 26414. (authored by aaboud).

Changed prior to commit:
  http://reviews.llvm.org/D17853?vs=49746&id=49953#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D17853

Files:
  cfe/trunk/lib/CodeGen/CGCall.cpp
  cfe/trunk/test/CodeGen/attr-x86-interrupt.c

Index: cfe/trunk/lib/CodeGen/CGCall.cpp
===
--- cfe/trunk/lib/CodeGen/CGCall.cpp
+++ cfe/trunk/lib/CodeGen/CGCall.cpp
@@ -1451,6 +1451,7 @@
 
   const Decl *TargetDecl = CalleeInfo.getCalleeDecl();
 
+  bool HasAnyX86InterruptAttr = false;
   // FIXME: handle sseregparm someday...
   if (TargetDecl) {
 if (TargetDecl->hasAttr())
@@ -1488,6 +1489,7 @@
 if (TargetDecl->hasAttr())
   RetAttrs.addAttribute(llvm::Attribute::NonNull);
 
+HasAnyX86InterruptAttr = TargetDecl->hasAttr();
 HasOptnone = TargetDecl->hasAttr();
   }
 
@@ -1527,10 +1529,11 @@
 }
 
 bool DisableTailCalls =
-CodeGenOpts.DisableTailCalls ||
+CodeGenOpts.DisableTailCalls || HasAnyX86InterruptAttr ||
 (TargetDecl && TargetDecl->hasAttr());
-FuncAttrs.addAttribute("disable-tail-calls",
-   llvm::toStringRef(DisableTailCalls));
+FuncAttrs.addAttribute(
+"disable-tail-calls",
+llvm::toStringRef(DisableTailCalls));
 
 FuncAttrs.addAttribute("less-precise-fpmad",
llvm::toStringRef(CodeGenOpts.LessPreciseFPMAD));
Index: cfe/trunk/test/CodeGen/attr-x86-interrupt.c
===
--- cfe/trunk/test/CodeGen/attr-x86-interrupt.c
+++ cfe/trunk/test/CodeGen/attr-x86-interrupt.c
@@ -15,12 +15,20 @@
 // X86_64_LINUX: @llvm.used = appending global [2 x i8*] [i8* bitcast (void 
(i32*, i64)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section 
"llvm.metadata"
 // X86_64_LINUX: define x86_intrcc void @foo7(i32* %{{.+}}, i64 %{{.+}})
 // X86_64_LINUX: define x86_intrcc void @foo8(i32* %{{.+}})
+// X86_64_LINUX: "disable-tail-calls"="true"
+// X86_64_LINUX-NOT: "disable-tail-calls"="false"
 // X86_LINUX: @llvm.used = appending global [2 x i8*] [i8* bitcast (void 
(i32*, i32)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section 
"llvm.metadata"
 // X86_LINUX: define x86_intrcc void @foo7(i32* %{{.+}}, i32 %{{.+}})
 // X86_LINUX: define x86_intrcc void @foo8(i32* %{{.+}})
+// X86_LINUX: "disable-tail-calls"="true"
+// X86_LINUX-NOT: "disable-tail-calls"="false"
 // X86_64_WIN: @llvm.used = appending global [2 x i8*] [i8* bitcast (void 
(i32*, i64)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section 
"llvm.metadata"
 // X86_64_WIN: define x86_intrcc void @foo7(i32* %{{.+}}, i64 %{{.+}})
 // X86_64_WIN: define x86_intrcc void @foo8(i32* %{{.+}})
+// X86_64_Win: "disable-tail-calls"="true"
+// X86_64_Win-NOT: "disable-tail-calls"="false"
 // X86_WIN: @llvm.used = appending global [2 x i8*] [i8* bitcast (void (i32*, 
i32)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section 
"llvm.metadata"
 // X86_WIN: define x86_intrcc void @foo7(i32* %{{.+}}, i32 %{{.+}})
 // X86_WIN: define x86_intrcc void @foo8(i32* %{{.+}})
+// X86_Win: "disable-tail-calls"="true"
+// X86_Win-NOT: "disable-tail-calls"="false"


Index: cfe/trunk/lib/CodeGen/CGCall.cpp
===
--- cfe/trunk/lib/CodeGen/CGCall.cpp
+++ cfe/trunk/lib/CodeGen/CGCall.cpp
@@ -1451,6 +1451,7 @@
 
   const Decl *TargetDecl = CalleeInfo.getCalleeDecl();
 
+  bool HasAnyX86InterruptAttr = false;
   // FIXME: handle sseregparm someday...
   if (TargetDecl) {
 if (TargetDecl->hasAttr())
@@ -1488,6 +1489,7 @@
 if (TargetDecl->hasAttr())
   RetAttrs.addAttribute(llvm::Attribute::NonNull);
 
+HasAnyX86InterruptAttr = TargetDecl->hasAttr();
 HasOptnone = TargetDecl->hasAttr();
   }
 
@@ -1527,10 +1529,11 @@
 }
 
 bool DisableTailCalls =
-CodeGenOpts.DisableTailCalls ||
+CodeGenOpts.DisableTailCalls || HasAnyX86InterruptAttr ||
 (TargetDecl && TargetDecl->hasAttr());
-FuncAttrs.addAttribute("disable-tail-calls",
-   llvm::toStringRef(DisableTailCalls));
+FuncAttrs.addAttribute(
+"disable-tail-calls",
+llvm::toStringRef(DisableTailCalls));
 
 FuncAttrs.addAttribute("less-precise-fpmad",
llvm::toStringRef(CodeGenOpts.LessPreciseFPMAD));
Index: cfe/trunk/test/CodeGen/attr-x86-interrupt.c
===
--- cfe/trunk/test/CodeGen/attr-x86-interrupt.c
+++ cfe/trunk/test/CodeGen/attr-x86-interrupt.c
@@ -15,12 +15,20 @@
 // X86_64_LINUX: @llvm.used = appending global [2 x i8*] [i8* bitcast (void (i32*, i64)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section "llvm.metadata"
 // X86_64_LINUX: define x86_intrcc void @foo7(i32*

r262830 - Resolved Bug 26414.

2016-03-07 Thread Amjad Aboud via cfe-commits
Author: aaboud
Date: Mon Mar  7 08:22:46 2016
New Revision: 262830

URL: http://llvm.org/viewvc/llvm-project?rev=262830&view=rev
Log:
Resolved Bug 26414.
https://llvm.org/bugs/show_bug.cgi?id=26414
Since interrupt handler must be returned with iret, tail call can't be used.

Differential Revision: http://reviews.llvm.org/D17853

Modified:
cfe/trunk/lib/CodeGen/CGCall.cpp
cfe/trunk/test/CodeGen/attr-x86-interrupt.c

Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=262830&r1=262829&r2=262830&view=diff
==
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Mon Mar  7 08:22:46 2016
@@ -1451,6 +1451,7 @@ void CodeGenModule::ConstructAttributeLi
 
   const Decl *TargetDecl = CalleeInfo.getCalleeDecl();
 
+  bool HasAnyX86InterruptAttr = false;
   // FIXME: handle sseregparm someday...
   if (TargetDecl) {
 if (TargetDecl->hasAttr())
@@ -1488,6 +1489,7 @@ void CodeGenModule::ConstructAttributeLi
 if (TargetDecl->hasAttr())
   RetAttrs.addAttribute(llvm::Attribute::NonNull);
 
+HasAnyX86InterruptAttr = TargetDecl->hasAttr();
 HasOptnone = TargetDecl->hasAttr();
   }
 
@@ -1527,10 +1529,11 @@ void CodeGenModule::ConstructAttributeLi
 }
 
 bool DisableTailCalls =
-CodeGenOpts.DisableTailCalls ||
+CodeGenOpts.DisableTailCalls || HasAnyX86InterruptAttr ||
 (TargetDecl && TargetDecl->hasAttr());
-FuncAttrs.addAttribute("disable-tail-calls",
-   llvm::toStringRef(DisableTailCalls));
+FuncAttrs.addAttribute(
+"disable-tail-calls",
+llvm::toStringRef(DisableTailCalls));
 
 FuncAttrs.addAttribute("less-precise-fpmad",
llvm::toStringRef(CodeGenOpts.LessPreciseFPMAD));

Modified: cfe/trunk/test/CodeGen/attr-x86-interrupt.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/attr-x86-interrupt.c?rev=262830&r1=262829&r2=262830&view=diff
==
--- cfe/trunk/test/CodeGen/attr-x86-interrupt.c (original)
+++ cfe/trunk/test/CodeGen/attr-x86-interrupt.c Mon Mar  7 08:22:46 2016
@@ -15,12 +15,20 @@ __attribute__((interrupt)) void foo8(int
 // X86_64_LINUX: @llvm.used = appending global [2 x i8*] [i8* bitcast (void 
(i32*, i64)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section 
"llvm.metadata"
 // X86_64_LINUX: define x86_intrcc void @foo7(i32* %{{.+}}, i64 %{{.+}})
 // X86_64_LINUX: define x86_intrcc void @foo8(i32* %{{.+}})
+// X86_64_LINUX: "disable-tail-calls"="true"
+// X86_64_LINUX-NOT: "disable-tail-calls"="false"
 // X86_LINUX: @llvm.used = appending global [2 x i8*] [i8* bitcast (void 
(i32*, i32)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section 
"llvm.metadata"
 // X86_LINUX: define x86_intrcc void @foo7(i32* %{{.+}}, i32 %{{.+}})
 // X86_LINUX: define x86_intrcc void @foo8(i32* %{{.+}})
+// X86_LINUX: "disable-tail-calls"="true"
+// X86_LINUX-NOT: "disable-tail-calls"="false"
 // X86_64_WIN: @llvm.used = appending global [2 x i8*] [i8* bitcast (void 
(i32*, i64)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section 
"llvm.metadata"
 // X86_64_WIN: define x86_intrcc void @foo7(i32* %{{.+}}, i64 %{{.+}})
 // X86_64_WIN: define x86_intrcc void @foo8(i32* %{{.+}})
+// X86_64_Win: "disable-tail-calls"="true"
+// X86_64_Win-NOT: "disable-tail-calls"="false"
 // X86_WIN: @llvm.used = appending global [2 x i8*] [i8* bitcast (void (i32*, 
i32)* @foo7 to i8*), i8* bitcast (void (i32*)* @foo8 to i8*)], section 
"llvm.metadata"
 // X86_WIN: define x86_intrcc void @foo7(i32* %{{.+}}, i32 %{{.+}})
 // X86_WIN: define x86_intrcc void @foo8(i32* %{{.+}})
+// X86_Win: "disable-tail-calls"="true"
+// X86_Win-NOT: "disable-tail-calls"="false"


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r263380 - Added test that covers changes in r263379.

2016-03-13 Thread Amjad Aboud via cfe-commits
Author: aaboud
Date: Sun Mar 13 06:12:57 2016
New Revision: 263380

URL: http://llvm.org/viewvc/llvm-project?rev=263380&view=rev
Log:
Added test that covers changes in r263379.

Added:
cfe/trunk/test/CodeGen/debug-info-imported-entity.cpp

Added: cfe/trunk/test/CodeGen/debug-info-imported-entity.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/debug-info-imported-entity.cpp?rev=263380&view=auto
==
--- cfe/trunk/test/CodeGen/debug-info-imported-entity.cpp (added)
+++ cfe/trunk/test/CodeGen/debug-info-imported-entity.cpp Sun Mar 13 06:12:57 
2016
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple x86_64-unk-unk -o - -emit-llvm 
-debug-info-kind=limited %s | FileCheck %s
+
+namespace std { class A; }
+using std::A; using ::A;
+
+
+// CHECK: [[CompileUnit:![0-9]+]] = distinct !DICompileUnit({{.+}} imports: 
[[Imports:![0-9]+]])
+// CHECK: [[Imports]] = !{[[ImportedEntity:![0-9]+]]}
+// CHECK: [[ImportedEntity]] = !DIImportedEntity(tag: 
DW_TAG_imported_declaration, scope: [[CompileUnit]], entity: !"_ZTSSt1A", line: 
4)
+


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r263425 - Recommitted r261634 "Supporting all entities declared in lexical scope in LLVM debug info."

2016-03-14 Thread Amjad Aboud via cfe-commits
Author: aaboud
Date: Mon Mar 14 07:03:55 2016
New Revision: 263425

URL: http://llvm.org/viewvc/llvm-project?rev=263425&view=rev
Log:
Recommitted r261634 "Supporting all entities declared in lexical scope in LLVM 
debug info."
After fixing PR26715 at r263379.

Added:
cfe/trunk/test/CodeGenCXX/debug-info-lb.cpp
  - copied unchanged from r261669, 
cfe/trunk/test/CodeGenCXX/debug-info-lb.cpp
Modified:
cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
cfe/trunk/lib/CodeGen/CGDebugInfo.h
cfe/trunk/lib/CodeGen/CGDecl.cpp
cfe/trunk/test/CodeGenCXX/debug-info-anon-union-vars.cpp

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=263425&r1=263424&r2=263425&view=diff
==
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Mon Mar 14 07:03:55 2016
@@ -831,15 +831,18 @@ llvm::DIType *CGDebugInfo::CreateType(co
 
 llvm::DIType *CGDebugInfo::CreateType(const TypedefType *Ty,
   llvm::DIFile *Unit) {
+  TypedefNameDecl *TD = Ty->getDecl();
   // We don't set size information, but do specify where the typedef was
   // declared.
-  SourceLocation Loc = Ty->getDecl()->getLocation();
+  SourceLocation Loc = TD->getLocation();
+
+  llvm::DIScope *TDContext = getDeclarationLexicalScope(*TD, QualType(Ty, 0));
 
   // Typedefs are derived from some other type.
   return DBuilder.createTypedef(
   getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
   Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
-  getDeclContextDescriptor(Ty->getDecl()));
+  TDContext);
 }
 
 llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty,
@@ -1472,6 +1475,23 @@ llvm::DIType *CGDebugInfo::getOrCreateSt
   return T;
 }
 
+void CGDebugInfo::recordDeclarationLexicalScope(const Decl &D) {
+  assert(LexicalBlockMap.find(&D) == LexicalBlockMap.end() &&
+ "D is already mapped to lexical block scope");
+  if (!LexicalBlockStack.empty())
+LexicalBlockMap[&D] = LexicalBlockStack.back();
+}
+
+llvm::DIScope *CGDebugInfo::getDeclarationLexicalScope(const Decl &D,
+   QualType Ty) {
+  auto I = LexicalBlockMap.find(&D);
+  if (I != LexicalBlockMap.end()) {
+RetainedTypes.push_back(Ty.getAsOpaquePtr());
+return I->second;
+  }
+  return getDeclContextDescriptor(cast(&D));
+}
+
 void CGDebugInfo::completeType(const EnumDecl *ED) {
   if (DebugKind <= codegenoptions::DebugLineTablesOnly)
 return;
@@ -2057,7 +2077,7 @@ llvm::DIType *CGDebugInfo::CreateEnumTyp
 // entered into the ReplaceMap: finalize() will replace the first
 // FwdDecl with the second and then replace the second with
 // complete type.
-llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
+llvm::DIScope *EDContext = getDeclarationLexicalScope(*ED, QualType(Ty, 
0));
 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
 llvm::dwarf::DW_TAG_enumeration_type, "", TheCU, DefUnit, 0));
@@ -2101,7 +2121,7 @@ llvm::DIType *CGDebugInfo::CreateTypeDef
 
   llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
   unsigned Line = getLineNumber(ED->getLocation());
-  llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
+  llvm::DIScope *EnumContext = getDeclarationLexicalScope(*ED, QualType(Ty, 
0));
   llvm::DIType *ClassTy =
   ED->isFixed() ? getOrCreateType(ED->getIntegerType(), DefUnit) : nullptr;
   return DBuilder.createEnumerationType(EnumContext, ED->getName(), DefUnit,
@@ -2362,7 +2382,7 @@ llvm::DICompositeType *CGDebugInfo::Crea
   unsigned Line = getLineNumber(RD->getLocation());
   StringRef RDName = getClassName(RD);
 
-  llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
+  llvm::DIScope *RDContext = getDeclarationLexicalScope(*RD, QualType(Ty, 0));
 
   // If we ended up creating the type during the context chain construction,
   // just return that.
@@ -2509,8 +2529,15 @@ void CGDebugInfo::collectVarDeclProps(co
   if (DC->isRecord())
 DC = CGM.getContext().getTranslationUnitDecl();
 
- llvm::DIScope *Mod = getParentModuleOrNull(VD);
- VDContext = getContextDescriptor(cast(DC), Mod ? Mod : TheCU);
+  if (VD->isStaticLocal()) {
+// Get context for static locals (that are technically globals) the same 
way
+// we do for "local" locals -- by using current lexical block.
+assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack 
empty!");
+VDContext = LexicalBlockStack.back();
+  } else {
+llvm::DIScope *Mod = getParentModuleOrNull(VD);
+VDContext = getContextDescriptor(cast(DC), Mod ? Mod : TheCU);
+  }
 }
 
 llvm::DISubprogram *

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.h?re

r264281 - Recommitted r263425 "Supporting all entities declared in lexical scope in LLVM debug info."

2016-03-24 Thread Amjad Aboud via cfe-commits
Author: aaboud
Date: Thu Mar 24 08:30:41 2016
New Revision: 264281

URL: http://llvm.org/viewvc/llvm-project?rev=264281&view=rev
Log:
Recommitted r263425 "Supporting all entities declared in lexical scope in LLVM 
debug info."
After fixing PR26942 (the fix is included in this commit).

Differential Revision: http://reviews.llvm.org/D18350

Added:
cfe/trunk/test/CodeGenCXX/debug-info-lb.cpp
  - copied unchanged from r263435, 
cfe/trunk/test/CodeGenCXX/debug-info-lb.cpp
Modified:
cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
cfe/trunk/lib/CodeGen/CGDebugInfo.h
cfe/trunk/lib/CodeGen/CGDecl.cpp
cfe/trunk/test/CodeGenCXX/debug-info-anon-union-vars.cpp

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=264281&r1=264280&r2=264281&view=diff
==
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Thu Mar 24 08:30:41 2016
@@ -831,15 +831,18 @@ llvm::DIType *CGDebugInfo::CreateType(co
 
 llvm::DIType *CGDebugInfo::CreateType(const TypedefType *Ty,
   llvm::DIFile *Unit) {
+  TypedefNameDecl *TD = Ty->getDecl();
   // We don't set size information, but do specify where the typedef was
   // declared.
-  SourceLocation Loc = Ty->getDecl()->getLocation();
+  SourceLocation Loc = TD->getLocation();
+
+  llvm::DIScope *TDContext = getDeclarationLexicalScope(*TD, QualType(Ty, 0));
 
   // Typedefs are derived from some other type.
   return DBuilder.createTypedef(
   getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
   Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
-  getDeclContextDescriptor(Ty->getDecl()));
+  TDContext);
 }
 
 llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty,
@@ -1472,6 +1475,23 @@ llvm::DIType *CGDebugInfo::getOrCreateSt
   return T;
 }
 
+void CGDebugInfo::recordDeclarationLexicalScope(const Decl &D) {
+  assert(LexicalBlockMap.find(&D) == LexicalBlockMap.end() &&
+ "D is already mapped to lexical block scope");
+  if (!LexicalBlockStack.empty())
+LexicalBlockMap[&D] = LexicalBlockStack.back();
+}
+
+llvm::DIScope *CGDebugInfo::getDeclarationLexicalScope(const Decl &D,
+   QualType Ty) {
+  auto I = LexicalBlockMap.find(&D);
+  if (I != LexicalBlockMap.end()) {
+RetainedTypes.push_back(Ty.getAsOpaquePtr());
+return I->second;
+  }
+  return getDeclContextDescriptor(cast(&D));
+}
+
 void CGDebugInfo::completeType(const EnumDecl *ED) {
   if (DebugKind <= codegenoptions::DebugLineTablesOnly)
 return;
@@ -2057,7 +2077,7 @@ llvm::DIType *CGDebugInfo::CreateEnumTyp
 // entered into the ReplaceMap: finalize() will replace the first
 // FwdDecl with the second and then replace the second with
 // complete type.
-llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
+llvm::DIScope *EDContext = getDeclarationLexicalScope(*ED, QualType(Ty, 
0));
 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
 llvm::TempDIScope TmpContext(DBuilder.createReplaceableCompositeType(
 llvm::dwarf::DW_TAG_enumeration_type, "", TheCU, DefUnit, 0));
@@ -2101,7 +2121,7 @@ llvm::DIType *CGDebugInfo::CreateTypeDef
 
   llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());
   unsigned Line = getLineNumber(ED->getLocation());
-  llvm::DIScope *EnumContext = getDeclContextDescriptor(ED);
+  llvm::DIScope *EnumContext = getDeclarationLexicalScope(*ED, QualType(Ty, 
0));
   llvm::DIType *ClassTy =
   ED->isFixed() ? getOrCreateType(ED->getIntegerType(), DefUnit) : nullptr;
   return DBuilder.createEnumerationType(EnumContext, ED->getName(), DefUnit,
@@ -2362,7 +2382,7 @@ llvm::DICompositeType *CGDebugInfo::Crea
   unsigned Line = getLineNumber(RD->getLocation());
   StringRef RDName = getClassName(RD);
 
-  llvm::DIScope *RDContext = getDeclContextDescriptor(RD);
+  llvm::DIScope *RDContext = getDeclarationLexicalScope(*RD, QualType(Ty, 0));
 
   // If we ended up creating the type during the context chain construction,
   // just return that.
@@ -2509,8 +2529,15 @@ void CGDebugInfo::collectVarDeclProps(co
   if (DC->isRecord())
 DC = CGM.getContext().getTranslationUnitDecl();
 
- llvm::DIScope *Mod = getParentModuleOrNull(VD);
- VDContext = getContextDescriptor(cast(DC), Mod ? Mod : TheCU);
+  if (VD->isStaticLocal()) {
+// Get context for static locals (that are technically globals) the same 
way
+// we do for "local" locals -- by using current lexical block.
+assert(!LexicalBlockStack.empty() && "Region stack mismatch, stack 
empty!");
+VDContext = LexicalBlockStack.back();
+  } else {
+llvm::DIScope *Mod = getParentModuleOrNull(VD);
+VDContext = getContextDescriptor(cast(DC), Mod ? Mod : TheCU);
+  }
 }
 
 llvm::DISubprogram *

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.h

[PATCH] D15977: [Clang] Supporting all entities declared in lexical scope in LLVM debug info

2016-01-07 Thread Amjad Aboud via cfe-commits
aaboud created this revision.
aaboud added reviewers: probinson, aprantl, echristo, dblaikie.
aaboud added a subscriber: cfe-commits.

This is the full implementation in Clang of the proposal:
http://lists.llvm.org/pipermail/llvm-dev/2015-December/093313.html

http://reviews.llvm.org/D15977

Files:
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CGDebugInfo.h
  lib/CodeGen/CGDecl.cpp
  test/CodeGenCXX/debug-info-lb-class.cpp
  test/CodeGenCXX/debug-info-lb-static.cpp
  test/CodeGenCXX/debug-info-lb-static2.cpp
  test/CodeGenCXX/debug-info-lb-typedef.cpp

Index: lib/CodeGen/CGDecl.cpp
===
--- lib/CodeGen/CGDecl.cpp
+++ lib/CodeGen/CGDecl.cpp
@@ -83,26 +83,30 @@
   case Decl::UsingShadow:
   case Decl::ObjCTypeParam:
 llvm_unreachable("Declaration should not be in declstmts!");
-  case Decl::Function:  // void X();
-  case Decl::Record:// struct/union/class X;
-  case Decl::Enum:  // enum X;
-  case Decl::EnumConstant: // enum ? { X = ? }
-  case Decl::CXXRecord: // struct/union/class X; [C++]
+  case Decl::Function: // void X();
   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;
 
+  case Decl::Record:   // struct/union/class X;
+  case Decl::Enum: // enum X;
+  case Decl::EnumConstant: // enum ? { X = ? }
+  case Decl::CXXRecord:// struct/union/class X; [C++]
+if (CGDebugInfo *DI = getDebugInfo())
+  DI->recordDeclarationLexicalScope(D);
+return;
+
   case Decl::NamespaceAlias:
 if (CGDebugInfo *DI = getDebugInfo())
-DI->EmitNamespaceAlias(cast(D));
+  DI->EmitNamespaceAlias(cast(D));
 return;
   case Decl::Using:  // using X; [C++]
 if (CGDebugInfo *DI = getDebugInfo())
-DI->EmitUsingDecl(cast(D));
+  DI->EmitUsingDecl(cast(D));
 return;
   case Decl::UsingDirective: // using namespace X; [C++]
 if (CGDebugInfo *DI = getDebugInfo())
@@ -120,6 +124,9 @@
 const TypedefNameDecl &TD = cast(D);
 QualType Ty = TD.getUnderlyingType();
 
+if (CGDebugInfo *DI = getDebugInfo())
+  DI->recordDeclarationLexicalScope(D);
+
 if (Ty->isVariablyModifiedType())
   EmitVariablyModifiedType(Ty);
   }
Index: lib/CodeGen/CGDebugInfo.h
===
--- lib/CodeGen/CGDebugInfo.h
+++ lib/CodeGen/CGDebugInfo.h
@@ -114,6 +114,11 @@
 
   /// Keep track of our current nested lexical block.
   std::vector> LexicalBlockStack;
+
+  /// Map of AST declaration to its lexical block scope.
+  llvm::DenseMap>
+  LexicalBlockMap;
+
   llvm::DenseMap RegionMap;
   /// Keep track of LexicalBlockStack counter at the beginning of a
   /// function. This is used to pop unbalanced regions at the end of a
@@ -365,6 +370,12 @@
   /// Emit an Objective-C interface type standalone debug info.
   llvm::DIType *getOrCreateInterfaceType(QualType Ty, SourceLocation Loc);
 
+  /// Map AST declaration to its lexical block scope if available.
+  void recordDeclarationLexicalScope(const Decl &D);
+
+  /// Get lexical scope of AST declaration.
+  llvm::DIScope *getDeclarationLexicalScope(const Decl &D, QualType Ty);
+
   /// Emit standalone debug info for a type.
   llvm::DIType *getOrCreateStandaloneType(QualType Ty, SourceLocation Loc);
 
Index: lib/CodeGen/CGDebugInfo.cpp
===
--- lib/CodeGen/CGDebugInfo.cpp
+++ lib/CodeGen/CGDebugInfo.cpp
@@ -831,15 +831,18 @@
 
 llvm::DIType *CGDebugInfo::CreateType(const TypedefType *Ty,
   llvm::DIFile *Unit) {
+  TypedefNameDecl *TD = Ty->getDecl();
   // We don't set size information, but do specify where the typedef was
   // declared.
-  SourceLocation Loc = Ty->getDecl()->getLocation();
+  SourceLocation Loc = TD->getLocation();
+
+  llvm::DIScope *TDContext = getDeclarationLexicalScope(*TD, QualType(Ty, 0));
 
   // Typedefs are derived from some other type.
   return DBuilder.createTypedef(
   getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
   Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
-  getDeclContextDescriptor(Ty->getDecl()));
+  TDContext);
 }
 
 llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty,
@@ -1472,6 +1475,23 @@
   return T;
 }
 
+void CGDebugInfo::recordDeclarationLexicalScope(const Decl &D) {
+  assert(LexicalBlockMap.find(&D) == LexicalBlockMap.end() &&
+ "D is already mapped to lexical block scope");
+  if (!LexicalBlockStack.empty())
+LexicalBlockMap[&D] = LexicalBlockStack.back();
+}
+
+llvm::DIScope *CGDebugInfo::getDeclarationLexicalScope(const Decl &D,
+   QualType Ty) {
+  auto I = LexicalBlockMap.find(&D);
+  if (I != LexicalBlockMap.end()) {
+

[PATCH] D16135: Macro Debug Info support in Clang

2016-01-13 Thread Amjad Aboud via cfe-commits
aaboud created this revision.
aaboud added reviewers: dblaikie, rsmith, aprantl, probinson.
aaboud added a subscriber: cfe-commits.

Added support for FE Clang to create Debug Info entries (DIMacro and 
DIMacroFile) into generated module if "debug-info-kind" flag is set to 
"standalone".

http://reviews.llvm.org/D16135

Files:
  include/clang/AST/ASTConsumer.h
  lib/AST/ASTConsumer.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CGDebugInfo.h
  lib/CodeGen/CMakeLists.txt
  lib/CodeGen/CodeGenAction.cpp
  lib/CodeGen/CodeGenModule.cpp
  lib/CodeGen/CodeGenModule.h
  lib/CodeGen/MacroPPCallbacks.cpp
  lib/CodeGen/MacroPPCallbacks.h
  lib/CodeGen/ModuleBuilder.cpp
  lib/Parse/ParseAST.cpp

Index: lib/Parse/ParseAST.cpp
===
--- lib/Parse/ParseAST.cpp
+++ lib/Parse/ParseAST.cpp
@@ -128,6 +128,12 @@
   new Parser(S.getPreprocessor(), S, SkipFunctionBodies));
   Parser &P = *ParseOP.get();
 
+  std::unique_ptr Callbacks =
+  Consumer->CreatePreprocessorCallbacks(S.getPreprocessor());
+  if (Callbacks) {
+S.getPreprocessor().addPPCallbacks(std::move(Callbacks));
+  }
+
   llvm::CrashRecoveryContextCleanupRegistrar
   CleanupPrettyStack(llvm::SavePrettyStackState());
   PrettyStackTraceParserEntry CrashInfo(P);
Index: lib/CodeGen/ModuleBuilder.cpp
===
--- lib/CodeGen/ModuleBuilder.cpp
+++ lib/CodeGen/ModuleBuilder.cpp
@@ -20,6 +20,7 @@
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Frontend/CodeGenOptions.h"
+#include "clang/Lex/PPCallbacks.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/LLVMContext.h"
@@ -234,6 +235,11 @@
 void HandleDependentLibrary(llvm::StringRef Lib) override {
   Builder->AddDependentLib(Lib);
 }
+
+std::unique_ptr
+CreatePreprocessorCallbacks(Preprocessor &PP) override {
+  return Builder->createPreprocessorCallbacks(PP);
+}
   };
 }
 
Index: lib/CodeGen/CodeGenModule.cpp
===
--- lib/CodeGen/CodeGenModule.cpp
+++ lib/CodeGen/CodeGenModule.cpp
@@ -24,6 +24,7 @@
 #include "CodeGenPGO.h"
 #include "CodeGenTBAA.h"
 #include "CoverageMappingGen.h"
+#include "MacroPPCallbacks.h"
 #include "TargetInfo.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CharUnits.h"
@@ -208,6 +209,16 @@
   CUDARuntime = CreateNVCUDARuntime(*this);
 }
 
+std::unique_ptr
+CodeGenModule::createPreprocessorCallbacks(Preprocessor &PP) {
+  // Enable generating macro debug info only in FullDebugInfo mode.
+  if (CodeGenOpts.getDebugInfo() < CodeGenOptions::FullDebugInfo ||
+  !getModuleDebugInfo())
+return nullptr;
+
+  return std::make_unique(*getModuleDebugInfo(), PP);
+}
+
 void CodeGenModule::addReplacement(StringRef Name, llvm::Constant *C) {
   Replacements[Name] = C;
 }
Index: lib/CodeGen/MacroPPCallbacks.h
===
--- lib/CodeGen/MacroPPCallbacks.h
+++ lib/CodeGen/MacroPPCallbacks.h
@@ -0,0 +1,94 @@
+//===--- MacroPPCallbacks.h ---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+//
+//  This file defines implementation for the macro preprocessors callbacks.
+//
+//===--===//
+
+#include "clang/Lex/PPCallbacks.h"
+#include "clang/Parse/Parser.h"
+#include 
+
+namespace llvm {
+  class DIMacroFile;
+}
+namespace clang {
+
+namespace CodeGen {
+  class CGDebugInfo;
+}
+class MacroPPCallbacks : public PPCallbacks {
+  CodeGen::CGDebugInfo &DebugInfo;
+  Preprocessor &PP;
+  SourceLocation LastHashLoc;
+  SourceLocation FirstIncludeFile;
+  bool FirstInclude;
+  bool FirstIncludeDone;
+  int CommandIncludeFiles;
+  int SkipFiles;
+  std::vector Parents;
+
+
+  static void getMacroDefinition(const IdentifierInfo &II, const MacroInfo &MI,
+ Preprocessor &PP, raw_ostream &Name,
+ raw_ostream &Value);
+
+public:
+  MacroPPCallbacks(CodeGen::CGDebugInfo& DI, Preprocessor &PP);
+
+  /// \brief Callback invoked whenever a source file is entered or exited.
+  ///
+  /// \param Loc Indicates the new location.
+  /// \param PrevFID the file that was exited if \p Reason is ExitFile.
+  virtual void FileChanged(SourceLocation Loc, FileChangeReason Reason,
+   SrcMgr::CharacteristicKind FileType,
+   FileID PrevFID = FileID());
+
+  /// \brief Callback invoked whenever a source file is skipped as the result
+  /// of header guard optimization.
+  ///
+  /// \param SkippedFile The file that is skipped i

Re: [PATCH] D16135: Macro Debug Info support in Clang

2016-01-13 Thread Amjad Aboud via cfe-commits
aaboud added inline comments.


Comment at: include/clang/AST/ASTConsumer.h:163
@@ -155,1 +162,3 @@
+  /// The caller takes ownership on the returned pointer.
+  virtual std::unique_ptr 
CreatePreprocessorCallbacks(Preprocessor &PP);
 };

Richard,
I know that you suggested not to introduce the Preprocessor in anyway to the 
ASTConsumer.
However, as I could not understand the other way to support macros in Clang 
without applying a huge redesign, I decided to upload the code I suggested in 
the proposal.
http://lists.llvm.org/pipermail/llvm-dev/2015-November/092449.html

If you still think that this approach is not the right one, I would appreciate 
it if you can explain again how to implement the macro support differently.


http://reviews.llvm.org/D16135



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D15977: [Clang] Supporting all entities declared in lexical scope in LLVM debug info

2016-01-20 Thread Amjad Aboud via cfe-commits
aaboud updated this revision to Diff 45400.
aaboud added a comment.

Merged all 4 Lit tests into one.


http://reviews.llvm.org/D15977

Files:
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CGDebugInfo.h
  lib/CodeGen/CGDecl.cpp
  test/CodeGenCXX/debug-info-lb.cpp

Index: lib/CodeGen/CGDecl.cpp
===
--- lib/CodeGen/CGDecl.cpp
+++ lib/CodeGen/CGDecl.cpp
@@ -83,26 +83,30 @@
   case Decl::UsingShadow:
   case Decl::ObjCTypeParam:
 llvm_unreachable("Declaration should not be in declstmts!");
-  case Decl::Function:  // void X();
-  case Decl::Record:// struct/union/class X;
-  case Decl::Enum:  // enum X;
-  case Decl::EnumConstant: // enum ? { X = ? }
-  case Decl::CXXRecord: // struct/union/class X; [C++]
+  case Decl::Function: // void X();
   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;
 
+  case Decl::Record:   // struct/union/class X;
+  case Decl::Enum: // enum X;
+  case Decl::EnumConstant: // enum ? { X = ? }
+  case Decl::CXXRecord:// struct/union/class X; [C++]
+if (CGDebugInfo *DI = getDebugInfo())
+  DI->recordDeclarationLexicalScope(D);
+return;
+
   case Decl::NamespaceAlias:
 if (CGDebugInfo *DI = getDebugInfo())
-DI->EmitNamespaceAlias(cast(D));
+  DI->EmitNamespaceAlias(cast(D));
 return;
   case Decl::Using:  // using X; [C++]
 if (CGDebugInfo *DI = getDebugInfo())
-DI->EmitUsingDecl(cast(D));
+  DI->EmitUsingDecl(cast(D));
 return;
   case Decl::UsingDirective: // using namespace X; [C++]
 if (CGDebugInfo *DI = getDebugInfo())
@@ -120,6 +124,9 @@
 const TypedefNameDecl &TD = cast(D);
 QualType Ty = TD.getUnderlyingType();
 
+if (CGDebugInfo *DI = getDebugInfo())
+  DI->recordDeclarationLexicalScope(D);
+
 if (Ty->isVariablyModifiedType())
   EmitVariablyModifiedType(Ty);
   }
Index: lib/CodeGen/CGDebugInfo.h
===
--- lib/CodeGen/CGDebugInfo.h
+++ lib/CodeGen/CGDebugInfo.h
@@ -114,6 +114,11 @@
 
   /// Keep track of our current nested lexical block.
   std::vector> LexicalBlockStack;
+
+  /// Map of AST declaration to its lexical block scope.
+  llvm::DenseMap>
+  LexicalBlockMap;
+
   llvm::DenseMap RegionMap;
   /// Keep track of LexicalBlockStack counter at the beginning of a
   /// function. This is used to pop unbalanced regions at the end of a
@@ -365,6 +370,12 @@
   /// Emit an Objective-C interface type standalone debug info.
   llvm::DIType *getOrCreateInterfaceType(QualType Ty, SourceLocation Loc);
 
+  /// Map AST declaration to its lexical block scope if available.
+  void recordDeclarationLexicalScope(const Decl &D);
+
+  /// Get lexical scope of AST declaration.
+  llvm::DIScope *getDeclarationLexicalScope(const Decl &D, QualType Ty);
+
   /// Emit standalone debug info for a type.
   llvm::DIType *getOrCreateStandaloneType(QualType Ty, SourceLocation Loc);
 
Index: lib/CodeGen/CGDebugInfo.cpp
===
--- lib/CodeGen/CGDebugInfo.cpp
+++ lib/CodeGen/CGDebugInfo.cpp
@@ -831,15 +831,18 @@
 
 llvm::DIType *CGDebugInfo::CreateType(const TypedefType *Ty,
   llvm::DIFile *Unit) {
+  TypedefNameDecl *TD = Ty->getDecl();
   // We don't set size information, but do specify where the typedef was
   // declared.
-  SourceLocation Loc = Ty->getDecl()->getLocation();
+  SourceLocation Loc = TD->getLocation();
+
+  llvm::DIScope *TDContext = getDeclarationLexicalScope(*TD, QualType(Ty, 0));
 
   // Typedefs are derived from some other type.
   return DBuilder.createTypedef(
   getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
   Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
-  getDeclContextDescriptor(Ty->getDecl()));
+  TDContext);
 }
 
 llvm::DIType *CGDebugInfo::CreateType(const FunctionType *Ty,
@@ -1472,6 +1475,23 @@
   return T;
 }
 
+void CGDebugInfo::recordDeclarationLexicalScope(const Decl &D) {
+  assert(LexicalBlockMap.find(&D) == LexicalBlockMap.end() &&
+ "D is already mapped to lexical block scope");
+  if (!LexicalBlockStack.empty())
+LexicalBlockMap[&D] = LexicalBlockStack.back();
+}
+
+llvm::DIScope *CGDebugInfo::getDeclarationLexicalScope(const Decl &D,
+   QualType Ty) {
+  auto I = LexicalBlockMap.find(&D);
+  if (I != LexicalBlockMap.end()) {
+RetainedTypes.push_back(Ty.getAsOpaquePtr());
+return I->second;
+  } else
+return getDeclContextDescriptor(cast(&D));
+}
+
 void CGDebugInfo::completeType(const EnumDecl *ED) {
   if (DebugKind <= CodeGenOptions::DebugLineTablesOnly)
 return;
@@ -2043,7 +2063,7 @@
   // If thi

Re: [PATCH] D15977: [Clang] Supporting all entities declared in lexical scope in LLVM debug info

2016-01-25 Thread Amjad Aboud via cfe-commits
aaboud marked an inline comment as done.
aaboud added a comment.

Thanks David for the feedback.
I have some answers below, please let me know if they are not sufficient or you 
are still have concerns.



Comment at: lib/CodeGen/CGDebugInfo.cpp:1479
@@ +1478,3 @@
+void CGDebugInfo::recordDeclarationLexicalScope(const Decl &D) {
+  assert(LexicalBlockMap.find(&D) == LexicalBlockMap.end() &&
+ "D is already mapped to lexical block scope");

dblaikie wrote:
> Dose this assert not fire if there are two decls in the same lexical scope?
Why two decls would have the same object instance "Decl"?
I am not sure even that you can declare two decls with same name at same 
lexical-scope, but even if they are defined in the same lexical scope, they 
will have different line numbers, right?


Comment at: lib/CodeGen/CGDebugInfo.cpp:1481
@@ +1480,3 @@
+ "D is already mapped to lexical block scope");
+  if (!LexicalBlockStack.empty())
+LexicalBlockMap[&D] = LexicalBlockStack.back();

dblaikie wrote:
> Should we assert that LexicalBlockStack isn't empty?
It might be empty, if the declaration is in the program scope, right?
So, we do not want to assert, just to check.


Comment at: lib/CodeGen/CGDebugInfo.cpp:1488
@@ +1487,3 @@
+  auto I = LexicalBlockMap.find(&D);
+  if (I != LexicalBlockMap.end()) {
+RetainedTypes.push_back(Ty.getAsOpaquePtr());

dblaikie wrote:
> Perhaps we should assert here that if D's scope is a lexical block, that it 
> should have a corresponding entry in the LexicalBlockMap?
We will get to this function also for D's that are not in lexical scope.
We should not assert, that is also why we have the else handling (which is how 
we used to get context before).

I can agree with you that the function name is misleading, and I am open to 
other suggestions.


Comment at: lib/CodeGen/CGDebugInfo.cpp:1489
@@ +1488,3 @@
+  if (I != LexicalBlockMap.end()) {
+RetainedTypes.push_back(Ty.getAsOpaquePtr());
+return I->second;

dblaikie wrote:
> Why does the type need to be added to the retained types list?
Excellent question :)
This was your suggestion few months ago.
The reason is that backend will need to know what types are declared in lexical 
blocks.
Imported entities are collected in the import entity list, while types are 
collected in the retained types.

Check line 518 at DwarfDebug.cpp (http://reviews.llvm.org/D15976#51cfb106)


Comment at: lib/CodeGen/CGDebugInfo.cpp:2066
@@ -2045,3 +2065,3 @@
   if (isImportedFromModule || !ED->getDefinition()) {
-llvm::DIScope *EDContext = getDeclContextDescriptor(ED);
+llvm::DIScope *EDContext = getDeclarationLexicalScope(*ED, QualType(Ty, 
0));
 llvm::DIFile *DefUnit = getOrCreateFile(ED->getLocation());

dblaikie wrote:
> Would it be reasonable/possible to do these changes one at a time & 
> demonstrate the different situations in which types were not correctly nested 
> in lexical scopes? Or are they all necessary for some correctness/invariant 
> that must hold?
Clang changes cannot be committed before the LLVM changes, otherwise we would 
crash in backend.
Regarding splitting Clang changes into several comments it is possible with the 
following splits:
1. Static variable (lines 2508-2517)
2. Types (all the others)

Now types can be split into several comments as well: Records and Typedef
But the infrastructure of recording lexical-scope declarations and getting the 
lexical-scope context should be committed with the first patch (nevertheless 
what one it would be, Records or Typedef).

Regarding the test, I used to have 3 (even 4) separate tests, but I was asked 
to merged them.
Now, if we do commit patches in steps, I suggest that I still end up with one 
final test, but I will need to modify it with each patch (I will be building it 
step by step).

Now, what is your call? do you want me to commit the this patch in 3 steps? Or 
just go with it as one piece?


http://reviews.llvm.org/D15977



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D16135: Macro Debug Info support in Clang

2016-01-26 Thread Amjad Aboud via cfe-commits
aaboud updated this revision to Diff 46034.
aaboud marked 6 inline comments as done.
aaboud added a comment.

Added comments explaining the implementation.


http://reviews.llvm.org/D16135

Files:
  include/clang/AST/ASTConsumer.h
  lib/AST/ASTConsumer.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CGDebugInfo.h
  lib/CodeGen/CMakeLists.txt
  lib/CodeGen/CodeGenAction.cpp
  lib/CodeGen/CodeGenModule.cpp
  lib/CodeGen/CodeGenModule.h
  lib/CodeGen/MacroPPCallbacks.cpp
  lib/CodeGen/MacroPPCallbacks.h
  lib/CodeGen/ModuleBuilder.cpp
  lib/Parse/ParseAST.cpp

Index: lib/Parse/ParseAST.cpp
===
--- lib/Parse/ParseAST.cpp
+++ lib/Parse/ParseAST.cpp
@@ -128,6 +128,12 @@
   new Parser(S.getPreprocessor(), S, SkipFunctionBodies));
   Parser &P = *ParseOP.get();
 
+  std::unique_ptr Callbacks =
+  Consumer->CreatePreprocessorCallbacks(S.getPreprocessor());
+  if (Callbacks) {
+S.getPreprocessor().addPPCallbacks(std::move(Callbacks));
+  }
+
   llvm::CrashRecoveryContextCleanupRegistrar
   CleanupPrettyStack(llvm::SavePrettyStackState());
   PrettyStackTraceParserEntry CrashInfo(P);
Index: lib/CodeGen/ModuleBuilder.cpp
===
--- lib/CodeGen/ModuleBuilder.cpp
+++ lib/CodeGen/ModuleBuilder.cpp
@@ -20,6 +20,7 @@
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Frontend/CodeGenOptions.h"
+#include "clang/Lex/PPCallbacks.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/LLVMContext.h"
@@ -234,6 +235,11 @@
 void HandleDependentLibrary(llvm::StringRef Lib) override {
   Builder->AddDependentLib(Lib);
 }
+
+std::unique_ptr
+CreatePreprocessorCallbacks(Preprocessor &PP) override {
+  return Builder->createPreprocessorCallbacks(PP);
+}
   };
 }
 
Index: lib/CodeGen/CodeGenModule.cpp
===
--- lib/CodeGen/CodeGenModule.cpp
+++ lib/CodeGen/CodeGenModule.cpp
@@ -24,6 +24,7 @@
 #include "CodeGenPGO.h"
 #include "CodeGenTBAA.h"
 #include "CoverageMappingGen.h"
+#include "MacroPPCallbacks.h"
 #include "TargetInfo.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/CharUnits.h"
@@ -208,6 +209,16 @@
   CUDARuntime = CreateNVCUDARuntime(*this);
 }
 
+std::unique_ptr
+CodeGenModule::createPreprocessorCallbacks(Preprocessor &PP) {
+  // Enable generating macro debug info only in FullDebugInfo mode.
+  if (CodeGenOpts.getDebugInfo() < CodeGenOptions::FullDebugInfo ||
+  !getModuleDebugInfo())
+return nullptr;
+
+  return std::make_unique(*getModuleDebugInfo(), PP);
+}
+
 void CodeGenModule::addReplacement(StringRef Name, llvm::Constant *C) {
   Replacements[Name] = C;
 }
Index: lib/CodeGen/MacroPPCallbacks.h
===
--- lib/CodeGen/MacroPPCallbacks.h
+++ lib/CodeGen/MacroPPCallbacks.h
@@ -0,0 +1,82 @@
+//===--- MacroPPCallbacks.h -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+//
+//  This file defines implementation for the macro preprocessors callbacks.
+//
+//===--===//
+
+#include "clang/Lex/PPCallbacks.h"
+#include "clang/Parse/Parser.h"
+#include 
+
+namespace llvm {
+class DIMacroFile;
+}
+namespace clang {
+
+namespace CodeGen {
+class CGDebugInfo;
+}
+class MacroPPCallbacks : public PPCallbacks {
+  /// Debug info code generator
+  CodeGen::CGDebugInfo &DebugInfo;
+  /// Preprocessor
+  Preprocessor &PP;
+  /// Location (used for line number) for recent included file.
+  SourceLocation LastHashLoc;
+  /// Location (used for file name) for first included file (source main).
+  SourceLocation FirstIncludeFile;
+  /// Indicates that first file inclusion occurred.
+  bool FirstInclude;
+  /// Indicates that DIMacroFile entry was created for first included file.
+  bool FirstIncludeDone;
+  /// Counts current number of command line included files, which was entered
+  /// and was not exited yet.
+  int CommandIncludeFiles;
+  /// Number of fake files that should skip that were not exited yet.
+  int SkipFiles;
+  /// Parent contains all entered files that were not exited yet according to
+  /// the inclusion order.
+  std::vector Parents;
+
+  /// Use the passed preprocessor to calculate the macro name and value from
+  /// the given macro info and identifier info.
+  static void getMacroDefinition(const IdentifierInfo &II, const MacroInfo &MI,
+ Preprocessor &PP, raw_ostream &Name,
+ raw_ostream &Value);
+
+public:
+  MacroPPCallbacks(CodeGen::CGDebugInfo