r298392 - [index/AST] Determine if a typedef shares a name and spelling location with its underlying tag type

Argyrios Kyrtzidis via cfe-commits cfe-commits at lists.llvm.org
Tue Mar 21 14:46:47 PDT 2017


Fixed in r298441, thanks!

> On Mar 21, 2017, at 2:05 PM, Vitaly Buka <vitalybuka at google.com> wrote:
> 
> Could you please take a look at these leaks
> 
> http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/3606/steps/check-clang%20asan/logs/stdio <http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fast/builds/3606/steps/check-clang%20asan/logs/stdio>
> 
> 
> =================================================================
> ==32547==ERROR: LeakSanitizer: detected memory leaks
> 
> Direct leak of 24 byte(s) in 1 object(s) allocated from:
>     #0 0x57a9a8 in __interceptor_malloc /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:64
>     #1 0x7f0c8c1de918 in clang::cxstring::createDup(llvm::StringRef) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/tools/libclang/CXString.cpp:99:40
>     #2 0x7f0c8c1e1120 in clang_getTypeSpelling /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/tools/libclang/CXType.cpp:273:10
>     #3 0x5b5a53 in PrintCursor /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/tools/c-index-test/c-index-test.c:718:24
>     #4 0x5b4dc5 in FilteredPrintingVisitor /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/tools/c-index-test/c-index-test.c:1116:5
>     #5 0x7f0c8c115829 in clang::cxcursor::CursorVisitor::Visit(CXCursor, bool) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/tools/libclang/CIndex.cpp:209:11
>     #6 0x7f0c8c11d451 in clang::cxcursor::CursorVisitor::handleDeclForVisitation(clang::Decl const*) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/tools/libclang/CIndex.cpp:666:7
>     #7 0x7f0c8c11d9fb in clang::cxcursor::CursorVisitor::VisitDeclContext(clang::DeclContext*) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/tools/libclang/CIndex.cpp:627:30
>     #8 0x7f0c8c116ecf in clang::cxcursor::CursorVisitor::VisitChildren(CXCursor) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/tools/libclang/CIndex.cpp:532:20
>     #9 0x7f0c8c149ad6 in clang_visitChildren /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/tools/libclang/CIndex.cpp:4172:20
>     #10 0x5b8628 in perform_test_load /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/tools/c-index-test/c-index-test.c:1601:5
>     #11 0x5b8d4f in perform_test_load_source /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/tools/c-index-test/c-index-test.c:1697:12
>     #12 0x5c0e76 in cindextest_main /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/tools/c-index-test/c-index-test.c:4373:14
>     #13 0x5c5a1d in thread_runner /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/tools/c-index-test/c-index-test.c:4444:25
>     #14 0x7f0c90a47daf in ExecuteOnThread_Dispatch(void*) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/lib/Support/Unix/Threading.inc:53:3
>     #15 0x7f0c8919b6b9 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x76b9)
> 
> SUMMARY: AddressSanitizer: 24 byte(s) leaked in 1 allocation(s).
> 
> --
> 
> 
> On Tue, Mar 21, 2017 at 10:08 AM Argyrios Kyrtzidis via cfe-commits <cfe-commits at lists.llvm.org <mailto:cfe-commits at lists.llvm.org>> wrote:
> Author: akirtzidis
> Date: Tue Mar 21 11:56:02 2017
> New Revision: 298392
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=298392&view=rev <http://llvm.org/viewvc/llvm-project?rev=298392&view=rev>
> Log:
> [index/AST] Determine if a typedef shares a name and spelling location with its underlying tag type
> 
> In such a case, as when using the NS_ENUM macro, for indexing purposes treat the typedef as 'transparent',
> meaning we treat its references as symbols of the underlying tag symbol.
> Also provide a libclang API to check for such typedefs.
> 
> Modified:
>     cfe/trunk/include/clang-c/Index.h
>     cfe/trunk/include/clang/AST/Decl.h
>     cfe/trunk/lib/AST/Decl.cpp
>     cfe/trunk/lib/Index/IndexDecl.cpp
>     cfe/trunk/lib/Index/IndexTypeSourceInfo.cpp
>     cfe/trunk/test/Index/Core/index-source.m
>     cfe/trunk/test/Index/get-cursor.m
>     cfe/trunk/tools/c-index-test/c-index-test.c
>     cfe/trunk/tools/libclang/CXType.cpp
>     cfe/trunk/tools/libclang/libclang.exports
> 
> Modified: cfe/trunk/include/clang-c/Index.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=298392&r1=298391&r2=298392&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang-c/Index.h?rev=298392&r1=298391&r2=298392&view=diff>
> ==============================================================================
> --- cfe/trunk/include/clang-c/Index.h (original)
> +++ cfe/trunk/include/clang-c/Index.h Tue Mar 21 11:56:02 2017
> @@ -3437,6 +3437,16 @@ CINDEX_LINKAGE long long clang_getArrayS
>  CINDEX_LINKAGE CXType clang_Type_getNamedType(CXType T);
> 
>  /**
> + * \brief Determine if a typedef is 'transparent' tag.
> + *
> + * A typedef is considered 'transparent' if it shares a name and spelling
> + * location with its underlying tag type, as is the case with the NS_ENUM macro.
> + *
> + * \returns non-zero if transparent and zero otherwise.
> + */
> +CINDEX_LINKAGE unsigned clang_Type_isTransparentTagTypedef(CXType T);
> +
> +/**
>   * \brief List the possible error codes for \c clang_Type_getSizeOf,
>   *   \c clang_Type_getAlignOf, \c clang_Type_getOffsetOf and
>   *   \c clang_Cursor_getOffsetOf.
> 
> Modified: cfe/trunk/include/clang/AST/Decl.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=298392&r1=298391&r2=298392&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=298392&r1=298391&r2=298392&view=diff>
> ==============================================================================
> --- cfe/trunk/include/clang/AST/Decl.h (original)
> +++ cfe/trunk/include/clang/AST/Decl.h Tue Mar 21 11:56:02 2017
> @@ -2641,12 +2641,17 @@ class TypedefNameDecl : public TypeDecl,
>    typedef std::pair<TypeSourceInfo*, QualType> ModedTInfo;
>    llvm::PointerUnion<TypeSourceInfo*, ModedTInfo*> MaybeModedTInfo;
> 
> +  // FIXME: This can be packed into the bitfields in Decl.
> +  /// If 0, we have not computed IsTransparentTag.
> +  /// Otherwise, IsTransparentTag is (CacheIsTransparentTag >> 1).
> +  mutable unsigned CacheIsTransparentTag : 2;
> +
>  protected:
>    TypedefNameDecl(Kind DK, ASTContext &C, DeclContext *DC,
>                    SourceLocation StartLoc, SourceLocation IdLoc,
>                    IdentifierInfo *Id, TypeSourceInfo *TInfo)
>        : TypeDecl(DK, DC, IdLoc, Id, StartLoc), redeclarable_base(C),
> -        MaybeModedTInfo(TInfo) {}
> +        MaybeModedTInfo(TInfo), CacheIsTransparentTag(0) {}
> 
>    typedef Redeclarable<TypedefNameDecl> redeclarable_base;
>    TypedefNameDecl *getNextRedeclarationImpl() override {
> @@ -2699,11 +2704,22 @@ public:
>    /// this typedef declaration.
>    TagDecl *getAnonDeclWithTypedefName(bool AnyRedecl = false) const;
> 
> +  /// Determines if this typedef shares a name and spelling location with its
> +  /// underlying tag type, as is the case with the NS_ENUM macro.
> +  bool isTransparentTag() const {
> +    if (CacheIsTransparentTag)
> +      return CacheIsTransparentTag & 0x2;
> +    return isTransparentTagSlow();
> +  }
> +
>    // Implement isa/cast/dyncast/etc.
>    static bool classof(const Decl *D) { return classofKind(D->getKind()); }
>    static bool classofKind(Kind K) {
>      return K >= firstTypedefName && K <= lastTypedefName;
>    }
> +
> +private:
> +  bool isTransparentTagSlow() const;
>  };
> 
>  /// TypedefDecl - Represents the declaration of a typedef-name via the 'typedef'
> 
> Modified: cfe/trunk/lib/AST/Decl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=298392&r1=298391&r2=298392&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=298392&r1=298391&r2=298392&view=diff>
> ==============================================================================
> --- cfe/trunk/lib/AST/Decl.cpp (original)
> +++ cfe/trunk/lib/AST/Decl.cpp Tue Mar 21 11:56:02 2017
> @@ -4242,6 +4242,30 @@ TagDecl *TypedefNameDecl::getAnonDeclWit
>    return nullptr;
>  }
> 
> +bool TypedefNameDecl::isTransparentTagSlow() const {
> +  auto determineIsTransparent = [&]() {
> +    if (auto *TT = getUnderlyingType()->getAs<TagType>()) {
> +      if (auto *TD = TT->getDecl()) {
> +        if (TD->getName() != getName())
> +          return false;
> +        SourceLocation TTLoc = getLocation();
> +        SourceLocation TDLoc = TD->getLocation();
> +        if (!TTLoc.isMacroID() || !TDLoc.isMacroID())
> +          return false;
> +        SourceManager &SM = getASTContext().getSourceManager();
> +        return SM.getSpellingLoc(TTLoc) == SM.getSpellingLoc(TDLoc);
> +      }
> +    }
> +    return false;
> +  };
> +
> +  bool isTransparent = determineIsTransparent();
> +  CacheIsTransparentTag = 1;
> +  if (isTransparent)
> +    CacheIsTransparentTag |= 0x2;
> +  return isTransparent;
> +}
> +
>  TypedefDecl *TypedefDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
>    return new (C, ID) TypedefDecl(C, nullptr, SourceLocation(), SourceLocation(),
>                                   nullptr, nullptr);
> 
> Modified: cfe/trunk/lib/Index/IndexDecl.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/IndexDecl.cpp?rev=298392&r1=298391&r2=298392&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/IndexDecl.cpp?rev=298392&r1=298391&r2=298392&view=diff>
> ==============================================================================
> --- cfe/trunk/lib/Index/IndexDecl.cpp (original)
> +++ cfe/trunk/lib/Index/IndexDecl.cpp Tue Mar 21 11:56:02 2017
> @@ -231,8 +231,9 @@ public:
>    }
> 
>    bool VisitTypedefNameDecl(const TypedefNameDecl *D) {
> -    if (!IndexCtx.handleDecl(D))
> -      return false;
> +    if (!D->isTransparentTag())
> +      if (!IndexCtx.handleDecl(D))
> +        return false;
>      IndexCtx.indexTypeSourceInfo(D->getTypeSourceInfo(), D);
>      return true;
>    }
> 
> Modified: cfe/trunk/lib/Index/IndexTypeSourceInfo.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/IndexTypeSourceInfo.cpp?rev=298392&r1=298391&r2=298392&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/IndexTypeSourceInfo.cpp?rev=298392&r1=298391&r2=298392&view=diff>
> ==============================================================================
> --- cfe/trunk/lib/Index/IndexTypeSourceInfo.cpp (original)
> +++ cfe/trunk/lib/Index/IndexTypeSourceInfo.cpp Tue Mar 21 11:56:02 2017
> @@ -47,9 +47,15 @@ public:
>    } while (0)
> 
>    bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
> +    SourceLocation Loc = TL.getNameLoc();
> +    TypedefNameDecl *ND = TL.getTypedefNameDecl();
> +    if (ND->isTransparentTag()) {
> +      TagDecl *Underlying = ND->getUnderlyingType()->getAsTagDecl();
> +      return IndexCtx.handleReference(Underlying, Loc, Parent,
> +                                      ParentDC, SymbolRoleSet(), Relations);
> +    }
>      if (IsBase) {
> -      SourceLocation Loc = TL.getNameLoc();
> -      TRY_TO(IndexCtx.handleReference(TL.getTypedefNameDecl(), Loc,
> +      TRY_TO(IndexCtx.handleReference(ND, Loc,
>                                        Parent, ParentDC, SymbolRoleSet()));
>        if (auto *CD = TL.getType()->getAsCXXRecordDecl()) {
>          TRY_TO(IndexCtx.handleReference(CD, Loc, Parent, ParentDC,
> @@ -57,7 +63,7 @@ public:
>                                          Relations));
>        }
>      } else {
> -      TRY_TO(IndexCtx.handleReference(TL.getTypedefNameDecl(), TL.getNameLoc(),
> +      TRY_TO(IndexCtx.handleReference(ND, Loc,
>                                        Parent, ParentDC, SymbolRoleSet(),
>                                        Relations));
>      }
> 
> Modified: cfe/trunk/test/Index/Core/index-source.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/Core/index-source.m?rev=298392&r1=298391&r2=298392&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/Core/index-source.m?rev=298392&r1=298391&r2=298392&view=diff>
> ==============================================================================
> --- cfe/trunk/test/Index/Core/index-source.m (original)
> +++ cfe/trunk/test/Index/Core/index-source.m Tue Mar 21 11:56:02 2017
> @@ -348,3 +348,39 @@ typedef MyGenCls<Base *><MyEnumerating>
>  // CHECK: [[@LINE-1]]:3 | field/ObjC | _foo | c:objc(cs)I7 at _foo | <no-cgname> | Ref,Writ,RelCont | rel: 1
>  }
>  @end
> +
> +#define NS_ENUM(_name, _type) enum _name:_type _name; enum _name : _type
> +
> +typedef NS_ENUM(AnotherEnum, int) {
> +// CHECK-NOT: [[@LINE-1]]:17 | type-alias/C | AnotherEnum |
> +// CHECK: [[@LINE-2]]:17 | enum/C | AnotherEnum | [[AnotherEnum_USR:.*]] | {{.*}} | Ref,RelCont | rel: 1
> +  AnotherEnumFirst = 0,
> +  AnotherEnumSecond = 1,
> +  AnotherEnumThird = 2,
> +};
> +
> +AnotherEnum anotherT;
> +// CHECK: [[@LINE-1]]:1 | enum/C | AnotherEnum | [[AnotherEnum_USR]] | {{.*}} | Ref,RelCont | rel: 1
> +enum AnotherEnum anotherE;
> +// CHECK: [[@LINE-1]]:6 | enum/C | AnotherEnum | [[AnotherEnum_USR]] | {{.*}} | Ref,RelCont | rel: 1
> +
> +#define TRANSPARENT(_name) struct _name _name; struct _name
> +#define OPAQUE(_name) struct _name *_name; struct _name
> +
> +typedef TRANSPARENT(AStruct) {
> +  int x;
> +};
> +
> +AStruct aStructT;
> +// CHECK: [[@LINE-1]]:1 | struct/C | AStruct | {{.*}} | {{.*}} | Ref,RelCont | rel: 1
> +struct AStruct aStructS;
> +// CHECK: [[@LINE-1]]:8 | struct/C | AStruct | {{.*}} | {{.*}} | Ref,RelCont | rel: 1
> +
> +typedef OPAQUE(Separate) {
> +  int x;
> +};
> +
> +Separate separateT;
> +// CHECK: [[@LINE-1]]:1 | type-alias/C | Separate | {{.*}} | {{.*}} | Ref,RelCont | rel: 1
> +struct Separate separateE;
> +// CHECK: [[@LINE-1]]:8 | struct/C | Separate | {{.*}} | {{.*}} | Ref,RelCont | rel: 1
> 
> Modified: cfe/trunk/test/Index/get-cursor.m
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/get-cursor.m?rev=298392&r1=298391&r2=298392&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/get-cursor.m?rev=298392&r1=298391&r2=298392&view=diff>
> ==============================================================================
> --- cfe/trunk/test/Index/get-cursor.m (original)
> +++ cfe/trunk/test/Index/get-cursor.m Tue Mar 21 11:56:02 2017
> @@ -129,6 +129,31 @@ void foo3(Test3 *test3) {
>  }
>  @end
> 
> +#define NS_ENUM(_name, _type) enum _name : _type _name; enum _name : _type
> +typedef NS_ENUM(TestTransparent, int) {
> +  TestTransparentFirst = 0,
> +  TestTransparentSecond = 1,
> +};
> +typedef enum TestTransparent NotTransparent;
> +
> +TestTransparent transparentTypedef;
> +enum TestTransparent transparentUnderlying;
> +NotTransparent opaqueTypedef;
> +
> +#define MY_ENUM(_name, _type) enum _name : _type _name##_t; enum _name : _type
> +typedef MY_ENUM(TokenPaste, int) {
> +  TokenPasteFirst = 0,
> +};
> +TokenPaste_t opaqueTypedef2;
> +
> +#define MY_TYPE(_name) struct _name _name; struct _name
> +typedef MY_TYPE(SomeT) { int x; };
> +SomeT someVar;
> +
> +#define MY_TYPE2(_name) struct _name *_name; struct _name
> +typedef MY_TYPE2(SomeT2) { int x; };
> +SomeT2 someVar2;
> +
> 
>  // RUN: c-index-test -cursor-at=%s:4:28 -cursor-at=%s:5:28 %s | FileCheck -check-prefix=CHECK-PROP %s
>  // CHECK-PROP: ObjCPropertyDecl=foo1:4:26
> @@ -193,3 +218,11 @@ void foo3(Test3 *test3) {
>  // RUN: c-index-test -cursor-at=%s:127:8 %s | FileCheck -check-prefix=CHECK-RECEIVER-WITH-NULLABILITY %s
>  // RUN: c-index-test -cursor-at=%s:128:8 %s | FileCheck -check-prefix=CHECK-RECEIVER-WITH-NULLABILITY %s
>  // CHECK-RECEIVER-WITH-NULLABILITY: Receiver-type=ObjCId
> +
> +// RUN: c-index-test -cursor-at=%s:139:1 -cursor-at=%s:140:6 -cursor-at=%s:141:1 -cursor-at=%s:147:1 -cursor-at=%s:151:1 -cursor-at=%s:155:1 %s | FileCheck -check-prefix=CHECK-TRANSPARENT %s
> +// CHECK-TRANSPARENT: 139:1 TypeRef=TestTransparent:133:17 (Transparent: enum TestTransparent) Extent=[139:1 - 139:16] Spelling=TestTransparent ([139:1 - 139:16])
> +// CHECK-TRANSPARENT: 140:6 TypeRef=enum TestTransparent:133:17 Extent=[140:6 - 140:21] Spelling=enum TestTransparent ([140:6 - 140:21])
> +// CHECK-TRANSPARENT: 141:1 TypeRef=NotTransparent:137:30 Extent=[141:1 - 141:15] Spelling=NotTransparent ([141:1 - 141:15])
> +// CHECK-TRANSPARENT: 147:1 TypeRef=TokenPaste_t:144:9 Extent=[147:1 - 147:13] Spelling=TokenPaste_t ([147:1 - 147:13])
> +// CHECK-TRANSPARENT: 151:1 TypeRef=SomeT:150:17 (Transparent: struct SomeT) Extent=[151:1 - 151:6] Spelling=SomeT ([151:1 - 151:6])
> +// CHECK-TRANSPARENT: 155:1 TypeRef=SomeT2:154:18 Extent=[155:1 - 155:7] Spelling=SomeT2 ([155:1 - 155:7])
> 
> Modified: cfe/trunk/tools/c-index-test/c-index-test.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=298392&r1=298391&r2=298392&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=298392&r1=298391&r2=298392&view=diff>
> ==============================================================================
> --- cfe/trunk/tools/c-index-test/c-index-test.c (original)
> +++ cfe/trunk/tools/c-index-test/c-index-test.c Tue Mar 21 11:56:02 2017
> @@ -710,6 +710,15 @@ static void PrintCursor(CXCursor Cursor,
>          clang_getSpellingLocation(Loc, 0, &line, &column, 0);
>          printf(":%d:%d", line, column);
>        }
> +
> +      if (clang_getCursorKind(Referenced) == CXCursor_TypedefDecl) {
> +        CXType T = clang_getCursorType(Referenced);
> +        if (clang_Type_isTransparentTagTypedef(T)) {
> +          CXType Underlying = clang_getTypedefDeclUnderlyingType(Referenced);
> +          CXString S = clang_getTypeSpelling(Underlying);
> +          printf(" (Transparent: %s)", clang_getCString(S));
> +        }
> +      }
>      }
> 
>      if (clang_isCursorDefinition(Cursor))
> 
> Modified: cfe/trunk/tools/libclang/CXType.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXType.cpp?rev=298392&r1=298391&r2=298392&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CXType.cpp?rev=298392&r1=298391&r2=298392&view=diff>
> ==============================================================================
> --- cfe/trunk/tools/libclang/CXType.cpp (original)
> +++ cfe/trunk/tools/libclang/CXType.cpp Tue Mar 21 11:56:02 2017
> @@ -1039,3 +1039,12 @@ CXType clang_Type_getNamedType(CXType CT
> 
>    return MakeCXType(QualType(), GetTU(CT));
>  }
> +
> +unsigned clang_Type_isTransparentTagTypedef(CXType TT){
> +  QualType T = GetQualType(TT);
> +  if (auto *TT = dyn_cast_or_null<TypedefType>(T.getTypePtrOrNull())) {
> +    if (auto *D = TT->getDecl())
> +      return D->isTransparentTag();
> +  }
> +  return false;
> +}
> 
> Modified: cfe/trunk/tools/libclang/libclang.exports
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/libclang.exports?rev=298392&r1=298391&r2=298392&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/libclang.exports?rev=298392&r1=298391&r2=298392&view=diff>
> ==============================================================================
> --- cfe/trunk/tools/libclang/libclang.exports (original)
> +++ cfe/trunk/tools/libclang/libclang.exports Tue Mar 21 11:56:02 2017
> @@ -88,6 +88,7 @@ clang_Type_getTemplateArgumentAsType
>  clang_Type_getCXXRefQualifier
>  clang_Type_visitFields
>  clang_Type_getNamedType
> +clang_Type_isTransparentTagTypedef
>  clang_VerbatimBlockLineComment_getText
>  clang_VerbatimLineComment_getText
>  clang_HTMLTagComment_getAsString
> 
> 
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org <mailto:cfe-commits at lists.llvm.org>
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits <http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170321/5d450deb/attachment-0001.html>


More information about the cfe-commits mailing list