diff options
-rw-r--r-- | clang/include/clang/AST/Type.h | 14 | ||||
-rw-r--r-- | clang/lib/AST/ASTDumper.cpp | 44 | ||||
-rw-r--r-- | clang/lib/AST/TypePrinter.cpp | 10 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp | 658 | ||||
-rw-r--r-- | clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp | 112 | ||||
-rw-r--r-- | clang/test/Frontend/float16.cpp | 652 | ||||
-rw-r--r-- | clang/test/Misc/ast-dump-attr.cpp | 422 | ||||
-rw-r--r-- | clang/test/Misc/ast-dump-color.cpp | 2 | ||||
-rw-r--r-- | clang/test/Misc/ast-dump-decl.cpp | 1078 | ||||
-rw-r--r-- | clang/test/Misc/ast-dump-invalid.cpp | 128 | ||||
-rw-r--r-- | clang/test/OpenMP/dump.cpp | 136 | ||||
-rw-r--r-- | clang/test/Parser/objc-default-ctor-init.mm | 42 | ||||
-rw-r--r-- | clang/test/SemaCXX/compound-literal.cpp | 196 | ||||
-rw-r--r-- | clang/test/SemaCXX/sourceranges.cpp | 104 | ||||
-rw-r--r-- | clang/test/SemaCXX/warn-redundant-move.cpp | 232 | ||||
-rw-r--r-- | clang/test/SemaObjCXX/block-cleanup.mm | 32 | ||||
-rw-r--r-- | clang/test/SemaTemplate/default-expr-arguments-2.cpp | 4 | ||||
-rw-r--r-- | clang/test/SemaTemplate/default-expr-arguments-3.cpp | 110 |
18 files changed, 1980 insertions, 1996 deletions
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 882878bb7e1..7247838947a 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -976,14 +976,16 @@ public: return LHS.Value != RHS.Value; } - static std::string getAsString(SplitQualType split, - const PrintingPolicy &Policy) { - return getAsString(split.Ty, split.Quals, Policy); + std::string getAsString() const { + return getAsString(split()); } - static std::string getAsString(const Type *ty, Qualifiers qs, - const PrintingPolicy &Policy); - std::string getAsString() const; + static std::string getAsString(SplitQualType split) { + return getAsString(split.Ty, split.Quals); + } + + static std::string getAsString(const Type *ty, Qualifiers qs); + std::string getAsString(const PrintingPolicy &Policy) const; void print(raw_ostream &OS, const PrintingPolicy &Policy, diff --git a/clang/lib/AST/ASTDumper.cpp b/clang/lib/AST/ASTDumper.cpp index 8b285db38e8..73154ba1413 100644 --- a/clang/lib/AST/ASTDumper.cpp +++ b/clang/lib/AST/ASTDumper.cpp @@ -99,9 +99,6 @@ namespace { const CommandTraits *Traits; const SourceManager *SM; - /// The policy to use for printing; can be defaulted. - PrintingPolicy PrintPolicy; - /// Pending[i] is an action to dump an entity at level i. llvm::SmallVector<std::function<void(bool isLastChild)>, 32> Pending; @@ -210,17 +207,12 @@ namespace { public: ASTDumper(raw_ostream &OS, const CommandTraits *Traits, const SourceManager *SM) - : ASTDumper(OS, Traits, SM, - SM && SM->getDiagnostics().getShowColors()) {} + : OS(OS), Traits(Traits), SM(SM), + ShowColors(SM && SM->getDiagnostics().getShowColors()) { } ASTDumper(raw_ostream &OS, const CommandTraits *Traits, const SourceManager *SM, bool ShowColors) - : ASTDumper(OS, Traits, SM, ShowColors, LangOptions()) {} - ASTDumper(raw_ostream &OS, const CommandTraits *Traits, - const SourceManager *SM, bool ShowColors, - const PrintingPolicy &PrintPolicy) - : OS(OS), Traits(Traits), SM(SM), PrintPolicy(PrintPolicy), - ShowColors(ShowColors) {} + : OS(OS), Traits(Traits), SM(SM), ShowColors(ShowColors) {} void setDeserialize(bool D) { Deserialize = D; } @@ -654,13 +646,13 @@ void ASTDumper::dumpBareType(QualType T, bool Desugar) { ColorScope Color(*this, TypeColor); SplitQualType T_split = T.split(); - OS << "'" << QualType::getAsString(T_split, PrintPolicy) << "'"; + OS << "'" << QualType::getAsString(T_split) << "'"; if (Desugar && !T.isNull()) { // If the type is sugared, also dump a (shallow) desugared type. SplitQualType D_split = T.getSplitDesugaredType(); if (T_split != D_split) - OS << ":'" << QualType::getAsString(D_split, PrintPolicy) << "'"; + OS << ":'" << QualType::getAsString(D_split) << "'"; } } @@ -1195,12 +1187,12 @@ void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) { if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) { if (MD->size_overridden_methods() != 0) { - auto dumpOverride = [=](const CXXMethodDecl *D) { - SplitQualType T_split = D->getType().split(); - OS << D << " " << D->getParent()->getName() - << "::" << D->getNameAsString() << " '" - << QualType::getAsString(T_split, PrintPolicy) << "'"; - }; + auto dumpOverride = + [=](const CXXMethodDecl *D) { + SplitQualType T_split = D->getType().split(); + OS << D << " " << D->getParent()->getName() << "::" + << D->getNameAsString() << " '" << QualType::getAsString(T_split) << "'"; + }; dumpChild([=] { auto Overrides = MD->overridden_methods(); @@ -2690,18 +2682,15 @@ LLVM_DUMP_METHOD void Type::dump(llvm::raw_ostream &OS) const { LLVM_DUMP_METHOD void Decl::dump() const { dump(llvm::errs()); } LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS, bool Deserialize) const { - const ASTContext &Ctx = getASTContext(); - ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &Ctx.getSourceManager(), - false, Ctx.getPrintingPolicy()); + ASTDumper P(OS, &getASTContext().getCommentCommandTraits(), + &getASTContext().getSourceManager()); P.setDeserialize(Deserialize); P.dumpDecl(this); } LLVM_DUMP_METHOD void Decl::dumpColor() const { - const ASTContext &Ctx = getASTContext(); - ASTDumper P(llvm::errs(), &Ctx.getCommentCommandTraits(), - &Ctx.getSourceManager(), /*ShowColors*/ true, - Ctx.getPrintingPolicy()); + ASTDumper P(llvm::errs(), &getASTContext().getCommentCommandTraits(), + &getASTContext().getSourceManager(), /*ShowColors*/true); P.dumpDecl(this); } @@ -2716,8 +2705,7 @@ LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS, while (!DC->isTranslationUnit()) DC = DC->getParent(); ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext(); - ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &Ctx.getSourceManager(), - false, Ctx.getPrintingPolicy()); + ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &Ctx.getSourceManager()); P.setDeserialize(Deserialize); P.dumpLookups(this, DumpDecls); } diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp index c28ada7dcb8..b13febc6523 100644 --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -1712,20 +1712,16 @@ void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy, OS << ' '; } -std::string QualType::getAsString() const { - return getAsString(split(), LangOptions()); -} - std::string QualType::getAsString(const PrintingPolicy &Policy) const { std::string S; getAsStringInternal(S, Policy); return S; } -std::string QualType::getAsString(const Type *ty, Qualifiers qs, - const PrintingPolicy &Policy) { +std::string QualType::getAsString(const Type *ty, Qualifiers qs) { std::string buffer; - getAsStringInternal(ty, qs, buffer, Policy); + LangOptions options; + getAsStringInternal(ty, qs, buffer, PrintingPolicy(options)); return buffer; } diff --git a/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp index b17cd8d3735..a51dda6fe85 100644 --- a/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp @@ -1,330 +1,328 @@ -//=======- PaddingChecker.cpp ------------------------------------*- 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 a checker that checks for padding that could be
-// removed by re-ordering members.
-//
-//===----------------------------------------------------------------------===//
-
-#include "ClangSACheckers.h"
-#include "clang/AST/CharUnits.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/RecordLayout.h"
-#include "clang/AST/RecursiveASTVisitor.h"
-#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
-#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
-#include "clang/StaticAnalyzer/Core/Checker.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/raw_ostream.h"
-#include <numeric>
-
-using namespace clang;
-using namespace ento;
-
-namespace {
-class PaddingChecker : public Checker<check::ASTDecl<TranslationUnitDecl>> {
-private:
- mutable std::unique_ptr<BugType> PaddingBug;
- mutable int64_t AllowedPad;
- mutable BugReporter *BR;
-
-public:
- void checkASTDecl(const TranslationUnitDecl *TUD, AnalysisManager &MGR,
- BugReporter &BRArg) const {
- BR = &BRArg;
- AllowedPad =
- MGR.getAnalyzerOptions().getOptionAsInteger("AllowedPad", 24, this);
- assert(AllowedPad >= 0 && "AllowedPad option should be non-negative");
-
- // The calls to checkAST* from AnalysisConsumer don't
- // visit template instantiations or lambda classes. We
- // want to visit those, so we make our own RecursiveASTVisitor.
- struct LocalVisitor : public RecursiveASTVisitor<LocalVisitor> {
- const PaddingChecker *Checker;
- bool shouldVisitTemplateInstantiations() const { return true; }
- bool shouldVisitImplicitCode() const { return true; }
- explicit LocalVisitor(const PaddingChecker *Checker) : Checker(Checker) {}
- bool VisitRecordDecl(const RecordDecl *RD) {
- Checker->visitRecord(RD);
- return true;
- }
- bool VisitVarDecl(const VarDecl *VD) {
- Checker->visitVariable(VD);
- return true;
- }
- // TODO: Visit array new and mallocs for arrays.
- };
-
- LocalVisitor visitor(this);
- visitor.TraverseDecl(const_cast<TranslationUnitDecl *>(TUD));
- }
-
- /// \brief Look for records of overly padded types. If padding *
- /// PadMultiplier exceeds AllowedPad, then generate a report.
- /// PadMultiplier is used to share code with the array padding
- /// checker.
- void visitRecord(const RecordDecl *RD, uint64_t PadMultiplier = 1) const {
- if (shouldSkipDecl(RD))
- return;
-
- auto &ASTContext = RD->getASTContext();
- const ASTRecordLayout &RL = ASTContext.getASTRecordLayout(RD);
- assert(llvm::isPowerOf2_64(RL.getAlignment().getQuantity()));
-
- CharUnits BaselinePad = calculateBaselinePad(RD, ASTContext, RL);
- if (BaselinePad.isZero())
- return;
-
- CharUnits OptimalPad;
- SmallVector<const FieldDecl *, 20> OptimalFieldsOrder;
- std::tie(OptimalPad, OptimalFieldsOrder) =
- calculateOptimalPad(RD, ASTContext, RL);
-
- CharUnits DiffPad = PadMultiplier * (BaselinePad - OptimalPad);
- if (DiffPad.getQuantity() <= AllowedPad) {
- assert(!DiffPad.isNegative() && "DiffPad should not be negative");
- // There is not enough excess padding to trigger a warning.
- return;
- }
- reportRecord(RD, BaselinePad, OptimalPad, OptimalFieldsOrder);
- }
-
- /// \brief Look for arrays of overly padded types. If the padding of the
- /// array type exceeds AllowedPad, then generate a report.
- void visitVariable(const VarDecl *VD) const {
- const ArrayType *ArrTy = VD->getType()->getAsArrayTypeUnsafe();
- if (ArrTy == nullptr)
- return;
- uint64_t Elts = 0;
- if (const ConstantArrayType *CArrTy = dyn_cast<ConstantArrayType>(ArrTy))
- Elts = CArrTy->getSize().getZExtValue();
- if (Elts == 0)
- return;
- const RecordType *RT = ArrTy->getElementType()->getAs<RecordType>();
- if (RT == nullptr)
- return;
-
- // TODO: Recurse into the fields and base classes to see if any
- // of those have excess padding.
- visitRecord(RT->getDecl(), Elts);
- }
-
- bool shouldSkipDecl(const RecordDecl *RD) const {
- auto Location = RD->getLocation();
- // If the construct doesn't have a source file, then it's not something
- // we want to diagnose.
- if (!Location.isValid())
- return true;
- SrcMgr::CharacteristicKind Kind =
- BR->getSourceManager().getFileCharacteristic(Location);
- // Throw out all records that come from system headers.
- if (Kind != SrcMgr::C_User)
- return true;
-
- // Not going to attempt to optimize unions.
- if (RD->isUnion())
- return true;
- // How do you reorder fields if you haven't got any?
- if (RD->field_empty())
- return true;
- if (auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
- // Tail padding with base classes ends up being very complicated.
- // We will skip objects with base classes for now.
- if (CXXRD->getNumBases() != 0)
- return true;
- // Virtual bases are complicated, skipping those for now.
- if (CXXRD->getNumVBases() != 0)
- return true;
- // Can't layout a template, so skip it. We do still layout the
- // instantiations though.
- if (CXXRD->getTypeForDecl()->isDependentType())
- return true;
- if (CXXRD->getTypeForDecl()->isInstantiationDependentType())
- return true;
- }
- auto IsTrickyField = [](const FieldDecl *FD) -> bool {
- // Bitfield layout is hard.
- if (FD->isBitField())
- return true;
-
- // Variable length arrays are tricky too.
- QualType Ty = FD->getType();
- if (Ty->isIncompleteArrayType())
- return true;
- return false;
- };
-
- if (std::any_of(RD->field_begin(), RD->field_end(), IsTrickyField))
- return true;
- return false;
- }
-
- static CharUnits calculateBaselinePad(const RecordDecl *RD,
- const ASTContext &ASTContext,
- const ASTRecordLayout &RL) {
- CharUnits PaddingSum;
- CharUnits Offset = ASTContext.toCharUnitsFromBits(RL.getFieldOffset(0));
- for (const FieldDecl *FD : RD->fields()) {
- // This checker only cares about the padded size of the
- // field, and not the data size. If the field is a record
- // with tail padding, then we won't put that number in our
- // total because reordering fields won't fix that problem.
- CharUnits FieldSize = ASTContext.getTypeSizeInChars(FD->getType());
- auto FieldOffsetBits = RL.getFieldOffset(FD->getFieldIndex());
- CharUnits FieldOffset = ASTContext.toCharUnitsFromBits(FieldOffsetBits);
- PaddingSum += (FieldOffset - Offset);
- Offset = FieldOffset + FieldSize;
- }
- PaddingSum += RL.getSize() - Offset;
- return PaddingSum;
- }
-
- /// Optimal padding overview:
- /// 1. Find a close approximation to where we can place our first field.
- /// This will usually be at offset 0.
- /// 2. Try to find the best field that can legally be placed at the current
- /// offset.
- /// a. "Best" is the largest alignment that is legal, but smallest size.
- /// This is to account for overly aligned types.
- /// 3. If no fields can fit, pad by rounding the current offset up to the
- /// smallest alignment requirement of our fields. Measure and track the
- // amount of padding added. Go back to 2.
- /// 4. Increment the current offset by the size of the chosen field.
- /// 5. Remove the chosen field from the set of future possibilities.
- /// 6. Go back to 2 if there are still unplaced fields.
- /// 7. Add tail padding by rounding the current offset up to the structure
- /// alignment. Track the amount of padding added.
-
- static std::pair<CharUnits, SmallVector<const FieldDecl *, 20>>
- calculateOptimalPad(const RecordDecl *RD, const ASTContext &ASTContext,
- const ASTRecordLayout &RL) {
- struct FieldInfo {
- CharUnits Align;
- CharUnits Size;
- const FieldDecl *Field;
- bool operator<(const FieldInfo &RHS) const {
- // Order from small alignments to large alignments,
- // then large sizes to small sizes.
- // then large field indices to small field indices
- return std::make_tuple(Align, -Size,
- Field ? -static_cast<int>(Field->getFieldIndex())
- : 0) <
- std::make_tuple(
- RHS.Align, -RHS.Size,
- RHS.Field ? -static_cast<int>(RHS.Field->getFieldIndex())
- : 0);
- }
- };
- SmallVector<FieldInfo, 20> Fields;
- auto GatherSizesAndAlignments = [](const FieldDecl *FD) {
- FieldInfo RetVal;
- RetVal.Field = FD;
- auto &Ctx = FD->getASTContext();
- std::tie(RetVal.Size, RetVal.Align) =
- Ctx.getTypeInfoInChars(FD->getType());
- assert(llvm::isPowerOf2_64(RetVal.Align.getQuantity()));
- if (auto Max = FD->getMaxAlignment())
- RetVal.Align = std::max(Ctx.toCharUnitsFromBits(Max), RetVal.Align);
- return RetVal;
- };
- std::transform(RD->field_begin(), RD->field_end(),
- std::back_inserter(Fields), GatherSizesAndAlignments);
- std::sort(Fields.begin(), Fields.end());
- // This lets us skip over vptrs and non-virtual bases,
- // so that we can just worry about the fields in our object.
- // Note that this does cause us to miss some cases where we
- // could pack more bytes in to a base class's tail padding.
- CharUnits NewOffset = ASTContext.toCharUnitsFromBits(RL.getFieldOffset(0));
- CharUnits NewPad;
- SmallVector<const FieldDecl *, 20> OptimalFieldsOrder;
- while (!Fields.empty()) {
- unsigned TrailingZeros =
- llvm::countTrailingZeros((unsigned long long)NewOffset.getQuantity());
- // If NewOffset is zero, then countTrailingZeros will be 64. Shifting
- // 64 will overflow our unsigned long long. Shifting 63 will turn
- // our long long (and CharUnits internal type) negative. So shift 62.
- long long CurAlignmentBits = 1ull << (std::min)(TrailingZeros, 62u);
- CharUnits CurAlignment = CharUnits::fromQuantity(CurAlignmentBits);
- FieldInfo InsertPoint = {CurAlignment, CharUnits::Zero(), nullptr};
- auto CurBegin = Fields.begin();
- auto CurEnd = Fields.end();
-
- // In the typical case, this will find the last element
- // of the vector. We won't find a middle element unless
- // we started on a poorly aligned address or have an overly
- // aligned field.
- auto Iter = std::upper_bound(CurBegin, CurEnd, InsertPoint);
- if (Iter != CurBegin) {
- // We found a field that we can layout with the current alignment.
- --Iter;
- NewOffset += Iter->Size;
- OptimalFieldsOrder.push_back(Iter->Field);
- Fields.erase(Iter);
- } else {
- // We are poorly aligned, and we need to pad in order to layout another
- // field. Round up to at least the smallest field alignment that we
- // currently have.
- CharUnits NextOffset = NewOffset.alignTo(Fields[0].Align);
- NewPad += NextOffset - NewOffset;
- NewOffset = NextOffset;
- }
- }
- // Calculate tail padding.
- CharUnits NewSize = NewOffset.alignTo(RL.getAlignment());
- NewPad += NewSize - NewOffset;
- return {NewPad, std::move(OptimalFieldsOrder)};
- }
-
- void reportRecord(
- const RecordDecl *RD, CharUnits BaselinePad, CharUnits OptimalPad,
- const SmallVector<const FieldDecl *, 20> &OptimalFieldsOrder) const {
- if (!PaddingBug)
- PaddingBug =
- llvm::make_unique<BugType>(this, "Excessive Padding", "Performance");
-
- SmallString<100> Buf;
- llvm::raw_svector_ostream Os(Buf);
- Os << "Excessive padding in '";
- Os << QualType::getAsString(RD->getTypeForDecl(), Qualifiers(),
- LangOptions())
- << "'";
-
- if (auto *TSD = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
- // TODO: make this show up better in the console output and in
- // the HTML. Maybe just make it show up in HTML like the path
- // diagnostics show.
- SourceLocation ILoc = TSD->getPointOfInstantiation();
- if (ILoc.isValid())
- Os << " instantiated here: "
- << ILoc.printToString(BR->getSourceManager());
- }
-
- Os << " (" << BaselinePad.getQuantity() << " padding bytes, where "
- << OptimalPad.getQuantity() << " is optimal). \n"
- << "Optimal fields order: \n";
- for (const auto *FD : OptimalFieldsOrder)
- Os << FD->getName() << ", \n";
- Os << "consider reordering the fields or adding explicit padding "
- "members.";
-
- PathDiagnosticLocation CELoc =
- PathDiagnosticLocation::create(RD, BR->getSourceManager());
- auto Report = llvm::make_unique<BugReport>(*PaddingBug, Os.str(), CELoc);
- Report->setDeclWithIssue(RD);
- Report->addRange(RD->getSourceRange());
- BR->emitReport(std::move(Report));
- }
-};
-}
-
-void ento::registerPaddingChecker(CheckerManager &Mgr) {
- Mgr.registerChecker<PaddingChecker>();
-}
+//=======- PaddingChecker.cpp ------------------------------------*- 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 a checker that checks for padding that could be +// removed by re-ordering members. +// +//===----------------------------------------------------------------------===// + +#include "ClangSACheckers.h" +#include "clang/AST/CharUnits.h" +#include "clang/AST/DeclTemplate.h" +#include "clang/AST/RecordLayout.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" +#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" +#include "clang/StaticAnalyzer/Core/Checker.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Support/MathExtras.h" +#include "llvm/Support/raw_ostream.h" +#include <numeric> + +using namespace clang; +using namespace ento; + +namespace { +class PaddingChecker : public Checker<check::ASTDecl<TranslationUnitDecl>> { +private: + mutable std::unique_ptr<BugType> PaddingBug; + mutable int64_t AllowedPad; + mutable BugReporter *BR; + +public: + void checkASTDecl(const TranslationUnitDecl *TUD, AnalysisManager &MGR, + BugReporter &BRArg) const { + BR = &BRArg; + AllowedPad = + MGR.getAnalyzerOptions().getOptionAsInteger("AllowedPad", 24, this); + assert(AllowedPad >= 0 && "AllowedPad option should be non-negative"); + + // The calls to checkAST* from AnalysisConsumer don't + // visit template instantiations or lambda classes. We + // want to visit those, so we make our own RecursiveASTVisitor. + struct LocalVisitor : public RecursiveASTVisitor<LocalVisitor> { + const PaddingChecker *Checker; + bool shouldVisitTemplateInstantiations() const { return true; } + bool shouldVisitImplicitCode() const { return true; } + explicit LocalVisitor(const PaddingChecker *Checker) : Checker(Checker) {} + bool VisitRecordDecl(const RecordDecl *RD) { + Checker->visitRecord(RD); + return true; + } + bool VisitVarDecl(const VarDecl *VD) { + Checker->visitVariable(VD); + return true; + } + // TODO: Visit array new and mallocs for arrays. + }; + + LocalVisitor visitor(this); + visitor.TraverseDecl(const_cast<TranslationUnitDecl *>(TUD)); + } + + /// \brief Look for records of overly padded types. If padding * + /// PadMultiplier exceeds AllowedPad, then generate a report. + /// PadMultiplier is used to share code with the array padding + /// checker. + void visitRecord(const RecordDecl *RD, uint64_t PadMultiplier = 1) const { + if (shouldSkipDecl(RD)) + return; + + auto &ASTContext = RD->getASTContext(); + const ASTRecordLayout &RL = ASTContext.getASTRecordLayout(RD); + assert(llvm::isPowerOf2_64(RL.getAlignment().getQuantity())); + + CharUnits BaselinePad = calculateBaselinePad(RD, ASTContext, RL); + if (BaselinePad.isZero()) + return; + + CharUnits OptimalPad; + SmallVector<const FieldDecl *, 20> OptimalFieldsOrder; + std::tie(OptimalPad, OptimalFieldsOrder) = + calculateOptimalPad(RD, ASTContext, RL); + + CharUnits DiffPad = PadMultiplier * (BaselinePad - OptimalPad); + if (DiffPad.getQuantity() <= AllowedPad) { + assert(!DiffPad.isNegative() && "DiffPad should not be negative"); + // There is not enough excess padding to trigger a warning. + return; + } + reportRecord(RD, BaselinePad, OptimalPad, OptimalFieldsOrder); + } + + /// \brief Look for arrays of overly padded types. If the padding of the + /// array type exceeds AllowedPad, then generate a report. + void visitVariable(const VarDecl *VD) const { + const ArrayType *ArrTy = VD->getType()->getAsArrayTypeUnsafe(); + if (ArrTy == nullptr) + return; + uint64_t Elts = 0; + if (const ConstantArrayType *CArrTy = dyn_cast<ConstantArrayType>(ArrTy)) + Elts = CArrTy->getSize().getZExtValue(); + if (Elts == 0) + return; + const RecordType *RT = ArrTy->getElementType()->getAs<RecordType>(); + if (RT == nullptr) + return; + + // TODO: Recurse into the fields and base classes to see if any + // of those have excess padding. + visitRecord(RT->getDecl(), Elts); + } + + bool shouldSkipDecl(const RecordDecl *RD) const { + auto Location = RD->getLocation(); + // If the construct doesn't have a source file, then it's not something + // we want to diagnose. + if (!Location.isValid()) + return true; + SrcMgr::CharacteristicKind Kind = + BR->getSourceManager().getFileCharacteristic(Location); + // Throw out all records that come from system headers. + if (Kind != SrcMgr::C_User) + return true; + + // Not going to attempt to optimize unions. + if (RD->isUnion()) + return true; + // How do you reorder fields if you haven't got any? + if (RD->field_empty()) + return true; + if (auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) { + // Tail padding with base classes ends up being very complicated. + // We will skip objects with base classes for now. + if (CXXRD->getNumBases() != 0) + return true; + // Virtual bases are complicated, skipping those for now. + if (CXXRD->getNumVBases() != 0) + return true; + // Can't layout a template, so skip it. We do still layout the + // instantiations though. + if (CXXRD->getTypeForDecl()->isDependentType()) + return true; + if (CXXRD->getTypeForDecl()->isInstantiationDependentType()) + return true; + } + auto IsTrickyField = [](const FieldDecl *FD) -> bool { + // Bitfield layout is hard. + if (FD->isBitField()) + return true; + + // Variable length arrays are tricky too. + QualType Ty = FD->getType(); + if (Ty->isIncompleteArrayType()) + return true; + return false; + }; + + if (std::any_of(RD->field_begin(), RD->field_end(), IsTrickyField)) + return true; + return false; + } + + static CharUnits calculateBaselinePad(const RecordDecl *RD, + const ASTContext &ASTContext, + const ASTRecordLayout &RL) { + CharUnits PaddingSum; + CharUnits Offset = ASTContext.toCharUnitsFromBits(RL.getFieldOffset(0)); + for (const FieldDecl *FD : RD->fields()) { + // This checker only cares about the padded size of the + // field, and not the data size. If the field is a record + // with tail padding, then we won't put that number in our + // total because reordering fields won't fix that problem. + CharUnits FieldSize = ASTContext.getTypeSizeInChars(FD->getType()); + auto FieldOffsetBits = RL.getFieldOffset(FD->getFieldIndex()); + CharUnits FieldOffset = ASTContext.toCharUnitsFromBits(FieldOffsetBits); + PaddingSum += (FieldOffset - Offset); + Offset = FieldOffset + FieldSize; + } + PaddingSum += RL.getSize() - Offset; + return PaddingSum; + } + + /// Optimal padding overview: + /// 1. Find a close approximation to where we can place our first field. + /// This will usually be at offset 0. + /// 2. Try to find the best field that can legally be placed at the current + /// offset. + /// a. "Best" is the largest alignment that is legal, but smallest size. + /// This is to account for overly aligned types. + /// 3. If no fields can fit, pad by rounding the current offset up to the + /// smallest alignment requirement of our fields. Measure and track the + // amount of padding added. Go back to 2. + /// 4. Increment the current offset by the size of the chosen field. + /// 5. Remove the chosen field from the set of future possibilities. + /// 6. Go back to 2 if there are still unplaced fields. + /// 7. Add tail padding by rounding the current offset up to the structure + /// alignment. Track the amount of padding added. + + static std::pair<CharUnits, SmallVector<const FieldDecl *, 20>> + calculateOptimalPad(const RecordDecl *RD, const ASTContext &ASTContext, + const ASTRecordLayout &RL) { + struct FieldInfo { + CharUnits Align; + CharUnits Size; + const FieldDecl *Field; + bool operator<(const FieldInfo &RHS) const { + // Order from small alignments to large alignments, + // then large sizes to small sizes. + // then large field indices to small field indices + return std::make_tuple(Align, -Size, + Field ? -static_cast<int>(Field->getFieldIndex()) + : 0) < + std::make_tuple( + RHS.Align, -RHS.Size, + RHS.Field ? -static_cast<int>(RHS.Field->getFieldIndex()) + : 0); + } + }; + SmallVector<FieldInfo, 20> Fields; + auto GatherSizesAndAlignments = [](const FieldDecl *FD) { + FieldInfo RetVal; + RetVal.Field = FD; + auto &Ctx = FD->getASTContext(); + std::tie(RetVal.Size, RetVal.Align) = + Ctx.getTypeInfoInChars(FD->getType()); + assert(llvm::isPowerOf2_64(RetVal.Align.getQuantity())); + if (auto Max = FD->getMaxAlignment()) + RetVal.Align = std::max(Ctx.toCharUnitsFromBits(Max), RetVal.Align); + return RetVal; + }; + std::transform(RD->field_begin(), RD->field_end(), + std::back_inserter(Fields), GatherSizesAndAlignments); + std::sort(Fields.begin(), Fields.end()); + // This lets us skip over vptrs and non-virtual bases, + // so that we can just worry about the fields in our object. + // Note that this does cause us to miss some cases where we + // could pack more bytes in to a base class's tail padding. + CharUnits NewOffset = ASTContext.toCharUnitsFromBits(RL.getFieldOffset(0)); + CharUnits NewPad; + SmallVector<const FieldDecl *, 20> OptimalFieldsOrder; + while (!Fields.empty()) { + unsigned TrailingZeros = + llvm::countTrailingZeros((unsigned long long)NewOffset.getQuantity()); + // If NewOffset is zero, then countTrailingZeros will be 64. Shifting + // 64 will overflow our unsigned long long. Shifting 63 will turn + // our long long (and CharUnits internal type) negative. So shift 62. + long long CurAlignmentBits = 1ull << (std::min)(TrailingZeros, 62u); + CharUnits CurAlignment = CharUnits::fromQuantity(CurAlignmentBits); + FieldInfo InsertPoint = {CurAlignment, CharUnits::Zero(), nullptr}; + auto CurBegin = Fields.begin(); + auto CurEnd = Fields.end(); + + // In the typical case, this will find the last element + // of the vector. We won't find a middle element unless + // we started on a poorly aligned address or have an overly + // aligned field. + auto Iter = std::upper_bound(CurBegin, CurEnd, InsertPoint); + if (Iter != CurBegin) { + // We found a field that we can layout with the current alignment. + --Iter; + NewOffset += Iter->Size; + OptimalFieldsOrder.push_back(Iter->Field); + Fields.erase(Iter); + } else { + // We are poorly aligned, and we need to pad in order to layout another + // field. Round up to at least the smallest field alignment that we + // currently have. + CharUnits NextOffset = NewOffset.alignTo(Fields[0].Align); + NewPad += NextOffset - NewOffset; + NewOffset = NextOffset; + } + } + // Calculate tail padding. + CharUnits NewSize = NewOffset.alignTo(RL.getAlignment()); + NewPad += NewSize - NewOffset; + return {NewPad, std::move(OptimalFieldsOrder)}; + } + + void reportRecord( + const RecordDecl *RD, CharUnits BaselinePad, CharUnits OptimalPad, + const SmallVector<const FieldDecl *, 20> &OptimalFieldsOrder) const { + if (!PaddingBug) + PaddingBug = + llvm::make_unique<BugType>(this, "Excessive Padding", "Performance"); + + SmallString<100> Buf; + llvm::raw_svector_ostream Os(Buf); + Os << "Excessive padding in '"; + Os << QualType::getAsString(RD->getTypeForDecl(), Qualifiers()) << "'"; + + if (auto *TSD = dyn_cast<ClassTemplateSpecializationDecl>(RD)) { + // TODO: make this show up better in the console output and in + // the HTML. Maybe just make it show up in HTML like the path + // diagnostics show. + SourceLocation ILoc = TSD->getPointOfInstantiation(); + if (ILoc.isValid()) + Os << " instantiated here: " + << ILoc.printToString(BR->getSourceManager()); + } + + Os << " (" << BaselinePad.getQuantity() << " padding bytes, where " + << OptimalPad.getQuantity() << " is optimal). \n" + << "Optimal fields order: \n"; + for (const auto *FD : OptimalFieldsOrder) + Os << FD->getName() << ", \n"; + Os << "consider reordering the fields or adding explicit padding " + "members."; + + PathDiagnosticLocation CELoc = + PathDiagnosticLocation::create(RD, BR->getSourceManager()); + auto Report = llvm::make_unique<BugReport>(*PaddingBug, Os.str(), CELoc); + Report->setDeclWithIssue(RD); + Report->addRange(RD->getSourceRange()); + BR->emitReport(std::move(Report)); + } +}; +} + +void ento::registerPaddingChecker(CheckerManager &Mgr) { + Mgr.registerChecker<PaddingChecker>(); +} diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp index 46593b7e2ad..052349c8e2e 100644 --- a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp +++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp @@ -1,56 +1,56 @@ -// RUN: %clang_cc1 -ast-dump %s 2>&1 | FileCheck %s
-
-// CHECK-LABEL: example0
-void example0() {
- double d = 2.0;
- // CHECK: VarDecl{{.*}}rd 'double &'
- // CHECK-NEXT: DeclRefExpr
- double &rd = d;
- // CHECK: VarDecl{{.*}}rcd 'const double &'
- // CHECK-NEXT: ImplicitCastExpr{{.*}}'const double' lvalue <NoOp>
- const double &rcd = d;
-}
-
-struct A { };
-struct B : A { } b;
-
-// CHECK-LABEL: example1
-void example1() {
- // CHECK: VarDecl{{.*}}ra 'A &'
- // CHECK: ImplicitCastExpr{{.*}}'A' lvalue <DerivedToBase (A)>
- A &ra = b;
- // CHECK: VarDecl{{.*}}rca 'const A &'
- // CHECK: ImplicitCastExpr{{.*}}'const A' lvalue <DerivedToBase (A)>
- // CHECK-NOT: MaterializeTemporaryExpr
- // CHECK: ImplicitCastExpr{{.*}}'const B' lvalue <NoOp>
- const A& rca = b;
-}
-
-extern B f();
-
-struct X {
- operator B();
-} x;
-
-// CHECK-LABEL: example2
-void example2() {
- // CHECK: VarDecl{{.*}}rca 'const A &'
- // CHECK: ImplicitCastExpr{{.*}}'const A' lvalue <DerivedToBase (A)>
- // CHECK: MaterializeTemporaryExpr{{.*}}'const B'
- // CHECK: ImplicitCastExpr{{.*}}'const B' <NoOp>
- // CHECK: CallExpr{{.*}}B
- const A &rca = f();
- // CHECK: VarDecl{{.*}}r 'const A &'
- // CHECK: ImplicitCastExpr{{.*}}'const A' lvalue <DerivedToBase (A)>
- // CHECK: MaterializeTemporaryExpr{{.*}}'const B'
- // CHECK: ImplicitCastExpr{{.*}}'const B' <NoOp>
- // CHECK: CXXMemberCallExpr{{.*}}'B'
- const A& r = x;
-}
-
-// CHECK-LABEL: example3
-void example3() {
- // CHECK: VarDecl{{.*}}rcd2 'const double &'
- // CHECK: ImplicitCastExpr{{.*}} <IntegralToFloating>
- const double& rcd2 = 2;
-}
+// RUN: %clang_cc1 -ast-dump %s 2>&1 | FileCheck %s + +// CHECK-LABEL: example0 +void example0() { + double d = 2.0; + // CHECK: VarDecl{{.*}}rd 'double &' + // CHECK-NEXT: DeclRefExpr + double &rd = d; + // CHECK: VarDecl{{.*}}rcd 'const double &' + // CHECK-NEXT: ImplicitCastExpr{{.*}}'const double' lvalue <NoOp> + const double &rcd = d; +} + +struct A { }; +struct B : A { } b; + +// CHECK-LABEL: example1 +void example1() { + // CHECK: VarDecl{{.*}}ra 'struct A &' + // CHECK: ImplicitCastExpr{{.*}}'struct A' lvalue <DerivedToBase (A)> + A &ra = b; + // CHECK: VarDecl{{.*}}rca 'const struct A &' + // CHECK: ImplicitCastExpr{{.*}}'const struct A' lvalue <DerivedToBase (A)> + // CHECK-NOT: MaterializeTemporaryExpr + // CHECK: ImplicitCastExpr{{.*}}'const struct B' lvalue <NoOp> + const A& rca = b; +} + +extern B f(); + +struct X { + operator B(); +} x; + +// CHECK-LABEL: example2 +void example2() { + // CHECK: VarDecl{{.*}}rca 'const struct A &' + // CHECK: ImplicitCastExpr{{.*}}'const struct A' lvalue <DerivedToBase (A)> + // CHECK: MaterializeTemporaryExpr{{.*}}'const struct B' + // CHECK: ImplicitCastExpr{{.*}}'const struct B' <NoOp> + // CHECK: CallExpr{{.*}}B + const A &rca = f(); + // CHECK: VarDecl{{.*}}r 'const struct A &' + // CHECK: ImplicitCastExpr{{.*}}'const struct A' lvalue <DerivedToBase (A)> + // CHECK: MaterializeTemporaryExpr{{.*}}'const struct B' + // CHECK: ImplicitCastExpr{{.*}}'const struct B' <NoOp> + // CHECK: CXXMemberCallExpr{{.*}}'struct B' + const A& r = x; +} + +// CHECK-LABEL: example3 +void example3() { + // CHECK: VarDecl{{.*}}rcd2 'const double &' + // CHECK: ImplicitCastExpr{{.*}} <IntegralToFloating> + const double& rcd2 = 2; +} diff --git a/clang/test/Frontend/float16.cpp b/clang/test/Frontend/float16.cpp index aa65270c75d..febd6b8e36a 100644 --- a/clang/test/Frontend/float16.cpp +++ b/clang/test/Frontend/float16.cpp @@ -1,326 +1,326 @@ -// RUN: %clang_cc1 -std=c++11 -ast-dump %s | FileCheck %s --strict-whitespace
-// RUN: %clang_cc1 -std=c++11 -ast-dump -fnative-half-type %s | FileCheck %s --check-prefix=CHECK-NATIVE --strict-whitespace
-
-/* Various contexts where type _Float16 can appear. */
-
-/* Namespace */
-namespace {
- _Float16 f1n;
- _Float16 f2n = 33.f16;
- _Float16 arr1n[10];
- _Float16 arr2n[] = { 1.2, 3.0, 3.e4 };
- const volatile _Float16 func1n(const _Float16 &arg) {
- return arg + f2n + arr1n[4] - arr2n[1];
- }
-}
-
-//CHECK: |-NamespaceDecl
-//CHECK-NEXT: | |-VarDecl {{.*}} f1n '_Float16'
-//CHECK-NEXT: | |-VarDecl {{.*}} f2n '_Float16' cinit
-//CHECK-NEXT: | | `-FloatingLiteral {{.*}} '_Float16' 3.300000e+01
-//CHECK-NEXT: | |-VarDecl {{.*}} arr1n '_Float16 [10]'
-//CHECK-NEXT: | |-VarDecl {{.*}} arr2n '_Float16 [3]' cinit
-//CHECK-NEXT: | | `-InitListExpr {{.*}} '_Float16 [3]'
-//CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
-//CHECK-NEXT: | | | `-FloatingLiteral {{.*}} 'double' 1.200000e+00
-//CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
-//CHECK-NEXT: | | | `-FloatingLiteral {{.*}} 'double' 3.000000e+00
-//CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
-//CHECK-NEXT: | | `-FloatingLiteral {{.*}} 'double' 3.000000e+04
-//CHECK-NEXT: | `-FunctionDecl {{.*}} func1n 'const volatile _Float16 (const _Float16 &)'
-
-/* File */
-_Float16 f1f;
-_Float16 f2f = 32.4;
-_Float16 arr1f[10];
-_Float16 arr2f[] = { -1.2, -3.0, -3.e4 };
-_Float16 func1f(_Float16 arg);
-
-//CHECK: |-VarDecl {{.*}} f1f '_Float16'
-//CHECK-NEXT: |-VarDecl {{.*}} f2f '_Float16' cinit
-//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
-//CHECK-NEXT: | `-FloatingLiteral {{.*}} 'double' 3.240000e+01
-//CHECK-NEXT: |-VarDecl {{.*}} arr1f '_Float16 [10]'
-//CHECK-NEXT: |-VarDecl {{.*}} arr2f '_Float16 [3]' cinit
-//CHECK-NEXT: | `-InitListExpr {{.*}} '_Float16 [3]'
-//CHECK-NEXT: | |-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
-//CHECK-NEXT: | | `-UnaryOperator {{.*}} 'double' prefix '-'
-//CHECK-NEXT: | | `-FloatingLiteral {{.*}} 'double' 1.200000e+00
-//CHECK-NEXT: | |-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
-//CHECK-NEXT: | | `-UnaryOperator {{.*}} 'double' prefix '-'
-//CHECK-NEXT: | | `-FloatingLiteral {{.*}} 'double' 3.000000e+00
-//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
-//CHECK-NEXT: | `-UnaryOperator {{.*}} 'double' prefix '-'
-//CHECK-NEXT: | `-FloatingLiteral {{.*}} 'double' 3.000000e+04
-//CHECK-NEXT: |-FunctionDecl {{.*}} func1f '_Float16 (_Float16)'
-//CHECK-NEXT: | `-ParmVarDecl {{.*}} arg '_Float16'
-
-
-// Mixing __fp16 and Float16 types:
-// The _Float16 type is first converted to __fp16 type and then the operation
-// is completed as if both operands were of __fp16 type.
-
-__fp16 B = -0.1;
-auto C = -1.0f16 + B;
-
-// When we do *not* have native half types, we expect __fp16 to be promoted to
-// float, and consequently also _Float16 promotions to float:
-
-//CHECK: -VarDecl {{.*}} used B '__fp16' cinit
-//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '__fp16' <FloatingCast>
-//CHECK-NEXT: | `-UnaryOperator {{.*}} 'double' prefix '-'
-//CHECK-NEXT: | `-FloatingLiteral {{.*}} 'double' 1.000000e-01
-//CHECK-NEXT: |-VarDecl {{.*}} C 'float':'float' cinit
-//CHECK-NEXT: | `-BinaryOperator {{.*}} 'float' '+'
-//CHECK-NEXT: | |-ImplicitCastExpr {{.*}} 'float' <FloatingCast>
-//CHECK-NEXT: | | `-UnaryOperator {{.*}} '_Float16' prefix '-'
-//CHECK-NEXT: | | `-FloatingLiteral {{.*}} '_Float16' 1.000000e+00
-//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'float' <FloatingCast>
-//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '__fp16' <LValueToRValue>
-//CHECK-NEXT: | `-DeclRefExpr {{.*}} '__fp16' lvalue Var 0x{{.*}} 'B' '__fp16'
-
-// When do have native half types, we expect to see promotions to fp16:
-
-//CHECK-NATIVE: |-VarDecl {{.*}} used B '__fp16' cinit
-//CHECK-NATIVE: | `-ImplicitCastExpr {{.*}} '__fp16' <FloatingCast>
-//CHECK-NATIVE: | `-UnaryOperator {{.*}} 'double' prefix '-'
-//CHECK-NATIVE: | `-FloatingLiteral {{.*}} 'double' 1.000000e-01
-//CHECK-NATIVE: |-VarDecl {{.*}} C '__fp16':'__fp16' cinit
-//CHECK-NATIVE: | `-BinaryOperator {{.*}} '__fp16' '+'
-//CHECK-NATIVE: | |-ImplicitCastExpr {{.*}} '__fp16' <FloatingCast>
-//CHECK-NATIVE: | | `-UnaryOperator {{.*}} '_Float16' prefix '-'
-//CHECK-NATIVE: | | `-FloatingLiteral {{.*}} '_Float16' 1.000000e+00
-//CHECK-NATIVE: | `-ImplicitCastExpr {{.*}} '__fp16' <LValueToRValue>
-//CHECK-NATIVE: | `-DeclRefExpr {{.*}} '__fp16' lvalue Var 0x{{.*}} 'B' '__fp16'
-
-
-/* Class */
-
-class C1 {
- _Float16 f1c;
- static const _Float16 f2c;
- volatile _Float16 f3c;
-public:
- C1(_Float16 arg) : f1c(arg), f3c(arg) { }
- _Float16 func1c(_Float16 arg ) {
- return f1c + arg;
- }
- static _Float16 func2c(_Float16 arg) {
- return arg * C1::f2c;
- }
-};
-
-//CHECK: |-CXXRecordDecl {{.*}} referenced class C1 definition
-//CHECK: | |-CXXRecordDecl {{.*}} implicit referenced class C1
-//CHECK-NEXT: | |-FieldDecl {{.*}} referenced f1c '_Float16'
-//CHECK-NEXT: | |-VarDecl {{.*}} used f2c 'const _Float16' static
-//CHECK-NEXT: | |-FieldDecl {{.*}} f3c 'volatile _Float16'
-//CHECK-NEXT: | |-AccessSpecDecl
-//CHECK-NEXT: | |-CXXConstructorDecl {{.*}} used C1 'void (_Float16)
-//CHECK-NEXT: | | |-ParmVarDecl {{.*}} used arg '_Float16'
-//CHECK-NEXT: | | |-CXXCtorInitializer Field {{.*}} 'f1c' '_Float16'
-//CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
-//CHECK-NEXT: | | | `-DeclRefExpr {{.*}} '_Float16' lvalue ParmVar 0x{{.*}} 'arg' '_Float16'
-//CHECK-NEXT: | | |-CXXCtorInitializer Field {{.*}} 'f3c' 'volatile _Float16'
-//CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
-//CHECK-NEXT: | | | `-DeclRefExpr {{.*}} '_Float16' lvalue ParmVar 0x{{.*}} 'arg' '_Float16'
-//CHECK-NEXT: | | `-CompoundStmt
-//CHECK-NEXT: | |-CXXMethodDecl {{.*}} used func1c '_Float16 (_Float16)
-//CHECK-NEXT: | | |-ParmVarDecl {{.*}} used arg '_Float16'
-//CHECK-NEXT: | | `-CompoundStmt
-//CHECK-NEXT: | | `-ReturnStmt
-//CHECK-NEXT: | | `-BinaryOperator {{.*}} '_Float16' '+'
-//CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
-//CHECK-NEXT: | | | `-MemberExpr {{.*}} '_Float16' lvalue ->f1c 0x{{.*}}
-//CHECK-NEXT: | | | `-CXXThisExpr {{.*}} 'C1 *' this
-//CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
-//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16' lvalue ParmVar 0x{{.*}} 'arg' '_Float16'
-//CHECK-NEXT: | |-CXXMethodDecl {{.*}} used func2c '_Float16 (_Float16)' static
-//CHECK-NEXT: | | |-ParmVarDecl {{.*}} used arg '_Float16'
-//CHECK-NEXT: | | `-CompoundStmt
-//CHECK-NEXT: | | `-ReturnStmt
-//CHECK-NEXT: | | `-BinaryOperator {{.*}} '_Float16' '*'
-//CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
-//CHECK-NEXT: | | | `-DeclRefExpr {{.*}} '_Float16' lvalue ParmVar 0x{{.*}} 'arg' '_Float16'
-//CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
-//CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'const _Float16' lvalue Var 0x{{.*}} 'f2c' 'const _Float16'
-
-
-/* Template */
-
-template <class C> C func1t(C arg) {
- return arg * 2.f16;
-}
-
-//CHECK: |-FunctionTemplateDecl {{.*}} func1t
-//CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} C
-//CHECK-NEXT: | |-FunctionDecl {{.*}} func1t 'C (C)'
-//CHECK-NEXT: | | |-ParmVarDecl {{.*}} referenced arg 'C'
-//CHECK-NEXT: | | `-CompoundStmt
-//CHECK-NEXT: | | `-ReturnStmt
-//CHECK-NEXT: | | `-BinaryOperator {{.*}} '<dependent type>' '*'
-//CHECK-NEXT: | | |-DeclRefExpr {{.*}} 'C' lvalue ParmVar {{.*}} 'arg' 'C'
-//CHECK-NEXT: | | `-FloatingLiteral {{.*}} '_Float16' 2.000000e+00
-//CHECK-NEXT: | `-FunctionDecl {{.*}} used func1t '_Float16 (_Float16)'
-//CHECK-NEXT: | |-TemplateArgument type '_Float16'
-//CHECK-NEXT: | |-ParmVarDecl {{.*}} used arg '_Float16':'_Float16'
-//CHECK-NEXT: | `-CompoundStmt
-//CHECK-NEXT: | `-ReturnStmt
-//CHECK-NEXT: | `-BinaryOperator {{.*}} '_Float16' '*'
-//CHECK-NEXT: | |-ImplicitCastExpr {{.*}} '_Float16':'_Float16' <LValueToRValue>
-//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16':'_Float16' lvalue ParmVar {{.*}} 'arg' '_Float16':'_Float16'
-//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 2.000000e+00
-
-
-template <class C> struct S1 {
- C mem1;
-};
-
-//CHECK: |-ClassTemplateDecl {{.*}} S1
-//CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} referenced class depth 0 index 0 C
-//CHECK-NEXT: | |-CXXRecordDecl {{.*}} struct S1 definition
-//CHECK: | | |-CXXRecordDecl {{.*}} implicit struct S1
-//CHECK-NEXT: | | `-FieldDecl {{.*}} mem1 'C'
-//CHECK-NEXT: | `-ClassTemplateSpecialization {{.*}} 'S1'
-
-template <> struct S1<_Float16> {
- _Float16 mem2;
-};
-
-
-/* Local */
-
-extern int printf (const char *__restrict __format, ...);
-
-int main(void) {
- _Float16 f1l = 1e3f16;
-//CHECK: | `-VarDecl {{.*}} used f1l '_Float16' cinit
-//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 1.000000e+03
-
- _Float16 f2l = -0.f16;
-//CHECK: | `-VarDecl {{.*}} used f2l '_Float16' cinit
-//CHECK-NEXT: | `-UnaryOperator {{.*}} '_Float16' prefix '-'
-//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 0.000000e+00
-
- _Float16 f3l = 1.000976562;
-//CHECK: | `-VarDecl {{.*}} used f3l '_Float16' cinit
-//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
-//CHECK-NEXT: | `-FloatingLiteral {{.*}} 'double' 1.000977e+00
-
- C1 c1(f1l);
-//CHECK: | `-VarDecl{{.*}} used c1 'C1' callinit
-//CHECK-NEXT: | `-CXXConstructExpr {{.*}} 'C1' 'void (_Float16)
-//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
-//CHECK-NEXT: | `-DeclRefExpr {{.*}} '_Float16' lvalue Var 0x{{.*}} 'f1l' '_Float16'
-
- S1<_Float16> s1 = { 132.f16 };
-//CHECK: | `-VarDecl {{.*}} used s1 'S1<_Float16>':'S1<_Float16>' cinit
-//CHECK-NEXT: | `-InitListExpr {{.*}} 'S1<_Float16>':'S1<_Float16>'
-//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 1.320000e+02
-
- _Float16 f4l = func1n(f1l) + func1f(f2l) + c1.func1c(f3l) + c1.func2c(f1l) +
- func1t(f1l) + s1.mem2 - f1n + f2n;
-//CHECK: | `-VarDecl {{.*}} used f4l '_Float16' cinit
-//CHECK-NEXT: | `-BinaryOperator {{.*}} '_Float16' '+'
-//CHECK-NEXT: | |-BinaryOperator {{.*}} '_Float16' '-'
-//CHECK-NEXT: | | |-BinaryOperator {{.*}} '_Float16' '+'
-//CHECK-NEXT: | | | |-BinaryOperator {{.*}} '_Float16' '+'
-//CHECK-NEXT: | | | | |-BinaryOperator {{.*}} '_Float16' '+'
-//CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} '_Float16' '+'
-//CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} '_Float16' '+'
-//CHECK-NEXT: | | | | | | | |-CallExpr {{.*}} '_Float16'
-//CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} 'const volatile _Float16 (*)(const _Float16 &)' <FunctionToPointerDecay>
-//CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} 'const volatile _Float16 (const _Float16 &)' lvalue Function {{.*}} 'func1n' 'const volatile _Float16 (const _Float16 &)'
-//CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} 'const _Float16' lvalue <NoOp>
-//CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f1l' '_Float16'
-//CHECK-NEXT: | | | | | | | `-CallExpr {{.*}} '_Float16'
-//CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} '_Float16 (*)(_Float16)' <FunctionToPointerDecay>
-//CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} '_Float16 (_Float16)' lvalue Function {{.*}} 'func1f' '_Float16 (_Float16)'
-//CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
-//CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2l' '_Float16'
-//CHECK-NEXT: | | | | | | `-CXXMemberCallExpr {{.*}} '_Float16'
-//CHECK-NEXT: | | | | | | |-MemberExpr {{.*}} '<bound member function type>' .func1c {{.*}}
-//CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} 'C1' lvalue Var {{.*}} 'c1' 'C1'
-//CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
-//CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f3l' '_Float16'
-//CHECK-NEXT: | | | | | `-CallExpr {{.*}} '_Float16'
-//CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} '_Float16 (*)(_Float16)' <FunctionToPointerDecay>
-//CHECK-NEXT: | | | | | | `-MemberExpr {{.*}} '_Float16 (_Float16)' lvalue .func2c {{.*}}
-//CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} 'C1' lvalue Var {{.*}} 'c1' 'C1'
-//CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
-//CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f1l' '_Float16'
-//CHECK-NEXT: | | | | `-CallExpr {{.*}} '_Float16':'_Float16'
-//CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} '_Float16 (*)(_Float16)' <FunctionToPointerDecay>
-//CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} '_Float16 (_Float16)' lvalue Function {{.*}} 'func1t' '_Float16 (_Float16)' (FunctionTemplate {{.*}} 'func1t')
-//CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
-//CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f1l' '_Float16'
-//CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
-//CHECK-NEXT: | | | `-MemberExpr {{.*}} '_Float16' lvalue .mem2 {{.*}}
-//CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'S1<_Float16>':'S1<_Float16>' lvalue Var {{.*}} 's1' 'S1<_Float16>':'S1<_Float16>'
-//CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
-//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f1n' '_Float16'
-//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
-//CHECK-NEXT: | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2n' '_Float16'
-
- auto f5l = -1.f16, *f6l = &f2l, f7l = func1t(f3l);
-//CHECK: | |-VarDecl {{.*}} f5l '_Float16':'_Float16' cinit
-//CHECK-NEXT: | | `-UnaryOperator {{.*}} '_Float16' prefix '-'
-//CHECK-NEXT: | | `-FloatingLiteral {{.*}} '_Float16' 1.000000e+00
-//CHECK-NEXT: | |-VarDecl {{.*}} f6l '_Float16 *' cinit
-//CHECK-NEXT: | | `-UnaryOperator {{.*}} '_Float16 *' prefix '&'
-//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2l' '_Float16'
-//CHECK-NEXT: | `-VarDecl {{.*}} f7l '_Float16':'_Float16' cinit
-//CHECK-NEXT: | `-CallExpr {{.*}} '_Float16':'_Float16'
-//CHECK-NEXT: | |-ImplicitCastExpr {{.*}} '_Float16 (*)(_Float16)' <FunctionToPointerDecay>
-//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16 (_Float16)' lvalue Function {{.*}} 'func1t' '_Float16 (_Float16)' (FunctionTemplate {{.*}} 'func1t')
-//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
-//CHECK-NEXT: | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f3l' '_Float16'
-
- _Float16 f8l = f4l++;
-//CHECK: | `-VarDecl {{.*}} f8l '_Float16' cinit
-//CHECK-NEXT: | `-UnaryOperator {{.*}} '_Float16' postfix '++'
-//CHECK-NEXT: | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f4l' '_Float16'
-
- _Float16 arr1l[] = { -1.f16, -0.f16, -11.f16 };
-//CHECK: `-VarDecl {{.*}} arr1l '_Float16 [3]' cinit
-//CHECK-NEXT: `-InitListExpr {{.*}} '_Float16 [3]'
-//CHECK-NEXT: |-UnaryOperator {{.*}} '_Float16' prefix '-'
-//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 1.000000e+00
-//CHECK-NEXT: |-UnaryOperator {{.*}} '_Float16' prefix '-'
-//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 0.000000e+00
-//CHECK-NEXT: `-UnaryOperator {{.*}} '_Float16' prefix '-'
-//CHECK-NEXT: `-FloatingLiteral {{.*}} '_Float16' 1.100000e+01
-
- float cvtf = f2n;
-//CHECK: `-VarDecl {{.*}} cvtf 'float' cinit
-//CHECK-NEXT: `-ImplicitCastExpr {{.*}} 'float' <FloatingCast>
-//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
-//CHECK-NEXT: `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2n' '_Float16'
-
- double cvtd = f2n;
-//CHECK: `-VarDecl {{.*}} cvtd 'double' cinit
-//CHECK-NEXT: `-ImplicitCastExpr {{.*}} 'double' <FloatingCast>
-//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
-//CHECK-NEXT: `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2n' '_Float16'
-
- long double cvtld = f2n;
-//CHECK: `-VarDecl {{.*}} cvtld 'long double' cinit
-//CHECK-NEXT: `-ImplicitCastExpr {{.*}} 'long double' <FloatingCast>
-//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
-//CHECK-NEXT: `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2n' '_Float16'
-
- _Float16 f2h = 42.0f;
-//CHECK: `-VarDecl {{.*}} f2h '_Float16' cinit
-//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
-//CHECK-NEXT: `-FloatingLiteral {{.*}} 'float' 4.200000e+01
-
- _Float16 d2h = 42.0;
-//CHECK: `-VarDecl {{.*}} d2h '_Float16' cinit
-//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
-//CHECK-NEXT: `-FloatingLiteral {{.*}} 'double' 4.200000e+01
-
- _Float16 ld2h = 42.0l;
-//CHECK: `-VarDecl {{.*}} ld2h '_Float16' cinit
-//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
-//CHECK-NEXT: `-FloatingLiteral {{.*}} 'long double' 4.200000e+01
-}
+// RUN: %clang_cc1 -std=c++11 -ast-dump %s | FileCheck %s --strict-whitespace +// RUN: %clang_cc1 -std=c++11 -ast-dump -fnative-half-type %s | FileCheck %s --check-prefix=CHECK-NATIVE --strict-whitespace + +/* Various contexts where type _Float16 can appear. */ + +/* Namespace */ +namespace { + _Float16 f1n; + _Float16 f2n = 33.f16; + _Float16 arr1n[10]; + _Float16 arr2n[] = { 1.2, 3.0, 3.e4 }; + const volatile _Float16 func1n(const _Float16 &arg) { + return arg + f2n + arr1n[4] - arr2n[1]; + } +} + +//CHECK: |-NamespaceDecl +//CHECK-NEXT: | |-VarDecl {{.*}} f1n '_Float16' +//CHECK-NEXT: | |-VarDecl {{.*}} f2n '_Float16' cinit +//CHECK-NEXT: | | `-FloatingLiteral {{.*}} '_Float16' 3.300000e+01 +//CHECK-NEXT: | |-VarDecl {{.*}} arr1n '_Float16 [10]' +//CHECK-NEXT: | |-VarDecl {{.*}} arr2n '_Float16 [3]' cinit +//CHECK-NEXT: | | `-InitListExpr {{.*}} '_Float16 [3]' +//CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast> +//CHECK-NEXT: | | | `-FloatingLiteral {{.*}} 'double' 1.200000e+00 +//CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast> +//CHECK-NEXT: | | | `-FloatingLiteral {{.*}} 'double' 3.000000e+00 +//CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast> +//CHECK-NEXT: | | `-FloatingLiteral {{.*}} 'double' 3.000000e+04 +//CHECK-NEXT: | `-FunctionDecl {{.*}} func1n 'const volatile _Float16 (const _Float16 &)' + +/* File */ +_Float16 f1f; +_Float16 f2f = 32.4; +_Float16 arr1f[10]; +_Float16 arr2f[] = { -1.2, -3.0, -3.e4 }; +_Float16 func1f(_Float16 arg); + +//CHECK: |-VarDecl {{.*}} f1f '_Float16' +//CHECK-NEXT: |-VarDecl {{.*}} f2f '_Float16' cinit +//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast> +//CHECK-NEXT: | `-FloatingLiteral {{.*}} 'double' 3.240000e+01 +//CHECK-NEXT: |-VarDecl {{.*}} arr1f '_Float16 [10]' +//CHECK-NEXT: |-VarDecl {{.*}} arr2f '_Float16 [3]' cinit +//CHECK-NEXT: | `-InitListExpr {{.*}} '_Float16 [3]' +//CHECK-NEXT: | |-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast> +//CHECK-NEXT: | | `-UnaryOperator {{.*}} 'double' prefix '-' +//CHECK-NEXT: | | `-FloatingLiteral {{.*}} 'double' 1.200000e+00 +//CHECK-NEXT: | |-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast> +//CHECK-NEXT: | | `-UnaryOperator {{.*}} 'double' prefix '-' +//CHECK-NEXT: | | `-FloatingLiteral {{.*}} 'double' 3.000000e+00 +//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast> +//CHECK-NEXT: | `-UnaryOperator {{.*}} 'double' prefix '-' +//CHECK-NEXT: | `-FloatingLiteral {{.*}} 'double' 3.000000e+04 +//CHECK-NEXT: |-FunctionDecl {{.*}} func1f '_Float16 (_Float16)' +//CHECK-NEXT: | `-ParmVarDecl {{.*}} arg '_Float16' + + +// Mixing __fp16 and Float16 types: +// The _Float16 type is first converted to __fp16 type and then the operation +// is completed as if both operands were of __fp16 type. + +__fp16 B = -0.1; +auto C = -1.0f16 + B; + +// When we do *not* have native half types, we expect __fp16 to be promoted to +// float, and consequently also _Float16 promotions to float: + +//CHECK: -VarDecl {{.*}} used B '__fp16' cinit +//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '__fp16' <FloatingCast> +//CHECK-NEXT: | `-UnaryOperator {{.*}} 'double' prefix '-' +//CHECK-NEXT: | `-FloatingLiteral {{.*}} 'double' 1.000000e-01 +//CHECK-NEXT: |-VarDecl {{.*}} C 'float':'float' cinit +//CHECK-NEXT: | `-BinaryOperator {{.*}} 'float' '+' +//CHECK-NEXT: | |-ImplicitCastExpr {{.*}} 'float' <FloatingCast> +//CHECK-NEXT: | | `-UnaryOperator {{.*}} '_Float16' prefix '-' +//CHECK-NEXT: | | `-FloatingLiteral {{.*}} '_Float16' 1.000000e+00 +//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'float' <FloatingCast> +//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '__fp16' <LValueToRValue> +//CHECK-NEXT: | `-DeclRefExpr {{.*}} '__fp16' lvalue Var 0x{{.*}} 'B' '__fp16' + +// When do have native half types, we expect to see promotions to fp16: + +//CHECK-NATIVE: |-VarDecl {{.*}} used B '__fp16' cinit +//CHECK-NATIVE: | `-ImplicitCastExpr {{.*}} '__fp16' <FloatingCast> +//CHECK-NATIVE: | `-UnaryOperator {{.*}} 'double' prefix '-' +//CHECK-NATIVE: | `-FloatingLiteral {{.*}} 'double' 1.000000e-01 +//CHECK-NATIVE: |-VarDecl {{.*}} C '__fp16':'__fp16' cinit +//CHECK-NATIVE: | `-BinaryOperator {{.*}} '__fp16' '+' +//CHECK-NATIVE: | |-ImplicitCastExpr {{.*}} '__fp16' <FloatingCast> +//CHECK-NATIVE: | | `-UnaryOperator {{.*}} '_Float16' prefix '-' +//CHECK-NATIVE: | | `-FloatingLiteral {{.*}} '_Float16' 1.000000e+00 +//CHECK-NATIVE: | `-ImplicitCastExpr {{.*}} '__fp16' <LValueToRValue> +//CHECK-NATIVE: | `-DeclRefExpr {{.*}} '__fp16' lvalue Var 0x{{.*}} 'B' '__fp16' + + +/* Class */ + +class C1 { + _Float16 f1c; + static const _Float16 f2c; + volatile _Float16 f3c; +public: + C1(_Float16 arg) : f1c(arg), f3c(arg) { } + _Float16 func1c(_Float16 arg ) { + return f1c + arg; + } + static _Float16 func2c(_Float16 arg) { + return arg * C1::f2c; + } +}; + +//CHECK: |-CXXRecordDecl {{.*}} referenced class C1 definition +//CHECK: | |-CXXRecordDecl {{.*}} implicit referenced class C1 +//CHECK-NEXT: | |-FieldDecl {{.*}} referenced f1c '_Float16' +//CHECK-NEXT: | |-VarDecl {{.*}} used f2c 'const _Float16' static +//CHECK-NEXT: | |-FieldDecl {{.*}} f3c 'volatile _Float16' +//CHECK-NEXT: | |-AccessSpecDecl +//CHECK-NEXT: | |-CXXConstructorDecl {{.*}} used C1 'void (_Float16) +//CHECK-NEXT: | | |-ParmVarDecl {{.*}} used arg '_Float16' +//CHECK-NEXT: | | |-CXXCtorInitializer Field {{.*}} 'f1c' '_Float16' +//CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> +//CHECK-NEXT: | | | `-DeclRefExpr {{.*}} '_Float16' lvalue ParmVar 0x{{.*}} 'arg' '_Float16' +//CHECK-NEXT: | | |-CXXCtorInitializer Field {{.*}} 'f3c' 'volatile _Float16' +//CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> +//CHECK-NEXT: | | | `-DeclRefExpr {{.*}} '_Float16' lvalue ParmVar 0x{{.*}} 'arg' '_Float16' +//CHECK-NEXT: | | `-CompoundStmt +//CHECK-NEXT: | |-CXXMethodDecl {{.*}} used func1c '_Float16 (_Float16) +//CHECK-NEXT: | | |-ParmVarDecl {{.*}} used arg '_Float16' +//CHECK-NEXT: | | `-CompoundStmt +//CHECK-NEXT: | | `-ReturnStmt +//CHECK-NEXT: | | `-BinaryOperator {{.*}} '_Float16' '+' +//CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> +//CHECK-NEXT: | | | `-MemberExpr {{.*}} '_Float16' lvalue ->f1c 0x{{.*}} +//CHECK-NEXT: | | | `-CXXThisExpr {{.*}} 'class C1 *' this +//CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> +//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16' lvalue ParmVar 0x{{.*}} 'arg' '_Float16' +//CHECK-NEXT: | |-CXXMethodDecl {{.*}} used func2c '_Float16 (_Float16)' static +//CHECK-NEXT: | | |-ParmVarDecl {{.*}} used arg '_Float16' +//CHECK-NEXT: | | `-CompoundStmt +//CHECK-NEXT: | | `-ReturnStmt +//CHECK-NEXT: | | `-BinaryOperator {{.*}} '_Float16' '*' +//CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> +//CHECK-NEXT: | | | `-DeclRefExpr {{.*}} '_Float16' lvalue ParmVar 0x{{.*}} 'arg' '_Float16' +//CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> +//CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'const _Float16' lvalue Var 0x{{.*}} 'f2c' 'const _Float16' + + +/* Template */ + +template <class C> C func1t(C arg) { + return arg * 2.f16; +} + +//CHECK: |-FunctionTemplateDecl {{.*}} func1t +//CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} C +//CHECK-NEXT: | |-FunctionDecl {{.*}} func1t 'C (C)' +//CHECK-NEXT: | | |-ParmVarDecl {{.*}} referenced arg 'C' +//CHECK-NEXT: | | `-CompoundStmt +//CHECK-NEXT: | | `-ReturnStmt +//CHECK-NEXT: | | `-BinaryOperator {{.*}} '<dependent type>' '*' +//CHECK-NEXT: | | |-DeclRefExpr {{.*}} 'C' lvalue ParmVar {{.*}} 'arg' 'C' +//CHECK-NEXT: | | `-FloatingLiteral {{.*}} '_Float16' 2.000000e+00 +//CHECK-NEXT: | `-FunctionDecl {{.*}} used func1t '_Float16 (_Float16)' +//CHECK-NEXT: | |-TemplateArgument type '_Float16' +//CHECK-NEXT: | |-ParmVarDecl {{.*}} used arg '_Float16':'_Float16' +//CHECK-NEXT: | `-CompoundStmt +//CHECK-NEXT: | `-ReturnStmt +//CHECK-NEXT: | `-BinaryOperator {{.*}} '_Float16' '*' +//CHECK-NEXT: | |-ImplicitCastExpr {{.*}} '_Float16':'_Float16' <LValueToRValue> +//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16':'_Float16' lvalue ParmVar {{.*}} 'arg' '_Float16':'_Float16' +//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 2.000000e+00 + + +template <class C> struct S1 { + C mem1; +}; + +//CHECK: |-ClassTemplateDecl {{.*}} S1 +//CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} referenced class depth 0 index 0 C +//CHECK-NEXT: | |-CXXRecordDecl {{.*}} struct S1 definition +//CHECK: | | |-CXXRecordDecl {{.*}} implicit struct S1 +//CHECK-NEXT: | | `-FieldDecl {{.*}} mem1 'C' +//CHECK-NEXT: | `-ClassTemplateSpecialization {{.*}} 'S1' + +template <> struct S1<_Float16> { + _Float16 mem2; +}; + + +/* Local */ + +extern int printf (const char *__restrict __format, ...); + +int main(void) { + _Float16 f1l = 1e3f16; +//CHECK: | `-VarDecl {{.*}} used f1l '_Float16' cinit +//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 1.000000e+03 + + _Float16 f2l = -0.f16; +//CHECK: | `-VarDecl {{.*}} used f2l '_Float16' cinit +//CHECK-NEXT: | `-UnaryOperator {{.*}} '_Float16' prefix '-' +//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 0.000000e+00 + + _Float16 f3l = 1.000976562; +//CHECK: | `-VarDecl {{.*}} used f3l '_Float16' cinit +//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast> +//CHECK-NEXT: | `-FloatingLiteral {{.*}} 'double' 1.000977e+00 + + C1 c1(f1l); +//CHECK: | `-VarDecl{{.*}} used c1 'class C1' callinit +//CHECK-NEXT: | `-CXXConstructExpr {{.*}} 'class C1' 'void (_Float16) +//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> +//CHECK-NEXT: | `-DeclRefExpr {{.*}} '_Float16' lvalue Var 0x{{.*}} 'f1l' '_Float16' + + S1<_Float16> s1 = { 132.f16 }; +//CHECK: | `-VarDecl {{.*}} used s1 'S1<_Float16>':'struct S1<_Float16>' cinit +//CHECK-NEXT: | `-InitListExpr {{.*}} 'S1<_Float16>':'struct S1<_Float16>' +//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 1.320000e+02 + + _Float16 f4l = func1n(f1l) + func1f(f2l) + c1.func1c(f3l) + c1.func2c(f1l) + + func1t(f1l) + s1.mem2 - f1n + f2n; +//CHECK: | `-VarDecl {{.*}} used f4l '_Float16' cinit +//CHECK-NEXT: | `-BinaryOperator {{.*}} '_Float16' '+' +//CHECK-NEXT: | |-BinaryOperator {{.*}} '_Float16' '-' +//CHECK-NEXT: | | |-BinaryOperator {{.*}} '_Float16' '+' +//CHECK-NEXT: | | | |-BinaryOperator {{.*}} '_Float16' '+' +//CHECK-NEXT: | | | | |-BinaryOperator {{.*}} '_Float16' '+' +//CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} '_Float16' '+' +//CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} '_Float16' '+' +//CHECK-NEXT: | | | | | | | |-CallExpr {{.*}} '_Float16' +//CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} 'const volatile _Float16 (*)(const _Float16 &)' <FunctionToPointerDecay> +//CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} 'const volatile _Float16 (const _Float16 &)' lvalue Function {{.*}} 'func1n' 'const volatile _Float16 (const _Float16 &)' +//CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} 'const _Float16' lvalue <NoOp> +//CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f1l' '_Float16' +//CHECK-NEXT: | | | | | | | `-CallExpr {{.*}} '_Float16' +//CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} '_Float16 (*)(_Float16)' <FunctionToPointerDecay> +//CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} '_Float16 (_Float16)' lvalue Function {{.*}} 'func1f' '_Float16 (_Float16)' +//CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> +//CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2l' '_Float16' +//CHECK-NEXT: | | | | | | `-CXXMemberCallExpr {{.*}} '_Float16' +//CHECK-NEXT: | | | | | | |-MemberExpr {{.*}} '<bound member function type>' .func1c {{.*}} +//CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} 'class C1' lvalue Var {{.*}} 'c1' 'class C1' +//CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> +//CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f3l' '_Float16' +//CHECK-NEXT: | | | | | `-CallExpr {{.*}} '_Float16' +//CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} '_Float16 (*)(_Float16)' <FunctionToPointerDecay> +//CHECK-NEXT: | | | | | | `-MemberExpr {{.*}} '_Float16 (_Float16)' lvalue .func2c {{.*}} +//CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} 'class C1' lvalue Var {{.*}} 'c1' 'class C1' +//CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> +//CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f1l' '_Float16' +//CHECK-NEXT: | | | | `-CallExpr {{.*}} '_Float16':'_Float16' +//CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} '_Float16 (*)(_Float16)' <FunctionToPointerDecay> +//CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} '_Float16 (_Float16)' lvalue Function {{.*}} 'func1t' '_Float16 (_Float16)' (FunctionTemplate {{.*}} 'func1t') +//CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> +//CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f1l' '_Float16' +//CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> +//CHECK-NEXT: | | | `-MemberExpr {{.*}} '_Float16' lvalue .mem2 {{.*}} +//CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'S1<_Float16>':'struct S1<_Float16>' lvalue Var {{.*}} 's1' 'S1<_Float16>':'struct S1<_Float16>' +//CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> +//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f1n' '_Float16' +//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> +//CHECK-NEXT: | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2n' '_Float16' + + auto f5l = -1.f16, *f6l = &f2l, f7l = func1t(f3l); +//CHECK: | |-VarDecl {{.*}} f5l '_Float16':'_Float16' cinit +//CHECK-NEXT: | | `-UnaryOperator {{.*}} '_Float16' prefix '-' +//CHECK-NEXT: | | `-FloatingLiteral {{.*}} '_Float16' 1.000000e+00 +//CHECK-NEXT: | |-VarDecl {{.*}} f6l '_Float16 *' cinit +//CHECK-NEXT: | | `-UnaryOperator {{.*}} '_Float16 *' prefix '&' +//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2l' '_Float16' +//CHECK-NEXT: | `-VarDecl {{.*}} f7l '_Float16':'_Float16' cinit +//CHECK-NEXT: | `-CallExpr {{.*}} '_Float16':'_Float16' +//CHECK-NEXT: | |-ImplicitCastExpr {{.*}} '_Float16 (*)(_Float16)' <FunctionToPointerDecay> +//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16 (_Float16)' lvalue Function {{.*}} 'func1t' '_Float16 (_Float16)' (FunctionTemplate {{.*}} 'func1t') +//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> +//CHECK-NEXT: | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f3l' '_Float16' + + _Float16 f8l = f4l++; +//CHECK: | `-VarDecl {{.*}} f8l '_Float16' cinit +//CHECK-NEXT: | `-UnaryOperator {{.*}} '_Float16' postfix '++' +//CHECK-NEXT: | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f4l' '_Float16' + + _Float16 arr1l[] = { -1.f16, -0.f16, -11.f16 }; +//CHECK: `-VarDecl {{.*}} arr1l '_Float16 [3]' cinit +//CHECK-NEXT: `-InitListExpr {{.*}} '_Float16 [3]' +//CHECK-NEXT: |-UnaryOperator {{.*}} '_Float16' prefix '-' +//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 1.000000e+00 +//CHECK-NEXT: |-UnaryOperator {{.*}} '_Float16' prefix '-' +//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 0.000000e+00 +//CHECK-NEXT: `-UnaryOperator {{.*}} '_Float16' prefix '-' +//CHECK-NEXT: `-FloatingLiteral {{.*}} '_Float16' 1.100000e+01 + + float cvtf = f2n; +//CHECK: `-VarDecl {{.*}} cvtf 'float' cinit +//CHECK-NEXT: `-ImplicitCastExpr {{.*}} 'float' <FloatingCast> +//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> +//CHECK-NEXT: `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2n' '_Float16' + + double cvtd = f2n; +//CHECK: `-VarDecl {{.*}} cvtd 'double' cinit +//CHECK-NEXT: `-ImplicitCastExpr {{.*}} 'double' <FloatingCast> +//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> +//CHECK-NEXT: `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2n' '_Float16' + + long double cvtld = f2n; +//CHECK: `-VarDecl {{.*}} cvtld 'long double' cinit +//CHECK-NEXT: `-ImplicitCastExpr {{.*}} 'long double' <FloatingCast> +//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue> +//CHECK-NEXT: `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2n' '_Float16' + + _Float16 f2h = 42.0f; +//CHECK: `-VarDecl {{.*}} f2h '_Float16' cinit +//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast> +//CHECK-NEXT: `-FloatingLiteral {{.*}} 'float' 4.200000e+01 + + _Float16 d2h = 42.0; +//CHECK: `-VarDecl {{.*}} d2h '_Float16' cinit +//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast> +//CHECK-NEXT: `-FloatingLiteral {{.*}} 'double' 4.200000e+01 + + _Float16 ld2h = 42.0l; +//CHECK: `-VarDecl {{.*}} ld2h '_Float16' cinit +//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast> +//CHECK-NEXT: `-FloatingLiteral {{.*}} 'long double' 4.200000e+01 +} diff --git a/clang/test/Misc/ast-dump-attr.cpp b/clang/test/Misc/ast-dump-attr.cpp index 9e6f257a920..bf942959a85 100644 --- a/clang/test/Misc/ast-dump-attr.cpp +++ b/clang/test/Misc/ast-dump-attr.cpp @@ -1,211 +1,211 @@ -// RUN: %clang_cc1 -triple x86_64-pc-linux -std=c++11 -Wno-deprecated-declarations -ast-dump -ast-dump-filter Test %s | FileCheck --strict-whitespace %s
-
-int TestLocation
-__attribute__((unused));
-// CHECK: VarDecl{{.*}}TestLocation
-// CHECK-NEXT: UnusedAttr 0x{{[^ ]*}} <line:[[@LINE-2]]:16>
-
-int TestIndent
-__attribute__((unused));
-// CHECK: {{^}}VarDecl{{.*TestIndent[^()]*$}}
-// CHECK-NEXT: {{^}}`-UnusedAttr{{[^()]*$}}
-
-void TestAttributedStmt() {
- switch (1) {
- case 1:
- [[clang::fallthrough]];
- case 2:
- ;
- }
-}
-// CHECK: FunctionDecl{{.*}}TestAttributedStmt
-// CHECK: AttributedStmt
-// CHECK-NEXT: FallThroughAttr
-// CHECK-NEXT: NullStmt
-
-[[clang::warn_unused_result]] int TestCXX11DeclAttr();
-// CHECK: FunctionDecl{{.*}}TestCXX11DeclAttr
-// CHECK-NEXT: WarnUnusedResultAttr
-
-int TestAlignedNull __attribute__((aligned));
-// CHECK: VarDecl{{.*}}TestAlignedNull
-// CHECK-NEXT: AlignedAttr {{.*}} aligned
-// CHECK-NEXT: <<<NULL>>>
-
-int TestAlignedExpr __attribute__((aligned(4)));
-// CHECK: VarDecl{{.*}}TestAlignedExpr
-// CHECK-NEXT: AlignedAttr {{.*}} aligned
-// CHECK-NEXT: IntegerLiteral
-
-int TestEnum __attribute__((visibility("default")));
-// CHECK: VarDecl{{.*}}TestEnum
-// CHECK-NEXT: VisibilityAttr{{.*}} Default
-
-class __attribute__((lockable)) Mutex {
-} mu1, mu2;
-int TestExpr __attribute__((guarded_by(mu1)));
-// CHECK: VarDecl{{.*}}TestExpr
-// CHECK-NEXT: GuardedByAttr
-// CHECK-NEXT: DeclRefExpr{{.*}}mu1
-
-class Mutex TestVariadicExpr __attribute__((acquired_after(mu1, mu2)));
-// CHECK: VarDecl{{.*}}TestVariadicExpr
-// CHECK: AcquiredAfterAttr
-// CHECK-NEXT: DeclRefExpr{{.*}}mu1
-// CHECK-NEXT: DeclRefExpr{{.*}}mu2
-
-void function1(void *) {
- int TestFunction __attribute__((cleanup(function1)));
-}
-// CHECK: VarDecl{{.*}}TestFunction
-// CHECK-NEXT: CleanupAttr{{.*}} Function{{.*}}function1
-
-void TestIdentifier(void *, int)
-__attribute__((pointer_with_type_tag(ident1,1,2)));
-// CHECK: FunctionDecl{{.*}}TestIdentifier
-// CHECK: ArgumentWithTypeTagAttr{{.*}} pointer_with_type_tag ident1
-
-void TestBool(void *, int)
-__attribute__((pointer_with_type_tag(bool1,1,2)));
-// CHECK: FunctionDecl{{.*}}TestBool
-// CHECK: ArgumentWithTypeTagAttr{{.*}}pointer_with_type_tag bool1 0 1 IsPointer
-
-void TestUnsigned(void *, int)
-__attribute__((pointer_with_type_tag(unsigned1,1,2)));
-// CHECK: FunctionDecl{{.*}}TestUnsigned
-// CHECK: ArgumentWithTypeTagAttr{{.*}} pointer_with_type_tag unsigned1 0 1
-
-void TestInt(void) __attribute__((constructor(123)));
-// CHECK: FunctionDecl{{.*}}TestInt
-// CHECK-NEXT: ConstructorAttr{{.*}} 123
-
-static int TestString __attribute__((alias("alias1")));
-// CHECK: VarDecl{{.*}}TestString
-// CHECK-NEXT: AliasAttr{{.*}} "alias1"
-
-extern struct s1 TestType
-__attribute__((type_tag_for_datatype(ident1,int)));
-// CHECK: VarDecl{{.*}}TestType
-// CHECK-NEXT: TypeTagForDatatypeAttr{{.*}} int
-
-void TestLabel() {
-L: __attribute__((unused)) int i;
-// CHECK: LabelStmt{{.*}}'L'
-// CHECK: VarDecl{{.*}}i 'int'
-// CHECK-NEXT: UnusedAttr{{.*}}
-
-M: __attribute(()) int j;
-// CHECK: LabelStmt {{.*}} 'M'
-// CHECK-NEXT: DeclStmt
-// CHECK-NEXT: VarDecl {{.*}} j 'int'
-
-N: __attribute(()) ;
-// CHECK: LabelStmt {{.*}} 'N'
-// CHECK-NEXT: NullStmt
-}
-
-namespace Test {
-extern "C" int printf(const char *format, ...);
-// CHECK: FunctionDecl{{.*}}printf
-// CHECK-NEXT: ParmVarDecl{{.*}}format{{.*}}'const char *'
-// CHECK-NEXT: FormatAttr{{.*}}Implicit printf 1 2
-
-alignas(8) extern int x;
-extern int x;
-// CHECK: VarDecl{{.*}} x 'int'
-// CHECK: VarDecl{{.*}} x 'int'
-// CHECK-NEXT: AlignedAttr{{.*}} Inherited
-}
-
-int __attribute__((cdecl)) TestOne(void), TestTwo(void);
-// CHECK: FunctionDecl{{.*}}TestOne{{.*}}__attribute__((cdecl))
-// CHECK: FunctionDecl{{.*}}TestTwo{{.*}}__attribute__((cdecl))
-
-void func() {
- auto Test = []() __attribute__((no_thread_safety_analysis)) {};
- // CHECK: CXXMethodDecl{{.*}}operator() 'void () const'
- // CHECK: NoThreadSafetyAnalysisAttr
-
- // Because GNU's noreturn applies to the function type, and this lambda does
- // not have a capture list, the call operator and the function pointer
- // conversion should both be noreturn, but the method should not contain a
- // NoReturnAttr because the attribute applied to the type.
- auto Test2 = []() __attribute__((noreturn)) { while(1); };
- // CHECK: CXXMethodDecl{{.*}}operator() 'void () __attribute__((noreturn)) const'
- // CHECK-NOT: NoReturnAttr
- // CHECK: CXXConversionDecl{{.*}}operator void (*)() __attribute__((noreturn))
-}
-
-namespace PR20930 {
-struct S {
- struct { int Test __attribute__((deprecated)); };
- // CHECK: FieldDecl{{.*}}Test 'int'
- // CHECK-NEXT: DeprecatedAttr
-};
-
-void f() {
- S s;
- s.Test = 1;
- // CHECK: IndirectFieldDecl{{.*}}Test 'int'
- // CHECK: DeprecatedAttr
-}
-}
-
-struct __attribute__((objc_bridge_related(NSParagraphStyle,,))) TestBridgedRef;
-// CHECK: CXXRecordDecl{{.*}} struct TestBridgedRef
-// CHECK-NEXT: ObjCBridgeRelatedAttr{{.*}} NSParagraphStyle
-
-void TestExternalSourceSymbolAttr1()
-__attribute__((external_source_symbol(language="Swift", defined_in="module", generated_declaration)));
-// CHECK: FunctionDecl{{.*}} TestExternalSourceSymbolAttr1
-// CHECK-NEXT: ExternalSourceSymbolAttr{{.*}} "Swift" "module" GeneratedDeclaration
-
-void TestExternalSourceSymbolAttr2()
-__attribute__((external_source_symbol(defined_in="module", language="Swift")));
-// CHECK: FunctionDecl{{.*}} TestExternalSourceSymbolAttr2
-// CHECK-NEXT: ExternalSourceSymbolAttr{{.*}} "Swift" "module"{{$}}
-
-void TestExternalSourceSymbolAttr3()
-__attribute__((external_source_symbol(generated_declaration, language="Objective-C++", defined_in="module")));
-// CHECK: FunctionDecl{{.*}} TestExternalSourceSymbolAttr3
-// CHECK-NEXT: ExternalSourceSymbolAttr{{.*}} "Objective-C++" "module" GeneratedDeclaration
-
-void TestExternalSourceSymbolAttr4()
-__attribute__((external_source_symbol(defined_in="Some external file.cs", generated_declaration, language="C Sharp")));
-// CHECK: FunctionDecl{{.*}} TestExternalSourceSymbolAttr4
-// CHECK-NEXT: ExternalSourceSymbolAttr{{.*}} "C Sharp" "Some external file.cs" GeneratedDeclaration
-
-void TestExternalSourceSymbolAttr5()
-__attribute__((external_source_symbol(generated_declaration, defined_in="module", language="Swift")));
-// CHECK: FunctionDecl{{.*}} TestExternalSourceSymbolAttr5
-// CHECK-NEXT: ExternalSourceSymbolAttr{{.*}} "Swift" "module" GeneratedDeclaration
-
-namespace TestNoEscape {
- void noescapeFunc(int *p0, __attribute__((noescape)) int *p1) {}
- // CHECK: `-FunctionDecl{{.*}} noescapeFunc 'void (int *, __attribute__((noescape)) int *)'
- // CHECK-NEXT: ParmVarDecl
- // CHECK-NEXT: ParmVarDecl
- // CHECK-NEXT: NoEscapeAttr
-}
-
-namespace TestSuppress {
- [[gsl::suppress("at-namespace")]];
- // CHECK: NamespaceDecl{{.*}} TestSuppress
- // CHECK-NEXT: EmptyDecl{{.*}}
- // CHECK-NEXT: SuppressAttr{{.*}} at-namespace
- [[gsl::suppress("on-decl")]]
- void TestSuppressFunction();
- // CHECK: FunctionDecl{{.*}} TestSuppressFunction
- // CHECK-NEXT SuppressAttr{{.*}} on-decl
-
- void f() {
- int *i;
-
- [[gsl::suppress("on-stmt")]] {
- // CHECK: AttributedStmt
- // CHECK-NEXT: SuppressAttr{{.*}} on-stmt
- // CHECK-NEXT: CompoundStmt
- i = reinterpret_cast<int*>(7);
- }
- }
-}
+// RUN: %clang_cc1 -triple x86_64-pc-linux -std=c++11 -Wno-deprecated-declarations -ast-dump -ast-dump-filter Test %s | FileCheck --strict-whitespace %s + +int TestLocation +__attribute__((unused)); +// CHECK: VarDecl{{.*}}TestLocation +// CHECK-NEXT: UnusedAttr 0x{{[^ ]*}} <line:[[@LINE-2]]:16> + +int TestIndent +__attribute__((unused)); +// CHECK: {{^}}VarDecl{{.*TestIndent[^()]*$}} +// CHECK-NEXT: {{^}}`-UnusedAttr{{[^()]*$}} + +void TestAttributedStmt() { + switch (1) { + case 1: + [[clang::fallthrough]]; + case 2: + ; + } +} +// CHECK: FunctionDecl{{.*}}TestAttributedStmt +// CHECK: AttributedStmt +// CHECK-NEXT: FallThroughAttr +// CHECK-NEXT: NullStmt + +[[clang::warn_unused_result]] int TestCXX11DeclAttr(); +// CHECK: FunctionDecl{{.*}}TestCXX11DeclAttr +// CHECK-NEXT: WarnUnusedResultAttr + +int TestAlignedNull __attribute__((aligned)); +// CHECK: VarDecl{{.*}}TestAlignedNull +// CHECK-NEXT: AlignedAttr {{.*}} aligned +// CHECK-NEXT: <<<NULL>>> + +int TestAlignedExpr __attribute__((aligned(4))); +// CHECK: VarDecl{{.*}}TestAlignedExpr +// CHECK-NEXT: AlignedAttr {{.*}} aligned +// CHECK-NEXT: IntegerLiteral + +int TestEnum __attribute__((visibility("default"))); +// CHECK: VarDecl{{.*}}TestEnum +// CHECK-NEXT: VisibilityAttr{{.*}} Default + +class __attribute__((lockable)) Mutex { +} mu1, mu2; +int TestExpr __attribute__((guarded_by(mu1))); +// CHECK: VarDecl{{.*}}TestExpr +// CHECK-NEXT: GuardedByAttr +// CHECK-NEXT: DeclRefExpr{{.*}}mu1 + +class Mutex TestVariadicExpr __attribute__((acquired_after(mu1, mu2))); +// CHECK: VarDecl{{.*}}TestVariadicExpr +// CHECK: AcquiredAfterAttr +// CHECK-NEXT: DeclRefExpr{{.*}}mu1 +// CHECK-NEXT: DeclRefExpr{{.*}}mu2 + +void function1(void *) { + int TestFunction __attribute__((cleanup(function1))); +} +// CHECK: VarDecl{{.*}}TestFunction +// CHECK-NEXT: CleanupAttr{{.*}} Function{{.*}}function1 + +void TestIdentifier(void *, int) +__attribute__((pointer_with_type_tag(ident1,1,2))); +// CHECK: FunctionDecl{{.*}}TestIdentifier +// CHECK: ArgumentWithTypeTagAttr{{.*}} pointer_with_type_tag ident1 + +void TestBool(void *, int) +__attribute__((pointer_with_type_tag(bool1,1,2))); +// CHECK: FunctionDecl{{.*}}TestBool +// CHECK: ArgumentWithTypeTagAttr{{.*}}pointer_with_type_tag bool1 0 1 IsPointer + +void TestUnsigned(void *, int) +__attribute__((pointer_with_type_tag(unsigned1,1,2))); +// CHECK: FunctionDecl{{.*}}TestUnsigned +// CHECK: ArgumentWithTypeTagAttr{{.*}} pointer_with_type_tag unsigned1 0 1 + +void TestInt(void) __attribute__((constructor(123))); +// CHECK: FunctionDecl{{.*}}TestInt +// CHECK-NEXT: ConstructorAttr{{.*}} 123 + +static int TestString __attribute__((alias("alias1"))); +// CHECK: VarDecl{{.*}}TestString +// CHECK-NEXT: AliasAttr{{.*}} "alias1" + +extern struct s1 TestType +__attribute__((type_tag_for_datatype(ident1,int))); +// CHECK: VarDecl{{.*}}TestType +// CHECK-NEXT: TypeTagForDatatypeAttr{{.*}} int + +void TestLabel() { +L: __attribute__((unused)) int i; +// CHECK: LabelStmt{{.*}}'L' +// CHECK: VarDecl{{.*}}i 'int' +// CHECK-NEXT: UnusedAttr{{.*}} + +M: __attribute(()) int j; +// CHECK: LabelStmt {{.*}} 'M' +// CHECK-NEXT: DeclStmt +// CHECK-NEXT: VarDecl {{.*}} j 'int' + +N: __attribute(()) ; +// CHECK: LabelStmt {{.*}} 'N' +// CHECK-NEXT: NullStmt +} + +namespace Test { +extern "C" int printf(const char *format, ...); +// CHECK: FunctionDecl{{.*}}printf +// CHECK-NEXT: ParmVarDecl{{.*}}format{{.*}}'const char *' +// CHECK-NEXT: FormatAttr{{.*}}Implicit printf 1 2 + +alignas(8) extern int x; +extern int x; +// CHECK: VarDecl{{.*}} x 'int' +// CHECK: VarDecl{{.*}} x 'int' +// CHECK-NEXT: AlignedAttr{{.*}} Inherited +} + +int __attribute__((cdecl)) TestOne(void), TestTwo(void); +// CHECK: FunctionDecl{{.*}}TestOne{{.*}}__attribute__((cdecl)) +// CHECK: FunctionDecl{{.*}}TestTwo{{.*}}__attribute__((cdecl)) + +void func() { + auto Test = []() __attribute__((no_thread_safety_analysis)) {}; + // CHECK: CXXMethodDecl{{.*}}operator() 'void (void) const' + // CHECK: NoThreadSafetyAnalysisAttr + + // Because GNU's noreturn applies to the function type, and this lambda does + // not have a capture list, the call operator and the function pointer + // conversion should both be noreturn, but the method should not contain a + // NoReturnAttr because the attribute applied to the type. + auto Test2 = []() __attribute__((noreturn)) { while(1); }; + // CHECK: CXXMethodDecl{{.*}}operator() 'void (void) __attribute__((noreturn)) const' + // CHECK-NOT: NoReturnAttr + // CHECK: CXXConversionDecl{{.*}}operator void (*)() __attribute__((noreturn)) +} + +namespace PR20930 { +struct S { + struct { int Test __attribute__((deprecated)); }; + // CHECK: FieldDecl{{.*}}Test 'int' + // CHECK-NEXT: DeprecatedAttr +}; + +void f() { + S s; + s.Test = 1; + // CHECK: IndirectFieldDecl{{.*}}Test 'int' + // CHECK: DeprecatedAttr +} +} + +struct __attribute__((objc_bridge_related(NSParagraphStyle,,))) TestBridgedRef; +// CHECK: CXXRecordDecl{{.*}} struct TestBridgedRef +// CHECK-NEXT: ObjCBridgeRelatedAttr{{.*}} NSParagraphStyle + +void TestExternalSourceSymbolAttr1() +__attribute__((external_source_symbol(language="Swift", defined_in="module", generated_declaration))); +// CHECK: FunctionDecl{{.*}} TestExternalSourceSymbolAttr1 +// CHECK-NEXT: ExternalSourceSymbolAttr{{.*}} "Swift" "module" GeneratedDeclaration + +void TestExternalSourceSymbolAttr2() +__attribute__((external_source_symbol(defined_in="module", language="Swift"))); +// CHECK: FunctionDecl{{.*}} TestExternalSourceSymbolAttr2 +// CHECK-NEXT: ExternalSourceSymbolAttr{{.*}} "Swift" "module"{{$}} + +void TestExternalSourceSymbolAttr3() +__attribute__((external_source_symbol(generated_declaration, language="Objective-C++", defined_in="module"))); +// CHECK: FunctionDecl{{.*}} TestExternalSourceSymbolAttr3 +// CHECK-NEXT: ExternalSourceSymbolAttr{{.*}} "Objective-C++" "module" GeneratedDeclaration + +void TestExternalSourceSymbolAttr4() +__attribute__((external_source_symbol(defined_in="Some external file.cs", generated_declaration, language="C Sharp"))); +// CHECK: FunctionDecl{{.*}} TestExternalSourceSymbolAttr4 +// CHECK-NEXT: ExternalSourceSymbolAttr{{.*}} "C Sharp" "Some external file.cs" GeneratedDeclaration + +void TestExternalSourceSymbolAttr5() +__attribute__((external_source_symbol(generated_declaration, defined_in="module", language="Swift"))); +// CHECK: FunctionDecl{{.*}} TestExternalSourceSymbolAttr5 +// CHECK-NEXT: ExternalSourceSymbolAttr{{.*}} "Swift" "module" GeneratedDeclaration + +namespace TestNoEscape { + void noescapeFunc(int *p0, __attribute__((noescape)) int *p1) {} + // CHECK: `-FunctionDecl{{.*}} noescapeFunc 'void (int *, __attribute__((noescape)) int *)' + // CHECK-NEXT: ParmVarDecl + // CHECK-NEXT: ParmVarDecl + // CHECK-NEXT: NoEscapeAttr +} + +namespace TestSuppress { + [[gsl::suppress("at-namespace")]]; + // CHECK: NamespaceDecl{{.*}} TestSuppress + // CHECK-NEXT: EmptyDecl{{.*}} + // CHECK-NEXT: SuppressAttr{{.*}} at-namespace + [[gsl::suppress("on-decl")]] + void TestSuppressFunction(); + // CHECK: FunctionDecl{{.*}} TestSuppressFunction + // CHECK-NEXT SuppressAttr{{.*}} on-decl + + void f() { + int *i; + + [[gsl::suppress("on-stmt")]] { + // CHECK: AttributedStmt + // CHECK-NEXT: SuppressAttr{{.*}} on-stmt + // CHECK-NEXT: CompoundStmt + i = reinterpret_cast<int*>(7); + } + } +} diff --git a/clang/test/Misc/ast-dump-color.cpp b/clang/test/Misc/ast-dump-color.cpp index bc01d4932f7..631bc05f228 100644 --- a/clang/test/Misc/ast-dump-color.cpp +++ b/clang/test/Misc/ast-dump-color.cpp @@ -43,7 +43,7 @@ struct Invalid { //CHECK: {{^}}[[Blue]]| |-[[RESET]][[Blue]]HTMLEndTagComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:13[[RESET]], [[Yellow]]col:16[[RESET]]> Name="a"{{$}} //CHECK: {{^}}[[Blue]]| |-[[RESET]][[Blue]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:5:4[[RESET]]> Text=" "{{$}} //CHECK: {{^}}[[Blue]]| `-[[RESET]][[Blue]]HTMLStartTagComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:5[[RESET]], [[Yellow]]col:8[[RESET]]> Name="br" SelfClosing{{$}} -//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]FunctionDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:9:1[[RESET]], [[Yellow]]line:16:1[[RESET]]> [[Yellow]]line:9:6[[RESET]][[CYAN]] TestAttributedStmt[[RESET]] [[Green]]'void (void)'[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]FunctionDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:9:1[[RESET]], [[Yellow]]line:16:1[[RESET]]> [[Yellow]]line:9:6[[RESET]][[CYAN]] TestAttributedStmt[[RESET]] [[Green]]'void ()'[[RESET]]{{$}} //CHECK: {{^}}[[Blue]]| |-[[RESET]][[MAGENTA:.\[0;1;35m]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:27[[RESET]], [[Yellow]]line:16:1[[RESET]]>{{$}} //CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]SwitchStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:10:3[[RESET]], [[Yellow]]line:15:3[[RESET]]>{{$}} //CHECK: {{^}}[[Blue]]| | |-[[RESET]][[Blue:.\[0;34m]]<<<NULL>>>[[RESET]]{{$}} diff --git a/clang/test/Misc/ast-dump-decl.cpp b/clang/test/Misc/ast-dump-decl.cpp index c689149af06..0df8a5a2b8f 100644 --- a/clang/test/Misc/ast-dump-decl.cpp +++ b/clang/test/Misc/ast-dump-decl.cpp @@ -1,539 +1,539 @@ -// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -fms-extensions -ast-dump -ast-dump-filter Test %s | FileCheck -strict-whitespace %s
-
-class testEnumDecl {
- enum class TestEnumDeclScoped;
- enum TestEnumDeclFixed : int;
-};
-// CHECK: EnumDecl{{.*}} class TestEnumDeclScoped 'int'
-// CHECK: EnumDecl{{.*}} TestEnumDeclFixed 'int'
-
-class testFieldDecl {
- int TestFieldDeclInit = 0;
-};
-// CHECK: FieldDecl{{.*}} TestFieldDeclInit 'int'
-// CHECK-NEXT: IntegerLiteral
-
-namespace testVarDeclNRVO {
- class A { };
- A foo() {
- A TestVarDeclNRVO;
- return TestVarDeclNRVO;
- }
-}
-// CHECK: VarDecl{{.*}} TestVarDeclNRVO 'testVarDeclNRVO::A' nrvo
-
-void testParmVarDeclInit(int TestParmVarDeclInit = 0);
-// CHECK: ParmVarDecl{{.*}} TestParmVarDeclInit 'int'
-// CHECK-NEXT: IntegerLiteral{{.*}}
-
-namespace TestNamespaceDecl {
- int i;
-}
-// CHECK: NamespaceDecl{{.*}} TestNamespaceDecl
-// CHECK-NEXT: VarDecl
-
-namespace TestNamespaceDecl {
- int j;
-}
-// CHECK: NamespaceDecl{{.*}} TestNamespaceDecl
-// CHECK-NEXT: original Namespace
-// CHECK-NEXT: VarDecl
-
-inline namespace TestNamespaceDeclInline {
-}
-// CHECK: NamespaceDecl{{.*}} TestNamespaceDeclInline inline
-
-namespace testUsingDirectiveDecl {
- namespace A {
- }
-}
-namespace TestUsingDirectiveDecl {
- using namespace testUsingDirectiveDecl::A;
-}
-// CHECK: NamespaceDecl{{.*}} TestUsingDirectiveDecl
-// CHECK-NEXT: UsingDirectiveDecl{{.*}} Namespace{{.*}} 'A'
-
-namespace testNamespaceAlias {
- namespace A {
- }
-}
-namespace TestNamespaceAlias = testNamespaceAlias::A;
-// CHECK: NamespaceAliasDecl{{.*}} TestNamespaceAlias
-// CHECK-NEXT: Namespace{{.*}} 'A'
-
-using TestTypeAliasDecl = int;
-// CHECK: TypeAliasDecl{{.*}} TestTypeAliasDecl 'int'
-
-namespace testTypeAliasTemplateDecl {
- template<typename T> class A;
- template<typename T> using TestTypeAliasTemplateDecl = A<T>;
-}
-// CHECK: TypeAliasTemplateDecl{{.*}} TestTypeAliasTemplateDecl
-// CHECK-NEXT: TemplateTypeParmDecl
-// CHECK-NEXT: TypeAliasDecl{{.*}} TestTypeAliasTemplateDecl 'A<T>'
-
-namespace testCXXRecordDecl {
- class TestEmpty {};
-// CHECK: CXXRecordDecl{{.*}} class TestEmpty
-// CHECK-NEXT: DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
-// CHECK-NEXT: DefaultConstructor exists trivial constexpr
-// CHECK-NEXT: CopyConstructor simple trivial has_const_param
-// CHECK-NEXT: MoveConstructor exists simple trivial
-// CHECK-NEXT: CopyAssignment trivial has_const_param
-// CHECK-NEXT: MoveAssignment exists simple trivial
-// CHECK-NEXT: Destructor simple irrelevant trivial
-
- class A { };
- class B { };
- class TestCXXRecordDecl : virtual A, public B {
- int i;
- };
-}
-// CHECK: CXXRecordDecl{{.*}} class TestCXXRecordDecl
-// CHECK-NEXT: DefinitionData{{$}}
-// CHECK-NEXT: DefaultConstructor exists non_trivial
-// CHECK-NEXT: CopyConstructor simple non_trivial has_const_param
-// CHECK-NEXT: MoveConstructor exists simple non_trivial
-// CHECK-NEXT: CopyAssignment non_trivial has_const_param
-// CHECK-NEXT: MoveAssignment exists simple non_trivial
-// CHECK-NEXT: Destructor simple irrelevant trivial
-// CHECK-NEXT: virtual private 'testCXXRecordDecl::A'
-// CHECK-NEXT: public 'testCXXRecordDecl::B'
-// CHECK-NEXT: CXXRecordDecl{{.*}} class TestCXXRecordDecl
-// CHECK-NEXT: FieldDecl
-
-template<class...T>
-class TestCXXRecordDeclPack : public T... {
-};
-// CHECK: CXXRecordDecl{{.*}} class TestCXXRecordDeclPack
-// CHECK: public 'T'...
-// CHECK-NEXT: CXXRecordDecl{{.*}} class TestCXXRecordDeclPack
-
-thread_local int TestThreadLocalInt;
-// CHECK: TestThreadLocalInt {{.*}} tls_dynamic
-
-class testCXXMethodDecl {
- virtual void TestCXXMethodDeclPure() = 0;
- void TestCXXMethodDeclDelete() = delete;
- void TestCXXMethodDeclThrow() throw();
- void TestCXXMethodDeclThrowType() throw(int);
-};
-// CHECK: CXXMethodDecl{{.*}} TestCXXMethodDeclPure 'void ()' virtual pure
-// CHECK: CXXMethodDecl{{.*}} TestCXXMethodDeclDelete 'void ()' delete
-// CHECK: CXXMethodDecl{{.*}} TestCXXMethodDeclThrow 'void () throw()'
-// CHECK: CXXMethodDecl{{.*}} TestCXXMethodDeclThrowType 'void () throw(int)'
-
-namespace testCXXConstructorDecl {
- class A { };
- class TestCXXConstructorDecl : public A {
- int I;
- TestCXXConstructorDecl(A &a, int i) : A(a), I(i) { }
- TestCXXConstructorDecl(A &a) : TestCXXConstructorDecl(a, 0) { }
- };
-}
-// CHECK: CXXConstructorDecl{{.*}} TestCXXConstructorDecl 'void {{.*}}'
-// CHECK-NEXT: ParmVarDecl{{.*}} a
-// CHECK-NEXT: ParmVarDecl{{.*}} i
-// CHECK-NEXT: CXXCtorInitializer{{.*}}A
-// CHECK-NEXT: Expr
-// CHECK: CXXCtorInitializer{{.*}}I
-// CHECK-NEXT: Expr
-// CHECK: CompoundStmt
-// CHECK: CXXConstructorDecl{{.*}} TestCXXConstructorDecl 'void {{.*}}'
-// CHECK-NEXT: ParmVarDecl{{.*}} a
-// CHECK-NEXT: CXXCtorInitializer{{.*}}TestCXXConstructorDecl
-// CHECK-NEXT: CXXConstructExpr{{.*}}TestCXXConstructorDecl
-
-class TestCXXDestructorDecl {
- ~TestCXXDestructorDecl() { }
-};
-// CHECK: CXXDestructorDecl{{.*}} ~TestCXXDestructorDecl 'void () noexcept'
-// CHECK-NEXT: CompoundStmt
-
-// Test that the range of a defaulted members is computed correctly.
-class TestMemberRanges {
-public:
- TestMemberRanges() = default;
- TestMemberRanges(const TestMemberRanges &Other) = default;
- TestMemberRanges(TestMemberRanges &&Other) = default;
- ~TestMemberRanges() = default;
- TestMemberRanges &operator=(const TestMemberRanges &Other) = default;
- TestMemberRanges &operator=(TestMemberRanges &&Other) = default;
-};
-void SomeFunction() {
- TestMemberRanges A;
- TestMemberRanges B(A);
- B = A;
- A = static_cast<TestMemberRanges &&>(B);
- TestMemberRanges C(static_cast<TestMemberRanges &&>(A));
-}
-// CHECK: CXXConstructorDecl{{.*}} <line:{{.*}}:3, col:30>
-// CHECK: CXXConstructorDecl{{.*}} <line:{{.*}}:3, col:59>
-// CHECK: CXXConstructorDecl{{.*}} <line:{{.*}}:3, col:54>
-// CHECK: CXXDestructorDecl{{.*}} <line:{{.*}}:3, col:31>
-// CHECK: CXXMethodDecl{{.*}} <line:{{.*}}:3, col:70>
-// CHECK: CXXMethodDecl{{.*}} <line:{{.*}}:3, col:65>
-
-class TestCXXConversionDecl {
- operator int() { return 0; }
-};
-// CHECK: CXXConversionDecl{{.*}} operator int 'int ()'
-// CHECK-NEXT: CompoundStmt
-
-namespace TestStaticAssertDecl {
- static_assert(true, "msg");
-}
-// CHECK: NamespaceDecl{{.*}} TestStaticAssertDecl
-// CHECK-NEXT: StaticAssertDecl{{.*> .*$}}
-// CHECK-NEXT: CXXBoolLiteralExpr
-// CHECK-NEXT: StringLiteral
-
-namespace testFunctionTemplateDecl {
- class A { };
- class B { };
- class C { };
- class D { };
- template<typename T> void TestFunctionTemplate(T) { }
-
- // implicit instantiation
- void bar(A a) { TestFunctionTemplate(a); }
-
- // explicit specialization
- template<> void TestFunctionTemplate(B);
-
- // explicit instantiation declaration
- extern template void TestFunctionTemplate(C);
-
- // explicit instantiation definition
- template void TestFunctionTemplate(D);
-}
-// CHECK: FunctionTemplateDecl{{.*}} TestFunctionTemplate
-// CHECK-NEXT: TemplateTypeParmDecl
-// CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate 'void (T)'
-// CHECK-NEXT: ParmVarDecl{{.*}} 'T'
-// CHECK-NEXT: CompoundStmt
-// CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate {{.*}}A
-// CHECK-NEXT: TemplateArgument
-// CHECK-NEXT: ParmVarDecl
-// CHECK-NEXT: CompoundStmt
-// CHECK-NEXT: Function{{.*}} 'TestFunctionTemplate' {{.*}}B
-// CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate {{.*}}C
-// CHECK-NEXT: TemplateArgument
-// CHECK-NEXT: ParmVarDecl
-// CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate {{.*}}D
-// CHECK-NEXT: TemplateArgument
-// CHECK-NEXT: ParmVarDecl
-// CHECK-NEXT: CompoundStmt
-// CHECK: FunctionDecl{{.*}} TestFunctionTemplate {{.*}}B
-// CHECK-NEXT: TemplateArgument
-// CHECK-NEXT: ParmVarDecl
-
-namespace testClassTemplateDecl {
- class A { };
- class B { };
- class C { };
- class D { };
-
- template<typename T> class TestClassTemplate {
- public:
- TestClassTemplate();
- ~TestClassTemplate();
- int j();
- int i;
- };
-
- // implicit instantiation
- TestClassTemplate<A> a;
-
- // explicit specialization
- template<> class TestClassTemplate<B> {
- int j;
- };
-
- // explicit instantiation declaration
- extern template class TestClassTemplate<C>;
-
- // explicit instantiation definition
- template class TestClassTemplate<D>;
-
- // partial explicit specialization
- template<typename T1, typename T2> class TestClassTemplatePartial {
- int i;
- };
- template<typename T1> class TestClassTemplatePartial<T1, A> {
- int j;
- };
-}
-// CHECK: ClassTemplateDecl{{.*}} TestClassTemplate
-// CHECK-NEXT: TemplateTypeParmDecl
-// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
-// CHECK: CXXRecordDecl{{.*}} class TestClassTemplate
-// CHECK-NEXT: AccessSpecDecl{{.*}} public
-// CHECK-NEXT: CXXConstructorDecl{{.*}} <line:{{.*}}:5, col:23>
-// CHECK-NEXT: CXXDestructorDecl{{.*}} <line:{{.*}}:5, col:24>
-// CHECK-NEXT: CXXMethodDecl{{.*}} <line:{{.*}}:5, col:11>
-// CHECK-NEXT: FieldDecl{{.*}} i
-// CHECK-NEXT: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate
-// CHECK: TemplateArgument{{.*}}A
-// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
-// CHECK-NEXT: AccessSpecDecl{{.*}} public
-// CHECK-NEXT: CXXConstructorDecl{{.*}} <line:{{.*}}:5, col:23>
-// CHECK-NEXT: CXXDestructorDecl{{.*}} <line:{{.*}}:5, col:24>
-// CHECK-NEXT: CXXMethodDecl{{.*}} <line:{{.*}}:5, col:11>
-// CHECK-NEXT: FieldDecl{{.*}} i
-// CHECK: ClassTemplateSpecialization{{.*}} 'TestClassTemplate'
-// CHECK-NEXT: ClassTemplateSpecialization{{.*}} 'TestClassTemplate'
-// CHECK-NEXT: ClassTemplateSpecialization{{.*}} 'TestClassTemplate'
-
-// CHECK: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate
-// CHECK-NEXT: DefinitionData
-// CHECK: TemplateArgument{{.*}}B
-// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
-// CHECK-NEXT: FieldDecl{{.*}} j
-
-// CHECK: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate
-// CHECK: TemplateArgument{{.*}}C
-// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
-// CHECK-NEXT: AccessSpecDecl{{.*}} public
-// CHECK-NEXT: CXXConstructorDecl{{.*}} <line:{{.*}}:5, col:23>
-// CHECK-NEXT: CXXDestructorDecl{{.*}} <line:{{.*}}:5, col:24>
-// CHECK-NEXT: CXXMethodDecl{{.*}} <line:{{.*}}:5, col:11>
-// CHECK-NEXT: FieldDecl{{.*}} i
-
-// CHECK: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate
-// CHECK: TemplateArgument{{.*}}D
-// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
-// CHECK-NEXT: AccessSpecDecl{{.*}} public
-// CHECK-NEXT: CXXConstructorDecl{{.*}} <line:{{.*}}:5, col:23>
-// CHECK-NEXT: CXXDestructorDecl{{.*}} <line:{{.*}}:5, col:24>
-// CHECK-NEXT: CXXMethodDecl{{.*}} <line:{{.*}}:5, col:11>
-// CHECK-NEXT: FieldDecl{{.*}} i
-
-// CHECK: ClassTemplatePartialSpecializationDecl{{.*}} class TestClassTemplatePartial
-// CHECK: TemplateArgument
-// CHECK-NEXT: TemplateArgument{{.*}}A
-// CHECK-NEXT: TemplateTypeParmDecl
-// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplatePartial
-// CHECK-NEXT: FieldDecl{{.*}} j
-
-// PR15220 dump instantiation only once
-namespace testCanonicalTemplate {
- class A {};
-
- template<typename T> void TestFunctionTemplate(T);
- template<typename T> void TestFunctionTemplate(T);
- void bar(A a) { TestFunctionTemplate(a); }
- // CHECK: FunctionTemplateDecl{{.*}} TestFunctionTemplate
- // CHECK-NEXT: TemplateTypeParmDecl
- // CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate 'void (T)'
- // CHECK-NEXT: ParmVarDecl{{.*}} 'T'
- // CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate {{.*}}A
- // CHECK-NEXT: TemplateArgument
- // CHECK-NEXT: ParmVarDecl
- // CHECK: FunctionTemplateDecl{{.*}} TestFunctionTemplate
- // CHECK-NEXT: TemplateTypeParmDecl
- // CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate 'void (T)'
- // CHECK-NEXT: ParmVarDecl{{.*}} 'T'
- // CHECK-NEXT: Function{{.*}} 'TestFunctionTemplate'
- // CHECK-NOT: TemplateArgument
-
- template<typename T1> class TestClassTemplate {
- template<typename T2> friend class TestClassTemplate;
- };
- TestClassTemplate<A> a;
- // CHECK: ClassTemplateDecl{{.*}} TestClassTemplate
- // CHECK-NEXT: TemplateTypeParmDecl
- // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
- // CHECK: CXXRecordDecl{{.*}} class TestClassTemplate
- // CHECK-NEXT: FriendDecl
- // CHECK-NEXT: ClassTemplateDecl{{.*}} TestClassTemplate
- // CHECK-NEXT: TemplateTypeParmDecl
- // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
- // CHECK-NEXT: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate
- // CHECK: TemplateArgument{{.*}}A
- // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate
-}
-
-template <class T>
-class TestClassScopeFunctionSpecialization {
- template<class U> void foo(U a) { }
- template<> void foo<int>(int a) { }
-};
-// CHECK: ClassScopeFunctionSpecializationDecl
-// CHECK-NEXT: CXXMethod{{.*}} 'foo' 'void (int)'
-// CHECK-NEXT: TemplateArgument{{.*}} 'int'
-
-namespace TestTemplateTypeParmDecl {
- template<typename ... T, class U = int> void foo();
-}
-// CHECK: NamespaceDecl{{.*}} TestTemplateTypeParmDecl
-// CHECK-NEXT: FunctionTemplateDecl
-// CHECK-NEXT: TemplateTypeParmDecl{{.*}} typename depth 0 index 0 ... T
-// CHECK-NEXT: TemplateTypeParmDecl{{.*}} class depth 0 index 1 U
-// CHECK-NEXT: TemplateArgument type 'int'
-
-namespace TestNonTypeTemplateParmDecl {
- template<int I = 1, int ... J> void foo();
-}
-// CHECK: NamespaceDecl{{.*}} TestNonTypeTemplateParmDecl
-// CHECK-NEXT: FunctionTemplateDecl
-// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} 'int' depth 0 index 0 I
-// CHECK-NEXT: TemplateArgument expr
-// CHECK-NEXT: IntegerLiteral{{.*}} 'int' 1
-// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} 'int' depth 0 index 1 ... J
-
-namespace TestTemplateTemplateParmDecl {
- template<typename T> class A;
- template <template <typename> class T = A, template <typename> class ... U> void foo();
-}
-// CHECK: NamespaceDecl{{.*}} TestTemplateTemplateParmDecl
-// CHECK: FunctionTemplateDecl
-// CHECK-NEXT: TemplateTemplateParmDecl{{.*}} T
-// CHECK-NEXT: TemplateTypeParmDecl{{.*}} typename
-// CHECK-NEXT: TemplateArgument{{.*}} template A
-// CHECK-NEXT: TemplateTemplateParmDecl{{.*}} ... U
-// CHECK-NEXT: TemplateTypeParmDecl{{.*}} typename
-
-namespace TestTemplateArgument {
- template<typename> class A { };
- template<template<typename> class ...> class B { };
- int foo();
-
- template<typename> class testType { };
- template class testType<int>;
- // CHECK: ClassTemplateSpecializationDecl{{.*}} class testType
- // CHECK: TemplateArgument{{.*}} type 'int'
-
- template<int fp(void)> class testDecl { };
- template class testDecl<foo>;
- // CHECK: ClassTemplateSpecializationDecl{{.*}} class testDecl
- // CHECK: TemplateArgument{{.*}} decl
- // CHECK-NEXT: Function{{.*}}foo
-
- template class testDecl<nullptr>;
- // CHECK: ClassTemplateSpecializationDecl{{.*}} class testDecl
- // CHECK: TemplateArgument{{.*}} nullptr
-
- template<int> class testIntegral { };
- template class testIntegral<1>;
- // CHECK: ClassTemplateSpecializationDecl{{.*}} class testIntegral
- // CHECK: TemplateArgument{{.*}} integral 1
-
- template<template<typename> class> class testTemplate { };
- template class testTemplate<A>;
- // CHECK: ClassTemplateSpecializationDecl{{.*}} class testTemplate
- // CHECK: TemplateArgument{{.*}} A
-
- template<template<typename> class ...T> class C {
- B<T...> testTemplateExpansion;
- };
- // FIXME: Need TemplateSpecializationType dumping to test TemplateExpansion.
-
- template<int, int = 0> class testExpr;
- template<int I> class testExpr<I> { };
- // CHECK: ClassTemplatePartialSpecializationDecl{{.*}} class testExpr
- // CHECK: TemplateArgument{{.*}} expr
- // CHECK-NEXT: DeclRefExpr{{.*}}I
-
- template<int, int ...> class testPack { };
- template class testPack<0, 1, 2>;
- // CHECK: ClassTemplateSpecializationDecl{{.*}} class testPack
- // CHECK: TemplateArgument{{.*}} integral 0
- // CHECK-NEXT: TemplateArgument{{.*}} pack
- // CHECK-NEXT: TemplateArgument{{.*}} integral 1
- // CHECK-NEXT: TemplateArgument{{.*}} integral 2
-}
-
-namespace testUsingDecl {
- int i;
-}
-namespace TestUsingDecl {
- using testUsingDecl::i;
-}
-// CHECK: NamespaceDecl{{.*}} TestUsingDecl
-// CHECK-NEXT: UsingDecl{{.*}} testUsingDecl::i
-// CHECK-NEXT: UsingShadowDecl{{.*}} Var{{.*}} 'i' 'int'
-
-namespace testUnresolvedUsing {
- class A { };
- template<class T> class B {
- public:
- A a;
- };
- template<class T> class TestUnresolvedUsing : public B<T> {
- using typename B<T>::a;
- using B<T>::a;
- };
-}
-// CHECK: CXXRecordDecl{{.*}} TestUnresolvedUsing
-// CHECK: UnresolvedUsingTypenameDecl{{.*}} B<T>::a
-// CHECK: UnresolvedUsingValueDecl{{.*}} B<T>::a
-
-namespace TestLinkageSpecDecl {
- extern "C" void test1();
- extern "C++" void test2();
-}
-// CHECK: NamespaceDecl{{.*}} TestLinkageSpecDecl
-// CHECK-NEXT: LinkageSpecDecl{{.*}} C
-// CHECK-NEXT: FunctionDecl
-// CHECK-NEXT: LinkageSpecDecl{{.*}} C++
-// CHECK-NEXT: FunctionDecl
-
-class TestAccessSpecDecl {
-public:
-private:
-protected:
-};
-// CHECK: CXXRecordDecl{{.*}} class TestAccessSpecDecl
-// CHECK: CXXRecordDecl{{.*}} class TestAccessSpecDecl
-// CHECK-NEXT: AccessSpecDecl{{.*}} public
-// CHECK-NEXT: AccessSpecDecl{{.*}} private
-// CHECK-NEXT: AccessSpecDecl{{.*}} protected
-
-template<typename T> class TestFriendDecl {
- friend int foo();
- friend class A;
- friend T;
-};
-// CHECK: CXXRecord{{.*}} TestFriendDecl
-// CHECK: CXXRecord{{.*}} TestFriendDecl
-// CHECK-NEXT: FriendDecl
-// CHECK-NEXT: FunctionDecl{{.*}} foo
-// CHECK-NEXT: FriendDecl{{.*}} 'class A':'A'
-// CHECK-NEXT: FriendDecl{{.*}} 'T'
-
-namespace TestFileScopeAsmDecl {
- asm("ret");
-}
-// CHECK: NamespaceDecl{{.*}} TestFileScopeAsmDecl{{$}}
-// CHECK: FileScopeAsmDecl{{.*> .*$}}
-// CHECK-NEXT: StringLiteral
-
-namespace TestFriendDecl2 {
- void f();
- struct S {
- friend void f();
- };
-}
-// CHECK: NamespaceDecl [[TestFriendDecl2:0x.*]] <{{.*}}> {{.*}} TestFriendDecl2
-// CHECK: |-FunctionDecl [[TestFriendDecl2_f:0x.*]] <{{.*}}> {{.*}} f 'void ()'
-// CHECK: `-CXXRecordDecl {{.*}} struct S
-// CHECK: |-CXXRecordDecl {{.*}} struct S
-// CHECK: `-FriendDecl
-// CHECK: `-FunctionDecl {{.*}} parent [[TestFriendDecl2]] prev [[TestFriendDecl2_f]] <{{.*}}> {{.*}} f 'void ()'
-
-namespace Comment {
- extern int Test;
- /// Something here.
- extern int Test;
- extern int Test;
-}
-
-// CHECK: VarDecl {{.*}} Test 'int' extern
-// CHECK-NOT: FullComment
-// CHECK: VarDecl {{.*}} Test 'int' extern
-// CHECK: `-FullComment
-// CHECK: `-ParagraphComment
-// CHECK: `-TextComment
-// CHECK: VarDecl {{.*}} Test 'int' extern
-// CHECK-NOT: FullComment
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -fms-extensions -ast-dump -ast-dump-filter Test %s | FileCheck -strict-whitespace %s + +class testEnumDecl { + enum class TestEnumDeclScoped; + enum TestEnumDeclFixed : int; +}; +// CHECK: EnumDecl{{.*}} class TestEnumDeclScoped 'int' +// CHECK: EnumDecl{{.*}} TestEnumDeclFixed 'int' + +class testFieldDecl { + int TestFieldDeclInit = 0; +}; +// CHECK: FieldDecl{{.*}} TestFieldDeclInit 'int' +// CHECK-NEXT: IntegerLiteral + +namespace testVarDeclNRVO { + class A { }; + A foo() { + A TestVarDeclNRVO; + return TestVarDeclNRVO; + } +} +// CHECK: VarDecl{{.*}} TestVarDeclNRVO 'class testVarDeclNRVO::A' nrvo + +void testParmVarDeclInit(int TestParmVarDeclInit = 0); +// CHECK: ParmVarDecl{{.*}} TestParmVarDeclInit 'int' +// CHECK-NEXT: IntegerLiteral{{.*}} + +namespace TestNamespaceDecl { + int i; +} +// CHECK: NamespaceDecl{{.*}} TestNamespaceDecl +// CHECK-NEXT: VarDecl + +namespace TestNamespaceDecl { + int j; +} +// CHECK: NamespaceDecl{{.*}} TestNamespaceDecl +// CHECK-NEXT: original Namespace +// CHECK-NEXT: VarDecl + +inline namespace TestNamespaceDeclInline { +} +// CHECK: NamespaceDecl{{.*}} TestNamespaceDeclInline inline + +namespace testUsingDirectiveDecl { + namespace A { + } +} +namespace TestUsingDirectiveDecl { + using namespace testUsingDirectiveDecl::A; +} +// CHECK: NamespaceDecl{{.*}} TestUsingDirectiveDecl +// CHECK-NEXT: UsingDirectiveDecl{{.*}} Namespace{{.*}} 'A' + +namespace testNamespaceAlias { + namespace A { + } +} +namespace TestNamespaceAlias = testNamespaceAlias::A; +// CHECK: NamespaceAliasDecl{{.*}} TestNamespaceAlias +// CHECK-NEXT: Namespace{{.*}} 'A' + +using TestTypeAliasDecl = int; +// CHECK: TypeAliasDecl{{.*}} TestTypeAliasDecl 'int' + +namespace testTypeAliasTemplateDecl { + template<typename T> class A; + template<typename T> using TestTypeAliasTemplateDecl = A<T>; +} +// CHECK: TypeAliasTemplateDecl{{.*}} TestTypeAliasTemplateDecl +// CHECK-NEXT: TemplateTypeParmDecl +// CHECK-NEXT: TypeAliasDecl{{.*}} TestTypeAliasTemplateDecl 'A<T>' + +namespace testCXXRecordDecl { + class TestEmpty {}; +// CHECK: CXXRecordDecl{{.*}} class TestEmpty +// CHECK-NEXT: DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init +// CHECK-NEXT: DefaultConstructor exists trivial constexpr +// CHECK-NEXT: CopyConstructor simple trivial has_const_param +// CHECK-NEXT: MoveConstructor exists simple trivial +// CHECK-NEXT: CopyAssignment trivial has_const_param +// CHECK-NEXT: MoveAssignment exists simple trivial +// CHECK-NEXT: Destructor simple irrelevant trivial + + class A { }; + class B { }; + class TestCXXRecordDecl : virtual A, public B { + int i; + }; +} +// CHECK: CXXRecordDecl{{.*}} class TestCXXRecordDecl +// CHECK-NEXT: DefinitionData{{$}} +// CHECK-NEXT: DefaultConstructor exists non_trivial +// CHECK-NEXT: CopyConstructor simple non_trivial has_const_param +// CHECK-NEXT: MoveConstructor exists simple non_trivial +// CHECK-NEXT: CopyAssignment non_trivial has_const_param +// CHECK-NEXT: MoveAssignment exists simple non_trivial +// CHECK-NEXT: Destructor simple irrelevant trivial +// CHECK-NEXT: virtual private 'class testCXXRecordDecl::A' +// CHECK-NEXT: public 'class testCXXRecordDecl::B' +// CHECK-NEXT: CXXRecordDecl{{.*}} class TestCXXRecordDecl +// CHECK-NEXT: FieldDecl + +template<class...T> +class TestCXXRecordDeclPack : public T... { +}; +// CHECK: CXXRecordDecl{{.*}} class TestCXXRecordDeclPack +// CHECK: public 'T'... +// CHECK-NEXT: CXXRecordDecl{{.*}} class TestCXXRecordDeclPack + +thread_local int TestThreadLocalInt; +// CHECK: TestThreadLocalInt {{.*}} tls_dynamic + +class testCXXMethodDecl { + virtual void TestCXXMethodDeclPure() = 0; + void TestCXXMethodDeclDelete() = delete; + void TestCXXMethodDeclThrow() throw(); + void TestCXXMethodDeclThrowType() throw(int); +}; +// CHECK: CXXMethodDecl{{.*}} TestCXXMethodDeclPure 'void (void)' virtual pure +// CHECK: CXXMethodDecl{{.*}} TestCXXMethodDeclDelete 'void (void)' delete +// CHECK: CXXMethodDecl{{.*}} TestCXXMethodDeclThrow 'void (void) throw()' +// CHECK: CXXMethodDecl{{.*}} TestCXXMethodDeclThrowType 'void (void) throw(int)' + +namespace testCXXConstructorDecl { + class A { }; + class TestCXXConstructorDecl : public A { + int I; + TestCXXConstructorDecl(A &a, int i) : A(a), I(i) { } + TestCXXConstructorDecl(A &a) : TestCXXConstructorDecl(a, 0) { } + }; +} +// CHECK: CXXConstructorDecl{{.*}} TestCXXConstructorDecl 'void {{.*}}' +// CHECK-NEXT: ParmVarDecl{{.*}} a +// CHECK-NEXT: ParmVarDecl{{.*}} i +// CHECK-NEXT: CXXCtorInitializer{{.*}}A +// CHECK-NEXT: Expr +// CHECK: CXXCtorInitializer{{.*}}I +// CHECK-NEXT: Expr +// CHECK: CompoundStmt +// CHECK: CXXConstructorDecl{{.*}} TestCXXConstructorDecl 'void {{.*}}' +// CHECK-NEXT: ParmVarDecl{{.*}} a +// CHECK-NEXT: CXXCtorInitializer{{.*}}TestCXXConstructorDecl +// CHECK-NEXT: CXXConstructExpr{{.*}}TestCXXConstructorDecl + +class TestCXXDestructorDecl { + ~TestCXXDestructorDecl() { } +}; +// CHECK: CXXDestructorDecl{{.*}} ~TestCXXDestructorDecl 'void (void) noexcept' +// CHECK-NEXT: CompoundStmt + +// Test that the range of a defaulted members is computed correctly. +class TestMemberRanges { +public: + TestMemberRanges() = default; + TestMemberRanges(const TestMemberRanges &Other) = default; + TestMemberRanges(TestMemberRanges &&Other) = default; + ~TestMemberRanges() = default; + TestMemberRanges &operator=(const TestMemberRanges &Other) = default; + TestMemberRanges &operator=(TestMemberRanges &&Other) = default; +}; +void SomeFunction() { + TestMemberRanges A; + TestMemberRanges B(A); + B = A; + A = static_cast<TestMemberRanges &&>(B); + TestMemberRanges C(static_cast<TestMemberRanges &&>(A)); +} +// CHECK: CXXConstructorDecl{{.*}} <line:{{.*}}:3, col:30> +// CHECK: CXXConstructorDecl{{.*}} <line:{{.*}}:3, col:59> +// CHECK: CXXConstructorDecl{{.*}} <line:{{.*}}:3, col:54> +// CHECK: CXXDestructorDecl{{.*}} <line:{{.*}}:3, col:31> +// CHECK: CXXMethodDecl{{.*}} <line:{{.*}}:3, col:70> +// CHECK: CXXMethodDecl{{.*}} <line:{{.*}}:3, col:65> + +class TestCXXConversionDecl { + operator int() { return 0; } +}; +// CHECK: CXXConversionDecl{{.*}} operator int 'int (void)' +// CHECK-NEXT: CompoundStmt + +namespace TestStaticAssertDecl { + static_assert(true, "msg"); +} +// CHECK: NamespaceDecl{{.*}} TestStaticAssertDecl +// CHECK-NEXT: StaticAssertDecl{{.*> .*$}} +// CHECK-NEXT: CXXBoolLiteralExpr +// CHECK-NEXT: StringLiteral + +namespace testFunctionTemplateDecl { + class A { }; + class B { }; + class C { }; + class D { }; + template<typename T> void TestFunctionTemplate(T) { } + + // implicit instantiation + void bar(A a) { TestFunctionTemplate(a); } + + // explicit specialization + template<> void TestFunctionTemplate(B); + + // explicit instantiation declaration + extern template void TestFunctionTemplate(C); + + // explicit instantiation definition + template void TestFunctionTemplate(D); +} +// CHECK: FunctionTemplateDecl{{.*}} TestFunctionTemplate +// CHECK-NEXT: TemplateTypeParmDecl +// CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate 'void (T)' +// CHECK-NEXT: ParmVarDecl{{.*}} 'T' +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate {{.*}}A +// CHECK-NEXT: TemplateArgument +// CHECK-NEXT: ParmVarDecl +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: Function{{.*}} 'TestFunctionTemplate' {{.*}}B +// CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate {{.*}}C +// CHECK-NEXT: TemplateArgument +// CHECK-NEXT: ParmVarDecl +// CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate {{.*}}D +// CHECK-NEXT: TemplateArgument +// CHECK-NEXT: ParmVarDecl +// CHECK-NEXT: CompoundStmt +// CHECK: FunctionDecl{{.*}} TestFunctionTemplate {{.*}}B +// CHECK-NEXT: TemplateArgument +// CHECK-NEXT: ParmVarDecl + +namespace testClassTemplateDecl { + class A { }; + class B { }; + class C { }; + class D { }; + + template<typename T> class TestClassTemplate { + public: + TestClassTemplate(); + ~TestClassTemplate(); + int j(); + int i; + }; + + // implicit instantiation + TestClassTemplate<A> a; + + // explicit specialization + template<> class TestClassTemplate<B> { + int j; + }; + + // explicit instantiation declaration + extern template class TestClassTemplate<C>; + + // explicit instantiation definition + template class TestClassTemplate<D>; + + // partial explicit specialization + template<typename T1, typename T2> class TestClassTemplatePartial { + int i; + }; + template<typename T1> class TestClassTemplatePartial<T1, A> { + int j; + }; +} +// CHECK: ClassTemplateDecl{{.*}} TestClassTemplate +// CHECK-NEXT: TemplateTypeParmDecl +// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate +// CHECK: CXXRecordDecl{{.*}} class TestClassTemplate +// CHECK-NEXT: AccessSpecDecl{{.*}} public +// CHECK-NEXT: CXXConstructorDecl{{.*}} <line:{{.*}}:5, col:23> +// CHECK-NEXT: CXXDestructorDecl{{.*}} <line:{{.*}}:5, col:24> +// CHECK-NEXT: CXXMethodDecl{{.*}} <line:{{.*}}:5, col:11> +// CHECK-NEXT: FieldDecl{{.*}} i +// CHECK-NEXT: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate +// CHECK: TemplateArgument{{.*}}A +// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate +// CHECK-NEXT: AccessSpecDecl{{.*}} public +// CHECK-NEXT: CXXConstructorDecl{{.*}} <line:{{.*}}:5, col:23> +// CHECK-NEXT: CXXDestructorDecl{{.*}} <line:{{.*}}:5, col:24> +// CHECK-NEXT: CXXMethodDecl{{.*}} <line:{{.*}}:5, col:11> +// CHECK-NEXT: FieldDecl{{.*}} i +// CHECK: ClassTemplateSpecialization{{.*}} 'TestClassTemplate' +// CHECK-NEXT: ClassTemplateSpecialization{{.*}} 'TestClassTemplate' +// CHECK-NEXT: ClassTemplateSpecialization{{.*}} 'TestClassTemplate' + +// CHECK: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate +// CHECK-NEXT: DefinitionData +// CHECK: TemplateArgument{{.*}}B +// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate +// CHECK-NEXT: FieldDecl{{.*}} j + +// CHECK: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate +// CHECK: TemplateArgument{{.*}}C +// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate +// CHECK-NEXT: AccessSpecDecl{{.*}} public +// CHECK-NEXT: CXXConstructorDecl{{.*}} <line:{{.*}}:5, col:23> +// CHECK-NEXT: CXXDestructorDecl{{.*}} <line:{{.*}}:5, col:24> +// CHECK-NEXT: CXXMethodDecl{{.*}} <line:{{.*}}:5, col:11> +// CHECK-NEXT: FieldDecl{{.*}} i + +// CHECK: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate +// CHECK: TemplateArgument{{.*}}D +// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate +// CHECK-NEXT: AccessSpecDecl{{.*}} public +// CHECK-NEXT: CXXConstructorDecl{{.*}} <line:{{.*}}:5, col:23> +// CHECK-NEXT: CXXDestructorDecl{{.*}} <line:{{.*}}:5, col:24> +// CHECK-NEXT: CXXMethodDecl{{.*}} <line:{{.*}}:5, col:11> +// CHECK-NEXT: FieldDecl{{.*}} i + +// CHECK: ClassTemplatePartialSpecializationDecl{{.*}} class TestClassTemplatePartial +// CHECK: TemplateArgument +// CHECK-NEXT: TemplateArgument{{.*}}A +// CHECK-NEXT: TemplateTypeParmDecl +// CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplatePartial +// CHECK-NEXT: FieldDecl{{.*}} j + +// PR15220 dump instantiation only once +namespace testCanonicalTemplate { + class A {}; + + template<typename T> void TestFunctionTemplate(T); + template<typename T> void TestFunctionTemplate(T); + void bar(A a) { TestFunctionTemplate(a); } + // CHECK: FunctionTemplateDecl{{.*}} TestFunctionTemplate + // CHECK-NEXT: TemplateTypeParmDecl + // CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate 'void (T)' + // CHECK-NEXT: ParmVarDecl{{.*}} 'T' + // CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate {{.*}}A + // CHECK-NEXT: TemplateArgument + // CHECK-NEXT: ParmVarDecl + // CHECK: FunctionTemplateDecl{{.*}} TestFunctionTemplate + // CHECK-NEXT: TemplateTypeParmDecl + // CHECK-NEXT: FunctionDecl{{.*}} TestFunctionTemplate 'void (T)' + // CHECK-NEXT: ParmVarDecl{{.*}} 'T' + // CHECK-NEXT: Function{{.*}} 'TestFunctionTemplate' + // CHECK-NOT: TemplateArgument + + template<typename T1> class TestClassTemplate { + template<typename T2> friend class TestClassTemplate; + }; + TestClassTemplate<A> a; + // CHECK: ClassTemplateDecl{{.*}} TestClassTemplate + // CHECK-NEXT: TemplateTypeParmDecl + // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate + // CHECK: CXXRecordDecl{{.*}} class TestClassTemplate + // CHECK-NEXT: FriendDecl + // CHECK-NEXT: ClassTemplateDecl{{.*}} TestClassTemplate + // CHECK-NEXT: TemplateTypeParmDecl + // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate + // CHECK-NEXT: ClassTemplateSpecializationDecl{{.*}} class TestClassTemplate + // CHECK: TemplateArgument{{.*}}A + // CHECK-NEXT: CXXRecordDecl{{.*}} class TestClassTemplate +} + +template <class T> +class TestClassScopeFunctionSpecialization { + template<class U> void foo(U a) { } + template<> void foo<int>(int a) { } +}; +// CHECK: ClassScopeFunctionSpecializationDecl +// CHECK-NEXT: CXXMethod{{.*}} 'foo' 'void (int)' +// CHECK-NEXT: TemplateArgument{{.*}} 'int' + +namespace TestTemplateTypeParmDecl { + template<typename ... T, class U = int> void foo(); +} +// CHECK: NamespaceDecl{{.*}} TestTemplateTypeParmDecl +// CHECK-NEXT: FunctionTemplateDecl +// CHECK-NEXT: TemplateTypeParmDecl{{.*}} typename depth 0 index 0 ... T +// CHECK-NEXT: TemplateTypeParmDecl{{.*}} class depth 0 index 1 U +// CHECK-NEXT: TemplateArgument type 'int' + +namespace TestNonTypeTemplateParmDecl { + template<int I = 1, int ... J> void foo(); +} +// CHECK: NamespaceDecl{{.*}} TestNonTypeTemplateParmDecl +// CHECK-NEXT: FunctionTemplateDecl +// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} 'int' depth 0 index 0 I +// CHECK-NEXT: TemplateArgument expr +// CHECK-NEXT: IntegerLiteral{{.*}} 'int' 1 +// CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} 'int' depth 0 index 1 ... J + +namespace TestTemplateTemplateParmDecl { + template<typename T> class A; + template <template <typename> class T = A, template <typename> class ... U> void foo(); +} +// CHECK: NamespaceDecl{{.*}} TestTemplateTemplateParmDecl +// CHECK: FunctionTemplateDecl +// CHECK-NEXT: TemplateTemplateParmDecl{{.*}} T +// CHECK-NEXT: TemplateTypeParmDecl{{.*}} typename +// CHECK-NEXT: TemplateArgument{{.*}} template A +// CHECK-NEXT: TemplateTemplateParmDecl{{.*}} ... U +// CHECK-NEXT: TemplateTypeParmDecl{{.*}} typename + +namespace TestTemplateArgument { + template<typename> class A { }; + template<template<typename> class ...> class B { }; + int foo(); + + template<typename> class testType { }; + template class testType<int>; + // CHECK: ClassTemplateSpecializationDecl{{.*}} class testType + // CHECK: TemplateArgument{{.*}} type 'int' + + template<int fp(void)> class testDecl { }; + template class testDecl<foo>; + // CHECK: ClassTemplateSpecializationDecl{{.*}} class testDecl + // CHECK: TemplateArgument{{.*}} decl + // CHECK-NEXT: Function{{.*}}foo + + template class testDecl<nullptr>; + // CHECK: ClassTemplateSpecializationDecl{{.*}} class testDecl + // CHECK: TemplateArgument{{.*}} nullptr + + template<int> class testIntegral { }; + template class testIntegral<1>; + // CHECK: ClassTemplateSpecializationDecl{{.*}} class testIntegral + // CHECK: TemplateArgument{{.*}} integral 1 + + template<template<typename> class> class testTemplate { }; + template class testTemplate<A>; + // CHECK: ClassTemplateSpecializationDecl{{.*}} class testTemplate + // CHECK: TemplateArgument{{.*}} A + + template<template<typename> class ...T> class C { + B<T...> testTemplateExpansion; + }; + // FIXME: Need TemplateSpecializationType dumping to test TemplateExpansion. + + template<int, int = 0> class testExpr; + template<int I> class testExpr<I> { }; + // CHECK: ClassTemplatePartialSpecializationDecl{{.*}} class testExpr + // CHECK: TemplateArgument{{.*}} expr + // CHECK-NEXT: DeclRefExpr{{.*}}I + + template<int, int ...> class testPack { }; + template class testPack<0, 1, 2>; + // CHECK: ClassTemplateSpecializationDecl{{.*}} class testPack + // CHECK: TemplateArgument{{.*}} integral 0 + // CHECK-NEXT: TemplateArgument{{.*}} pack + // CHECK-NEXT: TemplateArgument{{.*}} integral 1 + // CHECK-NEXT: TemplateArgument{{.*}} integral 2 +} + +namespace testUsingDecl { + int i; +} +namespace TestUsingDecl { + using testUsingDecl::i; +} +// CHECK: NamespaceDecl{{.*}} TestUsingDecl +// CHECK-NEXT: UsingDecl{{.*}} testUsingDecl::i +// CHECK-NEXT: UsingShadowDecl{{.*}} Var{{.*}} 'i' 'int' + +namespace testUnresolvedUsing { + class A { }; + template<class T> class B { + public: + A a; + }; + template<class T> class TestUnresolvedUsing : public B<T> { + using typename B<T>::a; + using B<T>::a; + }; +} +// CHECK: CXXRecordDecl{{.*}} TestUnresolvedUsing +// CHECK: UnresolvedUsingTypenameDecl{{.*}} B<T>::a +// CHECK: UnresolvedUsingValueDecl{{.*}} B<T>::a + +namespace TestLinkageSpecDecl { + extern "C" void test1(); + extern "C++" void test2(); +} +// CHECK: NamespaceDecl{{.*}} TestLinkageSpecDecl +// CHECK-NEXT: LinkageSpecDecl{{.*}} C +// CHECK-NEXT: FunctionDecl +// CHECK-NEXT: LinkageSpecDecl{{.*}} C++ +// CHECK-NEXT: FunctionDecl + +class TestAccessSpecDecl { +public: +private: +protected: +}; +// CHECK: CXXRecordDecl{{.*}} class TestAccessSpecDecl +// CHECK: CXXRecordDecl{{.*}} class TestAccessSpecDecl +// CHECK-NEXT: AccessSpecDecl{{.*}} public +// CHECK-NEXT: AccessSpecDecl{{.*}} private +// CHECK-NEXT: AccessSpecDecl{{.*}} protected + +template<typename T> class TestFriendDecl { + friend int foo(); + friend class A; + friend T; +}; +// CHECK: CXXRecord{{.*}} TestFriendDecl +// CHECK: CXXRecord{{.*}} TestFriendDecl +// CHECK-NEXT: FriendDecl +// CHECK-NEXT: FunctionDecl{{.*}} foo +// CHECK-NEXT: FriendDecl{{.*}} 'class A':'class A' +// CHECK-NEXT: FriendDecl{{.*}} 'T' + +namespace TestFileScopeAsmDecl { + asm("ret"); +} +// CHECK: NamespaceDecl{{.*}} TestFileScopeAsmDecl{{$}} +// CHECK: FileScopeAsmDecl{{.*> .*$}} +// CHECK-NEXT: StringLiteral + +namespace TestFriendDecl2 { + void f(); + struct S { + friend void f(); + }; +} +// CHECK: NamespaceDecl [[TestFriendDecl2:0x.*]] <{{.*}}> {{.*}} TestFriendDecl2 +// CHECK: |-FunctionDecl [[TestFriendDecl2_f:0x.*]] <{{.*}}> {{.*}} f 'void (void)' +// CHECK: `-CXXRecordDecl {{.*}} struct S +// CHECK: |-CXXRecordDecl {{.*}} struct S +// CHECK: `-FriendDecl +// CHECK: `-FunctionDecl {{.*}} parent [[TestFriendDecl2]] prev [[TestFriendDecl2_f]] <{{.*}}> {{.*}} f 'void (void)' + +namespace Comment { + extern int Test; + /// Something here. + extern int Test; + extern int Test; +} + +// CHECK: VarDecl {{.*}} Test 'int' extern +// CHECK-NOT: FullComment +// CHECK: VarDecl {{.*}} Test 'int' extern +// CHECK: `-FullComment +// CHECK: `-ParagraphComment +// CHECK: `-TextComment +// CHECK: VarDecl {{.*}} Test 'int' extern +// CHECK-NOT: FullComment diff --git a/clang/test/Misc/ast-dump-invalid.cpp b/clang/test/Misc/ast-dump-invalid.cpp index 3cc8f8b6252..842b057a4a5 100644 --- a/clang/test/Misc/ast-dump-invalid.cpp +++ b/clang/test/Misc/ast-dump-invalid.cpp @@ -1,64 +1,64 @@ -// RUN: not %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -fms-extensions -ast-dump -ast-dump-filter Test %s | FileCheck -check-prefix CHECK -strict-whitespace %s
-
-namespace TestInvalidRParenOnCXXUnresolvedConstructExpr {
-template <class T>
-void f(T i, T j) {
- return T (i, j;
-}
-}
-
-// CHECK: NamespaceDecl {{.*}} <{{.*}}> {{.*}} TestInvalidRParenOnCXXUnresolvedConstructExpr
-// CHECK-NEXT: `-FunctionTemplateDecl
-// CHECK-NEXT: |-TemplateTypeParmDecl
-// CHECK-NEXT: `-FunctionDecl
-// CHECK-NEXT: |-ParmVarDecl
-// CHECK-NEXT: |-ParmVarDecl
-// CHECK-NEXT: `-CompoundStmt
-// CHECK-NEXT: `-ReturnStmt
-// CHECK-NEXT: `-CXXUnresolvedConstructExpr {{.*}} <col:10, col:16> 'T'
-// CHECK-NEXT: |-DeclRefExpr {{.*}} <col:13> 'T' lvalue ParmVar {{.*}} 'i' 'T'
-// CHECK-NEXT: `-DeclRefExpr {{.*}} <col:16> 'T' lvalue ParmVar {{.*}} 'j' 'T'
-
-
-namespace TestInvalidIf {
-int g(int i) {
- if (invalid_condition)
- return 4;
- else
- return i;
-}
-}
-// CHECK: NamespaceDecl {{.*}} <{{.*}}> {{.*}} TestInvalidIf
-// CHECK-NEXT: `-FunctionDecl
-// CHECK-NEXT: |-ParmVarDecl
-// CHECK-NEXT: `-CompoundStmt
-// CHECK-NEXT: `-IfStmt {{.*}} <line:25:3, line:28:12>
-// CHECK-NEXT: |-<<<NULL>>>
-// CHECK-NEXT: |-<<<NULL>>>
-// CHECK-NEXT: |-OpaqueValueExpr {{.*}} <<invalid sloc>> 'bool'
-// CHECK-NEXT: |-ReturnStmt {{.*}} <line:26:5, col:12>
-// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:12> 'int' 4
-// CHECK-NEXT: `-ReturnStmt {{.*}} <line:28:5, col:12>
-// CHECK-NEXT: `-ImplicitCastExpr {{.*}} <col:12> 'int' <LValueToRValue>
-// CHECK-NEXT: `-DeclRefExpr {{.*}} <col:12> 'int' lvalue ParmVar {{.*}} 'i' 'int'
-
-namespace TestInvalidFunctionDecl {
-struct Str {
- double foo1(double, invalid_type);
-};
-double Str::foo1(double, invalid_type)
-{ return 45; }
-}
-// CHECK: NamespaceDecl {{.*}} <{{.*}}> {{.*}} TestInvalidFunctionDecl
-// CHECK-NEXT: |-CXXRecordDecl {{.*}} <line:46:1, line:48:1> line:46:8 struct Str definition
-// CHECK: | |-CXXRecordDecl {{.*}} <col:1, col:8> col:8 implicit struct Str
-// CHECK-NEXT: | `-CXXMethodDecl {{.*}} <line:47:4, col:36> col:11 invalid foo1 'double (double, int)'
-// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:16> col:22 'double'
-// CHECK-NEXT: | `-ParmVarDecl {{.*}} <col:24, <invalid sloc>> col:36 invalid 'int'
-// CHECK-NEXT: `-CXXMethodDecl {{.*}} parent {{.*}} <line:49:1, line:50:14> line:49:13 invalid foo1 'double (double, int)'
-// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:18> col:24 'double'
-// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:26, <invalid sloc>> col:38 invalid 'int'
-// CHECK-NEXT: `-CompoundStmt {{.*}} <line:50:1, col:14>
-// CHECK-NEXT: `-ReturnStmt {{.*}} <col:3, col:10>
-// CHECK-NEXT: `-ImplicitCastExpr {{.*}} <col:10> 'double' <IntegralToFloating>
-// CHECK-NEXT: `-IntegerLiteral {{.*}} <col:10> 'int' 45
+// RUN: not %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -fms-extensions -ast-dump -ast-dump-filter Test %s | FileCheck -check-prefix CHECK -strict-whitespace %s + +namespace TestInvalidRParenOnCXXUnresolvedConstructExpr { +template <class T> +void f(T i, T j) { + return T (i, j; +} +} + +// CHECK: NamespaceDecl {{.*}} <{{.*}}> {{.*}} TestInvalidRParenOnCXXUnresolvedConstructExpr +// CHECK-NEXT: `-FunctionTemplateDecl +// CHECK-NEXT: |-TemplateTypeParmDecl +// CHECK-NEXT: `-FunctionDecl +// CHECK-NEXT: |-ParmVarDecl +// CHECK-NEXT: |-ParmVarDecl +// CHECK-NEXT: `-CompoundStmt +// CHECK-NEXT: `-ReturnStmt +// CHECK-NEXT: `-CXXUnresolvedConstructExpr {{.*}} <col:10, col:16> 'T' +// CHECK-NEXT: |-DeclRefExpr {{.*}} <col:13> 'T' lvalue ParmVar {{.*}} 'i' 'T' +// CHECK-NEXT: `-DeclRefExpr {{.*}} <col:16> 'T' lvalue ParmVar {{.*}} 'j' 'T' + + +namespace TestInvalidIf { +int g(int i) { + if (invalid_condition) + return 4; + else + return i; +} +} +// CHECK: NamespaceDecl {{.*}} <{{.*}}> {{.*}} TestInvalidIf +// CHECK-NEXT: `-FunctionDecl +// CHECK-NEXT: |-ParmVarDecl +// CHECK-NEXT: `-CompoundStmt +// CHECK-NEXT: `-IfStmt {{.*}} <line:25:3, line:28:12> +// CHECK-NEXT: |-<<<NULL>>> +// CHECK-NEXT: |-<<<NULL>>> +// CHECK-NEXT: |-OpaqueValueExpr {{.*}} <<invalid sloc>> '_Bool' +// CHECK-NEXT: |-ReturnStmt {{.*}} <line:26:5, col:12> +// CHECK-NEXT: | `-IntegerLiteral {{.*}} <col:12> 'int' 4 +// CHECK-NEXT: `-ReturnStmt {{.*}} <line:28:5, col:12> +// CHECK-NEXT: `-ImplicitCastExpr {{.*}} <col:12> 'int' <LValueToRValue> +// CHECK-NEXT: `-DeclRefExpr {{.*}} <col:12> 'int' lvalue ParmVar {{.*}} 'i' 'int' + +namespace TestInvalidFunctionDecl { +struct Str { + double foo1(double, invalid_type); +}; +double Str::foo1(double, invalid_type) +{ return 45; } +} +// CHECK: NamespaceDecl {{.*}} <{{.*}}> {{.*}} TestInvalidFunctionDecl +// CHECK-NEXT: |-CXXRecordDecl {{.*}} <line:46:1, line:48:1> line:46:8 struct Str definition +// CHECK: | |-CXXRecordDecl {{.*}} <col:1, col:8> col:8 implicit struct Str +// CHECK-NEXT: | `-CXXMethodDecl {{.*}} <line:47:4, col:36> col:11 invalid foo1 'double (double, int)' +// CHECK-NEXT: | |-ParmVarDecl {{.*}} <col:16> col:22 'double' +// CHECK-NEXT: | `-ParmVarDecl {{.*}} <col:24, <invalid sloc>> col:36 invalid 'int' +// CHECK-NEXT: `-CXXMethodDecl {{.*}} parent {{.*}} <line:49:1, line:50:14> line:49:13 invalid foo1 'double (double, int)' +// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:18> col:24 'double' +// CHECK-NEXT: |-ParmVarDecl {{.*}} <col:26, <invalid sloc>> col:38 invalid 'int' +// CHECK-NEXT: `-CompoundStmt {{.*}} <line:50:1, col:14> +// CHECK-NEXT: `-ReturnStmt {{.*}} <col:3, col:10> +// CHECK-NEXT: `-ImplicitCastExpr {{.*}} <col:10> 'double' <IntegralToFloating> +// CHECK-NEXT: `-IntegerLiteral {{.*}} <col:10> 'int' 45 diff --git a/clang/test/OpenMP/dump.cpp b/clang/test/OpenMP/dump.cpp index 1cf8152bd2a..5ec202cc304 100644 --- a/clang/test/OpenMP/dump.cpp +++ b/clang/test/OpenMP/dump.cpp @@ -1,68 +1,68 @@ -// RUN: %clang_cc1 -verify -fopenmp -ast-dump %s | FileCheck %s
-// expected-no-diagnostics
-
-int ga, gb;
-#pragma omp threadprivate(ga, gb)
-
-// CHECK: |-OMPThreadPrivateDecl {{.+}} <col:9> col:9
-// CHECK-NEXT: | |-DeclRefExpr {{.+}} <col:27> 'int' lvalue Var {{.+}} 'ga' 'int'
-// CHECK-NEXT: | `-DeclRefExpr {{.+}} <col:31> 'int' lvalue Var {{.+}} 'gb' 'int'
-
-#pragma omp declare reduction(+ : int, char : omp_out *= omp_in)
-
-#pragma omp declare reduction(fun : float : omp_out += omp_in) initializer(omp_priv = omp_orig + 15)
-
-// CHECK: |-OMPDeclareReductionDecl {{.+}} <line:11:35> col:35 operator+ 'int' combiner
-// CHECK-NEXT: | |-CompoundAssignOperator {{.+}} <col:47, col:58> 'int' lvalue '*=' ComputeLHSTy='int' ComputeResultTy='int'
-// CHECK-NEXT: | | |-DeclRefExpr {{.+}} <col:47> 'int' lvalue Var {{.+}} 'omp_out' 'int'
-// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:58> 'int' <LValueToRValue>
-// CHECK-NEXT: | | `-DeclRefExpr {{.+}} <col:58> 'int' lvalue Var {{.+}} 'omp_in' 'int'
-// CHECK-NEXT: | |-VarDecl {{.+}} <col:35> col:35 implicit used omp_in 'int'
-// CHECK-NEXT: | `-VarDecl {{.+}} <col:35> col:35 implicit used omp_out 'int'
-// CHECK-NEXT: |-OMPDeclareReductionDecl {{.+}} <col:40> col:40 operator+ 'char' combiner
-// CHECK-NEXT: | |-CompoundAssignOperator {{.+}} <col:47, col:58> 'char' lvalue '*=' ComputeLHSTy='int' ComputeResultTy='int'
-// CHECK-NEXT: | | |-DeclRefExpr {{.+}} <col:47> 'char' lvalue Var {{.+}} 'omp_out' 'char'
-// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:58> 'int' <IntegralCast>
-// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:58> 'char' <LValueToRValue>
-// CHECK-NEXT: | | `-DeclRefExpr {{.+}} <col:58> 'char' lvalue Var {{.+}} 'omp_in' 'char'
-// CHECK-NEXT: | |-VarDecl {{.+}} <col:40> col:40 implicit used omp_in 'char'
-// CHECK-NEXT: | `-VarDecl {{.+}} <col:40> col:40 implicit used omp_out 'char'
-// CHECK-NEXT: |-OMPDeclareReductionDecl {{.+}} <line:13:37> col:37 fun 'float' combiner initializer
-// CHECK-NEXT: | |-CompoundAssignOperator {{.+}} <col:45, col:56> 'float' lvalue '+=' ComputeLHSTy='float' ComputeResultTy='float'
-// CHECK-NEXT: | | |-DeclRefExpr {{.+}} <col:45> 'float' lvalue Var {{.+}} 'omp_out' 'float'
-// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:56> 'float' <LValueToRValue>
-// CHECK-NEXT: | | `-DeclRefExpr {{.+}} <col:56> 'float' lvalue Var {{.+}} 'omp_in' 'float'
-
-struct S {
- int a, b;
- S() {
-#pragma omp parallel for default(none) private(a) shared(b) schedule(static, a)
- for (int i = 0; i < 0; ++i)
- ++a;
- }
-};
-
-// CHECK: | `-OMPParallelForDirective {{.+}} <line:39:9, col:80>
-// CHECK-NEXT: | |-OMPDefaultClause {{.+}} <col:26, col:40>
-// CHECK-NEXT: | |-OMPPrivateClause {{.+}} <col:40, col:51>
-// CHECK-NEXT: | | `-DeclRefExpr {{.+}} <col:48> 'int' lvalue OMPCapturedExpr {{.+}} 'a' 'int &'
-// CHECK-NEXT: | |-OMPSharedClause {{.+}} <col:51, col:61>
-// CHECK-NEXT: | | `-MemberExpr {{.+}} <col:58> 'int' lvalue ->b
-// CHECK-NEXT: | | `-CXXThisExpr {{.+}} <col:58> 'S *' this
-// CHECK-NEXT: | |-OMPScheduleClause {{.+}} <col:61, col:79>
-// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:78> 'int' <LValueToRValue>
-// CHECK-NEXT: | | `-DeclRefExpr {{.+}} <col:78> 'int' lvalue OMPCapturedExpr {{.+}} '.capture_expr.' 'int'
-// CHECK-NEXT: | |-CapturedStmt {{.+}} <line:40:5, line:41:9>
-// CHECK-NEXT: | | |-CapturedDecl {{.+}} <<invalid sloc>> <invalid sloc>
-// CHECK-NEXT: | | | |-ForStmt {{.+}} <line:40:5, line:41:9>
-// CHECK: | | | | `-UnaryOperator {{.+}} <line:41:7, col:9> 'int' lvalue prefix '++'
-// CHECK-NEXT: | | | | `-DeclRefExpr {{.+}} <col:9> 'int' lvalue OMPCapturedExpr {{.+}} 'a' 'int &'
-
-#pragma omp declare simd
-#pragma omp declare simd inbranch
-void foo();
-
-// CHECK: `-FunctionDecl {{.+}} <line:63:1, col:10> col:6 foo 'void ()'
-// CHECK-NEXT: |-OMPDeclareSimdDeclAttr {{.+}} <line:62:9, col:34> Implicit BS_Inbranch
-// CHECK: `-OMPDeclareSimdDeclAttr {{.+}} <line:61:9, col:25> Implicit BS_Undefined
-
+// RUN: %clang_cc1 -verify -fopenmp -ast-dump %s | FileCheck %s +// expected-no-diagnostics + +int ga, gb; +#pragma omp threadprivate(ga, gb) + +// CHECK: |-OMPThreadPrivateDecl {{.+}} <col:9> col:9 +// CHECK-NEXT: | |-DeclRefExpr {{.+}} <col:27> 'int' lvalue Var {{.+}} 'ga' 'int' +// CHECK-NEXT: | `-DeclRefExpr {{.+}} <col:31> 'int' lvalue Var {{.+}} 'gb' 'int' + +#pragma omp declare reduction(+ : int, char : omp_out *= omp_in) + +#pragma omp declare reduction(fun : float : omp_out += omp_in) initializer(omp_priv = omp_orig + 15) + +// CHECK: |-OMPDeclareReductionDecl {{.+}} <line:11:35> col:35 operator+ 'int' combiner +// CHECK-NEXT: | |-CompoundAssignOperator {{.+}} <col:47, col:58> 'int' lvalue '*=' ComputeLHSTy='int' ComputeResultTy='int' +// CHECK-NEXT: | | |-DeclRefExpr {{.+}} <col:47> 'int' lvalue Var {{.+}} 'omp_out' 'int' +// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:58> 'int' <LValueToRValue> +// CHECK-NEXT: | | `-DeclRefExpr {{.+}} <col:58> 'int' lvalue Var {{.+}} 'omp_in' 'int' +// CHECK-NEXT: | |-VarDecl {{.+}} <col:35> col:35 implicit used omp_in 'int' +// CHECK-NEXT: | `-VarDecl {{.+}} <col:35> col:35 implicit used omp_out 'int' +// CHECK-NEXT: |-OMPDeclareReductionDecl {{.+}} <col:40> col:40 operator+ 'char' combiner +// CHECK-NEXT: | |-CompoundAssignOperator {{.+}} <col:47, col:58> 'char' lvalue '*=' ComputeLHSTy='int' ComputeResultTy='int' +// CHECK-NEXT: | | |-DeclRefExpr {{.+}} <col:47> 'char' lvalue Var {{.+}} 'omp_out' 'char' +// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:58> 'int' <IntegralCast> +// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:58> 'char' <LValueToRValue> +// CHECK-NEXT: | | `-DeclRefExpr {{.+}} <col:58> 'char' lvalue Var {{.+}} 'omp_in' 'char' +// CHECK-NEXT: | |-VarDecl {{.+}} <col:40> col:40 implicit used omp_in 'char' +// CHECK-NEXT: | `-VarDecl {{.+}} <col:40> col:40 implicit used omp_out 'char' +// CHECK-NEXT: |-OMPDeclareReductionDecl {{.+}} <line:13:37> col:37 fun 'float' combiner initializer +// CHECK-NEXT: | |-CompoundAssignOperator {{.+}} <col:45, col:56> 'float' lvalue '+=' ComputeLHSTy='float' ComputeResultTy='float' +// CHECK-NEXT: | | |-DeclRefExpr {{.+}} <col:45> 'float' lvalue Var {{.+}} 'omp_out' 'float' +// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:56> 'float' <LValueToRValue> +// CHECK-NEXT: | | `-DeclRefExpr {{.+}} <col:56> 'float' lvalue Var {{.+}} 'omp_in' 'float' + +struct S { + int a, b; + S() { +#pragma omp parallel for default(none) private(a) shared(b) schedule(static, a) + for (int i = 0; i < 0; ++i) + ++a; + } +}; + +// CHECK: | `-OMPParallelForDirective {{.+}} <line:39:9, col:80> +// CHECK-NEXT: | |-OMPDefaultClause {{.+}} <col:26, col:40> +// CHECK-NEXT: | |-OMPPrivateClause {{.+}} <col:40, col:51> +// CHECK-NEXT: | | `-DeclRefExpr {{.+}} <col:48> 'int' lvalue OMPCapturedExpr {{.+}} 'a' 'int &' +// CHECK-NEXT: | |-OMPSharedClause {{.+}} <col:51, col:61> +// CHECK-NEXT: | | `-MemberExpr {{.+}} <col:58> 'int' lvalue ->b +// CHECK-NEXT: | | `-CXXThisExpr {{.+}} <col:58> 'struct S *' this +// CHECK-NEXT: | |-OMPScheduleClause {{.+}} <col:61, col:79> +// CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} <col:78> 'int' <LValueToRValue> +// CHECK-NEXT: | | `-DeclRefExpr {{.+}} <col:78> 'int' lvalue OMPCapturedExpr {{.+}} '.capture_expr.' 'int' +// CHECK-NEXT: | |-CapturedStmt {{.+}} <line:40:5, line:41:9> +// CHECK-NEXT: | | |-CapturedDecl {{.+}} <<invalid sloc>> <invalid sloc> +// CHECK-NEXT: | | | |-ForStmt {{.+}} <line:40:5, line:41:9> +// CHECK: | | | | `-UnaryOperator {{.+}} <line:41:7, col:9> 'int' lvalue prefix '++' +// CHECK-NEXT: | | | | `-DeclRefExpr {{.+}} <col:9> 'int' lvalue OMPCapturedExpr {{.+}} 'a' 'int &' + +#pragma omp declare simd +#pragma omp declare simd inbranch +void foo(); + +// CHECK: `-FunctionDecl {{.+}} <line:63:1, col:10> col:6 foo 'void (void)' +// CHECK-NEXT: |-OMPDeclareSimdDeclAttr {{.+}} <line:62:9, col:34> Implicit BS_Inbranch +// CHECK: `-OMPDeclareSimdDeclAttr {{.+}} <line:61:9, col:25> Implicit BS_Undefined + diff --git a/clang/test/Parser/objc-default-ctor-init.mm b/clang/test/Parser/objc-default-ctor-init.mm index a14a243a31c..ea4c064d779 100644 --- a/clang/test/Parser/objc-default-ctor-init.mm +++ b/clang/test/Parser/objc-default-ctor-init.mm @@ -1,21 +1,21 @@ -// RUN: %clang_cc1 -triple x86_64-apple-macosx10.10 -std=c++11 -ast-dump %s | FileCheck %s
-// CHECK: CXXCtorInitializer Field {{.*}} 'ptr' 'void *'
-// CHECK: CXXCtorInitializer Field {{.*}} 'q' 'Q'
-
-@interface NSObject
-@end
-
-@interface I : NSObject
-@end
-
-struct Q { Q(); };
-
-struct S {
- S();
- void *ptr = nullptr;
- Q q;
-};
-
-@implementation I
-S::S() {}
-@end
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.10 -std=c++11 -ast-dump %s | FileCheck %s +// CHECK: CXXCtorInitializer Field {{.*}} 'ptr' 'void *' +// CHECK: CXXCtorInitializer Field {{.*}} 'q' 'struct Q' + +@interface NSObject +@end + +@interface I : NSObject +@end + +struct Q { Q(); }; + +struct S { + S(); + void *ptr = nullptr; + Q q; +}; + +@implementation I +S::S() {} +@end diff --git a/clang/test/SemaCXX/compound-literal.cpp b/clang/test/SemaCXX/compound-literal.cpp index be9ebee00c2..5480b1fef44 100644 --- a/clang/test/SemaCXX/compound-literal.cpp +++ b/clang/test/SemaCXX/compound-literal.cpp @@ -1,98 +1,98 @@ -// RUN: %clang_cc1 -fsyntax-only -std=c++03 -verify -ast-dump %s > %t-03
-// RUN: FileCheck --input-file=%t-03 %s
-// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify -ast-dump %s > %t-11
-// RUN: FileCheck --input-file=%t-11 %s
-// RUN: FileCheck --input-file=%t-11 %s --check-prefix=CHECK-CXX11
-
-// http://llvm.org/PR7905
-namespace PR7905 {
-struct S; // expected-note {{forward declaration}}
-void foo1() {
- (void)(S[]) {{3}}; // expected-error {{array has incomplete element type}}
-}
-
-template <typename T> struct M { T m; };
-void foo2() {
- (void)(M<short> []) {{3}};
-}
-}
-
-// Check compound literals mixed with C++11 list-initialization.
-namespace brace_initializers {
- struct POD {
- int x, y;
- };
- struct HasCtor {
- HasCtor(int x, int y);
- };
- struct HasDtor {
- int x, y;
- ~HasDtor();
- };
- struct HasCtorDtor {
- HasCtorDtor(int x, int y);
- ~HasCtorDtor();
- };
-
- void test() {
- (void)(POD){1, 2};
- // CHECK-NOT: CXXBindTemporaryExpr {{.*}} 'brace_initializers::POD'
- // CHECK: CompoundLiteralExpr {{.*}} 'brace_initializers::POD'
- // CHECK-NEXT: InitListExpr {{.*}} 'brace_initializers::POD'
- // CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}}
- // CHECK-NEXT: IntegerLiteral {{.*}} 2{{$}}
-
- (void)(HasDtor){1, 2};
- // CHECK: CXXBindTemporaryExpr {{.*}} 'brace_initializers::HasDtor'
- // CHECK-NEXT: CompoundLiteralExpr {{.*}} 'brace_initializers::HasDtor'
- // CHECK-NEXT: InitListExpr {{.*}} 'brace_initializers::HasDtor'
- // CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}}
- // CHECK-NEXT: IntegerLiteral {{.*}} 2{{$}}
-
-#if __cplusplus >= 201103L
- (void)(HasCtor){1, 2};
- // CHECK-CXX11-NOT: CXXBindTemporaryExpr {{.*}} 'brace_initializers::HasCtor'
- // CHECK-CXX11: CompoundLiteralExpr {{.*}} 'brace_initializers::HasCtor'
- // CHECK-CXX11-NEXT: CXXTemporaryObjectExpr {{.*}} 'brace_initializers::HasCtor'
- // CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 1{{$}}
- // CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 2{{$}}
-
- (void)(HasCtorDtor){1, 2};
- // CHECK-CXX11: CXXBindTemporaryExpr {{.*}} 'brace_initializers::HasCtorDtor'
- // CHECK-CXX11-NEXT: CompoundLiteralExpr {{.*}} 'brace_initializers::HasCtorDtor'
- // CHECK-CXX11-NEXT: CXXTemporaryObjectExpr {{.*}} 'brace_initializers::HasCtorDtor'
- // CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 1{{$}}
- // CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 2{{$}}
-#endif
- }
-
- struct PrivateDtor {
- int x, y;
- private:
- ~PrivateDtor(); // expected-note {{declared private here}}
- };
-
- void testPrivateDtor() {
- (void)(PrivateDtor){1, 2}; // expected-error {{temporary of type 'brace_initializers::PrivateDtor' has private destructor}}
- }
-}
-
-// This doesn't necessarily need to be an error, but CodeGen can't handle it
-// at the moment.
-int PR17415 = (int){PR17415}; // expected-error {{initializer element is not a compile-time constant}}
-
-// Make sure we accept this. (Not sure if we actually should... but we do
-// at the moment.)
-template<unsigned> struct Value { };
-template<typename T>
-int &check_narrowed(Value<sizeof((T){1.1})>);
-
-#if __cplusplus >= 201103L
-// Compound literals in global lambdas have automatic storage duration
-// and are not subject to the constant-initialization rules.
-int computed_with_lambda = [] {
- int x = 5;
- int result = ((int[]) { x, x + 2, x + 4, x + 6 })[0];
- return result;
-}();
-#endif
+// RUN: %clang_cc1 -fsyntax-only -std=c++03 -verify -ast-dump %s > %t-03 +// RUN: FileCheck --input-file=%t-03 %s +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify -ast-dump %s > %t-11 +// RUN: FileCheck --input-file=%t-11 %s +// RUN: FileCheck --input-file=%t-11 %s --check-prefix=CHECK-CXX11 + +// http://llvm.org/PR7905 +namespace PR7905 { +struct S; // expected-note {{forward declaration}} +void foo1() { + (void)(S[]) {{3}}; // expected-error {{array has incomplete element type}} +} + +template <typename T> struct M { T m; }; +void foo2() { + (void)(M<short> []) {{3}}; +} +} + +// Check compound literals mixed with C++11 list-initialization. +namespace brace_initializers { + struct POD { + int x, y; + }; + struct HasCtor { + HasCtor(int x, int y); + }; + struct HasDtor { + int x, y; + ~HasDtor(); + }; + struct HasCtorDtor { + HasCtorDtor(int x, int y); + ~HasCtorDtor(); + }; + + void test() { + (void)(POD){1, 2}; + // CHECK-NOT: CXXBindTemporaryExpr {{.*}} 'struct brace_initializers::POD' + // CHECK: CompoundLiteralExpr {{.*}} 'struct brace_initializers::POD' + // CHECK-NEXT: InitListExpr {{.*}} 'struct brace_initializers::POD' + // CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}} + // CHECK-NEXT: IntegerLiteral {{.*}} 2{{$}} + + (void)(HasDtor){1, 2}; + // CHECK: CXXBindTemporaryExpr {{.*}} 'struct brace_initializers::HasDtor' + // CHECK-NEXT: CompoundLiteralExpr {{.*}} 'struct brace_initializers::HasDtor' + // CHECK-NEXT: InitListExpr {{.*}} 'struct brace_initializers::HasDtor' + // CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}} + // CHECK-NEXT: IntegerLiteral {{.*}} 2{{$}} + +#if __cplusplus >= 201103L + (void)(HasCtor){1, 2}; + // CHECK-CXX11-NOT: CXXBindTemporaryExpr {{.*}} 'struct brace_initializers::HasCtor' + // CHECK-CXX11: CompoundLiteralExpr {{.*}} 'struct brace_initializers::HasCtor' + // CHECK-CXX11-NEXT: CXXTemporaryObjectExpr {{.*}} 'struct brace_initializers::HasCtor' + // CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 1{{$}} + // CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 2{{$}} + + (void)(HasCtorDtor){1, 2}; + // CHECK-CXX11: CXXBindTemporaryExpr {{.*}} 'struct brace_initializers::HasCtorDtor' + // CHECK-CXX11-NEXT: CompoundLiteralExpr {{.*}} 'struct brace_initializers::HasCtorDtor' + // CHECK-CXX11-NEXT: CXXTemporaryObjectExpr {{.*}} 'struct brace_initializers::HasCtorDtor' + // CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 1{{$}} + // CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 2{{$}} +#endif + } + + struct PrivateDtor { + int x, y; + private: + ~PrivateDtor(); // expected-note {{declared private here}} + }; + + void testPrivateDtor() { + (void)(PrivateDtor){1, 2}; // expected-error {{temporary of type 'brace_initializers::PrivateDtor' has private destructor}} + } +} + +// This doesn't necessarily need to be an error, but CodeGen can't handle it +// at the moment. +int PR17415 = (int){PR17415}; // expected-error {{initializer element is not a compile-time constant}} + +// Make sure we accept this. (Not sure if we actually should... but we do +// at the moment.) +template<unsigned> struct Value { }; +template<typename T> +int &check_narrowed(Value<sizeof((T){1.1})>); + +#if __cplusplus >= 201103L +// Compound literals in global lambdas have automatic storage duration +// and are not subject to the constant-initialization rules. +int computed_with_lambda = [] { + int x = 5; + int result = ((int[]) { x, x + 2, x + 4, x + 6 })[0]; + return result; +}(); +#endif diff --git a/clang/test/SemaCXX/sourceranges.cpp b/clang/test/SemaCXX/sourceranges.cpp index 287925f7ffd..2f8eb2f2b96 100644 --- a/clang/test/SemaCXX/sourceranges.cpp +++ b/clang/test/SemaCXX/sourceranges.cpp @@ -1,52 +1,52 @@ -// RUN: %clang_cc1 -triple i686-mingw32 -ast-dump %s | FileCheck %s
-
-template<class T>
-class P {
- public:
- P(T* t) {}
-};
-
-namespace foo {
-class A { public: A(int = 0) {} };
-enum B {};
-typedef int C;
-}
-
-// CHECK: VarDecl {{0x[0-9a-fA-F]+}} <line:16:1, col:36> col:15 ImplicitConstrArray 'foo::A [2]'
-static foo::A ImplicitConstrArray[2];
-
-int main() {
- // CHECK: CXXNewExpr {{0x[0-9a-fA-F]+}} <col:19, col:28> 'foo::A *'
- P<foo::A> p14 = new foo::A;
- // CHECK: CXXNewExpr {{0x[0-9a-fA-F]+}} <col:19, col:28> 'foo::B *'
- P<foo::B> p24 = new foo::B;
- // CHECK: CXXNewExpr {{0x[0-9a-fA-F]+}} <col:19, col:28> 'foo::C *'
- P<foo::C> pr4 = new foo::C;
-}
-
-foo::A getName() {
- // CHECK: CXXConstructExpr {{0x[0-9a-fA-F]+}} <col:10, col:17> 'foo::A'
- return foo::A();
-}
-
-void destruct(foo::A *a1, foo::A *a2, P<int> *p1) {
- // CHECK: MemberExpr {{0x[0-9a-fA-F]+}} <col:3, col:8> '<bound member function type>' ->~A
- a1->~A();
- // CHECK: MemberExpr {{0x[0-9a-fA-F]+}} <col:3, col:16> '<bound member function type>' ->~A
- a2->foo::A::~A();
- // CHECK: MemberExpr {{0x[0-9a-fA-F]+}} <col:3, col:13> '<bound member function type>' ->~P
- p1->~P<int>();
-}
-
-struct D {
- D(int);
- ~D();
-};
-
-void construct() {
- using namespace foo;
- A a = A(12);
- // CHECK: CXXConstructExpr {{0x[0-9a-fA-F]+}} <col:9, col:13> 'foo::A' 'void (int){{( __attribute__\(\(thiscall\)\))?}}'
- D d = D(12);
- // CHECK: CXXConstructExpr {{0x[0-9a-fA-F]+}} <col:9, col:13> 'D' 'void (int){{( __attribute__\(\(thiscall\)\))?}}'
-}
+// RUN: %clang_cc1 -triple i686-mingw32 -ast-dump %s | FileCheck %s + +template<class T> +class P { + public: + P(T* t) {} +}; + +namespace foo { +class A { public: A(int = 0) {} }; +enum B {}; +typedef int C; +} + +// CHECK: VarDecl {{0x[0-9a-fA-F]+}} <line:16:1, col:36> col:15 ImplicitConstrArray 'foo::A [2]' +static foo::A ImplicitConstrArray[2]; + +int main() { + // CHECK: CXXNewExpr {{0x[0-9a-fA-F]+}} <col:19, col:28> 'foo::A *' + P<foo::A> p14 = new foo::A; + // CHECK: CXXNewExpr {{0x[0-9a-fA-F]+}} <col:19, col:28> 'foo::B *' + P<foo::B> p24 = new foo::B; + // CHECK: CXXNewExpr {{0x[0-9a-fA-F]+}} <col:19, col:28> 'foo::C *' + P<foo::C> pr4 = new foo::C; +} + +foo::A getName() { + // CHECK: CXXConstructExpr {{0x[0-9a-fA-F]+}} <col:10, col:17> 'foo::A' + return foo::A(); +} + +void destruct(foo::A *a1, foo::A *a2, P<int> *p1) { + // CHECK: MemberExpr {{0x[0-9a-fA-F]+}} <col:3, col:8> '<bound member function type>' ->~A + a1->~A(); + // CHECK: MemberExpr {{0x[0-9a-fA-F]+}} <col:3, col:16> '<bound member function type>' ->~A + a2->foo::A::~A(); + // CHECK: MemberExpr {{0x[0-9a-fA-F]+}} <col:3, col:13> '<bound member function type>' ->~P + p1->~P<int>(); +} + +struct D { + D(int); + ~D(); +}; + +void construct() { + using namespace foo; + A a = A(12); + // CHECK: CXXConstructExpr {{0x[0-9a-fA-F]+}} <col:9, col:13> 'class foo::A' 'void (int){{( __attribute__\(\(thiscall\)\))?}}' + D d = D(12); + // CHECK: CXXConstructExpr {{0x[0-9a-fA-F]+}} <col:9, col:13> 'struct D' 'void (int){{( __attribute__\(\(thiscall\)\))?}}' +} diff --git a/clang/test/SemaCXX/warn-redundant-move.cpp b/clang/test/SemaCXX/warn-redundant-move.cpp index 2bfc8c9312f..abfb001fa8e 100644 --- a/clang/test/SemaCXX/warn-redundant-move.cpp +++ b/clang/test/SemaCXX/warn-redundant-move.cpp @@ -1,116 +1,116 @@ -// RUN: %clang_cc1 -fsyntax-only -Wredundant-move -std=c++11 -verify %s
-// RUN: %clang_cc1 -fsyntax-only -Wredundant-move -std=c++11 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
-// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -ast-dump | FileCheck %s --check-prefix=CHECK-AST
-
-// definitions for std::move
-namespace std {
-inline namespace foo {
-template <class T> struct remove_reference { typedef T type; };
-template <class T> struct remove_reference<T&> { typedef T type; };
-template <class T> struct remove_reference<T&&> { typedef T type; };
-
-template <class T> typename remove_reference<T>::type &&move(T &&t);
-}
-}
-
-// test1 and test2 should not warn until after implementation of DR1579.
-struct A {};
-struct B : public A {};
-
-A test1(B b1) {
- B b2;
- return b1;
- return b2;
- return std::move(b1);
- return std::move(b2);
-}
-
-struct C {
- C() {}
- C(A) {}
-};
-
-C test2(A a1, B b1) {
- A a2;
- B b2;
-
- return a1;
- return a2;
- return b1;
- return b2;
-
- return std::move(a1);
- return std::move(a2);
- return std::move(b1);
- return std::move(b2);
-}
-
-// Copy of tests above with types changed to reference types.
-A test3(B& b1) {
- B& b2 = b1;
- return b1;
- return b2;
- return std::move(b1);
- return std::move(b2);
-}
-
-C test4(A& a1, B& b1) {
- A& a2 = a1;
- B& b2 = b1;
-
- return a1;
- return a2;
- return b1;
- return b2;
-
- return std::move(a1);
- return std::move(a2);
- return std::move(b1);
- return std::move(b2);
-}
-
-// PR23819, case 2
-struct D {};
-D test5(D d) {
- return d;
- // Verify the implicit move from the AST dump
- // CHECK-AST: ReturnStmt{{.*}}line:[[@LINE-2]]
- // CHECK-AST-NEXT: CXXConstructExpr{{.*}}D{{.*}}void (D &&)
- // CHECK-AST-NEXT: ImplicitCastExpr
- // CHECK-AST-NEXT: DeclRefExpr{{.*}}ParmVar{{.*}}'d'
-
- return std::move(d);
- // expected-warning@-1{{redundant move in return statement}}
- // expected-note@-2{{remove std::move call here}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:""
- // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:21-[[@LINE-4]]:22}:""
-}
-
-namespace templates {
- struct A {};
- struct B { B(A); };
-
- // Warn once here since the type is not dependent.
- template <typename T>
- A test1(A a) {
- return std::move(a);
- // expected-warning@-1{{redundant move in return statement}}
- // expected-note@-2{{remove std::move call here}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:22}:""
- // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:23-[[@LINE-4]]:24}:""
- }
- void run_test1() {
- test1<A>(A());
- test1<B>(A());
- }
-
- // T1 and T2 may not be the same, the warning may not always apply.
- template <typename T1, typename T2>
- T1 test2(T2 t) {
- return std::move(t);
- }
- void run_test2() {
- test2<A, A>(A());
- test2<B, A>(A());
- }
-}
+// RUN: %clang_cc1 -fsyntax-only -Wredundant-move -std=c++11 -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wredundant-move -std=c++11 -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s +// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -ast-dump | FileCheck %s --check-prefix=CHECK-AST + +// definitions for std::move +namespace std { +inline namespace foo { +template <class T> struct remove_reference { typedef T type; }; +template <class T> struct remove_reference<T&> { typedef T type; }; +template <class T> struct remove_reference<T&&> { typedef T type; }; + +template <class T> typename remove_reference<T>::type &&move(T &&t); +} +} + +// test1 and test2 should not warn until after implementation of DR1579. +struct A {}; +struct B : public A {}; + +A test1(B b1) { + B b2; + return b1; + return b2; + return std::move(b1); + return std::move(b2); +} + +struct C { + C() {} + C(A) {} +}; + +C test2(A a1, B b1) { + A a2; + B b2; + + return a1; + return a2; + return b1; + return b2; + + return std::move(a1); + return std::move(a2); + return std::move(b1); + return std::move(b2); +} + +// Copy of tests above with types changed to reference types. +A test3(B& b1) { + B& b2 = b1; + return b1; + return b2; + return std::move(b1); + return std::move(b2); +} + +C test4(A& a1, B& b1) { + A& a2 = a1; + B& b2 = b1; + + return a1; + return a2; + return b1; + return b2; + + return std::move(a1); + return std::move(a2); + return std::move(b1); + return std::move(b2); +} + +// PR23819, case 2 +struct D {}; +D test5(D d) { + return d; + // Verify the implicit move from the AST dump + // CHECK-AST: ReturnStmt{{.*}}line:[[@LINE-2]] + // CHECK-AST-NEXT: CXXConstructExpr{{.*}}struct D{{.*}}void (struct D &&) + // CHECK-AST-NEXT: ImplicitCastExpr + // CHECK-AST-NEXT: DeclRefExpr{{.*}}ParmVar{{.*}}'d' + + return std::move(d); + // expected-warning@-1{{redundant move in return statement}} + // expected-note@-2{{remove std::move call here}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:10-[[@LINE-3]]:20}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:21-[[@LINE-4]]:22}:"" +} + +namespace templates { + struct A {}; + struct B { B(A); }; + + // Warn once here since the type is not dependent. + template <typename T> + A test1(A a) { + return std::move(a); + // expected-warning@-1{{redundant move in return statement}} + // expected-note@-2{{remove std::move call here}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:12-[[@LINE-3]]:22}:"" + // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:23-[[@LINE-4]]:24}:"" + } + void run_test1() { + test1<A>(A()); + test1<B>(A()); + } + + // T1 and T2 may not be the same, the warning may not always apply. + template <typename T1, typename T2> + T1 test2(T2 t) { + return std::move(t); + } + void run_test2() { + test2<A, A>(A()); + test2<B, A>(A()); + } +} diff --git a/clang/test/SemaObjCXX/block-cleanup.mm b/clang/test/SemaObjCXX/block-cleanup.mm index 53b2c224ab5..0c6a6d8c26f 100644 --- a/clang/test/SemaObjCXX/block-cleanup.mm +++ b/clang/test/SemaObjCXX/block-cleanup.mm @@ -1,16 +1,16 @@ -// RUN: %clang_cc1 -triple x86_64-apple-macosx10.11.0 -std=gnu++11 -o /dev/null -x objective-c++ -fblocks -ast-dump %s 2>&1 | FileCheck %s
-
-// CHECK: -FunctionDecl {{.*}} test 'id ()'
-// CHECK-NEXT: -CompoundStmt
-// CHECK-NEXT: -ReturnStmt
-// CHECK-NEXT: -ExprWithCleanups
-// CHECK-NEXT: -cleanup Block
-// CHECK-NEXT: -cleanup Block
-
-@interface NSDictionary
-+ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt;
-@end
-
-id test() {
- return @{@"a": [](){}, @"b": [](){}};
-}
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.11.0 -std=gnu++11 -o /dev/null -x objective-c++ -fblocks -ast-dump %s 2>&1 | FileCheck %s + +// CHECK: -FunctionDecl {{.*}} test 'id (void)' +// CHECK-NEXT: -CompoundStmt +// CHECK-NEXT: -ReturnStmt +// CHECK-NEXT: -ExprWithCleanups +// CHECK-NEXT: -cleanup Block +// CHECK-NEXT: -cleanup Block + +@interface NSDictionary ++ (id)dictionaryWithObjects:(const id [])objects forKeys:(const id [])keys count:(unsigned long)cnt; +@end + +id test() { + return @{@"a": [](){}, @"b": [](){}}; +} diff --git a/clang/test/SemaTemplate/default-expr-arguments-2.cpp b/clang/test/SemaTemplate/default-expr-arguments-2.cpp index bfe87a931b9..037949455f5 100644 --- a/clang/test/SemaTemplate/default-expr-arguments-2.cpp +++ b/clang/test/SemaTemplate/default-expr-arguments-2.cpp @@ -9,8 +9,8 @@ namespace PR6733 { public: enum { kSomeConst = 128 }; bar(int x = kSomeConst) {} }; - - // CHECK: FunctionDecl{{.*}}f 'void ()' + + // CHECK: FunctionDecl{{.*}}f 'void (void)' void f() { // CHECK: VarDecl{{.*}}tmp 'bar<int>' // CHECK: CXXDefaultArgExpr{{.*}}'int' diff --git a/clang/test/SemaTemplate/default-expr-arguments-3.cpp b/clang/test/SemaTemplate/default-expr-arguments-3.cpp index 4d04209e110..4449eb7100a 100644 --- a/clang/test/SemaTemplate/default-expr-arguments-3.cpp +++ b/clang/test/SemaTemplate/default-expr-arguments-3.cpp @@ -1,55 +1,55 @@ -// RUN: %clang_cc1 -std=c++14 -verify -ast-dump %s | FileCheck %s
-// expected-no-diagnostics
-
-// CHECK: FunctionDecl {{.*}} used func 'void ()'
-// CHECK-NEXT: TemplateArgument type 'int'
-// CHECK: LambdaExpr {{.*}} '(lambda at
-// CHECK: ParmVarDecl {{.*}} used f 'foo' cinit
-// CHECK-NEXT: DeclRefExpr {{.*}} 'foo' EnumConstant {{.*}} 'a' 'foo'
-
-namespace PR28795 {
- template<typename T>
- void func() {
- enum class foo { a, b };
- auto bar = [](foo f = foo::a) { return f; };
- bar();
- }
-
- void foo() {
- func<int>();
- }
-}
-
-// CHECK: ClassTemplateSpecializationDecl {{.*}} struct class2 definition
-// CHECK: TemplateArgument type 'int'
-// CHECK: LambdaExpr {{.*}} '(lambda at
-// CHECK: ParmVarDecl {{.*}} used f 'foo' cinit
-// CHECK-NEXT: DeclRefExpr {{.*}} 'foo' EnumConstant {{.*}} 'a' 'foo'
-
-// Template struct case:
-template <class T> struct class2 {
- void bar() {
- enum class foo { a, b };
- [](foo f = foo::a) { return f; }();
- }
-};
-
-template struct class2<int>;
-
-// CHECK: FunctionTemplateDecl {{.*}} f1
-// CHECK-NEXT: TemplateTypeParmDecl {{.*}} typename depth 0 index 0 T
-// CHECK-NEXT: FunctionDecl {{.*}} f1 'void ()'
-// CHECK: FunctionDecl {{.*}} f1 'void ()'
-// CHECK-NEXT: TemplateArgument type 'int'
-// CHECK: ParmVarDecl {{.*}} n 'foo' cinit
-// CHECK-NEXT: DeclRefExpr {{.*}} 'foo' EnumConstant {{.*}} 'a' 'foo'
-
-template<typename T>
-void f1() {
- enum class foo { a, b };
- struct S {
- int g1(foo n = foo::a);
- };
-}
-
-template void f1<int>();
+// RUN: %clang_cc1 -std=c++14 -verify -ast-dump %s | FileCheck %s +// expected-no-diagnostics + +// CHECK: FunctionDecl {{.*}} used func 'void (void)' +// CHECK-NEXT: TemplateArgument type 'int' +// CHECK: LambdaExpr {{.*}} 'class (lambda at +// CHECK: ParmVarDecl {{.*}} used f 'enum foo' cinit +// CHECK-NEXT: DeclRefExpr {{.*}} 'enum foo' EnumConstant {{.*}} 'a' 'enum foo' + +namespace PR28795 { + template<typename T> + void func() { + enum class foo { a, b }; + auto bar = [](foo f = foo::a) { return f; }; + bar(); + } + + void foo() { + func<int>(); + } +} + +// CHECK: ClassTemplateSpecializationDecl {{.*}} struct class2 definition +// CHECK: TemplateArgument type 'int' +// CHECK: LambdaExpr {{.*}} 'class (lambda at +// CHECK: ParmVarDecl {{.*}} used f 'enum foo' cinit +// CHECK-NEXT: DeclRefExpr {{.*}} 'enum foo' EnumConstant {{.*}} 'a' 'enum foo' + +// Template struct case: +template <class T> struct class2 { + void bar() { + enum class foo { a, b }; + [](foo f = foo::a) { return f; }(); + } +}; + +template struct class2<int>; + +// CHECK: FunctionTemplateDecl {{.*}} f1 +// CHECK-NEXT: TemplateTypeParmDecl {{.*}} typename depth 0 index 0 T +// CHECK-NEXT: FunctionDecl {{.*}} f1 'void (void)' +// CHECK: FunctionDecl {{.*}} f1 'void (void)' +// CHECK-NEXT: TemplateArgument type 'int' +// CHECK: ParmVarDecl {{.*}} n 'enum foo' cinit +// CHECK-NEXT: DeclRefExpr {{.*}} 'enum foo' EnumConstant {{.*}} 'a' 'enum foo' + +template<typename T> +void f1() { + enum class foo { a, b }; + struct S { + int g1(foo n = foo::a); + }; +} + +template void f1<int>(); |