s属性什么意思| 尿路感染是什么原因造成的| 西安五行属什么| 西瓜可以做成什么美食| 被蝎子蛰了用什么药| 子宫内膜单纯性增生是什么意思| 身体出汗多是什么原因| 红颜知己代表什么关系| 神仙眷侣是什么意思| 心律失常是什么症状| 软下疳是什么症状| 甲亢有什么症状| 药流前需要做什么检查| 什么胃病需要做手术| 尾戒代表什么| 菁字五行属什么| 复方什么意思| 喝什么茶减肥效果最好| 顺风顺水是什么生肖| 右小腿抽筋是什么原因| 妊娠反应什么时候开始| 肚子疼拉稀是什么原因| 狗狗不吃饭是什么原因| 才高八斗是什么生肖| 梦到别人结婚是什么意思| 椰子不能和什么一起吃| 间接胆红素是什么| zara属于什么档次| 擦枪走火什么意思| 脸上过敏用什么药膏| 存款准备金率下调意味着什么| 辟支佛是什么意思| 六月二十七是什么日子| 甲醇是什么东西| 鸡拉白色稀粪吃什么药| 豌豆是什么豆| 经常嗓子哑是什么原因| 说辞是什么意思| 拉出黑色的屎是什么原因| 11.22什么星座| 距骨在什么位置| 口苦是什么问题| 血红蛋白低吃什么| 肺癌有什么症状| 一个火一个同念什么| 嘴角上火是什么原因| 发乎情止乎礼什么意思| 头发长的快是什么原因| 牙疼吃什么饭菜比较好| 朕是什么时候开始用的| 房颤吃什么药效果最好| 橱窗是什么意思| 美女是指什么生肖| 树欲静而风不止是什么意思| brush什么意思| 急性肠炎吃什么食物好| hpv是什么东西| 六根清净是什么意思| 家里有蚂蚁是什么原因| 做放疗的人吃什么好| 孙悟空头上戴的是什么| 右边肋骨下面是什么器官| 神经是什么东西| 大圆脸适合什么发型| 双鱼男喜欢什么样的女生| 阴吹是什么| 为什么要学数学| 多多包涵是什么意思| 早谢是什么症状| names是什么意思| 临终关怀的目的是什么| 碱性磷酸酶高是什么意思| 金字旁加者念什么| 宫颈炎吃什么药| 汉卿是什么意思| 牙套什么年龄戴合适| 寒疾现代叫什么病| cip是什么意思| 秋千为什么叫秋千| 什么是辅酶q10| h 是什么意思| 土茯苓与茯苓有什么区别| 格列卫是什么药| 长痘痘用什么药| 玫瑰茄和洛神花有什么区别吗| 低压偏低是什么原因| 时隔是什么意思| 什么是脂肪瘤| 一步登天是什么生肖| mrn是什么意思| 乳房疼吃什么药| 白癜风不能吃什么食物| 洋葱配什么菜炒好吃| 口苦吃什么药最有效| 避讳是什么意思| 蛔虫是什么动物| 门牙下面的牙叫什么| 为什么月经量少| 沙眼用什么眼药水| 轮回是什么意思| 猫的胡须有什么作用| 1952属什么生肖| 6周岁打什么疫苗| 什么动物睡觉不闭眼| 心肌缺血有什么症状和表现| 口甜是什么原因引起的| 89年五行属什么| 中药天龙又叫什么| 欧皇是什么意思| 心肌缺血用什么药| 母鸡学公鸡叫什么征兆| 失眠多梦是什么原因| 马蜂蛰了用什么药| 外交是什么意思| 9.23号是什么星座| 人血馒头是什么意思| RH什么意思| 阿司匹林和阿莫西林有什么区别| 巨蟹座和什么座最配对| 退烧药吃多了有什么副作用| 婴儿足底血筛查什么| 吃什么能让月经快点来| 孕妇梦到蛇是什么意思| 一级甲等医院是什么意思| lsa是什么意思| 喉咙疼痛吃什么药效果最好| 做宫腔镜检查需要提前做什么准备| 吃榴莲对妇科病有什么好处| 男人什么时候精子最强| crh是什么意思| 食指有痣代表什么意思| 手上长汗疱疹用什么药| 什么东东| nlp是什么| 尿检ph值偏高说明什么| 豪情万丈什么意思| 星巴克是什么| au是什么货币| 黄芪是什么味道| 老年人吃什么水果对身体好| 高密度脂蛋白胆固醇高是什么意思| 相见不如怀念是什么意思| 体面什么意思| 梦见大便是什么预兆| 湿疹是什么样子的| 梦见死了人是什么意思| rm是什么位置| 物以类聚人以群分什么意思| 三个又读什么| 便潜血阳性什么意思| 下巴肿大是什么原因| 烊化兑服是什么意思| 婴儿坐高铁需要什么证件| 谷丙转氨酶偏高吃什么药| 为什么不一样| 伤口发炎化脓用什么药| 孕囊长什么样| 感冒引起的咳嗽吃什么药| 什么是胶原蛋白| 吃龟苓膏有什么好处| 指甲很薄很软是为什么| 大姨妈来了不能吃什么水果| 前庭大腺囊肿是什么原因引起的| 帆布是什么材质| 什么样的手相最有福气| 莫逆之交是什么意思| 什么情况下会宫外孕| 肠胃炎什么症状| 为什么新生儿有胎记| 多愁善感是什么意思| 女人喝蜂蜜水有什么好处| 被银环蛇咬了有什么症状| 心脏突然剧烈跳动是什么原因| 轻微脑震荡有什么表现| 肺纹理增强是什么意思| blissful是什么意思| 胸口痛吃什么药| 为什么突然有狐臭了| 不丹为什么不跟中国建交| 三保是什么| 红玫瑰花语是什么意思| 什么时候降温| 蜱虫的天敌是什么| 什么的腊梅| 世界上什么东西最大| 什么长而什么| 为什么闭眼单脚站不稳| 肺部有结节要注意什么| 西瓜和什么不能一起吃| 隐翅虫擦什么药膏| 身上臭是什么原因| 启蒙是什么意思| 肖像是什么意思| 跳蚤咬了擦什么药| 孕妇吃火龙果有什么好处| 网络用语是什么意思| 精神卫生科看什么病| 肌酸是什么东西| 希望孩子成为什么样的人| 头部ct能检查出什么| 县长什么级别| 拔牙后可以吃什么食物| 舌炎吃什么药好得快| 香奶奶是什么牌子| 76年出生属什么生肖| 做什么生意最赚钱| 赡养是什么意思| 刑警队是干什么的| 男人为什么会得尿结石| 什么什么若狂| 嗓子干痒咳嗽吃什么药| 梦见自己有孩子了是什么预兆| 痔疮手术后可以吃什么水果| 党内警告处分有什么影响| 芒果有什么功效| 幽门螺杆菌吃什么药最好| 梦见白猫是什么预兆| 电动车是什么电池| 牛子是什么意思| 为什么会得脑梗| 小孩吃什么可以长高| 女人更年期吃什么药调理最好| 来月经腰疼是什么原因| 狗尾巴草有什么功效| 呼吸道感染用什么药| 怀孕打黄体酮针有什么作用| 指甲发紫是什么原因| 晚上猫叫有什么预兆| 扶正固本是什么意思| 腰酸是什么病的前兆| 八六年属什么生肖| 3月30号是什么星座| 子宫直肠陷凹什么意思| 尿路感染喝什么药| 汗疱疹用什么药| 岁月不饶人是什么意思| 乾隆为什么不喜欢雍正| 摔跤擦伤破皮擦什么药| 90年出生属什么生肖| 什么是灌肠| 可遇不可求什么意思| 宫腔内偏强回声是什么意思| 今天生日什么星座| 男生做爱什么感觉| 兔死狐悲指什么生肖| 马步鱼为什么是甜的| 尿潜血十一是什么意思| 睡觉咬牙齿是什么原因引起的| 一什么茶| 梦见狗打架是什么意思| 什么叫屌丝| 甜菜根在中国叫什么| 什么的长江| 什么是18k金| ct是什么| 当所有的人离开我的时候是什么歌| 小孩一到晚上就发烧是什么原因| 秒了是什么意思| 湿疹是什么原因造成的| 为什么喝绞股蓝会死亡| 类风湿关节炎不能吃什么食物| 文化是指什么| 菜籽油是什么油| 很困但是睡不着是什么原因| 百度
blob: a2b8e7db76550a042876355ee087d755677b12cb [file] [log] [blame] [edit]
#!/usr/bin/env python
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""This script should be run manually on occasion to make sure all PPAPI types
have appropriate size checking.
"""
from __future__ import print_function
import optparse
import os
import subprocess
import sys
# The string that the PrintNamesAndSizes plugin uses to indicate a type is
# expected to have architecture-dependent size.
ARCH_DEPENDENT_STRING = "ArchDependentSize"
COPYRIGHT_STRING_C = (
"""/* Copyright (c) %s The Chromium Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
* This file has compile assertions for the sizes of types that are dependent
* on the architecture for which they are compiled (i.e., 32-bit vs 64-bit).
*/
""") % datetime.date.today().year
class SourceLocation(object):
"""A class representing the source location of a definiton."""
def __init__(self, filename="", start_line=-1, end_line=-1):
self.filename = os.path.normpath(filename)
self.start_line = start_line
self.end_line = end_line
class TypeInfo(object):
"""A class representing information about a C++ type. It contains the
following fields:
- kind: The Clang TypeClassName (Record, Enum, Typedef, Union, etc)
- name: The unmangled string name of the type.
- size: The size in bytes of the type.
- arch_dependent: True if the type may have architecture dependent size
according to PrintNamesAndSizes. False otherwise. Types
which are considered architecture-dependent from 32-bit
to 64-bit are pointers, longs, unsigned longs, and any
type that contains an architecture-dependent type.
- source_location: A SourceLocation describing where the type is defined.
- target: The target Clang was compiling when it found the type definition.
This is used only for diagnostic output.
- parsed_line: The line which Clang output which was used to create this
TypeInfo (as the info_string parameter to __init__). This is
used only for diagnostic output.
"""
def __init__(self, info_string, target):
"""Create a TypeInfo from a given info_string. Also store the name of the
target for which the TypeInfo was first created just so we can print useful
error information.
info_string is a comma-delimited string of the following form:
kind,name,size,arch_dependent,source_file,start_line,end_line
Where:
- kind: The Clang TypeClassName (Record, Enum, Typedef, Union, etc)
- name: The unmangled string name of the type.
- size: The size in bytes of the type.
- arch_dependent: 'ArchDependentSize' if the type has architecture-dependent
size, NotArchDependentSize otherwise.
- source_file: The source file in which the type is defined.
- first_line: The first line of the definition (counting from 0).
- last_line: The last line of the definition (counting from 0).
This should match the output of the PrintNamesAndSizes plugin.
"""
[self.kind, self.name, self.size, arch_dependent_string, source_file,
start_line, end_line] = info_string.split(',')
self.target = target
self.parsed_line = info_string
# Note that Clang counts line numbers from 1, but we want to count from 0.
self.source_location = SourceLocation(source_file,
int(start_line)-1,
int(end_line)-1)
self.arch_dependent = (arch_dependent_string == ARCH_DEPENDENT_STRING)
class FilePatch(object):
"""A class representing a set of line-by-line changes to a particular file.
None of the changes are applied until Apply is called. All line numbers are
counted from 0.
"""
def __init__(self, filename):
self.filename = filename
self.linenums_to_delete = set()
# A dictionary from line number to an array of strings to be inserted at
# that line number.
self.lines_to_add = {}
def Delete(self, start_line, end_line):
"""Make the patch delete the lines starting with |start_line| up to but not
including |end_line|.
"""
self.linenums_to_delete |= set(range(start_line, end_line))
def Add(self, text, line_number):
"""Add the given text before the text on the given line number."""
if line_number in self.lines_to_add:
self.lines_to_add[line_number].append(text)
else:
self.lines_to_add[line_number] = [text]
def Apply(self):
"""Apply the patch by writing it to self.filename."""
# Read the lines of the existing file in to a list.
sourcefile = open(self.filename, "r")
file_lines = sourcefile.readlines()
sourcefile.close()
# Now apply the patch. Our strategy is to keep the array at the same size,
# and just edit strings in the file_lines list as necessary. When we delete
# lines, we just blank the line and keep it in the list. When we add lines,
# we just prepend the added source code to the start of the existing line at
# that line number. This way, all the line numbers we cached from calls to
# Add and Delete remain valid list indices, and we don't have to worry about
# maintaining any offsets. Each element of file_lines at the end may
# contain any number of lines (0 or more) delimited by carriage returns.
for linenum_to_delete in self.linenums_to_delete:
file_lines[linenum_to_delete] = "";
for linenum, sourcelines in self.lines_to_add.items():
# Sort the lines we're adding so we get relatively consistent results.
sourcelines.sort()
# Prepend the new lines. When we output
file_lines[linenum] = "".join(sourcelines) + file_lines[linenum]
newsource = open(self.filename, "w")
for line in file_lines:
newsource.write(line)
newsource.close()
def CheckAndInsert(typeinfo, typeinfo_map):
"""Check if a TypeInfo exists already in the given map with the same name. If
so, make sure the size is consistent.
- If the name exists but the sizes do not match, print a message and
exit with non-zero exit code.
- If the name exists and the sizes match, do nothing.
- If the name does not exist, insert the typeinfo in to the map.
"""
# If the type is unnamed, ignore it.
if typeinfo.name == "":
return
# If the size is 0, ignore it.
elif int(typeinfo.size) == 0:
return
# If the type is not defined under ppapi, ignore it.
elif typeinfo.source_location.filename.find("ppapi") == -1:
return
# If the type is defined under GLES2, ignore it.
elif typeinfo.source_location.filename.find("GLES2") > -1:
return
# If the type is an interface (by convention, starts with PPP_ or PPB_),
# ignore it.
elif (typeinfo.name[:4] == "PPP_") or (typeinfo.name[:4] == "PPB_"):
return
elif typeinfo.name in typeinfo_map:
if typeinfo.size != typeinfo_map[typeinfo.name].size:
print("Error: '" + typeinfo.name + "' is", \
typeinfo_map[typeinfo.name].size, \
"bytes on target '" + typeinfo_map[typeinfo.name].target + \
"', but", typeinfo.size, "on target '" + typeinfo.target + "'")
print(typeinfo_map[typeinfo.name].parsed_line)
print(typeinfo.parsed_line)
sys.exit(1)
else:
# It's already in the map and the sizes match.
pass
else:
typeinfo_map[typeinfo.name] = typeinfo
def ProcessTarget(clang_command, target, types):
"""Run clang using the given clang_command for the given target string. Parse
the output to create TypeInfos for each discovered type. Insert each type in
to the 'types' dictionary. If the type already exists in the types
dictionary, make sure that the size matches what's already in the map. If
not, exit with an error message.
"""
p = subprocess.Popen(clang_command + " -triple " + target,
shell=True,
stdout=subprocess.PIPE)
lines = p.communicate()[0].split()
for line in lines:
typeinfo = TypeInfo(line, target)
CheckAndInsert(typeinfo, types)
def ToAssertionCode(typeinfo):
"""Convert the TypeInfo to an appropriate C compile assertion.
If it's a struct (Record in Clang terminology), we want a line like this:
PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(<name>, <size>);\n
Enums:
PP_COMPILE_ASSERT_ENUM_SIZE_IN_BYTES(<name>, <size>);\n
Typedefs:
PP_COMPILE_ASSERT_SIZE_IN_BYTES(<name>, <size>);\n
"""
line = "PP_COMPILE_ASSERT_"
if typeinfo.kind == "Enum":
line += "ENUM_"
elif typeinfo.kind == "Record":
line += "STRUCT_"
line += "SIZE_IN_BYTES("
line += typeinfo.name
line += ", "
line += typeinfo.size
line += ");\n"
return line
def IsMacroDefinedName(typename):
"""Return true iff the given typename came from a PPAPI compile assertion."""
return typename.find("PP_Dummy_Struct_For_") == 0
def WriteArchSpecificCode(types, root, filename):
"""Write a header file that contains a compile-time assertion for the size of
each of the given typeinfos, in to a file named filename rooted at root.
"""
assertion_lines = [ToAssertionCode(typeinfo) for typeinfo in types]
assertion_lines.sort()
outfile = open(os.path.join(root, filename), "w")
header_guard = "PPAPI_TESTS_" + filename.upper().replace(".", "_") + "_"
outfile.write(COPYRIGHT_STRING_C)
outfile.write('#ifndef ' + header_guard + '\n')
outfile.write('#define ' + header_guard + '\n\n')
outfile.write('#include "ppapi/tests/test_struct_sizes.c"\n\n')
for line in assertion_lines:
outfile.write(line)
outfile.write('\n#endif /* ' + header_guard + ' */\n')
def main(argv):
# See README file for example command-line invocation. This script runs the
# PrintNamesAndSizes Clang plugin with 'test_struct_sizes.c' as input, which
# should include all C headers and all existing size checks. It runs the
# plugin multiple times; once for each of a set of targets, some 32-bit and
# some 64-bit. It verifies that wherever possible, types have a consistent
# size on both platforms. Types that can't easily have consistent size (e.g.
# ones that contain a pointer) are checked to make sure they are consistent
# for all 32-bit platforms and consistent on all 64-bit platforms, but the
# sizes on 32 vs 64 are allowed to differ.
#
# Then, if all the types have consistent size as expected, compile assertions
# are added to the source code. Types whose size is independent of
# architectureacross have their compile assertions placed immediately after
# their definition in the C API header. Types whose size differs on 32-bit
# vs 64-bit have a compile assertion placed in each of:
# ppapi/tests/arch_dependent_sizes_32.h and
# ppapi/tests/arch_dependent_sizes_64.h.
#
# Note that you should always check the results of the tool to make sure
# they are sane.
parser = optparse.OptionParser()
parser.add_option(
'-c', '--clang-path', dest='clang_path',
default=(''),
help='the path to the clang binary (default is to get it from your path)')
parser.add_option(
'-p', '--plugin', dest='plugin',
default='tests/clang/libPrintNamesAndSizes.so',
help='The path to the PrintNamesAndSizes plugin library.')
parser.add_option(
'--targets32', dest='targets32',
default='i386-pc-linux,arm-pc-linux,i386-pc-win32',
help='Which 32-bit target triples to provide to clang.')
parser.add_option(
'--targets64', dest='targets64',
default='x86_64-pc-linux,x86_64-pc-win',
help='Which 32-bit target triples to provide to clang.')
parser.add_option(
'-r', '--ppapi-root', dest='ppapi_root',
default='.',
help='The root directory of ppapi.')
options, args = parser.parse_args(argv)
if args:
parser.print_help()
print('ERROR: invalid argument')
sys.exit(1)
clang_executable = os.path.join(options.clang_path, 'clang')
clang_command = clang_executable + " -cc1" \
+ " -load " + options.plugin \
+ " -plugin PrintNamesAndSizes" \
+ " -I" + os.path.join(options.ppapi_root, "..") \
+ " " \
+ os.path.join(options.ppapi_root, "tests", "test_struct_sizes.c")
# Dictionaries mapping type names to TypeInfo objects.
# Types that have size dependent on architecture, for 32-bit
types32 = {}
# Types that have size dependent on architecture, for 64-bit
types64 = {}
# Note that types32 and types64 should contain the same types, but with
# different sizes.
# Types whose size should be consistent regardless of architecture.
types_independent = {}
# Now run clang for each target. Along the way, make sure architecture-
# dependent types are consistent sizes on all 32-bit platforms and consistent
# on all 64-bit platforms.
targets32 = options.targets32.split(',');
for target in targets32:
# For each 32-bit target, run the PrintNamesAndSizes Clang plugin to get
# information about all types in the translation unit, and add a TypeInfo
# for each of them to types32. If any size mismatches are found,
# ProcessTarget will spit out an error and exit.
ProcessTarget(clang_command, target, types32)
targets64 = options.targets64.split(',');
for target in targets64:
# Do the same as above for each 64-bit target; put all types in types64.
ProcessTarget(clang_command, target, types64)
# Now for each dictionary, find types whose size are consistent regardless of
# architecture, and move those in to types_independent. Anywhere sizes
# differ, make sure they are expected to be architecture-dependent based on
# their structure. If we find types which could easily be consistent but
# aren't, spit out an error and exit.
types_independent = {}
for typename, typeinfo32 in types32.items():
if (typename in types64):
typeinfo64 = types64[typename]
if (typeinfo64.size == typeinfo32.size):
# The types are the same size, so we can treat it as arch-independent.
types_independent[typename] = typeinfo32
del types32[typename]
del types64[typename]
elif (typeinfo32.arch_dependent or typeinfo64.arch_dependent):
# The type is defined in such a way that it would be difficult to make
# its size consistent. E.g., it has pointers. We'll leave it in the
# arch-dependent maps so that we can put arch-dependent size checks in
# test code.
pass
else:
# The sizes don't match, but there's no reason they couldn't. It's
# probably due to an alignment mismatch between Win32/NaCl vs Linux32/
# Mac32.
print("Error: '" + typename + "' is", typeinfo32.size, \
"bytes on target '" + typeinfo32.target + \
"', but", typeinfo64.size, "on target '" + typeinfo64.target + "'")
print(typeinfo32.parsed_line)
print(typeinfo64.parsed_line)
sys.exit(1)
else:
print("WARNING: Type '", typename, "' was defined for target '")
print(typeinfo32.target, ", but not for any 64-bit targets.")
# Now we have all the information we need to generate our static assertions.
# Types that have consistent size across architectures will have the static
# assertion placed immediately after their definition. Types whose size
# depends on 32-bit vs 64-bit architecture will have checks placed in
# tests/arch_dependent_sizes_32/64.h.
# This dictionary maps file names to FilePatch objects. We will add items
# to it as needed. Each FilePatch represents a set of changes to make to the
# associated file (additions and deletions).
file_patches = {}
# Find locations of existing macros, and just delete them all. Note that
# normally, only things in 'types_independent' need to be deleted, as arch-
# dependent checks exist in tests/arch_dependent_sizes_32/64.h, which are
# always completely over-ridden. However, it's possible that a type that used
# to be arch-independent has changed to now be arch-dependent (e.g., because
# a pointer was added), and we want to delete the old check in that case.
for name, typeinfo in \
types_independent.items() + types32.items() + types64.items():
if IsMacroDefinedName(name):
sourcefile = typeinfo.source_location.filename
if sourcefile not in file_patches:
file_patches[sourcefile] = FilePatch(sourcefile)
file_patches[sourcefile].Delete(typeinfo.source_location.start_line,
typeinfo.source_location.end_line+1)
# Add a compile-time assertion for each type whose size is independent of
# architecture. These assertions go immediately after the class definition.
for name, typeinfo in types_independent.items():
# Ignore dummy types that were defined by macros and also ignore types that
# are 0 bytes (i.e., typedefs to void).
if not IsMacroDefinedName(name) and typeinfo.size > 0:
sourcefile = typeinfo.source_location.filename
if sourcefile not in file_patches:
file_patches[sourcefile] = FilePatch(sourcefile)
# Add the assertion code just after the definition of the type.
# E.g.:
# struct Foo {
# int32_t x;
# };
# PP_COMPILE_ASSERT_STRUCT_SIZE_IN_BYTES(Foo, 4); <---Add this line
file_patches[sourcefile].Add(ToAssertionCode(typeinfo),
typeinfo.source_location.end_line+1)
# Apply our patches. This actually edits the files containing the definitions
# for the types in types_independent.
for filename, patch in file_patches.items():
patch.Apply()
# Write out a file of checks for 32-bit architectures and a separate file for
# 64-bit architectures. These only have checks for types that are
# architecture-dependent.
c_source_root = os.path.join(options.ppapi_root, "tests")
WriteArchSpecificCode(types32.values(),
c_source_root,
"arch_dependent_sizes_32.h")
WriteArchSpecificCode(types64.values(),
c_source_root,
"arch_dependent_sizes_64.h")
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))
为什么会得牙周炎 记过处分有什么影响 一什么公园 一戴套就软是什么原因 鼠疫是由什么引起的
generic是什么意思 脊椎痛什么原因 内分泌失调什么症状 夜晚尿频尿多是什么原因 什么食物最养胃
脖子不舒服看什么科 为什么会胃痛 石花膏是什么做的 aca是什么意思 2024年属什么
数位是什么 什么不能带上高铁 两小无猜是什么意思 女人脚肿是什么原因 做梦飞起来了是什么兆头
协警是什么编制helloaicloud.com 奶奶的妈妈叫什么hcv9jop1ns1r.cn 巡视员什么级别hcv9jop5ns2r.cn 什么是闭合性跌打损伤hcv9jop7ns2r.cn 颜狗是什么意思hcv9jop4ns2r.cn
仙草粉是什么做的hcv8jop2ns2r.cn 范思哲是什么品牌hcv9jop1ns2r.cn 什么叫cphcv8jop9ns6r.cn 检查肝脏应该挂什么科hcv8jop8ns0r.cn 鬼节为什么不能出去hcv9jop3ns5r.cn
2006属狗的五行缺什么hcv9jop3ns4r.cn 围绝经期是什么意思hcv7jop9ns1r.cn 失态是什么意思hcv7jop9ns7r.cn 肝囊肿有什么症状表现hcv9jop5ns5r.cn 烟草属于什么行业hcv9jop2ns6r.cn
红眼病用什么药hcv8jop6ns4r.cn 心影增大是什么意思hcv7jop4ns5r.cn 鼻子老流鼻涕是什么原因引起inbungee.com 后背发凉是什么原因hcv8jop5ns0r.cn 跑龙套是什么意思hcv8jop5ns5r.cn
百度