Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,31 @@
//===--- ASTConsumer.cpp - Abstract interface for reading ASTs --*- 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 the ASTConsumer class.
//
//===----------------------------------------------------------------------===//
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclGroup.h"
using namespace clang;
bool ASTConsumer::HandleTopLevelDecl(DeclGroupRef D) {
return true;
}
void ASTConsumer::HandleInterestingDecl(DeclGroupRef D) {
HandleTopLevelDecl(D);
}
void ASTConsumer::HandleTopLevelDeclInObjCContainer(DeclGroupRef D) {}
void ASTConsumer::HandleImplicitImportDecl(ImportDecl *D) {
HandleTopLevelDecl(DeclGroupRef(D));
}

View File

@@ -0,0 +1 @@
c73ae9efe1701e9df08eddff1935b140b8cb95f8

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
0d1d9807549f59090f070f1948b6aec3364f3254

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,159 @@
//===--- ASTTypeTraits.cpp --------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Provides a dynamic type identifier and a dynamically typed node container
// that can be used to store an AST base node at runtime in the same storage in
// a type safe way.
//
//===----------------------------------------------------------------------===//
#include "clang/AST/ASTTypeTraits.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclCXX.h"
namespace clang {
namespace ast_type_traits {
const ASTNodeKind::KindInfo ASTNodeKind::AllKindInfo[] = {
{ NKI_None, "<None>" },
{ NKI_None, "TemplateArgument" },
{ NKI_None, "TemplateName" },
{ NKI_None, "NestedNameSpecifierLoc" },
{ NKI_None, "QualType" },
{ NKI_None, "TypeLoc" },
{ NKI_None, "CXXCtorInitializer" },
{ NKI_None, "NestedNameSpecifier" },
{ NKI_None, "Decl" },
#define DECL(DERIVED, BASE) { NKI_##BASE, #DERIVED "Decl" },
#include "clang/AST/DeclNodes.inc"
{ NKI_None, "Stmt" },
#define STMT(DERIVED, BASE) { NKI_##BASE, #DERIVED },
#include "clang/AST/StmtNodes.inc"
{ NKI_None, "Type" },
#define TYPE(DERIVED, BASE) { NKI_##BASE, #DERIVED "Type" },
#include "clang/AST/TypeNodes.def"
};
bool ASTNodeKind::isBaseOf(ASTNodeKind Other, unsigned *Distance) const {
return isBaseOf(KindId, Other.KindId, Distance);
}
bool ASTNodeKind::isBaseOf(NodeKindId Base, NodeKindId Derived,
unsigned *Distance) {
if (Base == NKI_None || Derived == NKI_None) return false;
unsigned Dist = 0;
while (Derived != Base && Derived != NKI_None) {
Derived = AllKindInfo[Derived].ParentId;
++Dist;
}
if (Distance)
*Distance = Dist;
return Derived == Base;
}
StringRef ASTNodeKind::asStringRef() const { return AllKindInfo[KindId].Name; }
ASTNodeKind ASTNodeKind::getMostDerivedType(ASTNodeKind Kind1,
ASTNodeKind Kind2) {
if (Kind1.isBaseOf(Kind2)) return Kind2;
if (Kind2.isBaseOf(Kind1)) return Kind1;
return ASTNodeKind();
}
ASTNodeKind ASTNodeKind::getMostDerivedCommonAncestor(ASTNodeKind Kind1,
ASTNodeKind Kind2) {
NodeKindId Parent = Kind1.KindId;
while (!isBaseOf(Parent, Kind2.KindId, nullptr) && Parent != NKI_None) {
Parent = AllKindInfo[Parent].ParentId;
}
return ASTNodeKind(Parent);
}
ASTNodeKind ASTNodeKind::getFromNode(const Decl &D) {
switch (D.getKind()) {
#define DECL(DERIVED, BASE) \
case Decl::DERIVED: return ASTNodeKind(NKI_##DERIVED##Decl);
#define ABSTRACT_DECL(D)
#include "clang/AST/DeclNodes.inc"
};
llvm_unreachable("invalid decl kind");
}
ASTNodeKind ASTNodeKind::getFromNode(const Stmt &S) {
switch (S.getStmtClass()) {
case Stmt::NoStmtClass: return NKI_None;
#define STMT(CLASS, PARENT) \
case Stmt::CLASS##Class: return ASTNodeKind(NKI_##CLASS);
#define ABSTRACT_STMT(S)
#include "clang/AST/StmtNodes.inc"
}
llvm_unreachable("invalid stmt kind");
}
ASTNodeKind ASTNodeKind::getFromNode(const Type &T) {
switch (T.getTypeClass()) {
#define TYPE(Class, Base) \
case Type::Class: return ASTNodeKind(NKI_##Class##Type);
#define ABSTRACT_TYPE(Class, Base)
#include "clang/AST/TypeNodes.def"
}
llvm_unreachable("invalid type kind");
}
void DynTypedNode::print(llvm::raw_ostream &OS,
const PrintingPolicy &PP) const {
if (const TemplateArgument *TA = get<TemplateArgument>())
TA->print(PP, OS);
else if (const TemplateName *TN = get<TemplateName>())
TN->print(OS, PP);
else if (const NestedNameSpecifier *NNS = get<NestedNameSpecifier>())
NNS->print(OS, PP);
else if (const NestedNameSpecifierLoc *NNSL = get<NestedNameSpecifierLoc>())
NNSL->getNestedNameSpecifier()->print(OS, PP);
else if (const QualType *QT = get<QualType>())
QT->print(OS, PP);
else if (const TypeLoc *TL = get<TypeLoc>())
TL->getType().print(OS, PP);
else if (const Decl *D = get<Decl>())
D->print(OS, PP);
else if (const Stmt *S = get<Stmt>())
S->printPretty(OS, nullptr, PP);
else if (const Type *T = get<Type>())
QualType(T, 0).print(OS, PP);
else
OS << "Unable to print values of type " << NodeKind.asStringRef() << "\n";
}
void DynTypedNode::dump(llvm::raw_ostream &OS, SourceManager &SM) const {
if (const Decl *D = get<Decl>())
D->dump(OS);
else if (const Stmt *S = get<Stmt>())
S->dump(OS, SM);
else if (const Type *T = get<Type>())
T->dump(OS);
else
OS << "Unable to dump values of type " << NodeKind.asStringRef() << "\n";
}
SourceRange DynTypedNode::getSourceRange() const {
if (const CXXCtorInitializer *CCI = get<CXXCtorInitializer>())
return CCI->getSourceRange();
if (const NestedNameSpecifierLoc *NNSL = get<NestedNameSpecifierLoc>())
return NNSL->getSourceRange();
if (const TypeLoc *TL = get<TypeLoc>())
return TL->getSourceRange();
if (const Decl *D = get<Decl>())
return D->getSourceRange();
if (const Stmt *S = get<Stmt>())
return S->getSourceRange();
return SourceRange();
}
} // end namespace ast_type_traits
} // end namespace clang

View File

@@ -0,0 +1,20 @@
//===--- AttrImpl.cpp - Classes for representing attributes -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains out-of-line methods for Attr classes.
//
//===----------------------------------------------------------------------===//
#include "clang/AST/ASTContext.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Expr.h"
#include "clang/AST/Type.h"
using namespace clang;
#include "clang/AST/AttrImpl.inc"

View File

@@ -0,0 +1,76 @@
set(LLVM_LINK_COMPONENTS
BinaryFormat
Support
)
add_clang_library(clangAST
APValue.cpp
ASTConsumer.cpp
ASTContext.cpp
ASTDiagnostic.cpp
ASTDumper.cpp
ASTImporter.cpp
ASTStructuralEquivalence.cpp
ASTTypeTraits.cpp
AttrImpl.cpp
CXXInheritance.cpp
Comment.cpp
CommentBriefParser.cpp
CommentCommandTraits.cpp
CommentLexer.cpp
CommentParser.cpp
CommentSema.cpp
DataCollection.cpp
Decl.cpp
DeclarationName.cpp
DeclBase.cpp
DeclCXX.cpp
DeclFriend.cpp
DeclGroup.cpp
DeclObjC.cpp
DeclOpenMP.cpp
DeclPrinter.cpp
DeclTemplate.cpp
Expr.cpp
ExprClassification.cpp
ExprConstant.cpp
ExprCXX.cpp
ExprObjC.cpp
ExternalASTMerger.cpp
ExternalASTSource.cpp
InheritViz.cpp
ItaniumCXXABI.cpp
ItaniumMangle.cpp
Mangle.cpp
MicrosoftCXXABI.cpp
MicrosoftMangle.cpp
NestedNameSpecifier.cpp
NSAPI.cpp
ODRHash.cpp
OpenMPClause.cpp
ParentMap.cpp
QualTypeNames.cpp
RawCommentList.cpp
RecordLayout.cpp
RecordLayoutBuilder.cpp
SelectorLocationsKind.cpp
Stmt.cpp
StmtCXX.cpp
StmtIterator.cpp
StmtObjC.cpp
StmtOpenMP.cpp
StmtPrinter.cpp
StmtProfile.cpp
StmtViz.cpp
TemplateBase.cpp
TemplateName.cpp
Type.cpp
TypeLoc.cpp
TypePrinter.cpp
VTableBuilder.cpp
VTTBuilder.cpp
LINK_LIBS
clangBasic
clangLex
)

View File

@@ -0,0 +1,81 @@
//===----- CXXABI.h - Interface to C++ ABIs ---------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This provides an abstract class for C++ AST support. Concrete
// subclasses of this implement AST support for specific C++ ABIs.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_LIB_AST_CXXABI_H
#define LLVM_CLANG_LIB_AST_CXXABI_H
#include "clang/AST/Type.h"
namespace clang {
class ASTContext;
class CXXConstructorDecl;
class DeclaratorDecl;
class Expr;
class MemberPointerType;
class MangleNumberingContext;
/// Implements C++ ABI-specific semantic analysis functions.
class CXXABI {
public:
virtual ~CXXABI();
struct MemberPointerInfo {
uint64_t Width;
unsigned Align;
bool HasPadding;
};
/// Returns the width and alignment of a member pointer in bits, as well as
/// whether it has padding.
virtual MemberPointerInfo
getMemberPointerInfo(const MemberPointerType *MPT) const = 0;
/// Returns the default calling convention for C++ methods.
virtual CallingConv getDefaultMethodCallConv(bool isVariadic) const = 0;
/// Returns whether the given class is nearly empty, with just virtual
/// pointers and no data except possibly virtual bases.
virtual bool isNearlyEmpty(const CXXRecordDecl *RD) const = 0;
/// Returns a new mangling number context for this C++ ABI.
virtual std::unique_ptr<MangleNumberingContext>
createMangleNumberingContext() const = 0;
/// Adds a mapping from class to copy constructor for this C++ ABI.
virtual void addCopyConstructorForExceptionObject(CXXRecordDecl *,
CXXConstructorDecl *) = 0;
/// Retrieves the mapping from class to copy constructor for this C++ ABI.
virtual const CXXConstructorDecl *
getCopyConstructorForExceptionObject(CXXRecordDecl *) = 0;
virtual void addTypedefNameForUnnamedTagDecl(TagDecl *TD,
TypedefNameDecl *DD) = 0;
virtual TypedefNameDecl *
getTypedefNameForUnnamedTagDecl(const TagDecl *TD) = 0;
virtual void addDeclaratorForUnnamedTagDecl(TagDecl *TD,
DeclaratorDecl *DD) = 0;
virtual DeclaratorDecl *getDeclaratorForUnnamedTagDecl(const TagDecl *TD) = 0;
};
/// Creates an instance of a C++ ABI class.
CXXABI *CreateItaniumCXXABI(ASTContext &Ctx);
CXXABI *CreateMicrosoftCXXABI(ASTContext &Ctx);
}
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,380 @@
//===--- Comment.cpp - Comment AST node implementation --------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "clang/AST/Comment.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/Basic/CharInfo.h"
#include "llvm/Support/ErrorHandling.h"
namespace clang {
namespace comments {
const char *Comment::getCommentKindName() const {
switch (getCommentKind()) {
case NoCommentKind: return "NoCommentKind";
#define ABSTRACT_COMMENT(COMMENT)
#define COMMENT(CLASS, PARENT) \
case CLASS##Kind: \
return #CLASS;
#include "clang/AST/CommentNodes.inc"
#undef COMMENT
#undef ABSTRACT_COMMENT
}
llvm_unreachable("Unknown comment kind!");
}
namespace {
struct good {};
struct bad {};
template <typename T>
good implements_child_begin_end(Comment::child_iterator (T::*)() const) {
return good();
}
LLVM_ATTRIBUTE_UNUSED
static inline bad implements_child_begin_end(
Comment::child_iterator (Comment::*)() const) {
return bad();
}
#define ASSERT_IMPLEMENTS_child_begin(function) \
(void) good(implements_child_begin_end(function))
LLVM_ATTRIBUTE_UNUSED
static inline void CheckCommentASTNodes() {
#define ABSTRACT_COMMENT(COMMENT)
#define COMMENT(CLASS, PARENT) \
ASSERT_IMPLEMENTS_child_begin(&CLASS::child_begin); \
ASSERT_IMPLEMENTS_child_begin(&CLASS::child_end);
#include "clang/AST/CommentNodes.inc"
#undef COMMENT
#undef ABSTRACT_COMMENT
}
#undef ASSERT_IMPLEMENTS_child_begin
} // end unnamed namespace
Comment::child_iterator Comment::child_begin() const {
switch (getCommentKind()) {
case NoCommentKind: llvm_unreachable("comment without a kind");
#define ABSTRACT_COMMENT(COMMENT)
#define COMMENT(CLASS, PARENT) \
case CLASS##Kind: \
return static_cast<const CLASS *>(this)->child_begin();
#include "clang/AST/CommentNodes.inc"
#undef COMMENT
#undef ABSTRACT_COMMENT
}
llvm_unreachable("Unknown comment kind!");
}
Comment::child_iterator Comment::child_end() const {
switch (getCommentKind()) {
case NoCommentKind: llvm_unreachable("comment without a kind");
#define ABSTRACT_COMMENT(COMMENT)
#define COMMENT(CLASS, PARENT) \
case CLASS##Kind: \
return static_cast<const CLASS *>(this)->child_end();
#include "clang/AST/CommentNodes.inc"
#undef COMMENT
#undef ABSTRACT_COMMENT
}
llvm_unreachable("Unknown comment kind!");
}
bool TextComment::isWhitespaceNoCache() const {
for (StringRef::const_iterator I = Text.begin(), E = Text.end();
I != E; ++I) {
if (!clang::isWhitespace(*I))
return false;
}
return true;
}
bool ParagraphComment::isWhitespaceNoCache() const {
for (child_iterator I = child_begin(), E = child_end(); I != E; ++I) {
if (const TextComment *TC = dyn_cast<TextComment>(*I)) {
if (!TC->isWhitespace())
return false;
} else
return false;
}
return true;
}
static TypeLoc lookThroughTypedefOrTypeAliasLocs(TypeLoc &SrcTL) {
TypeLoc TL = SrcTL.IgnoreParens();
// Look through attribute types.
if (AttributedTypeLoc AttributeTL = TL.getAs<AttributedTypeLoc>())
return AttributeTL.getModifiedLoc();
// Look through qualified types.
if (QualifiedTypeLoc QualifiedTL = TL.getAs<QualifiedTypeLoc>())
return QualifiedTL.getUnqualifiedLoc();
// Look through pointer types.
if (PointerTypeLoc PointerTL = TL.getAs<PointerTypeLoc>())
return PointerTL.getPointeeLoc().getUnqualifiedLoc();
// Look through reference types.
if (ReferenceTypeLoc ReferenceTL = TL.getAs<ReferenceTypeLoc>())
return ReferenceTL.getPointeeLoc().getUnqualifiedLoc();
// Look through adjusted types.
if (AdjustedTypeLoc ATL = TL.getAs<AdjustedTypeLoc>())
return ATL.getOriginalLoc();
if (BlockPointerTypeLoc BlockPointerTL = TL.getAs<BlockPointerTypeLoc>())
return BlockPointerTL.getPointeeLoc().getUnqualifiedLoc();
if (MemberPointerTypeLoc MemberPointerTL = TL.getAs<MemberPointerTypeLoc>())
return MemberPointerTL.getPointeeLoc().getUnqualifiedLoc();
if (ElaboratedTypeLoc ETL = TL.getAs<ElaboratedTypeLoc>())
return ETL.getNamedTypeLoc();
return TL;
}
static bool getFunctionTypeLoc(TypeLoc TL, FunctionTypeLoc &ResFTL) {
TypeLoc PrevTL;
while (PrevTL != TL) {
PrevTL = TL;
TL = lookThroughTypedefOrTypeAliasLocs(TL);
}
if (FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>()) {
ResFTL = FTL;
return true;
}
if (TemplateSpecializationTypeLoc STL =
TL.getAs<TemplateSpecializationTypeLoc>()) {
// If we have a typedef to a template specialization with exactly one
// template argument of a function type, this looks like std::function,
// boost::function, or other function wrapper. Treat these typedefs as
// functions.
if (STL.getNumArgs() != 1)
return false;
TemplateArgumentLoc MaybeFunction = STL.getArgLoc(0);
if (MaybeFunction.getArgument().getKind() != TemplateArgument::Type)
return false;
TypeSourceInfo *MaybeFunctionTSI = MaybeFunction.getTypeSourceInfo();
TypeLoc TL = MaybeFunctionTSI->getTypeLoc().getUnqualifiedLoc();
if (FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>()) {
ResFTL = FTL;
return true;
}
}
return false;
}
const char *ParamCommandComment::getDirectionAsString(PassDirection D) {
switch (D) {
case ParamCommandComment::In:
return "[in]";
case ParamCommandComment::Out:
return "[out]";
case ParamCommandComment::InOut:
return "[in,out]";
}
llvm_unreachable("unknown PassDirection");
}
void DeclInfo::fill() {
assert(!IsFilled);
// Set defaults.
Kind = OtherKind;
TemplateKind = NotTemplate;
IsObjCMethod = false;
IsInstanceMethod = false;
IsClassMethod = false;
ParamVars = None;
TemplateParameters = nullptr;
if (!CommentDecl) {
// If there is no declaration, the defaults is our only guess.
IsFilled = true;
return;
}
CurrentDecl = CommentDecl;
Decl::Kind K = CommentDecl->getKind();
switch (K) {
default:
// Defaults are should be good for declarations we don't handle explicitly.
break;
case Decl::Function:
case Decl::CXXMethod:
case Decl::CXXConstructor:
case Decl::CXXDestructor:
case Decl::CXXConversion: {
const FunctionDecl *FD = cast<FunctionDecl>(CommentDecl);
Kind = FunctionKind;
ParamVars = FD->parameters();
ReturnType = FD->getReturnType();
unsigned NumLists = FD->getNumTemplateParameterLists();
if (NumLists != 0) {
TemplateKind = TemplateSpecialization;
TemplateParameters =
FD->getTemplateParameterList(NumLists - 1);
}
if (K == Decl::CXXMethod || K == Decl::CXXConstructor ||
K == Decl::CXXDestructor || K == Decl::CXXConversion) {
const CXXMethodDecl *MD = cast<CXXMethodDecl>(CommentDecl);
IsInstanceMethod = MD->isInstance();
IsClassMethod = !IsInstanceMethod;
}
break;
}
case Decl::ObjCMethod: {
const ObjCMethodDecl *MD = cast<ObjCMethodDecl>(CommentDecl);
Kind = FunctionKind;
ParamVars = MD->parameters();
ReturnType = MD->getReturnType();
IsObjCMethod = true;
IsInstanceMethod = MD->isInstanceMethod();
IsClassMethod = !IsInstanceMethod;
break;
}
case Decl::FunctionTemplate: {
const FunctionTemplateDecl *FTD = cast<FunctionTemplateDecl>(CommentDecl);
Kind = FunctionKind;
TemplateKind = Template;
const FunctionDecl *FD = FTD->getTemplatedDecl();
ParamVars = FD->parameters();
ReturnType = FD->getReturnType();
TemplateParameters = FTD->getTemplateParameters();
break;
}
case Decl::ClassTemplate: {
const ClassTemplateDecl *CTD = cast<ClassTemplateDecl>(CommentDecl);
Kind = ClassKind;
TemplateKind = Template;
TemplateParameters = CTD->getTemplateParameters();
break;
}
case Decl::ClassTemplatePartialSpecialization: {
const ClassTemplatePartialSpecializationDecl *CTPSD =
cast<ClassTemplatePartialSpecializationDecl>(CommentDecl);
Kind = ClassKind;
TemplateKind = TemplatePartialSpecialization;
TemplateParameters = CTPSD->getTemplateParameters();
break;
}
case Decl::ClassTemplateSpecialization:
Kind = ClassKind;
TemplateKind = TemplateSpecialization;
break;
case Decl::Record:
case Decl::CXXRecord:
Kind = ClassKind;
break;
case Decl::Var:
case Decl::Field:
case Decl::EnumConstant:
case Decl::ObjCIvar:
case Decl::ObjCAtDefsField:
case Decl::ObjCProperty: {
const TypeSourceInfo *TSI;
if (const auto *VD = dyn_cast<DeclaratorDecl>(CommentDecl))
TSI = VD->getTypeSourceInfo();
else if (const auto *PD = dyn_cast<ObjCPropertyDecl>(CommentDecl))
TSI = PD->getTypeSourceInfo();
else
TSI = nullptr;
if (TSI) {
TypeLoc TL = TSI->getTypeLoc().getUnqualifiedLoc();
FunctionTypeLoc FTL;
if (getFunctionTypeLoc(TL, FTL)) {
ParamVars = FTL.getParams();
ReturnType = FTL.getReturnLoc().getType();
}
}
Kind = VariableKind;
break;
}
case Decl::Namespace:
Kind = NamespaceKind;
break;
case Decl::TypeAlias:
case Decl::Typedef: {
Kind = TypedefKind;
// If this is a typedef / using to something we consider a function, extract
// arguments and return type.
const TypeSourceInfo *TSI =
K == Decl::Typedef
? cast<TypedefDecl>(CommentDecl)->getTypeSourceInfo()
: cast<TypeAliasDecl>(CommentDecl)->getTypeSourceInfo();
if (!TSI)
break;
TypeLoc TL = TSI->getTypeLoc().getUnqualifiedLoc();
FunctionTypeLoc FTL;
if (getFunctionTypeLoc(TL, FTL)) {
Kind = FunctionKind;
ParamVars = FTL.getParams();
ReturnType = FTL.getReturnLoc().getType();
}
break;
}
case Decl::TypeAliasTemplate: {
const TypeAliasTemplateDecl *TAT = cast<TypeAliasTemplateDecl>(CommentDecl);
Kind = TypedefKind;
TemplateKind = Template;
TemplateParameters = TAT->getTemplateParameters();
TypeAliasDecl *TAD = TAT->getTemplatedDecl();
if (!TAD)
break;
const TypeSourceInfo *TSI = TAD->getTypeSourceInfo();
if (!TSI)
break;
TypeLoc TL = TSI->getTypeLoc().getUnqualifiedLoc();
FunctionTypeLoc FTL;
if (getFunctionTypeLoc(TL, FTL)) {
Kind = FunctionKind;
ParamVars = FTL.getParams();
ReturnType = FTL.getReturnLoc().getType();
}
break;
}
case Decl::Enum:
Kind = EnumKind;
break;
}
IsFilled = true;
}
StringRef ParamCommandComment::getParamName(const FullComment *FC) const {
assert(isParamIndexValid());
if (isVarArgParam())
return "...";
return FC->getDeclInfo()->ParamVars[getParamIndex()]->getName();
}
StringRef TParamCommandComment::getParamName(const FullComment *FC) const {
assert(isPositionValid());
const TemplateParameterList *TPL = FC->getDeclInfo()->TemplateParameters;
for (unsigned i = 0, e = getDepth(); i != e; ++i) {
if (i == e-1)
return TPL->getParam(getIndex(i))->getName();
const NamedDecl *Param = TPL->getParam(getIndex(i));
if (const TemplateTemplateParmDecl *TTP =
dyn_cast<TemplateTemplateParmDecl>(Param))
TPL = TTP->getTemplateParameters();
}
return "";
}
} // end namespace comments
} // end namespace clang

View File

@@ -0,0 +1,154 @@
//===--- CommentBriefParser.cpp - Dumb comment parser ---------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "clang/AST/CommentBriefParser.h"
#include "clang/AST/CommentCommandTraits.h"
namespace clang {
namespace comments {
namespace {
inline bool isWhitespace(char C) {
return C == ' ' || C == '\n' || C == '\r' ||
C == '\t' || C == '\f' || C == '\v';
}
/// Convert all whitespace into spaces, remove leading and trailing spaces,
/// compress multiple spaces into one.
void cleanupBrief(std::string &S) {
bool PrevWasSpace = true;
std::string::iterator O = S.begin();
for (std::string::iterator I = S.begin(), E = S.end();
I != E; ++I) {
const char C = *I;
if (isWhitespace(C)) {
if (!PrevWasSpace) {
*O++ = ' ';
PrevWasSpace = true;
}
continue;
} else {
*O++ = C;
PrevWasSpace = false;
}
}
if (O != S.begin() && *(O - 1) == ' ')
--O;
S.resize(O - S.begin());
}
bool isWhitespace(StringRef Text) {
for (StringRef::const_iterator I = Text.begin(), E = Text.end();
I != E; ++I) {
if (!isWhitespace(*I))
return false;
}
return true;
}
} // unnamed namespace
BriefParser::BriefParser(Lexer &L, const CommandTraits &Traits) :
L(L), Traits(Traits) {
// Get lookahead token.
ConsumeToken();
}
std::string BriefParser::Parse() {
std::string FirstParagraphOrBrief;
std::string ReturnsParagraph;
bool InFirstParagraph = true;
bool InBrief = false;
bool InReturns = false;
while (Tok.isNot(tok::eof)) {
if (Tok.is(tok::text)) {
if (InFirstParagraph || InBrief)
FirstParagraphOrBrief += Tok.getText();
else if (InReturns)
ReturnsParagraph += Tok.getText();
ConsumeToken();
continue;
}
if (Tok.is(tok::backslash_command) || Tok.is(tok::at_command)) {
const CommandInfo *Info = Traits.getCommandInfo(Tok.getCommandID());
if (Info->IsBriefCommand) {
FirstParagraphOrBrief.clear();
InBrief = true;
ConsumeToken();
continue;
}
if (Info->IsReturnsCommand) {
InReturns = true;
InBrief = false;
InFirstParagraph = false;
ReturnsParagraph += "Returns ";
ConsumeToken();
continue;
}
// Block commands implicitly start a new paragraph.
if (Info->IsBlockCommand) {
// We found an implicit paragraph end.
InFirstParagraph = false;
if (InBrief)
break;
}
}
if (Tok.is(tok::newline)) {
if (InFirstParagraph || InBrief)
FirstParagraphOrBrief += ' ';
else if (InReturns)
ReturnsParagraph += ' ';
ConsumeToken();
// If the next token is a whitespace only text, ignore it. Thus we allow
// two paragraphs to be separated by line that has only whitespace in it.
//
// We don't need to add a space to the parsed text because we just added
// a space for the newline.
if (Tok.is(tok::text)) {
if (isWhitespace(Tok.getText()))
ConsumeToken();
}
if (Tok.is(tok::newline)) {
ConsumeToken();
// We found a paragraph end. This ends the brief description if
// \\brief command or its equivalent was explicitly used.
// Stop scanning text because an explicit \\brief paragraph is the
// preffered one.
if (InBrief)
break;
// End first paragraph if we found some non-whitespace text.
if (InFirstParagraph && !isWhitespace(FirstParagraphOrBrief))
InFirstParagraph = false;
// End the \\returns paragraph because we found the paragraph end.
InReturns = false;
}
continue;
}
// We didn't handle this token, so just drop it.
ConsumeToken();
}
cleanupBrief(FirstParagraphOrBrief);
if (!FirstParagraphOrBrief.empty())
return FirstParagraphOrBrief;
cleanupBrief(ReturnsParagraph);
return ReturnsParagraph;
}
} // end namespace comments
} // end namespace clang

View File

@@ -0,0 +1,139 @@
//===--- CommentCommandTraits.cpp - Comment command properties --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "clang/AST/CommentCommandTraits.h"
#include "llvm/ADT/STLExtras.h"
namespace clang {
namespace comments {
#include "clang/AST/CommentCommandInfo.inc"
CommandTraits::CommandTraits(llvm::BumpPtrAllocator &Allocator,
const CommentOptions &CommentOptions) :
NextID(llvm::array_lengthof(Commands)), Allocator(Allocator) {
registerCommentOptions(CommentOptions);
}
void CommandTraits::registerCommentOptions(
const CommentOptions &CommentOptions) {
for (CommentOptions::BlockCommandNamesTy::const_iterator
I = CommentOptions.BlockCommandNames.begin(),
E = CommentOptions.BlockCommandNames.end();
I != E; I++) {
registerBlockCommand(*I);
}
}
const CommandInfo *CommandTraits::getCommandInfoOrNULL(StringRef Name) const {
if (const CommandInfo *Info = getBuiltinCommandInfo(Name))
return Info;
return getRegisteredCommandInfo(Name);
}
const CommandInfo *CommandTraits::getCommandInfo(unsigned CommandID) const {
if (const CommandInfo *Info = getBuiltinCommandInfo(CommandID))
return Info;
return getRegisteredCommandInfo(CommandID);
}
const CommandInfo *
CommandTraits::getTypoCorrectCommandInfo(StringRef Typo) const {
// Single-character command impostures, such as \t or \n, should not go
// through the fixit logic.
if (Typo.size() <= 1)
return nullptr;
// The maximum edit distance we're prepared to accept.
const unsigned MaxEditDistance = 1;
unsigned BestEditDistance = MaxEditDistance;
SmallVector<const CommandInfo *, 2> BestCommand;
auto ConsiderCorrection = [&](const CommandInfo *Command) {
StringRef Name = Command->Name;
unsigned MinPossibleEditDistance = abs((int)Name.size() - (int)Typo.size());
if (MinPossibleEditDistance <= BestEditDistance) {
unsigned EditDistance = Typo.edit_distance(Name, true, BestEditDistance);
if (EditDistance < BestEditDistance) {
BestEditDistance = EditDistance;
BestCommand.clear();
}
if (EditDistance == BestEditDistance)
BestCommand.push_back(Command);
}
};
for (const auto &Command : Commands)
ConsiderCorrection(&Command);
for (const auto *Command : RegisteredCommands)
if (!Command->IsUnknownCommand)
ConsiderCorrection(Command);
return BestCommand.size() == 1 ? BestCommand[0] : nullptr;
}
CommandInfo *CommandTraits::createCommandInfoWithName(StringRef CommandName) {
char *Name = Allocator.Allocate<char>(CommandName.size() + 1);
memcpy(Name, CommandName.data(), CommandName.size());
Name[CommandName.size()] = '\0';
// Value-initialize (=zero-initialize in this case) a new CommandInfo.
CommandInfo *Info = new (Allocator) CommandInfo();
Info->Name = Name;
// We only have a limited number of bits to encode command IDs in the
// CommandInfo structure, so the ID numbers can potentially wrap around.
assert((NextID < (1 << CommandInfo::NumCommandIDBits))
&& "Too many commands. We have limited bits for the command ID.");
Info->ID = NextID++;
RegisteredCommands.push_back(Info);
return Info;
}
const CommandInfo *CommandTraits::registerUnknownCommand(
StringRef CommandName) {
CommandInfo *Info = createCommandInfoWithName(CommandName);
Info->IsUnknownCommand = true;
return Info;
}
const CommandInfo *CommandTraits::registerBlockCommand(StringRef CommandName) {
CommandInfo *Info = createCommandInfoWithName(CommandName);
Info->IsBlockCommand = true;
return Info;
}
const CommandInfo *CommandTraits::getBuiltinCommandInfo(
unsigned CommandID) {
if (CommandID < llvm::array_lengthof(Commands))
return &Commands[CommandID];
return nullptr;
}
const CommandInfo *CommandTraits::getRegisteredCommandInfo(
StringRef Name) const {
for (unsigned i = 0, e = RegisteredCommands.size(); i != e; ++i) {
if (RegisteredCommands[i]->Name == Name)
return RegisteredCommands[i];
}
return nullptr;
}
const CommandInfo *CommandTraits::getRegisteredCommandInfo(
unsigned CommandID) const {
return RegisteredCommands[CommandID - llvm::array_lengthof(Commands)];
}
} // end namespace comments
} // end namespace clang

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,50 @@
//===-- DataCollection.cpp --------------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "clang/AST/DataCollection.h"
#include "clang/Lex/Lexer.h"
namespace clang {
namespace data_collection {
/// Prints the macro name that contains the given SourceLocation into the given
/// raw_string_ostream.
static void printMacroName(llvm::raw_string_ostream &MacroStack,
ASTContext &Context, SourceLocation Loc) {
MacroStack << Lexer::getImmediateMacroName(Loc, Context.getSourceManager(),
Context.getLangOpts());
// Add an empty space at the end as a padding to prevent
// that macro names concatenate to the names of other macros.
MacroStack << " ";
}
/// Returns a string that represents all macro expansions that expanded into the
/// given SourceLocation.
///
/// If 'getMacroStack(A) == getMacroStack(B)' is true, then the SourceLocations
/// A and B are expanded from the same macros in the same order.
std::string getMacroStack(SourceLocation Loc, ASTContext &Context) {
std::string MacroStack;
llvm::raw_string_ostream MacroStackStream(MacroStack);
SourceManager &SM = Context.getSourceManager();
// Iterate over all macros that expanded into the given SourceLocation.
while (Loc.isMacroID()) {
// Add the macro name to the stream.
printMacroName(MacroStackStream, Context, Loc);
Loc = SM.getImmediateMacroCallerLoc(Loc);
}
MacroStackStream.flush();
return MacroStack;
}
} // end namespace data_collection
} // end namespace clang

View File

@@ -0,0 +1 @@
918466236bffd7c7740415b97a3b24eb240f9134

Some files were not shown because too many files have changed in this diff Show More